Chromium Code Reviews| Index: Source/core/rendering/InlineTextBox.cpp |
| diff --git a/Source/core/rendering/InlineTextBox.cpp b/Source/core/rendering/InlineTextBox.cpp |
| index dcb093c0379302ef922e0d75d88c12ff06442363..7c7013e851d5d5545588397e4d9b2d4d4c31c5b8 100644 |
| --- a/Source/core/rendering/InlineTextBox.cpp |
| +++ b/Source/core/rendering/InlineTextBox.cpp |
| @@ -60,6 +60,7 @@ struct SameSizeAsInlineTextBox : public InlineBox { |
| unsigned variables[1]; |
| unsigned short variables2[2]; |
| void* pointers[2]; |
| + float u; |
| }; |
| COMPILE_ASSERT(sizeof(InlineTextBox) == sizeof(SameSizeAsInlineTextBox), InlineTextBox_should_stay_small); |
| @@ -750,44 +751,15 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, |
| } |
| } |
| - // Paint decorations |
| + // lets only store decorations style and underline thickness, painting of decoration style will be done later |
| TextDecoration textDecorations = styleToUse->textDecorationsInEffect(); |
| if (textDecorations != TextDecorationNone && paintInfo.phase != PaintPhaseSelection) { |
| - updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth); |
| - if (combinedText) |
| - context->concatCTM(rotation(boxRect, Clockwise)); |
| - paintDecoration(context, boxOrigin, textDecorations, textShadow); |
| - if (combinedText) |
| - context->concatCTM(rotation(boxRect, Counterclockwise)); |
| - } |
| - |
| - if (paintInfo.phase == PaintPhaseForeground) { |
| - paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); |
| - |
| - if (useCustomUnderlines) { |
| - const Vector<CompositionUnderline>& underlines = renderer().frame()->inputMethodController().customCompositionUnderlines(); |
| - size_t numUnderlines = underlines.size(); |
| + float textDecorationThickness = styleToUse->fontMetrics().underlineThickness(); |
|
leviw_travelin_and_unemployed
2014/03/21 20:43:08
Don't copy and paste this block of code. If you ne
|
| + int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5); |
| + if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHeightInt >> 1))) |
| + textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() / 10.f); |
| - for (size_t index = 0; index < numUnderlines; ++index) { |
| - const CompositionUnderline& underline = underlines[index]; |
| - |
| - if (underline.endOffset <= start()) |
| - // underline is completely before this run. This might be an underline that sits |
| - // before the first run we draw, or underlines that were within runs we skipped |
| - // due to truncation. |
| - continue; |
| - |
| - if (underline.startOffset <= end()) { |
| - // underline intersects this run. Paint it. |
| - paintCompositionUnderline(context, boxOrigin, underline); |
| - if (underline.endOffset > end() + 1) |
| - // underline also runs into the next run. Bail now, no more marker advancement. |
| - break; |
| - } else |
| - // underline is completely after this run, bail. A later run will paint it. |
| - break; |
| - } |
| - } |
| + setDecorationThickness(textDecorationThickness); |
| } |
| if (shouldRotate) |
| @@ -1093,7 +1065,7 @@ static void paintAppliedDecoration(GraphicsContext* context, FloatPoint start, f |
| } |
| } |
| -void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, TextDecoration deco, const ShadowList* shadowList) |
| +void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, TextDecoration deco, const ShadowList* shadowList, float decorationThickness) |
| { |
| GraphicsContextStateSaver stateSaver(*context); |
| @@ -1129,10 +1101,15 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& |
| // Using computedFontSize should take care of zoom as well. |
| // Update Underline thickness, in case we have Faulty Font Metrics calculating underline thickness by old method. |
| - float textDecorationThickness = styleToUse->fontMetrics().underlineThickness(); |
| - int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5); |
| - if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHeightInt >> 1))) |
| - textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() / 10.f); |
| + float textDecorationThickness = 0; |
| + if (!decorationThickness) { |
|
leviw_travelin_and_unemployed
2014/03/21 20:43:08
I don't fully understand the case when we have to
|
| + textDecorationThickness = styleToUse->fontMetrics().underlineThickness(); |
| + int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5); |
| + if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHeightInt >> 1))) |
| + textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() / 10.f); |
| + } else { |
| + textDecorationThickness = decorationThickness; |
| + } |
| context->setStrokeThickness(textDecorationThickness); |
| @@ -1188,6 +1165,136 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& |
| } |
| } |
| +void InlineTextBox::paintDecorationStyle(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom, float decorationThickness) |
|
leviw_travelin_and_unemployed
2014/03/21 20:43:08
Whoa... This is a *ton* of code duplication, no?
|
| +{ |
| + if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->visibility() != VISIBLE |
| + || m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutline || !m_len) |
| + return; |
| + |
| + ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines); |
| + |
| + LayoutUnit logicalLeftSide = logicalLeftVisualOverflow(); |
| + LayoutUnit logicalRightSide = logicalRightVisualOverflow(); |
| + LayoutUnit logicalStart = logicalLeftSide + (isHorizontal() ? paintOffset.x() : paintOffset.y()); |
| + LayoutUnit logicalExtent = logicalRightSide - logicalLeftSide; |
| + |
| + LayoutUnit paintEnd = isHorizontal() ? paintInfo.rect.maxX() : paintInfo.rect.maxY(); |
| + LayoutUnit paintStart = isHorizontal() ? paintInfo.rect.x() : paintInfo.rect.y(); |
| + |
| + LayoutPoint adjustedPaintOffset = roundedIntPoint(paintOffset); |
| + bool isPrinting = textRenderer().document().printing(); |
| + |
| + if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart) |
| + return; |
| + |
| + // Determine whether or not we have composition underlines to draw. |
| + bool containsComposition = renderer().node() && renderer().frame()->inputMethodController().compositionNode() == renderer().node(); |
| + bool useCustomUnderlines = containsComposition && renderer().frame()->inputMethodController().compositionUsesCustomUnderlines(); |
| + |
| + // Determine whether or not we're selected. |
| + bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip && selectionState() != RenderObject::SelectionNone; |
| + if (!haveSelection && paintInfo.phase == PaintPhaseSelection) { |
| + // When only painting the selection, don't bother to paint if there is none. |
| + return; |
| + } |
| + |
| + GraphicsContext* context = paintInfo.context; |
| + RenderObject& rendererToUse = renderer(); |
| + RenderStyle* styleToUse = rendererToUse.style(isFirstLineStyle()); |
| + |
| + // Set our font. |
| + const Font& font = styleToUse->font(); |
| + FloatPoint boxOrigin = locationIncludingFlipping(); |
| + // FIXME: Shouldn't these offsets be rounded? |
| + boxOrigin.move(adjustedPaintOffset.x().toFloat(), adjustedPaintOffset.y().toFloat()); |
| + FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), logicalHeight())); |
| + |
| + TextDecoration deco = styleToUse->textDecorationsInEffect(); |
| + const ShadowList* textShadow = (context->printing() || paintInfo.forceBlackText()) ? 0 : styleToUse->textShadow(); |
| + |
| + // Determine the text colors and selection colors. |
| + Color textFillColor; |
| + Color textStrokeColor; |
| + Color emphasisMarkColor; |
| + float textStrokeWidth = styleToUse->textStrokeWidth(); |
| + |
| + if (paintInfo.forceBlackText()) { |
| + textFillColor = Color::black; |
| + textStrokeColor = Color::black; |
| + emphasisMarkColor = Color::black; |
| + } else { |
| + textFillColor = rendererToUse.resolveColor(styleToUse, CSSPropertyWebkitTextFillColor); |
| + |
| + bool forceBackgroundToWhite = false; |
| + if (isPrinting) { |
| + if (styleToUse->printColorAdjust() == PrintColorAdjustEconomy) |
| + forceBackgroundToWhite = true; |
| + if (textRenderer().document().settings() && textRenderer().document().settings()->shouldPrintBackgrounds()) |
| + forceBackgroundToWhite = false; |
| + } |
| + |
| + // Make the text fill color legible against a white background |
| + if (forceBackgroundToWhite) |
| + textFillColor = correctedTextColor(textFillColor, Color::white); |
| + |
| + textStrokeColor = rendererToUse.resolveColor(styleToUse, CSSPropertyWebkitTextStrokeColor); |
| + |
| + // Make the text stroke color legible against a white background |
| + if (forceBackgroundToWhite) |
| + textStrokeColor = correctedTextColor(textStrokeColor, Color::white); |
| + |
| + emphasisMarkColor = rendererToUse.resolveColor(styleToUse, CSSPropertyWebkitTextEmphasisColor); |
| + |
| + // Make the text stroke color legible against a white background |
| + if (forceBackgroundToWhite) |
| + emphasisMarkColor = correctedTextColor(emphasisMarkColor, Color::white); |
| + } |
| + updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth); |
| + paintDecoration(context, boxOrigin, deco, textShadow, decorationThickness); |
| + |
| + if (paintInfo.phase == PaintPhaseForeground) { |
| + paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); |
| + |
| + if (useCustomUnderlines) { |
| + const Vector<CompositionUnderline>& underlines = renderer().frame()->inputMethodController().customCompositionUnderlines(); |
| + size_t numUnderlines = underlines.size(); |
| + |
| + for (size_t index = 0; index < numUnderlines; ++index) { |
| + const CompositionUnderline& underline = underlines[index]; |
| + |
| + if (underline.endOffset <= start()) { |
| + // underline is completely before this run. This might be an underline that sits |
| + // before the first run we draw, or underlines that were within runs we skipped |
| + // due to truncation. |
| + continue; |
| + } |
| + |
| + if (underline.startOffset <= end()) { |
| + // underline intersects this run. Paint it. |
| + paintCompositionUnderline(context, boxOrigin, underline); |
| + if (underline.endOffset > end() + 1) { |
| + // underline also runs into the next run. Bail now, no more marker advancement. |
| + break; |
| + } |
| + } else { |
| + // underline is completely after this run, bail. A later run will paint it. |
| + break; |
| + } |
| + } |
| + } |
| + } |
| +} |
| + |
| +void InlineTextBox::getPaintDecorationSyle(PaintInfo& paintInfo, const LayoutPoint& paintOffset, float * decorationThickness) |
| +{ |
| + *decorationThickness = 0; |
| + if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->visibility() != VISIBLE |
| + || m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutline || !m_len) |
| + return; |
| + |
| + *decorationThickness = getDecorationThickness(); |
| +} |
| + |
| static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentMarker::MarkerType markerType) |
| { |
| switch (markerType) { |