11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/* 31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project 41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * 51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file. 740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 91cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger 1040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkFontHost.h" 1140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkDescriptor.h" 1240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkMMapStream.h" 1340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkOSFile.h" 1440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkPaint.h" 1540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkString.h" 1640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkStream.h" 1740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkThread.h" 1840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include "SkTSearch.h" 1940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#include <stdio.h> 2040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#ifndef SK_FONT_FILE_PREFIX 2240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger #define SK_FONT_FILE_PREFIX "/usr/share/fonts/truetype/msttcorefonts/" 2340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#endif 2440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 254f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenbergerbool find_name_and_attributes(SkStream* stream, SkString* name, 264f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkTypeface::Style* style, bool* isFixedWidth); 2740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 2840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void GetFullPathForSysFonts(SkString* full, const char name[]) 2940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger{ 3040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger full->append(SK_FONT_FILE_PREFIX); 3140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger full->append(name); 3240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 3340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 3440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 3540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 3640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstruct FamilyRec; 3740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 3840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/* This guy holds a mapping of a name -> family, used for looking up fonts. 3940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger Since it is stored in a stretchy array that doesn't preserve object 4040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger semantics, we don't use constructor/destructors, but just have explicit 4140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger helpers to manage our internal bookkeeping. 4240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 4340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstruct NameFamilyPair { 4440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char* fName; // we own this 4540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec* fFamily; // we don't own this, we just reference it 4640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 4740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void construct(const char name[], FamilyRec* family) 4840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { 4940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fName = strdup(name); 5040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fFamily = family; // we don't own this, so just record the referene 5140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 5240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger void destruct() 5340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { 5440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger free((char*)fName); 5540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // we don't own family, so just ignore our reference 5640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 5740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}; 5840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// we use atomic_inc to grow this for each typeface we create 6040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic int32_t gUniqueFontID; 6140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// this is the mutex that protects these globals 634f1dae40e24d57d647db01443b8bf2410514b8b5Derek SollenbergerSK_DECLARE_STATIC_MUTEX(gFamilyMutex); 6440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic FamilyRec* gFamilyHead; 6540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkTDArray<NameFamilyPair> gNameList; 6640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 6740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstruct FamilyRec { 6840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec* fNext; 6940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkTypeface* fFaces[4]; 7040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec() 7240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { 7340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fNext = gFamilyHead; 7440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger memset(fFaces, 0, sizeof(fFaces)); 7540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger gFamilyHead = this; 7640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 7740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}; 7840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 7940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkTypeface* find_best_face(const FamilyRec* family, 8040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkTypeface::Style style) { 8140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkTypeface* const* faces = family->fFaces; 8240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 8340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (faces[style] != NULL) { // exact match 8440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return faces[style]; 8540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 8640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // look for a matching bold 8740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger style = (SkTypeface::Style)(style ^ SkTypeface::kItalic); 8840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (faces[style] != NULL) { 8940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return faces[style]; 9040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 9140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // look for the plain 9240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (faces[SkTypeface::kNormal] != NULL) { 9340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return faces[SkTypeface::kNormal]; 9440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 9540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // look for anything 9640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = 0; i < 4; i++) { 9740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (faces[i] != NULL) { 9840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return faces[i]; 9940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 10040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 10140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // should never get here, since the faces list should not be empty 1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("faces list is empty"); 10340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return NULL; 10440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 10540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 10640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic FamilyRec* find_family(const SkTypeface* member) { 10740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec* curr = gFamilyHead; 10840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (curr != NULL) { 10940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = 0; i < 4; i++) { 11040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (curr->fFaces[i] == member) { 11140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return curr; 11240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 11340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 11440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger curr = curr->fNext; 11540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 11640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return NULL; 11740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 11840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 11940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkTypeface* find_from_uniqueID(uint32_t uniqueID) { 12040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec* curr = gFamilyHead; 12140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (curr != NULL) { 12240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = 0; i < 4; i++) { 12340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkTypeface* face = curr->fFaces[i]; 12440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (face != NULL && face->uniqueID() == uniqueID) { 12540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return face; 12640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 12740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 12840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger curr = curr->fNext; 12940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger return NULL; 13140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 13240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 13340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool valid_uniqueID(uint32_t uniqueID) { 13440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return find_from_uniqueID(uniqueID) != NULL; 13540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 13640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 13740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/* Remove reference to this face from its family. If the resulting family 13840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger is empty (has no faces), return that family, otherwise return NULL 13940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 14040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic FamilyRec* remove_from_family(const SkTypeface* face) { 14140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec* family = find_family(face); 14240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(family->fFaces[face->style()] == face); 14340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger family->fFaces[face->style()] = NULL; 14440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 14540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = 0; i < 4; i++) { 14640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (family->fFaces[i] != NULL) { // family is non-empty 14740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return NULL; 14840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 14940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 15040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return family; // return the empty family 15140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 15240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 15340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// maybe we should make FamilyRec be doubly-linked 15440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void detach_and_delete_family(FamilyRec* family) { 15540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec* curr = gFamilyHead; 15640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec* prev = NULL; 15740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 15840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (curr != NULL) { 15940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec* next = curr->fNext; 16040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (curr == family) { 16140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (prev == NULL) { 16240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger gFamilyHead = next; 16340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 16440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger prev->fNext = next; 16540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 16640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkDELETE(family); 16740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return; 16840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 16940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger prev = curr; 17040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger curr = next; 17140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 1721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger SkDEBUGFAIL("Yikes, couldn't find family in our list to remove/delete"); 17340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 17440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 17540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic FamilyRec* find_familyrec(const char name[]) { 17640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const NameFamilyPair* list = gNameList.begin(); 17740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int index = SkStrLCSearch(&list[0].fName, gNameList.count(), name, 17840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger sizeof(list[0])); 17940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return index >= 0 ? list[index].fFamily : NULL; 18040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 18140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 18240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkTypeface* find_typeface(const char name[], SkTypeface::Style style) { 18340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec* rec = find_familyrec(name); 18440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return rec ? find_best_face(rec, style) : NULL; 18540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 18640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 18740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkTypeface* find_typeface(const SkTypeface* familyMember, 18840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkTypeface::Style style) { 18940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const FamilyRec* family = find_family(familyMember); 19040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return family ? find_best_face(family, style) : NULL; 19140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 19240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 19340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void add_name(const char name[], FamilyRec* family) { 19440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAutoAsciiToLC tolc(name); 19540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger name = tolc.lc(); 19640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 19740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger NameFamilyPair* list = gNameList.begin(); 19840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int count = gNameList.count(); 19940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 20040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0])); 20140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 20240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (index < 0) { 20340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger list = gNameList.insert(~index); 20440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger list->construct(name, family); 20540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 20640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 20740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 20840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void remove_from_names(FamilyRec* emptyFamily) { 20940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#ifdef SK_DEBUG 21040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = 0; i < 4; i++) { 21140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkASSERT(emptyFamily->fFaces[i] == NULL); 21240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 21340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#endif 21440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 21540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkTDArray<NameFamilyPair>& list = gNameList; 21640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 21740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // must go backwards when removing 21840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = list.count() - 1; i >= 0; --i) { 21940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger NameFamilyPair* pair = &list[i]; 22040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (pair->fFamily == emptyFamily) { 22140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger pair->destruct(); 22240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger list.remove(i); 22340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 22440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 22540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 22640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 22740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 22840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 22940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerclass FamilyTypeface : public SkTypeface { 23040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerpublic: 23171531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger FamilyTypeface(Style style, bool sysFont, FamilyRec* family, bool isFixedWidth) 23271531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1, isFixedWidth) { 23340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fIsSysFont = sysFont; 23440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 23540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAutoMutexAcquire ac(gFamilyMutex); 23640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 23740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == family) { 23840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger family = SkNEW(FamilyRec); 23940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 24040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger family->fFaces[style] = this; 24140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fFamilyRec = family; // just record it so we can return it if asked 24240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 24340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 24440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual ~FamilyTypeface() { 24540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAutoMutexAcquire ac(gFamilyMutex); 24640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 24740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // remove us from our family. If the family is now empty, we return 24840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // that and then remove that family from the name list 24940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec* family = remove_from_family(this); 25040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL != family) { 25140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger remove_from_names(family); 25240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger detach_and_delete_family(family); 25340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 25440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 25540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 25640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger bool isSysFont() const { return fIsSysFont; } 25740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec* getFamily() const { return fFamilyRec; } 25840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // openStream returns a SkStream that has been ref-ed 25940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual SkStream* openStream() = 0; 26040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual const char* getUniqueString() const = 0; 26140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 26240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerprivate: 26340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec* fFamilyRec; // we don't own this, just point to it 26440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger bool fIsSysFont; 26540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 26640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger typedef SkTypeface INHERITED; 26740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}; 26840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 26940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 27040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 27140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/* This subclass is just a place holder for when we have no fonts available. 27240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger It exists so that our globals (e.g. gFamilyHead) that expect *something* 27340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger will not be null. 27440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger */ 27540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerclass EmptyTypeface : public FamilyTypeface { 27640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerpublic: 27771531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger EmptyTypeface() : INHERITED(SkTypeface::kNormal, true, NULL, false) {} 27840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 27940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // overrides 28040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual SkStream* openStream() { return NULL; } 28140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual const char* getUniqueString() const { return NULL; } 28240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 28340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerprivate: 28440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger typedef FamilyTypeface INHERITED; 28540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}; 28640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 28740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerclass StreamTypeface : public FamilyTypeface { 28840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerpublic: 28940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger StreamTypeface(Style style, bool sysFont, FamilyRec* family, 29071531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkStream* stream, bool isFixedWidth) 29171531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger : INHERITED(style, sysFont, family, isFixedWidth) { 29240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger stream->ref(); 29340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fStream = stream; 29440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 29540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual ~StreamTypeface() { 29640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fStream->unref(); 29740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 29840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 29940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // overrides 30040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual SkStream* openStream() 30140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { 30240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // openStream returns a refed stream. 30340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fStream->ref(); 30440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return fStream; 30540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 30640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual const char* getUniqueString() const { return NULL; } 30740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 30840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerprivate: 30940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkStream* fStream; 31040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 31140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger typedef FamilyTypeface INHERITED; 31240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}; 31340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 31440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerclass FileTypeface : public FamilyTypeface { 31540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerpublic: 31640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FileTypeface(Style style, bool sysFont, FamilyRec* family, 31771531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger const char path[], bool isFixedWidth) 31871531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger : INHERITED(style, sysFont, family, isFixedWidth) { 31940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger fPath.set(path); 32040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 32140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 32240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // overrides 32340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual SkStream* openStream() 32440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger { 32540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str())); 32640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 32740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // check for failure 32840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (stream->getLength() <= 0) { 32940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkDELETE(stream); 33040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // maybe MMAP isn't supported. try FILE 33140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str())); 33240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (stream->getLength() <= 0) { 33340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkDELETE(stream); 33440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger stream = NULL; 33540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 33640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 33740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return stream; 33840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 33940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 34040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger virtual const char* getUniqueString() const { 34140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char* str = strrchr(fPath.c_str(), '/'); 34240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (str) { 34340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger str += 1; // skip the '/' 34440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 34540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return str; 34640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 34740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 34840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerprivate: 34940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkString fPath; 35040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 35140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger typedef FamilyTypeface INHERITED; 35240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger}; 35340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 35440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 35540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 35640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 35740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic bool get_name_and_style(const char path[], SkString* name, 35871531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger SkTypeface::Style* style, bool* isFixedWidth) { 35940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkMMAPStream stream(path); 36040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (stream.getLength() > 0) { 3614f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return find_name_and_attributes(&stream, name, style, isFixedWidth); 36240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 36340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger else { 36440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkFILEStream stream(path); 36540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (stream.getLength() > 0) { 3664f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return find_name_and_attributes(&stream, name, style, isFixedWidth); 36740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 36840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 36940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 37040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkDebugf("---- failed to open <%s> as a font\n", path); 37140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return false; 37240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 37340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 37440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// these globals are assigned (once) by load_system_fonts() 37540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkTypeface* gFallBackTypeface; 37640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic FamilyRec* gDefaultFamily; 37740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic SkTypeface* gDefaultNormal; 37840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 37940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergerstatic void load_system_fonts() { 38040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // check if we've already be called 38140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL != gDefaultNormal) { 3820b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger// printf("---- default font %p\n", gDefaultNormal); 38340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return; 38440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 38540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 38640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkOSFile::Iter iter(SK_FONT_FILE_PREFIX, ".ttf"); 38740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkString name; 38840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int count = 0; 38940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 39040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (iter.next(&name, false)) { 39140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkString filename; 39240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger GetFullPathForSysFonts(&filename, name.c_str()); 39340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 39471531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger bool isFixedWidth; 39540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkString realname; 39640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkTypeface::Style style = SkTypeface::kNormal; // avoid uninitialized warning 39740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 39871531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger if (!get_name_and_style(filename.c_str(), &realname, &style, &isFixedWidth)) { 39940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkDebugf("------ can't load <%s> as a font\n", filename.c_str()); 40040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger continue; 40140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 40240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 40340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// SkDebugf("font: <%s> %d <%s>\n", realname.c_str(), style, filename.c_str()); 40440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 40540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyRec* family = find_familyrec(realname.c_str()); 40640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (family && family->fFaces[style]) { 40740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// SkDebugf("---- skipping duplicate typeface %s style %d\n", 40840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// realname.c_str(), style); 40940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger continue; 41040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 41140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 41240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // this constructor puts us into the global gFamilyHead llist 41340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyTypeface* tf = SkNEW_ARGS(FileTypeface, 41440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger (style, 41540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger true, // system-font (cannot delete) 41640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger family, // what family to join 41771531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger filename.c_str(), 41871531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger isFixedWidth) // filename 41940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger ); 42040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 42140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == family) { 42240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger add_name(realname.c_str(), tf->getFamily()); 42340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 42440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger count += 1; 42540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 42640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 42740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (0 == count) { 42840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkNEW(EmptyTypeface); 42940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 43040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 43140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // do this after all fonts are loaded. This is our default font, and it 43240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // acts as a sentinel so we only execute load_system_fonts() once 43340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger static const char* gDefaultNames[] = { 43440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger "Arial", "Verdana", "Times New Roman", NULL 43540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger }; 43640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char** names = gDefaultNames; 43740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger while (*names) { 43840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkTypeface* tf = find_typeface(*names++, SkTypeface::kNormal); 43940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (tf) { 44040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger gDefaultNormal = tf; 44140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 44240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 44340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 44440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // check if we found *something* 44540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == gDefaultNormal) { 44640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == gFamilyHead) { 44740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger sk_throw(); 44840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 44940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int i = 0; i < 4; i++) { 45040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if ((gDefaultNormal = gFamilyHead->fFaces[i]) != NULL) { 45140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger break; 45240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 45340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 45440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 45540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == gDefaultNormal) { 45640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger sk_throw(); 45740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 45840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger gFallBackTypeface = gDefaultNormal; 45940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger gDefaultFamily = find_family(gDefaultNormal); 46040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 46140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger// SkDebugf("---- default %p head %p family %p\n", gDefaultNormal, gFamilyHead, gDefaultFamily); 46240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 46340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 46440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 46540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 46640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergervoid SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) { 46740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#if 0 46840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char* name = ((FamilyTypeface*)face)->getUniqueString(); 46940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 47040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger stream->write8((uint8_t)face->getStyle()); 47140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 47240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == name || 0 == *name) { 47340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger stream->writePackedUInt(0); 47440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // SkDebugf("--- fonthost serialize null\n"); 47540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else { 47640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger uint32_t len = strlen(name); 47740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger stream->writePackedUInt(len); 47840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger stream->write(name, len); 47940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // SkDebugf("--- fonthost serialize <%s> %d\n", name, face->getStyle()); 48040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 48140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#endif 48240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger sk_throw(); 48340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 48440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 48540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkTypeface* SkFontHost::Deserialize(SkStream* stream) { 48640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#if 0 48740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger load_system_fonts(); 48840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 48940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int style = stream->readU8(); 49040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 49140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int len = stream->readPackedUInt(); 49240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (len > 0) { 49340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkString str; 49440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger str.resize(len); 49540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger stream->read(str.writable_str(), len); 49640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 49740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const FontInitRec* rec = gSystemFonts; 49840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) { 49940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (strcmp(rec[i].fFileName, str.c_str()) == 0) { 50040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // backup until we hit the fNames 50140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger for (int j = i; j >= 0; --j) { 50240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (rec[j].fNames != NULL) { 50340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkFontHost::CreateTypeface(NULL, rec[j].fNames[0], NULL, 0, 50440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger (SkTypeface::Style)style); 50540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 50640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 50740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 50840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 50940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 51040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return SkFontHost::CreateTypeface(NULL, NULL, NULL, 0, (SkTypeface::Style)style); 51140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger#endif 51240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger sk_throw(); 51340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return NULL; 51440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 51540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 51640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 51740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 51840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, 51940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const char familyName[], 52040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger const void* data, size_t bytelength, 52140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkTypeface::Style style) { 52240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger load_system_fonts(); 52340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 52440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkAutoMutexAcquire ac(gFamilyMutex); 52540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 52640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // clip to legal style bits 52740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic); 52840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 52940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkTypeface* tf = NULL; 53040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 53140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL != familyFace) { 53240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger tf = find_typeface(familyFace, style); 53340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } else if (NULL != familyName) { 53440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger // SkDebugf("======= familyName <%s>\n", familyName); 53540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger tf = find_typeface(familyName, style); 53640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 53740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 53840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == tf) { 53940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger tf = find_best_face(gDefaultFamily, style); 54040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 54140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 54240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkSafeRef(tf); 54340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return tf; 54440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 54540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 54640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkStream* SkFontHost::OpenStream(uint32_t fontID) { 54740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID); 54840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkStream* stream = tf ? tf->openStream() : NULL; 54940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 55040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (stream && stream->getLength() == 0) { 55140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger stream->unref(); 55240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger stream = NULL; 55340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 55440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return stream; 55540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 55640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 55740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenbergersize_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length, 55840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger int32_t* index) { 55940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkDebugf("SkFontHost::GetFileName unimplemented\n"); 56040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return 0; 56140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 56240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 5630199fa7423f89a129da2b22a488f2c18e2e4727fDerek SollenbergerSkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) { 56440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return 0; 56540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 56640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 56740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger/////////////////////////////////////////////////////////////////////////////// 56840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 56940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { 57040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (NULL == stream || stream->getLength() <= 0) { 57140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkDELETE(stream); 57240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return NULL; 57340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 57471531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger 57571531ca1f484da5837be8017a0c83e5bff701587Derek Sollenberger bool isFixedWidth; 5764f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger SkTypeface::Style style; 5774f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger if (find_name_and_attributes(stream, NULL, &style, &isFixedWidth)) { 5784f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream, isFixedWidth)); 5794f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } else { 5804f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger return NULL; 5814f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger } 58240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 58340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 58440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek SollenbergerSkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) { 58540528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkTypeface* face = NULL; 58640528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path)); 58740528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 58840528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger if (stream->isValid()) { 58940528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger face = CreateTypefaceFromStream(stream); 59040528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger } 59140528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger stream->unref(); 59240528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger return face; 59340528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger} 59440528743dbb9ce7f39f093e0cdc47849ac8887cfDerek Sollenberger 595