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