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 "core/rendering/RenderTextFragment.h"
     25 
     26 #include "core/dom/Text.h"
     27 #include "core/rendering/RenderBlock.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) : PassRefPtr<StringImpl>(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()) ? toText(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::willBeDestroyed()
     72 {
     73     if (m_firstLetter)
     74         m_firstLetter->destroy();
     75     RenderText::willBeDestroyed();
     76 }
     77 
     78 void RenderTextFragment::setText(PassRefPtr<StringImpl> text, bool force)
     79 {
     80     RenderText::setText(text, force);
     81 
     82     m_start = 0;
     83     m_end = textLength();
     84     if (m_firstLetter) {
     85         ASSERT(!m_contentString);
     86         m_firstLetter->destroy();
     87         m_firstLetter = 0;
     88         if (Node* t = node()) {
     89             ASSERT(!t->renderer());
     90             t->setRenderer(this);
     91         }
     92     }
     93 }
     94 
     95 void RenderTextFragment::transformText()
     96 {
     97     // Don't reset first-letter here because we are only transforming the truncated fragment.
     98     if (RefPtr<StringImpl> textToTransform = originalText())
     99         RenderText::setText(textToTransform.release(), true);
    100 }
    101 
    102 UChar RenderTextFragment::previousCharacter() const
    103 {
    104     if (start()) {
    105         Node* e = node();
    106         StringImpl* original = ((e && e->isTextNode()) ? toText(e)->dataImpl() : contentString());
    107         if (original && start() <= original->length())
    108             return (*original)[start() - 1];
    109     }
    110 
    111     return RenderText::previousCharacter();
    112 }
    113 
    114 RenderBlock* RenderTextFragment::blockForAccompanyingFirstLetter() const
    115 {
    116     if (!m_firstLetter)
    117         return 0;
    118     for (RenderObject* block = m_firstLetter->parent(); block; block = block->parent()) {
    119         if (block->style()->hasPseudoStyle(FIRST_LETTER) && block->canHaveChildren() && block->isRenderBlock())
    120             return toRenderBlock(block);
    121     }
    122     return 0;
    123 }
    124 
    125 } // namespace WebCore
    126