blob: 2d445f35d8d4a7ae413a14e19c133a57ff0e4a41 [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"
halcanary33779752015-10-27 14:01:05 -070015#include "SkTextBlobRunIterator.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
bsalomonabd30f52015-08-13 13:34:48 -070021class GrDrawBatch;
robertphillipsea461502015-05-26 11:38:03 -070022class GrDrawContext;
robertphillips2334fb62015-06-17 05:43:33 -070023class GrDrawTarget;
joshualitt1d89e8d2015-04-01 12:40:54 -070024class GrPipelineBuilder;
joshualittb7133be2015-04-08 09:08:31 -070025class GrTextBlobCache;
joshualitt6c2c2b02015-07-24 10:37:00 -070026class SkGlyph;
joshualitt1d89e8d2015-04-01 12:40:54 -070027
28/*
29 * This class implements GrTextContext using standard bitmap fonts, and can also process textblobs.
joshualitt1d89e8d2015-04-01 12:40:54 -070030 */
joshualittdbd35932015-04-02 09:19:04 -070031class GrAtlasTextContext : public GrTextContext {
joshualitt1d89e8d2015-04-01 12:40:54 -070032public:
robertphillipsf6703fa2015-09-01 05:36:47 -070033 static GrAtlasTextContext* Create(GrContext*, const SkSurfaceProps&);
joshualitt1d89e8d2015-04-01 12:40:54 -070034
joshualitt1d89e8d2015-04-01 12:40:54 -070035private:
robertphillipsf6703fa2015-09-01 05:36:47 -070036 GrAtlasTextContext(GrContext*, const SkSurfaceProps&);
joshualitt9bd2daf2015-04-17 09:30:06 -070037 ~GrAtlasTextContext() override {}
joshualitt1d89e8d2015-04-01 12:40:54 -070038
robertphillips6ee690e2015-12-02 08:57:50 -080039 bool canDraw(const SkPaint&, const SkMatrix& viewMatrix) override;
joshualitt1d89e8d2015-04-01 12:40:54 -070040
robertphillipsf6703fa2015-09-01 05:36:47 -070041 void onDrawText(GrDrawContext*, 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;
robertphillipsf6703fa2015-09-01 05:36:47 -070044 void onDrawPosText(GrDrawContext*, 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;
robertphillipsf6703fa2015-09-01 05:36:47 -070049 void drawTextBlob(GrDrawContext*, 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,
jvanverth157e6482015-09-09 08:05:12 -070058 const SkMatrix& viewMatrix, SkPaint* dfPaint,
59 SkScalar* textRatio);
joshualitt6c2c2b02015-07-24 10:37:00 -070060 void bmpAppendGlyph(GrAtlasTextBlob*, int runIndex, const SkGlyph&, int left, int top,
robertphillips6ee690e2015-12-02 08:57:50 -080061 GrColor color, GrFontScaler*);
joshualitt6c2c2b02015-07-24 10:37:00 -070062 bool dfAppendGlyph(GrAtlasTextBlob*, int runIndex, const SkGlyph&, SkScalar sx, SkScalar sy,
robertphillips6ee690e2015-12-02 08:57:50 -080063 GrColor color, GrFontScaler*, SkScalar textRatio,
joshualitt9bd2daf2015-04-17 09:30:06 -070064 const SkMatrix& viewMatrix);
joshualitt6c2c2b02015-07-24 10:37:00 -070065 inline void appendGlyphPath(GrAtlasTextBlob*, GrGlyph*, GrFontScaler*, const SkGlyph&,
joshualitt0fe04a22015-08-25 12:05:50 -070066 SkScalar x, SkScalar y, SkScalar scale = 1.0f,
67 bool applyVM = false);
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
robertphillips7bceedc2015-12-01 12:51:26 -080073 inline void flushRunAsPaths(GrDrawContext*,
halcanary33779752015-10-27 14:01:05 -070074 const SkTextBlobRunIterator&, const GrClip& clip,
robertphillipsccb1b572015-05-27 11:02:55 -070075 const SkPaint&, SkDrawFilter*,
joshualitt9a27e632015-04-06 10:53:36 -070076 const SkMatrix& viewMatrix, const SkIRect& clipBounds, SkScalar x,
77 SkScalar y);
bsalomonabd30f52015-08-13 13:34:48 -070078 inline GrDrawBatch* createBatch(GrAtlasTextBlob*, const PerSubRunInfo&,
79 int glyphCount, int run, int subRun,
80 GrColor, SkScalar transX, SkScalar transY,
81 const SkPaint&);
robertphillipsf6703fa2015-09-01 05:36:47 -070082 inline void flushRun(GrDrawContext*, GrPipelineBuilder*, GrAtlasTextBlob*, int run, GrColor,
joshualitt9bd2daf2015-04-17 09:30:06 -070083 SkScalar transX, SkScalar transY, const SkPaint&);
robertphillips7bceedc2015-12-01 12:51:26 -080084 inline void flushBigGlyphs(GrAtlasTextBlob* cacheBlob, GrDrawContext*,
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
robertphillipsf6703fa2015-09-01 05:36:47 -070089 void flush(const SkTextBlob*, GrAtlasTextBlob*, GrDrawContext*, 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);
robertphillipsf6703fa2015-09-01 05:36:47 -070093 void flush(GrAtlasTextBlob*, GrDrawContext*, 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,
robertphillips6ee690e2015-12-02 08:57:50 -080098 const GrClip&, GrColor color,
joshualitt9bd2daf2015-04-17 09:30:06 -070099 const SkPaint&, const SkMatrix& viewMatrix,
100 const SkTDArray<char>& fallbackTxt,
101 const SkTDArray<SkScalar>& fallbackPos,
102 int scalarsPerPosition,
robertphillips6ee690e2015-12-02 08:57:50 -0800103 const SkPoint& offset);
joshualitt9bd2daf2015-04-17 09:30:06 -0700104
joshualitt374b2f72015-07-21 08:05:03 -0700105 void internalDrawBMPText(GrAtlasTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
joshualitt9e36c1a2015-04-14 12:17:27 -0700106 GrColor color, const SkMatrix& viewMatrix,
joshualitt1d89e8d2015-04-01 12:40:54 -0700107 const char text[], size_t byteLength,
robertphillips6ee690e2015-12-02 08:57:50 -0800108 SkScalar x, SkScalar y);
joshualitt374b2f72015-07-21 08:05:03 -0700109 void internalDrawBMPPosText(GrAtlasTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
joshualitt9bd2daf2015-04-17 09:30:06 -0700110 GrColor color, const SkMatrix& viewMatrix,
111 const char text[], size_t byteLength,
112 const SkScalar pos[], int scalarsPerPosition,
robertphillips6ee690e2015-12-02 08:57:50 -0800113 const SkPoint& offset);
joshualitt9bd2daf2015-04-17 09:30:06 -0700114
jvanverth157e6482015-09-09 08:05:12 -0700115 void internalDrawDFText(GrAtlasTextBlob*, int runIndex, const SkPaint&,
joshualitt9bd2daf2015-04-17 09:30:06 -0700116 GrColor color, const SkMatrix& viewMatrix,
117 const char text[], size_t byteLength,
robertphillips6ee690e2015-12-02 08:57:50 -0800118 SkScalar x, SkScalar y,
joshualitt9bd2daf2015-04-17 09:30:06 -0700119 SkScalar textRatio,
120 SkTDArray<char>* fallbackTxt,
121 SkTDArray<SkScalar>* fallbackPos,
122 SkPoint* offset, const SkPaint& origPaint);
jvanverth157e6482015-09-09 08:05:12 -0700123 void internalDrawDFPosText(GrAtlasTextBlob*, int runIndex, const SkPaint&,
joshualitt9bd2daf2015-04-17 09:30:06 -0700124 GrColor color, const SkMatrix& viewMatrix,
125 const char text[], size_t byteLength,
126 const SkScalar pos[], int scalarsPerPosition,
robertphillips6ee690e2015-12-02 08:57:50 -0800127 const SkPoint& offset,
joshualitt9bd2daf2015-04-17 09:30:06 -0700128 SkScalar textRatio,
129 SkTDArray<char>* fallbackTxt,
130 SkTDArray<SkScalar>* fallbackPos);
joshualitt1d89e8d2015-04-01 12:40:54 -0700131
132 // sets up the descriptor on the blob and returns a detached cache. Client must attach
joshualitt9e36c1a2015-04-14 12:17:27 -0700133 inline static GrColor ComputeCanonicalColor(const SkPaint&, bool lcd);
joshualitt9bd2daf2015-04-17 09:30:06 -0700134 inline SkGlyphCache* setupCache(Run*, const SkPaint&, const SkMatrix* viewMatrix, bool noGamma);
joshualitt2a0e9f32015-04-13 06:12:21 -0700135 static inline bool MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTransY,
jvanverth0628a522015-08-18 07:44:22 -0700136 const GrAtlasTextBlob&, const SkPaint&, GrColor,
joshualitt53b5f442015-04-13 06:33:59 -0700137 const SkMaskFilter::BlurRec&,
joshualitt1d89e8d2015-04-01 12:40:54 -0700138 const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
joshualitt374b2f72015-07-21 08:05:03 -0700139 void regenerateTextBlob(GrAtlasTextBlob* bmp, const SkPaint& skPaint, GrColor,
joshualitt9e36c1a2015-04-14 12:17:27 -0700140 const SkMatrix& viewMatrix,
joshualitt1d89e8d2015-04-01 12:40:54 -0700141 const SkTextBlob* blob, SkScalar x, SkScalar y,
robertphillips6ee690e2015-12-02 08:57:50 -0800142 SkDrawFilter* drawFilter,
jvanverth0628a522015-08-18 07:44:22 -0700143 const GrClip&);
joshualitt9e36c1a2015-04-14 12:17:27 -0700144 inline static bool HasLCD(const SkTextBlob*);
joshualitt374b2f72015-07-21 08:05:03 -0700145 inline void initDistanceFieldPaint(GrAtlasTextBlob*, SkPaint*, SkScalar* textRatio,
joshualitt64c99cc2015-04-21 09:43:03 -0700146 const SkMatrix&);
joshualitt9bd2daf2015-04-17 09:30:06 -0700147
joshualitt79dfb2b2015-05-11 08:58:08 -0700148 // Test methods
149 // TODO this is really ugly. It'd be much nicer if positioning could be moved to batch
robertphillips6ee690e2015-12-02 08:57:50 -0800150 inline GrAtlasTextBlob* createDrawTextBlob(const GrClip&, const GrPaint&,
151 const SkPaint&, const SkMatrix& viewMatrix,
152 const char text[], size_t byteLength,
153 SkScalar x, SkScalar y,
154 const SkIRect& regionClipBounds);
155 inline GrAtlasTextBlob* createDrawPosTextBlob(const GrClip&, const GrPaint&,
156 const SkPaint&, const SkMatrix& viewMatrix,
157 const char text[], size_t byteLength,
158 const SkScalar pos[], int scalarsPerPosition,
159 const SkPoint& offset,
160 const SkIRect& regionClipBounds);
joshualitt79dfb2b2015-05-11 08:58:08 -0700161
joshualitt9bd2daf2015-04-17 09:30:06 -0700162 // Distance field text needs this table to compute a value for use in the fragment shader.
163 // Because the GrAtlasTextContext can go out of scope before the final flush, this needs to be
164 // refcnted and malloced
165 struct DistanceAdjustTable : public SkNVRefCnt<DistanceAdjustTable> {
robertphillips9fc82752015-06-19 04:46:45 -0700166 DistanceAdjustTable() { this->buildDistanceAdjustTable(); }
halcanary385fe4d2015-08-26 13:07:48 -0700167 ~DistanceAdjustTable() { delete[] fTable; }
joshualitt9bd2daf2015-04-17 09:30:06 -0700168
joshualitt9bd2daf2015-04-17 09:30:06 -0700169 const SkScalar& operator[] (int i) const {
170 return fTable[i];
171 }
172
robertphillips9fc82752015-06-19 04:46:45 -0700173 private:
174 void buildDistanceAdjustTable();
175
joshualitt9bd2daf2015-04-17 09:30:06 -0700176 SkScalar* fTable;
177 };
joshualitt1d89e8d2015-04-01 12:40:54 -0700178
joshualitt1d89e8d2015-04-01 12:40:54 -0700179 GrBatchTextStrike* fCurrStrike;
joshualittb7133be2015-04-08 09:08:31 -0700180 GrTextBlobCache* fCache;
robertphillipsf6703fa2015-09-01 05:36:47 -0700181 SkAutoTUnref<const DistanceAdjustTable> fDistanceAdjustTable;
joshualitt1d89e8d2015-04-01 12:40:54 -0700182
joshualittb7133be2015-04-08 09:08:31 -0700183 friend class GrTextBlobCache;
joshualitta751c972015-11-20 13:37:32 -0800184 friend class GrAtlasTextBatch;
joshualitt1d89e8d2015-04-01 12:40:54 -0700185
joshualitt79dfb2b2015-05-11 08:58:08 -0700186#ifdef GR_TEST_UTILS
bsalomonabd30f52015-08-13 13:34:48 -0700187 DRAW_BATCH_TEST_FRIEND(TextBlobBatch);
joshualitt79dfb2b2015-05-11 08:58:08 -0700188#endif
189
joshualitt1d89e8d2015-04-01 12:40:54 -0700190 typedef GrTextContext INHERITED;
191};
192
193#endif