Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / Source / core / layout / LayoutTextFragment.cpp
blob13209b9f5404a7acd73e59bf6dc25006d0973a98
1 /*
2 * (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 2000 Dirk Mueller (mueller@kde.org)
4 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
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.
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.
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.
23 #include "config.h"
24 #include "core/layout/LayoutTextFragment.h"
26 #include "core/dom/FirstLetterPseudoElement.h"
27 #include "core/dom/PseudoElement.h"
28 #include "core/dom/StyleChangeReason.h"
29 #include "core/dom/Text.h"
30 #include "core/layout/HitTestResult.h"
31 #include "core/layout/LayoutBlock.h"
33 namespace blink {
35 LayoutTextFragment::LayoutTextFragment(Node* node, StringImpl* str, int startOffset, int length)
36 : LayoutText(node, str ? str->substring(startOffset, length) : PassRefPtr<StringImpl>(nullptr))
37 , m_start(startOffset)
38 , m_end(length)
39 , m_isRemainingTextLayoutObject(false)
40 , m_contentString(str)
41 , m_firstLetterPseudoElement(nullptr)
45 LayoutTextFragment::LayoutTextFragment(Node* node, StringImpl* str)
46 : LayoutText(node, str)
47 , m_start(0)
48 , m_end(str ? str->length() : 0)
49 , m_isRemainingTextLayoutObject(false)
50 , m_contentString(str)
51 , m_firstLetterPseudoElement(nullptr)
55 LayoutTextFragment::~LayoutTextFragment()
57 ASSERT(!m_firstLetterPseudoElement);
60 void LayoutTextFragment::willBeDestroyed()
62 if (m_isRemainingTextLayoutObject && m_firstLetterPseudoElement)
63 m_firstLetterPseudoElement->setRemainingTextLayoutObject(nullptr);
64 m_firstLetterPseudoElement = nullptr;
65 LayoutText::willBeDestroyed();
68 PassRefPtr<StringImpl> LayoutTextFragment::completeText() const
70 Text* text = associatedTextNode();
71 return text ? text->dataImpl() : contentString();
74 void LayoutTextFragment::setContentString(StringImpl* str)
76 m_contentString = str;
77 setText(str);
80 PassRefPtr<StringImpl> LayoutTextFragment::originalText() const
82 RefPtr<StringImpl> result = completeText();
83 if (!result)
84 return nullptr;
85 return result->substring(start(), end());
88 void LayoutTextFragment::setText(PassRefPtr<StringImpl> text, bool force)
90 LayoutText::setText(text, force);
92 m_start = 0;
93 m_end = textLength();
95 // If we're the remaining text from a first letter then we have to tell the
96 // first letter pseudo element to reattach itself so it can re-calculate the
97 // correct first-letter settings.
98 if (isRemainingTextLayoutObject()) {
99 ASSERT(firstLetterPseudoElement());
100 firstLetterPseudoElement()->updateTextFragments();
104 void LayoutTextFragment::setTextFragment(PassRefPtr<StringImpl> text, unsigned start, unsigned length)
106 LayoutText::setText(text, false);
108 m_start = start;
109 m_end = length;
112 void LayoutTextFragment::transformText()
114 // Note, we have to call LayoutText::setText here because, if we use our
115 // version we will, potentially, screw up the first-letter settings where
116 // we only use portions of the string.
117 if (RefPtr<StringImpl> textToTransform = originalText())
118 LayoutText::setText(textToTransform.release(), true);
121 UChar LayoutTextFragment::previousCharacter() const
123 if (start()) {
124 StringImpl* original = completeText().get();
125 if (original && start() <= original->length())
126 return (*original)[start() - 1];
129 return LayoutText::previousCharacter();
132 // If this is the layoutObject for a first-letter pseudoNode then we have to look
133 // at the node for the remaining text to find our content.
134 Text* LayoutTextFragment::associatedTextNode() const
136 Node* node = this->firstLetterPseudoElement();
137 if (m_isRemainingTextLayoutObject || !node) {
138 // If we don't have a node, then we aren't part of a first-letter pseudo
139 // element, so use the actual node. Likewise, if we have a node, but
140 // we're the remainingTextLayoutObject for a pseudo element use the real
141 // text node.
142 node = this->node();
145 if (!node)
146 return nullptr;
148 if (node->isFirstLetterPseudoElement()) {
149 FirstLetterPseudoElement* pseudo = toFirstLetterPseudoElement(node);
150 LayoutObject* nextLayoutObject = FirstLetterPseudoElement::firstLetterTextLayoutObject(*pseudo);
151 if (!nextLayoutObject)
152 return nullptr;
153 node = nextLayoutObject->node();
155 return (node && node->isTextNode()) ? toText(node) : nullptr;
158 void LayoutTextFragment::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
160 if (result.innerNode())
161 return;
163 LayoutObject::updateHitTestResult(result, point);
165 // If we aren't part of a first-letter element, or if we
166 // are part of first-letter but we're the remaining text then return.
167 if (m_isRemainingTextLayoutObject || !firstLetterPseudoElement())
168 return;
169 result.setInnerNode(firstLetterPseudoElement());
172 } // namespace blink