SkFontHost_linux.cpp revision fe74765f0d302669ae49e68074492bdfe0ce6e6f
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFontHost.h" 110fc17c33f144956bb75650f991226a14e555f189reed@google.com#include "SkFontHost_FreeType_common.h" 129714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com#include "SkFontDescriptor.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDescriptor.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkOSFile.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h" 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkString.h" 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h" 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkThread.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTSearch.h" 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SK_FONT_FILE_PREFIX 222cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com #define SK_FONT_FILE_PREFIX "/usr/share/fonts/truetype/" 232cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com#endif 242cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com#ifndef SK_FONT_FILE_DIR_SEPERATOR 252cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com #define SK_FONT_FILE_DIR_SEPERATOR "/" 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 284dc686d75353235260c716242f4ed596b70beb95djsollen@google.combool find_name_and_attributes(SkStream* stream, SkString* name, 29fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com SkTypeface::Style* style, bool* isFixedPitch); 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct FamilyRec; 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This guy holds a mapping of a name -> family, used for looking up fonts. 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since it is stored in a stretchy array that doesn't preserve object 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com semantics, we don't use constructor/destructors, but just have explicit 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com helpers to manage our internal bookkeeping. 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct NameFamilyPair { 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* fName; // we own this 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* fFamily; // we don't own this, we just reference it 43ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void construct(const char name[], FamilyRec* family) 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fName = strdup(name); 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFamily = family; // we don't own this, so just record the referene 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void destruct() 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com free((char*)fName); 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we don't own family, so just ignore our reference 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// we use atomic_inc to grow this for each typeface we create 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic int32_t gUniqueFontID; 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// this is the mutex that protects these globals 601771cbf43d9a1334e3d870c635b4215bb888dd98digit@google.comSK_DECLARE_STATIC_MUTEX(gFamilyMutex); 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic FamilyRec* gFamilyHead; 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTDArray<NameFamilyPair> gNameList; 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct FamilyRec { 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* fNext; 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface* fFaces[4]; 67ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec() 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fNext = gFamilyHead; 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(fFaces, 0, sizeof(fFaces)); 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gFamilyHead = this; 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTypeface* find_best_face(const FamilyRec* family, 771bfd0ca7804a082ce29fd56adb311c79fc11a99freed@android.com SkTypeface::Style style) { 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface* const* faces = family->fFaces; 79ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (faces[style] != NULL) { // exact match 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return faces[style]; 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // look for a matching bold 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com style = (SkTypeface::Style)(style ^ SkTypeface::kItalic); 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (faces[style] != NULL) { 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return faces[style]; 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // look for the plain 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (faces[SkTypeface::kNormal] != NULL) { 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return faces[SkTypeface::kNormal]; 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // look for anything 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 4; i++) { 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (faces[i] != NULL) { 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return faces[i]; 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // should never get here, since the faces list should not be empty 990c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("faces list is empty"); 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1031bfd0ca7804a082ce29fd56adb311c79fc11a99freed@android.comstatic FamilyRec* find_family(const SkTypeface* member) { 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* curr = gFamilyHead; 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (curr != NULL) { 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 4; i++) { 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (curr->fFaces[i] == member) { 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return curr; 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com curr = curr->fNext; 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 116f2afb67bab01062d2632543c1f004b166bf01e31reed@android.comstatic SkTypeface* find_from_uniqueID(uint32_t uniqueID) { 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* curr = gFamilyHead; 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (curr != NULL) { 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 4; i++) { 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface* face = curr->fFaces[i]; 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (face != NULL && face->uniqueID() == uniqueID) { 122f2afb67bab01062d2632543c1f004b166bf01e31reed@android.com return face; 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com curr = curr->fNext; 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 12717b78946096265d80215a6c946286ecaa35ea7edepoger@google.com return NULL; 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* Remove reference to this face from its family. If the resulting family 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com is empty (has no faces), return that family, otherwise return NULL 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1331bfd0ca7804a082ce29fd56adb311c79fc11a99freed@android.comstatic FamilyRec* remove_from_family(const SkTypeface* face) { 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* family = find_family(face); 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(family->fFaces[face->style()] == face); 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com family->fFaces[face->style()] = NULL; 137ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 4; i++) { 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (family->fFaces[i] != NULL) { // family is non-empty 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return family; // return the empty family 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// maybe we should make FamilyRec be doubly-linked 1471bfd0ca7804a082ce29fd56adb311c79fc11a99freed@android.comstatic void detach_and_delete_family(FamilyRec* family) { 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* curr = gFamilyHead; 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* prev = NULL; 150ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (curr != NULL) { 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* next = curr->fNext; 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (curr == family) { 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (prev == NULL) { 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gFamilyHead = next; 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com prev->fNext = next; 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(family); 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com prev = curr; 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com curr = next; 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1650c00f21fee3f5cfa3aa7e5d46ff94cb8cf340451tomhudson@google.com SkDEBUGFAIL("Yikes, couldn't find family in our list to remove/delete"); 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1689714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.comstatic const char* find_family_name(const SkTypeface* familyMember) { 1699714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com const FamilyRec* familyRec = find_family(familyMember); 1709714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com for (int i = 0; i < gNameList.count(); i++) { 1719714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com if (gNameList[i].fFamily == familyRec) { 1729714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com return gNameList[i].fName; 1739714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com } 1749714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com } 1759714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com return NULL; 1769714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com} 1779714516a0db56fe1c59d5e831cb0c6d820102c30djsollen@google.com 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic FamilyRec* find_familyrec(const char name[]) { 179ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com const NameFamilyPair* list = gNameList.begin(); 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int index = SkStrLCSearch(&list[0].fName, gNameList.count(), name, 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sizeof(list[0])); 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return index >= 0 ? list[index].fFamily : NULL; 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTypeface* find_typeface(const char name[], SkTypeface::Style style) { 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* rec = find_familyrec(name); 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec ? find_best_face(rec, style) : NULL; 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTypeface* find_typeface(const SkTypeface* familyMember, 1911bfd0ca7804a082ce29fd56adb311c79fc11a99freed@android.com SkTypeface::Style style) { 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const FamilyRec* family = find_family(familyMember); 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return family ? find_best_face(family, style) : NULL; 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1961bfd0ca7804a082ce29fd56adb311c79fc11a99freed@android.comstatic void add_name(const char name[], FamilyRec* family) { 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoAsciiToLC tolc(name); 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com name = tolc.lc(); 199ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NameFamilyPair* list = gNameList.begin(); 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = gNameList.count(); 202ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0])); 204ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (index < 0) { 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com list = gNameList.insert(~index); 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com list->construct(name, family); 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2111bfd0ca7804a082ce29fd56adb311c79fc11a99freed@android.comstatic void remove_from_names(FamilyRec* emptyFamily) { 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 4; i++) { 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(emptyFamily->fFaces[i] == NULL); 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 217ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTDArray<NameFamilyPair>& list = gNameList; 219ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // must go backwards when removing 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = list.count() - 1; i >= 0; --i) { 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NameFamilyPair* pair = &list[i]; 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (pair->fFamily == emptyFamily) { 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pair->destruct(); 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com list.remove(i); 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2320fc17c33f144956bb75650f991226a14e555f189reed@google.comclass FamilyTypeface : public SkTypeface_FreeType { 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 234fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com FamilyTypeface(Style style, bool sysFont, FamilyRec* family, bool isFixedPitch) 235fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com : INHERITED(style, sk_atomic_inc(&gUniqueFontID) + 1, isFixedPitch) { 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fIsSysFont = sysFont; 237ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoMutexAcquire ac(gFamilyMutex); 239ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == family) { 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com family = SkNEW(FamilyRec); 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com family->fFaces[style] = this; 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFamilyRec = family; // just record it so we can return it if asked 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 246ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 2471bfd0ca7804a082ce29fd56adb311c79fc11a99freed@android.com virtual ~FamilyTypeface() { 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoMutexAcquire ac(gFamilyMutex); 249ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // remove us from our family. If the family is now empty, we return 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // that and then remove that family from the name list 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* family = remove_from_family(this); 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != family) { 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com remove_from_names(family); 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com detach_and_delete_family(family); 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 258ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool isSysFont() const { return fIsSysFont; } 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* getFamily() const { return fFamilyRec; } 261292b1d4903a770a77282508054917b48fb989d49reed@google.com 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual const char* getUniqueString() const = 0; 263ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 2645526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.comprotected: 2655526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE; 2665526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* fFamilyRec; // we don't own this, just point to it 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool fIsSysFont; 270ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 271032fbb8ebff7816793b077b6113de702e48713c1reed@google.com typedef SkTypeface_FreeType INHERITED; 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 276f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.com/* This subclass is just a place holder for when we have no fonts available. 277f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.com It exists so that our globals (e.g. gFamilyHead) that expect *something* 278f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.com will not be null. 279f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.com */ 280f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.comclass EmptyTypeface : public FamilyTypeface { 281f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.compublic: 2823681276c7847594ff7b175c01dbd6b5d87e9d286reed@google.com EmptyTypeface() : INHERITED(SkTypeface::kNormal, true, NULL, false) {} 283ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 284e1575aa21619e252f6c6514317041c32d00ce5a6reed@google.com virtual const char* getUniqueString() SK_OVERRIDE const { return NULL; } 285ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 286292b1d4903a770a77282508054917b48fb989d49reed@google.comprotected: 287292b1d4903a770a77282508054917b48fb989d49reed@google.com virtual SkStream* onOpenStream(int*) const SK_OVERRIDE { return NULL; } 288292b1d4903a770a77282508054917b48fb989d49reed@google.com 289f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.comprivate: 290f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.com typedef FamilyTypeface INHERITED; 291f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.com}; 292f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.com 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass StreamTypeface : public FamilyTypeface { 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com StreamTypeface(Style style, bool sysFont, FamilyRec* family, 296fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com SkStream* stream, bool isFixedPitch) 297fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com : INHERITED(style, sysFont, family, isFixedPitch) { 2981c0c5a0a52d0d94653c6ca959a43226228a5ca08reed@android.com stream->ref(); 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream = stream; 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3011bfd0ca7804a082ce29fd56adb311c79fc11a99freed@android.com virtual ~StreamTypeface() { 3021c0c5a0a52d0d94653c6ca959a43226228a5ca08reed@android.com fStream->unref(); 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 304ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 305e1575aa21619e252f6c6514317041c32d00ce5a6reed@google.com virtual const char* getUniqueString() const SK_OVERRIDE { return NULL; } 306ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 307292b1d4903a770a77282508054917b48fb989d49reed@google.comprotected: 308292b1d4903a770a77282508054917b48fb989d49reed@google.com virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE { 309292b1d4903a770a77282508054917b48fb989d49reed@google.com *ttcIndex = 0; 310292b1d4903a770a77282508054917b48fb989d49reed@google.com fStream->ref(); 311292b1d4903a770a77282508054917b48fb989d49reed@google.com return fStream; 312292b1d4903a770a77282508054917b48fb989d49reed@google.com } 313292b1d4903a770a77282508054917b48fb989d49reed@google.com 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkStream* fStream; 316ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef FamilyTypeface INHERITED; 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass FileTypeface : public FamilyTypeface { 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FileTypeface(Style style, bool sysFont, FamilyRec* family, 323fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com const char path[], bool isFixedPitch) 324fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com : INHERITED(style, sysFont, family, isFixedPitch) { 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPath.set(path); 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 327ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 328e1575aa21619e252f6c6514317041c32d00ce5a6reed@google.com virtual const char* getUniqueString() const SK_OVERRIDE { 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* str = strrchr(fPath.c_str(), '/'); 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (str) { 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com str += 1; // skip the '/' 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return str; 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 335ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 336292b1d4903a770a77282508054917b48fb989d49reed@google.comprotected: 337292b1d4903a770a77282508054917b48fb989d49reed@google.com virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE { 338292b1d4903a770a77282508054917b48fb989d49reed@google.com *ttcIndex = 0; 339292b1d4903a770a77282508054917b48fb989d49reed@google.com return SkStream::NewFromFile(fPath.c_str()); 340292b1d4903a770a77282508054917b48fb989d49reed@google.com } 341292b1d4903a770a77282508054917b48fb989d49reed@google.com 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString fPath; 344ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef FamilyTypeface INHERITED; 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool get_name_and_style(const char path[], SkString* name, 352fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com SkTypeface::Style* style, bool* isFixedPitch) { 353e1575aa21619e252f6c6514317041c32d00ce5a6reed@google.com SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); 354e1575aa21619e252f6c6514317041c32d00ce5a6reed@google.com if (stream.get()) { 355fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com return find_name_and_attributes(stream, name, style, isFixedPitch); 356e1575aa21619e252f6c6514317041c32d00ce5a6reed@google.com } else { 357e1575aa21619e252f6c6514317041c32d00ce5a6reed@google.com SkDebugf("---- failed to open <%s> as a font\n", path); 358e1575aa21619e252f6c6514317041c32d00ce5a6reed@google.com return false; 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// these globals are assigned (once) by load_system_fonts() 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTypeface* gFallBackTypeface; 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic FamilyRec* gDefaultFamily; 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTypeface* gDefaultNormal; 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3672cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.comstatic void load_directory_fonts(const SkString& directory, unsigned int* count) { 3682cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com SkOSFile::Iter iter(directory.c_str(), ".ttf"); 369f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.com SkString name; 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next(&name, false)) { 3722cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com SkString filename(directory); 3732cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com filename.append(name); 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 375fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com bool isFixedPitch; 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString realname; 3776963af2327a9738d22716759dc39526a4935ecdereed@google.com SkTypeface::Style style = SkTypeface::kNormal; // avoid uninitialized warning 378ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 379fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com if (!get_name_and_style(filename.c_str(), &realname, &style, &isFixedPitch)) { 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDebugf("------ can't load <%s> as a font\n", filename.c_str()); 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com continue; 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 383f2afb67bab01062d2632543c1f004b166bf01e31reed@android.com 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* family = find_familyrec(realname.c_str()); 385887e4f325c2b9b306116a4eea37c5afad1db3346reed@android.com if (family && family->fFaces[style]) { 386887e4f325c2b9b306116a4eea37c5afad1db3346reed@android.com continue; 387887e4f325c2b9b306116a4eea37c5afad1db3346reed@android.com } 388887e4f325c2b9b306116a4eea37c5afad1db3346reed@android.com 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // this constructor puts us into the global gFamilyHead llist 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyTypeface* tf = SkNEW_ARGS(FileTypeface, 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (style, 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com true, // system-font (cannot delete) 3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com family, // what family to join 3943681276c7847594ff7b175c01dbd6b5d87e9d286reed@google.com filename.c_str(), 395fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com isFixedPitch) // filename 3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ); 3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == family) { 3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com add_name(realname.c_str(), tf->getFamily()); 4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4012cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com *count += 1; 402f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.com } 403f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.com 4042cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com SkOSFile::Iter dirIter(directory.c_str()); 4052cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com while (dirIter.next(&name, true)) { 4062cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com if (name.startsWith(".")) { 4072cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com continue; 4082cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com } 4092cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com SkString dirname(directory); 4102cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com dirname.append(name); 4112cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com dirname.append(SK_FONT_FILE_DIR_SEPERATOR); 4122cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com load_directory_fonts(dirname, count); 4132cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com } 4142cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com} 4152cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com 4162cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.comstatic void load_system_fonts() { 4172cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com // check if we've already be called 4182cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com if (NULL != gDefaultNormal) { 4192cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com return; 4202cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com } 4212cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com 4222cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com SkString baseDirectory(SK_FONT_FILE_PREFIX); 4232cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com unsigned int count = 0; 4242cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com load_directory_fonts(baseDirectory, &count); 4252cf84ec1e15fe69ca8840eab9e32708b81b95c90bungeman@google.com 426f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.com if (0 == count) { 427f244f1b19f07b1c946f8d7e24decbe1809dda7f6reed@android.com SkNEW(EmptyTypeface); 4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 429f2afb67bab01062d2632543c1f004b166bf01e31reed@android.com 4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // do this after all fonts are loaded. This is our default font, and it 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // acts as a sentinel so we only execute load_system_fonts() once 4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static const char* gDefaultNames[] = { 4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "Arial", "Verdana", "Times New Roman", NULL 4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char** names = gDefaultNames; 4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (*names) { 4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface* tf = find_typeface(*names++, SkTypeface::kNormal); 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (tf) { 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gDefaultNormal = tf; 4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // check if we found *something* 4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == gDefaultNormal) { 4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == gFamilyHead) { 4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_throw(); 4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 4; i++) { 4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((gDefaultNormal = gFamilyHead->fFaces[i]) != NULL) { 4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == gDefaultNormal) { 4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_throw(); 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 457ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com gFallBackTypeface = gDefaultNormal; 4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gDefaultFamily = find_family(gDefaultNormal); 4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4635526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.comvoid FamilyTypeface::onGetFontDescriptor(SkFontDescriptor* desc, 4645526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com bool* isLocalStream) const { 4655526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com desc->setFamilyName(find_family_name(this)); 4665526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com desc->setFontFileName(this->getUniqueString()); 4675526ede94a2fc58bcf6b578b12a29f6addad776dreed@google.com *isLocalStream = !this->isSysFont(); 4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 472b1d9d2ef2803bd55fdc886d13033b48f8450dd14reed@android.comSkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, 473b1d9d2ef2803bd55fdc886d13033b48f8450dd14reed@android.com const char familyName[], 474b1d9d2ef2803bd55fdc886d13033b48f8450dd14reed@android.com SkTypeface::Style style) { 4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com load_system_fonts(); 476ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoMutexAcquire ac(gFamilyMutex); 478ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // clip to legal style bits 4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic); 481ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface* tf = NULL; 483ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != familyFace) { 4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tf = find_typeface(familyFace, style); 4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else if (NULL != familyName) { 4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // SkDebugf("======= familyName <%s>\n", familyName); 4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tf = find_typeface(familyName, style); 4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 490ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == tf) { 4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tf = find_best_face(gDefaultFamily, style); 4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 494ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com 495ada448040f04bb4c8fae82fe839807ba45a85d61chudy@google.com SkSafeRef(tf); 4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return tf; 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4990da48618a758ef46c2174bdc1eaeb6dd8a693a2ereed@google.comSkTypeface* SkFontHost::NextLogicalTypeface(SkFontID currFontID, SkFontID origFontID) { 5000da48618a758ef46c2174bdc1eaeb6dd8a693a2ereed@google.com return NULL; 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 505b1d9d2ef2803bd55fdc886d13033b48f8450dd14reed@android.comSkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { 5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == stream || stream->getLength() <= 0) { 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(stream); 5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5103681276c7847594ff7b175c01dbd6b5d87e9d286reed@google.com 511fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com bool isFixedPitch; 5124dc686d75353235260c716242f4ed596b70beb95djsollen@google.com SkTypeface::Style style; 513fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com if (find_name_and_attributes(stream, NULL, &style, &isFixedPitch)) { 514fe74765f0d302669ae49e68074492bdfe0ce6e6fbungeman@google.com return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream, isFixedPitch)); 5154dc686d75353235260c716242f4ed596b70beb95djsollen@google.com } else { 5164dc686d75353235260c716242f4ed596b70beb95djsollen@google.com return NULL; 5174dc686d75353235260c716242f4ed596b70beb95djsollen@google.com } 5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5201bfd0ca7804a082ce29fd56adb311c79fc11a99freed@android.comSkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { 521f381162e5616daacdbcc06d693aca5111aeeebe8mike@reedtribe.org SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); 522f381162e5616daacdbcc06d693aca5111aeeebe8mike@reedtribe.org return stream.get() ? CreateTypefaceFromStream(stream) : NULL; 5230becfc5b7608ba67a4c98721cd61939e89ac5653reed@android.com} 524