SkFontMgr_custom_embedded.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*
  2. * Copyright 2017 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/core/SkStream.h"
  8. #include "src/core/SkFontDescriptor.h"
  9. #include "src/core/SkMakeUnique.h"
  10. #include "src/ports/SkFontMgr_custom.h"
  11. struct SkEmbeddedResource { const uint8_t* data; size_t size; };
  12. struct SkEmbeddedResourceHeader { const SkEmbeddedResource* entries; int count; };
  13. class EmbeddedSystemFontLoader : public SkFontMgr_Custom::SystemFontLoader {
  14. public:
  15. EmbeddedSystemFontLoader(const SkEmbeddedResourceHeader* header) : fHeader(header) { }
  16. void loadSystemFonts(const SkTypeface_FreeType::Scanner& scanner,
  17. SkFontMgr_Custom::Families* families) const override
  18. {
  19. for (int i = 0; i < fHeader->count; ++i) {
  20. const SkEmbeddedResource& fontEntry = fHeader->entries[i];
  21. load_embedded_font(scanner, fontEntry.data, fontEntry.size, i, families);
  22. }
  23. if (families->empty()) {
  24. SkFontStyleSet_Custom* family = new SkFontStyleSet_Custom(SkString());
  25. families->push_back().reset(family);
  26. family->appendTypeface(sk_make_sp<SkTypeface_Empty>());
  27. }
  28. }
  29. private:
  30. static SkFontStyleSet_Custom* find_family(SkFontMgr_Custom::Families& families,
  31. const char familyName[])
  32. {
  33. for (int i = 0; i < families.count(); ++i) {
  34. if (families[i]->getFamilyName().equals(familyName)) {
  35. return families[i].get();
  36. }
  37. }
  38. return nullptr;
  39. }
  40. static void load_embedded_font(const SkTypeface_FreeType::Scanner& scanner,
  41. const uint8_t* data, size_t size, int index,
  42. SkFontMgr_Custom::Families* families)
  43. {
  44. auto stream = skstd::make_unique<SkMemoryStream>(data, size, false);
  45. int numFaces;
  46. if (!scanner.recognizedFont(stream.get(), &numFaces)) {
  47. SkDebugf("---- failed to open <%d> as a font\n", index);
  48. return;
  49. }
  50. for (int faceIndex = 0; faceIndex < numFaces; ++faceIndex) {
  51. bool isFixedPitch;
  52. SkString realname;
  53. SkFontStyle style = SkFontStyle(); // avoid uninitialized warning
  54. if (!scanner.scanFont(stream.get(), faceIndex,
  55. &realname, &style, &isFixedPitch, nullptr))
  56. {
  57. SkDebugf("---- failed to open <%d> <%d> as a font\n", index, faceIndex);
  58. return;
  59. }
  60. SkFontStyleSet_Custom* addTo = find_family(*families, realname.c_str());
  61. if (nullptr == addTo) {
  62. addTo = new SkFontStyleSet_Custom(realname);
  63. families->push_back().reset(addTo);
  64. }
  65. auto data = skstd::make_unique<SkFontData>(std::move(stream), faceIndex, nullptr, 0);
  66. addTo->appendTypeface(sk_make_sp<SkTypeface_Stream>(std::move(data),
  67. style, isFixedPitch,
  68. true, realname));
  69. }
  70. }
  71. const SkEmbeddedResourceHeader* fHeader;
  72. };
  73. sk_sp<SkFontMgr> SkFontMgr_New_Custom_Embedded(const SkEmbeddedResourceHeader* header) {
  74. return sk_make_sp<SkFontMgr_Custom>(EmbeddedSystemFontLoader(header));
  75. }