ComputedStyle* FirstLetterPseudoElement::styleForFirstLetter(LayoutObject* layoutObjectContainer) { ASSERT(layoutObjectContainer); LayoutObject* styleContainer = parentOrShadowHostElement()->layoutObject(); ASSERT(styleContainer); // We always force the pseudo style to recompute as the first-letter style // computed by the style container may not have taken the layoutObjects styles // into account. styleContainer->mutableStyle()->removeCachedPseudoStyle(FIRST_LETTER); ComputedStyle* pseudoStyle = styleContainer->getCachedPseudoStyle(FIRST_LETTER, layoutObjectContainer->firstLineStyle()); ASSERT(pseudoStyle); return pseudoStyle; }
TextPainter::Style TextPainter::selectionPaintingStyle(LayoutObject& layoutObject, bool haveSelection, bool usesTextAsClip, bool isPrinting, const TextPainter::Style& textStyle) { TextPainter::Style selectionStyle = textStyle; if (haveSelection) { if (!usesTextAsClip) { selectionStyle.fillColor = layoutObject.selectionForegroundColor(); selectionStyle.emphasisMarkColor = layoutObject.selectionEmphasisMarkColor(); } if (const ComputedStyle* pseudoStyle = layoutObject.getCachedPseudoStyle(SELECTION)) { selectionStyle.strokeColor = usesTextAsClip ? Color::black : layoutObject.resolveColor(*pseudoStyle, CSSPropertyWebkitTextStrokeColor); selectionStyle.strokeWidth = pseudoStyle->textStrokeWidth(); selectionStyle.shadow = usesTextAsClip ? 0 : pseudoStyle->textShadow(); } // Text shadows are disabled when printing. http://crbug.com/258321 if (isPrinting) selectionStyle.shadow = 0; } return selectionStyle; }
void SVGInlineTextBoxPainter::paintTextFragments(const PaintInfo& paintInfo, LayoutObject& parentLayoutObject) { const ComputedStyle& style = parentLayoutObject.styleRef(); const SVGComputedStyle& svgStyle = style.svgStyle(); bool hasFill = svgStyle.hasFill(); bool hasVisibleStroke = svgStyle.hasVisibleStroke(); const ComputedStyle* selectionStyle = &style; bool shouldPaintSelection = this->shouldPaintSelection(); if (shouldPaintSelection) { selectionStyle = parentLayoutObject.getCachedPseudoStyle(SELECTION); if (selectionStyle) { const SVGComputedStyle& svgSelectionStyle = selectionStyle->svgStyle(); if (!hasFill) hasFill = svgSelectionStyle.hasFill(); if (!hasVisibleStroke) hasVisibleStroke = svgSelectionStyle.hasVisibleStroke(); } else { selectionStyle = &style; } } if (paintInfo.isRenderingClipPathAsMaskImage()) { hasFill = true; hasVisibleStroke = false; } AffineTransform fragmentTransform; unsigned textFragmentsSize = m_svgInlineTextBox.textFragments().size(); for (unsigned i = 0; i < textFragmentsSize; ++i) { SVGTextFragment& fragment = m_svgInlineTextBox.textFragments().at(i); GraphicsContextStateSaver stateSaver(*paintInfo.context, false); fragment.buildFragmentTransform(fragmentTransform); if (!fragmentTransform.isIdentity()) { stateSaver.save(); paintInfo.context->concatCTM(fragmentTransform); } // Spec: All text decorations except line-through should be drawn before the text is filled and stroked; thus, the text is rendered on top of these decorations. unsigned decorations = style.textDecorationsInEffect(); if (decorations & TextDecorationUnderline) paintDecoration(paintInfo, TextDecorationUnderline, fragment); if (decorations & TextDecorationOverline) paintDecoration(paintInfo, TextDecorationOverline, fragment); for (int i = 0; i < 3; i++) { switch (svgStyle.paintOrderType(i)) { case PT_FILL: if (hasFill) paintText(paintInfo, style, *selectionStyle, fragment, ApplyToFillMode, shouldPaintSelection); break; case PT_STROKE: if (hasVisibleStroke) paintText(paintInfo, style, *selectionStyle, fragment, ApplyToStrokeMode, shouldPaintSelection); break; case PT_MARKERS: // Markers don't apply to text break; default: ASSERT_NOT_REACHED(); break; } } // Spec: Line-through should be drawn after the text is filled and stroked; thus, the line-through is rendered on top of the text. if (decorations & TextDecorationLineThrough) paintDecoration(paintInfo, TextDecorationLineThrough, fragment); } }