Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: src/ports/SkFontHost_FreeType.cpp

Issue 18040004: impl charsToGlyphs for freetype (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkBitmap.h" 9 #include "SkBitmap.h"
10 #include "SkCanvas.h" 10 #include "SkCanvas.h"
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 SkDELETE(rec); 331 SkDELETE(rec);
332 } 332 }
333 return; 333 return;
334 } 334 }
335 prev = rec; 335 prev = rec;
336 rec = next; 336 rec = next;
337 } 337 }
338 SkDEBUGFAIL("shouldn't get here, face not in list"); 338 SkDEBUGFAIL("shouldn't get here, face not in list");
339 } 339 }
340 340
341 class AutoFTAccess {
342 public:
343 AutoFTAccess(const SkTypeface* tf) : fRec(NULL), fFace(NULL) {
344 gFTMutex.acquire();
345 if (1 == ++gFTCount) {
346 if (!InitFreetype()) {
347 sk_throw();
348 }
349 }
350 fRec = ref_ft_face(tf);
351 if (fRec) {
352 fFace = fRec->fFace;
353 }
354 }
355
356 ~AutoFTAccess() {
357 if (fFace) {
358 unref_ft_face(fFace);
359 }
360 if (0 == --gFTCount) {
361 FT_Done_FreeType(gFTLibrary);
362 }
363 gFTMutex.release();
364 }
365
366 SkFaceRec* rec() { return fRec; }
367 FT_Face face() { return fFace; }
368
369 private:
370 SkFaceRec* fRec;
371 FT_Face fFace;
372 };
373
341 /////////////////////////////////////////////////////////////////////////// 374 ///////////////////////////////////////////////////////////////////////////
342 375
343 // Work around for old versions of freetype. 376 // Work around for old versions of freetype.
344 static FT_Error getAdvances(FT_Face face, FT_UInt start, FT_UInt count, 377 static FT_Error getAdvances(FT_Face face, FT_UInt start, FT_UInt count,
345 FT_Int32 loadFlags, FT_Fixed* advances) { 378 FT_Int32 loadFlags, FT_Fixed* advances) {
346 #ifdef FT_ADVANCES_H 379 #ifdef FT_ADVANCES_H
347 return FT_Get_Advances(face, start, count, loadFlags, advances); 380 return FT_Get_Advances(face, start, count, loadFlags, advances);
348 #else 381 #else
349 if (!face || start >= face->num_glyphs || 382 if (!face || start >= face->num_glyphs ||
350 start + count > face->num_glyphs || loadFlags != FT_LOAD_NO_SCALE) { 383 start + count > face->num_glyphs || loadFlags != FT_LOAD_NO_SCALE) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 } 481 }
449 } 482 }
450 483
451 SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( 484 SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics(
452 SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo, 485 SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
453 const uint32_t* glyphIDs, 486 const uint32_t* glyphIDs,
454 uint32_t glyphIDsCount) const { 487 uint32_t glyphIDsCount) const {
455 #if defined(SK_BUILD_FOR_MAC) 488 #if defined(SK_BUILD_FOR_MAC)
456 return NULL; 489 return NULL;
457 #else 490 #else
458 SkAutoMutexAcquire ac(gFTMutex); 491 AutoFTAccess fta(this);
459 FT_Library libInit = NULL; 492 FT_Face face = fta.face();
460 if (gFTCount == 0) { 493 if (!face) {
461 if (!InitFreetype()) 494 return NULL;
462 sk_throw();
463 libInit = gFTLibrary;
464 } 495 }
465 SkAutoTCallIProc<struct FT_LibraryRec_, FT_Done_FreeType> ftLib(libInit);
466 SkFaceRec* rec = ref_ft_face(this);
467 if (NULL == rec)
468 return NULL;
469 FT_Face face = rec->fFace;
470 496
471 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics; 497 SkAdvancedTypefaceMetrics* info = new SkAdvancedTypefaceMetrics;
472 info->fFontName.set(FT_Get_Postscript_Name(face)); 498 info->fFontName.set(FT_Get_Postscript_Name(face));
473 info->fMultiMaster = FT_HAS_MULTIPLE_MASTERS(face); 499 info->fMultiMaster = FT_HAS_MULTIPLE_MASTERS(face);
474 info->fLastGlyphID = face->num_glyphs - 1; 500 info->fLastGlyphID = face->num_glyphs - 1;
475 info->fEmSize = 1000; 501 info->fEmSize = 1000;
476 502
477 bool cid = false; 503 bool cid = false;
478 const char* fontType = FT_Get_X11_Font_Format(face); 504 const char* fontType = FT_Get_X11_Font_Format(face);
479 if (strcmp(fontType, "Type 1") == 0) { 505 if (strcmp(fontType, "Type 1") == 0) {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 647
622 if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo && 648 if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo &&
623 info->fType != SkAdvancedTypefaceMetrics::kType1_Font && 649 info->fType != SkAdvancedTypefaceMetrics::kType1_Font &&
624 face->num_charmaps) { 650 face->num_charmaps) {
625 populate_glyph_to_unicode(face, &(info->fGlyphToUnicode)); 651 populate_glyph_to_unicode(face, &(info->fGlyphToUnicode));
626 } 652 }
627 653
628 if (!canEmbed(face)) 654 if (!canEmbed(face))
629 info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font; 655 info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
630 656
631 unref_ft_face(face);
632 return info; 657 return info;
633 #endif 658 #endif
634 } 659 }
635 660
636 /////////////////////////////////////////////////////////////////////////// 661 ///////////////////////////////////////////////////////////////////////////
637 662
638 #define BLACK_LUMINANCE_LIMIT 0x40 663 #define BLACK_LUMINANCE_LIMIT 0x40
639 #define WHITE_LUMINANCE_LIMIT 0xA0 664 #define WHITE_LUMINANCE_LIMIT 0xA0
640 665
641 static bool bothZero(SkScalar a, SkScalar b) { 666 static bool bothZero(SkScalar a, SkScalar b) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 rec->setHinting(h); 718 rec->setHinting(h);
694 719
695 #ifndef SK_GAMMA_APPLY_TO_A8 720 #ifndef SK_GAMMA_APPLY_TO_A8
696 if (!isLCD(*rec)) { 721 if (!isLCD(*rec)) {
697 rec->ignorePreBlend(); 722 rec->ignorePreBlend();
698 } 723 }
699 #endif 724 #endif
700 } 725 }
701 726
702 int SkTypeface_FreeType::onGetUPEM() const { 727 int SkTypeface_FreeType::onGetUPEM() const {
703 SkAutoMutexAcquire ac(gFTMutex); 728 AutoFTAccess fta(this);
704 FT_Library libInit = NULL; 729 FT_Face face = fta.face();
705 if (gFTCount == 0) { 730 return face ? face->units_per_EM : 0;
706 if (!InitFreetype())
707 sk_throw();
708 libInit = gFTLibrary;
709 }
710 SkAutoTCallIProc<struct FT_LibraryRec_, FT_Done_FreeType> ftLib(libInit);
711 SkFaceRec *rec = ref_ft_face(this);
712 int unitsPerEm = 0;
713
714 if (rec != NULL && rec->fFace != NULL) {
715 unitsPerEm = rec->fFace->units_per_EM;
716 unref_ft_face(rec->fFace);
717 }
718
719 return unitsPerEm;
720 } 731 }
721 732
722 SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface, 733 SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface,
723 const SkDescriptor* desc) 734 const SkDescriptor* desc)
724 : SkScalerContext_FreeType_Base(typeface, desc) { 735 : SkScalerContext_FreeType_Base(typeface, desc) {
725 SkAutoMutexAcquire ac(gFTMutex); 736 SkAutoMutexAcquire ac(gFTMutex);
726 737
727 if (gFTCount == 0) { 738 if (gFTCount == 0) {
728 if (!InitFreetype()) { 739 if (!InitFreetype()) {
729 sk_throw(); 740 sk_throw();
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after
1313 my->fDescent = pts[2].fY; 1324 my->fDescent = pts[2].fY;
1314 my->fBottom = pts[3].fY; 1325 my->fBottom = pts[3].fY;
1315 my->fLeading = pts[4].fY; 1326 my->fLeading = pts[4].fY;
1316 my->fAvgCharWidth = pts[5].fY; 1327 my->fAvgCharWidth = pts[5].fY;
1317 my->fXMin = xmin; 1328 my->fXMin = xmin;
1318 my->fXMax = xmax; 1329 my->fXMax = xmax;
1319 my->fXHeight = x_height; 1330 my->fXHeight = x_height;
1320 } 1331 }
1321 } 1332 }
1322 1333
1323 //////////////////////////////////////////////////////////////////////// 1334 ///////////////////////////////////////////////////////////////////////////////
1324 //////////////////////////////////////////////////////////////////////// 1335
1336 #include "SkUtils.h"
1337
1338 static SkUnichar next_utf8(const void** chars) {
1339 return SkUTF8_NextUnichar((const char**)chars);
1340 }
1341
1342 static SkUnichar next_utf16(const void** chars) {
1343 return SkUTF16_NextUnichar((const uint16_t**)chars);
1344 }
1345
1346 static SkUnichar next_utf32(const void** chars) {
1347 const SkUnichar** uniChars = (const SkUnichar**)chars;
1348 SkUnichar uni = **uniChars;
1349 *uniChars += 1;
1350 return uni;
1351 }
1352
1353 typedef SkUnichar (*EncodingProc)(const void**);
1354
1355 static EncodingProc find_encoding_proc(SkTypeface::Encoding enc) {
1356 static const EncodingProc gProcs[] = {
1357 next_utf8, next_utf16, next_utf32
1358 };
1359 SkASSERT((size_t)enc < SK_ARRAY_COUNT(gProcs));
1360 return gProcs[enc];
1361 }
1362
1363 int SkTypeface_FreeType::onCharsToGlyphs(const void* chars, Encoding encoding,
1364 uint16_t glyphs[], int glyphCount) const {
1365 AutoFTAccess fta(this);
1366 FT_Face face = fta.face();
1367 if (!face) {
1368 if (glyphs) {
1369 sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
1370 }
1371 return 0;
1372 }
1373
1374 EncodingProc next_uni_proc = find_encoding_proc(encoding);
1375
1376 if (NULL == glyphs) {
1377 for (int i = 0; i < glyphCount; ++i) {
1378 if (0 == FT_Get_Char_Index(face, next_uni_proc(&chars))) {
1379 return i;
1380 }
1381 }
1382 return glyphCount;
1383 } else {
1384 int first = glyphCount;
1385 for (int i = 0; i < glyphCount; ++i) {
1386 unsigned id = FT_Get_Char_Index(face, next_uni_proc(&chars));
1387 glyphs[i] = SkToU16(id);
1388 if (0 == id && i < first) {
1389 first = i;
1390 }
1391 }
1392 return first;
1393 }
1394 }
1395
1396 int SkTypeface_FreeType::onCountGlyphs() const {
bungeman-skia 2013/07/02 16:04:20 Is this intended to replace SkScalerContext::gener
reed1 2013/07/02 16:14:37 Not sure I follow : I'm extracting a cached FT_Fac
bungeman-skia 2013/07/02 16:25:31 I suppose I'm just pointing out that the entirety
1397 // we cache this value, using -1 as a sentinel for "not computed"
1398 if (fGlyphCount < 0) {
1399 AutoFTAccess fta(this);
1400 FT_Face face = fta.face();
1401 // if the face failed, we still assign a non-negative value
1402 fGlyphCount = face ? face->num_glyphs : 0;
1403 }
1404 return fGlyphCount;
1405 }
1406
1407 ///////////////////////////////////////////////////////////////////////////////
1408 ///////////////////////////////////////////////////////////////////////////////
1325 1409
1326 /* Export this so that other parts of our FonttHost port can make use of our 1410 /* Export this so that other parts of our FonttHost port can make use of our
1327 ability to extract the name+style from a stream, using FreeType's api. 1411 ability to extract the name+style from a stream, using FreeType's api.
1328 */ 1412 */
1329 bool find_name_and_attributes(SkStream* stream, SkString* name, 1413 bool find_name_and_attributes(SkStream* stream, SkString* name,
1330 SkTypeface::Style* style, bool* isFixedPitch) { 1414 SkTypeface::Style* style, bool* isFixedPitch) {
1331 FT_Library library; 1415 FT_Library library;
1332 if (FT_Init_FreeType(&library)) { 1416 if (FT_Init_FreeType(&library)) {
1333 return false; 1417 return false;
1334 } 1418 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 *style = (SkTypeface::Style) tempStyle; 1459 *style = (SkTypeface::Style) tempStyle;
1376 } 1460 }
1377 if (isFixedPitch) { 1461 if (isFixedPitch) {
1378 *isFixedPitch = FT_IS_FIXED_WIDTH(face); 1462 *isFixedPitch = FT_IS_FIXED_WIDTH(face);
1379 } 1463 }
1380 1464
1381 FT_Done_Face(face); 1465 FT_Done_Face(face);
1382 FT_Done_FreeType(library); 1466 FT_Done_FreeType(library);
1383 return true; 1467 return true;
1384 } 1468 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698