1 /* 2 * Copyright 2015 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 8 #ifndef sktext_gpu_TextBlob_DEFINED 9 #define sktext_gpu_TextBlob_DEFINED 10 11 #include "include/core/SkColor.h" 12 #include "include/core/SkMatrix.h" 13 #include "include/core/SkPaint.h" 14 #include "include/core/SkRefCnt.h" 15 #include "include/core/SkScalar.h" 16 #include "include/core/SkSurfaceProps.h" 17 #include "include/private/base/SkTo.h" 18 #include "src/base/SkTInternalLList.h" 19 #include "src/core/SkMaskFilterBase.h" 20 #include "src/text/gpu/SubRunAllocator.h" 21 #include "src/text/gpu/SubRunContainer.h" 22 23 #include <cstddef> 24 #include <cstdint> 25 #include <tuple> 26 27 class SkCanvas; 28 struct SkPoint; 29 struct SkStrikeDeviceInfo; 30 31 namespace sktext { 32 class GlyphRunList; 33 class StrikeForGPUCacheInterface; 34 } 35 36 namespace sktext::gpu { 37 class Slug; 38 39 // -- TextBlob ----------------------------------------------------------------------------------- 40 // A TextBlob contains a fully processed SkTextBlob, suitable for nearly immediate drawing 41 // on the GPU. These are initially created with valid positions and colors, but with invalid 42 // texture coordinates. 43 // 44 // A TextBlob contains a number of SubRuns that are created in the blob's arena. Each SubRun 45 // tracks its own glyph and position data. 46 // 47 // In these classes, I'm trying to follow the convention about matrices and origins. 48 // * drawMatrix and drawOrigin - describes transformations for the current draw command. 49 // * positionMatrix - is equal to drawMatrix * [drawOrigin-as-translation-matrix] 50 // * initial Matrix - describes the combined initial matrix and origin the TextBlob was created 51 // with. 52 // 53 // 54 class TextBlob final : public SkRefCnt { 55 public: 56 // Key is not used as part of a hash map, so the hash is never taken. It's only used in a 57 // list search using operator =(). 58 struct Key { 59 static std::tuple<bool, Key> Make(const GlyphRunList& glyphRunList, 60 const SkPaint& paint, 61 const SkMatrix& drawMatrix, 62 const SkStrikeDeviceInfo& strikeDevice); 63 uint32_t fUniqueID; 64 // Color may affect the gamma of the mask we generate, but in a fairly limited way. 65 // Each color is assigned to on of a fixed number of buckets based on its 66 // luminance. For each luminance bucket there is a "canonical color" that 67 // represents the bucket. This functionality is currently only supported for A8 68 SkColor fCanonicalColor; 69 SkScalar fFrameWidth; 70 SkScalar fMiterLimit; 71 SkPixelGeometry fPixelGeometry; 72 SkMaskFilterBase::BlurRec fBlurRec; 73 uint32_t fScalerContextFlags; 74 SkMatrix fPositionMatrix; 75 // Below here fields are of size 1 byte. 76 bool fHasSomeDirectSubRuns; 77 bool fHasBlur; 78 SkPaint::Style fStyle; 79 SkPaint::Join fJoin; 80 81 bool operator==(const Key& other) const; 82 }; 83 84 SK_DECLARE_INTERNAL_LLIST_INTERFACE(TextBlob); 85 86 // Make a TextBlob and its sub runs. 87 static sk_sp<TextBlob> Make(const sktext::GlyphRunList& glyphRunList, 88 const SkPaint& paint, 89 const SkMatrix& positionMatrix, 90 SkStrikeDeviceInfo strikeDeviceInfo, 91 StrikeForGPUCacheInterface* strikeCache); 92 93 TextBlob(SubRunAllocator&& alloc, 94 SubRunContainerOwner subRuns, 95 int totalMemorySize, 96 SkColor initialLuminance); 97 98 ~TextBlob() override; 99 100 // Change memory management to handle the data after TextBlob, but in the same allocation 101 // of memory. Only allow placement new. 102 void operator delete(void* p); 103 void* operator new(size_t); 104 void* operator new(size_t, void* p); 105 key()106 const Key& key() { return fKey; } 107 108 void addKey(const Key& key); 109 110 bool canReuse(const SkPaint& paint, const SkMatrix& positionMatrix) const; 111 112 const Key& key() const; size()113 size_t size() const { return SkTo<size_t>(fSize); } 114 115 void draw(SkCanvas*, 116 SkPoint drawOrigin, 117 const SkPaint& paint, 118 const AtlasDrawDelegate&); 119 120 private: 121 friend class TextBlobTools; 122 // The allocator must come first because it needs to be destroyed last. Other fields of this 123 // structure may have pointers into it. 124 SubRunAllocator fAlloc; 125 126 SubRunContainerOwner fSubRuns; 127 128 // Overall size of this struct plus vertices and glyphs at the end. 129 const int fSize; 130 131 const SkColor fInitialLuminance; 132 133 Key fKey; 134 }; 135 136 sk_sp<sktext::gpu::Slug> MakeSlug(const SkMatrix& drawMatrix, 137 const sktext::GlyphRunList& glyphRunList, 138 const SkPaint& paint, 139 SkStrikeDeviceInfo strikeDeviceInfo, 140 sktext::StrikeForGPUCacheInterface* strikeCache); 141 } // namespace sktext::gpu 142 #endif // sktext_gpu_TextBlob_DEFINED 143