SkFontHost_linux.cpp revision 8a1c16ff38322f0210116fa7293eb8817c7e477e
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* libs/graphics/ports/SkFontHost_android.cpp 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** Copyright 2006, The Android Open Source Project 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** 58a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** Licensed under the Apache License, Version 2.0 (the "License"); 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** you may not use this file except in compliance with the License. 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** You may obtain a copy of the License at 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** http://www.apache.org/licenses/LICENSE-2.0 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** Unless required by applicable law or agreed to in writing, software 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** distributed under the License is distributed on an "AS IS" BASIS, 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** See the License for the specific language governing permissions and 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ** limitations under the License. 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkFontHost.h" 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkDescriptor.h" 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMMapStream.h" 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkOSFile.h" 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPaint.h" 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkString.h" 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStream.h" 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkThread.h" 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkTSearch.h" 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include <stdio.h> 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define FONT_CACHE_MEMORY_BUDGET (1 * 1024 * 1024) 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SK_FONT_FILE_PREFIX 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SK_FONT_FILE_PREFIX "/usr/share/fonts/truetype/msttcorefonts/" 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkTypeface::Style find_name_and_style(SkStream* stream, SkString* name); 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void GetFullPathForSysFonts(SkString* full, const char name[]) 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com full->append(SK_FONT_FILE_PREFIX); 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com full->append(name); 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct FamilyRec; 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* This guy holds a mapping of a name -> family, used for looking up fonts. 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Since it is stored in a stretchy array that doesn't preserve object 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com semantics, we don't use constructor/destructors, but just have explicit 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com helpers to manage our internal bookkeeping. 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct NameFamilyPair { 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* fName; // we own this 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* fFamily; // we don't own this, we just reference it 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void construct(const char name[], FamilyRec* family) 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fName = strdup(name); 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFamily = family; // we don't own this, so just record the referene 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com void destruct() 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com free((char*)fName); 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // we don't own family, so just ignore our reference 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// we use atomic_inc to grow this for each typeface we create 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic int32_t gUniqueFontID; 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// this is the mutex that protects these globals 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkMutex gFamilyMutex; 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic FamilyRec* gFamilyHead; 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTDArray<NameFamilyPair> gNameList; 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct FamilyRec { 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* fNext; 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface* fFaces[4]; 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec() 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fNext = gFamilyHead; 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memset(fFaces, 0, sizeof(fFaces)); 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gFamilyHead = this; 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTypeface* find_best_face(const FamilyRec* family, 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface::Style style) 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface* const* faces = family->fFaces; 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (faces[style] != NULL) { // exact match 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return faces[style]; 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // look for a matching bold 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com style = (SkTypeface::Style)(style ^ SkTypeface::kItalic); 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (faces[style] != NULL) { 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return faces[style]; 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // look for the plain 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (faces[SkTypeface::kNormal] != NULL) { 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return faces[SkTypeface::kNormal]; 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // look for anything 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 4; i++) { 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (faces[i] != NULL) { 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return faces[i]; 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // should never get here, since the faces list should not be empty 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!"faces list is empty"); 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic FamilyRec* find_family(const SkTypeface* member) 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* curr = gFamilyHead; 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (curr != NULL) { 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 4; i++) { 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (curr->fFaces[i] == member) { 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return curr; 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com curr = curr->fNext; 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTypeface* resolve_uniqueID(uint32_t uniqueID) 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* curr = gFamilyHead; 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (curr != NULL) { 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 4; i++) { 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface* face = curr->fFaces[i]; 1368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (face != NULL && face->uniqueID() == uniqueID) { 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return face; 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com curr = curr->fNext; 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* Remove reference to this face from its family. If the resulting family 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com is empty (has no faces), return that family, otherwise return NULL 1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic FamilyRec* remove_from_family(const SkTypeface* face) 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* family = find_family(face); 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(family->fFaces[face->style()] == face); 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com family->fFaces[face->style()] = NULL; 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 4; i++) { 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (family->fFaces[i] != NULL) { // family is non-empty 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return family; // return the empty family 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// maybe we should make FamilyRec be doubly-linked 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void detach_and_delete_family(FamilyRec* family) 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* curr = gFamilyHead; 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* prev = NULL; 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (curr != NULL) { 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* next = curr->fNext; 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (curr == family) { 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (prev == NULL) { 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gFamilyHead = next; 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com prev->fNext = next; 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(family); 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com prev = curr; 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com curr = next; 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(!"Yikes, couldn't find family in our list to remove/delete"); 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic FamilyRec* find_familyrec(const char name[]) { 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const NameFamilyPair* list = gNameList.begin(); 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int index = SkStrLCSearch(&list[0].fName, gNameList.count(), name, 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sizeof(list[0])); 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return index >= 0 ? list[index].fFamily : NULL; 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTypeface* find_typeface(const char name[], SkTypeface::Style style) { 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* rec = find_familyrec(name); 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return rec ? find_best_face(rec, style) : NULL; 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTypeface* find_typeface(const SkTypeface* familyMember, 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface::Style style) 1998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const FamilyRec* family = find_family(familyMember); 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return family ? find_best_face(family, style) : NULL; 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void add_name(const char name[], FamilyRec* family) 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoAsciiToLC tolc(name); 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com name = tolc.lc(); 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NameFamilyPair* list = gNameList.begin(); 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int count = gNameList.count(); 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0])); 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (index < 0) { 2158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com list = gNameList.insert(~index); 2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com list->construct(name, family); 2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void remove_from_names(FamilyRec* emptyFamily) 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 4; i++) { 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(emptyFamily->fFaces[i] == NULL); 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTDArray<NameFamilyPair>& list = gNameList; 2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // must go backwards when removing 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = list.count() - 1; i >= 0; --i) { 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NameFamilyPair* pair = &list[i]; 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (pair->fFamily == emptyFamily) { 2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com pair->destruct(); 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com list.remove(i); 2368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass FamilyTypeface : public SkTypeface { 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyTypeface(Style style, bool sysFont, FamilyRec* family) 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1) 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fIsSysFont = sysFont; 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoMutexAcquire ac(gFamilyMutex); 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == family) { 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com family = SkNEW(FamilyRec); 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com family->fFaces[style] = this; 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fFamilyRec = family; // just record it so we can return it if asked 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual ~FamilyTypeface() 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoMutexAcquire ac(gFamilyMutex); 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // remove us from our family. If the family is now empty, we return 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // that and then remove that family from the name list 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* family = remove_from_family(this); 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != family) { 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com remove_from_names(family); 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com detach_and_delete_family(family); 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool isSysFont() const { return fIsSysFont; } 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* getFamily() const { return fFamilyRec; } 2738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual SkStream* openStream() = 0; 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual void closeStream(SkStream*) = 0; 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual const char* getUniqueString() const = 0; 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* fFamilyRec; // we don't own this, just point to it 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com bool fIsSysFont; 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef SkTypeface INHERITED; 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass StreamTypeface : public FamilyTypeface { 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com StreamTypeface(Style style, bool sysFont, FamilyRec* family, 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkStream* stream) 2918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : INHERITED(style, sysFont, family) 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStream = stream; 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual ~StreamTypeface() 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(fStream); 2988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // overrides 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual SkStream* openStream() { return fStream; } 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual void closeStream(SkStream*) {} 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual const char* getUniqueString() const { return NULL; } 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkStream* fStream; 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef FamilyTypeface INHERITED; 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass FileTypeface : public FamilyTypeface { 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FileTypeface(Style style, bool sysFont, FamilyRec* family, 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char path[]) 3158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : INHERITED(style, sysFont, family) { 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPath.set(path); 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // overrides 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual SkStream* openStream() 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str())); 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // check for failure 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (stream->getLength() <= 0) { 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(stream); 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // maybe MMAP isn't supported. try FILE 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str())); 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (stream->getLength() <= 0) { 3308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(stream); 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stream = NULL; 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return stream; 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual void closeStream(SkStream* stream) 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(stream); 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com virtual const char* getUniqueString() const { 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* str = strrchr(fPath.c_str(), '/'); 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (str) { 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com str += 1; // skip the '/' 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return str; 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString fPath; 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com typedef FamilyTypeface INHERITED; 3528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic bool get_name_and_style(const char path[], SkString* name, 3588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface::Style* style) 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkMMAPStream stream(path); 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (stream.getLength() > 0) { 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *style = find_name_and_style(&stream, name); 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com else { 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFILEStream stream(path); 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (stream.getLength() > 0) { 3688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *style = find_name_and_style(&stream, name); 3698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDebugf("---- failed to open <%s> as a font\n", path); 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// these globals are assigned (once) by load_system_fonts() 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTypeface* gFallBackTypeface; 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic FamilyRec* gDefaultFamily; 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic SkTypeface* gDefaultNormal; 3818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic void load_system_fonts() 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // check if we've already be called 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != gDefaultNormal) { 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return; 3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkOSFile::Iter iter(SK_FONT_FILE_PREFIX, ".ttf"); 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString name; 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (iter.next(&name, false)) { 3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString filename; 3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com GetFullPathForSysFonts(&filename, name.c_str()); 3958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// while (filename.size() == 0) { filename.set("/usr/share/fonts/truetype/msttcorefonts/Arial.ttf"); 3968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString realname; 3988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface::Style style; 3998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!get_name_and_style(filename.c_str(), &realname, &style)) { 4018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDebugf("------ can't load <%s> as a font\n", filename.c_str()); 4028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com continue; 4038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// SkDebugf("font: <%s> %d <%s>\n", realname.c_str(), style, filename.c_str()); 4068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyRec* family = find_familyrec(realname.c_str()); 4088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // this constructor puts us into the global gFamilyHead llist 4098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyTypeface* tf = SkNEW_ARGS(FileTypeface, 4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (style, 4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com true, // system-font (cannot delete) 4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com family, // what family to join 4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com filename.c_str()) // filename 4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ); 4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == family) { 4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com add_name(realname.c_str(), tf->getFamily()); 4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // do this after all fonts are loaded. This is our default font, and it 4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // acts as a sentinel so we only execute load_system_fonts() once 4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com static const char* gDefaultNames[] = { 4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "Arial", "Verdana", "Times New Roman", NULL 4258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com }; 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char** names = gDefaultNames; 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com while (*names) { 4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface* tf = find_typeface(*names++, SkTypeface::kNormal); 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (tf) { 4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gDefaultNormal = tf; 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // check if we found *something* 4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == gDefaultNormal) { 4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == gFamilyHead) { 4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_throw(); 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int i = 0; i < 4; i++) { 4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if ((gDefaultNormal = gFamilyHead->fFaces[i]) != NULL) { 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com break; 4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == gDefaultNormal) { 4468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_throw(); 4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gFallBackTypeface = gDefaultNormal; 4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com gDefaultFamily = find_family(gDefaultNormal); 4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// SkDebugf("---- default %p head %p family %p\n", gDefaultNormal, gFamilyHead, gDefaultFamily); 4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) { 4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0 4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char* name = ((FamilyTypeface*)face)->getUniqueString(); 4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stream->write8((uint8_t)face->getStyle()); 4618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == name || 0 == *name) { 4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stream->writePackedUInt(0); 4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // SkDebugf("--- fonthost serialize null\n"); 4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else { 4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t len = strlen(name); 4678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stream->writePackedUInt(len); 4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stream->write(name, len); 4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // SkDebugf("--- fonthost serialize <%s> %d\n", name, face->getStyle()); 4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_throw(); 4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkTypeface* SkFontHost::Deserialize(SkStream* stream) { 4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0 4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com load_system_fonts(); 4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int style = stream->readU8(); 4808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int len = stream->readPackedUInt(); 4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (len > 0) { 4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString str; 4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com str.resize(len); 4858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stream->read(str.writable_str(), len); 4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const FontInitRec* rec = gSystemFonts; 4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { 4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (strcmp(rec[i].fFileName, str.c_str()) == 0) { 4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // backup until we hit the fNames 4918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com for (int j = i; j >= 0; --j) { 4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (rec[j].fNames != NULL) { 4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkFontHost::FindTypeface(NULL, rec[j].fNames[0], 4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (SkTypeface::Style)style); 4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkFontHost::FindTypeface(NULL, NULL, (SkTypeface::Style)style); 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_throw(); 5038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkTypeface* SkFontHost::FindTypeface(const SkTypeface* familyFace, 5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const char familyName[], 5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface::Style style) 5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com load_system_fonts(); 5128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoMutexAcquire ac(gFamilyMutex); 5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // clip to legal style bits 5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic); 5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface* tf = NULL; 5198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != familyFace) { 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tf = find_typeface(familyFace, style); 5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } else if (NULL != familyName) { 5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // SkDebugf("======= familyName <%s>\n", familyName); 5248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tf = find_typeface(familyName, style); 5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == tf) { 5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tf = find_best_face(gDefaultFamily, style); 5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return tf; 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkTypeface* SkFontHost::ResolveTypeface(uint32_t fontID) 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 5368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoMutexAcquire ac(gFamilyMutex); 5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return resolve_uniqueID(fontID); 5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkStream* SkFontHost::OpenStream(uint32_t fontID) 5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyTypeface* tf = (FamilyTypeface*)SkFontHost::ResolveTypeface(fontID); 5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkStream* stream = tf ? tf->openStream() : NULL; 5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == stream || stream->getLength() == 0) { 5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com delete stream; 5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stream = NULL; 5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return stream; 5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid SkFontHost::CloseStream(uint32_t fontID, SkStream* stream) 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com FamilyTypeface* tf = (FamilyTypeface*)SkFontHost::ResolveTypeface(fontID); 5578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL != tf) { 5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com tf->closeStream(stream); 5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkScalerContext* SkFontHost::CreateFallbackScalerContext( 5638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkScalerContext::Rec& rec) 5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 5658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com load_system_fonts(); 5668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1)); 5688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDescriptor* desc = ad.getDesc(); 5698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com desc->init(); 5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScalerContext::Rec* newRec = 5728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag, 5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sizeof(rec), &rec); 5748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com newRec->fFontID = gFallBackTypeface->uniqueID(); 5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com desc->computeChecksum(); 5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkFontHost::CreateScalerContext(desc); 5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkTypeface* SkFontHost::CreateTypeface(SkStream* stream) 5838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 5848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (NULL == stream || stream->getLength() <= 0) { 5858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDELETE(stream); 5868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return NULL; 5878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkString name; 5908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkTypeface::Style style = find_name_and_style(stream, &name); 5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream)); 5938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 5968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comsize_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) 5988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{ 5998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (sizeAllocatedSoFar > FONT_CACHE_MEMORY_BUDGET) 6008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return sizeAllocatedSoFar - FONT_CACHE_MEMORY_BUDGET; 6018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com else 6028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return 0; // nothing to do 6038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 605