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 #include "src/core/SkZip.h" 21 22 class SkBaseDevice; 23 class SkGlyph; 24 class SkTextBlob; 25 class SkTextBlobRunIterator; 26 27 class SkGlyphRun { 28 public: 29 SkGlyphRun() = default; 30 SkGlyphRun(const SkFont& font, 31 SkSpan<const SkPoint> positions, 32 SkSpan<const SkGlyphID> glyphIDs, 33 SkSpan<const char> text, 34 SkSpan<const uint32_t> clusters); 35 SkGlyphRun(const SkGlyphRun& glyphRun, const SkFont& font); 36 runSize()37 size_t runSize() const { return fSource.size(); } positions()38 SkSpan<const SkPoint> positions() const { return fSource.get<1>(); } glyphsIDs()39 SkSpan<const SkGlyphID> glyphsIDs() const { return fSource.get<0>(); } source()40 SkZip<const SkGlyphID, const SkPoint> source() const { return fSource; } 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 // GlyphIDs and positions. 47 const SkZip<const SkGlyphID, const SkPoint> fSource; 48 // Original text from SkTextBlob if present. Will be empty of not present. 49 const SkSpan<const char> fText; 50 // Original clusters from SkTextBlob if present. Will be empty if not present. 51 const SkSpan<const uint32_t> fClusters; 52 // Paint for this run modified to have glyph encoding and left alignment. 53 SkFont fFont; 54 }; 55 56 class SkGlyphRunList { 57 SkSpan<const SkGlyphRun> fGlyphRuns; 58 59 public: 60 SkGlyphRunList(); 61 // Blob maybe null. 62 SkGlyphRunList( 63 const SkPaint& paint, 64 const SkTextBlob* blob, 65 SkPoint origin, 66 SkSpan<const SkGlyphRun> glyphRunList); 67 68 SkGlyphRunList(const SkGlyphRun& glyphRun, const SkPaint& paint); 69 70 uint64_t uniqueID() const; 71 bool anyRunsLCD() const; 72 bool anyRunsSubpixelPositioned() const; 73 void temporaryShuntBlobNotifyAddedToCache(uint32_t cacheID) const; 74 canCache()75 bool canCache() const { return fOriginalTextBlob != nullptr; } runCount()76 size_t runCount() const { return fGlyphRuns.size(); } totalGlyphCount()77 size_t totalGlyphCount() const { 78 size_t glyphCount = 0; 79 for(const auto& run : fGlyphRuns) { 80 glyphCount += run.runSize(); 81 } 82 return glyphCount; 83 } 84 bool allFontsFinite() const; 85 origin()86 SkPoint origin() const { return fOrigin; } paint()87 const SkPaint& paint() const { return *fOriginalPaint; } blob()88 const SkTextBlob* blob() const { return fOriginalTextBlob; } 89 90 auto begin() -> decltype(fGlyphRuns.begin()) { return fGlyphRuns.begin(); } 91 auto end() -> decltype(fGlyphRuns.end()) { return fGlyphRuns.end(); } 92 auto begin() const -> decltype(fGlyphRuns.cbegin()) { return fGlyphRuns.cbegin(); } 93 auto end() const -> decltype(fGlyphRuns.cend()) { return fGlyphRuns.cend(); } 94 auto size() const -> decltype(fGlyphRuns.size()) { return fGlyphRuns.size(); } 95 auto empty() const -> decltype(fGlyphRuns.empty()) { return fGlyphRuns.empty(); } 96 auto operator [] (size_t i) const -> decltype(fGlyphRuns[i]) { return fGlyphRuns[i]; } 97 98 private: 99 const SkPaint* fOriginalPaint{nullptr}; // This should be deleted soon. 100 // The text blob is needed to hookup the call back that the SkTextBlob destructor calls. It 101 // should be used for nothing else 102 const SkTextBlob* fOriginalTextBlob{nullptr}; 103 SkPoint fOrigin = {0, 0}; 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.empty(); } 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 175 #endif // SkGlyphRun_DEFINED 176