Home | History | Annotate | Download | only in ports
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #include "SkFontHost.h"
     11 #include "SkFontHost_FreeType_common.h"
     12 #include "SkFontDescriptor.h"
     13 #include "SkDescriptor.h"
     14 #include "SkOSFile.h"
     15 #include "SkPaint.h"
     16 #include "SkString.h"
     17 #include "SkStream.h"
     18 #include "SkThread.h"
     19 #include "SkTSearch.h"
     20 
     21 #ifndef SK_FONT_FILE_PREFIX
     22     #define SK_FONT_FILE_PREFIX "/usr/share/fonts/truetype/"
     23 #endif
     24 #ifndef SK_FONT_FILE_DIR_SEPERATOR
     25     #define SK_FONT_FILE_DIR_SEPERATOR "/"
     26 #endif
     27 
     28 bool find_name_and_attributes(SkStream* stream, SkString* name,
     29                               SkTypeface::Style* style, bool* isFixedPitch);
     30 
     31 ///////////////////////////////////////////////////////////////////////////////
     32 
     33 struct FamilyRec;
     34 
     35 /*  This guy holds a mapping of a name -> family, used for looking up fonts.
     36  Since it is stored in a stretchy array that doesn't preserve object
     37  semantics, we don't use constructor/destructors, but just have explicit
     38  helpers to manage our internal bookkeeping.
     39  */
     40 struct NameFamilyPair {
     41     const char* fName;      // we own this
     42     FamilyRec*  fFamily;    // we don't own this, we just reference it
     43 
     44     void construct(const char name[], FamilyRec* family)
     45     {
     46         fName = strdup(name);
     47         fFamily = family;   // we don't own this, so just record the referene
     48     }
     49     void destruct()
     50     {
     51         free((char*)fName);
     52         // we don't own family, so just ignore our reference
     53     }
     54 };
     55 
     56 // we use atomic_inc to grow this for each typeface we create
     57 static int32_t gUniqueFontID;
     58 
     59 // this is the mutex that protects these globals
     60 SK_DECLARE_STATIC_MUTEX(gFamilyMutex);
     61 static FamilyRec* gFamilyHead;
     62 static SkTDArray<NameFamilyPair> gNameList;
     63 
     64 struct FamilyRec {
     65     FamilyRec*  fNext;
     66     SkTypeface* fFaces[4];
     67 
     68     FamilyRec()
     69     {
     70         fNext = gFamilyHead;
     71         memset(fFaces, 0, sizeof(fFaces));
     72         gFamilyHead = this;
     73     }
     74 };
     75 
     76 static SkTypeface* find_best_face(const FamilyRec* family,
     77                                   SkTypeface::Style style) {
     78     SkTypeface* const* faces = family->fFaces;
     79 
     80     if (faces[style] != NULL) { // exact match
     81         return faces[style];
     82     }
     83     // look for a matching bold
     84     style = (SkTypeface::Style)(style ^ SkTypeface::kItalic);
     85     if (faces[style] != NULL) {
     86         return faces[style];
     87     }
     88     // look for the plain
     89     if (faces[SkTypeface::kNormal] != NULL) {
     90         return faces[SkTypeface::kNormal];
     91     }
     92     // look for anything
     93     for (int i = 0; i < 4; i++) {
     94         if (faces[i] != NULL) {
     95             return faces[i];
     96         }
     97     }
     98     // should never get here, since the faces list should not be empty
     99     SkDEBUGFAIL("faces list is empty");
    100     return NULL;
    101 }
    102 
    103 static FamilyRec* find_family(const SkTypeface* member) {
    104     FamilyRec* curr = gFamilyHead;
    105     while (curr != NULL) {
    106         for (int i = 0; i < 4; i++) {
    107             if (curr->fFaces[i] == member) {
    108                 return curr;
    109             }
    110         }
    111         curr = curr->fNext;
    112     }
    113     return NULL;
    114 }
    115 
    116 /*  Remove reference to this face from its family. If the resulting family
    117  is empty (has no faces), return that family, otherwise return NULL
    118  */
    119 static FamilyRec* remove_from_family(const SkTypeface* face) {
    120     FamilyRec* family = find_family(face);
    121     SkASSERT(family->fFaces[face->style()] == face);
    122     family->fFaces[face->style()] = NULL;
    123 
    124     for (int i = 0; i < 4; i++) {
    125         if (family->fFaces[i] != NULL) {    // family is non-empty
    126             return NULL;
    127         }
    128     }
    129     return family;  // return the empty family
    130 }
    131 
    132 // maybe we should make FamilyRec be doubly-linked
    133 static void detach_and_delete_family(FamilyRec* family) {
    134     FamilyRec* curr = gFamilyHead;
    135     FamilyRec* prev = NULL;
    136 
    137     while (curr != NULL) {
    138         FamilyRec* next = curr->fNext;
    139         if (curr == family) {
    140             if (prev == NULL) {
    141                 gFamilyHead = next;
    142             } else {
    143                 prev->fNext = next;
    144             }
    145             SkDELETE(family);
    146             return;
    147         }
    148         prev = curr;
    149         curr = next;
    150     }
    151     SkDEBUGFAIL("Yikes, couldn't find family in our list to remove/delete");
    152 }
    153 
    154 static const char* find_family_name(const SkTypeface* familyMember) {
    155     const FamilyRec* familyRec = find_family(familyMember);
    156     for (int i = 0; i < gNameList.count(); i++) {
    157         if (gNameList[i].fFamily == familyRec) {
    158             return gNameList[i].fName;
    159         }
    160     }
    161     return NULL;
    162 }
    163 
    164 static FamilyRec* find_familyrec(const char name[]) {
    165     const NameFamilyPair* list = gNameList.begin();
    166     int index = SkStrLCSearch(&list[0].fName, gNameList.count(), name,
    167                               sizeof(list[0]));
    168     return index >= 0 ? list[index].fFamily : NULL;
    169 }
    170 
    171 static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) {
    172     FamilyRec* rec = find_familyrec(name);
    173     return rec ? find_best_face(rec, style) : NULL;
    174 }
    175 
    176 static SkTypeface* find_typeface(const SkTypeface* familyMember,
    177                                  SkTypeface::Style style) {
    178     const FamilyRec* family = find_family(familyMember);
    179     return family ? find_best_face(family, style) : NULL;
    180 }
    181 
    182 static void add_name(const char name[], FamilyRec* family) {
    183     SkAutoAsciiToLC tolc(name);
    184     name = tolc.lc();
    185 
    186     NameFamilyPair* list = gNameList.begin();
    187     int             count = gNameList.count();
    188 
    189     int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
    190 
    191     if (index < 0) {
    192         list = gNameList.insert(~index);
    193         list->construct(name, family);
    194     }
    195 }
    196 
    197 static void remove_from_names(FamilyRec* emptyFamily) {
    198 #ifdef SK_DEBUG
    199     for (int i = 0; i < 4; i++) {
    200         SkASSERT(emptyFamily->fFaces[i] == NULL);
    201     }
    202 #endif
    203 
    204     SkTDArray<NameFamilyPair>& list = gNameList;
    205 
    206     // must go backwards when removing
    207     for (int i = list.count() - 1; i >= 0; --i) {
    208         NameFamilyPair* pair = &list[i];
    209         if (pair->fFamily == emptyFamily) {
    210             pair->destruct();
    211             list.remove(i);
    212         }
    213     }
    214 }
    215 
    216 ///////////////////////////////////////////////////////////////////////////////
    217 
    218 class FamilyTypeface : public SkTypeface_FreeType {
    219 public:
    220     FamilyTypeface(Style style, bool sysFont, FamilyRec* family, bool isFixedPitch)
    221     : INHERITED(style, sk_atomic_inc(&gUniqueFontID) + 1, isFixedPitch) {
    222         fIsSysFont = sysFont;
    223 
    224         SkAutoMutexAcquire  ac(gFamilyMutex);
    225 
    226         if (NULL == family) {
    227             family = SkNEW(FamilyRec);
    228         }
    229         family->fFaces[style] = this;
    230         fFamilyRec = family;    // just record it so we can return it if asked
    231     }
    232 
    233     virtual ~FamilyTypeface() {
    234         SkAutoMutexAcquire  ac(gFamilyMutex);
    235 
    236         // remove us from our family. If the family is now empty, we return
    237         // that and then remove that family from the name list
    238         FamilyRec* family = remove_from_family(this);
    239         if (NULL != family) {
    240             remove_from_names(family);
    241             detach_and_delete_family(family);
    242         }
    243     }
    244 
    245     bool isSysFont() const { return fIsSysFont; }
    246     FamilyRec* getFamily() const { return fFamilyRec; }
    247 
    248     virtual const char* getUniqueString() const = 0;
    249 
    250 protected:
    251     virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
    252     virtual SkTypeface* onRefMatchingStyle(Style styleBits) const SK_OVERRIDE;
    253 
    254 private:
    255     FamilyRec*  fFamilyRec; // we don't own this, just point to it
    256     bool        fIsSysFont;
    257 
    258     typedef SkTypeface_FreeType INHERITED;
    259 };
    260 
    261 ///////////////////////////////////////////////////////////////////////////////
    262 
    263 /* This subclass is just a place holder for when we have no fonts available.
    264     It exists so that our globals (e.g. gFamilyHead) that expect *something*
    265     will not be null.
    266  */
    267 class EmptyTypeface : public FamilyTypeface {
    268 public:
    269     EmptyTypeface() : INHERITED(SkTypeface::kNormal, true, NULL, false) {}
    270 
    271     virtual const char* getUniqueString() SK_OVERRIDE const { return NULL; }
    272 
    273 protected:
    274     virtual SkStream* onOpenStream(int*) const SK_OVERRIDE { return NULL; }
    275 
    276 private:
    277     typedef FamilyTypeface INHERITED;
    278 };
    279 
    280 class StreamTypeface : public FamilyTypeface {
    281 public:
    282     StreamTypeface(Style style, bool sysFont, FamilyRec* family,
    283                    SkStream* stream, bool isFixedPitch)
    284     : INHERITED(style, sysFont, family, isFixedPitch) {
    285         stream->ref();
    286         fStream = stream;
    287     }
    288     virtual ~StreamTypeface() {
    289         fStream->unref();
    290     }
    291 
    292     virtual const char* getUniqueString() const SK_OVERRIDE { return NULL; }
    293 
    294 protected:
    295     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
    296         *ttcIndex = 0;
    297         fStream->ref();
    298         return fStream;
    299     }
    300 
    301 private:
    302     SkStream* fStream;
    303 
    304     typedef FamilyTypeface INHERITED;
    305 };
    306 
    307 class FileTypeface : public FamilyTypeface {
    308 public:
    309     FileTypeface(Style style, bool sysFont, FamilyRec* family,
    310                  const char path[], bool isFixedPitch)
    311         : INHERITED(style, sysFont, family, isFixedPitch) {
    312         fPath.set(path);
    313     }
    314 
    315     virtual const char* getUniqueString() const SK_OVERRIDE {
    316         const char* str = strrchr(fPath.c_str(), '/');
    317         if (str) {
    318             str += 1;   // skip the '/'
    319         }
    320         return str;
    321     }
    322 
    323 protected:
    324     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE {
    325         *ttcIndex = 0;
    326         return SkStream::NewFromFile(fPath.c_str());
    327     }
    328 
    329 private:
    330     SkString fPath;
    331 
    332     typedef FamilyTypeface INHERITED;
    333 };
    334 
    335 ///////////////////////////////////////////////////////////////////////////////
    336 ///////////////////////////////////////////////////////////////////////////////
    337 
    338 static bool get_name_and_style(const char path[], SkString* name,
    339                                SkTypeface::Style* style, bool* isFixedPitch) {
    340     SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
    341     if (stream.get()) {
    342         return find_name_and_attributes(stream, name, style, isFixedPitch);
    343     } else {
    344         SkDebugf("---- failed to open <%s> as a font\n", path);
    345         return false;
    346     }
    347 }
    348 
    349 // these globals are assigned (once) by load_system_fonts()
    350 static SkTypeface* gFallBackTypeface;
    351 static FamilyRec* gDefaultFamily;
    352 static SkTypeface* gDefaultNormal;
    353 
    354 static void load_directory_fonts(const SkString& directory, unsigned int* count) {
    355     SkOSFile::Iter  iter(directory.c_str(), ".ttf");
    356     SkString        name;
    357 
    358     while (iter.next(&name, false)) {
    359         SkString filename(directory);
    360         filename.append(name);
    361 
    362         bool isFixedPitch;
    363         SkString realname;
    364         SkTypeface::Style style = SkTypeface::kNormal; // avoid uninitialized warning
    365 
    366         if (!get_name_and_style(filename.c_str(), &realname, &style, &isFixedPitch)) {
    367             SkDebugf("------ can't load <%s> as a font\n", filename.c_str());
    368             continue;
    369         }
    370 
    371         FamilyRec* family = find_familyrec(realname.c_str());
    372         if (family && family->fFaces[style]) {
    373             continue;
    374         }
    375 
    376         // this constructor puts us into the global gFamilyHead llist
    377         FamilyTypeface* tf = SkNEW_ARGS(FileTypeface,
    378                                         (style,
    379                                          true,  // system-font (cannot delete)
    380                                          family, // what family to join
    381                                          filename.c_str(),
    382                                          isFixedPitch) // filename
    383                                         );
    384 
    385         if (NULL == family) {
    386             add_name(realname.c_str(), tf->getFamily());
    387         }
    388         *count += 1;
    389     }
    390 
    391     SkOSFile::Iter  dirIter(directory.c_str());
    392     while (dirIter.next(&name, true)) {
    393         if (name.startsWith(".")) {
    394             continue;
    395         }
    396         SkString dirname(directory);
    397         dirname.append(name);
    398         dirname.append(SK_FONT_FILE_DIR_SEPERATOR);
    399         load_directory_fonts(dirname, count);
    400     }
    401 }
    402 
    403 static void load_system_fonts() {
    404     // check if we've already be called
    405     if (NULL != gDefaultNormal) {
    406         return;
    407     }
    408 
    409     SkString baseDirectory(SK_FONT_FILE_PREFIX);
    410     unsigned int count = 0;
    411     load_directory_fonts(baseDirectory, &count);
    412 
    413     if (0 == count) {
    414         SkNEW(EmptyTypeface);
    415     }
    416 
    417     // do this after all fonts are loaded. This is our default font, and it
    418     // acts as a sentinel so we only execute load_system_fonts() once
    419     static const char* gDefaultNames[] = {
    420         "Arial", "Verdana", "Times New Roman", NULL
    421     };
    422     const char** names = gDefaultNames;
    423     while (*names) {
    424         SkTypeface* tf = find_typeface(*names++, SkTypeface::kNormal);
    425         if (tf) {
    426             gDefaultNormal = tf;
    427             break;
    428         }
    429     }
    430     // check if we found *something*
    431     if (NULL == gDefaultNormal) {
    432         if (NULL == gFamilyHead) {
    433             sk_throw();
    434         }
    435         for (int i = 0; i < 4; i++) {
    436             if ((gDefaultNormal = gFamilyHead->fFaces[i]) != NULL) {
    437                 break;
    438             }
    439         }
    440     }
    441     if (NULL == gDefaultNormal) {
    442         sk_throw();
    443     }
    444     gFallBackTypeface = gDefaultNormal;
    445     gDefaultFamily = find_family(gDefaultNormal);
    446 }
    447 
    448 ///////////////////////////////////////////////////////////////////////////////
    449 
    450 void FamilyTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
    451                                          bool* isLocalStream) const {
    452     desc->setFamilyName(find_family_name(this));
    453     desc->setFontFileName(this->getUniqueString());
    454     *isLocalStream = !this->isSysFont();
    455 }
    456 
    457 static SkTypeface* create_typeface(const SkTypeface* familyFace,
    458                                    const char familyName[],
    459                                    SkTypeface::Style style) {
    460     load_system_fonts();
    461 
    462     SkAutoMutexAcquire  ac(gFamilyMutex);
    463 
    464     // clip to legal style bits
    465     style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
    466 
    467     SkTypeface* tf = NULL;
    468 
    469     if (NULL != familyFace) {
    470         tf = find_typeface(familyFace, style);
    471     } else if (NULL != familyName) {
    472         //        SkDebugf("======= familyName <%s>\n", familyName);
    473         tf = find_typeface(familyName, style);
    474     }
    475 
    476     if (NULL == tf) {
    477         tf = find_best_face(gDefaultFamily, style);
    478     }
    479 
    480     SkSafeRef(tf);
    481     return tf;
    482 }
    483 
    484 SkTypeface* FamilyTypeface::onRefMatchingStyle(Style style) const {
    485     return create_typeface(this, NULL, style);
    486 }
    487 
    488 ///////////////////////////////////////////////////////////////////////////////
    489 
    490 #ifndef SK_FONTHOST_USES_FONTMGR
    491 
    492 SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
    493                                        const char familyName[],
    494                                        SkTypeface::Style style) {
    495     return create_typeface(familyFace, NULL, style);
    496 }
    497 
    498 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
    499     if (NULL == stream || stream->getLength() <= 0) {
    500         SkDELETE(stream);
    501         return NULL;
    502     }
    503 
    504     bool isFixedPitch;
    505     SkTypeface::Style style;
    506     if (find_name_and_attributes(stream, NULL, &style, &isFixedPitch)) {
    507         return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream, isFixedPitch));
    508     } else {
    509         return NULL;
    510     }
    511 }
    512 
    513 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
    514     SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
    515     return stream.get() ? CreateTypefaceFromStream(stream) : NULL;
    516 }
    517 
    518 #endif
    519 
    520 ///////////////////////////////////////////////////////////////////////////////
    521 
    522 #include "SkFontMgr.h"
    523 
    524 SkFontMgr* SkFontMgr::Factory() {
    525     // todo
    526     return NULL;
    527 }
    528