| 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 |