Changeset 193929 in webkit


Ignore:
Timestamp:
Dec 10, 2015, 3:30:41 PM (10 years ago)
Author:
Alan Bujtas
Message:

TextPainter: Add support for painting multiple text runs.
https://bugs.webkit.org/show_bug.cgi?id=152148

Reviewed by Simon Fraser.

This is in preparation for adding simple line layout as a client.

No change in functionality.

  • rendering/InlineTextBox.cpp:

(WebCore::drawSkipInkUnderline): Decouple underline skipping intersection calculation and text painter.
(WebCore::InlineTextBox::paint):
(WebCore::InlineTextBox::paintDecoration):

  • rendering/InlineTextBox.h:
  • rendering/TextPainter.cpp:

(WebCore::TextPainter::TextPainter):
(WebCore::TextPainter::paintTextWithShadows):
(WebCore::TextPainter::paintTextAndEmphasisMarksIfNeeded):
(WebCore::TextPainter::paintText):
(WebCore::TextPainter::dashesForIntersectionsWithRect): Deleted.

  • rendering/TextPainter.h:

(WebCore::TextPainter::setTextPaintStyle):
(WebCore::TextPainter::setSelectionPaintStyle):
(WebCore::TextPainter::setIsHorizontal):
(WebCore::TextPainter::setFont):
(WebCore::TextPainter::addEmphasis):
(WebCore::TextPainter::addTextShadow):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r193922 r193929  
     12015-12-10  Zalan Bujtas  <zalan@apple.com>
     2
     3        TextPainter: Add support for painting multiple text runs.
     4        https://bugs.webkit.org/show_bug.cgi?id=152148
     5
     6        Reviewed by Simon Fraser.
     7
     8        This is in preparation for adding simple line layout as a client.
     9
     10        No change in functionality.
     11
     12        * rendering/InlineTextBox.cpp:
     13        (WebCore::drawSkipInkUnderline): Decouple underline skipping intersection calculation and text painter.
     14        (WebCore::InlineTextBox::paint):
     15        (WebCore::InlineTextBox::paintDecoration):
     16        * rendering/InlineTextBox.h:
     17        * rendering/TextPainter.cpp:
     18        (WebCore::TextPainter::TextPainter):
     19        (WebCore::TextPainter::paintTextWithShadows):
     20        (WebCore::TextPainter::paintTextAndEmphasisMarksIfNeeded):
     21        (WebCore::TextPainter::paintText):
     22        (WebCore::TextPainter::dashesForIntersectionsWithRect): Deleted.
     23        * rendering/TextPainter.h:
     24        (WebCore::TextPainter::setTextPaintStyle):
     25        (WebCore::TextPainter::setSelectionPaintStyle):
     26        (WebCore::TextPainter::setIsHorizontal):
     27        (WebCore::TextPainter::setFont):
     28        (WebCore::TextPainter::addEmphasis):
     29        (WebCore::TextPainter::addTextShadow):
     30
    1312015-12-10  Enrica Casucci  <enrica@apple.com>
    232
  • trunk/Source/WebCore/rendering/InlineTextBox.cpp

    r193857 r193929  
    120120}
    121121
    122 static void drawSkipInkUnderline(TextPainter& textPainter, GraphicsContext& context, FloatPoint localOrigin, float underlineOffset, float width, bool isPrinting, bool doubleLines)
     122static void drawSkipInkUnderline(GraphicsContext& context, const FontCascade& font, const TextRun& textRun, const FloatPoint& textOrigin, const FloatPoint& localOrigin,
     123    float underlineOffset, float width, bool isPrinting, bool doubleLines)
    123124{
    124125    FloatPoint adjustedLocalOrigin = localOrigin;
    125126    adjustedLocalOrigin.move(0, underlineOffset);
    126127    FloatRect underlineBoundingBox = context.computeLineBoundsForText(adjustedLocalOrigin, width, isPrinting);
    127     DashArray intersections = textPainter.dashesForIntersectionsWithRect(underlineBoundingBox);
     128    DashArray intersections = font.dashesForIntersectionsWithRect(textRun, textOrigin, underlineBoundingBox);
    128129    DashArray a = translateIntersectionPointsToSkipInkBoundaries(intersections, underlineBoundingBox.height(), width);
    129 
    130130    ASSERT(!(a.size() % 2));
    131131    context.drawLinesForText(adjustedLocalOrigin, a, isPrinting, doubleLines);
     
    613613        textOrigin.setX(roundToDevicePixel(LayoutUnit(textOrigin.x()), renderer().document().deviceScaleFactor()));
    614614
    615     TextPainter textPainter(context, paintSelectedTextOnly, paintSelectedTextSeparately, font, selectionStart, selectionEnd, length, emphasisMark, combinedText, textRun, boxRect, textOrigin, emphasisMarkOffset, textShadow, selectionShadow, isHorizontal(), textPaintStyle, selectionPaintStyle);
    616     textPainter.paintText();
     615    TextPainter textPainter(context);
     616    textPainter.setFont(font);
     617    textPainter.setTextPaintStyle(textPaintStyle);
     618    textPainter.setSelectionPaintStyle(selectionPaintStyle);
     619    textPainter.setIsHorizontal(isHorizontal());
     620    textPainter.addTextShadow(textShadow, selectionShadow);
     621    textPainter.addEmphasis(emphasisMark, emphasisMarkOffset, combinedText);
     622
     623    textPainter.paintText(textRun, length, boxRect, textOrigin, selectionStart, selectionEnd, paintSelectedTextOnly, paintSelectedTextSeparately);
    617624
    618625    // Paint decorations
     
    622629        if (combinedText)
    623630            context.concatCTM(rotation(boxRect, Clockwise));
    624         paintDecoration(context, boxOrigin, textDecorations, textShadow, textPainter);
     631        paintDecoration(context, font, textRun, textOrigin, boxOrigin, textDecorations, textShadow);
    625632        if (combinedText)
    626633            context.concatCTM(rotation(boxRect, Counterclockwise));
     
    895902}
    896903
    897 void InlineTextBox::paintDecoration(GraphicsContext& context, const FloatPoint& boxOrigin, TextDecoration decoration, const ShadowData* shadow, TextPainter& textPainter)
     904void InlineTextBox::paintDecoration(GraphicsContext& context, const FontCascade& font, const TextRun& textRun, const FloatPoint& textOrigin, const FloatPoint& boxOrigin,
     905    TextDecoration decoration, const ShadowData* shadow)
    898906{
    899907#if !ENABLE(CSS3_TEXT_DECORATION_SKIP_INK)
    900     UNUSED_PARAM(textPainter);
     908    UNUSED_PARAM(font);
     909    UNUSED_PARAM(textRun);
     910    UNUSED_PARAM(textOrigin);
    901911#endif
    902 
    903912    if (m_truncation == cFullTruncation)
    904913        return;
     
    986995#if ENABLE(CSS3_TEXT_DECORATION_SKIP_INK)
    987996                if ((lineStyle.textDecorationSkip() == TextDecorationSkipInk || lineStyle.textDecorationSkip() == TextDecorationSkipAuto) && isHorizontal()) {
    988                     if (!context.paintingDisabled()) {
    989                         drawSkipInkUnderline(textPainter, context, localOrigin, underlineOffset, width, isPrinting, underlineStyle == TextDecorationStyleDouble);
    990                     }
     997                    if (!context.paintingDisabled())
     998                        drawSkipInkUnderline(context, font, textRun, textOrigin, localOrigin, underlineOffset, width, isPrinting, underlineStyle == TextDecorationStyleDouble);
    991999                } else
    9921000                    // FIXME: Need to support text-decoration-skip: none.
     
    10091017                if ((lineStyle.textDecorationSkip() == TextDecorationSkipInk || lineStyle.textDecorationSkip() == TextDecorationSkipAuto) && isHorizontal()) {
    10101018                    if (!context.paintingDisabled())
    1011                         drawSkipInkUnderline(textPainter, context, localOrigin, 0, width, isPrinting, overlineStyle == TextDecorationStyleDouble);
     1019                        drawSkipInkUnderline(context, font, textRun, textOrigin, localOrigin, 0, width, isPrinting, overlineStyle == TextDecorationStyleDouble);
    10121020                } else
    10131021                    // FIXME: Need to support text-decoration-skip: none.
  • trunk/Source/WebCore/rendering/InlineTextBox.h

    r190363 r193929  
    160160
    161161private:
    162     void paintDecoration(GraphicsContext&, const FloatPoint& boxOrigin, TextDecoration, const ShadowData*, TextPainter&);
     162    void paintDecoration(GraphicsContext&, const FontCascade&, const TextRun&, const FloatPoint& textOrigin, const FloatPoint& boxOrigin, TextDecoration, const ShadowData*);
    163163    void paintSelection(GraphicsContext&, const FloatPoint& boxOrigin, const RenderStyle&, const FontCascade&, Color textColor);
    164164    void paintDocumentMarker(GraphicsContext&, const FloatPoint& boxOrigin, RenderedDocumentMarker&, const RenderStyle&, const FontCascade&, bool grammar);
  • trunk/Source/WebCore/rendering/TextPainter.cpp

    r193891 r193929  
    2727#include "InlineTextBox.h"
    2828#include "RenderCombineText.h"
    29 #include "TextPaintStyle.h"
    3029#include <wtf/NeverDestroyed.h>
    3130
     
    8079}
    8180
    82 TextPainter::TextPainter(GraphicsContext& context, bool paintSelectedTextOnly, bool paintSelectedTextSeparately, const FontCascade& font, int selectionStart,
    83     int selectionEnd, int length, const AtomicString& emphasisMark, RenderCombineText* combinedText, TextRun& textRun, FloatRect& boxRect,
    84     FloatPoint& textOrigin, int emphasisMarkOffset, const ShadowData* textShadow, const ShadowData* selectionShadow, bool textBoxIsHorizontal,
    85     TextPaintStyle& textPaintStyle, TextPaintStyle& selectionPaintStyle)
     81TextPainter::TextPainter(GraphicsContext& context)
    8682    : m_context(context)
    87     , m_textPaintStyle(textPaintStyle)
    88     , m_selectionPaintStyle(selectionPaintStyle)
    89     , m_textShadow(textShadow)
    90     , m_selectionShadow(selectionShadow)
    91     , m_paintSelectedTextOnly(paintSelectedTextOnly)
    92     , m_paintSelectedTextSeparately(paintSelectedTextSeparately)
    93     , m_font(font)
    94     , m_selectionStart(selectionStart)
    95     , m_selectionEnd(selectionEnd)
    96     , m_length(length)
    97     , m_emphasisMark(emphasisMark)
    98     , m_combinedText(combinedText)
    99     , m_textRun(textRun)
    100     , m_boxRect(boxRect)
    101     , m_textOrigin(textOrigin)
    102     , m_emphasisMarkOffset(emphasisMarkOffset)
    103     , m_textBoxIsHorizontal(textBoxIsHorizontal)
    10483{
    10584}
     
    11594}
    11695
    117 void TextPainter::paintTextWithShadows(const ShadowData* shadow, const FontCascade& font, const TextRun& textRun, const AtomicString& emphasisMark,
    118     int emphasisMarkOffset, int startOffset, int endOffset, const FloatPoint& textOrigin, bool stroked)
     96void TextPainter::paintTextWithShadows(const ShadowData* shadow, const FontCascade& font, const TextRun& textRun, const FloatRect& boxRect, const FloatPoint& textOrigin,
     97    int startOffset, int endOffset, const AtomicString& emphasisMark, int emphasisMarkOffset, bool stroked)
    11998{
    12099    if (!shadow) {
     
    129108        m_context.setFillColor(Color::black);
    130109    while (shadow) {
    131         ShadowApplier shadowApplier(m_context, shadow, m_boxRect, lastShadowIterationShouldDrawText, opaque, m_textBoxIsHorizontal ? Horizontal : Vertical);
     110        ShadowApplier shadowApplier(m_context, shadow, boxRect, lastShadowIterationShouldDrawText, opaque, m_textBoxIsHorizontal ? Horizontal : Vertical);
    132111        if (!shadowApplier.nothingToDraw())
    133112            drawTextOrEmphasisMarks(font, textRun, emphasisMark, emphasisMarkOffset, textOrigin + shadowApplier.extraOffset(), startOffset, endOffset);
     
    142121}
    143122
    144 void TextPainter::paintTextAndEmphasisMarksIfNeeded(int startOffset, int endOffset, const TextPaintStyle& paintStyle, const ShadowData* shadow)
     123void TextPainter::paintTextAndEmphasisMarksIfNeeded(const TextRun& textRun, const FloatRect& boxRect, const FloatPoint& textOrigin, int startOffset, int endOffset,
     124    const TextPaintStyle& paintStyle, const ShadowData* shadow)
    145125{
    146126    // FIXME: Truncate right-to-left text correctly.
    147     paintTextWithShadows(shadow, m_font, m_textRun, nullAtom, 0, startOffset, endOffset, m_textOrigin, paintStyle.strokeWidth > 0);
     127    paintTextWithShadows(shadow, *m_font, textRun, boxRect, textOrigin, startOffset, endOffset, nullAtom, 0, paintStyle.strokeWidth > 0);
    148128
    149129    if (m_emphasisMark.isEmpty())
    150130        return;
    151131
    152     FloatPoint boxOrigin = m_boxRect.location();
     132    FloatPoint boxOrigin = boxRect.location();
    153133    updateGraphicsContext(m_context, paintStyle, UseEmphasisMarkColor);
    154134    static NeverDestroyed<TextRun> objectReplacementCharacterTextRun(StringView(&objectReplacementCharacter, 1));
    155     TextRun& emphasisMarkTextRun = m_combinedText ? objectReplacementCharacterTextRun.get() : m_textRun;
    156     FloatPoint emphasisMarkTextOrigin = m_combinedText ? FloatPoint(boxOrigin.x() + m_boxRect.width() / 2, boxOrigin.y() + m_font.fontMetrics().ascent()) : m_textOrigin;
     135    const TextRun& emphasisMarkTextRun = m_combinedText ? objectReplacementCharacterTextRun.get() : textRun;
     136    FloatPoint emphasisMarkTextOrigin = m_combinedText ? FloatPoint(boxOrigin.x() + boxRect.width() / 2, boxOrigin.y() + m_font->fontMetrics().ascent()) : textOrigin;
    157137    if (m_combinedText)
    158         m_context.concatCTM(rotation(m_boxRect, Clockwise));
     138        m_context.concatCTM(rotation(boxRect, Clockwise));
    159139
    160140    // FIXME: Truncate right-to-left text correctly.
    161     paintTextWithShadows(shadow, m_combinedText ? m_combinedText->originalFont() : m_font, emphasisMarkTextRun, m_emphasisMark, m_emphasisMarkOffset, startOffset, endOffset, emphasisMarkTextOrigin, paintStyle.strokeWidth > 0);
     141    paintTextWithShadows(shadow, m_combinedText ? m_combinedText->originalFont() : *m_font, emphasisMarkTextRun, boxRect, emphasisMarkTextOrigin, startOffset, endOffset,
     142        m_emphasisMark, m_emphasisMarkOffset, paintStyle.strokeWidth > 0);
    162143
    163144    if (m_combinedText)
    164         m_context.concatCTM(rotation(m_boxRect, Counterclockwise));
     145        m_context.concatCTM(rotation(boxRect, Counterclockwise));
    165146}
    166147   
    167 void TextPainter::paintText()
     148void TextPainter::paintText(const TextRun& textRun, int length, const FloatRect& boxRect, const FloatPoint& textOrigin, int selectionStart, int selectionEnd,
     149    bool paintSelectedTextOnly, bool paintSelectedTextSeparately)
    168150{
    169     if (!m_paintSelectedTextOnly) {
     151    ASSERT(m_font);
     152    if (!paintSelectedTextOnly) {
    170153        // For stroked painting, we have to change the text drawing mode. It's probably dangerous to leave that mutated as a side
    171154        // effect, so only when we know we're stroking, do a save/restore.
    172155        GraphicsContextStateSaver stateSaver(m_context, m_textPaintStyle.strokeWidth > 0);
    173156        updateGraphicsContext(m_context, m_textPaintStyle);
    174         if (m_paintSelectedTextSeparately) {
     157        if (paintSelectedTextSeparately) {
    175158            // Paint the before and after selection parts.
    176             if (m_selectionStart > 0)
    177                 paintTextAndEmphasisMarksIfNeeded(0, m_selectionStart, m_textPaintStyle, m_textShadow);
    178             if (m_selectionEnd < m_length)
    179                 paintTextAndEmphasisMarksIfNeeded(m_selectionEnd, m_length, m_textPaintStyle, m_textShadow);
     159            if (selectionStart > 0)
     160                paintTextAndEmphasisMarksIfNeeded(textRun, boxRect, textOrigin, 0, selectionStart, m_textPaintStyle, m_textShadow);
     161            if (selectionEnd < length)
     162                paintTextAndEmphasisMarksIfNeeded(textRun, boxRect, textOrigin, selectionEnd, length, m_textPaintStyle, m_textShadow);
    180163        } else
    181             paintTextAndEmphasisMarksIfNeeded(0, m_length, m_textPaintStyle, m_textShadow);
     164            paintTextAndEmphasisMarksIfNeeded(textRun, boxRect, textOrigin, 0, length, m_textPaintStyle, m_textShadow);
    182165    }
    183166
    184167    // Paint only the text that is selected.
    185     if ((m_paintSelectedTextOnly || m_paintSelectedTextSeparately) && m_selectionStart < m_selectionEnd) {
     168    if ((paintSelectedTextOnly || paintSelectedTextSeparately) && selectionStart < selectionEnd) {
    186169        GraphicsContextStateSaver stateSaver(m_context, m_selectionPaintStyle.strokeWidth > 0);
    187170        updateGraphicsContext(m_context, m_selectionPaintStyle);
    188         paintTextAndEmphasisMarksIfNeeded(m_selectionStart, m_selectionEnd, m_selectionPaintStyle, m_selectionShadow);
     171        paintTextAndEmphasisMarksIfNeeded(textRun, boxRect, textOrigin, selectionStart, selectionEnd, m_selectionPaintStyle, m_selectionShadow);
    189172    }
    190173}
    191174
    192 #if ENABLE(CSS3_TEXT_DECORATION_SKIP_INK)
    193 DashArray TextPainter::dashesForIntersectionsWithRect(const FloatRect& lineExtents)
    194 {
    195     return m_font.dashesForIntersectionsWithRect(m_textRun, m_textOrigin, lineExtents);
    196 }
    197 #endif
    198 
    199175} // namespace WebCore
  • trunk/Source/WebCore/rendering/TextPainter.h

    r193891 r193929  
    2525
    2626#include "AffineTransform.h"
    27 #include "DashArray.h"
    2827#include "RenderText.h"
    2928#include "TextFlags.h"
     29#include "TextPaintStyle.h"
    3030
    3131namespace WebCore {
     
    4545class TextPainter {
    4646public:
    47     TextPainter(GraphicsContext&, bool paintSelectedTextOnly, bool paintSelectedTextSeparately, const FontCascade&,
    48         int selectionStart, int selectionEnd, int length, const AtomicString& emphasisMark, RenderCombineText*,
    49         TextRun&, FloatRect& boxRect, FloatPoint& textOrigin, int emphasisMarkOffset, const ShadowData* textShadow, const ShadowData* selectionShadow,
    50         bool textBoxIsHorizontal, TextPaintStyle& nonSelectionPaintStyle, TextPaintStyle& selectionPaintStyle);
     47    TextPainter(GraphicsContext&);
    5148   
    52     void paintText();
    53 #if ENABLE(CSS3_TEXT_DECORATION_SKIP_INK)
    54     DashArray dashesForIntersectionsWithRect(const FloatRect& lineExtents);
    55 #endif
     49    void setTextPaintStyle(const TextPaintStyle& textPaintStyle) { m_textPaintStyle = textPaintStyle; }
     50    void setSelectionPaintStyle(const TextPaintStyle& selectionPaintStyle) { m_selectionPaintStyle = selectionPaintStyle; }
     51    void setIsHorizontal(bool isHorizontal) { m_textBoxIsHorizontal = isHorizontal; }
     52    void setFont(const FontCascade& font) { m_font = &font; }
     53    void addEmphasis(const AtomicString& emphasisMark, int emphasisMarkOffset, RenderCombineText*);
     54    void addTextShadow(const ShadowData* textShadow, const ShadowData* selectionShadow);
     55
     56    void paintText(const TextRun&, int length, const FloatRect& boxRect, const FloatPoint& textOrigin,
     57        int selectionStart, int selectionEnd, bool paintSelectedTextOnly, bool paintSelectedTextSeparately);
    5658
    5759private:
    5860    void drawTextOrEmphasisMarks(const FontCascade&, const TextRun&, const AtomicString& emphasisMark, int emphasisMarkOffset,
    5961        const FloatPoint& textOrigin, int startOffset, int endOffset);
    60     void paintTextWithShadows(const ShadowData*, const FontCascade&, const TextRun&, const AtomicString& emphasisMark, int emphasisMarkOffset,
    61         int startOffset, int endOffset, const FloatPoint& textOrigin, bool stroked);
    62     void paintTextAndEmphasisMarksIfNeeded(int startOffset, int endOffset, const TextPaintStyle&, const ShadowData*);
     62    void paintTextWithShadows(const ShadowData*, const FontCascade&, const TextRun&, const FloatRect& boxRect, const FloatPoint& textOrigin,
     63        int startOffset, int endOffset, const AtomicString& emphasisMark, int emphasisMarkOffset, bool stroked);
     64    void paintTextAndEmphasisMarksIfNeeded(const TextRun&, const FloatRect& boxRect, const FloatPoint& textOrigin, int startOffset, int endOffset,
     65        const TextPaintStyle&, const ShadowData*);
    6366
    6467    GraphicsContext& m_context;
    65     TextPaintStyle& m_textPaintStyle;
    66     TextPaintStyle& m_selectionPaintStyle;
    67     const ShadowData* m_textShadow;
    68     const ShadowData* m_selectionShadow;
    69     bool m_paintSelectedTextOnly;
    70     bool m_paintSelectedTextSeparately;
    71     const FontCascade& m_font;
    72     int m_selectionStart;
    73     int m_selectionEnd;
    74     int m_length;
    75     const AtomicString& m_emphasisMark;
    76     RenderCombineText* m_combinedText;
    77     TextRun& m_textRun;
    78     FloatRect m_boxRect;
    79     FloatPoint m_textOrigin;
    80     int m_emphasisMarkOffset;
    81     bool m_textBoxIsHorizontal;
     68    const FontCascade* m_font { nullptr };
     69    TextPaintStyle m_textPaintStyle;
     70    TextPaintStyle m_selectionPaintStyle;
     71    const ShadowData* m_textShadow { nullptr };
     72    const ShadowData* m_selectionShadow { nullptr };
     73    AtomicString m_emphasisMark;
     74    RenderCombineText* m_combinedText { nullptr };
     75    int m_emphasisMarkOffset { 0 };
     76    bool m_textBoxIsHorizontal { true };
    8277};
     78
     79inline void TextPainter::addEmphasis(const AtomicString& emphasisMark, int emphasisMarkOffset, RenderCombineText* combinedText)
     80{
     81    m_emphasisMark = emphasisMark;
     82    m_emphasisMarkOffset = emphasisMarkOffset;
     83    m_combinedText = combinedText;
     84}
     85
     86inline void TextPainter::addTextShadow(const ShadowData* textShadow, const ShadowData* selectionShadow)
     87{
     88    m_textShadow = textShadow;
     89    m_selectionShadow = selectionShadow;
     90}
    8391
    8492class ShadowApplier {
Note: See TracChangeset for help on using the changeset viewer.