| Index: Source/core/rendering/InlineTextBox.cpp
|
| diff --git a/Source/core/rendering/InlineTextBox.cpp b/Source/core/rendering/InlineTextBox.cpp
|
| index eddf89d029d025d0773351a28179902fa7d271b8..a6de48eab8b1679f6d0e4cedd663fc2b73298b69 100644
|
| --- a/Source/core/rendering/InlineTextBox.cpp
|
| +++ b/Source/core/rendering/InlineTextBox.cpp
|
| @@ -60,6 +60,8 @@ struct SameSizeAsInlineTextBox : public InlineBox {
|
| unsigned variables[1];
|
| unsigned short variables2[2];
|
| void* pointers[2];
|
| + float u;
|
| + TextDecorationStyle t;
|
| };
|
|
|
| COMPILE_ASSERT(sizeof(InlineTextBox) == sizeof(SameSizeAsInlineTextBox), InlineTextBox_should_stay_small);
|
| @@ -750,44 +752,16 @@ 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, styleToUse->textDecorationStyle(), 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();
|
| + 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;
|
| - }
|
| - }
|
| + setUnderlineThickness(textDecorationThickness);
|
| + setTextDecoration(styleToUse->textDecorationStyle());
|
| }
|
|
|
| if (shouldRotate)
|
| @@ -911,6 +885,8 @@ static StrokeStyle textDecorationStyleToStrokeStyle(TextDecorationStyle decorati
|
| case TextDecorationStyleWavy:
|
| strokeStyle = WavyStroke;
|
| break;
|
| + case TextDecorationStyleNone:
|
| + break;
|
| }
|
|
|
| return strokeStyle;
|
| @@ -1061,7 +1037,7 @@ static void strokeWavyTextDecoration(GraphicsContext* context, FloatPoint& p1, F
|
| context->strokePath(path);
|
| }
|
|
|
| -void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, TextDecoration deco, TextDecorationStyle decorationStyle, const ShadowList* shadowList)
|
| +void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, TextDecoration deco, TextDecorationStyle decorationStyle, const ShadowList* shadowList, float underlineThickness)
|
| {
|
| GraphicsContextStateSaver stateSaver(*context);
|
|
|
| @@ -1096,10 +1072,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 (!underlineThickness) {
|
| + 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 = underlineThickness;
|
| + }
|
|
|
| context->setStrokeThickness(textDecorationThickness);
|
|
|
| @@ -1111,6 +1092,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint&
|
| case TextDecorationStyleSolid:
|
| case TextDecorationStyleDouble:
|
| case TextDecorationStyleWavy:
|
| + case TextDecorationStyleNone:
|
| break;
|
| }
|
|
|
| @@ -1199,6 +1181,138 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint&
|
| }
|
| }
|
|
|
| +void InlineTextBox::paintDecorationStyle(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom, float underlineThickness)
|
| +{
|
| + 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();
|
| + TextDecorationStyle decorationStyle = styleToUse->textDecorationStyle();
|
| + 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, decorationStyle, textShadow, underlineThickness);
|
| +
|
| + 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 * underlineThickness, TextDecorationStyle * style)
|
| +{
|
| + *underlineThickness = 0;
|
| + if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->visibility() != VISIBLE
|
| + || m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutline || !m_len)
|
| + return;
|
| +
|
| + *underlineThickness = getUnderlineThickness();
|
| + *style = getTextDecorations();
|
| +}
|
| +
|
| static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentMarker::MarkerType markerType)
|
| {
|
| switch (markerType) {
|
|
|