SkGlyphRun.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright 2018 The Android Open Source Project
  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. #ifndef SkGlyphRun_DEFINED
  8. #define SkGlyphRun_DEFINED
  9. #include <functional>
  10. #include <vector>
  11. #include "include/core/SkFont.h"
  12. #include "include/core/SkPaint.h"
  13. #include "include/core/SkPoint.h"
  14. #include "include/core/SkTypes.h"
  15. #include "include/private/SkTemplates.h"
  16. #include "src/core/SkSpan.h"
  17. class SkBaseDevice;
  18. class SkGlyph;
  19. class SkTextBlob;
  20. class SkTextBlobRunIterator;
  21. class SkGlyphRun {
  22. public:
  23. SkGlyphRun() = default;
  24. SkGlyphRun(const SkFont& font,
  25. SkSpan<const SkPoint> positions,
  26. SkSpan<const SkGlyphID> glyphIDs,
  27. SkSpan<const char> text,
  28. SkSpan<const uint32_t> clusters);
  29. SkGlyphRun(const SkGlyphRun& glyphRun, const SkFont& font);
  30. void filloutGlyphsAndPositions(SkGlyphID* glyphIDs, SkPoint* positions);
  31. size_t runSize() const { return fGlyphIDs.size(); }
  32. SkSpan<const SkPoint> positions() const { return fPositions; }
  33. SkSpan<const SkGlyphID> glyphsIDs() const { return fGlyphIDs; }
  34. const SkFont& font() const { return fFont; }
  35. SkSpan<const uint32_t> clusters() const { return fClusters; }
  36. SkSpan<const char> text() const { return fText; }
  37. private:
  38. // Positions of each glyph.
  39. const SkSpan<const SkPoint> fPositions;
  40. // This is temporary while converting from the old per glyph code to the bulk code.
  41. const SkSpan<const SkGlyphID> fGlyphIDs;
  42. // Original text from SkTextBlob if present. Will be empty of not present.
  43. const SkSpan<const char> fText;
  44. // Original clusters from SkTextBlob if present. Will be empty if not present.
  45. const SkSpan<const uint32_t> fClusters;
  46. // Paint for this run modified to have glyph encoding and left alignment.
  47. SkFont fFont;
  48. };
  49. class SkGlyphRunList {
  50. const SkPaint* fOriginalPaint{nullptr}; // This should be deleted soon.
  51. // The text blob is needed to hookup the call back that the SkTextBlob destructor calls. It
  52. // should be used for nothing else
  53. const SkTextBlob* fOriginalTextBlob{nullptr};
  54. SkPoint fOrigin = {0, 0};
  55. SkSpan<const SkGlyphRun> fGlyphRuns;
  56. public:
  57. SkGlyphRunList();
  58. // Blob maybe null.
  59. SkGlyphRunList(
  60. const SkPaint& paint,
  61. const SkTextBlob* blob,
  62. SkPoint origin,
  63. SkSpan<const SkGlyphRun> glyphRunList);
  64. SkGlyphRunList(const SkGlyphRun& glyphRun, const SkPaint& paint);
  65. uint64_t uniqueID() const;
  66. bool anyRunsLCD() const;
  67. bool anyRunsSubpixelPositioned() const;
  68. void temporaryShuntBlobNotifyAddedToCache(uint32_t cacheID) const;
  69. bool canCache() const { return fOriginalTextBlob != nullptr; }
  70. size_t runCount() const { return fGlyphRuns.size(); }
  71. size_t totalGlyphCount() const {
  72. size_t glyphCount = 0;
  73. for(const auto& run : fGlyphRuns) {
  74. glyphCount += run.runSize();
  75. }
  76. return glyphCount;
  77. }
  78. bool allFontsFinite() const;
  79. SkPoint origin() const { return fOrigin; }
  80. const SkPaint& paint() const { return *fOriginalPaint; }
  81. const SkTextBlob* blob() const { return fOriginalTextBlob; }
  82. auto begin() -> decltype(fGlyphRuns.begin()) { return fGlyphRuns.begin(); }
  83. auto end() -> decltype(fGlyphRuns.end()) { return fGlyphRuns.end(); }
  84. auto begin() const -> decltype(fGlyphRuns.cbegin()) { return fGlyphRuns.cbegin(); }
  85. auto end() const -> decltype(fGlyphRuns.cend()) { return fGlyphRuns.cend(); }
  86. auto size() const -> decltype(fGlyphRuns.size()) { return fGlyphRuns.size(); }
  87. auto empty() const -> decltype(fGlyphRuns.empty()) { return fGlyphRuns.empty(); }
  88. auto operator [] (size_t i) const -> decltype(fGlyphRuns[i]) { return fGlyphRuns[i]; }
  89. };
  90. class SkGlyphIDSet {
  91. public:
  92. SkSpan<const SkGlyphID> uniquifyGlyphIDs(
  93. uint32_t universeSize, SkSpan<const SkGlyphID> glyphIDs,
  94. SkGlyphID* uniqueGlyphIDs, uint16_t* denseindices);
  95. private:
  96. size_t fUniverseToUniqueSize{0};
  97. SkAutoTMalloc<uint16_t> fUniverseToUnique;
  98. };
  99. class SkGlyphRunBuilder {
  100. public:
  101. void drawTextUTF8(
  102. const SkPaint& paint, const SkFont&, const void* bytes, size_t byteLength, SkPoint origin);
  103. void drawGlyphsWithPositions(
  104. const SkPaint&, const SkFont&, SkSpan<const SkGlyphID> glyphIDs, const SkPoint* pos);
  105. void drawTextBlob(const SkPaint& paint, const SkTextBlob& blob, SkPoint origin, SkBaseDevice*);
  106. void textBlobToGlyphRunListIgnoringRSXForm(
  107. const SkPaint& paint, const SkTextBlob& blob, SkPoint origin);
  108. const SkGlyphRunList& useGlyphRunList();
  109. bool empty() const { return fGlyphRunListStorage.size() == 0; }
  110. private:
  111. void initialize(size_t totalRunSize);
  112. SkSpan<const SkGlyphID> textToGlyphIDs(
  113. const SkFont& font, const void* bytes, size_t byteLength, SkTextEncoding);
  114. void makeGlyphRun(
  115. const SkFont& font,
  116. SkSpan<const SkGlyphID> glyphIDs,
  117. SkSpan<const SkPoint> positions,
  118. SkSpan<const char> text,
  119. SkSpan<const uint32_t> clusters);
  120. void makeGlyphRunList(const SkPaint& paint, const SkTextBlob* blob, SkPoint origin);
  121. void simplifyDrawText(
  122. const SkFont& font, SkSpan<const SkGlyphID> glyphIDs,
  123. SkPoint origin, SkPoint* positions,
  124. SkSpan<const char> text = SkSpan<const char>{},
  125. SkSpan<const uint32_t> clusters = SkSpan<const uint32_t>{});
  126. void simplifyDrawPosTextH(
  127. const SkFont& font, SkSpan<const SkGlyphID> glyphIDs,
  128. const SkScalar* xpos, SkScalar constY, SkPoint* positions,
  129. SkSpan<const char> text = SkSpan<const char>{},
  130. SkSpan<const uint32_t> clusters = SkSpan<const uint32_t>{});
  131. void simplifyDrawPosText(
  132. const SkFont& font, SkSpan<const SkGlyphID> glyphIDs,
  133. const SkPoint* pos,
  134. SkSpan<const char> text = SkSpan<const char>{},
  135. SkSpan<const uint32_t> clusters = SkSpan<const uint32_t>{});
  136. void simplifyTextBlobIgnoringRSXForm(
  137. const SkPaint& paint,
  138. const SkTextBlobRunIterator& it,
  139. SkPoint* positions);
  140. size_t fMaxTotalRunSize{0};
  141. SkAutoTMalloc<SkPoint> fPositions;
  142. std::vector<SkGlyphRun> fGlyphRunListStorage;
  143. SkGlyphRunList fGlyphRunList;
  144. // Used as a temporary for preparing using utfN text. This implies that only one run of
  145. // glyph ids will ever be needed because blobs are already glyph based.
  146. std::vector<SkGlyphID> fScratchGlyphIDs;
  147. // Used for collecting the set of unique glyphs.
  148. SkGlyphIDSet fGlyphIDSet;
  149. SkAutoTMalloc<SkGlyphID> fUniqueGlyphIDs;
  150. SkAutoTMalloc<uint16_t> fUniqueGlyphIDIndices;
  151. };
  152. #endif // SkGlyphRun_DEFINED