036cfd924d5536778166235e2a20d1ad49ffd5aa
[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, unsigned from, int initialTo, 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     unsigned to = initialTo < 0 ? run.length() : initialTo;
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, unsigned from, int initialTo) const
354 {
355     if (loadingCustomFonts())
356         return;
357     
358     unsigned to = initialTo < 0 ? run.length() : initialTo;
359
360     CodePath codePathToUse = codePath(run);
361     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
362     if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !isDrawnWithSVGFont(run))
363         codePathToUse = Complex;
364
365     if (codePathToUse != Complex)
366         drawEmphasisMarksForSimpleText(context, run, mark, point, from, to);
367     else
368         drawEmphasisMarksForComplexText(context, run, mark, point, from, to);
369 }
370
371 float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
372 {
373     CodePath codePathToUse = codePath(run);
374     if (codePathToUse != Complex) {
375         // 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.
376         if (!canReturnFallbackFontsForComplexText())
377             fallbackFonts = 0;
378         // The simple path can optimize the case where glyph overflow is not observable.
379         if (codePathToUse != SimpleWithGlyphOverflow && (glyphOverflow && !glyphOverflow->computeBounds))
380             glyphOverflow = 0;
381     }
382
383     bool hasKerningOrLigatures = typesettingFeatures() & (Kerning | Ligatures);
384     bool hasWordSpacingOrLetterSpacing = wordSpacing() || letterSpacing();
385     float* cacheEntry = m_glyphs->widthCache().add(run, std::numeric_limits<float>::quiet_NaN(), hasKerningOrLigatures, hasWordSpacingOrLetterSpacing, glyphOverflow);
386     if (cacheEntry && !std::isnan(*cacheEntry))
387         return *cacheEntry;
388
389     HashSet<const SimpleFontData*> localFallbackFonts;
390     if (!fallbackFonts)
391         fallbackFonts = &localFallbackFonts;
392
393     float result;
394     if (codePathToUse == Complex)
395         result = floatWidthForComplexText(run, fallbackFonts, glyphOverflow);
396     else
397         result = floatWidthForSimpleText(run, fallbackFonts, glyphOverflow);
398
399     if (cacheEntry && fallbackFonts->isEmpty())
400         *cacheEntry = result;
401     return result;
402 }
403
404 float Font::width(const TextRun& run, int& charsConsumed, String& glyphName) const
405 {
406 #if ENABLE(SVG_FONTS)
407     if (isDrawnWithSVGFont(run))
408         return run.renderingContext()->floatWidthUsingSVGFont(*this, run, charsConsumed, glyphName);
409 #endif
410
411     charsConsumed = run.length();
412     glyphName = "";
413     return width(run);
414 }
415
416 #if !PLATFORM(COCOA)
417 PassOwnPtr<TextLayout> Font::createLayout(RenderText*, float, bool) const
418 {
419     return nullptr;
420 }
421
422 void Font::deleteLayout(TextLayout*)
423 {
424 }
425
426 float Font::width(TextLayout&, unsigned, unsigned, HashSet<const SimpleFontData*>*)
427 {
428     ASSERT_NOT_REACHED();
429     return 0;
430 }
431 #endif
432
433
434
435 static const char* fontFamiliesWithInvalidCharWidth[] = {
436     "American Typewriter",
437     "Arial Hebrew",
438     "Chalkboard",
439     "Cochin",
440     "Corsiva Hebrew",
441     "Courier",
442     "Euphemia UCAS",
443     "Geneva",
444     "Gill Sans",
445     "Hei",
446     "Helvetica",
447     "Hoefler Text",
448     "InaiMathi",
449     "Kai",
450     "Lucida Grande",
451     "Marker Felt",
452     "Monaco",
453     "Mshtakan",
454     "New Peninim MT",
455     "Osaka",
456     "Raanana",
457     "STHeiti",
458     "Symbol",
459     "Times",
460     "Apple Braille",
461     "Apple LiGothic",
462     "Apple LiSung",
463     "Apple Symbols",
464     "AppleGothic",
465     "AppleMyungjo",
466     "#GungSeo",
467     "#HeadLineA",
468     "#PCMyungjo",
469     "#PilGi",
470 };
471
472 // For font families where any of the fonts don't have a valid entry in the OS/2 table
473 // for avgCharWidth, fallback to the legacy webkit behavior of getting the avgCharWidth
474 // from the width of a '0'. This only seems to apply to a fixed number of Mac fonts,
475 // but, in order to get similar rendering across platforms, we do this check for
476 // all platforms.
477 bool Font::hasValidAverageCharWidth() const
478 {
479     AtomicString family = firstFamily();
480     if (family.isEmpty())
481         return false;
482
483 #if PLATFORM(MAC) || PLATFORM(IOS)
484     // Internal fonts on OS X and iOS also have an invalid entry in the table for avgCharWidth.
485     if (primaryFontDataIsSystemFont())
486         return false;
487 #endif
488
489     static HashSet<AtomicString>* fontFamiliesWithInvalidCharWidthMap = 0;
490
491     if (!fontFamiliesWithInvalidCharWidthMap) {
492         fontFamiliesWithInvalidCharWidthMap = new HashSet<AtomicString>;
493
494         for (size_t i = 0; i < WTF_ARRAY_LENGTH(fontFamiliesWithInvalidCharWidth); ++i)
495             fontFamiliesWithInvalidCharWidthMap->add(AtomicString(fontFamiliesWithInvalidCharWidth[i]));
496     }
497
498     return !fontFamiliesWithInvalidCharWidthMap->contains(family);
499 }
500
501 bool Font::fastAverageCharWidthIfAvailable(float& width) const
502 {
503     bool success = hasValidAverageCharWidth();
504     if (success)
505         width = roundf(primaryFont()->avgCharWidth()); // FIXME: primaryFont() might not correspond to firstFamily().
506     return success;
507 }
508
509 void Font::adjustSelectionRectForText(const TextRun& run, LayoutRect& selectionRect, unsigned from, int initialTo) const
510 {
511     unsigned to = initialTo < 0 ? run.length() : initialTo;
512
513     CodePath codePathToUse = codePath(run);
514     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
515     if (codePathToUse != Complex && typesettingFeatures() && (from || to != run.length()) && !isDrawnWithSVGFont(run))
516         codePathToUse = Complex;
517
518     if (codePathToUse != Complex)
519         return adjustSelectionRectForSimpleText(run, selectionRect, from, to);
520
521     return adjustSelectionRectForComplexText(run, selectionRect, from, to);
522 }
523
524 int Font::offsetForPosition(const TextRun& run, float x, bool includePartialGlyphs) const
525 {
526     // FIXME: Use the fast code path once it handles partial runs with kerning and ligatures. See http://webkit.org/b/100050
527     if (codePath(run) != Complex && (!typesettingFeatures() || isDrawnWithSVGFont(run)))
528         return offsetForPositionForSimpleText(run, x, includePartialGlyphs);
529
530     return offsetForPositionForComplexText(run, x, includePartialGlyphs);
531 }
532
533 template <typename CharacterType>
534 static inline String normalizeSpacesInternal(const CharacterType* characters, unsigned length)
535 {
536     StringBuilder normalized;
537     normalized.reserveCapacity(length);
538
539     for (unsigned i = 0; i < length; ++i)
540         normalized.append(Font::normalizeSpaces(characters[i]));
541
542     return normalized.toString();
543 }
544
545 String Font::normalizeSpaces(const LChar* characters, unsigned length)
546 {
547     return normalizeSpacesInternal(characters, length);
548 }
549
550 String Font::normalizeSpaces(const UChar* characters, unsigned length)
551 {
552     return normalizeSpacesInternal(characters, length);
553 }
554
555 static bool shouldUseFontSmoothing = true;
556
557 void Font::setShouldUseSmoothing(bool shouldUseSmoothing)
558 {
559     ASSERT(isMainThread());
560     shouldUseFontSmoothing = shouldUseSmoothing;
561 }
562
563 bool Font::shouldUseSmoothing()
564 {
565     return shouldUseFontSmoothing;
566 }
567
568 void Font::setCodePath(CodePath p)
569 {
570     s_codePath = p;
571 }
572
573 Font::CodePath Font::codePath()
574 {
575     return s_codePath;
576 }
577
578 void Font::setDefaultTypesettingFeatures(TypesettingFeatures typesettingFeatures)
579 {
580     s_defaultTypesettingFeatures = typesettingFeatures;
581 }
582
583 TypesettingFeatures Font::defaultTypesettingFeatures()
584 {
585     return s_defaultTypesettingFeatures;
586 }
587
588 Font::CodePath Font::codePath(const TextRun& run) const
589 {
590     if (s_codePath != Auto)
591         return s_codePath;
592
593 #if ENABLE(SVG_FONTS)
594     if (isDrawnWithSVGFont(run))
595         return Simple;
596 #endif
597
598     if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings()->size() > 0)
599         return Complex;
600     
601     if (run.length() > 1 && !WidthIterator::supportsTypesettingFeatures(*this))
602         return Complex;
603
604     if (!run.characterScanForCodePath())
605         return Simple;
606
607     if (run.is8Bit())
608         return Simple;
609
610     // Start from 0 since drawing and highlighting also measure the characters before run->from.
611     return characterRangeCodePath(run.characters16(), run.length());
612 }
613
614 Font::CodePath Font::characterRangeCodePath(const UChar* characters, unsigned len)
615 {
616     // FIXME: Should use a UnicodeSet in ports where ICU is used. Note that we 
617     // can't simply use UnicodeCharacter Property/class because some characters
618     // are not 'combining', but still need to go to the complex path.
619     // Alternatively, we may as well consider binary search over a sorted
620     // list of ranges.
621     CodePath result = Simple;
622     for (unsigned i = 0; i < len; i++) {
623         const UChar c = characters[i];
624         if (c < 0x2E5) // U+02E5 through U+02E9 (Modifier Letters : Tone letters)  
625             continue;
626         if (c <= 0x2E9) 
627             return Complex;
628
629         if (c < 0x300) // U+0300 through U+036F Combining diacritical marks
630             continue;
631         if (c <= 0x36F)
632             return Complex;
633
634         if (c < 0x0591 || c == 0x05BE) // U+0591 through U+05CF excluding U+05BE Hebrew combining marks, Hebrew punctuation Paseq, Sof Pasuq and Nun Hafukha
635             continue;
636         if (c <= 0x05CF)
637             return Complex;
638
639         // U+0600 through U+109F Arabic, Syriac, Thaana, NKo, Samaritan, Mandaic,
640         // Devanagari, Bengali, Gurmukhi, Gujarati, Oriya, Tamil, Telugu, Kannada, 
641         // Malayalam, Sinhala, Thai, Lao, Tibetan, Myanmar
642         if (c < 0x0600) 
643             continue;
644         if (c <= 0x109F)
645             return Complex;
646
647         // U+1100 through U+11FF Hangul Jamo (only Ancient Korean should be left here if you precompose;
648         // Modern Korean will be precomposed as a result of step A)
649         if (c < 0x1100)
650             continue;
651         if (c <= 0x11FF)
652             return Complex;
653
654         if (c < 0x135D) // U+135D through U+135F Ethiopic combining marks
655             continue;
656         if (c <= 0x135F)
657             return Complex;
658
659         if (c < 0x1700) // U+1780 through U+18AF Tagalog, Hanunoo, Buhid, Taghanwa,Khmer, Mongolian
660             continue;
661         if (c <= 0x18AF)
662             return Complex;
663
664         if (c < 0x1900) // U+1900 through U+194F Limbu (Unicode 4.0)
665             continue;
666         if (c <= 0x194F)
667             return Complex;
668
669         if (c < 0x1980) // U+1980 through U+19DF New Tai Lue
670             continue;
671         if (c <= 0x19DF)
672             return Complex;
673
674         if (c < 0x1A00) // U+1A00 through U+1CFF Buginese, Tai Tham, Balinese, Batak, Lepcha, Vedic
675             continue;
676         if (c <= 0x1CFF)
677             return Complex;
678
679         if (c < 0x1DC0) // U+1DC0 through U+1DFF Comining diacritical mark supplement
680             continue;
681         if (c <= 0x1DFF)
682             return Complex;
683
684         // U+1E00 through U+2000 characters with diacritics and stacked diacritics
685         if (c <= 0x2000) {
686             result = SimpleWithGlyphOverflow;
687             continue;
688         }
689
690         if (c < 0x20D0) // U+20D0 through U+20FF Combining marks for symbols
691             continue;
692         if (c <= 0x20FF)
693             return Complex;
694
695         if (c < 0x2CEF) // U+2CEF through U+2CF1 Combining marks for Coptic
696             continue;
697         if (c <= 0x2CF1)
698             return Complex;
699
700         if (c < 0x302A) // U+302A through U+302F Ideographic and Hangul Tone marks
701             continue;
702         if (c <= 0x302F)
703             return Complex;
704
705         if (c < 0xA67C) // U+A67C through U+A67D Combining marks for old Cyrillic
706             continue;
707         if (c <= 0xA67D)
708             return Complex;
709
710         if (c < 0xA6F0) // U+A6F0 through U+A6F1 Combining mark for Bamum
711             continue;
712         if (c <= 0xA6F1)
713             return Complex;
714
715        // U+A800 through U+ABFF Nagri, Phags-pa, Saurashtra, Devanagari Extended,
716        // Hangul Jamo Ext. A, Javanese, Myanmar Extended A, Tai Viet, Meetei Mayek,
717         if (c < 0xA800) 
718             continue;
719         if (c <= 0xABFF)
720             return Complex;
721
722         if (c < 0xD7B0) // U+D7B0 through U+D7FF Hangul Jamo Ext. B
723             continue;
724         if (c <= 0xD7FF)
725             return Complex;
726
727         if (c <= 0xDBFF) {
728             // High surrogate
729
730             if (i == len - 1)
731                 continue;
732
733             UChar next = characters[++i];
734             if (!U16_IS_TRAIL(next))
735                 continue;
736
737             UChar32 supplementaryCharacter = U16_GET_SUPPLEMENTARY(c, next);
738
739             if (supplementaryCharacter < 0x1F1E6) // U+1F1E6 through U+1F1FF Regional Indicator Symbols
740                 continue;
741             if (supplementaryCharacter <= 0x1F1FF)
742                 return Complex;
743
744             if (supplementaryCharacter < 0xE0100) // U+E0100 through U+E01EF Unicode variation selectors.
745                 continue;
746             if (supplementaryCharacter <= 0xE01EF)
747                 return Complex;
748
749             // FIXME: Check for Brahmi (U+11000 block), Kaithi (U+11080 block) and other complex scripts
750             // in plane 1 or higher.
751
752             continue;
753         }
754
755         if (c < 0xFE00) // U+FE00 through U+FE0F Unicode variation selectors
756             continue;
757         if (c <= 0xFE0F)
758             return Complex;
759
760         if (c < 0xFE20) // U+FE20 through U+FE2F Combining half marks
761             continue;
762         if (c <= 0xFE2F)
763             return Complex;
764     }
765     return result;
766 }
767
768 bool Font::isCJKIdeograph(UChar32 c)
769 {
770     // The basic CJK Unified Ideographs block.
771     if (c >= 0x4E00 && c <= 0x9FFF)
772         return true;
773     
774     // CJK Unified Ideographs Extension A.
775     if (c >= 0x3400 && c <= 0x4DBF)
776         return true;
777     
778     // CJK Radicals Supplement.
779     if (c >= 0x2E80 && c <= 0x2EFF)
780         return true;
781     
782     // Kangxi Radicals.
783     if (c >= 0x2F00 && c <= 0x2FDF)
784         return true;
785     
786     // CJK Strokes.
787     if (c >= 0x31C0 && c <= 0x31EF)
788         return true;
789     
790     // CJK Compatibility Ideographs.
791     if (c >= 0xF900 && c <= 0xFAFF)
792         return true;
793     
794     // CJK Unified Ideographs Extension B.
795     if (c >= 0x20000 && c <= 0x2A6DF)
796         return true;
797         
798     // CJK Unified Ideographs Extension C.
799     if (c >= 0x2A700 && c <= 0x2B73F)
800         return true;
801     
802     // CJK Unified Ideographs Extension D.
803     if (c >= 0x2B740 && c <= 0x2B81F)
804         return true;
805     
806     // CJK Compatibility Ideographs Supplement.
807     if (c >= 0x2F800 && c <= 0x2FA1F)
808         return true;
809
810     return false;
811 }
812
813 bool Font::isCJKIdeographOrSymbol(UChar32 c)
814 {
815     // 0x2C7 Caron, Mandarin Chinese 3rd Tone
816     // 0x2CA Modifier Letter Acute Accent, Mandarin Chinese 2nd Tone
817     // 0x2CB Modifier Letter Grave Access, Mandarin Chinese 4th Tone 
818     // 0x2D9 Dot Above, Mandarin Chinese 5th Tone 
819     if ((c == 0x2C7) || (c == 0x2CA) || (c == 0x2CB) || (c == 0x2D9))
820         return true;
821
822     if ((c == 0x2020) || (c == 0x2021) || (c == 0x2030) || (c == 0x203B) || (c == 0x203C)
823         || (c == 0x2042) || (c == 0x2047) || (c == 0x2048) || (c == 0x2049) || (c == 0x2051)
824         || (c == 0x20DD) || (c == 0x20DE) || (c == 0x2100) || (c == 0x2103) || (c == 0x2105)
825         || (c == 0x2109) || (c == 0x210A) || (c == 0x2113) || (c == 0x2116) || (c == 0x2121)
826         || (c == 0x212B) || (c == 0x213B) || (c == 0x2150) || (c == 0x2151) || (c == 0x2152))
827         return true;
828
829     if (c >= 0x2156 && c <= 0x215A)
830         return true;
831
832     if (c >= 0x2160 && c <= 0x216B)
833         return true;
834
835     if (c >= 0x2170 && c <= 0x217B)
836         return true;
837
838     if ((c == 0x217F) || (c == 0x2189) || (c == 0x2307) || (c == 0x2312) || (c == 0x23BE) || (c == 0x23BF))
839         return true;
840
841     if (c >= 0x23C0 && c <= 0x23CC)
842         return true;
843
844     if ((c == 0x23CE) || (c == 0x2423))
845         return true;
846
847     if (c >= 0x2460 && c <= 0x2492)
848         return true;
849
850     if (c >= 0x249C && c <= 0x24FF)
851         return true;
852
853     if ((c == 0x25A0) || (c == 0x25A1) || (c == 0x25A2) || (c == 0x25AA) || (c == 0x25AB))
854         return true;
855
856     if ((c == 0x25B1) || (c == 0x25B2) || (c == 0x25B3) || (c == 0x25B6) || (c == 0x25B7) || (c == 0x25BC) || (c == 0x25BD))
857         return true;
858     
859     if ((c == 0x25C0) || (c == 0x25C1) || (c == 0x25C6) || (c == 0x25C7) || (c == 0x25C9) || (c == 0x25CB) || (c == 0x25CC))
860         return true;
861
862     if (c >= 0x25CE && c <= 0x25D3)
863         return true;
864
865     if (c >= 0x25E2 && c <= 0x25E6)
866         return true;
867
868     if (c == 0x25EF)
869         return true;
870
871     if (c >= 0x2600 && c <= 0x2603)
872         return true;
873
874     if ((c == 0x2605) || (c == 0x2606) || (c == 0x260E) || (c == 0x2616) || (c == 0x2617) || (c == 0x2640) || (c == 0x2642))
875         return true;
876
877     if (c >= 0x2660 && c <= 0x266F)
878         return true;
879
880     if (c >= 0x2672 && c <= 0x267D)
881         return true;
882
883     if ((c == 0x26A0) || (c == 0x26BD) || (c == 0x26BE) || (c == 0x2713) || (c == 0x271A) || (c == 0x273F) || (c == 0x2740) || (c == 0x2756))
884         return true;
885
886     if (c >= 0x2776 && c <= 0x277F)
887         return true;
888
889     if (c == 0x2B1A)
890         return true;
891
892     // Ideographic Description Characters.
893     if (c >= 0x2FF0 && c <= 0x2FFF)
894         return true;
895     
896     // CJK Symbols and Punctuation, excluding 0x3030.
897     if (c >= 0x3000 && c < 0x3030)
898         return true;
899
900     if (c > 0x3030 && c <= 0x303F)
901         return true;
902
903     // Hiragana
904     if (c >= 0x3040 && c <= 0x309F)
905         return true;
906
907     // Katakana 
908     if (c >= 0x30A0 && c <= 0x30FF)
909         return true;
910
911     // Bopomofo
912     if (c >= 0x3100 && c <= 0x312F)
913         return true;
914
915     if (c >= 0x3190 && c <= 0x319F)
916         return true;
917
918     // Bopomofo Extended
919     if (c >= 0x31A0 && c <= 0x31BF)
920         return true;
921  
922     // Enclosed CJK Letters and Months.
923     if (c >= 0x3200 && c <= 0x32FF)
924         return true;
925     
926     // CJK Compatibility.
927     if (c >= 0x3300 && c <= 0x33FF)
928         return true;
929
930     if (c >= 0xF860 && c <= 0xF862)
931         return true;
932
933     // CJK Compatibility Forms.
934     if (c >= 0xFE30 && c <= 0xFE4F)
935         return true;
936
937     if ((c == 0xFE10) || (c == 0xFE11) || (c == 0xFE12) || (c == 0xFE19))
938         return true;
939
940     if ((c == 0xFF0D) || (c == 0xFF1B) || (c == 0xFF1C) || (c == 0xFF1E))
941         return false;
942
943     // Halfwidth and Fullwidth Forms
944     // Usually only used in CJK
945     if (c >= 0xFF00 && c <= 0xFFEF)
946         return true;
947
948     // Emoji.
949     if (c == 0x1F100)
950         return true;
951
952     if (c >= 0x1F110 && c <= 0x1F129)
953         return true;
954
955     if (c >= 0x1F130 && c <= 0x1F149)
956         return true;
957
958     if (c >= 0x1F150 && c <= 0x1F169)
959         return true;
960
961     if (c >= 0x1F170 && c <= 0x1F189)
962         return true;
963
964     if (c >= 0x1F200 && c <= 0x1F6C5)
965         return true;
966
967     return isCJKIdeograph(c);
968 }
969
970 unsigned Font::expansionOpportunityCount(const LChar* characters, size_t length, TextDirection direction, bool& isAfterExpansion)
971 {
972     unsigned count = 0;
973     if (direction == LTR) {
974         for (size_t i = 0; i < length; ++i) {
975             if (treatAsSpace(characters[i])) {
976                 count++;
977                 isAfterExpansion = true;
978             } else
979                 isAfterExpansion = false;
980         }
981     } else {
982         for (size_t i = length; i > 0; --i) {
983             if (treatAsSpace(characters[i - 1])) {
984                 count++;
985                 isAfterExpansion = true;
986             } else
987                 isAfterExpansion = false;
988         }
989     }
990     return count;
991 }
992
993 unsigned Font::expansionOpportunityCount(const UChar* characters, size_t length, TextDirection direction, bool& isAfterExpansion)
994 {
995     static bool expandAroundIdeographs = canExpandAroundIdeographsInComplexText();
996     unsigned count = 0;
997     if (direction == LTR) {
998         for (size_t i = 0; i < length; ++i) {
999             UChar32 character = characters[i];
1000             if (treatAsSpace(character)) {
1001                 count++;
1002                 isAfterExpansion = true;
1003                 continue;
1004             }
1005             if (U16_IS_LEAD(character) && i + 1 < length && U16_IS_TRAIL(characters[i + 1])) {
1006                 character = U16_GET_SUPPLEMENTARY(character, characters[i + 1]);
1007                 i++;
1008             }
1009             if (expandAroundIdeographs && isCJKIdeographOrSymbol(character)) {
1010                 if (!isAfterExpansion)
1011                     count++;
1012                 count++;
1013                 isAfterExpansion = true;
1014                 continue;
1015             }
1016             isAfterExpansion = false;
1017         }
1018     } else {
1019         for (size_t i = length; i > 0; --i) {
1020             UChar32 character = characters[i - 1];
1021             if (treatAsSpace(character)) {
1022                 count++;
1023                 isAfterExpansion = true;
1024                 continue;
1025             }
1026             if (U16_IS_TRAIL(character) && i > 1 && U16_IS_LEAD(characters[i - 2])) {
1027                 character = U16_GET_SUPPLEMENTARY(characters[i - 2], character);
1028                 i--;
1029             }
1030             if (expandAroundIdeographs && isCJKIdeographOrSymbol(character)) {
1031                 if (!isAfterExpansion)
1032                     count++;
1033                 count++;
1034                 isAfterExpansion = true;
1035                 continue;
1036             }
1037             isAfterExpansion = false;
1038         }
1039     }
1040     return count;
1041 }
1042
1043 bool Font::canReceiveTextEmphasis(UChar32 c)
1044 {
1045     if (U_GET_GC_MASK(c) & (U_GC_Z_MASK | U_GC_CN_MASK | U_GC_CC_MASK | U_GC_CF_MASK))
1046         return false;
1047
1048     // Additional word-separator characters listed in CSS Text Level 3 Editor's Draft 3 November 2010.
1049     if (c == ethiopicWordspace || c == aegeanWordSeparatorLine || c == aegeanWordSeparatorDot
1050         || c == ugariticWordDivider || c == tibetanMarkIntersyllabicTsheg || c == tibetanMarkDelimiterTshegBstar)
1051         return false;
1052
1053     return true;
1054 }
1055     
1056 GlyphToPathTranslator::GlyphUnderlineType computeUnderlineType(const TextRun& textRun, const GlyphBuffer& glyphBuffer, unsigned index)
1057 {
1058     // In general, we want to skip descenders. However, skipping descenders on CJK characters leads to undesirable renderings,
1059     // so we want to draw through CJK characters (on a character-by-character basis).
1060     UChar32 baseCharacter;
1061     int initialOffsetInString = glyphBuffer.offsetInString(index);
1062
1063     if (initialOffsetInString == GlyphBuffer::kNoOffset) {
1064         // We have no idea which character spawned this glyph. Bail.
1065         return GlyphToPathTranslator::GlyphUnderlineType::DrawOverGlyph;
1066     }
1067     
1068     ASSERT(initialOffsetInString >= 0);
1069     unsigned offsetInString = static_cast<unsigned>(initialOffsetInString);
1070     
1071     if (textRun.is8Bit())
1072         baseCharacter = textRun.characters8()[offsetInString];
1073     else
1074         U16_NEXT(textRun.characters16(), offsetInString, textRun.length(), baseCharacter);
1075     
1076     // u_getIntPropertyValue with UCHAR_IDEOGRAPHIC doesn't return true for Japanese or Korean codepoints.
1077     // Instead, we can use the "Unicode allocation block" for the character.
1078     UBlockCode blockCode = ublock_getCode(baseCharacter);
1079     switch (blockCode) {
1080     case UBLOCK_CJK_RADICALS_SUPPLEMENT:
1081     case UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION:
1082     case UBLOCK_ENCLOSED_CJK_LETTERS_AND_MONTHS:
1083     case UBLOCK_CJK_COMPATIBILITY:
1084     case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A:
1085     case UBLOCK_CJK_UNIFIED_IDEOGRAPHS:
1086     case UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS:
1087     case UBLOCK_CJK_COMPATIBILITY_FORMS:
1088     case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B:
1089     case UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT:
1090     case UBLOCK_CJK_STROKES:
1091     case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C:
1092     case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D:
1093     case UBLOCK_IDEOGRAPHIC_DESCRIPTION_CHARACTERS:
1094     case UBLOCK_LINEAR_B_IDEOGRAMS:
1095     case UBLOCK_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT:
1096     case UBLOCK_HIRAGANA:
1097     case UBLOCK_KATAKANA:
1098     case UBLOCK_BOPOMOFO:
1099     case UBLOCK_BOPOMOFO_EXTENDED:
1100     case UBLOCK_HANGUL_JAMO:
1101     case UBLOCK_HANGUL_COMPATIBILITY_JAMO:
1102     case UBLOCK_HANGUL_SYLLABLES:
1103     case UBLOCK_HANGUL_JAMO_EXTENDED_A:
1104     case UBLOCK_HANGUL_JAMO_EXTENDED_B:
1105         return GlyphToPathTranslator::GlyphUnderlineType::DrawOverGlyph;
1106     default:
1107         return GlyphToPathTranslator::GlyphUnderlineType::SkipDescenders;
1108     }
1109 }
1110
1111 }