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(); }
void PaintPropertyTreeBuilder::updateMainThreadScrollingReasons( const LayoutObject& object, PaintPropertyTreeBuilderContext& context) { if (context.current.scroll && !object.document().settings()->threadedScrollingEnabled()) context.current.scroll->addMainThreadScrollingReasons( MainThreadScrollingReason::kThreadedScrollingDisabled); if (object.isBackgroundAttachmentFixedObject()) { auto* scrollNode = context.current.scroll; while ( scrollNode && !scrollNode->hasMainThreadScrollingReasons( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects)) { scrollNode->addMainThreadScrollingReasons( MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); scrollNode = scrollNode->parent(); } } }
// static TextPainter::Style TextPainter::textPaintingStyle(LayoutObject& layoutObject, const ComputedStyle& style, bool usesTextAsClip, bool isPrinting) { TextPainter::Style textStyle; if (usesTextAsClip) { // When we use the text as a clip, we only care about the alpha, thus we make all the colors black. textStyle.currentColor = Color::black; textStyle.fillColor = Color::black; textStyle.strokeColor = Color::black; textStyle.emphasisMarkColor = Color::black; textStyle.strokeWidth = style.textStrokeWidth(); textStyle.shadow = 0; } else { textStyle.currentColor = style.visitedDependentColor(CSSPropertyColor); textStyle.fillColor = layoutObject.resolveColor(style, CSSPropertyWebkitTextFillColor); textStyle.strokeColor = layoutObject.resolveColor(style, CSSPropertyWebkitTextStrokeColor); textStyle.emphasisMarkColor = layoutObject.resolveColor(style, CSSPropertyWebkitTextEmphasisColor); textStyle.strokeWidth = style.textStrokeWidth(); textStyle.shadow = style.textShadow(); // Adjust text color when printing with a white background. ASSERT(layoutObject.document().printing() == isPrinting); bool forceBackgroundToWhite = BoxPainter::shouldForceWhiteBackgroundForPrintEconomy(style, layoutObject.document()); if (forceBackgroundToWhite) { textStyle.fillColor = textColorForWhiteBackground(textStyle.fillColor); textStyle.strokeColor = textColorForWhiteBackground(textStyle.strokeColor); textStyle.emphasisMarkColor = textColorForWhiteBackground(textStyle.emphasisMarkColor); } // Text shadows are disabled when printing. http://crbug.com/258321 if (isPrinting) textStyle.shadow = 0; } return textStyle; }
void writeResources(TextStream& ts, const LayoutObject& object, int indent) { const ComputedStyle& style = object.styleRef(); const SVGComputedStyle& svgStyle = style.svgStyle(); // FIXME: We want to use SVGResourcesCache to determine which resources are present, instead of quering the resource <-> id cache. // For now leave the DRT output as is, but later on we should change this so cycles are properly ignored in the DRT output. LayoutObject& layoutObject = const_cast<LayoutObject&>(object); if (!svgStyle.maskerResource().isEmpty()) { if (LayoutSVGResourceMasker* masker = getLayoutSVGResourceById<LayoutSVGResourceMasker>(object.document(), svgStyle.maskerResource())) { writeIndent(ts, indent); ts << " "; writeNameAndQuotedValue(ts, "masker", svgStyle.maskerResource()); ts << " "; writeStandardPrefix(ts, *masker, 0); ts << " " << masker->resourceBoundingBox(&layoutObject) << "\n"; } } if (!svgStyle.clipperResource().isEmpty()) { if (LayoutSVGResourceClipper* clipper = getLayoutSVGResourceById<LayoutSVGResourceClipper>(object.document(), svgStyle.clipperResource())) { writeIndent(ts, indent); ts << " "; writeNameAndQuotedValue(ts, "clipPath", svgStyle.clipperResource()); ts << " "; writeStandardPrefix(ts, *clipper, 0); ts << " " << clipper->resourceBoundingBox(&layoutObject) << "\n"; } } if (!svgStyle.filterResource().isEmpty()) { if (LayoutSVGResourceFilter* filter = getLayoutSVGResourceById<LayoutSVGResourceFilter>(object.document(), svgStyle.filterResource())) { writeIndent(ts, indent); ts << " "; writeNameAndQuotedValue(ts, "filter", svgStyle.filterResource()); ts << " "; writeStandardPrefix(ts, *filter, 0); ts << " " << filter->resourceBoundingBox(&layoutObject) << "\n"; } } }