Revert r170413 and r170390
[WebKit-https.git] / Source / WebCore / platform / graphics / Font.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved.
6  *
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.
11  *
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.
16  *
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.
21  *
22  */
23
24 #include "config.h"
25 #include "Font.h"
26
27 #include "FloatRect.h"
28 #include "FontCache.h"
29 #include "GlyphBuffer.h"
30 #include "LayoutRect.h"
31 #include "TextRun.h"
32 #include "WidthIterator.h"
33 #include <wtf/MainThread.h>
34 #include <wtf/MathExtras.h>
35 #include <wtf/text/AtomicStringHash.h>
36 #include <wtf/text/StringBuilder.h>
37
38 using namespace WTF;
39 using namespace Unicode;
40
41 namespace WTF {
42
43 // allow compilation of OwnPtr<TextLayout> in source files that don't have access to the TextLayout class definition
44 template <> void deleteOwnedPtr<WebCore::TextLayout>(WebCore::TextLayout* ptr)
45 {
46     WebCore::Font::deleteLayout(ptr);
47 }
48
49 }
50
51 namespace WebCore {
52
53 static PassRef<FontGlyphs> retrieveOrAddCachedFontGlyphs(const FontDescription&, PassRefPtr<FontSelector>);
54
55 const uint8_t Font::s_roundingHackCharacterTable[256] = {
56     0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*\t*/, 1 /*\n*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57     1 /*space*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*-*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*?*/,
58     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61     1 /*no-break space*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
64 };
65
66 static bool isDrawnWithSVGFont(const TextRun& run)
67 {
68     return run.renderingContext();
69 }
70
71 static bool useBackslashAsYenSignForFamily(const AtomicString& family)
72 {
73     if (family.isEmpty())
74         return false;
75     static HashSet<AtomicString>* set;
76     if (!set) {
77         set = new HashSet<AtomicString>;
78         set->add("MS PGothic");
79         UChar unicodeNameMSPGothic[] = {0xFF2D, 0xFF33, 0x0020, 0xFF30, 0x30B4, 0x30B7, 0x30C3, 0x30AF};
80         set->add(AtomicString(unicodeNameMSPGothic, WTF_ARRAY_LENGTH(unicodeNameMSPGothic)));
81
82         set->add("MS PMincho");
83         UChar unicodeNameMSPMincho[] = {0xFF2D, 0xFF33, 0x0020, 0xFF30, 0x660E, 0x671D};
84         set->add(AtomicString(unicodeNameMSPMincho, WTF_ARRAY_LENGTH(unicodeNameMSPMincho)));
85
86         set->add("MS Gothic");
87         UChar unicodeNameMSGothic[] = {0xFF2D, 0xFF33, 0x0020, 0x30B4, 0x30B7, 0x30C3, 0x30AF};
88         set->add(AtomicString(unicodeNameMSGothic, WTF_ARRAY_LENGTH(unicodeNameMSGothic)));
89
90         set->add("MS Mincho");
91         UChar unicodeNameMSMincho[] = {0xFF2D, 0xFF33, 0x0020, 0x660E, 0x671D};
92         set->add(AtomicString(unicodeNameMSMincho, WTF_ARRAY_LENGTH(unicodeNameMSMincho)));
93
94         set->add("Meiryo");
95         UChar unicodeNameMeiryo[] = {0x30E1, 0x30A4, 0x30EA, 0x30AA};
96         set->add(AtomicString(unicodeNameMeiryo, WTF_ARRAY_LENGTH(unicodeNameMeiryo)));
97     }
98     return set->contains(family);
99 }
100
101 Font::CodePath Font::s_codePath = Auto;
102
103 TypesettingFeatures Font::s_defaultTypesettingFeatures = 0;
104
105 // ============================================================================================
106 // Font Implementation (Cross-Platform Portion)
107 // ============================================================================================
108
109 Font::Font()
110     : m_letterSpacing(0)
111     , m_wordSpacing(0)
112     , m_useBackslashAsYenSymbol(false)
113     , m_typesettingFeatures(0)
114 {
115 }
116
117 Font::Font(const FontDescription& fd, float letterSpacing, float wordSpacing)
118     : m_fontDescription(fd)
119     , m_letterSpacing(letterSpacing)
120     , m_wordSpacing(wordSpacing)
121     , m_useBackslashAsYenSymbol(useBackslashAsYenSignForFamily(fd.firstFamily()))
122     , m_typesettingFeatures(computeTypesettingFeatures())
123 {
124 }
125
126 // FIXME: We should make this constructor platform-independent.
127 Font::Font(const FontPlatformData& fontData, bool isPrinterFont, FontSmoothingMode fontSmoothingMode)
128     : m_glyphs(FontGlyphs::createForPlatformFont(fontData))
129     , m_letterSpacing(0)
130     , m_wordSpacing(0)
131     , m_useBackslashAsYenSymbol(false)
132     , m_typesettingFeatures(computeTypesettingFeatures())
133 {
134     m_fontDescription.setUsePrinterFont(isPrinterFont);
135     m_fontDescription.setFontSmoothing(fontSmoothingMode);
136 #if PLATFORM(IOS)
137     m_fontDescription.setSpecifiedSize(CTFontGetSize(fontData.font()));
138     m_fontDescription.setComputedSize(CTFontGetSize(fontData.font()));
139     m_fontDescription.setItalic(CTFontGetSymbolicTraits(fontData.font()) & kCTFontTraitItalic);
140     m_fontDescription.setWeight((CTFontGetSymbolicTraits(fontData.font()) & kCTFontTraitBold) ? FontWeightBold : FontWeightNormal);
141 #endif
142 }
143
144 // FIXME: We should make this constructor platform-independent.
145 #if PLATFORM(IOS)
146 Font::Font(const FontPlatformData& fontData, PassRefPtr<FontSelector> fontSelector)
147     : m_glyphs(FontGlyphs::createForPlatformFont(fontData))
148     , m_letterSpacing(0)
149     , m_wordSpacing(0)
150     , m_typesettingFeatures(computeTypesettingFeatures())
151 {
152     CTFontRef primaryFont = fontData.font();
153     m_fontDescription.setSpecifiedSize(CTFontGetSize(primaryFont));
154     m_fontDescription.setComputedSize(CTFontGetSize(primaryFont));
155     m_fontDescription.setItalic(CTFontGetSymbolicTraits(primaryFont) & kCTFontTraitItalic);
156     m_fontDescription.setWeight((CTFontGetSymbolicTraits(primaryFont) & kCTFontTraitBold) ? FontWeightBold : FontWeightNormal);
157     m_fontDescription.setUsePrinterFont(fontData.isPrinterFont());
158     m_glyphs = retrieveOrAddCachedFontGlyphs(m_fontDescription, fontSelector.get());
159 }
160 #endif
161
162 Font::Font(const Font& other)
163     : m_fontDescription(other.m_fontDescription)
164     , m_glyphs(other.m_glyphs)
165     , m_letterSpacing(other.m_letterSpacing)
166     , m_wordSpacing(other.m_wordSpacing)
167     , m_useBackslashAsYenSymbol(other.m_useBackslashAsYenSymbol)
168     , m_typesettingFeatures(computeTypesettingFeatures())
169 {
170 }
171
172 Font& Font::operator=(const Font& other)
173 {
174     m_fontDescription = other.m_fontDescription;
175     m_glyphs = other.m_glyphs;
176     m_letterSpacing = other.m_letterSpacing;
177     m_wordSpacing = other.m_wordSpacing;
178     m_useBackslashAsYenSymbol = other.m_useBackslashAsYenSymbol;
179     m_typesettingFeatures = other.m_typesettingFeatures;
180     return *this;
181 }
182
183 bool Font::operator==(const Font& other) const
184 {
185     // Our FontData don't have to be checked, since checking the font description will be fine.
186     // FIXME: This does not work if the font was made with the FontPlatformData constructor.
187     if (loadingCustomFonts() || other.loadingCustomFonts())
188         return false;
189
190     if (m_fontDescription != other.m_fontDescription || m_letterSpacing != other.m_letterSpacing || m_wordSpacing != other.m_wordSpacing)
191         return false;
192     if (m_glyphs == other.m_glyphs)
193         return true;
194     if (!m_glyphs || !other.m_glyphs)
195         return false;
196     if (m_glyphs->fontSelector() != other.m_glyphs->fontSelector())
197         return false;
198     // Can these cases actually somehow occur? All fonts should get wiped out by full style recalc.
199     if (m_glyphs->fontSelectorVersion() != other.m_glyphs->fontSelectorVersion())
200         return false;
201     if (m_glyphs->generation() != other.m_glyphs->generation())
202         return false;
203     return true;
204 }
205
206 struct FontGlyphsCacheKey {
207     // This part of the key is shared with the lower level FontCache (caching FontData objects).
208     FontDescriptionFontDataCacheKey fontDescriptionCacheKey;
209     Vector<AtomicString, 3> families;
210     unsigned fontSelectorId;
211     unsigned fontSelectorVersion;
212     unsigned fontSelectorFlags;
213 };
214
215 struct FontGlyphsCacheEntry {
216     WTF_MAKE_FAST_ALLOCATED;
217 public:
218     FontGlyphsCacheEntry(FontGlyphsCacheKey&& k, PassRef<FontGlyphs> g) : key(WTF::move(k)), glyphs(WTF::move(g)) { }
219     FontGlyphsCacheKey key;
220     Ref<FontGlyphs> glyphs;
221 };
222
223 typedef HashMap<unsigned, OwnPtr<FontGlyphsCacheEntry>, AlreadyHashed> FontGlyphsCache;
224
225 static bool operator==(const FontGlyphsCacheKey& a, const FontGlyphsCacheKey& b)
226 {
227     if (a.fontDescriptionCacheKey != b.fontDescriptionCacheKey)
228         return false;
229     if (a.fontSelectorId != b.fontSelectorId || a.fontSelectorVersion != b.fontSelectorVersion || a.fontSelectorFlags != b.fontSelectorFlags)
230         return false;
231     if (a.families.size() != b.families.size())
232         return false;
233     for (unsigned i = 0; i < a.families.size(); ++i) {
234         if (!equalIgnoringCase(a.families[i].impl(), b.families[i].impl()))
235             return false;
236     }
237     return true;
238 }
239
240 static FontGlyphsCache& fontGlyphsCache()
241 {
242     DEPRECATED_DEFINE_STATIC_LOCAL(FontGlyphsCache, cache, ());
243     return cache;
244 }
245
246 void invalidateFontGlyphsCache()
247 {
248     fontGlyphsCache().clear();
249 }
250
251 void clearWidthCaches()
252 {
253     for (auto it = fontGlyphsCache().begin(), end = fontGlyphsCache().end(); it != end; ++it)
254         it->value->glyphs.get().widthCache().clear();
255 }
256
257 static unsigned makeFontSelectorFlags(const FontDescription& description)
258 {
259     return static_cast<unsigned>(description.script()) << 1 | static_cast<unsigned>(description.smallCaps());
260 }
261
262 static void makeFontGlyphsCacheKey(FontGlyphsCacheKey& key, const FontDescription& description, FontSelector* fontSelector)
263 {
264     key.fontDescriptionCacheKey = FontDescriptionFontDataCacheKey(description);
265     for (unsigned i = 0; i < description.familyCount(); ++i)
266         key.families.append(description.familyAt(i));
267     key.fontSelectorId = fontSelector ? fontSelector->uniqueId() : 0;
268     key.fontSelectorVersion = fontSelector ? fontSelector->version() : 0;
269     key.fontSelectorFlags = fontSelector && fontSelector->resolvesFamilyFor(description) ? makeFontSelectorFlags(description) : 0;
270 }
271
272 static unsigned computeFontGlyphsCacheHash(const FontGlyphsCacheKey& key)
273 {
274     Vector<unsigned, 7> hashCodes;
275     hashCodes.reserveInitialCapacity(4 + key.families.size());
276
277     hashCodes.uncheckedAppend(key.fontDescriptionCacheKey.computeHash());
278     hashCodes.uncheckedAppend(key.fontSelectorId);
279     hashCodes.uncheckedAppend(key.fontSelectorVersion);
280     hashCodes.uncheckedAppend(key.fontSelectorFlags);
281     for (unsigned i = 0; i < key.families.size(); ++i)
282         hashCodes.uncheckedAppend(key.families[i].impl() ? CaseFoldingHash::hash(key.families[i]) : 0);
283
284     return StringHasher::hashMemory(hashCodes.data(), hashCodes.size() * sizeof(unsigned));
285 }
286
287 void pruneUnreferencedEntriesFromFontGlyphsCache()
288 {
289     Vector<unsigned, 50> toRemove;
290     FontGlyphsCache::iterator end = fontGlyphsCache().end();
291     for (FontGlyphsCache::iterator it = fontGlyphsCache().begin(); it != end; ++it) {
292         if (it->value->glyphs.get().hasOneRef())
293             toRemove.append(it->key);
294     }
295     for (unsigned i = 0; i < toRemove.size(); ++i)
296         fontGlyphsCache().remove(toRemove[i]);
297 }
298
299 static PassRef<FontGlyphs> retrieveOrAddCachedFontGlyphs(const FontDescription& fontDescription, PassRefPtr<FontSelector> fontSelector)
300 {
301     FontGlyphsCacheKey key;
302     makeFontGlyphsCacheKey(key, fontDescription, fontSelector.get());
303
304     unsigned hash = computeFontGlyphsCacheHash(key);
305     FontGlyphsCache::AddResult addResult = fontGlyphsCache().add(hash, PassOwnPtr<FontGlyphsCacheEntry>());
306     if (!addResult.isNewEntry && addResult.iterator->value->key == key)
307         return addResult.iterator->value->glyphs.get();
308
309     OwnPtr<FontGlyphsCacheEntry>& newEntry = addResult.iterator->value;
310     newEntry = adoptPtr(new FontGlyphsCacheEntry(WTF::move(key), FontGlyphs::create(fontSelector)));
311     PassRef<FontGlyphs> glyphs = newEntry->glyphs.get();
312
313     static const unsigned unreferencedPruneInterval = 50;
314     static const int maximumEntries = 400;
315     static unsigned pruneCounter;
316     // Referenced FontGlyphs would exist anyway so pruning them saves little memory.
317     if (!(++pruneCounter % unreferencedPruneInterval))
318         pruneUnreferencedEntriesFromFontGlyphsCache();
319     // Prevent pathological growth.
320     if (fontGlyphsCache().size() > maximumEntries)
321         fontGlyphsCache().remove(fontGlyphsCache().begin());
322     return glyphs;
323 }
324
325 void Font::update(PassRefPtr<FontSelector> fontSelector) const
326 {
327     m_glyphs = retrieveOrAddCachedFontGlyphs(m_fontDescription, fontSelector.get());
328     m_useBackslashAsYenSymbol = useBackslashAsYenSignForFamily(firstFamily());
329     m_typesettingFeatures = computeTypesettingFeatures();
330 }
331
332 float Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to, CustomFontNotReadyAction customFontNotReadyAction) const
333 {
334     // Don't draw anything while we are using custom fonts that are in the process of loading,
335     // except if the 'force' argument is set to true (in which case it will use a fallback
336     // font).
337     if (loadingCustomFonts() && customFontNotReadyAction == DoNotPaintIfFontNotReady)
338         return 0;
339
340     to = (to == -1 ? run.length() : to);
341
342     CodePath codePathToUse = codePath(run);
343     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
344     if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !isDrawnWithSVGFont(run))
345         codePathToUse = Complex;
346
347     if (codePathToUse != Complex)
348         return drawSimpleText(context, run, point, from, to);
349
350     return drawComplexText(context, run, point, from, to);
351 }
352
353 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
354 {
355     if (loadingCustomFonts())
356         return;
357
358     if (to < 0)
359         to = run.length();
360
361     CodePath codePathToUse = codePath(run);
362     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
363     if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !isDrawnWithSVGFont(run))
364         codePathToUse = Complex;
365
366     if (codePathToUse != Complex)
367         drawEmphasisMarksForSimpleText(context, run, mark, point, from, to);
368     else
369         drawEmphasisMarksForComplexText(context, run, mark, point, from, to);
370 }
371
372 float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
373 {
374     CodePath codePathToUse = codePath(run);
375     if (codePathToUse != Complex) {
376         // The complex path is more restrictive about returning fallback fonts than the simple path, so we need an explicit test to make their behaviors match.
377         if (!canReturnFallbackFontsForComplexText())
378             fallbackFonts = 0;
379         // The simple path can optimize the case where glyph overflow is not observable.
380         if (codePathToUse != SimpleWithGlyphOverflow && (glyphOverflow && !glyphOverflow->computeBounds))
381             glyphOverflow = 0;
382     }
383
384     bool hasKerningOrLigatures = typesettingFeatures() & (Kerning | Ligatures);
385     bool hasWordSpacingOrLetterSpacing = wordSpacing() || letterSpacing();
386     float* cacheEntry = m_glyphs->widthCache().add(run, std::numeric_limits<float>::quiet_NaN(), hasKerningOrLigatures, hasWordSpacingOrLetterSpacing, glyphOverflow);
387     if (cacheEntry && !std::isnan(*cacheEntry))
388         return *cacheEntry;
389
390     HashSet<const SimpleFontData*> localFallbackFonts;
391     if (!fallbackFonts)
392         fallbackFonts = &localFallbackFonts;
393
394     float result;
395     if (codePathToUse == Complex)
396         result = floatWidthForComplexText(run, fallbackFonts, glyphOverflow);
397     else
398         result = floatWidthForSimpleText(run, fallbackFonts, glyphOverflow);
399
400     if (cacheEntry && fallbackFonts->isEmpty())
401         *cacheEntry = result;
402     return result;
403 }
404
405 float Font::width(const TextRun& run, int& charsConsumed, String& glyphName) const
406 {
407 #if ENABLE(SVG_FONTS)
408     if (isDrawnWithSVGFont(run))
409         return run.renderingContext()->floatWidthUsingSVGFont(*this, run, charsConsumed, glyphName);
410 #endif
411
412     charsConsumed = run.length();
413     glyphName = "";
414     return width(run);
415 }
416
417 #if !PLATFORM(COCOA)
418 PassOwnPtr<TextLayout> Font::createLayout(RenderText*, float, bool) const
419 {
420     return nullptr;
421 }
422
423 void Font::deleteLayout(TextLayout*)
424 {
425 }
426
427 float Font::width(TextLayout&, unsigned, unsigned, HashSet<const SimpleFontData*>*)
428 {
429     ASSERT_NOT_REACHED();
430     return 0;
431 }
432 #endif
433
434
435
436 static const char* fontFamiliesWithInvalidCharWidth[] = {
437     "American Typewriter",
438     "Arial Hebrew",
439     "Chalkboard",
440     "Cochin",
441     "Corsiva Hebrew",
442     "Courier",
443     "Euphemia UCAS",
444     "Geneva",
445     "Gill Sans",
446     "Hei",
447     "Helvetica",
448     "Hoefler Text",
449     "InaiMathi",
450     "Kai",
451     "Lucida Grande",
452     "Marker Felt",
453     "Monaco",
454     "Mshtakan",
455     "New Peninim MT",
456     "Osaka",
457     "Raanana",
458     "STHeiti",
459     "Symbol",
460     "Times",
461     "Apple Braille",
462     "Apple LiGothic",
463     "Apple LiSung",
464     "Apple Symbols",
465     "AppleGothic",
466     "AppleMyungjo",
467     "#GungSeo",
468     "#HeadLineA",
469     "#PCMyungjo",
470     "#PilGi",
471 };
472
473 // For font families where any of the fonts don't have a valid entry in the OS/2 table
474 // for avgCharWidth, fallback to the legacy webkit behavior of getting the avgCharWidth
475 // from the width of a '0'. This only seems to apply to a fixed number of Mac fonts,
476 // but, in order to get similar rendering across platforms, we do this check for
477 // all platforms.
478 bool Font::hasValidAverageCharWidth() const
479 {
480     AtomicString family = firstFamily();
481     if (family.isEmpty())
482         return false;
483
484 #if PLATFORM(MAC) || PLATFORM(IOS)
485     // Internal fonts on OS X and iOS also have an invalid entry in the table for avgCharWidth.
486     if (primaryFontDataIsSystemFont())
487         return false;
488 #endif
489
490     static HashSet<AtomicString>* fontFamiliesWithInvalidCharWidthMap = 0;
491
492     if (!fontFamiliesWithInvalidCharWidthMap) {
493         fontFamiliesWithInvalidCharWidthMap = new HashSet<AtomicString>;
494
495         for (size_t i = 0; i < WTF_ARRAY_LENGTH(fontFamiliesWithInvalidCharWidth); ++i)
496             fontFamiliesWithInvalidCharWidthMap->add(AtomicString(fontFamiliesWithInvalidCharWidth[i]));
497     }
498
499     return !fontFamiliesWithInvalidCharWidthMap->contains(family);
500 }
501
502 bool Font::fastAverageCharWidthIfAvailable(float& width) const
503 {
504     bool success = hasValidAverageCharWidth();
505     if (success)
506         width = roundf(primaryFont()->avgCharWidth()); // FIXME: primaryFont() might not correspond to firstFamily().
507     return success;
508 }
509
510 void Font::adjustSelectionRectForText(const TextRun& run, LayoutRect& selectionRect, int from, int to) const
511 {
512     to = (to == -1 ? run.length() : to);
513
514     CodePath codePathToUse = codePath(run);
515     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
516     if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !isDrawnWithSVGFont(run))
517         codePathToUse = Complex;
518
519     if (codePathToUse != Complex)
520         return adjustSelectionRectForSimpleText(run, selectionRect, from, to);
521
522     return adjustSelectionRectForComplexText(run, selectionRect, from, to);
523 }
524
525 int Font::offsetForPosition(const TextRun& run, float x, bool includePartialGlyphs) const
526 {
527     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
528     if (codePath(run) != Complex && (!typesettingFeatures() || isDrawnWithSVGFont(run)))
529         return offsetForPositionForSimpleText(run, x, includePartialGlyphs);
530
531     return offsetForPositionForComplexText(run, x, includePartialGlyphs);
532 }
533
534 template <typename CharacterType>
535 static inline String normalizeSpacesInternal(const CharacterType* characters, unsigned length)
536 {
537     StringBuilder normalized;
538     normalized.reserveCapacity(length);
539
540     for (unsigned i = 0; i < length; ++i)
541         normalized.append(Font::normalizeSpaces(characters[i]));
542
543     return normalized.toString();
544 }
545
546 String Font::normalizeSpaces(const LChar* characters, unsigned length)
547 {
548     return normalizeSpacesInternal(characters, length);
549 }
550
551 String Font::normalizeSpaces(const UChar* characters, unsigned length)
552 {
553     return normalizeSpacesInternal(characters, length);
554 }
555
556 static bool shouldUseFontSmoothing = true;
557
558 void Font::setShouldUseSmoothing(bool shouldUseSmoothing)
559 {
560     ASSERT(isMainThread());
561     shouldUseFontSmoothing = shouldUseSmoothing;
562 }
563
564 bool Font::shouldUseSmoothing()
565 {
566     return shouldUseFontSmoothing;
567 }
568
569 void Font::setCodePath(CodePath p)
570 {
571     s_codePath = p;
572 }
573
574 Font::CodePath Font::codePath()
575 {
576     return s_codePath;
577 }
578
579 void Font::setDefaultTypesettingFeatures(TypesettingFeatures typesettingFeatures)
580 {
581     s_defaultTypesettingFeatures = typesettingFeatures;
582 }
583
584 TypesettingFeatures Font::defaultTypesettingFeatures()
585 {
586     return s_defaultTypesettingFeatures;
587 }
588
589 Font::CodePath Font::codePath(const TextRun& run) const
590 {
591     if (s_codePath != Auto)
592         return s_codePath;
593
594 #if ENABLE(SVG_FONTS)
595     if (isDrawnWithSVGFont(run))
596         return Simple;
597 #endif
598
599     if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings()->size() > 0)
600         return Complex;
601     
602     if (run.length() > 1 && !WidthIterator::supportsTypesettingFeatures(*this))
603         return Complex;
604
605     if (!run.characterScanForCodePath())
606         return Simple;
607
608     if (run.is8Bit())
609         return Simple;
610
611     // Start from 0 since drawing and highlighting also measure the characters before run->from.
612     return characterRangeCodePath(run.characters16(), run.length());
613 }
614
615 Font::CodePath Font::characterRangeCodePath(const UChar* characters, unsigned len)
616 {
617     // FIXME: Should use a UnicodeSet in ports where ICU is used. Note that we 
618     // can't simply use UnicodeCharacter Property/class because some characters
619     // are not 'combining', but still need to go to the complex path.
620     // Alternatively, we may as well consider binary search over a sorted
621     // list of ranges.
622     CodePath result = Simple;
623     for (unsigned i = 0; i < len; i++) {
624         const UChar c = characters[i];
625         if (c < 0x2E5) // U+02E5 through U+02E9 (Modifier Letters : Tone letters)  
626             continue;
627         if (c <= 0x2E9) 
628             return Complex;
629
630         if (c < 0x300) // U+0300 through U+036F Combining diacritical marks
631             continue;
632         if (c <= 0x36F)
633             return Complex;
634
635         if (c < 0x0591 || c == 0x05BE) // U+0591 through U+05CF excluding U+05BE Hebrew combining marks, Hebrew punctuation Paseq, Sof Pasuq and Nun Hafukha
636             continue;
637         if (c <= 0x05CF)
638             return Complex;
639
640         // U+0600 through U+109F Arabic, Syriac, Thaana, NKo, Samaritan, Mandaic,
641         // Devanagari, Bengali, Gurmukhi, Gujarati, Oriya, Tamil, Telugu, Kannada, 
642         // Malayalam, Sinhala, Thai, Lao, Tibetan, Myanmar
643         if (c < 0x0600) 
644             continue;
645         if (c <= 0x109F)
646             return Complex;
647
648         // U+1100 through U+11FF Hangul Jamo (only Ancient Korean should be left here if you precompose;
649         // Modern Korean will be precomposed as a result of step A)
650         if (c < 0x1100)
651             continue;
652         if (c <= 0x11FF)
653             return Complex;
654
655         if (c < 0x135D) // U+135D through U+135F Ethiopic combining marks
656             continue;
657         if (c <= 0x135F)
658             return Complex;
659
660         if (c < 0x1700) // U+1780 through U+18AF Tagalog, Hanunoo, Buhid, Taghanwa,Khmer, Mongolian
661             continue;
662         if (c <= 0x18AF)
663             return Complex;
664
665         if (c < 0x1900) // U+1900 through U+194F Limbu (Unicode 4.0)
666             continue;
667         if (c <= 0x194F)
668             return Complex;
669
670         if (c < 0x1980) // U+1980 through U+19DF New Tai Lue
671             continue;
672         if (c <= 0x19DF)
673             return Complex;
674
675         if (c < 0x1A00) // U+1A00 through U+1CFF Buginese, Tai Tham, Balinese, Batak, Lepcha, Vedic
676             continue;
677         if (c <= 0x1CFF)
678             return Complex;
679
680         if (c < 0x1DC0) // U+1DC0 through U+1DFF Comining diacritical mark supplement
681             continue;
682         if (c <= 0x1DFF)
683             return Complex;
684
685         // U+1E00 through U+2000 characters with diacritics and stacked diacritics
686         if (c <= 0x2000) {
687             result = SimpleWithGlyphOverflow;
688             continue;
689         }
690
691         if (c < 0x20D0) // U+20D0 through U+20FF Combining marks for symbols
692             continue;
693         if (c <= 0x20FF)
694             return Complex;
695
696         if (c < 0x2CEF) // U+2CEF through U+2CF1 Combining marks for Coptic
697             continue;
698         if (c <= 0x2CF1)
699             return Complex;
700
701         if (c < 0x302A) // U+302A through U+302F Ideographic and Hangul Tone marks
702             continue;
703         if (c <= 0x302F)
704             return Complex;
705
706         if (c < 0xA67C) // U+A67C through U+A67D Combining marks for old Cyrillic
707             continue;
708         if (c <= 0xA67D)
709             return Complex;
710
711         if (c < 0xA6F0) // U+A6F0 through U+A6F1 Combining mark for Bamum
712             continue;
713         if (c <= 0xA6F1)
714             return Complex;
715
716        // U+A800 through U+ABFF Nagri, Phags-pa, Saurashtra, Devanagari Extended,
717        // Hangul Jamo Ext. A, Javanese, Myanmar Extended A, Tai Viet, Meetei Mayek,
718         if (c < 0xA800) 
719             continue;
720         if (c <= 0xABFF)
721             return Complex;
722
723         if (c < 0xD7B0) // U+D7B0 through U+D7FF Hangul Jamo Ext. B
724             continue;
725         if (c <= 0xD7FF)
726             return Complex;
727
728         if (c <= 0xDBFF) {
729             // High surrogate
730
731             if (i == len - 1)
732                 continue;
733
734             UChar next = characters[++i];
735             if (!U16_IS_TRAIL(next))
736                 continue;
737
738             UChar32 supplementaryCharacter = U16_GET_SUPPLEMENTARY(c, next);
739
740             if (supplementaryCharacter < 0x1F1E6) // U+1F1E6 through U+1F1FF Regional Indicator Symbols
741                 continue;
742             if (supplementaryCharacter <= 0x1F1FF)
743                 return Complex;
744
745             if (supplementaryCharacter < 0xE0100) // U+E0100 through U+E01EF Unicode variation selectors.
746                 continue;
747             if (supplementaryCharacter <= 0xE01EF)
748                 return Complex;
749
750             // FIXME: Check for Brahmi (U+11000 block), Kaithi (U+11080 block) and other complex scripts
751             // in plane 1 or higher.
752
753             continue;
754         }
755
756         if (c < 0xFE00) // U+FE00 through U+FE0F Unicode variation selectors
757             continue;
758         if (c <= 0xFE0F)
759             return Complex;
760
761         if (c < 0xFE20) // U+FE20 through U+FE2F Combining half marks
762             continue;
763         if (c <= 0xFE2F)
764             return Complex;
765     }
766     return result;
767 }
768
769 bool Font::isCJKIdeograph(UChar32 c)
770 {
771     // The basic CJK Unified Ideographs block.
772     if (c >= 0x4E00 && c <= 0x9FFF)
773         return true;
774     
775     // CJK Unified Ideographs Extension A.
776     if (c >= 0x3400 && c <= 0x4DBF)
777         return true;
778     
779     // CJK Radicals Supplement.
780     if (c >= 0x2E80 && c <= 0x2EFF)
781         return true;
782     
783     // Kangxi Radicals.
784     if (c >= 0x2F00 && c <= 0x2FDF)
785         return true;
786     
787     // CJK Strokes.
788     if (c >= 0x31C0 && c <= 0x31EF)
789         return true;
790     
791     // CJK Compatibility Ideographs.
792     if (c >= 0xF900 && c <= 0xFAFF)
793         return true;
794     
795     // CJK Unified Ideographs Extension B.
796     if (c >= 0x20000 && c <= 0x2A6DF)
797         return true;
798         
799     // CJK Unified Ideographs Extension C.
800     if (c >= 0x2A700 && c <= 0x2B73F)
801         return true;
802     
803     // CJK Unified Ideographs Extension D.
804     if (c >= 0x2B740 && c <= 0x2B81F)
805         return true;
806     
807     // CJK Compatibility Ideographs Supplement.
808     if (c >= 0x2F800 && c <= 0x2FA1F)
809         return true;
810
811     return false;
812 }
813
814 bool Font::isCJKIdeographOrSymbol(UChar32 c)
815 {
816     // 0x2C7 Caron, Mandarin Chinese 3rd Tone
817     // 0x2CA Modifier Letter Acute Accent, Mandarin Chinese 2nd Tone
818     // 0x2CB Modifier Letter Grave Access, Mandarin Chinese 4th Tone 
819     // 0x2D9 Dot Above, Mandarin Chinese 5th Tone 
820     if ((c == 0x2C7) || (c == 0x2CA) || (c == 0x2CB) || (c == 0x2D9))
821         return true;
822
823     if ((c == 0x2020) || (c == 0x2021) || (c == 0x2030) || (c == 0x203B) || (c == 0x203C)
824         || (c == 0x2042) || (c == 0x2047) || (c == 0x2048) || (c == 0x2049) || (c == 0x2051)
825         || (c == 0x20DD) || (c == 0x20DE) || (c == 0x2100) || (c == 0x2103) || (c == 0x2105)
826         || (c == 0x2109) || (c == 0x210A) || (c == 0x2113) || (c == 0x2116) || (c == 0x2121)
827         || (c == 0x212B) || (c == 0x213B) || (c == 0x2150) || (c == 0x2151) || (c == 0x2152))
828         return true;
829
830     if (c >= 0x2156 && c <= 0x215A)
831         return true;
832
833     if (c >= 0x2160 && c <= 0x216B)
834         return true;
835
836     if (c >= 0x2170 && c <= 0x217B)
837         return true;
838
839     if ((c == 0x217F) || (c == 0x2189) || (c == 0x2307) || (c == 0x2312) || (c == 0x23BE) || (c == 0x23BF))
840         return true;
841
842     if (c >= 0x23C0 && c <= 0x23CC)
843         return true;
844
845     if ((c == 0x23CE) || (c == 0x2423))
846         return true;
847
848     if (c >= 0x2460 && c <= 0x2492)
849         return true;
850
851     if (c >= 0x249C && c <= 0x24FF)
852         return true;
853
854     if ((c == 0x25A0) || (c == 0x25A1) || (c == 0x25A2) || (c == 0x25AA) || (c == 0x25AB))
855         return true;
856
857     if ((c == 0x25B1) || (c == 0x25B2) || (c == 0x25B3) || (c == 0x25B6) || (c == 0x25B7) || (c == 0x25BC) || (c == 0x25BD))
858         return true;
859     
860     if ((c == 0x25C0) || (c == 0x25C1) || (c == 0x25C6) || (c == 0x25C7) || (c == 0x25C9) || (c == 0x25CB) || (c == 0x25CC))
861         return true;
862
863     if (c >= 0x25CE && c <= 0x25D3)
864         return true;
865
866     if (c >= 0x25E2 && c <= 0x25E6)
867         return true;
868
869     if (c == 0x25EF)
870         return true;
871
872     if (c >= 0x2600 && c <= 0x2603)
873         return true;
874
875     if ((c == 0x2605) || (c == 0x2606) || (c == 0x260E) || (c == 0x2616) || (c == 0x2617) || (c == 0x2640) || (c == 0x2642))
876         return true;
877
878     if (c >= 0x2660 && c <= 0x266F)
879         return true;
880
881     if (c >= 0x2672 && c <= 0x267D)
882         return true;
883
884     if ((c == 0x26A0) || (c == 0x26BD) || (c == 0x26BE) || (c == 0x2713) || (c == 0x271A) || (c == 0x273F) || (c == 0x2740) || (c == 0x2756))
885         return true;
886
887     if (c >= 0x2776 && c <= 0x277F)
888         return true;
889
890     if (c == 0x2B1A)
891         return true;
892
893     // Ideographic Description Characters.
894     if (c >= 0x2FF0 && c <= 0x2FFF)
895         return true;
896     
897     // CJK Symbols and Punctuation, excluding 0x3030.
898     if (c >= 0x3000 && c < 0x3030)
899         return true;
900
901     if (c > 0x3030 && c <= 0x303F)
902         return true;
903
904     // Hiragana
905     if (c >= 0x3040 && c <= 0x309F)
906         return true;
907
908     // Katakana 
909     if (c >= 0x30A0 && c <= 0x30FF)
910         return true;
911
912     // Bopomofo
913     if (c >= 0x3100 && c <= 0x312F)
914         return true;
915
916     if (c >= 0x3190 && c <= 0x319F)
917         return true;
918
919     // Bopomofo Extended
920     if (c >= 0x31A0 && c <= 0x31BF)
921         return true;
922  
923     // Enclosed CJK Letters and Months.
924     if (c >= 0x3200 && c <= 0x32FF)
925         return true;
926     
927     // CJK Compatibility.
928     if (c >= 0x3300 && c <= 0x33FF)
929         return true;
930
931     if (c >= 0xF860 && c <= 0xF862)
932         return true;
933
934     // CJK Compatibility Forms.
935     if (c >= 0xFE30 && c <= 0xFE4F)
936         return true;
937
938     if ((c == 0xFE10) || (c == 0xFE11) || (c == 0xFE12) || (c == 0xFE19))
939         return true;
940
941     if ((c == 0xFF0D) || (c == 0xFF1B) || (c == 0xFF1C) || (c == 0xFF1E))
942         return false;
943
944     // Halfwidth and Fullwidth Forms
945     // Usually only used in CJK
946     if (c >= 0xFF00 && c <= 0xFFEF)
947         return true;
948
949     // Emoji.
950     if (c == 0x1F100)
951         return true;
952
953     if (c >= 0x1F110 && c <= 0x1F129)
954         return true;
955
956     if (c >= 0x1F130 && c <= 0x1F149)
957         return true;
958
959     if (c >= 0x1F150 && c <= 0x1F169)
960         return true;
961
962     if (c >= 0x1F170 && c <= 0x1F189)
963         return true;
964
965     if (c >= 0x1F200 && c <= 0x1F6C5)
966         return true;
967
968     return isCJKIdeograph(c);
969 }
970
971 unsigned Font::expansionOpportunityCount(const LChar* characters, size_t length, TextDirection direction, bool& isAfterExpansion)
972 {
973     unsigned count = 0;
974     if (direction == LTR) {
975         for (size_t i = 0; i < length; ++i) {
976             if (treatAsSpace(characters[i])) {
977                 count++;
978                 isAfterExpansion = true;
979             } else
980                 isAfterExpansion = false;
981         }
982     } else {
983         for (size_t i = length; i > 0; --i) {
984             if (treatAsSpace(characters[i - 1])) {
985                 count++;
986                 isAfterExpansion = true;
987             } else
988                 isAfterExpansion = false;
989         }
990     }
991     return count;
992 }
993
994 unsigned Font::expansionOpportunityCount(const UChar* characters, size_t length, TextDirection direction, bool& isAfterExpansion)
995 {
996     static bool expandAroundIdeographs = canExpandAroundIdeographsInComplexText();
997     unsigned count = 0;
998     if (direction == LTR) {
999         for (size_t i = 0; i < length; ++i) {
1000             UChar32 character = characters[i];
1001             if (treatAsSpace(character)) {
1002                 count++;
1003                 isAfterExpansion = true;
1004                 continue;
1005             }
1006             if (U16_IS_LEAD(character) && i + 1 < length && U16_IS_TRAIL(characters[i + 1])) {
1007                 character = U16_GET_SUPPLEMENTARY(character, characters[i + 1]);
1008                 i++;
1009             }
1010             if (expandAroundIdeographs && isCJKIdeographOrSymbol(character)) {
1011                 if (!isAfterExpansion)
1012                     count++;
1013                 count++;
1014                 isAfterExpansion = true;
1015                 continue;
1016             }
1017             isAfterExpansion = false;
1018         }
1019     } else {
1020         for (size_t i = length; i > 0; --i) {
1021             UChar32 character = characters[i - 1];
1022             if (treatAsSpace(character)) {
1023                 count++;
1024                 isAfterExpansion = true;
1025                 continue;
1026             }
1027             if (U16_IS_TRAIL(character) && i > 1 && U16_IS_LEAD(characters[i - 2])) {
1028                 character = U16_GET_SUPPLEMENTARY(characters[i - 2], character);
1029                 i--;
1030             }
1031             if (expandAroundIdeographs && isCJKIdeographOrSymbol(character)) {
1032                 if (!isAfterExpansion)
1033                     count++;
1034                 count++;
1035                 isAfterExpansion = true;
1036                 continue;
1037             }
1038             isAfterExpansion = false;
1039         }
1040     }
1041     return count;
1042 }
1043
1044 bool Font::canReceiveTextEmphasis(UChar32 c)
1045 {
1046     if (U_GET_GC_MASK(c) & (U_GC_Z_MASK | U_GC_CN_MASK | U_GC_CC_MASK | U_GC_CF_MASK))
1047         return false;
1048
1049     // Additional word-separator characters listed in CSS Text Level 3 Editor's Draft 3 November 2010.
1050     if (c == ethiopicWordspace || c == aegeanWordSeparatorLine || c == aegeanWordSeparatorDot
1051         || c == ugariticWordDivider || c == tibetanMarkIntersyllabicTsheg || c == tibetanMarkDelimiterTshegBstar)
1052         return false;
1053
1054     return true;
1055 }
1056     
1057 GlyphToPathTranslator::GlyphUnderlineType computeUnderlineType(const TextRun& textRun, const GlyphBuffer& glyphBuffer, int index)
1058 {
1059     // In general, we want to skip descenders. However, skipping descenders on CJK characters leads to undesirable renderings,
1060     // so we want to draw through CJK characters (on a character-by-character basis).
1061     UChar32 baseCharacter;
1062     int offsetInString = glyphBuffer.offsetInString(index);
1063
1064     if (offsetInString == GlyphBuffer::kNoOffset) {
1065         // We have no idea which character spawned this glyph. Bail.
1066         return GlyphToPathTranslator::GlyphUnderlineType::DrawOverGlyph;
1067     }
1068     
1069     if (textRun.is8Bit())
1070         baseCharacter = textRun.characters8()[offsetInString];
1071     else
1072         U16_NEXT(textRun.characters16(), offsetInString, textRun.length(), baseCharacter);
1073     
1074     // u_getIntPropertyValue with UCHAR_IDEOGRAPHIC doesn't return true for Japanese or Korean codepoints.
1075     // Instead, we can use the "Unicode allocation block" for the character.
1076     UBlockCode blockCode = ublock_getCode(baseCharacter);
1077     switch (blockCode) {
1078     case UBLOCK_CJK_RADICALS_SUPPLEMENT:
1079     case UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION:
1080     case UBLOCK_ENCLOSED_CJK_LETTERS_AND_MONTHS:
1081     case UBLOCK_CJK_COMPATIBILITY:
1082     case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A:
1083     case UBLOCK_CJK_UNIFIED_IDEOGRAPHS:
1084     case UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS:
1085     case UBLOCK_CJK_COMPATIBILITY_FORMS:
1086     case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B:
1087     case UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT:
1088     case UBLOCK_CJK_STROKES:
1089     case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C:
1090     case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D:
1091     case UBLOCK_IDEOGRAPHIC_DESCRIPTION_CHARACTERS:
1092     case UBLOCK_LINEAR_B_IDEOGRAMS:
1093     case UBLOCK_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT:
1094     case UBLOCK_HIRAGANA:
1095     case UBLOCK_KATAKANA:
1096     case UBLOCK_BOPOMOFO:
1097     case UBLOCK_BOPOMOFO_EXTENDED:
1098     case UBLOCK_HANGUL_JAMO:
1099     case UBLOCK_HANGUL_COMPATIBILITY_JAMO:
1100     case UBLOCK_HANGUL_SYLLABLES:
1101     case UBLOCK_HANGUL_JAMO_EXTENDED_A:
1102     case UBLOCK_HANGUL_JAMO_EXTENDED_B:
1103         return GlyphToPathTranslator::GlyphUnderlineType::DrawOverGlyph;
1104     default:
1105         return GlyphToPathTranslator::GlyphUnderlineType::SkipDescenders;
1106     }
1107 }
1108
1109 }