TypefaceSkia.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/LsanSuppressions.h>
  7. #include <LibGfx/Font/FontDatabase.h>
  8. #include <LibGfx/Font/Typeface.h>
  9. #include <LibGfx/Font/TypefaceSkia.h>
  10. #include <core/SkData.h>
  11. #include <core/SkFontMgr.h>
  12. #include <core/SkRefCnt.h>
  13. #include <core/SkTypeface.h>
  14. #ifndef AK_OS_ANDROID
  15. # include <ports/SkFontMgr_fontconfig.h>
  16. #else
  17. # include <ports/SkFontMgr_android.h>
  18. #endif
  19. #ifdef AK_OS_MACOS
  20. # include <ports/SkFontMgr_mac_ct.h>
  21. #endif
  22. namespace Gfx {
  23. static sk_sp<SkFontMgr> s_font_manager;
  24. struct TypefaceSkia::Impl {
  25. sk_sp<SkTypeface> skia_typeface;
  26. };
  27. ErrorOr<NonnullRefPtr<TypefaceSkia>> TypefaceSkia::load_from_buffer(AK::ReadonlyBytes buffer, int ttc_index)
  28. {
  29. if (!s_font_manager) {
  30. #ifdef AK_OS_MACOS
  31. if (Gfx::FontDatabase::the().system_font_provider_name() != "FontConfig"sv) {
  32. s_font_manager = SkFontMgr_New_CoreText(nullptr);
  33. }
  34. #endif
  35. #ifndef AK_OS_ANDROID
  36. if (!s_font_manager) {
  37. s_font_manager = SkFontMgr_New_FontConfig(nullptr);
  38. }
  39. #else
  40. s_font_manager = SkFontMgr_New_Android(nullptr);
  41. #endif
  42. }
  43. auto data = SkData::MakeWithoutCopy(buffer.data(), buffer.size());
  44. auto skia_typeface = s_font_manager->makeFromData(data, ttc_index);
  45. if (!skia_typeface) {
  46. return Error::from_string_literal("Failed to load typeface from buffer");
  47. }
  48. return adopt_ref(*new TypefaceSkia { make<TypefaceSkia::Impl>(skia_typeface), buffer, ttc_index });
  49. }
  50. SkTypeface const* TypefaceSkia::sk_typeface() const
  51. {
  52. return impl().skia_typeface.get();
  53. }
  54. TypefaceSkia::TypefaceSkia(NonnullOwnPtr<Impl> impl, ReadonlyBytes buffer, int ttc_index)
  55. : m_impl(move(impl))
  56. , m_buffer(buffer)
  57. , m_ttc_index(ttc_index) {
  58. };
  59. u32 TypefaceSkia::glyph_count() const
  60. {
  61. return impl().skia_typeface->countGlyphs();
  62. }
  63. u16 TypefaceSkia::units_per_em() const
  64. {
  65. return impl().skia_typeface->getUnitsPerEm();
  66. }
  67. u32 TypefaceSkia::glyph_id_for_code_point(u32 code_point) const
  68. {
  69. return glyph_page(code_point / GlyphPage::glyphs_per_page).glyph_ids[code_point % GlyphPage::glyphs_per_page];
  70. }
  71. TypefaceSkia::GlyphPage const& TypefaceSkia::glyph_page(size_t page_index) const
  72. {
  73. if (page_index == 0) {
  74. if (!m_glyph_page_zero) {
  75. m_glyph_page_zero = make<GlyphPage>();
  76. populate_glyph_page(*m_glyph_page_zero, 0);
  77. }
  78. return *m_glyph_page_zero;
  79. }
  80. if (auto it = m_glyph_pages.find(page_index); it != m_glyph_pages.end()) {
  81. return *it->value;
  82. }
  83. auto glyph_page = make<GlyphPage>();
  84. populate_glyph_page(*glyph_page, page_index);
  85. auto const* glyph_page_ptr = glyph_page.ptr();
  86. m_glyph_pages.set(page_index, move(glyph_page));
  87. return *glyph_page_ptr;
  88. }
  89. void TypefaceSkia::populate_glyph_page(GlyphPage& glyph_page, size_t page_index) const
  90. {
  91. u32 first_code_point = page_index * GlyphPage::glyphs_per_page;
  92. for (size_t i = 0; i < GlyphPage::glyphs_per_page; ++i) {
  93. u32 code_point = first_code_point + i;
  94. glyph_page.glyph_ids[i] = impl().skia_typeface->unicharToGlyph(code_point);
  95. }
  96. }
  97. FlyString const& TypefaceSkia::family() const
  98. {
  99. if (!m_family.has_value()) {
  100. SkString family_name;
  101. impl().skia_typeface->getFamilyName(&family_name);
  102. m_family = FlyString::from_utf8_without_validation(ReadonlyBytes { family_name.c_str(), family_name.size() });
  103. }
  104. return m_family.value();
  105. }
  106. u16 TypefaceSkia::weight() const
  107. {
  108. return impl().skia_typeface->fontStyle().weight();
  109. }
  110. u16 TypefaceSkia::width() const
  111. {
  112. return impl().skia_typeface->fontStyle().width();
  113. }
  114. u8 TypefaceSkia::slope() const
  115. {
  116. auto slant = impl().skia_typeface->fontStyle().slant();
  117. switch (slant) {
  118. case SkFontStyle::kUpright_Slant:
  119. return 0;
  120. case SkFontStyle::kItalic_Slant:
  121. return 1;
  122. case SkFontStyle::kOblique_Slant:
  123. return 2;
  124. default:
  125. return 0;
  126. }
  127. }
  128. }