Home | History | Annotate | Download | only in ios
      1 #import <UIKit/UIKit.h>
      2 
      3 #include "SkStream_NSData.h"
      4 #include "SkTypeface.h"
      5 #include "SkFontHost.h"
      6 #include "SkThread.h"
      7 #include "SkTemplates.h"
      8 
      9 enum FontDesign {
     10     kUnknown_Design,
     11     kSans_FontDesign,
     12     kSerif_FontDesign,
     13 
     14     kIllegal_FontDesign,    // never use with a real font
     15 };
     16 
     17 // returns kIllegal_FontDesign if not found
     18 static FontDesign find_design_from_name(const char name[]) {
     19     static const struct {
     20         const char* fName;
     21         FontDesign  fDesign;
     22     } gRec[] = {
     23         { "sans-serif", kSans_FontDesign },
     24         { "serif",      kSerif_FontDesign },
     25     };
     26 
     27     for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
     28         if (!strcasecmp(name, gRec[i].fName)) {
     29             return gRec[i].fDesign;
     30         }
     31     }
     32     return kIllegal_FontDesign;
     33 }
     34 
     35 struct FontRes {
     36     const char*         fName;
     37     SkTypeface::Style   fStyle;
     38     FontDesign          fDesign;
     39 };
     40 
     41 static const FontRes gFontRes[] = {
     42     { "DroidSans",          SkTypeface::kNormal,    kSans_FontDesign    },
     43     { "DroidSans",          SkTypeface::kBold,      kSans_FontDesign    },
     44     { "DroidSerif-Regular", SkTypeface::kNormal,    kSerif_FontDesign    },
     45     { "DroidSerif-Bold",    SkTypeface::kBold,      kSerif_FontDesign    },
     46 //    { "PescaderoPro",       SkTypeface::kNormal,    kSerif_FontDesign   },
     47 //    { "PescaderoPro-Bold",  SkTypeface::kBold,      kSerif_FontDesign   },
     48 };
     49 #define FONTRES_COUNT SK_ARRAY_COUNT(gFontRes)
     50 
     51 #define DEFAULT_INDEX_REGULAR   1
     52 #define DEFAULT_INDEX_BOLD      2
     53 
     54 ///////////////////////////////////////////////////////////////////////////////
     55 
     56 class SkTypeface_Stream : public SkTypeface {
     57 public:
     58     SkTypeface_Stream(SkStream* stream, Style style);
     59     virtual ~SkTypeface_Stream();
     60 
     61     SkStream* refStream() {
     62         fStream->ref();
     63         return fStream;
     64     }
     65 
     66 private:
     67     SkStream*   fStream;
     68 };
     69 
     70 static int32_t gUniqueFontID;
     71 
     72 SkTypeface_Stream::SkTypeface_Stream(SkStream* stream, Style style)
     73 : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1) {
     74     fStream = stream;
     75     fStream->ref();
     76 }
     77 
     78 SkTypeface_Stream::~SkTypeface_Stream() {
     79     fStream->unref();
     80 }
     81 
     82 static SkTypeface_Stream* create_from_fontres(const FontRes& res) {
     83     SkStream* stream = SkStream_NSData::CreateFromResource(res.fName, "ttf");
     84     SkAutoUnref aur(stream);
     85 
     86     return SkNEW_ARGS(SkTypeface_Stream, (stream, res.fStyle));
     87 }
     88 
     89 ///////////////////////////////////////////////////////////////////////////////
     90 
     91 static int compute_style_distance(SkTypeface::Style a, SkTypeface::Style b) {
     92     int dist = 0;
     93     int diff = a ^ b;
     94     if (diff & SkTypeface::kBold) {
     95         dist += 2;
     96     }
     97     if (diff & SkTypeface::kItalic) {
     98         dist += 1;
     99     }
    100     return dist;
    101 }
    102 
    103 static SkTypeface_Stream* gFonts[FONTRES_COUNT];
    104 
    105 static void assure_init_fonts() {
    106     static bool gOnce;
    107     if (!gOnce) {
    108         for (size_t i = 0; i < FONTRES_COUNT; i++) {
    109             gFonts[i] = create_from_fontres(gFontRes[i]);
    110             gOnce = true;
    111         }
    112     }
    113 }
    114 
    115 static SkTypeface_Stream* get_default_font(SkTypeface::Style style) {
    116     assure_init_fonts();
    117 
    118     if (style & SkTypeface::kBold) {
    119         return gFonts[DEFAULT_INDEX_BOLD];
    120     } else {
    121         return gFonts[DEFAULT_INDEX_REGULAR];
    122     }
    123 }
    124 
    125 static SkTypeface_Stream* find_by_id(SkFontID fontID) {
    126     assure_init_fonts();
    127     
    128     for (size_t i = 0; i < FONTRES_COUNT; i++) {
    129         if (gFonts[i]->uniqueID() == fontID) {
    130             return gFonts[i];
    131         }
    132     }
    133     return NULL;
    134 }
    135 
    136 ///////////////////////////////////////////////////////////////////////////////
    137 
    138 template <typename T> T* ref_and_return(T* obj) {
    139     obj->ref();
    140     return obj;
    141 }
    142 
    143 SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
    144                                      const char familyName[],
    145                                      const void* data, size_t bytelength,
    146                                      SkTypeface::Style style) {
    147     assure_init_fonts();
    148 
    149     if (familyName) {
    150         FontDesign design = find_design_from_name(familyName);
    151         if (kIllegal_FontDesign != design) {
    152             familyName = "$#@*&%*#$@ never match any name";
    153         }
    154 
    155         int bestDistance = 999;
    156         int bestIndex = -1;
    157         for (size_t i = 0; i < FONTRES_COUNT; i++) {
    158             if (design == gFontRes[i].fDesign || !strcmp(gFontRes[i].fName, familyName)) {
    159                 int dist = compute_style_distance(style, gFontRes[i].fStyle);
    160                 if (dist < bestDistance) {
    161                     bestDistance = dist;
    162                     bestIndex = i;
    163                 }
    164             }
    165         }
    166         if (bestIndex >= 0) {
    167             return ref_and_return(gFonts[bestIndex]);
    168         }
    169     }
    170 
    171     return ref_and_return(get_default_font(style));
    172 }
    173 
    174 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
    175     SkDEBUGFAIL("SkFontHost::CreateTypeface unimplemented");
    176     return NULL;
    177 }
    178 
    179 SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*) {
    180 //    SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented");
    181     return NULL;
    182 }
    183 
    184 ///////////////////////////////////////////////////////////////////////////////
    185 
    186 SkStream* SkFontHost::OpenStream(uint32_t uniqueID) {
    187     SkTypeface_Stream* tf = find_by_id(uniqueID);
    188     SkASSERT(tf);
    189     return tf->refStream();
    190 }
    191 
    192 size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
    193                                int32_t* index) {
    194     SkDebugf("SkFontHost::GetFileName unimplemented\n");
    195     return 0;
    196 }
    197 
    198 ///////////////////////////////////////////////////////////////////////////////
    199 
    200 void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
    201     SkDEBUGFAIL("SkFontHost::Serialize unimplemented");
    202 }
    203 
    204 SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
    205     int style = stream->readU8();
    206     int len = stream->readPackedUInt();
    207     const char* name = NULL;
    208     if (len > 0) {
    209         SkString str;
    210         str.resize(len);
    211         stream->read(str.writable_str(), len);
    212         
    213         if (str.startsWith("DroidSans")) {
    214             name = "sans-serif";
    215         } else if (str.startsWith("DroidSerif")) {
    216             name = "serif";
    217         }
    218         SkDebugf("---- deserialize typeface <%s> %d %s\n", str.c_str(), style, name);
    219     }
    220 //    name = NULL; style = 0;
    221     return SkFontHost::CreateTypeface(NULL, name, NULL, NULL,
    222                                       (SkTypeface::Style)style);
    223 }
    224 
    225 SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
    226     return 0;
    227 }
    228 
    229 #define FONT_CACHE_MEMORY_BUDGET    1 * 1024 * 1024
    230 
    231 size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) {
    232     if (sizeAllocatedSoFar > FONT_CACHE_MEMORY_BUDGET)
    233         return sizeAllocatedSoFar - FONT_CACHE_MEMORY_BUDGET;
    234     else
    235         return 0;   // nothing to do
    236 }
    237 
    238 ///////////////////////////////////////////////////////////////////////////////
    239 int SkFontHost::ComputeGammaFlag(const SkPaint& paint) {
    240     return 0;
    241 }
    242 
    243 void SkFontHost::GetGammaTables(const uint8_t* tables[2]) {
    244     tables[0] = NULL;   // black gamma (e.g. exp=1.4)
    245     tables[1] = NULL;   // white gamma (e.g. exp= 1/1.4)
    246 }
    247 
    248 // static
    249 SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
    250                                                                   uint32_t fontID,
    251                                                                   SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
    252     SkDEBUGFAIL("SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
    253     return NULL;
    254 }
    255 
    256 void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface*) {
    257 }
    258 
    259 SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
    260     SkDEBUGFAIL("SkFontHost::CreateScalarContext unimplemented");
    261     return NULL;
    262 }