| OLD | NEW |
| (Empty) |
| 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, fami
lyName)) { | |
| 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, n
ame); | |
| 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 fontI
D, | |
| 251 SkAdvancedType
faceMetrics::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 } | |
| OLD | NEW |