gfx/skia/trunk/src/utils/ios/SkFontHost_iOS.mm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 #import <UIKit/UIKit.h>
     3 #include "SkStream_NSData.h"
     4 #include "SkTypeface.h"
     5 #include "SkFontHost.h"
     6 #include "SkThread.h"
     7 #include "SkTemplates.h"
     9 enum FontDesign {
    10     kUnknown_Design,
    11     kSans_FontDesign,
    12     kSerif_FontDesign,
    14     kIllegal_FontDesign,    // never use with a real font
    15 };
    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     };
    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 }
    35 struct FontRes {
    36     const char*         fName;
    37     SkTypeface::Style   fStyle;
    38     FontDesign          fDesign;
    39 };
    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)
    51 #define DEFAULT_INDEX_REGULAR   1
    52 #define DEFAULT_INDEX_BOLD      2
    54 ///////////////////////////////////////////////////////////////////////////////
    56 class SkTypeface_Stream : public SkTypeface {
    57 public:
    58     SkTypeface_Stream(SkStream* stream, Style style);
    59     virtual ~SkTypeface_Stream();
    61     SkStream* refStream() {
    62         fStream->ref();
    63         return fStream;
    64     }
    66 private:
    67     SkStream*   fStream;
    68 };
    70 static int32_t gUniqueFontID;
    72 SkTypeface_Stream::SkTypeface_Stream(SkStream* stream, Style style)
    73 : SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1) {
    74     fStream = stream;
    75     fStream->ref();
    76 }
    78 SkTypeface_Stream::~SkTypeface_Stream() {
    79     fStream->unref();
    80 }
    82 static SkTypeface_Stream* create_from_fontres(const FontRes& res) {
    83     SkStream* stream = SkStream_NSData::CreateFromResource(res.fName, "ttf");
    84     SkAutoUnref aur(stream);
    86     return SkNEW_ARGS(SkTypeface_Stream, (stream, res.fStyle));
    87 }
    89 ///////////////////////////////////////////////////////////////////////////////
    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 }
   103 static SkTypeface_Stream* gFonts[FONTRES_COUNT];
   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 }
   115 static SkTypeface_Stream* get_default_font(SkTypeface::Style style) {
   116     assure_init_fonts();
   118     if (style & SkTypeface::kBold) {
   119         return gFonts[DEFAULT_INDEX_BOLD];
   120     } else {
   121         return gFonts[DEFAULT_INDEX_REGULAR];
   122     }
   123 }
   125 static SkTypeface_Stream* find_by_id(SkFontID fontID) {
   126     assure_init_fonts();
   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 }
   136 ///////////////////////////////////////////////////////////////////////////////
   138 template <typename T> T* ref_and_return(T* obj) {
   139     obj->ref();
   140     return obj;
   141 }
   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();
   149     if (familyName) {
   150         FontDesign design = find_design_from_name(familyName);
   151         if (kIllegal_FontDesign != design) {
   152             familyName = "$#@*&%*#$@ never match any name";
   153         }
   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     }
   171     return ref_and_return(get_default_font(style));
   172 }
   174 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
   175     SkDEBUGFAIL("SkFontHost::CreateTypeface unimplemented");
   176     return NULL;
   177 }
   179 SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*) {
   180 //    SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented");
   181     return NULL;
   182 }
   184 ///////////////////////////////////////////////////////////////////////////////
   186 SkStream* SkFontHost::OpenStream(uint32_t uniqueID) {
   187     SkTypeface_Stream* tf = find_by_id(uniqueID);
   188     SkASSERT(tf);
   189     return tf->refStream();
   190 }
   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 }
   198 ///////////////////////////////////////////////////////////////////////////////
   200 void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
   201     SkDEBUGFAIL("SkFontHost::Serialize unimplemented");
   202 }
   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);
   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 }
   225 SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
   226     return 0;
   227 }
   229 #define FONT_CACHE_MEMORY_BUDGET    1 * 1024 * 1024
   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 }
   238 ///////////////////////////////////////////////////////////////////////////////
   239 int SkFontHost::ComputeGammaFlag(const SkPaint& paint) {
   240     return 0;
   241 }
   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 }
   248 // static
   249 SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
   250                                                                   uint32_t fontID,
   251                                                                   SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
   252     SkDEBUGFAIL("SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
   253     return NULL;
   254 }
   256 void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface*) {
   257 }
   259 SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
   260     SkDEBUGFAIL("SkFontHost::CreateScalarContext unimplemented");
   261     return NULL;
   262 }

mercurial