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