diff options
Diffstat (limited to 'Source/WebCore/rendering/InlineTextBox.cpp')
-rw-r--r-- | Source/WebCore/rendering/InlineTextBox.cpp | 79 |
1 files changed, 52 insertions, 27 deletions
diff --git a/Source/WebCore/rendering/InlineTextBox.cpp b/Source/WebCore/rendering/InlineTextBox.cpp index 3c3e450..b614f0f 100644 --- a/Source/WebCore/rendering/InlineTextBox.cpp +++ b/Source/WebCore/rendering/InlineTextBox.cpp @@ -163,7 +163,7 @@ IntRect InlineTextBox::selectionRect(int tx, int ty, int startPos, int endPos) ePos = len; } - IntRect r = enclosingIntRect(f.selectionRectForText(TextRun(characters, len, textObj->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride), + IntRect r = enclosingIntRect(f.selectionRectForText(TextRun(characters, len, textObj->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride), IntPoint(), selHeight, sPos, ePos)); int logicalWidth = r.width(); @@ -427,6 +427,14 @@ bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi return !rubyText || !rubyText->firstLineBox(); } +enum RotationDirection { Counterclockwise, Clockwise }; + +static inline AffineTransform rotation(const FloatRect& boxRect, RotationDirection clockwise) +{ + return clockwise ? AffineTransform(0, 1, -1, 0, boxRect.x() + boxRect.maxY(), boxRect.maxY() - boxRect.x()) + : AffineTransform(0, -1, 1, 0, boxRect.x() - boxRect.maxY(), boxRect.x() + boxRect.maxY()); +} + void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty) { if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(renderer()) || renderer()->style()->visibility() != VISIBLE || @@ -485,26 +493,22 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty) FloatPoint boxOrigin = locationIncludingFlipping(); boxOrigin.move(tx, ty); FloatRect boxRect(boxOrigin, IntSize(logicalWidth(), logicalHeight())); - FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + styleToUse->fontMetrics().ascent()); - RenderCombineText* combinedText = styleToUse->hasTextCombine() ? toRenderCombineText(textRenderer()) : 0; - bool shouldRotate = !isHorizontal() && (!combinedText || !combinedText->isCombined()); - if (shouldRotate) { - context->save(); - context->translate(boxRect.x(), boxRect.maxY()); - context->rotate(static_cast<float>(deg2rad(90.))); - context->translate(-boxRect.x(), -boxRect.maxY()); - } - - + RenderCombineText* combinedText = styleToUse->hasTextCombine() && textRenderer()->isCombineText() && toRenderCombineText(textRenderer())->isCombined() ? toRenderCombineText(textRenderer()) : 0; + + bool shouldRotate = !isHorizontal() && !combinedText; + if (shouldRotate) + context->concatCTM(rotation(boxRect, Clockwise)); + // Determine whether or not we have composition underlines to draw. bool containsComposition = renderer()->node() && renderer()->frame()->editor()->compositionNode() == renderer()->node(); bool useCustomUnderlines = containsComposition && renderer()->frame()->editor()->compositionUsesCustomUnderlines(); // Set our font. - int d = styleToUse->textDecorationsInEffect(); const Font& font = styleToUse->font(); + FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent()); + if (combinedText) combinedText->adjustTextOrigin(textOrigin, boxRect); @@ -618,7 +622,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty) if (hasHyphen()) adjustCharactersAndLengthForHyphen(charactersWithHyphen, styleToUse, characters, length); - TextRun textRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || styleToUse->visuallyOrdered()); + TextRun textRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride || styleToUse->visuallyOrdered()); int sPos = 0; int ePos = 0; @@ -653,11 +657,21 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty) if (!emphasisMark.isEmpty()) { updateGraphicsContext(context, emphasisMarkColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace()); + + static TextRun objectReplacementCharacterTextRun(&objectReplacementCharacter, 1); + TextRun& emphasisMarkTextRun = combinedText ? objectReplacementCharacterTextRun : textRun; + FloatPoint emphasisMarkTextOrigin = combinedText ? FloatPoint(boxOrigin.x() + boxRect.width() / 2, boxOrigin.y() + font.fontMetrics().ascent()) : textOrigin; + if (combinedText) + context->concatCTM(rotation(boxRect, Clockwise)); + if (!paintSelectedTextSeparately || ePos <= sPos) { // FIXME: Truncate right-to-left text correctly. - paintTextWithShadows(context, font, textRun, emphasisMark, emphasisMarkOffset, 0, length, length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal()); + paintTextWithShadows(context, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, 0, length, length, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal()); } else - paintTextWithShadows(context, font, textRun, emphasisMark, emphasisMarkOffset, ePos, sPos, length, textOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal()); + paintTextWithShadows(context, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, ePos, sPos, length, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal()); + + if (combinedText) + context->concatCTM(rotation(boxRect, Counterclockwise)); } if (textStrokeWidth > 0) @@ -673,16 +687,27 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty) paintTextWithShadows(context, font, textRun, nullAtom, 0, sPos, ePos, length, textOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizontal()); if (!emphasisMark.isEmpty()) { updateGraphicsContext(context, selectionEmphasisMarkColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace()); - paintTextWithShadows(context, font, textRun, emphasisMark, emphasisMarkOffset, sPos, ePos, length, textOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizontal()); + + static TextRun objectReplacementCharacterTextRun(&objectReplacementCharacter, 1); + TextRun& emphasisMarkTextRun = combinedText ? objectReplacementCharacterTextRun : textRun; + FloatPoint emphasisMarkTextOrigin = combinedText ? FloatPoint(boxOrigin.x() + boxRect.width() / 2, boxOrigin.y() + font.fontMetrics().ascent()) : textOrigin; + if (combinedText) + context->concatCTM(rotation(boxRect, Clockwise)); + + paintTextWithShadows(context, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, sPos, ePos, length, emphasisMarkTextOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizontal()); + + if (combinedText) + context->concatCTM(rotation(boxRect, Counterclockwise)); } if (selectionStrokeWidth > 0) context->restore(); } // Paint decorations - if (d != TDNONE && paintInfo.phase != PaintPhaseSelection) { + int textDecorations = styleToUse->textDecorationsInEffect(); + if (textDecorations != TDNONE && paintInfo.phase != PaintPhaseSelection) { updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace()); - paintDecoration(context, boxOrigin, d, textShadow); + paintDecoration(context, boxOrigin, textDecorations, textShadow); } if (paintInfo.phase == PaintPhaseForeground) { @@ -715,7 +740,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty) } if (shouldRotate) - context->restore(); + context->concatCTM(rotation(boxRect, Counterclockwise)); } void InlineTextBox::selectionStartEnd(int& sPos, int& ePos) @@ -772,7 +797,7 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& b int selHeight = selectionHeight(); FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); context->clip(FloatRect(localOrigin, FloatSize(m_logicalWidth, selHeight))); - context->drawHighlightForText(font, TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), + context->drawHighlightForText(font, TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()), localOrigin, selHeight, c, style->colorSpace(), sPos, ePos); context->restore(); @@ -796,7 +821,7 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const F int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop(); int selHeight = selectionHeight(); FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); - context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), + context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()), localOrigin, selHeight, c, style->colorSpace(), sPos, ePos); context->restore(); @@ -958,7 +983,7 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const Floa int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop(); int selHeight = selectionHeight(); FloatPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY); - TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()); + TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()); // FIXME: Convert the document markers to float rects. IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, selHeight, startPosition, endPosition)); @@ -1003,7 +1028,7 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint& int sPos = max(marker.startOffset - m_start, (unsigned)0); int ePos = min(marker.endOffset - m_start, (unsigned)m_len); - TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()); + TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()); // Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates. IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(m_x, selectionTop()), selHeight, sPos, ePos)); @@ -1031,7 +1056,7 @@ void InlineTextBox::computeRectForReplacementMarker(const DocumentMarker& marker int sPos = max(marker.startOffset - m_start, (unsigned)0); int ePos = min(marker.endOffset - m_start, (unsigned)m_len); - TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()); + TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()); IntPoint startPoint = IntPoint(m_x, y); // Compute and store the rect associated with this marker. @@ -1192,7 +1217,7 @@ int InlineTextBox::offsetForPosition(float lineOffset, bool includePartialGlyphs RenderStyle* style = text->style(m_firstLine); const Font* f = &style->font(); int offset = f->offsetForPosition(TextRun(textRenderer()->text()->characters() + m_start, m_len, - textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()), + textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()), lineOffset - logicalLeft(), includePartialGlyphs); if (blockIsInOppositeDirection && (!offset || offset == m_len)) return !offset ? m_len : 0; @@ -1212,7 +1237,7 @@ float InlineTextBox::positionForOffset(int offset) const int from = !isLeftToRightDirection() ? offset - m_start : 0; int to = !isLeftToRightDirection() ? m_len : offset - m_start; // FIXME: Do we need to add rightBearing here? - return f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride), + return f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, expansionBehavior(), !isLeftToRightDirection(), m_dirOverride), IntPoint(logicalLeft(), 0), 0, from, to).maxX(); } |