OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkFontHost_FreeType_common.h" | 8 #include "SkFontHost_FreeType_common.h" |
9 #include "SkFontDescriptor.h" | 9 #include "SkFontDescriptor.h" |
10 #include "SkFontMgr.h" | 10 #include "SkFontMgr.h" |
11 #include "SkDescriptor.h" | 11 #include "SkDescriptor.h" |
12 #include "SkOSFile.h" | 12 #include "SkOSFile.h" |
13 #include "SkPaint.h" | 13 #include "SkPaint.h" |
14 #include "SkRTConf.h" | 14 #include "SkRTConf.h" |
15 #include "SkString.h" | 15 #include "SkString.h" |
16 #include "SkStream.h" | 16 #include "SkStream.h" |
17 #include "SkThread.h" | 17 #include "SkThread.h" |
18 #include "SkTSearch.h" | 18 #include "SkTSearch.h" |
19 #include "SkTypefaceCache.h" | 19 #include "SkTypefaceCache.h" |
20 #include "SkTArray.h" | 20 #include "SkTArray.h" |
21 | 21 |
22 #include <limits> | 22 #include <limits> |
23 | 23 |
24 #ifndef SK_FONT_FILE_PREFIX | |
25 # define SK_FONT_FILE_PREFIX "/usr/share/fonts/" | |
26 #endif | |
27 | |
28 /////////////////////////////////////////////////////////////////////////////// | |
29 | |
30 /** The base SkTypeface implementation for the custom font manager. */ | 24 /** The base SkTypeface implementation for the custom font manager. */ |
31 class SkTypeface_Custom : public SkTypeface_FreeType { | 25 class SkTypeface_Custom : public SkTypeface_FreeType { |
32 public: | 26 public: |
33 SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch, | 27 SkTypeface_Custom(const SkFontStyle& style, bool isFixedPitch, |
34 bool sysFont, const SkString familyName, int index) | 28 bool sysFont, const SkString familyName, int index) |
35 : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch) | 29 : INHERITED(style, SkTypefaceCache::NewFontID(), isFixedPitch) |
36 , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index) | 30 , fIsSysFont(sysFont), fFamilyName(familyName), fIndex(index) |
37 { } | 31 { } |
38 | 32 |
39 bool isSysFont() const { return fIsSysFont; } | 33 bool isSysFont() const { return fIsSysFont; } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 | 141 |
148 /** | 142 /** |
149 * SkFontStyleSet_Custom | 143 * SkFontStyleSet_Custom |
150 * | 144 * |
151 * This class is used by SkFontMgr_Custom to hold SkTypeface_Custom families. | 145 * This class is used by SkFontMgr_Custom to hold SkTypeface_Custom families. |
152 */ | 146 */ |
153 class SkFontStyleSet_Custom : public SkFontStyleSet { | 147 class SkFontStyleSet_Custom : public SkFontStyleSet { |
154 public: | 148 public: |
155 explicit SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(fami
lyName) { } | 149 explicit SkFontStyleSet_Custom(const SkString familyName) : fFamilyName(fami
lyName) { } |
156 | 150 |
| 151 /** Should only be called during the inital build phase. */ |
| 152 void appendTypeface(SkTypeface_Custom* typeface) { |
| 153 fStyles.push_back().reset(typeface); |
| 154 } |
| 155 |
157 int count() override { | 156 int count() override { |
158 return fStyles.count(); | 157 return fStyles.count(); |
159 } | 158 } |
160 | 159 |
161 void getStyle(int index, SkFontStyle* style, SkString* name) override { | 160 void getStyle(int index, SkFontStyle* style, SkString* name) override { |
162 SkASSERT(index < fStyles.count()); | 161 SkASSERT(index < fStyles.count()); |
163 bool bold = fStyles[index]->isBold(); | 162 bool bold = fStyles[index]->isBold(); |
164 bool italic = fStyles[index]->isItalic(); | 163 bool italic = fStyles[index]->isItalic(); |
165 *style = SkFontStyle(bold ? SkFontStyle::kBold_Weight : SkFontStyle::kNo
rmal_Weight, | 164 *style = SkFontStyle(bold ? SkFontStyle::kBold_Weight : SkFontStyle::kNo
rmal_Weight, |
166 SkFontStyle::kNormal_Width, | 165 SkFontStyle::kNormal_Width, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 | 198 |
200 int score = match_score(pattern, style); | 199 int score = match_score(pattern, style); |
201 if (score < minScore) { | 200 if (score < minScore) { |
202 closest = fStyles[i]; | 201 closest = fStyles[i]; |
203 minScore = score; | 202 minScore = score; |
204 } | 203 } |
205 } | 204 } |
206 return SkRef(closest); | 205 return SkRef(closest); |
207 } | 206 } |
208 | 207 |
| 208 SkString getFamilyName() { return fFamilyName; } |
| 209 |
209 private: | 210 private: |
210 SkTArray<SkAutoTUnref<SkTypeface_Custom>, true> fStyles; | 211 SkTArray<SkAutoTUnref<SkTypeface_Custom>, true> fStyles; |
211 SkString fFamilyName; | 212 SkString fFamilyName; |
212 | 213 |
213 void appendTypeface(SkTypeface_Custom* typeface) { | |
214 fStyles.push_back().reset(typeface); | |
215 } | |
216 | |
217 friend class SkFontMgr_Custom; | 214 friend class SkFontMgr_Custom; |
218 }; | 215 }; |
219 | 216 |
220 /** | 217 /** |
221 * SkFontMgr_Custom | 218 * SkFontMgr_Custom |
222 * | 219 * |
223 * This class is essentially a collection of SkFontStyleSet_Custom, | 220 * This class is essentially a collection of SkFontStyleSet_Custom, |
224 * one SkFontStyleSet_Custom for each family. This class may be modified | 221 * one SkFontStyleSet_Custom for each family. This class may be modified |
225 * to load fonts from any source by changing the initialization. | 222 * to load fonts from any source by changing the initialization. |
226 */ | 223 */ |
227 class SkFontMgr_Custom : public SkFontMgr { | 224 class SkFontMgr_Custom : public SkFontMgr { |
228 public: | 225 public: |
229 explicit SkFontMgr_Custom(const char* dir) { | 226 typedef SkTArray<SkAutoTUnref<SkFontStyleSet_Custom>, true> Families; |
230 this->load_system_fonts(dir); | 227 class SystemFontLoader { |
| 228 public: |
| 229 virtual ~SystemFontLoader() { } |
| 230 virtual void loadSystemFonts(const SkTypeface_FreeType::Scanner&, Famili
es*) const = 0; |
| 231 }; |
| 232 explicit SkFontMgr_Custom(const SystemFontLoader& loader) { |
| 233 loader.loadSystemFonts(fScanner, &fFamilies); |
| 234 |
| 235 // Try to pick a default font. |
| 236 static const char* defaultNames[] = { |
| 237 "Arial", "Verdana", "Times New Roman", "Droid Sans", NULL |
| 238 }; |
| 239 for (size_t i = 0; i < SK_ARRAY_COUNT(defaultNames); ++i) { |
| 240 SkFontStyleSet_Custom* set = this->onMatchFamily(defaultNames[i]); |
| 241 if (NULL == set) { |
| 242 continue; |
| 243 } |
| 244 |
| 245 SkTypeface* tf = set->matchStyle(SkFontStyle(SkFontStyle::kNormal_We
ight, |
| 246 SkFontStyle::kNormal_Wi
dth, |
| 247 SkFontStyle::kUpright_S
lant)); |
| 248 if (NULL == tf) { |
| 249 continue; |
| 250 } |
| 251 |
| 252 fDefaultFamily = set; |
| 253 break; |
| 254 } |
| 255 if (NULL == fDefaultFamily) { |
| 256 fDefaultFamily = fFamilies[0]; |
| 257 } |
231 } | 258 } |
232 | 259 |
233 protected: | 260 protected: |
234 int onCountFamilies() const override { | 261 int onCountFamilies() const override { |
235 return fFamilies.count(); | 262 return fFamilies.count(); |
236 } | 263 } |
237 | 264 |
238 void onGetFamilyName(int index, SkString* familyName) const override { | 265 void onGetFamilyName(int index, SkString* familyName) const override { |
239 SkASSERT(index < fFamilies.count()); | 266 SkASSERT(index < fFamilies.count()); |
240 familyName->set(fFamilies[index]->fFamilyName); | 267 familyName->set(fFamilies[index]->getFamilyName()); |
241 } | 268 } |
242 | 269 |
243 SkFontStyleSet_Custom* onCreateStyleSet(int index) const override { | 270 SkFontStyleSet_Custom* onCreateStyleSet(int index) const override { |
244 SkASSERT(index < fFamilies.count()); | 271 SkASSERT(index < fFamilies.count()); |
245 return SkRef(fFamilies[index].get()); | 272 return SkRef(fFamilies[index].get()); |
246 } | 273 } |
247 | 274 |
248 SkFontStyleSet_Custom* onMatchFamily(const char familyName[]) const override
{ | 275 SkFontStyleSet_Custom* onMatchFamily(const char familyName[]) const override
{ |
249 for (int i = 0; i < fFamilies.count(); ++i) { | 276 for (int i = 0; i < fFamilies.count(); ++i) { |
250 if (fFamilies[i]->fFamilyName.equals(familyName)) { | 277 if (fFamilies[i]->getFamilyName().equals(familyName)) { |
251 return SkRef(fFamilies[i].get()); | 278 return SkRef(fFamilies[i].get()); |
252 } | 279 } |
253 } | 280 } |
254 return NULL; | 281 return NULL; |
255 } | 282 } |
256 | 283 |
257 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], | 284 SkTypeface* onMatchFamilyStyle(const char familyName[], |
258 const SkFontStyle& fontStyle) const o
verride | 285 const SkFontStyle& fontStyle) const override |
259 { | 286 { |
260 SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); | 287 SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); |
261 return sset->matchStyle(fontStyle); | 288 return sset->matchStyle(fontStyle); |
262 } | 289 } |
263 | 290 |
264 virtual SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], con
st SkFontStyle&, | 291 SkTypeface* onMatchFamilyStyleCharacter(const char familyName[], const SkFon
tStyle&, |
265 const char* bcp47[], int bcp
47Count, | 292 const char* bcp47[], int bcp47Count, |
266 SkUnichar character) const o
verride | 293 SkUnichar character) const override |
267 { | 294 { |
268 return NULL; | 295 return NULL; |
269 } | 296 } |
270 | 297 |
271 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, | 298 SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, |
272 const SkFontStyle& fontStyle) const ove
rride | 299 const SkFontStyle& fontStyle) const override |
273 { | 300 { |
274 for (int i = 0; i < fFamilies.count(); ++i) { | 301 for (int i = 0; i < fFamilies.count(); ++i) { |
275 for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) { | 302 for (int j = 0; j < fFamilies[i]->fStyles.count(); ++j) { |
276 if (fFamilies[i]->fStyles[j] == familyMember) { | 303 if (fFamilies[i]->fStyles[j] == familyMember) { |
277 return fFamilies[i]->matchStyle(fontStyle); | 304 return fFamilies[i]->matchStyle(fontStyle); |
278 } | 305 } |
279 } | 306 } |
280 } | 307 } |
281 return NULL; | 308 return NULL; |
282 } | 309 } |
(...skipping 17 matching lines...) Expand all Loading... |
300 } else { | 327 } else { |
301 return NULL; | 328 return NULL; |
302 } | 329 } |
303 } | 330 } |
304 | 331 |
305 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override
{ | 332 SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const override
{ |
306 SkAutoTDelete<SkStreamAsset> stream(SkStream::NewFromFile(path)); | 333 SkAutoTDelete<SkStreamAsset> stream(SkStream::NewFromFile(path)); |
307 return stream.get() ? this->createFromStream(stream.detach(), ttcIndex)
: NULL; | 334 return stream.get() ? this->createFromStream(stream.detach(), ttcIndex)
: NULL; |
308 } | 335 } |
309 | 336 |
310 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[], | 337 SkTypeface* onLegacyCreateTypeface(const char familyName[], unsigned styleBi
ts) const override { |
311 unsigned styleBits) const overrid
e | |
312 { | |
313 SkTypeface::Style oldStyle = (SkTypeface::Style)styleBits; | 338 SkTypeface::Style oldStyle = (SkTypeface::Style)styleBits; |
314 SkFontStyle style = SkFontStyle(oldStyle & SkTypeface::kBold | 339 SkFontStyle style = SkFontStyle(oldStyle & SkTypeface::kBold |
315 ? SkFontStyle::kBold_Weight | 340 ? SkFontStyle::kBold_Weight |
316 : SkFontStyle::kNormal_Weight, | 341 : SkFontStyle::kNormal_Weight, |
317 SkFontStyle::kNormal_Width, | 342 SkFontStyle::kNormal_Width, |
318 oldStyle & SkTypeface::kItalic | 343 oldStyle & SkTypeface::kItalic |
319 ? SkFontStyle::kItalic_Slant | 344 ? SkFontStyle::kItalic_Slant |
320 : SkFontStyle::kUpright_Slant); | 345 : SkFontStyle::kUpright_Slant); |
321 SkTypeface* tf = NULL; | 346 SkTypeface* tf = NULL; |
322 | 347 |
323 if (familyName) { | 348 if (familyName) { |
324 tf = this->onMatchFamilyStyle(familyName, style); | 349 tf = this->onMatchFamilyStyle(familyName, style); |
325 } | 350 } |
326 | 351 |
327 if (NULL == tf) { | 352 if (NULL == tf) { |
328 tf = gDefaultFamily->matchStyle(style); | 353 tf = fDefaultFamily->matchStyle(style); |
329 } | 354 } |
330 | 355 |
331 return SkSafeRef(tf); | 356 return SkSafeRef(tf); |
332 } | 357 } |
333 | 358 |
334 private: | 359 private: |
| 360 Families fFamilies; |
| 361 SkFontStyleSet_Custom* fDefaultFamily; |
| 362 SkTypeface_FreeType::Scanner fScanner; |
| 363 }; |
335 | 364 |
336 void load_directory_fonts(const SkString& directory, const char* suffix) { | 365 /////////////////////////////////////////////////////////////////////////////// |
| 366 |
| 367 class DirectorySystemFontLoader : public SkFontMgr_Custom::SystemFontLoader { |
| 368 public: |
| 369 DirectorySystemFontLoader(const char* dir) : fBaseDirectory(dir) { } |
| 370 |
| 371 void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner, |
| 372 SkFontMgr_Custom::Families* families) const override |
| 373 { |
| 374 load_directory_fonts(scanner, fBaseDirectory, ".ttf", families); |
| 375 load_directory_fonts(scanner, fBaseDirectory, ".ttc", families); |
| 376 load_directory_fonts(scanner, fBaseDirectory, ".otf", families); |
| 377 load_directory_fonts(scanner, fBaseDirectory, ".pfb", families); |
| 378 |
| 379 if (families->empty()) { |
| 380 SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString()
); |
| 381 families->push_back().reset(family); |
| 382 family->appendTypeface(SkNEW(SkTypeface_Empty)); |
| 383 } |
| 384 } |
| 385 |
| 386 private: |
| 387 static SkFontStyleSet_Custom* find_family(SkFontMgr_Custom::Families& famili
es, |
| 388 const char familyName[]) |
| 389 { |
| 390 for (int i = 0; i < families.count(); ++i) { |
| 391 if (families[i]->getFamilyName().equals(familyName)) { |
| 392 return families[i].get(); |
| 393 } |
| 394 } |
| 395 return NULL; |
| 396 } |
| 397 |
| 398 static void load_directory_fonts(const SkTypeface_FreeType::Scanner& scanner
, |
| 399 const SkString& directory, const char* suff
ix, |
| 400 SkFontMgr_Custom::Families* families) |
| 401 { |
337 SkOSFile::Iter iter(directory.c_str(), suffix); | 402 SkOSFile::Iter iter(directory.c_str(), suffix); |
338 SkString name; | 403 SkString name; |
339 | 404 |
340 while (iter.next(&name, false)) { | 405 while (iter.next(&name, false)) { |
341 SkString filename(SkOSPath::Join(directory.c_str(), name.c_str())); | 406 SkString filename(SkOSPath::Join(directory.c_str(), name.c_str())); |
342 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(filename.c_str(
))); | 407 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(filename.c_str(
))); |
343 if (!stream.get()) { | 408 if (!stream.get()) { |
344 SkDebugf("---- failed to open <%s>\n", filename.c_str()); | 409 SkDebugf("---- failed to open <%s>\n", filename.c_str()); |
345 continue; | 410 continue; |
346 } | 411 } |
347 | 412 |
348 int numFaces; | 413 int numFaces; |
349 if (!fScanner.recognizedFont(stream, &numFaces)) { | 414 if (!scanner.recognizedFont(stream, &numFaces)) { |
350 SkDebugf("---- failed to open <%s> as a font\n", filename.c_str(
)); | 415 SkDebugf("---- failed to open <%s> as a font\n", filename.c_str(
)); |
351 continue; | 416 continue; |
352 } | 417 } |
353 | 418 |
354 for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) { | 419 for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) { |
355 bool isFixedPitch; | 420 bool isFixedPitch; |
356 SkString realname; | 421 SkString realname; |
357 SkFontStyle style = SkFontStyle(); // avoid uninitialized warnin
g | 422 SkFontStyle style = SkFontStyle(); // avoid uninitialized warnin
g |
358 if (!fScanner.scanFont(stream, faceIndex, &realname, &style, &is
FixedPitch)) { | 423 if (!scanner.scanFont(stream, faceIndex, &realname, &style, &isF
ixedPitch)) { |
359 SkDebugf("---- failed to open <%s> <%d> as a font\n", | 424 SkDebugf("---- failed to open <%s> <%d> as a font\n", |
360 filename.c_str(), faceIndex); | 425 filename.c_str(), faceIndex); |
361 continue; | 426 continue; |
362 } | 427 } |
363 | 428 |
364 SkTypeface_Custom* tf = SkNEW_ARGS(SkTypeface_File, ( | 429 SkTypeface_Custom* tf = SkNEW_ARGS(SkTypeface_File, ( |
365 style, | 430 style, |
366 isFixedPitch, | 431 isFixedPitch, |
367 true, // system-font (canno
t delete) | 432 true, // system-font (canno
t delete) |
368 realname, | 433 realname, |
369 filename.c_str(), 0)); | 434 filename.c_str(), |
| 435 faceIndex)); |
370 | 436 |
371 SkFontStyleSet_Custom* addTo = this->onMatchFamily(realname.c_st
r()); | 437 SkFontStyleSet_Custom* addTo = find_family(*families, realname.c
_str()); |
372 if (NULL == addTo) { | 438 if (NULL == addTo) { |
373 addTo = new SkFontStyleSet_Custom(realname); | 439 addTo = new SkFontStyleSet_Custom(realname); |
374 fFamilies.push_back().reset(addTo); | 440 families->push_back().reset(addTo); |
375 } | 441 } |
376 addTo->appendTypeface(tf); | 442 addTo->appendTypeface(tf); |
377 } | 443 } |
378 } | 444 } |
379 | 445 |
380 SkOSFile::Iter dirIter(directory.c_str()); | 446 SkOSFile::Iter dirIter(directory.c_str()); |
381 while (dirIter.next(&name, true)) { | 447 while (dirIter.next(&name, true)) { |
382 if (name.startsWith(".")) { | 448 if (name.startsWith(".")) { |
383 continue; | 449 continue; |
384 } | 450 } |
385 SkString dirname(SkOSPath::Join(directory.c_str(), name.c_str())); | 451 SkString dirname(SkOSPath::Join(directory.c_str(), name.c_str())); |
386 load_directory_fonts(dirname, suffix); | 452 load_directory_fonts(scanner, dirname, suffix, families); |
387 } | 453 } |
388 } | 454 } |
389 | 455 |
390 void load_system_fonts(const char* dir) { | 456 SkString fBaseDirectory; |
391 SkString baseDirectory(dir); | 457 }; |
392 load_directory_fonts(baseDirectory, ".ttf"); | |
393 load_directory_fonts(baseDirectory, ".ttc"); | |
394 load_directory_fonts(baseDirectory, ".otf"); | |
395 load_directory_fonts(baseDirectory, ".pfb"); | |
396 | 458 |
397 if (fFamilies.empty()) { | 459 struct SkEmbeddedResource { const uint8_t* data; size_t size; }; |
398 SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString()
); | 460 struct SkEmbeddedResourceHeader { const SkEmbeddedResource* entries; int count;
}; |
399 fFamilies.push_back().reset(family); | 461 |
400 family->appendTypeface(SkNEW(SkTypeface_Empty)); | 462 class EmbeddedSystemFontLoader : public SkFontMgr_Custom::SystemFontLoader { |
| 463 public: |
| 464 EmbeddedSystemFontLoader(const SkEmbeddedResourceHeader* header) : fHeader(h
eader) { } |
| 465 |
| 466 void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner, |
| 467 SkFontMgr_Custom::Families* families) const override |
| 468 { |
| 469 for (int i = 0; i < fHeader->count; ++i) { |
| 470 const SkEmbeddedResource& fontEntry = fHeader->entries[i]; |
| 471 load_embedded_font(scanner, fontEntry.data, fontEntry.size, i, famil
ies); |
401 } | 472 } |
402 | 473 |
403 // Try to pick a default font. | 474 if (families->empty()) { |
404 static const char* gDefaultNames[] = { | 475 SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString()
); |
405 "Arial", "Verdana", "Times New Roman", "Droid Sans", NULL | 476 families->push_back().reset(family); |
406 }; | 477 family->appendTypeface(SkNEW(SkTypeface_Empty)); |
407 for (size_t i = 0; i < SK_ARRAY_COUNT(gDefaultNames); ++i) { | |
408 SkFontStyleSet_Custom* set = this->onMatchFamily(gDefaultNames[i]); | |
409 if (NULL == set) { | |
410 continue; | |
411 } | |
412 | |
413 SkTypeface* tf = set->matchStyle(SkFontStyle(SkFontStyle::kNormal_We
ight, | |
414 SkFontStyle::kNormal_Wi
dth, | |
415 SkFontStyle::kUpright_S
lant)); | |
416 if (NULL == tf) { | |
417 continue; | |
418 } | |
419 | |
420 gDefaultFamily = set; | |
421 gDefaultNormal = tf; | |
422 break; | |
423 } | |
424 if (NULL == gDefaultNormal) { | |
425 gDefaultFamily = fFamilies[0]; | |
426 gDefaultNormal = gDefaultFamily->fStyles[0]; | |
427 } | 478 } |
428 } | 479 } |
429 | 480 |
430 SkTArray<SkAutoTUnref<SkFontStyleSet_Custom>, true> fFamilies; | 481 private: |
431 SkFontStyleSet_Custom* gDefaultFamily; | 482 static SkFontStyleSet_Custom* find_family(SkFontMgr_Custom::Families& famili
es, |
432 SkTypeface* gDefaultNormal; | 483 const char familyName[]) |
433 SkTypeface_FreeType::Scanner fScanner; | 484 { |
| 485 for (int i = 0; i < families.count(); ++i) { |
| 486 if (families[i]->getFamilyName().equals(familyName)) { |
| 487 return families[i].get(); |
| 488 } |
| 489 } |
| 490 return NULL; |
| 491 } |
| 492 |
| 493 static void load_embedded_font(const SkTypeface_FreeType::Scanner& scanner, |
| 494 const uint8_t* data, size_t size, int index, |
| 495 SkFontMgr_Custom::Families* families) |
| 496 { |
| 497 SkAutoTDelete<SkMemoryStream> stream(new SkMemoryStream(data, size, fals
e)); |
| 498 |
| 499 int numFaces; |
| 500 if (!scanner.recognizedFont(stream, &numFaces)) { |
| 501 SkDebugf("---- failed to open <%d> as a font\n", index); |
| 502 return; |
| 503 } |
| 504 |
| 505 for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) { |
| 506 bool isFixedPitch; |
| 507 SkString realname; |
| 508 SkFontStyle style = SkFontStyle(); // avoid uninitialized warning |
| 509 if (!scanner.scanFont(stream, faceIndex, &realname, &style, &isFixed
Pitch)) { |
| 510 SkDebugf("---- failed to open <%d> <%d> as a font\n", index, fac
eIndex); |
| 511 return; |
| 512 } |
| 513 |
| 514 SkTypeface_Custom* tf = SkNEW_ARGS(SkTypeface_Stream, ( |
| 515 style, |
| 516 isFixedPitch, |
| 517 true, // system-font (cannot de
lete) |
| 518 realname, |
| 519 stream.detach(), |
| 520 faceIndex)); |
| 521 |
| 522 SkFontStyleSet_Custom* addTo = find_family(*families, realname.c_str
()); |
| 523 if (NULL == addTo) { |
| 524 addTo = new SkFontStyleSet_Custom(realname); |
| 525 families->push_back().reset(addTo); |
| 526 } |
| 527 addTo->appendTypeface(tf); |
| 528 } |
| 529 } |
| 530 |
| 531 const SkEmbeddedResourceHeader* fHeader; |
434 }; | 532 }; |
435 | 533 |
| 534 #ifdef SK_EMBEDDED_FONTS |
| 535 |
| 536 extern "C" const SkEmbeddedResourceHeader SK_EMBEDDED_FONTS; |
436 SkFontMgr* SkFontMgr::Factory() { | 537 SkFontMgr* SkFontMgr::Factory() { |
437 return new SkFontMgr_Custom(SK_FONT_FILE_PREFIX); | 538 return new SkFontMgr_Custom(EmbeddedSystemFontLoader(&SK_EMBEDDED_FONTS)); |
438 } | 539 } |
| 540 |
| 541 #else |
| 542 |
| 543 #ifndef SK_FONT_FILE_PREFIX |
| 544 # define SK_FONT_FILE_PREFIX "/usr/share/fonts/" |
| 545 #endif |
| 546 SkFontMgr* SkFontMgr::Factory() { |
| 547 return new SkFontMgr_Custom(DirectorySystemFontLoader(SK_FONT_FILE_PREFIX)); |
| 548 } |
| 549 |
| 550 #endif |
OLD | NEW |