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
21class GrDrawOp;
22class GrTextBlobCache;
23class SkGlyph;
24
25/*
26 * Renders text using some kind of an atlas, ie BitmapText or DistanceField text
27 */
28class GrAtlasTextContext {
29public:
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    bool canDraw(const GrAtlasGlyphCache* fontCache, const SkPaint&, const SkMatrix& viewMatrix,
48                 const SkSurfaceProps&, const GrShaderCaps&);
49
50    void drawText(GrContext*, GrTextUtils::Target*, const GrClip&, const SkPaint&,
51                  const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
52                  size_t byteLength, SkScalar x, SkScalar y, const SkIRect& regionClipBounds);
53    void drawPosText(GrContext*, GrTextUtils::Target*, const GrClip&, const SkPaint&,
54                     const SkMatrix& viewMatrix, const SkSurfaceProps&, const char text[],
55                     size_t byteLength, const SkScalar pos[], int scalarsPerPosition,
56                     const SkPoint& offset, const SkIRect& regionClipBounds);
57    void drawTextBlob(GrContext*, GrTextUtils::Target*, const GrClip&, const SkPaint&,
58                      const SkMatrix& viewMatrix, const SkSurfaceProps&, const SkTextBlob*,
59                      SkScalar x, SkScalar y, SkDrawFilter*, const SkIRect& clipBounds);
60
61private:
62    GrAtlasTextContext(const Options& options);
63
64    // sets up the descriptor on the blob and returns a detached cache.  Client must attach
65    static SkColor ComputeCanonicalColor(const SkPaint&, bool lcd);
66    // Determines if we need to use fake gamma (and contrast boost):
67    static SkScalerContextFlags ComputeScalerContextFlags(const GrColorSpaceInfo&);
68    void regenerateTextBlob(GrAtlasTextBlob* bmp,
69                            GrAtlasGlyphCache*,
70                            const GrShaderCaps&,
71                            const GrTextUtils::Paint&,
72                            SkScalerContextFlags scalerContextFlags,
73                            const SkMatrix& viewMatrix,
74                            const SkSurfaceProps&,
75                            const SkTextBlob* blob, SkScalar x, SkScalar y,
76                            SkDrawFilter* drawFilter) const;
77
78    static bool HasLCD(const SkTextBlob*);
79
80    sk_sp<GrAtlasTextBlob> makeDrawTextBlob(GrTextBlobCache*, GrAtlasGlyphCache*,
81                                            const GrShaderCaps&,
82                                            const GrTextUtils::Paint&,
83                                            SkScalerContextFlags scalerContextFlags,
84                                            const SkMatrix& viewMatrix,
85                                            const SkSurfaceProps&,
86                                            const char text[], size_t byteLength,
87                                            SkScalar x, SkScalar y) const;
88
89    sk_sp<GrAtlasTextBlob> makeDrawPosTextBlob(GrTextBlobCache*, GrAtlasGlyphCache*,
90                                               const GrShaderCaps&,
91                                               const GrTextUtils::Paint&,
92                                               SkScalerContextFlags scalerContextFlags,
93                                               const SkMatrix& viewMatrix,
94                                               const SkSurfaceProps&,
95                                               const char text[], size_t byteLength,
96                                               const SkScalar pos[],
97                                               int scalarsPerPosition,
98                                               const SkPoint& offset) const;
99
100    // Functions for appending BMP text to GrAtlasTextBlob
101    static void DrawBmpText(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
102                            const SkSurfaceProps&, const GrTextUtils::Paint& paint,
103                            SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix,
104                            const char text[], size_t byteLength, SkScalar x, SkScalar y);
105
106    static void DrawBmpPosText(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
107                               const SkSurfaceProps&, const GrTextUtils::Paint& paint,
108                               SkScalerContextFlags scalerContextFlags, const SkMatrix& viewMatrix,
109                               const char text[], size_t byteLength, const SkScalar pos[],
110                               int scalarsPerPosition, const SkPoint& offset,
111                               SkScalar textRatio);
112
113    // functions for appending distance field text
114    bool canDrawAsDistanceFields(const SkPaint& skPaint, const SkMatrix& viewMatrix,
115                                 const SkSurfaceProps& props, const GrShaderCaps& caps) const;
116
117    void drawDFText(GrAtlasTextBlob* blob, int runIndex, GrAtlasGlyphCache*, const SkSurfaceProps&,
118                    const GrTextUtils::Paint& paint, SkScalerContextFlags scalerContextFlags,
119                    const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x,
120                    SkScalar y) const;
121
122    void drawDFPosText(GrAtlasTextBlob* blob, int runIndex, GrAtlasGlyphCache*,
123                       const SkSurfaceProps&, const GrTextUtils::Paint& paint,
124                       SkScalerContextFlags scalerContextFlags,
125                       const SkMatrix& viewMatrix, const char text[],
126                       size_t byteLength, const SkScalar pos[], int scalarsPerPosition,
127                       const SkPoint& offset) const;
128
129    void initDistanceFieldPaint(GrAtlasTextBlob* blob,
130                                SkPaint* skPaint,
131                                SkScalar* textRatio,
132                                const SkMatrix& viewMatrix) const;
133
134    static void BmpAppendGlyph(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
135                               GrAtlasTextStrike**, const SkGlyph&, SkScalar sx, SkScalar sy,
136                               GrColor color, SkGlyphCache*, SkScalar textRatio);
137
138    static void DfAppendGlyph(GrAtlasTextBlob*, int runIndex, GrAtlasGlyphCache*,
139                              GrAtlasTextStrike**, const SkGlyph&, SkScalar sx, SkScalar sy,
140                              GrColor color, SkGlyphCache* cache, SkScalar textRatio);
141
142    const GrDistanceFieldAdjustTable* dfAdjustTable() const { return fDistanceAdjustTable.get(); }
143
144    sk_sp<const GrDistanceFieldAdjustTable> fDistanceAdjustTable;
145
146    SkScalar fMinDistanceFieldFontSize;
147    SkScalar fMaxDistanceFieldFontSize;
148    bool fDistanceFieldVerticesAlwaysHaveW;
149
150#if GR_TEST_UTILS
151    static const SkScalerContextFlags kTextBlobOpScalerContextFlags =
152            SkScalerContextFlags::kFakeGammaAndBoostContrast;
153    GR_DRAW_OP_TEST_FRIEND(GrAtlasTextOp);
154#endif
155};
156
157#endif
158