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 }