Index: Source/core/rendering/InlineTextBox.cpp |
diff --git a/Source/core/rendering/InlineTextBox.cpp b/Source/core/rendering/InlineTextBox.cpp |
index dcb093c0379302ef922e0d75d88c12ff06442363..766de5c3e6db6002325761dd33b0b80aaf0a0080 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); |
@@ -464,13 +465,11 @@ bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi |
return !rubyText || !rubyText->firstLineBox(); |
} |
-void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/) |
+bool InlineTextBox::isLogicalStartEndCorrect(PaintInfo& paintInfo, const LayoutPoint& paintOffset) |
{ |
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); |
+ return false; |
LayoutUnit logicalLeftSide = logicalLeftVisualOverflow(); |
LayoutUnit logicalRightSide = logicalRightVisualOverflow(); |
@@ -480,19 +479,31 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, |
LayoutUnit paintEnd = isHorizontal() ? paintInfo.rect.maxX() : paintInfo.rect.maxY(); |
LayoutUnit paintStart = isHorizontal() ? paintInfo.rect.x() : paintInfo.rect.y(); |
- LayoutPoint adjustedPaintOffset = roundedIntPoint(paintOffset); |
- |
if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart) |
- return; |
+ return false; |
bool isPrinting = textRenderer().document().printing(); |
// Determine whether or not we're selected. |
bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip && selectionState() != RenderObject::SelectionNone; |
- if (!haveSelection && paintInfo.phase == PaintPhaseSelection) |
+ if (!haveSelection && paintInfo.phase == PaintPhaseSelection) { |
// When only painting the selection, don't bother to paint if there is none. |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/) |
+{ |
+ ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines); |
+ |
+ if (!isLogicalStartEndCorrect(paintInfo, paintOffset)) |
return; |
+ LayoutPoint adjustedPaintOffset = roundedIntPoint(paintOffset); |
+ bool isPrinting = textRenderer().document().printing(); |
+ bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip && selectionState() != RenderObject::SelectionNone; |
+ |
if (m_truncation != cNoTruncation) { |
if (renderer().containingBlock()->style()->isLeftToRightDirection() != isLeftToRightDirection()) { |
// Make the visible fragment of text hug the edge closest to the rest of the run by moving the origin |
@@ -750,44 +761,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)); |
- } |
+ 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); |
- 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; |
- } |
- } |
+ setDecorationThickness(textDecorationThickness); |
} |
if (shouldRotate) |
@@ -1093,7 +1075,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 +1111,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) { |
+ 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 +1175,72 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& |
} |
} |
+void InlineTextBox::paintDecorationStyle(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom, float decorationThickness) |
+{ |
+ ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines); |
+ |
+ if (!isLogicalStartEndCorrect(paintInfo, paintOffset)) |
+ return; |
+ |
+ LayoutPoint adjustedPaintOffset = roundedIntPoint(paintOffset); |
+ GraphicsContext* context = paintInfo.context; |
+ RenderObject& rendererToUse = renderer(); |
+ RenderStyle* styleToUse = rendererToUse.style(isFirstLineStyle()); |
+ |
+ FloatPoint boxOrigin = locationIncludingFlipping(); |
+ boxOrigin.move(adjustedPaintOffset.x().toFloat(), adjustedPaintOffset.y().toFloat()); |
+ |
+ TextDecoration deco = styleToUse->textDecorationsInEffect(); |
+ const ShadowList* textShadow = (context->printing() || paintInfo.forceBlackText()) ? 0 : styleToUse->textShadow(); |
+ |
+ paintDecoration(context, boxOrigin, deco, textShadow, decorationThickness); |
+ if (paintInfo.phase == PaintPhaseForeground) { |
+ const Font& font = styleToUse->font(); |
+ bool containsComposition = renderer().node() && renderer().frame()->inputMethodController().compositionNode() == renderer().node(); |
+ bool useCustomUnderlines = containsComposition && renderer().frame()->inputMethodController().compositionUsesCustomUnderlines(); |
+ |
+ 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) { |