Chromium Code Reviews| Index: Source/core/rendering/InlineTextBox.cpp |
| diff --git a/Source/core/rendering/InlineTextBox.cpp b/Source/core/rendering/InlineTextBox.cpp |
| index fee393d6e8be5d6c59974f98f8dbd361831c32f4..9c9defb64b03f1ccd55e7055df3da1677db3ba65 100644 |
| --- a/Source/core/rendering/InlineTextBox.cpp |
| +++ b/Source/core/rendering/InlineTextBox.cpp |
| @@ -27,6 +27,8 @@ |
| #include "core/dom/DocumentMarkerController.h" |
| #include "core/dom/RenderedDocumentMarker.h" |
| #include "core/dom/Text.h" |
| +#include "core/editing/CompositionUnderline.h" |
| +#include "core/editing/CompositionUnderlineVisitor.h" |
| #include "core/editing/Editor.h" |
| #include "core/editing/InputMethodController.h" |
| #include "core/frame/LocalFrame.h" |
| @@ -630,13 +632,27 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, |
| combinedText->adjustTextOrigin(textOrigin, boxRect); |
| // 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection |
| - // and composition underlines. |
| + // and composition highlights. |
| if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseTextClip && !isPrinting) { |
| - |
| - if (containsComposition && !useCustomUnderlines) { |
| - paintCompositionBackground(context, boxOrigin, styleToUse, font, |
| - renderer().frame()->inputMethodController().compositionStart(), |
| - renderer().frame()->inputMethodController().compositionEnd()); |
| + if (containsComposition) { |
| + if (useCustomUnderlines) { |
| + // Paint custom background highlights for compositions. |
| + const Vector<CompositionUnderline>& underlines = renderer().frame()->inputMethodController().customCompositionUnderlines(); |
| + CompositionUnderlineVisitor visitor(underlines, start(), end()); |
|
yosin_UTC9
2014/06/05 01:19:00
How about using begin()/end() STL iterator protoco
huangs
2014/06/05 15:40:33
Range-for and auto aren't used in WebKit. Also, e
|
| + const CompositionUnderline* underline; |
| + while (visitor.next(&underline)) { |
| + if (underline->backgroundColor != Color::transparent) { |
| + unsigned paintStart = getUnderlinePaintStart(*underline); |
| + unsigned paintEnd = getUnderlinePaintEnd(*underline); |
| + paintCompositionBackground(context, boxOrigin, styleToUse, font, underline->backgroundColor, paintStart, paintEnd); |
| + } |
| + } |
| + |
| + } else { |
| + paintCompositionBackground(context, boxOrigin, styleToUse, font, Color(225, 221, 85), |
|
yosin_UTC9
2014/06/05 01:19:00
Could you move this hard coded color value to some
huangs
2014/06/05 15:40:33
Done.
"%02X%02X%02X" % (255, 221, 85) == "FFDD55"
|
| + renderer().frame()->inputMethodController().compositionStart(), |
| + renderer().frame()->inputMethodController().compositionEnd()); |
| + } |
| } |
| paintDocumentMarkers(context, boxOrigin, styleToUse, font, true); |
| @@ -762,28 +778,13 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, |
| if (paintInfo.phase == PaintPhaseForeground) { |
| paintDocumentMarkers(context, boxOrigin, styleToUse, font, false); |
| + // Paint custom underlines for compositions. |
| 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; |
| + CompositionUnderlineVisitor visitor(underlines, start(), end()); |
| + const CompositionUnderline* underline; |
| + while (visitor.next(&underline)) { |
| + paintCompositionUnderline(context, boxOrigin, *underline); |
| } |
| } |
| } |
| @@ -869,25 +870,34 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& b |
| context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, sPos, ePos); |
| } |
| -void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font, int startPos, int endPos) |
| +unsigned InlineTextBox::getUnderlinePaintStart(const CompositionUnderline& underline) |
| { |
| - int offset = m_start; |
| - int sPos = max(startPos - offset, 0); |
| - int ePos = min(endPos - offset, (int)m_len); |
| + return max((unsigned)m_start, underline.startOffset); |
| +} |
| +unsigned InlineTextBox::getUnderlinePaintEnd(const CompositionUnderline& underline) |
| +{ |
| + unsigned paintEnd = min(end() + 1, underline.endOffset); // end() points at the last char, not past it. |
| + if (m_truncation != cNoTruncation) |
| + paintEnd = min(paintEnd, (unsigned)m_start + m_truncation); |
| + return paintEnd; |
| +} |
| + |
| +void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font, Color backgroundColor, int startPos, int endPos) |
| +{ |
| + int sPos = max(startPos - m_start, 0); |
| + int ePos = min(endPos - m_start, (int)m_len); |
|
yosin_UTC9
2014/06/05 01:19:00
nit: static_cast<int>(m_len)
huangs
2014/06/05 15:40:33
Done, replaced globally.
|
| if (sPos >= ePos) |
| return; |
| GraphicsContextStateSaver stateSaver(*context); |
| - Color c = Color(225, 221, 85); |
| - |
| - updateGraphicsContext(context, c, c, 0); // Don't draw text at all! |
| + updateGraphicsContext(context, backgroundColor, backgroundColor, 0); // Don't draw text at all! |
| int deltaY = renderer().style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop(); |
| int selHeight = selectionHeight(); |
| FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); |
| - context->drawHighlightForText(font, constructTextRun(style, font), localOrigin, selHeight, c, sPos, ePos); |
| + context->drawHighlightForText(font, constructTextRun(style, font), localOrigin, selHeight, backgroundColor, sPos, ePos); |
| } |
| static StrokeStyle textDecorationStyleToStrokeStyle(TextDecorationStyle decorationStyle) |
| @@ -1366,27 +1376,15 @@ void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const FloatP |
| if (m_truncation == cFullTruncation) |
| return; |
| - float start = 0; // start of line to draw, relative to tx |
| - float width = m_logicalWidth; // how much line to draw |
| - bool useWholeWidth = true; |
| - unsigned paintStart = m_start; |
| - unsigned paintEnd = end() + 1; // end points at the last char, not past it |
| - if (paintStart <= underline.startOffset) { |
| - paintStart = underline.startOffset; |
| - useWholeWidth = false; |
| - start = toRenderText(renderer()).width(m_start, paintStart - m_start, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); |
| - } |
| - if (paintEnd != underline.endOffset) { // end points at the last char, not past it |
| - paintEnd = min(paintEnd, (unsigned)underline.endOffset); |
| - useWholeWidth = false; |
| - } |
| - if (m_truncation != cNoTruncation) { |
| - paintEnd = min(paintEnd, (unsigned)m_start + m_truncation); |
| - useWholeWidth = false; |
| - } |
| - if (!useWholeWidth) { |
| - width = toRenderText(renderer()).width(paintStart, paintEnd - paintStart, textPos() + start, isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); |
| - } |
| + unsigned paintStart = getUnderlinePaintStart(underline); |
| + unsigned paintEnd = getUnderlinePaintEnd(underline); |
| + |
| + // start of line to draw, relative to tx |
| + float start = paintStart == (unsigned)m_start ? 0 : |
| + toRenderText(renderer()).width(m_start, paintStart - m_start, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); |
| + // how much line to draw |
| + float width = (paintStart == (unsigned)m_start && paintEnd == (unsigned)end() + 1) ? m_logicalWidth : |
| + toRenderText(renderer()).width(paintStart, paintEnd - paintStart, textPos() + start, isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle()); |
| // Thick marked text underlines are 2px thick as long as there is room for the 2px line under the baseline. |
| // All other marked text underlines are 1px thick. |