blob: 41c5217b9bfff085989a0bf0eac2d67791e1b48b [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;
joshualitt6c2c2b02015-07-24 10:37:00 -070025class SkGlyph;
joshualitt1d89e8d2015-04-01 12:40:54 -070026
27/*
28 * This class implements GrTextContext using standard bitmap fonts, and can also process textblobs.
29 * TODO replace GrBitmapTextContext
30 */
joshualittdbd35932015-04-02 09:19:04 -070031class GrAtlasTextContext : public GrTextContext {
joshualitt1d89e8d2015-04-01 12:40:54 -070032public:
robertphillipsfcf78292015-06-19 11:49:52 -070033 static GrAtlasTextContext* Create(GrContext*, GrDrawContext*, const SkSurfaceProps&);
joshualitt1d89e8d2015-04-01 12:40:54 -070034
joshualitt1d89e8d2015-04-01 12:40:54 -070035private:
robertphillipsfcf78292015-06-19 11:49:52 -070036 GrAtlasTextContext(GrContext*, GrDrawContext*, const SkSurfaceProps&);
joshualitt9bd2daf2015-04-17 09:30:06 -070037 ~GrAtlasTextContext() override {}
joshualitt1d89e8d2015-04-01 12:40:54 -070038
39 bool canDraw(const GrRenderTarget*, const GrClip&, const GrPaint&,
40 const SkPaint&, const SkMatrix& viewMatrix) override;
41
robertphillips2334fb62015-06-17 05:43:33 -070042 void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
joshualitt1d89e8d2015-04-01 12:40:54 -070043 const SkMatrix& viewMatrix, const char text[], size_t byteLength,
44 SkScalar x, SkScalar y, const SkIRect& regionClipBounds) override;
robertphillips2334fb62015-06-17 05:43:33 -070045 void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&,
robertphillipsccb1b572015-05-27 11:02:55 -070046 const SkPaint&, const SkMatrix& viewMatrix,
joshualitt1d89e8d2015-04-01 12:40:54 -070047 const char text[], size_t byteLength,
48 const SkScalar pos[], int scalarsPerPosition,
49 const SkPoint& offset, const SkIRect& regionClipBounds) override;
robertphillips9c240a12015-05-28 07:45:59 -070050 void drawTextBlob(GrRenderTarget*, const GrClip&, const SkPaint&,
joshualitt1d89e8d2015-04-01 12:40:54 -070051 const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x, SkScalar y,
52 SkDrawFilter*, const SkIRect& clipBounds) override;
53
joshualitt374b2f72015-07-21 08:05:03 -070054 typedef GrAtlasTextBlob::Run Run;
joshualitt1d89e8d2015-04-01 12:40:54 -070055 typedef Run::SubRunInfo PerSubRunInfo;
56
joshualitt9bd2daf2015-04-17 09:30:06 -070057 inline bool canDrawAsDistanceFields(const SkPaint&, const SkMatrix& viewMatrix);
joshualitt374b2f72015-07-21 08:05:03 -070058 GrAtlasTextBlob* setupDFBlob(int glyphCount, const SkPaint& origPaint,
joshualitt9bd2daf2015-04-17 09:30:06 -070059 const SkMatrix& viewMatrix, SkGlyphCache** cache,
60 SkPaint* dfPaint, SkScalar* textRatio);
joshualitt6c2c2b02015-07-24 10:37:00 -070061 void bmpAppendGlyph(GrAtlasTextBlob*, int runIndex, const SkGlyph&, int left, int top,
joshualitt9bd2daf2015-04-17 09:30:06 -070062 GrColor color, GrFontScaler*, const SkIRect& clipRect);
joshualitt6c2c2b02015-07-24 10:37:00 -070063 bool dfAppendGlyph(GrAtlasTextBlob*, int runIndex, const SkGlyph&, SkScalar sx, SkScalar sy,
joshualitt9bd2daf2015-04-17 09:30:06 -070064 GrColor color, GrFontScaler*, const SkIRect& clipRect, SkScalar textRatio,
65 const SkMatrix& viewMatrix);
joshualitt6c2c2b02015-07-24 10:37:00 -070066 inline void appendGlyphPath(GrAtlasTextBlob*, GrGlyph*, GrFontScaler*, const SkGlyph&,
67 SkScalar x, SkScalar y);
joshualitt374b2f72015-07-21 08:05:03 -070068 inline void appendGlyphCommon(GrAtlasTextBlob*, Run*, Run::SubRunInfo*,
joshualitt9bd2daf2015-04-17 09:30:06 -070069 const SkRect& positions, GrColor color,
70 size_t vertexStride, bool useVertexColor,
joshualittae32c102015-04-21 09:37:57 -070071 GrGlyph*);
joshualitt9a27e632015-04-06 10:53:36 -070072
robertphillips2334fb62015-06-17 05:43:33 -070073 inline void flushRunAsPaths(GrRenderTarget*,
robertphillipsccb1b572015-05-27 11:02:55 -070074 const SkTextBlob::RunIterator&, const GrClip& clip,
75 const SkPaint&, SkDrawFilter*,
joshualitt9a27e632015-04-06 10:53:36 -070076 const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x,
77 SkScalar y);
bsalomon265697d2015-07-22 10:17:26 -070078 inline GrBatch* createBatch(GrAtlasTextBlob*, const PerSubRunInfo&,
79 int glyphCount, int run, int subRun,
80 GrColor, SkScalar transX, SkScalar transY,
81 const SkPaint&);
joshualitt374b2f72015-07-21 08:05:03 -070082 inline void flushRun(GrPipelineBuilder*, GrAtlasTextBlob*, int run, GrColor,
joshualitt9bd2daf2015-04-17 09:30:06 -070083 SkScalar transX, SkScalar transY, const SkPaint&);
joshualitt374b2f72015-07-21 08:05:03 -070084 inline void flushBigGlyphs(GrAtlasTextBlob* cacheBlob, GrRenderTarget*,
robertphillipsccb1b572015-05-27 11:02:55 -070085 const GrClip& clip, const SkPaint& skPaint,
joshualitt1107e902015-05-11 14:52:11 -070086 SkScalar transX, SkScalar transY, const SkIRect& clipBounds);
joshualitt9a27e632015-04-06 10:53:36 -070087
88 // We have to flush SkTextBlobs differently from drawText / drawPosText
joshualitt374b2f72015-07-21 08:05:03 -070089 void flush(const SkTextBlob*, GrAtlasTextBlob*, GrRenderTarget*,
robertphillipsccb1b572015-05-27 11:02:55 -070090 const SkPaint&, const GrPaint&, SkDrawFilter*, const GrClip&,
91 const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x, SkScalar y,
92 SkScalar transX, SkScalar transY);
joshualitt374b2f72015-07-21 08:05:03 -070093 void flush(GrAtlasTextBlob*, GrRenderTarget*, const SkPaint&,
joshualitt1107e902015-05-11 14:52:11 -070094 const GrPaint&, const GrClip&, const SkIRect& clipBounds);
joshualitt1d89e8d2015-04-01 12:40:54 -070095
joshualitt9bd2daf2015-04-17 09:30:06 -070096 // A helper for drawing BitmapText in a run of distance fields
joshualitt374b2f72015-07-21 08:05:03 -070097 inline void fallbackDrawPosText(GrAtlasTextBlob*, int runIndex,
joshualittfcfb9fc2015-04-21 07:35:10 -070098 GrRenderTarget*, const GrClip&,
joshualitt9bd2daf2015-04-17 09:30:06 -070099 const GrPaint&,
100 const SkPaint&, const SkMatrix& viewMatrix,
101 const SkTDArray<char>& fallbackTxt,
102 const SkTDArray<SkScalar>& fallbackPos,
103 int scalarsPerPosition,
104 const SkPoint& offset,
105 const SkIRect& clipRect);
106
joshualitt374b2f72015-07-21 08:05:03 -0700107 void internalDrawBMPText(GrAtlasTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
joshualitt9e36c1a2015-04-14 12:17:27 -0700108 GrColor color, const SkMatrix& viewMatrix,
joshualitt1d89e8d2015-04-01 12:40:54 -0700109 const char text[], size_t byteLength,
joshualitt9bd2daf2015-04-17 09:30:06 -0700110 SkScalar x, SkScalar y, const SkIRect& clipRect);
joshualitt374b2f72015-07-21 08:05:03 -0700111 void internalDrawBMPPosText(GrAtlasTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
joshualitt9bd2daf2015-04-17 09:30:06 -0700112 GrColor color, const SkMatrix& viewMatrix,
113 const char text[], size_t byteLength,
114 const SkScalar pos[], int scalarsPerPosition,
115 const SkPoint& offset, const SkIRect& clipRect);
116
joshualitt374b2f72015-07-21 08:05:03 -0700117 void internalDrawDFText(GrAtlasTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
joshualitt9bd2daf2015-04-17 09:30:06 -0700118 GrColor color, const SkMatrix& viewMatrix,
119 const char text[], size_t byteLength,
120 SkScalar x, SkScalar y, const SkIRect& clipRect,
121 SkScalar textRatio,
122 SkTDArray<char>* fallbackTxt,
123 SkTDArray<SkScalar>* fallbackPos,
124 SkPoint* offset, const SkPaint& origPaint);
joshualitt374b2f72015-07-21 08:05:03 -0700125 void internalDrawDFPosText(GrAtlasTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
joshualitt9bd2daf2015-04-17 09:30:06 -0700126 GrColor color, const SkMatrix& viewMatrix,
127 const char text[], size_t byteLength,
128 const SkScalar pos[], int scalarsPerPosition,
129 const SkPoint& offset, const SkIRect& clipRect,
130 SkScalar textRatio,
131 SkTDArray<char>* fallbackTxt,
132 SkTDArray<SkScalar>* fallbackPos);
joshualitt1d89e8d2015-04-01 12:40:54 -0700133
134 // sets up the descriptor on the blob and returns a detached cache. Client must attach
joshualitt9e36c1a2015-04-14 12:17:27 -0700135 inline static GrColor ComputeCanonicalColor(const SkPaint&, bool lcd);
joshualitt9bd2daf2015-04-17 09:30:06 -0700136 inline SkGlyphCache* setupCache(Run*, const SkPaint&, const SkMatrix* viewMatrix, bool noGamma);
joshualitt2a0e9f32015-04-13 06:12:21 -0700137 static inline bool MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTransY,
joshualitt374b2f72015-07-21 08:05:03 -0700138 const GrAtlasTextBlob&, const SkPaint&,
joshualitt53b5f442015-04-13 06:33:59 -0700139 const SkMaskFilter::BlurRec&,
joshualitt1d89e8d2015-04-01 12:40:54 -0700140 const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
joshualitt374b2f72015-07-21 08:05:03 -0700141 void regenerateTextBlob(GrAtlasTextBlob* bmp, const SkPaint& skPaint, GrColor,
joshualitt9e36c1a2015-04-14 12:17:27 -0700142 const SkMatrix& viewMatrix,
joshualitt1d89e8d2015-04-01 12:40:54 -0700143 const SkTextBlob* blob, SkScalar x, SkScalar y,
joshualittfcfb9fc2015-04-21 07:35:10 -0700144 SkDrawFilter* drawFilter, const SkIRect& clipRect, GrRenderTarget*,
145 const GrClip&, const GrPaint&);
joshualitt9e36c1a2015-04-14 12:17:27 -0700146 inline static bool HasLCD(const SkTextBlob*);
joshualitt374b2f72015-07-21 08:05:03 -0700147 inline void initDistanceFieldPaint(GrAtlasTextBlob*, SkPaint*, SkScalar* textRatio,
joshualitt64c99cc2015-04-21 09:43:03 -0700148 const SkMatrix&);
joshualitt9bd2daf2015-04-17 09:30:06 -0700149
joshualitt79dfb2b2015-05-11 08:58:08 -0700150 // Test methods
151 // TODO this is really ugly. It'd be much nicer if positioning could be moved to batch
joshualitt374b2f72015-07-21 08:05:03 -0700152 inline GrAtlasTextBlob* createDrawTextBlob(GrRenderTarget*, const GrClip&, const GrPaint&,
joshualitt79dfb2b2015-05-11 08:58:08 -0700153 const SkPaint&, const SkMatrix& viewMatrix,
154 const char text[], size_t byteLength,
155 SkScalar x, SkScalar y,
156 const SkIRect& regionClipBounds);
joshualitt374b2f72015-07-21 08:05:03 -0700157 inline GrAtlasTextBlob* createDrawPosTextBlob(GrRenderTarget*, const GrClip&, const GrPaint&,
joshualitt79dfb2b2015-05-11 08:58:08 -0700158 const SkPaint&, const SkMatrix& viewMatrix,
159 const char text[], size_t byteLength,
160 const SkScalar pos[], int scalarsPerPosition,
161 const SkPoint& offset,
162 const SkIRect& regionClipBounds);
163
joshualitt9bd2daf2015-04-17 09:30:06 -0700164 // Distance field text needs this table to compute a value for use in the fragment shader.
165 // Because the GrAtlasTextContext can go out of scope before the final flush, this needs to be
166 // refcnted and malloced
167 struct DistanceAdjustTable : public SkNVRefCnt<DistanceAdjustTable> {
robertphillips9fc82752015-06-19 04:46:45 -0700168 DistanceAdjustTable() { this->buildDistanceAdjustTable(); }
joshualitt9bd2daf2015-04-17 09:30:06 -0700169 ~DistanceAdjustTable() { SkDELETE_ARRAY(fTable); }
170
joshualitt9bd2daf2015-04-17 09:30:06 -0700171 const SkScalar& operator[] (int i) const {
172 return fTable[i];
173 }
174
robertphillips9fc82752015-06-19 04:46:45 -0700175 private:
176 void buildDistanceAdjustTable();
177
joshualitt9bd2daf2015-04-17 09:30:06 -0700178 SkScalar* fTable;
179 };
joshualitt1d89e8d2015-04-01 12:40:54 -0700180
joshualitt1d89e8d2015-04-01 12:40:54 -0700181 GrBatchTextStrike* fCurrStrike;
joshualittb7133be2015-04-08 09:08:31 -0700182 GrTextBlobCache* fCache;
joshualitt9bd2daf2015-04-17 09:30:06 -0700183 SkAutoTUnref<DistanceAdjustTable> fDistanceAdjustTable;
joshualitt1d89e8d2015-04-01 12:40:54 -0700184
joshualittb7133be2015-04-08 09:08:31 -0700185 friend class GrTextBlobCache;
bsalomon265697d2015-07-22 10:17:26 -0700186 friend class TextBatch;
joshualitt1d89e8d2015-04-01 12:40:54 -0700187
joshualitt79dfb2b2015-05-11 08:58:08 -0700188#ifdef GR_TEST_UTILS
joshualitt6c891102015-05-13 08:51:49 -0700189 BATCH_TEST_FRIEND(TextBlobBatch);
joshualitt79dfb2b2015-05-11 08:58:08 -0700190#endif
191
joshualitt1d89e8d2015-04-01 12:40:54 -0700192 typedef GrTextContext INHERITED;
193};
194
195#endif