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 GrAtlasTextContext_DEFINED 9 #define GrAtlasTextContext_DEFINED 10 11 #include "GrAtlasTextBlob.h" 12 #include "GrDistanceFieldAdjustTable.h" 13 #include "GrGeometryProcessor.h" 14 #include "GrTextUtils.h" 15 #include "SkTextBlobRunIterator.h" 16 17 #if GR_TEST_UTILS 18 #include "GrDrawOpTest.h" 19 #endif 20 21 class GrDrawOp; 22 class GrTextBlobCache; 23 class SkGlyph; 24 25 /* 26 * Renders text using some kind of an atlas, ie BitmapText or DistanceField text 27 */ 28 class GrAtlasTextContext { 29 public: 30 struct Options { 31 /** 32 * Below this size (in device space) distance field text will not be used. Negative means 33 * use a default value. 34 */ 35 SkScalar fMinDistanceFieldFontSize = -1.f; 36 /** 37 * Above this size (in device space) distance field text will not be used and glyphs will 38 * be rendered from outline as individual paths. Negative means use a default value. 39 */ 40 SkScalar fMaxDistanceFieldFontSize = -1.f; 41 /** Forces all distance field vertices to use 3 components, not just when in perspective. */ 42 bool fDistanceFieldVerticesAlwaysHaveW = false; 43 }; 44 45 static std::unique_ptr<GrAtlasTextContext> Make(const Options& options); 46 47 void drawText(GrContext*, GrTextUtils::Target*, const GrClip&, const SkPaint&, 48 const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[], 49 size_t byteLength, SkScalar x, SkScalar y, const SkIRect& regionClipBounds); 50 void drawPosText(GrContext*, GrTextUtils::Target*, const GrClip&, const SkPaint&, 51 const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[], 52 size_t byteLength, const SkScalar pos[], int scalarsPerPosition, 53 const SkPoint& offset, const SkIRect& regionClipBounds); 54 void drawTextBlob(GrContext*, GrTextUtils::Target*, const GrClip&, const SkPaint&, 55 const SkMatrix& viewMatrix, const SkSurfaceProps&, const SkTextBlob*, 56 SkScalar x, SkScalar y, SkDrawFilter*, const SkIRect& clipBounds); 57 58 private: 59 GrAtlasTextContext(const Options& options); 60 61 class FallbackTextHelper { 62 public: FallbackTextHelper(const SkMatrix & viewMatrix,const SkPaint & pathPaint,const GrGlyphCache * glyphCache,SkScalar textRatio)63 FallbackTextHelper(const SkMatrix& viewMatrix, 64 const SkPaint& pathPaint, 65 const GrGlyphCache* glyphCache, 66 SkScalar textRatio) 67 : fViewMatrix(viewMatrix) 68 , fTextSize(pathPaint.getTextSize()) 69 , fMaxTextSize(glyphCache->getGlyphSizeLimit()) 70 , fTextRatio(textRatio) 71 , fScaledFallbackTextSize(fMaxTextSize) 72 , fUseScaledFallback(false) { 73 fMaxScale = viewMatrix.getMaxScale(); 74 } 75 76 void appendText(const SkGlyph& glyph, int count, const char* text, SkPoint glyphPos); 77 void drawText(GrAtlasTextBlob* blob, int runIndex, GrGlyphCache*, const SkSurfaceProps&, 78 const GrTextUtils::Paint&, SkScalerContextFlags); 79 80 private: 81 SkTDArray<char> fFallbackTxt; 82 SkTDArray<SkPoint> fFallbackPos; 83 84 const SkMatrix& fViewMatrix; 85 SkScalar fTextSize; 86 SkScalar fMaxTextSize; 87 SkScalar fTextRatio; 88 SkScalar fScaledFallbackTextSize; 89 SkScalar fMaxScale; 90 bool fUseScaledFallback; 91 }; 92 93 // sets up the descriptor on the blob and returns a detached cache. Client must attach 94 static SkColor ComputeCanonicalColor(const SkPaint&, bool lcd); 95 // Determines if we need to use fake gamma (and contrast boost): 96 static SkScalerContextFlags ComputeScalerContextFlags(const GrColorSpaceInfo&); 97 void regenerateTextBlob(GrAtlasTextBlob* bmp, 98 GrGlyphCache*, 99 const GrShaderCaps&, 100 const GrTextUtils::Paint&, 101 SkScalerContextFlags scalerContextFlags, 102 const SkMatrix& viewMatrix, 103 const SkSurfaceProps&, 104 const SkTextBlob* blob, SkScalar x, SkScalar y, 105 SkDrawFilter* drawFilter) const; 106 107 static bool HasLCD(const SkTextBlob*); 108 109 sk_sp<GrAtlasTextBlob> makeDrawTextBlob(GrTextBlobCache*, GrGlyphCache*, 110 const GrShaderCaps&, 111 const GrTextUtils::Paint&, 112 SkScalerContextFlags scalerContextFlags, 113 const SkMatrix& viewMatrix, 114 const SkSurfaceProps&, 115 const char text[], size_t byteLength, 116 SkScalar x, SkScalar y) const; 117 118 sk_sp<GrAtlasTextBlob> makeDrawPosTextBlob(GrTextBlobCache*, GrGlyphCache*, 119 const GrShaderCaps&, 120 const GrTextUtils::Paint&, 121 SkScalerContextFlags scalerContextFlags, 122 const SkMatrix& viewMatrix, 123 const SkSurfaceProps&, 124 const char text[], size_t byteLength, 125 const SkScalar pos[], 126 int scalarsPerPosition, 127 const SkPoint& offset) const; 128 129 // Functions for appending BMP text to GrAtlasTextBlob 130 static void DrawBmpText(GrAtlasTextBlob*, int runIndex, GrGlyphCache*, 131 const SkSurfaceProps&, const GrTextUtils::Paint& paint, 132 SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix, 133 const char text[], size_t byteLength, SkScalar x, SkScalar y); 134 135 static void DrawBmpPosText(GrAtlasTextBlob*, int runIndex, GrGlyphCache*, 136 const SkSurfaceProps&, const GrTextUtils::Paint& paint, 137 SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix, 138 const char text[], size_t byteLength, const SkScalar pos[], 139 int scalarsPerPosition, const SkPoint& offset); 140 141 static void DrawBmpTextAsPaths(GrAtlasTextBlob*, int runIndex, GrGlyphCache*, 142 const SkSurfaceProps&, const GrTextUtils::Paint& paint, 143 SkScalerContextFlags scalerContextFlags, 144 const SkMatrix& viewMatrix, const char text[], 145 size_t byteLength, SkScalar x, SkScalar y); 146 147 static void DrawBmpPosTextAsPaths(GrAtlasTextBlob*, int runIndex, GrGlyphCache*, 148 const SkSurfaceProps&, const GrTextUtils::Paint& paint, 149 SkScalerContextFlags scalerContextFlags, 150 const SkMatrix& viewMatrix, 151 const char text[], size_t byteLength, 152 const SkScalar pos[], int scalarsPerPosition, 153 const SkPoint& offset); 154 155 // functions for appending distance field text 156 bool canDrawAsDistanceFields(const SkPaint& skPaint, const SkMatrix& viewMatrix, 157 const SkSurfaceProps& props, const GrShaderCaps& caps) const; 158 159 void drawDFText(GrAtlasTextBlob* blob, int runIndex, GrGlyphCache*, const SkSurfaceProps&, 160 const GrTextUtils::Paint& paint, SkScalerContextFlags scalerContextFlags, 161 const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x, 162 SkScalar y) const; 163 164 void drawDFPosText(GrAtlasTextBlob* blob, int runIndex, GrGlyphCache*, 165 const SkSurfaceProps&, const GrTextUtils::Paint& paint, 166 SkScalerContextFlags scalerContextFlags, 167 const SkMatrix& viewMatrix, const char text[], 168 size_t byteLength, const SkScalar pos[], int scalarsPerPosition, 169 const SkPoint& offset) const; 170 171 void initDistanceFieldPaint(GrAtlasTextBlob* blob, 172 SkPaint* skPaint, 173 SkScalar* textRatio, 174 const SkMatrix& viewMatrix) const; 175 176 static void BmpAppendGlyph(GrAtlasTextBlob*, int runIndex, GrGlyphCache*, 177 sk_sp<GrTextStrike>*, const SkGlyph&, SkScalar sx, SkScalar sy, 178 GrColor color, SkGlyphCache*, SkScalar textRatio); 179 180 static void DfAppendGlyph(GrAtlasTextBlob*, int runIndex, GrGlyphCache*, 181 sk_sp<GrTextStrike>*, const SkGlyph&, SkScalar sx, SkScalar sy, 182 GrColor color, SkGlyphCache* cache, SkScalar textRatio); 183 dfAdjustTable()184 const GrDistanceFieldAdjustTable* dfAdjustTable() const { return fDistanceAdjustTable.get(); } 185 186 sk_sp<const GrDistanceFieldAdjustTable> fDistanceAdjustTable; 187 188 SkScalar fMinDistanceFieldFontSize; 189 SkScalar fMaxDistanceFieldFontSize; 190 bool fDistanceFieldVerticesAlwaysHaveW; 191 192 #if GR_TEST_UTILS 193 static const SkScalerContextFlags kTextBlobOpScalerContextFlags = 194 SkScalerContextFlags::kFakeGammaAndBoostContrast; 195 GR_DRAW_OP_TEST_FRIEND(GrAtlasTextOp); 196 #endif 197 }; 198 199 #endif 200