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

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/utils/ios/SkFontHost_iOS.mm	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,262 @@
     1.4 +#import <UIKit/UIKit.h>
     1.5 +
     1.6 +#include "SkStream_NSData.h"
     1.7 +#include "SkTypeface.h"
     1.8 +#include "SkFontHost.h"
     1.9 +#include "SkThread.h"
    1.10 +#include "SkTemplates.h"
    1.11 +
    1.12 +enum FontDesign {
    1.13 +    kUnknown_Design,
    1.14 +    kSans_FontDesign,
    1.15 +    kSerif_FontDesign,
    1.16 +
    1.17 +    kIllegal_FontDesign,    // never use with a real font
    1.18 +};
    1.19 +
    1.20 +// returns kIllegal_FontDesign if not found
    1.21 +static FontDesign find_design_from_name(const char name[]) {
    1.22 +    static const struct {
    1.23 +        const char* fName;
    1.24 +        FontDesign  fDesign;
    1.25 +    } gRec[] = {
    1.26 +        { "sans-serif", kSans_FontDesign },
    1.27 +        { "serif",      kSerif_FontDesign },
    1.28 +    };
    1.29 +
    1.30 +    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
    1.31 +        if (!strcasecmp(name, gRec[i].fName)) {
    1.32 +            return gRec[i].fDesign;
    1.33 +        }
    1.34 +    }
    1.35 +    return kIllegal_FontDesign;
    1.36 +}
    1.37 +
    1.38 +struct FontRes {
    1.39 +    const char*         fName;
    1.40 +    SkTypeface::Style   fStyle;
    1.41 +    FontDesign          fDesign;
    1.42 +};
    1.43 +
    1.44 +static const FontRes gFontRes[] = {
    1.45 +    { "DroidSans",          SkTypeface::kNormal,    kSans_FontDesign    },
    1.46 +    { "DroidSans",          SkTypeface::kBold,      kSans_FontDesign    },
    1.47 +    { "DroidSerif-Regular", SkTypeface::kNormal,    kSerif_FontDesign    },
    1.48 +    { "DroidSerif-Bold",    SkTypeface::kBold,      kSerif_FontDesign    },
    1.49 +//    { "PescaderoPro",       SkTypeface::kNormal,    kSerif_FontDesign   },
    1.50 +//    { "PescaderoPro-Bold",  SkTypeface::kBold,      kSerif_FontDesign   },
    1.51 +};
    1.52 +#define FONTRES_COUNT SK_ARRAY_COUNT(gFontRes)
    1.53 +
    1.54 +#define DEFAULT_INDEX_REGULAR   1
    1.55 +#define DEFAULT_INDEX_BOLD      2
    1.56 +
    1.57 +///////////////////////////////////////////////////////////////////////////////
    1.58 +
    1.59 +class SkTypeface_Stream : public SkTypeface {
    1.60 +public:
    1.61 +    SkTypeface_Stream(SkStream* stream, Style style);
    1.62 +    virtual ~SkTypeface_Stream();
    1.63 +
    1.64 +    SkStream* refStream() {
    1.65 +        fStream->ref();
    1.66 +        return fStream;
    1.67 +    }
    1.68 +
    1.69 +private:
    1.70 +    SkStream*   fStream;
    1.71 +};
    1.72 +
    1.73 +static int32_t gUniqueFontID;
    1.74 +
    1.75 +SkTypeface_Stream::SkTypeface_Stream(SkStream* stream, Style style)
    1.76 +: SkTypeface(style, sk_atomic_inc(&gUniqueFontID) + 1) {
    1.77 +    fStream = stream;
    1.78 +    fStream->ref();
    1.79 +}
    1.80 +
    1.81 +SkTypeface_Stream::~SkTypeface_Stream() {
    1.82 +    fStream->unref();
    1.83 +}
    1.84 +
    1.85 +static SkTypeface_Stream* create_from_fontres(const FontRes& res) {
    1.86 +    SkStream* stream = SkStream_NSData::CreateFromResource(res.fName, "ttf");
    1.87 +    SkAutoUnref aur(stream);
    1.88 +
    1.89 +    return SkNEW_ARGS(SkTypeface_Stream, (stream, res.fStyle));
    1.90 +}
    1.91 +
    1.92 +///////////////////////////////////////////////////////////////////////////////
    1.93 +
    1.94 +static int compute_style_distance(SkTypeface::Style a, SkTypeface::Style b) {
    1.95 +    int dist = 0;
    1.96 +    int diff = a ^ b;
    1.97 +    if (diff & SkTypeface::kBold) {
    1.98 +        dist += 2;
    1.99 +    }
   1.100 +    if (diff & SkTypeface::kItalic) {
   1.101 +        dist += 1;
   1.102 +    }
   1.103 +    return dist;
   1.104 +}
   1.105 +
   1.106 +static SkTypeface_Stream* gFonts[FONTRES_COUNT];
   1.107 +
   1.108 +static void assure_init_fonts() {
   1.109 +    static bool gOnce;
   1.110 +    if (!gOnce) {
   1.111 +        for (size_t i = 0; i < FONTRES_COUNT; i++) {
   1.112 +            gFonts[i] = create_from_fontres(gFontRes[i]);
   1.113 +            gOnce = true;
   1.114 +        }
   1.115 +    }
   1.116 +}
   1.117 +
   1.118 +static SkTypeface_Stream* get_default_font(SkTypeface::Style style) {
   1.119 +    assure_init_fonts();
   1.120 +
   1.121 +    if (style & SkTypeface::kBold) {
   1.122 +        return gFonts[DEFAULT_INDEX_BOLD];
   1.123 +    } else {
   1.124 +        return gFonts[DEFAULT_INDEX_REGULAR];
   1.125 +    }
   1.126 +}
   1.127 +
   1.128 +static SkTypeface_Stream* find_by_id(SkFontID fontID) {
   1.129 +    assure_init_fonts();
   1.130 +    
   1.131 +    for (size_t i = 0; i < FONTRES_COUNT; i++) {
   1.132 +        if (gFonts[i]->uniqueID() == fontID) {
   1.133 +            return gFonts[i];
   1.134 +        }
   1.135 +    }
   1.136 +    return NULL;
   1.137 +}
   1.138 +
   1.139 +///////////////////////////////////////////////////////////////////////////////
   1.140 +
   1.141 +template <typename T> T* ref_and_return(T* obj) {
   1.142 +    obj->ref();
   1.143 +    return obj;
   1.144 +}
   1.145 +
   1.146 +SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
   1.147 +                                     const char familyName[],
   1.148 +                                     const void* data, size_t bytelength,
   1.149 +                                     SkTypeface::Style style) {
   1.150 +    assure_init_fonts();
   1.151 +
   1.152 +    if (familyName) {
   1.153 +        FontDesign design = find_design_from_name(familyName);
   1.154 +        if (kIllegal_FontDesign != design) {
   1.155 +            familyName = "$#@*&%*#$@ never match any name";
   1.156 +        }
   1.157 +
   1.158 +        int bestDistance = 999;
   1.159 +        int bestIndex = -1;
   1.160 +        for (size_t i = 0; i < FONTRES_COUNT; i++) {
   1.161 +            if (design == gFontRes[i].fDesign || !strcmp(gFontRes[i].fName, familyName)) {
   1.162 +                int dist = compute_style_distance(style, gFontRes[i].fStyle);
   1.163 +                if (dist < bestDistance) {
   1.164 +                    bestDistance = dist;
   1.165 +                    bestIndex = i;
   1.166 +                }
   1.167 +            }
   1.168 +        }
   1.169 +        if (bestIndex >= 0) {
   1.170 +            return ref_and_return(gFonts[bestIndex]);
   1.171 +        }
   1.172 +    }
   1.173 +
   1.174 +    return ref_and_return(get_default_font(style));
   1.175 +}
   1.176 +
   1.177 +SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
   1.178 +    SkDEBUGFAIL("SkFontHost::CreateTypeface unimplemented");
   1.179 +    return NULL;
   1.180 +}
   1.181 +
   1.182 +SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*) {
   1.183 +//    SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented");
   1.184 +    return NULL;
   1.185 +}
   1.186 +
   1.187 +///////////////////////////////////////////////////////////////////////////////
   1.188 +
   1.189 +SkStream* SkFontHost::OpenStream(uint32_t uniqueID) {
   1.190 +    SkTypeface_Stream* tf = find_by_id(uniqueID);
   1.191 +    SkASSERT(tf);
   1.192 +    return tf->refStream();
   1.193 +}
   1.194 +
   1.195 +size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
   1.196 +                               int32_t* index) {
   1.197 +    SkDebugf("SkFontHost::GetFileName unimplemented\n");
   1.198 +    return 0;
   1.199 +}
   1.200 +
   1.201 +///////////////////////////////////////////////////////////////////////////////
   1.202 +
   1.203 +void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
   1.204 +    SkDEBUGFAIL("SkFontHost::Serialize unimplemented");
   1.205 +}
   1.206 +
   1.207 +SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
   1.208 +    int style = stream->readU8();
   1.209 +    int len = stream->readPackedUInt();
   1.210 +    const char* name = NULL;
   1.211 +    if (len > 0) {
   1.212 +        SkString str;
   1.213 +        str.resize(len);
   1.214 +        stream->read(str.writable_str(), len);
   1.215 +        
   1.216 +        if (str.startsWith("DroidSans")) {
   1.217 +            name = "sans-serif";
   1.218 +        } else if (str.startsWith("DroidSerif")) {
   1.219 +            name = "serif";
   1.220 +        }
   1.221 +        SkDebugf("---- deserialize typeface <%s> %d %s\n", str.c_str(), style, name);
   1.222 +    }
   1.223 +//    name = NULL; style = 0;
   1.224 +    return SkFontHost::CreateTypeface(NULL, name, NULL, NULL,
   1.225 +                                      (SkTypeface::Style)style);
   1.226 +}
   1.227 +
   1.228 +SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
   1.229 +    return 0;
   1.230 +}
   1.231 +
   1.232 +#define FONT_CACHE_MEMORY_BUDGET    1 * 1024 * 1024
   1.233 +
   1.234 +size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) {
   1.235 +    if (sizeAllocatedSoFar > FONT_CACHE_MEMORY_BUDGET)
   1.236 +        return sizeAllocatedSoFar - FONT_CACHE_MEMORY_BUDGET;
   1.237 +    else
   1.238 +        return 0;   // nothing to do
   1.239 +}
   1.240 +
   1.241 +///////////////////////////////////////////////////////////////////////////////
   1.242 +int SkFontHost::ComputeGammaFlag(const SkPaint& paint) {
   1.243 +    return 0;
   1.244 +}
   1.245 +
   1.246 +void SkFontHost::GetGammaTables(const uint8_t* tables[2]) {
   1.247 +    tables[0] = NULL;   // black gamma (e.g. exp=1.4)
   1.248 +    tables[1] = NULL;   // white gamma (e.g. exp= 1/1.4)
   1.249 +}
   1.250 +
   1.251 +// static
   1.252 +SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
   1.253 +                                                                  uint32_t fontID,
   1.254 +                                                                  SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo) {
   1.255 +    SkDEBUGFAIL("SkFontHost::GetAdvancedTypefaceMetrics unimplemented");
   1.256 +    return NULL;
   1.257 +}
   1.258 +
   1.259 +void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface*) {
   1.260 +}
   1.261 +
   1.262 +SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
   1.263 +    SkDEBUGFAIL("SkFontHost::CreateScalarContext unimplemented");
   1.264 +    return NULL;
   1.265 +}
   1.266 \ No newline at end of file

mercurial