blob: e89f98719c3404396c670d7d30042031397759fb [file] [log] [blame]
joshualitt1d89e8d2015-04-01 12:40:54 -07001/*
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 "GrTextContext.h"
12
joshualitt374b2f72015-07-21 08:05:03 -070013#include "GrAtlasTextBlob.h"
joshualitt1d89e8d2015-04-01 12:40:54 -070014#include "GrGeometryProcessor.h"
joshualitt9a27e632015-04-06 10:53:36 -070015#include "SkTextBlob.h"
joshualitt1d89e8d2015-04-01 12:40:54 -070016
joshualitt79dfb2b2015-05-11 08:58:08 -070017#ifdef GR_TEST_UTILS
18#include "GrBatchTest.h"
19#endif
20
robertphillipsea461502015-05-26 11:38:03 -070021class GrDrawContext;
robertphillips2334fb62015-06-17 05:43:33 -070022class GrDrawTarget;
joshualitt1d89e8d2015-04-01 12:40:54 -070023class GrPipelineBuilder;
joshualittb7133be2015-04-08 09:08:31 -070024class GrTextBlobCache;
joshualitt1d89e8d2015-04-01 12:40:54 -070025
26/*
27 * This class implements GrTextContext using standard bitmap fonts, and can also process textblobs.
28 * TODO replace GrBitmapTextContext
29 */
joshualittdbd35932015-04-02 09:19:04 -070030class GrAtlasTextContext : public GrTextContext {
joshualitt1d89e8d2015-04-01 12:40:54 -070031public:
robertphillipsfcf78292015-06-19 11:49:52 -070032 static GrAtlasTextContext* Create(GrContext*, GrDrawContext*, const SkSurfaceProps&);
joshualitt1d89e8d2015-04-01 12:40:54 -070033
joshualitt1d89e8d2015-04-01 12:40:54 -070034private:
robertphillipsfcf78292015-06-19 11:49:52 -070035 GrAtlasTextContext(GrContext*, GrDrawContext*, const SkSurfaceProps&);
joshualitt9bd2daf2015-04-17 09:30:06 -070036 ~GrAtlasTextContext() override {}
joshualitt1d89e8d2015-04-01 12:40:54 -070037
38 bool canDraw(const GrRenderTarget*, const GrClip&, const GrPaint&,
39 const SkPaint&, const SkMatrix& viewMatrix) override;
40
robertphillips2334fb62015-06-17 05:43:33 -070041 void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
joshualitt1d89e8d2015-04-01 12:40:54 -070042 const SkMatrix& viewMatrix, const char text[], size_t byteLength,
43 SkScalar x, SkScalar y, const SkIRect& regionClipBounds) override;
robertphillips2334fb62015-06-17 05:43:33 -070044 void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&,
robertphillipsccb1b572015-05-27 11:02:55 -070045 const SkPaint&, const SkMatrix& viewMatrix,
joshualitt1d89e8d2015-04-01 12:40:54 -070046 const char text[], size_t byteLength,
47 const SkScalar pos[], int scalarsPerPosition,
48 const SkPoint& offset, const SkIRect& regionClipBounds) override;
robertphillips9c240a12015-05-28 07:45:59 -070049 void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&,
joshualitt1d89e8d2015-04-01 12:40:54 -070050 const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x, SkScalar y,
51 SkDrawFilter*, const SkIRect& clipBounds) override;
52
joshualitt374b2f72015-07-21 08:05:03 -070053 typedef GrAtlasTextBlob::Run Run;
joshualitt1d89e8d2015-04-01 12:40:54 -070054 typedef Run::SubRunInfo PerSubRunInfo;
55
joshualitt9bd2daf2015-04-17 09:30:06 -070056 inline bool canDrawAsDistanceFields(const SkPaint&, const SkMatrix& viewMatrix);
joshualitt374b2f72015-07-21 08:05:03 -070057 GrAtlasTextBlob* setupDFBlob(int glyphCount, const SkPaint& origPaint,
joshualitt9bd2daf2015-04-17 09:30:06 -070058 const SkMatrix& viewMatrix, SkGlyphCache** cache,
59 SkPaint* dfPaint, SkScalar* textRatio);
joshualitt374b2f72015-07-21 08:05:03 -070060 void bmpAppendGlyph(GrAtlasTextBlob*, int runIndex, GrGlyph::PackedID, int left, int top,
joshualitt9bd2daf2015-04-17 09:30:06 -070061 GrColor color, GrFontScaler*, const SkIRect& clipRect);
joshualitt374b2f72015-07-21 08:05:03 -070062 bool dfAppendGlyph(GrAtlasTextBlob*, int runIndex, GrGlyph::PackedID, SkScalar sx, SkScalar sy,
joshualitt9bd2daf2015-04-17 09:30:06 -070063 GrColor color, GrFontScaler*, const SkIRect& clipRect, SkScalar textRatio,
64 const SkMatrix& viewMatrix);
joshualitt374b2f72015-07-21 08:05:03 -070065 inline void appendGlyphPath(GrAtlasTextBlob* blob, GrGlyph* glyph,
joshualitt19e4c022015-05-13 11:23:03 -070066 GrFontScaler* scaler, SkScalar x, SkScalar y);
joshualitt374b2f72015-07-21 08:05:03 -070067 inline void appendGlyphCommon(GrAtlasTextBlob*, Run*, Run::SubRunInfo*,
joshualitt9bd2daf2015-04-17 09:30:06 -070068 const SkRect& positions, GrColor color,
69 size_t vertexStride, bool useVertexColor,
joshualittae32c102015-04-21 09:37:57 -070070 GrGlyph*);
joshualitt9a27e632015-04-06 10:53:36 -070071
robertphillips2334fb62015-06-17 05:43:33 -070072 inline void flushRunAsPaths(GrRenderTarget*,
robertphillipsccb1b572015-05-27 11:02:55 -070073 const SkTextBlob::RunIterator&, const GrClip& clip,
74 const SkPaint&, SkDrawFilter*,
joshualitt9a27e632015-04-06 10:53:36 -070075 const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x,
76 SkScalar y);
bsalomon265697d2015-07-22 10:17:26 -070077 inline GrBatch* createBatch(GrAtlasTextBlob*, const PerSubRunInfo&,
78 int glyphCount, int run, int subRun,
79 GrColor, SkScalar transX, SkScalar transY,
80 const SkPaint&);
joshualitt374b2f72015-07-21 08:05:03 -070081 inline void flushRun(GrPipelineBuilder*, GrAtlasTextBlob*, int run, GrColor,
joshualitt9bd2daf2015-04-17 09:30:06 -070082 SkScalar transX, SkScalar transY, const SkPaint&);
joshualitt374b2f72015-07-21 08:05:03 -070083 inline void flushBigGlyphs(GrAtlasTextBlob* cacheBlob, GrRenderTarget*,
robertphillipsccb1b572015-05-27 11:02:55 -070084 const GrClip& clip, const SkPaint& skPaint,
joshualitt1107e902015-05-11 14:52:11 -070085 SkScalar transX, SkScalar transY, const SkIRect& clipBounds);
joshualitt9a27e632015-04-06 10:53:36 -070086
87 // We have to flush SkTextBlobs differently from drawText / drawPosText
joshualitt374b2f72015-07-21 08:05:03 -070088 void flush(const SkTextBlob*, GrAtlasTextBlob*, GrRenderTarget*,
robertphillipsccb1b572015-05-27 11:02:55 -070089 const SkPaint&, const GrPaint&, SkDrawFilter*, const GrClip&,
90 const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, SkScalar y,
91 SkScalar transX, SkScalar transY);
joshualitt374b2f72015-07-21 08:05:03 -070092 void flush(GrAtlasTextBlob*, GrRenderTarget*, const SkPaint&,
joshualitt1107e902015-05-11 14:52:11 -070093 const GrPaint&, const GrClip&, const SkIRect& clipBounds);
joshualitt1d89e8d2015-04-01 12:40:54 -070094
joshualitt9bd2daf2015-04-17 09:30:06 -070095 // A helper for drawing BitmapText in a run of distance fields
joshualitt374b2f72015-07-21 08:05:03 -070096 inline void fallbackDrawPosText(GrAtlasTextBlob*, int runIndex,
joshualittfcfb9fc2015-04-21 07:35:10 -070097 GrRenderTarget*, const GrClip&,
joshualitt9bd2daf2015-04-17 09:30:06 -070098 const GrPaint&,
99 const SkPaint&, const SkMatrix& viewMatrix,
100 const SkTDArray<char>& fallbackTxt,
101 const SkTDArray<SkScalar>& fallbackPos,
102 int scalarsPerPosition,
103 const SkPoint& offset,
104 const SkIRect& clipRect);
105
joshualitt374b2f72015-07-21 08:05:03 -0700106 void internalDrawBMPText(GrAtlasTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
joshualitt9e36c1a2015-04-14 12:17:27 -0700107 GrColor color, const SkMatrix& viewMatrix,
joshualitt1d89e8d2015-04-01 12:40:54 -0700108 const char text[], size_t byteLength,
joshualitt9bd2daf2015-04-17 09:30:06 -0700109 SkScalar x, SkScalar y, const SkIRect& clipRect);
joshualitt374b2f72015-07-21 08:05:03 -0700110 void internalDrawBMPPosText(GrAtlasTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
joshualitt9bd2daf2015-04-17 09:30:06 -0700111 GrColor color, const SkMatrix& viewMatrix,
112 const char text[], size_t byteLength,
113 const SkScalar pos[], int scalarsPerPosition,
114 const SkPoint& offset, const SkIRect& clipRect);
115
joshualitt374b2f72015-07-21 08:05:03 -0700116 void internalDrawDFText(GrAtlasTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
joshualitt9bd2daf2015-04-17 09:30:06 -0700117 GrColor color, const SkMatrix& viewMatrix,
118 const char text[], size_t byteLength,
119 SkScalar x, SkScalar y, const SkIRect& clipRect,
120 SkScalar textRatio,
121 SkTDArray<char>* fallbackTxt,
122 SkTDArray<SkScalar>* fallbackPos,
123 SkPoint* offset, const SkPaint& origPaint);
joshualitt374b2f72015-07-21 08:05:03 -0700124 void internalDrawDFPosText(GrAtlasTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
joshualitt9bd2daf2015-04-17 09:30:06 -0700125 GrColor color, const SkMatrix& viewMatrix,
126 const char text[], size_t byteLength,
127 const SkScalar pos[], int scalarsPerPosition,
128 const SkPoint& offset, const SkIRect& clipRect,
129 SkScalar textRatio,
130 SkTDArray<char>* fallbackTxt,
131 SkTDArray<SkScalar>* fallbackPos);
joshualitt1d89e8d2015-04-01 12:40:54 -0700132
133 // sets up the descriptor on the blob and returns a detached cache. Client must attach
joshualitt9e36c1a2015-04-14 12:17:27 -0700134 inline static GrColor ComputeCanonicalColor(const SkPaint&, bool lcd);
joshualitt9bd2daf2015-04-17 09:30:06 -0700135 inline SkGlyphCache* setupCache(Run*, const SkPaint&, const SkMatrix* viewMatrix, bool noGamma);
joshualitt2a0e9f32015-04-13 06:12:21 -0700136 static inline bool MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTransY,
joshualitt374b2f72015-07-21 08:05:03 -0700137 const GrAtlasTextBlob&, const SkPaint&,
joshualitt53b5f442015-04-13 06:33:59 -0700138 const SkMaskFilter::BlurRec&,
joshualitt1d89e8d2015-04-01 12:40:54 -0700139 const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
joshualitt374b2f72015-07-21 08:05:03 -0700140 void regenerateTextBlob(GrAtlasTextBlob* bmp, const SkPaint& skPaint, GrColor,
joshualitt9e36c1a2015-04-14 12:17:27 -0700141 const SkMatrix& viewMatrix,
joshualitt1d89e8d2015-04-01 12:40:54 -0700142 const SkTextBlob* blob, SkScalar x, SkScalar y,
joshualittfcfb9fc2015-04-21 07:35:10 -0700143 SkDrawFilter* drawFilter, const SkIRect& clipRect, GrRenderTarget*,
144 const GrClip&, const GrPaint&);
joshualitt9e36c1a2015-04-14 12:17:27 -0700145 inline static bool HasLCD(const SkTextBlob*);
joshualitt374b2f72015-07-21 08:05:03 -0700146 inline void initDistanceFieldPaint(GrAtlasTextBlob*, SkPaint*, SkScalar* textRatio,
joshualitt64c99cc2015-04-21 09:43:03 -0700147 const SkMatrix&);
joshualitt9bd2daf2015-04-17 09:30:06 -0700148
joshualitt79dfb2b2015-05-11 08:58:08 -0700149 // Test methods
150 // TODO this is really ugly. It'd be much nicer if positioning could be moved to batch
joshualitt374b2f72015-07-21 08:05:03 -0700151 inline GrAtlasTextBlob* createDrawTextBlob(GrRenderTarget*, const GrClip&, const GrPaint&,
joshualitt79dfb2b2015-05-11 08:58:08 -0700152 const SkPaint&, const SkMatrix& viewMatrix,
153 const char text[], size_t byteLength,
154 SkScalar x, SkScalar y,
155 const SkIRect& regionClipBounds);
joshualitt374b2f72015-07-21 08:05:03 -0700156 inline GrAtlasTextBlob* createDrawPosTextBlob(GrRenderTarget*, const GrClip&, const GrPaint&,
joshualitt79dfb2b2015-05-11 08:58:08 -0700157 const SkPaint&, const SkMatrix& viewMatrix,
158 const char text[], size_t byteLength,
159 const SkScalar pos[], int scalarsPerPosition,
160 const SkPoint& offset,
161 const SkIRect& regionClipBounds);
162
joshualitt9bd2daf2015-04-17 09:30:06 -0700163 // Distance field text needs this table to compute a value for use in the fragment shader.
164 // Because the GrAtlasTextContext can go out of scope before the final flush, this needs to be
165 // refcnted and malloced
166 struct DistanceAdjustTable : public SkNVRefCnt<DistanceAdjustTable> {
robertphillips9fc82752015-06-19 04:46:45 -0700167 DistanceAdjustTable() { this->buildDistanceAdjustTable(); }
joshualitt9bd2daf2015-04-17 09:30:06 -0700168 ~DistanceAdjustTable() { SkDELETE_ARRAY(fTable); }
169
joshualitt9bd2daf2015-04-17 09:30:06 -0700170 const SkScalar& operator[] (int i) const {
171 return fTable[i];
172 }
173
robertphillips9fc82752015-06-19 04:46:45 -0700174 private:
175 void buildDistanceAdjustTable();
176
joshualitt9bd2daf2015-04-17 09:30:06 -0700177 SkScalar* fTable;
178 };
joshualitt1d89e8d2015-04-01 12:40:54 -0700179
joshualitt1d89e8d2015-04-01 12:40:54 -0700180 GrBatchTextStrike* fCurrStrike;
joshualittb7133be2015-04-08 09:08:31 -0700181 GrTextBlobCache* fCache;
joshualitt9bd2daf2015-04-17 09:30:06 -0700182 SkAutoTUnref<DistanceAdjustTable> fDistanceAdjustTable;
joshualitt1d89e8d2015-04-01 12:40:54 -0700183
joshualittb7133be2015-04-08 09:08:31 -0700184 friend class GrTextBlobCache;
bsalomon265697d2015-07-22 10:17:26 -0700185 friend class TextBatch;
joshualitt1d89e8d2015-04-01 12:40:54 -0700186
joshualitt79dfb2b2015-05-11 08:58:08 -0700187#ifdef GR_TEST_UTILS
joshualitt6c891102015-05-13 08:51:49 -0700188 BATCH_TEST_FRIEND(TextBlobBatch);
joshualitt79dfb2b2015-05-11 08:58:08 -0700189#endif
190
joshualitt1d89e8d2015-04-01 12:40:54 -0700191 typedef GrTextContext INHERITED;
192};
193
194#endif