3b81473cc8292937fdccb0f08f9b4449f5ae1306
[WebKit-https.git] / Source / WebCore / rendering / TextPainter.h
1 /*
2  * (C) 1999 Lars Knoll (knoll@kde.org)
3  * (C) 2000 Dirk Mueller (mueller@kde.org)
4  * Copyright (C) 2004-2017 Apple Inc. All rights reserved.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #pragma once
24
25 #include "AffineTransform.h"
26 #include "FloatRect.h"
27 #include "TextFlags.h"
28 #include "TextPaintStyle.h"
29 #include <wtf/text/AtomicString.h>
30
31 namespace WebCore {
32
33 class FontCascade;
34 class RenderCombineText;
35 class ShadowData;
36 class TextRun;
37
38 struct TextPaintStyle;
39
40 enum RotationDirection { Counterclockwise, Clockwise };
41
42 static inline AffineTransform rotation(const FloatRect& boxRect, RotationDirection clockwise)
43 {
44     return clockwise ? AffineTransform(0, 1, -1, 0, boxRect.x() + boxRect.maxY(), boxRect.maxY() - boxRect.x())
45         : AffineTransform(0, -1, 1, 0, boxRect.x() - boxRect.maxY(), boxRect.x() + boxRect.maxY());
46 }
47
48 class TextPainter {
49 public:
50     TextPainter(GraphicsContext&);
51     
52     void setStyle(const TextPaintStyle& textPaintStyle) { m_style = textPaintStyle; }
53     void setSelectionStyle(const TextPaintStyle& selectionPaintStyle) { m_selectionStyle = selectionPaintStyle; }
54
55     void setShadow(const ShadowData* shadow) { m_shadow = shadow; }
56     void setSelectionShadow(const ShadowData* selectionShadow) { m_selectionShadow = selectionShadow; }
57
58     void setFont(const FontCascade& font) { m_font = &font; }
59
60     void setIsHorizontal(bool isHorizontal) { m_textBoxIsHorizontal = isHorizontal; }
61
62     void setEmphasisMark(const AtomicString& mark, float offset, RenderCombineText*);
63
64     void paintRange(const TextRun&, const FloatRect& boxRect, const FloatPoint& textOrigin, unsigned start, unsigned end);
65     void paint(const TextRun&, unsigned length, const FloatRect& boxRect, const FloatPoint& textOrigin,
66         unsigned selectionStart = 0, unsigned selectionEnd = 0, bool paintSelectedTextOnly = false, bool paintSelectedTextSeparately = false, bool paintNonSelectedTextOnly = false);
67
68 private:
69     void paintTextOrEmphasisMarks(const FontCascade&, const TextRun&, const AtomicString& emphasisMark, float emphasisMarkOffset,
70         const FloatPoint& textOrigin, unsigned startOffset, unsigned endOffset);
71     void paintTextWithShadows(const ShadowData*, const FontCascade&, const TextRun&, const FloatRect& boxRect, const FloatPoint& textOrigin,
72         unsigned startOffset, unsigned endOffset, const AtomicString& emphasisMark, float emphasisMarkOffset, bool stroked);
73     void paintTextAndEmphasisMarksIfNeeded(const TextRun&, const FloatRect& boxRect, const FloatPoint& textOrigin, unsigned startOffset, unsigned endOffset,
74         const TextPaintStyle&, const ShadowData*);
75
76     GraphicsContext& m_context;
77     const FontCascade* m_font { nullptr };
78     TextPaintStyle m_style;
79     TextPaintStyle m_selectionStyle;
80     const ShadowData* m_shadow { nullptr };
81     const ShadowData* m_selectionShadow { nullptr };
82     AtomicString m_emphasisMark;
83     RenderCombineText* m_combinedText { nullptr };
84     float m_emphasisMarkOffset { 0 };
85     bool m_textBoxIsHorizontal { true };
86 };
87
88 inline void TextPainter::setEmphasisMark(const AtomicString& mark, float offset, RenderCombineText* combinedText)
89 {
90     m_emphasisMark = mark;
91     m_emphasisMarkOffset = offset;
92     m_combinedText = combinedText;
93 }
94
95 class ShadowApplier {
96 public:
97     ShadowApplier(GraphicsContext&, const ShadowData*, const FloatRect& textRect, bool lastShadowIterationShouldDrawText = true, bool opaque = false, FontOrientation = Horizontal);
98     FloatSize extraOffset() const { return m_extraOffset; }
99     bool nothingToDraw() const { return m_nothingToDraw; }
100     bool didSaveContext() const { return m_didSaveContext; }
101     ~ShadowApplier();
102
103 private:
104     bool isLastShadowIteration();
105     bool shadowIsCompletelyCoveredByText(bool textIsOpaque);
106
107     FloatSize m_extraOffset;
108     GraphicsContext& m_context;
109     const ShadowData* m_shadow;
110     bool m_onlyDrawsShadow : 1;
111     bool m_avoidDrawingShadow : 1;
112     bool m_nothingToDraw : 1;
113     bool m_didSaveContext : 1;
114 };
115
116 } // namespace WebCore