Part 2 of removing PlatformString.h, remove PlatformString.h
[WebKit-https.git] / Source / WebCore / platform / graphics / harfbuzz / FontPlatformDataHarfBuzz.cpp
1 /*
2  * Copyright (c) 2006, 2007, 2008, Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "FontPlatformDataHarfBuzz.h"
33
34 #include "NotImplemented.h"
35 #include "SkAdvancedTypefaceMetrics.h"
36 #include "SkFontHost.h"
37 #include "SkPaint.h"
38 #include "SkTypeface.h"
39
40 #if USE(HARFBUZZ_NG)
41 #include "HarfBuzzNGFace.h"
42 #else
43 #include "HarfBuzzSkia.h"
44 #endif
45
46 #include <public/linux/WebFontInfo.h>
47 #include <public/linux/WebFontRenderStyle.h>
48 #include <public/linux/WebSandboxSupport.h>
49 #include <public/Platform.h>
50 #include <wtf/text/StringImpl.h>
51 #include <wtf/text/WTFString.h>
52
53 namespace WebCore {
54
55 static SkPaint::Hinting skiaHinting = SkPaint::kNormal_Hinting;
56 static bool useSkiaAutoHint = true;
57 static bool useSkiaBitmaps = true;
58 static bool useSkiaAntiAlias = true;
59 static bool useSkiaSubpixelRendering = false;
60 static bool useSkiaSubpixelPositioning = false;
61
62 void FontPlatformData::setHinting(SkPaint::Hinting hinting)
63 {
64     skiaHinting = hinting;
65 }
66
67 void FontPlatformData::setAutoHint(bool useAutoHint)
68 {
69     useSkiaAutoHint = useAutoHint;
70 }
71
72 void FontPlatformData::setUseBitmaps(bool useBitmaps)
73 {
74     useSkiaBitmaps = useBitmaps;
75 }
76
77 void FontPlatformData::setAntiAlias(bool useAntiAlias)
78 {
79     useSkiaAntiAlias = useAntiAlias;
80 }
81
82 void FontPlatformData::setSubpixelRendering(bool useSubpixelRendering)
83 {
84     useSkiaSubpixelRendering = useSubpixelRendering;
85 }
86
87 void FontPlatformData::setSubpixelPositioning(bool useSubpixelPositioning)
88 {
89     useSkiaSubpixelPositioning = useSubpixelPositioning;
90 }
91
92 FontPlatformData::FontPlatformData(WTF::HashTableDeletedValueType)
93     : m_typeface(hashTableDeletedFontValue())
94     , m_textSize(0)
95     , m_emSizeInFontUnits(0)
96     , m_fakeBold(false)
97     , m_fakeItalic(false)
98     , m_orientation(Horizontal)
99     , m_textOrientation(TextOrientationVerticalRight)
100 {
101 }
102
103 FontPlatformData::FontPlatformData()
104     : m_typeface(0)
105     , m_textSize(0)
106     , m_emSizeInFontUnits(0)
107     , m_fakeBold(false)
108     , m_fakeItalic(false)
109     , m_orientation(Horizontal)
110     , m_textOrientation(TextOrientationVerticalRight)
111 {
112 }
113
114 FontPlatformData::FontPlatformData(float textSize, bool fakeBold, bool fakeItalic)
115     : m_typeface(0)
116     , m_textSize(textSize)
117     , m_emSizeInFontUnits(0)
118     , m_fakeBold(fakeBold)
119     , m_fakeItalic(fakeItalic)
120     , m_orientation(Horizontal)
121     , m_textOrientation(TextOrientationVerticalRight)
122 {
123 }
124
125 FontPlatformData::FontPlatformData(const FontPlatformData& src)
126     : m_typeface(src.m_typeface)
127     , m_family(src.m_family)
128     , m_textSize(src.m_textSize)
129     , m_emSizeInFontUnits(src.m_emSizeInFontUnits)
130     , m_fakeBold(src.m_fakeBold)
131     , m_fakeItalic(src.m_fakeItalic)
132     , m_orientation(src.m_orientation)
133     , m_textOrientation(src.m_textOrientation)
134     , m_style(src.m_style)
135     , m_harfbuzzFace(src.m_harfbuzzFace)
136 {
137     SkSafeRef(m_typeface);
138 }
139
140 FontPlatformData::FontPlatformData(SkTypeface* tf, const char* family, float textSize, bool fakeBold, bool fakeItalic, FontOrientation orientation, TextOrientation textOrientation)
141     : m_typeface(tf)
142     , m_family(family)
143     , m_textSize(textSize)
144     , m_emSizeInFontUnits(0)
145     , m_fakeBold(fakeBold)
146     , m_fakeItalic(fakeItalic)
147     , m_orientation(orientation)
148     , m_textOrientation(textOrientation)
149 {
150     SkSafeRef(m_typeface);
151     querySystemForRenderStyle();
152 }
153
154 FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
155     : m_typeface(src.m_typeface)
156     , m_family(src.m_family)
157     , m_textSize(textSize)
158     , m_emSizeInFontUnits(src.m_emSizeInFontUnits)
159     , m_fakeBold(src.m_fakeBold)
160     , m_fakeItalic(src.m_fakeItalic)
161     , m_orientation(src.m_orientation)
162     , m_textOrientation(src.m_textOrientation)
163     , m_harfbuzzFace(src.m_harfbuzzFace)
164 {
165     SkSafeRef(m_typeface);
166     querySystemForRenderStyle();
167 }
168
169 FontPlatformData::~FontPlatformData()
170 {
171     SkSafeUnref(m_typeface);
172 }
173
174 int FontPlatformData::emSizeInFontUnits() const
175 {
176     if (m_emSizeInFontUnits)
177         return m_emSizeInFontUnits;
178
179     // FIXME: Switch to the SkTypeface::GetUnitsPerEm API once this becomes available.
180     // https://bugs.webkit.org/show_bug.cgi?id=75961
181 #if OS(ANDROID)
182     // Android doesn't currently support Skia's getAdvancedTypefaceMetrics(),
183     // but it has access to another method to replace this functionality.
184     m_emSizeInFontUnits = SkFontHost::GetUnitsPerEm(m_typeface->uniqueID());
185 #else
186     SkAdvancedTypefaceMetrics* metrics = m_typeface->getAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo);
187     m_emSizeInFontUnits = metrics->fEmSize;
188     metrics->unref();
189 #endif
190     return m_emSizeInFontUnits;
191 }
192
193 FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
194 {
195     SkRefCnt_SafeAssign(m_typeface, src.m_typeface);
196
197     m_family = src.m_family;
198     m_textSize = src.m_textSize;
199     m_fakeBold = src.m_fakeBold;
200     m_fakeItalic = src.m_fakeItalic;
201     m_harfbuzzFace = src.m_harfbuzzFace;
202     m_orientation = src.m_orientation;
203     m_textOrientation = src.m_textOrientation;
204     m_style = src.m_style;
205     m_emSizeInFontUnits = src.m_emSizeInFontUnits;
206
207     return *this;
208 }
209
210 #ifndef NDEBUG
211 String FontPlatformData::description() const
212 {
213     return String();
214 }
215 #endif
216
217 void FontPlatformData::setupPaint(SkPaint* paint) const
218 {
219     paint->setAntiAlias(m_style.useAntiAlias);
220     paint->setHinting(static_cast<SkPaint::Hinting>(m_style.hintStyle));
221     paint->setEmbeddedBitmapText(m_style.useBitmaps);
222     paint->setAutohinted(m_style.useAutoHint);
223     paint->setSubpixelText(m_style.useSubpixelPositioning);
224     if (m_style.useAntiAlias)
225         paint->setLCDRenderText(m_style.useSubpixelRendering);
226
227     const float ts = m_textSize >= 0 ? m_textSize : 12;
228     paint->setTextSize(SkFloatToScalar(ts));
229     paint->setTypeface(m_typeface);
230     paint->setFakeBoldText(m_fakeBold);
231     paint->setTextSkewX(m_fakeItalic ? -SK_Scalar1 / 4 : 0);
232 }
233
234 SkFontID FontPlatformData::uniqueID() const
235 {
236     return m_typeface->uniqueID();
237 }
238
239 bool FontPlatformData::operator==(const FontPlatformData& a) const
240 {
241     // If either of the typeface pointers are invalid (either 0 or the
242     // special deleted value) then we test for pointer equality. Otherwise, we
243     // call SkTypeface::Equal on the valid pointers.
244     bool typefacesEqual;
245     if (m_typeface == hashTableDeletedFontValue()
246         || a.m_typeface == hashTableDeletedFontValue()
247         || !m_typeface
248         || !a.m_typeface)
249         typefacesEqual = m_typeface == a.m_typeface;
250     else
251         typefacesEqual = SkTypeface::Equal(m_typeface, a.m_typeface);
252
253     return typefacesEqual
254         && m_textSize == a.m_textSize
255         && m_fakeBold == a.m_fakeBold
256         && m_fakeItalic == a.m_fakeItalic
257         && m_orientation == a.m_orientation
258         && m_textOrientation == a.m_textOrientation
259         && m_style == a.m_style;
260 }
261
262 unsigned FontPlatformData::hash() const
263 {
264     unsigned h = SkTypeface::UniqueID(m_typeface);
265     h ^= 0x01010101 * ((static_cast<int>(m_textOrientation) << 3) | (static_cast<int>(m_orientation) << 2) | (static_cast<int>(m_fakeBold) << 1) | static_cast<int>(m_fakeItalic));
266
267     // This memcpy is to avoid a reinterpret_cast that breaks strict-aliasing
268     // rules. Memcpy is generally optimized enough so that performance doesn't
269     // matter here.
270     uint32_t textSizeBytes;
271     memcpy(&textSizeBytes, &m_textSize, sizeof(uint32_t));
272     h ^= textSizeBytes;
273
274     return h;
275 }
276
277 bool FontPlatformData::isFixedPitch() const
278 {
279     notImplemented();
280     return false;
281 }
282
283 #if USE(HARFBUZZ_NG)
284 HarfBuzzNGFace* FontPlatformData::harfbuzzFace() const
285 {
286     if (!m_harfbuzzFace)
287         m_harfbuzzFace = HarfBuzzNGFace::create(const_cast<FontPlatformData*>(this), uniqueID());
288
289     return m_harfbuzzFace.get();
290 }
291 #else
292 HarfbuzzFace* FontPlatformData::harfbuzzFace() const
293 {
294     if (!m_harfbuzzFace)
295         m_harfbuzzFace = HarfbuzzFace::create(const_cast<FontPlatformData*>(this));
296
297     return m_harfbuzzFace.get();
298 }
299 #endif
300
301 void FontPlatformData::getRenderStyleForStrike(const char* font, int sizeAndStyle)
302 {
303     WebKit::WebFontRenderStyle style;
304
305 #if OS(ANDROID)
306     style.setDefaults();
307 #else
308     if (!font || !*font)
309         style.setDefaults(); // It's probably a webfont. Take the system defaults.
310     else if (WebKit::Platform::current()->sandboxSupport())
311         WebKit::Platform::current()->sandboxSupport()->getRenderStyleForStrike(font, sizeAndStyle, &style);
312     else
313         WebKit::WebFontInfo::renderStyleForStrike(font, sizeAndStyle, &style);
314 #endif
315
316     style.toFontRenderStyle(&m_style);
317 }
318
319 void FontPlatformData::querySystemForRenderStyle()
320 {
321     getRenderStyleForStrike(m_family.data(), (((int)m_textSize) << 2) | (m_typeface->style() & 3));
322
323     // Fix FontRenderStyle::NoPreference to actual styles.
324     if (m_style.useAntiAlias == FontRenderStyle::NoPreference)
325          m_style.useAntiAlias = useSkiaAntiAlias;
326
327     if (!m_style.useHinting)
328         m_style.hintStyle = SkPaint::kNo_Hinting;
329     else if (m_style.useHinting == FontRenderStyle::NoPreference)
330         m_style.hintStyle = skiaHinting;
331
332     if (m_style.useBitmaps == FontRenderStyle::NoPreference)
333         m_style.useBitmaps = useSkiaBitmaps;
334     if (m_style.useAutoHint == FontRenderStyle::NoPreference)
335         m_style.useAutoHint = useSkiaAutoHint;
336     if (m_style.useSubpixelPositioning == FontRenderStyle::NoPreference)
337         m_style.useSubpixelPositioning = useSkiaSubpixelPositioning;
338     if (m_style.useAntiAlias == FontRenderStyle::NoPreference)
339         m_style.useAntiAlias = useSkiaAntiAlias;
340     if (m_style.useSubpixelRendering == FontRenderStyle::NoPreference)
341         m_style.useSubpixelRendering = useSkiaSubpixelRendering;
342 }
343
344 } // namespace WebCore