1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "SkFontHost.h"
18#include "SkDescriptor.h"
19#include "SkMMapStream.h"
20#include "SkPaint.h"
21#include "SkString.h"
22#include "SkStream.h"
23#include "SkThread.h"
24#include "SkTSearch.h"
25#include <stdio.h>
26
27#define FONT_CACHE_MEMORY_BUDGET    (768 * 1024)
28
29#ifdef SK_BUILD_FOR_MAC
30    #define SK_FONT_FILE_PREFIX     "/Library/Fonts/"
31#else
32    #define SK_FONT_FILE_PREFIX          "/skimages/"
33#endif
34
35SkTypeface::Style find_name_and_attributes(SkStream* stream, SkString* name,
36                                           bool* isFixedWidth);
37
38static void GetFullPathForSysFonts(SkString* full, const char name[]) {
39    full->set(SK_FONT_FILE_PREFIX);
40    full->append(name);
41}
42
43///////////////////////////////////////////////////////////////////////////////
44
45struct FamilyRec;
46
47/*  This guy holds a mapping of a name -> family, used for looking up fonts.
48    Since it is stored in a stretchy array that doesn't preserve object
49    semantics, we don't use constructor/destructors, but just have explicit
50    helpers to manage our internal bookkeeping.
51*/
52struct NameFamilyPair {
53    const char* fName;      // we own this
54    FamilyRec*  fFamily;    // we don't own this, we just reference it
55
56    void construct(const char name[], FamilyRec* family) {
57        fName = strdup(name);
58        fFamily = family;   // we don't own this, so just record the referene
59    }
60
61    void destruct() {
62        free((char*)fName);
63        // we don't own family, so just ignore our reference
64    }
65};
66
67// we use atomic_inc to grow this for each typeface we create
68static int32_t gUniqueFontID;
69
70// this is the mutex that protects these globals
71static SkMutex gFamilyMutex;
72static FamilyRec* gFamilyHead;
73static SkTDArray<NameFamilyPair> gNameList;
74
75struct FamilyRec {
76    FamilyRec*  fNext;
77    SkTypeface* fFaces[4];
78
79    FamilyRec()
80    {
81        fNext = gFamilyHead;
82        memset(fFaces, 0, sizeof(fFaces));
83        gFamilyHead = this;
84    }
85};
86
87static SkTypeface* find_best_face(const FamilyRec* family,
88                                  SkTypeface::Style style) {
89    SkTypeface* const* faces = family->fFaces;
90
91    if (faces[style] != NULL) { // exact match
92        return faces[style];
93    }
94    // look for a matching bold
95    style = (SkTypeface::Style)(style ^ SkTypeface::kItalic);
96    if (faces[style] != NULL) {
97        return faces[style];
98    }
99    // look for the plain
100    if (faces[SkTypeface::kNormal] != NULL) {
101        return faces[SkTypeface::kNormal];
102    }
103    // look for anything
104    for (int i = 0; i < 4; i++) {
105        if (faces[i] != NULL) {
106            return faces[i];
107        }
108    }
109    // should never get here, since the faces list should not be empty
110    SkASSERT(!"faces list is empty");
111    return NULL;
112}
113
114static FamilyRec* find_family(const SkTypeface* member) {
115    FamilyRec* curr = gFamilyHead;
116    while (curr != NULL) {
117        for (int i = 0; i < 4; i++) {
118            if (curr->fFaces[i] == member) {
119                return curr;
120            }
121        }
122        curr = curr->fNext;
123    }
124    return NULL;
125}
126
127/*  Returns the matching typeface, or NULL. If a typeface is found, its refcnt
128    is not modified.
129 */
130static SkTypeface* find_from_uniqueID(uint32_t uniqueID) {
131    FamilyRec* curr = gFamilyHead;
132    while (curr != NULL) {
133        for (int i = 0; i < 4; i++) {
134            SkTypeface* face = curr->fFaces[i];
135            if (face != NULL && face->uniqueID() == uniqueID) {
136                return face;
137            }
138        }
139        curr = curr->fNext;
140    }
141    return NULL;
142}
143
144/*  Remove reference to this face from its family. If the resulting family
145    is empty (has no faces), return that family, otherwise return NULL
146*/
147static FamilyRec* remove_from_family(const SkTypeface* face) {
148    FamilyRec* family = find_family(face);
149    SkASSERT(family->fFaces[face->style()] == face);
150    family->fFaces[face->style()] = NULL;
151
152    for (int i = 0; i < 4; i++) {
153        if (family->fFaces[i] != NULL) {    // family is non-empty
154            return NULL;
155        }
156    }
157    return family;  // return the empty family
158}
159
160// maybe we should make FamilyRec be doubly-linked
161static void detach_and_delete_family(FamilyRec* family) {
162    FamilyRec* curr = gFamilyHead;
163    FamilyRec* prev = NULL;
164
165    while (curr != NULL) {
166        FamilyRec* next = curr->fNext;
167        if (curr == family) {
168            if (prev == NULL) {
169                gFamilyHead = next;
170            } else {
171                prev->fNext = next;
172            }
173            SkDELETE(family);
174            return;
175        }
176        prev = curr;
177        curr = next;
178    }
179    SkASSERT(!"Yikes, couldn't find family in our list to remove/delete");
180}
181
182static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) {
183    NameFamilyPair* list = gNameList.begin();
184    int             count = gNameList.count();
185
186    int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
187
188    if (index >= 0) {
189        return find_best_face(list[index].fFamily, style);
190    }
191    return NULL;
192}
193
194static SkTypeface* find_typeface(const SkTypeface* familyMember,
195                                 SkTypeface::Style style) {
196    const FamilyRec* family = find_family(familyMember);
197    return family ? find_best_face(family, style) : NULL;
198}
199
200static void add_name(const char name[], FamilyRec* family) {
201    SkAutoAsciiToLC tolc(name);
202    name = tolc.lc();
203
204    NameFamilyPair* list = gNameList.begin();
205    int             count = gNameList.count();
206
207    int index = SkStrLCSearch(&list[0].fName, count, name, sizeof(list[0]));
208
209    if (index < 0) {
210        list = gNameList.insert(~index);
211        list->construct(name, family);
212    }
213}
214
215static void remove_from_names(FamilyRec* emptyFamily)
216{
217#ifdef SK_DEBUG
218    for (int i = 0; i < 4; i++) {
219        SkASSERT(emptyFamily->fFaces[i] == NULL);
220    }
221#endif
222
223    SkTDArray<NameFamilyPair>& list = gNameList;
224
225    // must go backwards when removing
226    for (int i = list.count() - 1; i >= 0; --i) {
227        NameFamilyPair* pair = &list[i];
228        if (pair->fFamily == emptyFamily) {
229            pair->destruct();
230            list.remove(i);
231        }
232    }
233}
234
235///////////////////////////////////////////////////////////////////////////////
236
237class FamilyTypeface : public SkTypeface {
238public:
239    FamilyTypeface(Style style, bool sysFont, SkTypeface* familyMember)
240    : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1) {
241        fIsSysFont = sysFont;
242
243        SkAutoMutexAcquire  ac(gFamilyMutex);
244
245        FamilyRec* rec = NULL;
246        if (familyMember) {
247            rec = find_family(familyMember);
248            SkASSERT(rec);
249        } else {
250            rec = SkNEW(FamilyRec);
251        }
252        rec->fFaces[style] = this;
253    }
254
255    virtual ~FamilyTypeface() {
256        SkAutoMutexAcquire  ac(gFamilyMutex);
257
258        // remove us from our family. If the family is now empty, we return
259        // that and then remove that family from the name list
260        FamilyRec* family = remove_from_family(this);
261        if (NULL != family) {
262            remove_from_names(family);
263            detach_and_delete_family(family);
264        }
265    }
266
267    bool isSysFont() const { return fIsSysFont; }
268
269    virtual SkStream* openStream() = 0;
270    virtual const char* getUniqueString() const = 0;
271    virtual const char* getFilePath() const = 0;
272
273private:
274    bool    fIsSysFont;
275
276    typedef SkTypeface INHERITED;
277};
278
279///////////////////////////////////////////////////////////////////////////////
280
281class StreamTypeface : public FamilyTypeface {
282public:
283    StreamTypeface(Style style, bool sysFont, SkTypeface* familyMember,
284                   SkStream* stream)
285    : INHERITED(style, sysFont, familyMember) {
286        SkASSERT(stream);
287        stream->ref();
288        fStream = stream;
289    }
290    virtual ~StreamTypeface() {
291        fStream->unref();
292    }
293
294    // overrides
295    virtual SkStream* openStream() {
296        // we just ref our existing stream, since the caller will call unref()
297        // when they are through
298        fStream->ref();
299        return fStream;
300    }
301    virtual const char* getUniqueString() const { return NULL; }
302    virtual const char* getFilePath() const { return NULL; }
303
304private:
305    SkStream* fStream;
306
307    typedef FamilyTypeface INHERITED;
308};
309
310class FileTypeface : public FamilyTypeface {
311public:
312    FileTypeface(Style style, bool sysFont, SkTypeface* familyMember,
313                 const char path[])
314    : INHERITED(style, sysFont, familyMember) {
315        SkString fullpath;
316
317        if (sysFont) {
318            GetFullPathForSysFonts(&fullpath, path);
319            path = fullpath.c_str();
320        }
321        fPath.set(path);
322    }
323
324    // overrides
325    virtual SkStream* openStream() {
326        SkStream* stream = SkNEW_ARGS(SkMMAPStream, (fPath.c_str()));
327
328        // check for failure
329        if (stream->getLength() <= 0) {
330            SkDELETE(stream);
331            // maybe MMAP isn't supported. try FILE
332            stream = SkNEW_ARGS(SkFILEStream, (fPath.c_str()));
333            if (stream->getLength() <= 0) {
334                SkDELETE(stream);
335                stream = NULL;
336            }
337        }
338        return stream;
339    }
340    virtual const char* getUniqueString() const {
341        const char* str = strrchr(fPath.c_str(), '/');
342        if (str) {
343            str += 1;   // skip the '/'
344        }
345        return str;
346    }
347    virtual const char* getFilePath() const {
348        return fPath.c_str();
349    }
350
351private:
352    SkString fPath;
353
354    typedef FamilyTypeface INHERITED;
355};
356
357///////////////////////////////////////////////////////////////////////////////
358///////////////////////////////////////////////////////////////////////////////
359
360static bool get_name_and_style(const char path[], SkString* name,
361                               SkTypeface::Style* style, bool isExpected) {
362    bool            isFixedWidth;
363    SkString        fullpath;
364    GetFullPathForSysFonts(&fullpath, path);
365
366    SkMMAPStream stream(fullpath.c_str());
367    if (stream.getLength() > 0) {
368        *style = find_name_and_attributes(&stream, name, &isFixedWidth);
369        return true;
370    }
371    else {
372        SkFILEStream stream(fullpath.c_str());
373        if (stream.getLength() > 0) {
374            *style = find_name_and_attributes(&stream, name, &isFixedWidth);
375            return true;
376        }
377    }
378
379    if (isExpected) {
380        SkDebugf("---- failed to open <%s> as a font\n", fullpath.c_str());
381    }
382    return false;
383}
384
385// used to record our notion of the pre-existing fonts
386struct FontInitRec {
387    const char*         fFileName;
388    const char* const*  fNames;     // null-terminated list
389};
390
391static const char* gSansNames[] = {
392    "sans-serif", "arial", "helvetica", "tahoma", "verdana", NULL
393};
394
395static const char* gSerifNames[] = {
396    "serif", "times", "times new roman", "palatino", "georgia", "baskerville",
397    "goudy", "fantasy", "cursive", "ITC Stone Serif", NULL
398};
399
400static const char* gMonoNames[] = {
401    "monospace", "courier", "courier new", "monaco", NULL
402};
403
404// deliberately empty, but we use the address to identify fallback fonts
405static const char* gFBNames[] = { NULL };
406
407/*  Fonts must be grouped by family, with the first font in a family having the
408    list of names (even if that list is empty), and the following members having
409    null for the list. The names list must be NULL-terminated
410*/
411static const FontInitRec gSystemFonts[] = {
412    { "Arial.ttf",              gSansNames  },
413    { "Times.ttf",              gSerifNames  },
414    { "samplefont.ttf",              gSansNames  },
415};
416
417#define DEFAULT_NAMES   gSansNames
418
419// these globals are assigned (once) by load_system_fonts()
420static FamilyRec* gDefaultFamily;
421static SkTypeface* gDefaultNormal;
422
423/*  This is sized conservatively, assuming that it will never be a size issue.
424    It will be initialized in load_system_fonts(), and will be filled with the
425    fontIDs that can be used for fallback consideration, in sorted order (sorted
426    meaning element[0] should be used first, then element[1], etc. When we hit
427    a fontID==0 in the array, the list is done, hence our allocation size is
428    +1 the total number of possible system fonts. Also see NextLogicalFont().
429 */
430static uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1];
431
432/*  Called once (ensured by the sentinel check at the beginning of our body).
433    Initializes all the globals, and register the system fonts.
434 */
435static void load_system_fonts() {
436    // check if we've already be called
437    if (NULL != gDefaultNormal) {
438        return;
439    }
440
441    const FontInitRec* rec = gSystemFonts;
442    SkTypeface* firstInFamily = NULL;
443    int fallbackCount = 0;
444
445    for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
446        // if we're the first in a new family, clear firstInFamily
447        if (rec[i].fNames != NULL) {
448            firstInFamily = NULL;
449        }
450
451        SkString name;
452        SkTypeface::Style style;
453
454        // we expect all the fonts, except the "fallback" fonts
455        bool isExpected = (rec[i].fNames != gFBNames);
456        if (!get_name_and_style(rec[i].fFileName, &name, &style, isExpected)) {
457            continue;
458        }
459
460        SkTypeface* tf = SkNEW_ARGS(FileTypeface,
461                                    (style,
462                                     true,  // system-font (cannot delete)
463                                     firstInFamily, // what family to join
464                                     rec[i].fFileName) // filename
465                                    );
466
467        if (rec[i].fNames != NULL) {
468            // see if this is one of our fallback fonts
469            if (rec[i].fNames == gFBNames) {
470            //    SkDebugf("---- adding %s as fallback[%d] fontID %d\n",
471            //             rec[i].fFileName, fallbackCount, tf->uniqueID());
472                gFallbackFonts[fallbackCount++] = tf->uniqueID();
473            }
474
475            firstInFamily = tf;
476            FamilyRec* family = find_family(tf);
477            const char* const* names = rec[i].fNames;
478
479            // record the default family if this is it
480            if (names == DEFAULT_NAMES) {
481                gDefaultFamily = family;
482            }
483            // add the names to map to this family
484            while (*names) {
485                add_name(*names, family);
486                names += 1;
487            }
488        }
489    }
490
491    // do this after all fonts are loaded. This is our default font, and it
492    // acts as a sentinel so we only execute load_system_fonts() once
493    gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal);
494    // now terminate our fallback list with the sentinel value
495    gFallbackFonts[fallbackCount] = 0;
496}
497
498///////////////////////////////////////////////////////////////////////////////
499
500void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
501    const char* name = ((FamilyTypeface*)face)->getUniqueString();
502
503    stream->write8((uint8_t)face->style());
504
505    if (NULL == name || 0 == *name) {
506        stream->writePackedUInt(0);
507//        SkDebugf("--- fonthost serialize null\n");
508    } else {
509        uint32_t len = strlen(name);
510        stream->writePackedUInt(len);
511        stream->write(name, len);
512//      SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style());
513    }
514}
515
516SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
517    load_system_fonts();
518
519    int style = stream->readU8();
520
521    int len = stream->readPackedUInt();
522    if (len > 0) {
523        SkString str;
524        str.resize(len);
525        stream->read(str.writable_str(), len);
526
527        const FontInitRec* rec = gSystemFonts;
528        for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
529            if (strcmp(rec[i].fFileName, str.c_str()) == 0) {
530                // backup until we hit the fNames
531                for (int j = i; j >= 0; --j) {
532                    if (rec[j].fNames != NULL) {
533                        return SkFontHost::CreateTypeface(NULL,
534                                    rec[j].fNames[0], NULL, 0, (SkTypeface::Style)style);
535                    }
536                }
537            }
538        }
539    }
540    return NULL;
541}
542
543///////////////////////////////////////////////////////////////////////////////
544
545SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
546                                       const char familyName[],
547                                       const void* data, size_t bytelength,
548                                       SkTypeface::Style style) {
549    load_system_fonts();
550
551    SkAutoMutexAcquire  ac(gFamilyMutex);
552
553    // clip to legal style bits
554    style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
555
556    SkTypeface* tf = NULL;
557
558    if (NULL != familyFace) {
559        tf = find_typeface(familyFace, style);
560    } else if (NULL != familyName) {
561//        SkDebugf("======= familyName <%s>\n", familyName);
562        tf = find_typeface(familyName, style);
563    }
564
565    if (NULL == tf) {
566        tf = find_best_face(gDefaultFamily, style);
567    }
568
569    // we ref(), since the symantic is to return a new instance
570    tf->ref();
571    return tf;
572}
573
574bool SkFontHost::ValidFontID(uint32_t fontID) {
575    SkAutoMutexAcquire  ac(gFamilyMutex);
576
577    return find_from_uniqueID(fontID) != NULL;
578}
579
580SkStream* SkFontHost::OpenStream(uint32_t fontID) {
581    SkAutoMutexAcquire  ac(gFamilyMutex);
582
583    FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID);
584    SkStream* stream = tf ? tf->openStream() : NULL;
585
586    if (stream && stream->getLength() == 0) {
587        stream->unref();
588        stream = NULL;
589    }
590    return stream;
591}
592
593#if 0
594SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
595        uint32_t fontID,
596        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
597    SkASSERT(!"SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
598    return NULL;
599}
600#endif
601
602size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
603                               int32_t* index) {
604    SkAutoMutexAcquire  ac(gFamilyMutex);
605
606    FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID);
607    const char* src = tf ? tf->getFilePath() : NULL;
608
609    if (src) {
610        size_t size = strlen(src);
611        if (path) {
612            memcpy(path, src, SkMin32(size, length));
613        }
614        if (index) {
615            *index = 0; // we don't have collections (yet)
616        }
617        return size;
618    } else {
619        return 0;
620    }
621}
622
623SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
624    load_system_fonts();
625
626    /*  First see if fontID is already one of our fallbacks. If so, return
627        its successor. If fontID is not in our list, then return the first one
628        in our list. Note: list is zero-terminated, and returning zero means
629        we have no more fonts to use for fallbacks.
630     */
631    const uint32_t* list = gFallbackFonts;
632    for (int i = 0; list[i] != 0; i++) {
633        if (list[i] == currFontID) {
634            return list[i+1];
635        }
636    }
637    return list[0];
638}
639
640///////////////////////////////////////////////////////////////////////////////
641
642SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
643    if (NULL == stream || stream->getLength() <= 0) {
644        return NULL;
645    }
646
647    bool     isFixedWidth;
648    SkString name;
649    SkTypeface::Style style = find_name_and_attributes(stream, &name,
650                                                       &isFixedWidth);
651
652    return SkNEW_ARGS(StreamTypeface, (style, false, NULL, stream));
653}
654
655SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
656    SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path));
657    SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream);
658    // since we created the stream, we let go of our ref() here
659    stream->unref();
660    return face;
661}
662
663///////////////////////////////////////////////////////////////////////////////
664
665size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) {
666    if (sizeAllocatedSoFar > FONT_CACHE_MEMORY_BUDGET)
667        return sizeAllocatedSoFar - FONT_CACHE_MEMORY_BUDGET;
668    else
669        return 0;   // nothing to do
670}
671
672