| Index: Source/core/rendering/InlineTextBox.cpp
|
| diff --git a/Source/core/rendering/InlineTextBox.cpp b/Source/core/rendering/InlineTextBox.cpp
|
| index fee393d6e8be5d6c59974f98f8dbd361831c32f4..9cead06b3705b4c8342c28fbb6d0ab3017f710e3 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/CompositionUnderlineIterator.h"
|
| #include "core/editing/Editor.h"
|
| #include "core/editing/InputMethodController.h"
|
| #include "core/frame/LocalFrame.h"
|
| @@ -193,7 +195,7 @@ RenderObject::SelectionState InlineTextBox::selectionState()
|
| LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos)
|
| {
|
| int sPos = max(startPos - m_start, 0);
|
| - int ePos = min(endPos - m_start, (int)m_len);
|
| + int ePos = min(endPos - m_start, static_cast<int>(m_len));
|
|
|
| if (sPos > ePos)
|
| return LayoutRect();
|
| @@ -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();
|
| + CompositionUnderlineIterator it(underlines, start(), end());
|
| + const CompositionUnderline* underline;
|
| + while (it.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, RenderTheme::theme().platformDefaultCompositionBackgroundColor(),
|
| + 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;
|
| + CompositionUnderlineIterator it(underlines, start(), end());
|
| + const CompositionUnderline* underline;
|
| + while (it.next(&underline)) {
|
| + paintCompositionUnderline(context, boxOrigin, *underline);
|
| }
|
| }
|
| }
|
| @@ -807,7 +808,7 @@ void InlineTextBox::selectionStartEnd(int& sPos, int& ePos)
|
| }
|
|
|
| sPos = max(startPos - m_start, 0);
|
| - ePos = min(endPos - m_start, (int)m_len);
|
| + ePos = min(endPos - m_start, static_cast<int>(m_len));
|
| }
|
|
|
| void alignSelectionRectToDevicePixels(FloatRect& rect)
|
| @@ -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(static_cast<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, static_cast<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, static_cast<int>(m_len));
|
| 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)
|
| @@ -1139,7 +1149,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint&
|
|
|
| // 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);
|
| + int fontHeightInt = static_cast<int>(styleToUse->fontMetrics().floatHeight() + 0.5);
|
| if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHeightInt >> 1)))
|
| textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() / 10.f);
|
|
|
| @@ -1224,7 +1234,7 @@ void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& b
|
|
|
| // Determine whether we need to measure text
|
| bool markerSpansWholeBox = true;
|
| - if (m_start <= (int)marker->startOffset())
|
| + if (m_start <= static_cast<int>(marker->startOffset()))
|
| markerSpansWholeBox = false;
|
| if ((end() + 1) != marker->endOffset()) // end points at the last char, not past it
|
| markerSpansWholeBox = false;
|
| @@ -1285,8 +1295,8 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint&
|
| int deltaY = renderer().style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
|
| int selHeight = selectionHeight();
|
|
|
| - int sPos = max(marker->startOffset() - m_start, (unsigned)0);
|
| - int ePos = min(marker->endOffset() - m_start, (unsigned)m_len);
|
| + int sPos = max(marker->startOffset() - m_start, 0U);
|
| + int ePos = min(marker->endOffset() - m_start, static_cast<unsigned>(m_len));
|
| TextRun run = constructTextRun(style, font);
|
|
|
| // Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
|
| @@ -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 == static_cast<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 == static_cast<unsigned>(m_start) && paintEnd == static_cast<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.
|
|
|