2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3 * (C) 2000 Antti Koivisto (koivisto@kde.org)
4 * (C) 2000 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2003, 2006, 2007, 2011 Apple Inc. All rights reserved.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
27 #include "platform/PlatformExport.h"
28 #include "platform/fonts/Glyph.h"
29 #include "platform/geometry/FloatRect.h"
30 #include "platform/heap/Heap.h"
31 #include "platform/text/TabSize.h"
32 #include "platform/text/TextDirection.h"
33 #include "platform/text/TextPath.h"
34 #include "wtf/RefCounted.h"
35 #include "wtf/text/WTFString.h"
42 TextJustifyAuto
= 0x0,
43 TextJustifyNone
= 0x1,
44 TextJustifyInterWord
= 0x2,
45 TextJustifyDistribute
= 0x3
48 class PLATFORM_EXPORT TextRun
{
49 WTF_MAKE_FAST_ALLOCATED(TextRun
);
51 enum ExpansionBehaviorFlags
{
52 ForbidTrailingExpansion
= 0 << 0,
53 AllowTrailingExpansion
= 1 << 0,
54 ForbidLeadingExpansion
= 0 << 1,
55 AllowLeadingExpansion
= 1 << 1,
64 typedef unsigned ExpansionBehavior
;
66 TextRun(const LChar
* c
, unsigned len
, float xpos
= 0, float expansion
= 0, ExpansionBehavior expansionBehavior
= AllowTrailingExpansion
| ForbidLeadingExpansion
, TextDirection direction
= LTR
, bool directionalOverride
= false)
67 : m_charactersLength(len
)
70 , m_horizontalGlyphStretch(1)
71 , m_expansion(expansion
)
72 , m_expansionBehavior(expansionBehavior
)
76 , m_direction(direction
)
77 , m_directionalOverride(directionalOverride
)
78 , m_disableSpacing(false)
79 , m_textJustify(TextJustifyAuto
)
80 , m_normalizeSpace(false)
83 m_data
.characters8
= c
;
86 TextRun(const UChar
* c
, unsigned len
, float xpos
= 0, float expansion
= 0, ExpansionBehavior expansionBehavior
= AllowTrailingExpansion
| ForbidLeadingExpansion
, TextDirection direction
= LTR
, bool directionalOverride
= false)
87 : m_charactersLength(len
)
90 , m_horizontalGlyphStretch(1)
91 , m_expansion(expansion
)
92 , m_expansionBehavior(expansionBehavior
)
96 , m_direction(direction
)
97 , m_directionalOverride(directionalOverride
)
98 , m_disableSpacing(false)
99 , m_textJustify(TextJustifyAuto
)
100 , m_normalizeSpace(false)
103 m_data
.characters16
= c
;
106 TextRun(const String
& string
, float xpos
= 0, float expansion
= 0, ExpansionBehavior expansionBehavior
= AllowTrailingExpansion
| ForbidLeadingExpansion
, TextDirection direction
= LTR
, bool directionalOverride
= false)
107 : m_charactersLength(string
.length())
108 , m_len(string
.length())
110 , m_horizontalGlyphStretch(1)
111 , m_expansion(expansion
)
112 , m_expansionBehavior(expansionBehavior
)
115 , m_direction(direction
)
116 , m_directionalOverride(directionalOverride
)
117 , m_disableSpacing(false)
118 , m_textJustify(TextJustifyAuto
)
119 , m_normalizeSpace(false)
122 if (!m_charactersLength
) {
124 m_data
.characters8
= 0;
125 } else if (string
.is8Bit()) {
126 m_data
.characters8
= string
.characters8();
129 m_data
.characters16
= string
.characters16();
134 TextRun(const StringView
& string
, float xpos
= 0, float expansion
= 0, ExpansionBehavior expansionBehavior
= AllowTrailingExpansion
| ForbidLeadingExpansion
, TextDirection direction
= LTR
, bool directionalOverride
= false)
135 : m_charactersLength(string
.length())
136 , m_len(string
.length())
138 , m_horizontalGlyphStretch(1)
139 , m_expansion(expansion
)
140 , m_expansionBehavior(expansionBehavior
)
143 , m_direction(direction
)
144 , m_directionalOverride(directionalOverride
)
145 , m_disableSpacing(false)
146 , m_textJustify(TextJustifyAuto
)
147 , m_normalizeSpace(false)
150 if (!m_charactersLength
) {
152 m_data
.characters8
= 0;
153 } else if (string
.is8Bit()) {
154 m_data
.characters8
= string
.characters8();
157 m_data
.characters16
= string
.characters16();
162 TextRun
subRun(unsigned startOffset
, unsigned length
) const
164 ASSERT(startOffset
< m_len
);
166 TextRun result
= *this;
169 result
.setText(data8(startOffset
), length
);
172 result
.setText(data16(startOffset
), length
);
176 UChar
operator[](unsigned i
) const { ASSERT_WITH_SECURITY_IMPLICATION(i
< m_len
); return is8Bit() ? m_data
.characters8
[i
] :m_data
.characters16
[i
]; }
177 const LChar
* data8(unsigned i
) const { ASSERT_WITH_SECURITY_IMPLICATION(i
< m_len
); ASSERT(is8Bit()); return &m_data
.characters8
[i
]; }
178 const UChar
* data16(unsigned i
) const { ASSERT_WITH_SECURITY_IMPLICATION(i
< m_len
); ASSERT(!is8Bit()); return &m_data
.characters16
[i
]; }
180 const LChar
* characters8() const { ASSERT(is8Bit()); return m_data
.characters8
; }
181 const UChar
* characters16() const { ASSERT(!is8Bit()); return m_data
.characters16
; }
183 bool is8Bit() const { return m_is8Bit
; }
184 int length() const { return m_len
; }
185 int charactersLength() const { return m_charactersLength
; }
187 bool normalizeSpace() const { return m_normalizeSpace
; }
188 void setNormalizeSpace(bool normalizeSpace
) { m_normalizeSpace
= normalizeSpace
; }
190 void setText(const LChar
* c
, unsigned len
) { m_data
.characters8
= c
; m_len
= len
; m_is8Bit
= true;}
191 void setText(const UChar
* c
, unsigned len
) { m_data
.characters16
= c
; m_len
= len
; m_is8Bit
= false;}
192 void setText(const String
&);
193 void setCharactersLength(unsigned charactersLength
) { m_charactersLength
= charactersLength
; }
195 void setExpansionBehavior(ExpansionBehavior behavior
) { m_expansionBehavior
= behavior
; }
196 float horizontalGlyphStretch() const { return m_horizontalGlyphStretch
; }
197 void setHorizontalGlyphStretch(float scale
) { m_horizontalGlyphStretch
= scale
; }
199 bool allowTabs() const { return m_allowTabs
; }
200 TabSize
tabSize() const { return m_tabSize
; }
201 void setTabSize(bool, TabSize
);
203 float xPos() const { return m_xpos
; }
204 void setXPos(float xPos
) { m_xpos
= xPos
; }
205 float expansion() const { return m_expansion
; }
206 bool allowsLeadingExpansion() const { return m_expansionBehavior
& AllowLeadingExpansion
; }
207 bool allowsTrailingExpansion() const { return m_expansionBehavior
& AllowTrailingExpansion
; }
208 TextDirection
direction() const { return static_cast<TextDirection
>(m_direction
); }
209 bool rtl() const { return m_direction
== RTL
; }
210 bool ltr() const { return m_direction
== LTR
; }
211 bool directionalOverride() const { return m_directionalOverride
; }
212 TextCodePath
codePath() const { return static_cast<TextCodePath
>(m_codePath
); }
213 bool spacingDisabled() const { return m_disableSpacing
; }
215 void disableSpacing() { m_disableSpacing
= true; }
216 void setDirection(TextDirection direction
) { m_direction
= direction
; }
217 void setDirectionalOverride(bool override
) { m_directionalOverride
= override
; }
219 void setCodePath(TextCodePath
);
221 void setCodePath(TextCodePath codePath
) { m_codePath
= codePath
; }
222 #endif // ENABLE(ASSERT)
224 void setTextJustify(TextJustify textJustify
) { m_textJustify
= static_cast<unsigned>(textJustify
); }
225 TextJustify
textJustify() const { return static_cast<TextJustify
>(m_textJustify
); }
227 class RenderingContext
: public RefCounted
<RenderingContext
> {
229 virtual ~RenderingContext() { }
232 RenderingContext
* renderingContext() const { return m_renderingContext
.get(); }
233 void setRenderingContext(PassRefPtr
<RenderingContext
> context
) { m_renderingContext
= context
; }
237 const LChar
* characters8
;
238 const UChar
* characters16
;
240 unsigned m_charactersLength
; // Marks the end of the characters buffer. Default equals to m_len.
243 // m_xpos is the x position relative to the left start of the text line, not relative to the left
244 // start of the containing block. In the case of right alignment or center alignment, left start of
245 // the text line is not the same as left start of the containing block.
247 float m_horizontalGlyphStretch
;
250 ExpansionBehavior m_expansionBehavior
: 2;
251 unsigned m_codePath
: 2;
252 unsigned m_is8Bit
: 1;
253 unsigned m_allowTabs
: 1;
254 unsigned m_direction
: 1;
255 unsigned m_directionalOverride
: 1; // Was this direction set by an override character.
256 unsigned m_disableSpacing
: 1;
257 unsigned m_textJustify
: 2;
258 bool m_normalizeSpace
;
259 RefPtr
<RenderingContext
> m_renderingContext
;
263 inline void TextRun::setTabSize(bool allow
, TabSize size
)
269 // Container for parameters needed to paint TextRun.
270 struct TextRunPaintInfo
{
273 explicit TextRunPaintInfo(const TextRun
& r
)
277 , cachedTextBlob(nullptr)
285 RefPtr
<const SkTextBlob
>* cachedTextBlob
;