OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkAdvancedTypefaceMetrics.h" | 8 #include "SkAdvancedTypefaceMetrics.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 FT_Error err = FT_Open_Face(gFTLibrary->library(), &args, data->getIndex(),
&rec->fFace); | 345 FT_Error err = FT_Open_Face(gFTLibrary->library(), &args, data->getIndex(),
&rec->fFace); |
346 if (err) { | 346 if (err) { |
347 SkDEBUGF(("ERROR: unable to open font '%x'\n", fontID)); | 347 SkDEBUGF(("ERROR: unable to open font '%x'\n", fontID)); |
348 SkDELETE(rec); | 348 SkDELETE(rec); |
349 return NULL; | 349 return NULL; |
350 } | 350 } |
351 SkASSERT(rec->fFace); | 351 SkASSERT(rec->fFace); |
352 | 352 |
353 ft_face_setup_axes(rec->fFace, *data); | 353 ft_face_setup_axes(rec->fFace, *data); |
354 | 354 |
| 355 // FreeType will set the charmap to the "most unicode" cmap if it exists. |
| 356 // If there are no unicode cmaps, the charmap is set to NULL. |
| 357 // However, "symbol" cmaps should also be considered "fallback unicode" cmap
s |
| 358 // because they are effectively private use area only (even if they aren't). |
| 359 // This is the last on the fallback list at |
| 360 // https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cma
p.html |
| 361 if (!rec->fFace->charmap) { |
| 362 FT_Select_Charmap(rec->fFace, FT_ENCODING_MS_SYMBOL); |
| 363 } |
| 364 |
355 rec->fNext = gFaceRecHead; | 365 rec->fNext = gFaceRecHead; |
356 gFaceRecHead = rec; | 366 gFaceRecHead = rec; |
357 return rec; | 367 return rec; |
358 } | 368 } |
359 | 369 |
360 // Caller must lock gFTMutex before calling this function. | 370 // Caller must lock gFTMutex before calling this function. |
361 static void unref_ft_face(FT_Face face) { | 371 static void unref_ft_face(FT_Face face) { |
362 gFTMutex.assertHeld(); | 372 gFTMutex.assertHeld(); |
363 | 373 |
364 SkFaceRec* rec = gFaceRecHead; | 374 SkFaceRec* rec = gFaceRecHead; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 FT_Fixed advance = 0; | 449 FT_Fixed advance = 0; |
440 if (FT_Get_Advances(face, gId, 1, FT_LOAD_NO_SCALE, &advance)) { | 450 if (FT_Get_Advances(face, gId, 1, FT_LOAD_NO_SCALE, &advance)) { |
441 return false; | 451 return false; |
442 } | 452 } |
443 SkASSERT(data); | 453 SkASSERT(data); |
444 *data = advance; | 454 *data = advance; |
445 return true; | 455 return true; |
446 } | 456 } |
447 | 457 |
448 static void populate_glyph_to_unicode(FT_Face& face, SkTDArray<SkUnichar>* glyph
ToUnicode) { | 458 static void populate_glyph_to_unicode(FT_Face& face, SkTDArray<SkUnichar>* glyph
ToUnicode) { |
449 // Check and see if we have Unicode cmaps. | 459 glyphToUnicode->setCount(face->num_glyphs); |
450 for (int i = 0; i < face->num_charmaps; ++i) { | 460 sk_bzero(glyphToUnicode->begin(), sizeof((*glyphToUnicode)[0]) * face->num_g
lyphs); |
451 // CMaps known to support Unicode: | |
452 // Platform ID Encoding ID Name | |
453 // ----------- ----------- ----------------------------------- | |
454 // 0 0,1 Apple Unicode | |
455 // 0 3 Apple Unicode 2.0 (preferred) | |
456 // 3 1 Microsoft Unicode UCS-2 | |
457 // 3 10 Microsoft Unicode UCS-4 (preferred) | |
458 // | |
459 // See Apple TrueType Reference Manual | |
460 // http://developer.apple.com/fonts/TTRefMan/RM06/Chap6cmap.html | |
461 // http://developer.apple.com/fonts/TTRefMan/RM06/Chap6name.html#ID | |
462 // Microsoft OpenType Specification | |
463 // http://www.microsoft.com/typography/otspec/cmap.htm | |
464 | 461 |
465 FT_UShort platformId = face->charmaps[i]->platform_id; | 462 FT_UInt glyphIndex; |
466 FT_UShort encodingId = face->charmaps[i]->encoding_id; | 463 SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex); |
467 | 464 while (glyphIndex) { |
468 if (platformId != 0 && platformId != 3) { | 465 (*glyphToUnicode)[glyphIndex] = charCode; |
469 continue; | 466 charCode = FT_Get_Next_Char(face, charCode, &glyphIndex); |
470 } | |
471 if (platformId == 3 && encodingId != 1 && encodingId != 10) { | |
472 continue; | |
473 } | |
474 bool preferredMap = ((platformId == 3 && encodingId == 10) || | |
475 (platformId == 0 && encodingId == 3)); | |
476 | |
477 FT_Set_Charmap(face, face->charmaps[i]); | |
478 if (glyphToUnicode->isEmpty()) { | |
479 glyphToUnicode->setCount(face->num_glyphs); | |
480 memset(glyphToUnicode->begin(), 0, | |
481 sizeof(SkUnichar) * face->num_glyphs); | |
482 } | |
483 | |
484 // Iterate through each cmap entry. | |
485 FT_UInt glyphIndex; | |
486 for (SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex); | |
487 glyphIndex != 0; | |
488 charCode = FT_Get_Next_Char(face, charCode, &glyphIndex)) { | |
489 if (charCode && | |
490 ((*glyphToUnicode)[glyphIndex] == 0 || preferredMap)) { | |
491 (*glyphToUnicode)[glyphIndex] = charCode; | |
492 } | |
493 } | |
494 } | 467 } |
495 } | 468 } |
496 | 469 |
497 SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( | 470 SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( |
498 PerGlyphInfo perGlyphInfo, | 471 PerGlyphInfo perGlyphInfo, |
499 const uint32_t* glyphIDs, | 472 const uint32_t* glyphIDs, |
500 uint32_t glyphIDsCount) const { | 473 uint32_t glyphIDsCount) const { |
501 #if defined(SK_BUILD_FOR_MAC) | 474 #if defined(SK_BUILD_FOR_MAC) |
502 return NULL; | 475 return NULL; |
503 #else | 476 #else |
(...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1500 | 1473 |
1501 static EncodingProc find_encoding_proc(SkTypeface::Encoding enc) { | 1474 static EncodingProc find_encoding_proc(SkTypeface::Encoding enc) { |
1502 static const EncodingProc gProcs[] = { | 1475 static const EncodingProc gProcs[] = { |
1503 next_utf8, next_utf16, next_utf32 | 1476 next_utf8, next_utf16, next_utf32 |
1504 }; | 1477 }; |
1505 SkASSERT((size_t)enc < SK_ARRAY_COUNT(gProcs)); | 1478 SkASSERT((size_t)enc < SK_ARRAY_COUNT(gProcs)); |
1506 return gProcs[enc]; | 1479 return gProcs[enc]; |
1507 } | 1480 } |
1508 | 1481 |
1509 int SkTypeface_FreeType::onCharsToGlyphs(const void* chars, Encoding encoding, | 1482 int SkTypeface_FreeType::onCharsToGlyphs(const void* chars, Encoding encoding, |
1510 uint16_t glyphs[], int glyphCount) const { | 1483 uint16_t glyphs[], int glyphCount) cons
t |
| 1484 { |
1511 AutoFTAccess fta(this); | 1485 AutoFTAccess fta(this); |
1512 FT_Face face = fta.face(); | 1486 FT_Face face = fta.face(); |
1513 if (!face) { | 1487 if (!face) { |
1514 if (glyphs) { | 1488 if (glyphs) { |
1515 sk_bzero(glyphs, glyphCount * sizeof(glyphs[0])); | 1489 sk_bzero(glyphs, glyphCount * sizeof(glyphs[0])); |
1516 } | 1490 } |
1517 return 0; | 1491 return 0; |
1518 } | 1492 } |
1519 | 1493 |
1520 EncodingProc next_uni_proc = find_encoding_proc(encoding); | 1494 EncodingProc next_uni_proc = find_encoding_proc(encoding); |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1777 (*axes)[i].fTag = ftAxis.tag; | 1751 (*axes)[i].fTag = ftAxis.tag; |
1778 (*axes)[i].fMinimum = ftAxis.minimum; | 1752 (*axes)[i].fMinimum = ftAxis.minimum; |
1779 (*axes)[i].fDefault = ftAxis.def; | 1753 (*axes)[i].fDefault = ftAxis.def; |
1780 (*axes)[i].fMaximum = ftAxis.maximum; | 1754 (*axes)[i].fMaximum = ftAxis.maximum; |
1781 } | 1755 } |
1782 } | 1756 } |
1783 | 1757 |
1784 FT_Done_Face(face); | 1758 FT_Done_Face(face); |
1785 return true; | 1759 return true; |
1786 } | 1760 } |
OLD | NEW |