void FirstLetterPseudoElement::updateTextFragments() { String oldText = m_remainingTextLayoutObject->completeText(); ASSERT(oldText.impl()); unsigned length = FirstLetterPseudoElement::firstLetterLength(oldText); m_remainingTextLayoutObject->setTextFragment(oldText.impl()->substring(length, oldText.length()), length, oldText.length() - length); m_remainingTextLayoutObject->dirtyLineBoxes(); for (auto child = layoutObject()->slowFirstChild(); child; child = child->nextSibling()) { if (!child->isText() || !toLayoutText(child)->isTextFragment()) continue; LayoutTextFragment* childFragment = toLayoutTextFragment(child); if (childFragment->firstLetterPseudoElement() != this) continue; childFragment->setTextFragment(oldText.impl()->substring(0, length), 0, length); childFragment->dirtyLineBoxes(); // Make sure the first-letter layoutObject is set to require a layout as it // needs to re-create the line boxes. The remaining text layoutObject // will be marked by the LayoutText::setText. childFragment->setNeedsLayoutAndPrefWidthsRecalc(LayoutInvalidationReason::TextChanged); break; } }
void LayoutQuote::updateText() { String text = computeText(); if (m_text == text) return; m_text = text; LayoutTextFragment* fragment = findFragmentChild(); if (fragment) { fragment->setStyle(mutableStyle()); fragment->setContentString(m_text.impl()); } else { fragment = new LayoutTextFragment(&document(), m_text.impl()); fragment->setStyle(mutableStyle()); addChild(fragment); } }
LayoutText* SimplifiedBackwardsTextIteratorAlgorithm<Strategy>::handleFirstLetter(int& startOffset, int& offsetInNode) { LayoutText* layoutObject = toLayoutText(m_node->layoutObject()); startOffset = (m_node == m_startNode) ? m_startOffset : 0; if (!layoutObject->isTextFragment()) { offsetInNode = 0; return layoutObject; } LayoutTextFragment* fragment = toLayoutTextFragment(layoutObject); int offsetAfterFirstLetter = fragment->start(); if (startOffset >= offsetAfterFirstLetter) { ASSERT(!m_shouldHandleFirstLetter); offsetInNode = offsetAfterFirstLetter; return layoutObject; } if (!m_shouldHandleFirstLetter && offsetAfterFirstLetter < m_offset) { m_shouldHandleFirstLetter = true; offsetInNode = offsetAfterFirstLetter; return layoutObject; } m_shouldHandleFirstLetter = false; offsetInNode = 0; ASSERT(fragment->isRemainingTextLayoutObject()); ASSERT(fragment->firstLetterPseudoElement()); LayoutObject* pseudoElementLayoutObject = fragment->firstLetterPseudoElement()->layoutObject(); ASSERT(pseudoElementLayoutObject); ASSERT(pseudoElementLayoutObject->slowFirstChild()); LayoutText* firstLetterLayoutObject = toLayoutText(pseudoElementLayoutObject->slowFirstChild()); m_offset = firstLetterLayoutObject->caretMaxOffset(); m_offset += collapsedSpaceLength(firstLetterLayoutObject, m_offset); return firstLetterLayoutObject; }
void FirstLetterPseudoElement::attachFirstLetterTextLayoutObjects() { LayoutObject* nextLayoutObject = FirstLetterPseudoElement::firstLetterTextLayoutObject(*this); ASSERT(nextLayoutObject); ASSERT(nextLayoutObject->isText()); // The original string is going to be either a generated content string or a DOM node's // string. We want the original string before it got transformed in case first-letter has // no text-transform or a different text-transform applied to it. String oldText = toLayoutText(nextLayoutObject)->isTextFragment() ? toLayoutTextFragment(nextLayoutObject)->completeText() : toLayoutText(nextLayoutObject)->originalText(); ASSERT(oldText.impl()); ComputedStyle* pseudoStyle = styleForFirstLetter(nextLayoutObject->parent()); layoutObject()->setStyle(pseudoStyle); // FIXME: This would already have been calculated in firstLetterLayoutObject. Can we pass the length through? unsigned length = FirstLetterPseudoElement::firstLetterLength(oldText); // Construct a text fragment for the text after the first letter. // This text fragment might be empty. LayoutTextFragment* remainingText = new LayoutTextFragment(nextLayoutObject->node() ? nextLayoutObject->node() : &nextLayoutObject->document(), oldText.impl(), length, oldText.length() - length); remainingText->setFirstLetterPseudoElement(this); remainingText->setIsRemainingTextLayoutObject(true); remainingText->setStyle(nextLayoutObject->mutableStyle()); if (remainingText->node()) remainingText->node()->setLayoutObject(remainingText); m_remainingTextLayoutObject = remainingText; LayoutObject* nextSibling = layoutObject()->nextSibling(); layoutObject()->parent()->addChild(remainingText, nextSibling); // Construct text fragment for the first letter. LayoutTextFragment* letter = new LayoutTextFragment(&nextLayoutObject->document(), oldText.impl(), 0, length); letter->setFirstLetterPseudoElement(this); letter->setStyle(pseudoStyle); layoutObject()->addChild(letter); nextLayoutObject->destroy(); }