tagging audio streams and changing audio sink to pulseaudio
[profile/ivi/webkit-efl.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 "FontTranscoder.h"
30 #include "IntPoint.h"
31 #include "GlyphBuffer.h"
32 #include "TextRun.h"
33 #include "WidthIterator.h"
34 #include <wtf/MainThread.h>
35 #include <wtf/MathExtras.h>
36 #include <wtf/text/StringBuilder.h>
37 #include <wtf/UnusedParam.h>
38
39 using namespace WTF;
40 using namespace Unicode;
41
42 namespace WebCore {
43
44 const uint8_t Font::s_roundingHackCharacterTable[256] = {
45     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,
46     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 /*?*/,
47     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,
48     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,
49     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,
50     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,
51     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,
52     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
53 };
54
55 Font::CodePath Font::s_codePath = Auto;
56
57 // ============================================================================================
58 // Font Implementation (Cross-Platform Portion)
59 // ============================================================================================
60
61 Font::Font()
62     : m_letterSpacing(0)
63     , m_wordSpacing(0)
64     , m_isPlatformFont(false)
65     , m_needsTranscoding(false)
66 {
67 }
68
69 Font::Font(const FontDescription& fd, short letterSpacing, short wordSpacing) 
70     : m_fontDescription(fd)
71     , m_letterSpacing(letterSpacing)
72     , m_wordSpacing(wordSpacing)
73     , m_isPlatformFont(false)
74     , m_needsTranscoding(fontTranscoder().needsTranscoding(fd))
75 {
76 }
77
78 Font::Font(const FontPlatformData& fontData, bool isPrinterFont, FontSmoothingMode fontSmoothingMode)
79     : m_fontList(FontFallbackList::create())
80     , m_letterSpacing(0)
81     , m_wordSpacing(0)
82     , m_isPlatformFont(true)
83 {
84     m_fontDescription.setUsePrinterFont(isPrinterFont);
85     m_fontDescription.setFontSmoothing(fontSmoothingMode);
86     m_needsTranscoding = fontTranscoder().needsTranscoding(fontDescription());
87     m_fontList->setPlatformFont(fontData);
88 }
89
90 Font::Font(const Font& other)
91     : m_fontDescription(other.m_fontDescription)
92     , m_fontList(other.m_fontList)
93     , m_letterSpacing(other.m_letterSpacing)
94     , m_wordSpacing(other.m_wordSpacing)
95     , m_isPlatformFont(other.m_isPlatformFont)
96     , m_needsTranscoding(other.m_needsTranscoding)
97 {
98 }
99
100 Font& Font::operator=(const Font& other)
101 {
102     m_fontDescription = other.m_fontDescription;
103     m_fontList = other.m_fontList;
104     m_letterSpacing = other.m_letterSpacing;
105     m_wordSpacing = other.m_wordSpacing;
106     m_isPlatformFont = other.m_isPlatformFont;
107     m_needsTranscoding = other.m_needsTranscoding;
108     return *this;
109 }
110
111 bool Font::operator==(const Font& other) const
112 {
113     // Our FontData don't have to be checked, since checking the font description will be fine.
114     // FIXME: This does not work if the font was made with the FontPlatformData constructor.
115     if (loadingCustomFonts() || other.loadingCustomFonts())
116         return false;
117     
118     FontSelector* first = m_fontList ? m_fontList->fontSelector() : 0;
119     FontSelector* second = other.m_fontList ? other.m_fontList->fontSelector() : 0;
120
121     return first == second
122            && m_fontDescription == other.m_fontDescription
123            && m_letterSpacing == other.m_letterSpacing
124            && m_wordSpacing == other.m_wordSpacing
125            && (m_fontList ? m_fontList->fontSelectorVersion() : 0) == (other.m_fontList ? other.m_fontList->fontSelectorVersion() : 0)
126            && (m_fontList ? m_fontList->generation() : 0) == (other.m_fontList ? other.m_fontList->generation() : 0);
127 }
128
129 void Font::update(PassRefPtr<FontSelector> fontSelector) const
130 {
131     // FIXME: It is pretty crazy that we are willing to just poke into a RefPtr, but it ends up 
132     // being reasonably safe (because inherited fonts in the render tree pick up the new
133     // style anyway. Other copies are transient, e.g., the state in the GraphicsContext, and
134     // won't stick around long enough to get you in trouble). Still, this is pretty disgusting,
135     // and could eventually be rectified by using RefPtrs for Fonts themselves.
136     if (!m_fontList)
137         m_fontList = FontFallbackList::create();
138     m_fontList->invalidate(fontSelector);
139 }
140
141 void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to, CustomFontNotReadyAction customFontNotReadyAction) const
142 {
143     // Don't draw anything while we are using custom fonts that are in the process of loading,
144     // except if the 'force' argument is set to true (in which case it will use a fallback
145     // font).
146     if (loadingCustomFonts() && customFontNotReadyAction == DoNotPaintIfFontNotReady)
147         return;
148     
149     to = (to == -1 ? run.length() : to);
150
151     CodePath codePathToUse = codePath(run);
152
153     if (codePathToUse != Complex)
154         return drawSimpleText(context, run, point, from, to);
155
156     return drawComplexText(context, run, point, from, to);
157 }
158
159 void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) const
160 {
161     if (loadingCustomFonts())
162         return;
163
164     if (to < 0)
165         to = run.length();
166
167     if (codePath(run) != Complex)
168         drawEmphasisMarksForSimpleText(context, run, mark, point, from, to);
169     else
170         drawEmphasisMarksForComplexText(context, run, mark, point, from, to);
171 }
172
173 float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
174 {
175     CodePath codePathToUse = codePath(run);
176     if (codePathToUse != Complex) {
177         // If the complex text implementation cannot return fallback fonts, avoid
178         // returning them for simple text as well.
179         static bool returnFallbackFonts = canReturnFallbackFontsForComplexText();
180         return floatWidthForSimpleText(run, 0, returnFallbackFonts ? fallbackFonts : 0, codePathToUse == SimpleWithGlyphOverflow || (glyphOverflow && glyphOverflow->computeBounds) ? glyphOverflow : 0);
181     }
182
183     return floatWidthForComplexText(run, fallbackFonts, glyphOverflow);
184 }
185
186 float Font::width(const TextRun& run, int& charsConsumed, String& glyphName) const
187 {
188 #if ENABLE(SVG_FONTS)
189     if (TextRun::RenderingContext* renderingContext = run.renderingContext())
190         return renderingContext->floatWidthUsingSVGFont(*this, run, charsConsumed, glyphName);
191 #endif
192
193     charsConsumed = run.length();
194     glyphName = "";
195
196     if (codePath(run) != Complex)
197         return floatWidthForSimpleText(run, 0);
198
199     return floatWidthForComplexText(run);
200 }
201
202 FloatRect Font::selectionRectForText(const TextRun& run, const FloatPoint& point, int h, int from, int to) const
203 {
204     to = (to == -1 ? run.length() : to);
205
206     if (codePath(run) != Complex)
207         return selectionRectForSimpleText(run, point, h, from, to);
208
209     return selectionRectForComplexText(run, point, h, from, to);
210 }
211
212 int Font::offsetForPosition(const TextRun& run, float x, bool includePartialGlyphs) const
213 {
214     if (codePath(run) != Complex)
215         return offsetForPositionForSimpleText(run, x, includePartialGlyphs);
216
217     return offsetForPositionForComplexText(run, x, includePartialGlyphs);
218 }
219
220 String Font::normalizeSpaces(const UChar* characters, unsigned length)
221 {
222     StringBuilder normalized;
223     normalized.reserveCapacity(length);
224
225     for (unsigned i = 0; i < length; ++i)
226         normalized.append(normalizeSpaces(characters[i]));
227
228     return normalized.toString();
229 }
230
231 static bool shouldUseFontSmoothing = true;
232
233 void Font::setShouldUseSmoothing(bool shouldUseSmoothing)
234 {
235     ASSERT(isMainThread());
236     shouldUseFontSmoothing = shouldUseSmoothing;
237 }
238
239 bool Font::shouldUseSmoothing()
240 {
241     return shouldUseFontSmoothing;
242 }
243
244 void Font::setCodePath(CodePath p)
245 {
246     s_codePath = p;
247 }
248
249 Font::CodePath Font::codePath()
250 {
251     return s_codePath;
252 }
253
254 Font::CodePath Font::codePath(const TextRun& run) const
255 {
256     if (s_codePath != Auto)
257         return s_codePath;
258
259 #if ENABLE(SVG_FONTS)
260     if (run.renderingContext())
261         return Simple;
262 #endif
263
264 #if PLATFORM(QT) && !HAVE(QRAWFONT)
265     if (run.expansion() || run.rtl() || isSmallCaps() || wordSpacing() || letterSpacing())
266         return Complex;
267 #endif
268
269     if (m_fontDescription.featureSettings() && m_fontDescription.featureSettings()->size() > 0)
270         return Complex;
271     
272     if (run.length() > 1 && typesettingFeatures())
273         return Complex;
274
275     if (!run.characterScanForCodePath())
276         return Simple;
277
278     // Start from 0 since drawing and highlighting also measure the characters before run->from.
279     return characterRangeCodePath(run.characters(), run.length());
280 }
281
282 Font::CodePath Font::characterRangeCodePath(const UChar* characters, unsigned len)
283 {
284     // FIXME: Should use a UnicodeSet in ports where ICU is used. Note that we 
285     // can't simply use UnicodeCharacter Property/class because some characters
286     // are not 'combining', but still need to go to the complex path.
287     // Alternatively, we may as well consider binary search over a sorted
288     // list of ranges.
289     CodePath result = Simple;
290     for (unsigned i = 0; i < len; i++) {
291         const UChar c = characters[i];
292         if (c < 0x2E5) // U+02E5 through U+02E9 (Modifier Letters : Tone letters)  
293             continue;
294         if (c <= 0x2E9) 
295             return Complex;
296
297         if (c < 0x300) // U+0300 through U+036F Combining diacritical marks
298             continue;
299         if (c <= 0x36F)
300             return Complex;
301
302         if (c < 0x0591 || c == 0x05BE) // U+0591 through U+05CF excluding U+05BE Hebrew combining marks, Hebrew punctuation Paseq, Sof Pasuq and Nun Hafukha
303             continue;
304         if (c <= 0x05CF)
305             return Complex;
306
307         // U+0600 through U+109F Arabic, Syriac, Thaana, NKo, Samaritan, Mandaic,
308         // Devanagari, Bengali, Gurmukhi, Gujarati, Oriya, Tamil, Telugu, Kannada, 
309         // Malayalam, Sinhala, Thai, Lao, Tibetan, Myanmar
310         if (c < 0x0600) 
311             continue;
312         if (c <= 0x109F)
313             return Complex;
314
315         // U+1100 through U+11FF Hangul Jamo (only Ancient Korean should be left here if you precompose;
316         // Modern Korean will be precomposed as a result of step A)
317         if (c < 0x1100)
318             continue;
319         if (c <= 0x11FF)
320             return Complex;
321
322         if (c < 0x135D) // U+135D through U+135F Ethiopic combining marks
323             continue;
324         if (c <= 0x135F)
325             return Complex;
326
327         if (c < 0x1700) // U+1780 through U+18AF Tagalog, Hanunoo, Buhid, Taghanwa,Khmer, Mongolian
328             continue;
329         if (c <= 0x18AF)
330             return Complex;
331
332         if (c < 0x1900) // U+1900 through U+194F Limbu (Unicode 4.0)
333             continue;
334         if (c <= 0x194F)
335             return Complex;
336
337         if (c < 0x1980) // U+1980 through U+19DF New Tai Lue
338             continue;
339         if (c <= 0x19DF)
340             return Complex;
341
342         if (c < 0x1A00) // U+1A00 through U+1CFF Buginese, Tai Tham, Balinese, Batak, Lepcha, Vedic
343             continue;
344         if (c <= 0x1CFF)
345             return Complex;
346
347         if (c < 0x1DC0) // U+1DC0 through U+1DFF Comining diacritical mark supplement
348             continue;
349         if (c <= 0x1DFF)
350             return Complex;
351
352         // U+1E00 through U+2000 characters with diacritics and stacked diacritics
353         if (c <= 0x2000) {
354             result = SimpleWithGlyphOverflow;
355             continue;
356         }
357
358         if (c < 0x20D0) // U+20D0 through U+20FF Combining marks for symbols
359             continue;
360         if (c <= 0x20FF)
361             return Complex;
362
363         if (c < 0x2CEF) // U+2CEF through U+2CF1 Combining marks for Coptic
364             continue;
365         if (c <= 0x2CF1)
366             return Complex;
367
368         if (c < 0x302A) // U+302A through U+302F Ideographic and Hangul Tone marks
369             continue;
370         if (c <= 0x302F)
371             return Complex;
372
373         if (c < 0xA67C) // U+A67C through U+A67D Combining marks for old Cyrillic
374             continue;
375         if (c <= 0xA67D)
376             return Complex;
377
378         if (c < 0xA6F0) // U+A6F0 through U+A6F1 Combining mark for Bamum
379             continue;
380         if (c <= 0xA6F1)
381             return Complex;
382
383        // U+A800 through U+ABFF Nagri, Phags-pa, Saurashtra, Devanagari Extended,
384        // Hangul Jamo Ext. A, Javanese, Myanmar Extended A, Tai Viet, Meetei Mayek,
385         if (c < 0xA800) 
386             continue;
387         if (c <= 0xABFF)
388             return Complex;
389
390         if (c < 0xD7B0) // U+D7B0 through U+D7FF Hangul Jamo Ext. B
391             continue;
392         if (c <= 0xD7FF)
393             return Complex;
394
395         if (c <= 0xDBFF) {
396             // High surrogate
397
398             if (i == len - 1)
399                 continue;
400
401             UChar next = characters[++i];
402             if (!U16_IS_TRAIL(next))
403                 continue;
404
405             UChar32 supplementaryCharacter = U16_GET_SUPPLEMENTARY(c, next);
406
407             if (supplementaryCharacter < 0x1F1E6) // U+1F1E6 through U+1F1FF Regional Indicator Symbols
408                 continue;
409             if (supplementaryCharacter <= 0x1F1FF)
410                 return Complex;
411
412             if (supplementaryCharacter < 0xE0100) // U+E0100 through U+E01EF Unicode variation selectors.
413                 continue;
414             if (supplementaryCharacter <= 0xE01EF)
415                 return Complex;
416
417             // FIXME: Check for Brahmi (U+11000 block), Kaithi (U+11080 block) and other complex scripts
418             // in plane 1 or higher.
419
420             continue;
421         }
422
423         if (c < 0xFE00) // U+FE00 through U+FE0F Unicode variation selectors
424             continue;
425         if (c <= 0xFE0F)
426             return Complex;
427
428         if (c < 0xFE20) // U+FE20 through U+FE2F Combining half marks
429             continue;
430         if (c <= 0xFE2F)
431             return Complex;
432     }
433     return result;
434 }
435
436 bool Font::isCJKIdeograph(UChar32 c)
437 {
438     // The basic CJK Unified Ideographs block.
439     if (c >= 0x4E00 && c <= 0x9FFF)
440         return true;
441     
442     // CJK Unified Ideographs Extension A.
443     if (c >= 0x3400 && c <= 0x4DBF)
444         return true;
445     
446     // CJK Radicals Supplement.
447     if (c >= 0x2E80 && c <= 0x2EFF)
448         return true;
449     
450     // Kangxi Radicals.
451     if (c >= 0x2F00 && c <= 0x2FDF)
452         return true;
453     
454     // CJK Strokes.
455     if (c >= 0x31C0 && c <= 0x31EF)
456         return true;
457     
458     // CJK Compatibility Ideographs.
459     if (c >= 0xF900 && c <= 0xFAFF)
460         return true;
461     
462     // CJK Unified Ideographs Extension B.
463     if (c >= 0x20000 && c <= 0x2A6DF)
464         return true;
465         
466     // CJK Unified Ideographs Extension C.
467     if (c >= 0x2A700 && c <= 0x2B73F)
468         return true;
469     
470     // CJK Unified Ideographs Extension D.
471     if (c >= 0x2B740 && c <= 0x2B81F)
472         return true;
473     
474     // CJK Compatibility Ideographs Supplement.
475     if (c >= 0x2F800 && c <= 0x2FA1F)
476         return true;
477
478     return false;
479 }
480
481 bool Font::isCJKIdeographOrSymbol(UChar32 c)
482 {
483     // 0x2C7 Caron, Mandarin Chinese 3rd Tone
484     // 0x2CA Modifier Letter Acute Accent, Mandarin Chinese 2nd Tone
485     // 0x2CB Modifier Letter Grave Access, Mandarin Chinese 4th Tone 
486     // 0x2D9 Dot Above, Mandarin Chinese 5th Tone 
487     if ((c == 0x2C7) || (c == 0x2CA) || (c == 0x2CB) || (c == 0x2D9))
488         return true;
489
490     // Ideographic Description Characters.
491     if (c >= 0x2FF0 && c <= 0x2FFF)
492         return true;
493     
494     // CJK Symbols and Punctuation.
495     if (c >= 0x3000 && c <= 0x303F)
496         return true;
497    
498     // Hiragana 
499     if (c >= 0x3040 && c <= 0x309F)
500         return true;
501
502     // Katakana 
503     if (c >= 0x30A0 && c <= 0x30FF)
504         return true;
505
506     // Bopomofo
507     if (c >= 0x3100 && c <= 0x312F)
508         return true;
509     
510     // Bopomofo Extended
511     if (c >= 0x31A0 && c <= 0x31BF)
512         return true;
513  
514     // Enclosed CJK Letters and Months.
515     if (c >= 0x3200 && c <= 0x32FF)
516         return true;
517     
518     // CJK Compatibility.
519     if (c >= 0x3300 && c <= 0x33FF)
520         return true;
521     
522     // CJK Compatibility Forms.
523     if (c >= 0xFE30 && c <= 0xFE4F)
524         return true;
525
526     // Halfwidth and Fullwidth Forms
527     // Usually only used in CJK
528     if (c >= 0xFF00 && c <= 0xFFEF)
529         return true;
530
531     // Emoji.
532     if (c >= 0x1F200 && c <= 0x1F6F)
533         return true;
534
535     return isCJKIdeograph(c);
536 }
537
538 unsigned Font::expansionOpportunityCount(const UChar* characters, size_t length, TextDirection direction, bool& isAfterExpansion)
539 {
540     static bool expandAroundIdeographs = canExpandAroundIdeographsInComplexText();
541     unsigned count = 0;
542     if (direction == LTR) {
543         for (size_t i = 0; i < length; ++i) {
544             UChar32 character = characters[i];
545             if (treatAsSpace(character)) {
546                 count++;
547                 isAfterExpansion = true;
548                 continue;
549             }
550             if (U16_IS_LEAD(character) && i + 1 < length && U16_IS_TRAIL(characters[i + 1])) {
551                 character = U16_GET_SUPPLEMENTARY(character, characters[i + 1]);
552                 i++;
553             }
554             if (expandAroundIdeographs && isCJKIdeographOrSymbol(character)) {
555                 if (!isAfterExpansion)
556                     count++;
557                 count++;
558                 isAfterExpansion = true;
559                 continue;
560             }
561             isAfterExpansion = false;
562         }
563     } else {
564         for (size_t i = length; i > 0; --i) {
565             UChar32 character = characters[i - 1];
566             if (treatAsSpace(character)) {
567                 count++;
568                 isAfterExpansion = true;
569                 continue;
570             }
571             if (U16_IS_TRAIL(character) && i > 1 && U16_IS_LEAD(characters[i - 2])) {
572                 character = U16_GET_SUPPLEMENTARY(characters[i - 2], character);
573                 i--;
574             }
575             if (expandAroundIdeographs && isCJKIdeographOrSymbol(character)) {
576                 if (!isAfterExpansion)
577                     count++;
578                 count++;
579                 isAfterExpansion = true;
580                 continue;
581             }
582             isAfterExpansion = false;
583         }
584     }
585     return count;
586 }
587
588 bool Font::canReceiveTextEmphasis(UChar32 c)
589 {
590     CharCategory category = Unicode::category(c);
591     if (category & (Separator_Space | Separator_Line | Separator_Paragraph | Other_NotAssigned | Other_Control | Other_Format))
592         return false;
593
594     // Additional word-separator characters listed in CSS Text Level 3 Editor's Draft 3 November 2010.
595     if (c == ethiopicWordspace || c == aegeanWordSeparatorLine || c == aegeanWordSeparatorDot
596         || c == ugariticWordDivider || c == tibetanMarkIntersyllabicTsheg || c == tibetanMarkDelimiterTshegBstar)
597         return false;
598
599     return true;
600 }
601
602 }