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