Home | History | Annotate | Download | only in rendering
      1 /*
      2  * (C) 1999 Lars Knoll (knoll (at) kde.org)
      3  * (C) 2000 Dirk Mueller (mueller (at) kde.org)
      4  * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
      5  *
      6  * This library is free software; you can redistribute it and/or
      7  * modify it under the terms of the GNU Library General Public
      8  * License as published by the Free Software Foundation; either
      9  * version 2 of the License, or (at your option) any later version.
     10  *
     11  * This library is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  * Library General Public License for more details.
     15  *
     16  * You should have received a copy of the GNU Library General Public License
     17  * along with this library; see the file COPYING.LIB.  If not, write to
     18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     19  * Boston, MA 02110-1301, USA.
     20  *
     21  */
     22 
     23 #include "config.h"
     24 #include "RenderTextFragment.h"
     25 
     26 #include "RenderBlock.h"
     27 #include "Text.h"
     28 
     29 namespace WebCore {
     30 
     31 RenderTextFragment::RenderTextFragment(Node* node, StringImpl* str, int startOffset, int length)
     32     : RenderText(node, str ? str->substring(startOffset, length) : 0)
     33     , m_start(startOffset)
     34     , m_end(length)
     35     , m_firstLetter(0)
     36 {
     37 }
     38 
     39 RenderTextFragment::RenderTextFragment(Node* node, StringImpl* str)
     40     : RenderText(node, str)
     41     , m_start(0)
     42     , m_end(str ? str->length() : 0)
     43     , m_contentString(str)
     44     , m_firstLetter(0)
     45 {
     46 }
     47 
     48 RenderTextFragment::~RenderTextFragment()
     49 {
     50 }
     51 
     52 PassRefPtr<StringImpl> RenderTextFragment::originalText() const
     53 {
     54     Node* e = node();
     55     RefPtr<StringImpl> result = ((e && e->isTextNode()) ? static_cast<Text*>(e)->dataImpl() : contentString());
     56     if (!result)
     57         return 0;
     58     return result->substring(start(), end());
     59 }
     60 
     61 void RenderTextFragment::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
     62 {
     63     RenderText::styleDidChange(diff, oldStyle);
     64 
     65     if (RenderBlock* block = blockForAccompanyingFirstLetter()) {
     66         block->style()->removeCachedPseudoStyle(FIRST_LETTER);
     67         block->updateFirstLetter();
     68     }
     69 }
     70 
     71 void RenderTextFragment::destroy()
     72 {
     73     if (m_firstLetter)
     74         m_firstLetter->destroy();
     75     RenderText::destroy();
     76 }
     77 
     78 void RenderTextFragment::setTextInternal(PassRefPtr<StringImpl> text)
     79 {
     80     RenderText::setTextInternal(text);
     81     if (m_firstLetter) {
     82         ASSERT(!m_contentString);
     83         m_firstLetter->destroy();
     84         m_firstLetter = 0;
     85         m_start = 0;
     86         m_end = textLength();
     87         if (Node* t = node()) {
     88             ASSERT(!t->renderer());
     89             t->setRenderer(this);
     90         }
     91     }
     92 }
     93 
     94 UChar RenderTextFragment::previousCharacter() const
     95 {
     96     if (start()) {
     97         Node* e = node();
     98         StringImpl*  original = ((e && e->isTextNode()) ? static_cast<Text*>(e)->dataImpl() : contentString());
     99         if (original && start() <= original->length())
    100             return (*original)[start() - 1];
    101     }
    102 
    103     return RenderText::previousCharacter();
    104 }
    105 
    106 RenderBlock* RenderTextFragment::blockForAccompanyingFirstLetter() const
    107 {
    108     if (!m_firstLetter)
    109         return 0;
    110     for (RenderObject* block = m_firstLetter->parent(); block; block = block->parent()) {
    111         if (block->style()->hasPseudoStyle(FIRST_LETTER) && block->canHaveChildren() && block->isRenderBlock())
    112             return toRenderBlock(block);
    113     }
    114     return 0;
    115 }
    116 
    117 } // namespace WebCore
    118