blob: af1403825abab58a122b30b5e5d6389314dcb78b [file] [log] [blame]
kkinnunenc6cb56f2014-06-24 00:12:27 -07001/*
2 * Copyright 2014 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 GrStencilAndCoverTextContext_DEFINED
9#define GrStencilAndCoverTextContext_DEFINED
10
11#include "GrTextContext.h"
cdaltonb2808cd2014-07-25 14:13:57 -070012#include "GrDrawTarget.h"
kkinnunen50b58e62015-05-18 23:02:07 -070013#include "GrStrokeInfo.h"
cdaltoncdd79072015-10-05 15:37:35 -070014#include "SkTHash.h"
15#include "SkTInternalLList.h"
16#include "SkTLList.h"
kkinnunenc6cb56f2014-06-24 00:12:27 -070017
18class GrTextStrike;
19class GrPath;
robertphillipsfcf78292015-06-19 11:49:52 -070020class SkSurfaceProps;
kkinnunenc6cb56f2014-06-24 00:12:27 -070021
22/*
23 * This class implements text rendering using stencil and cover path rendering
24 * (by the means of GrDrawTarget::drawPath).
25 * This class exposes the functionality through GrTextContext interface.
26 */
27class GrStencilAndCoverTextContext : public GrTextContext {
28public:
robertphillipsf6703fa2015-09-01 05:36:47 -070029 static GrStencilAndCoverTextContext* Create(GrContext*, const SkSurfaceProps&);
jvanverth8c27a182014-10-14 08:45:50 -070030
kkinnunenc6cb56f2014-06-24 00:12:27 -070031 virtual ~GrStencilAndCoverTextContext();
32
kkinnunenc6cb56f2014-06-24 00:12:27 -070033private:
robertphillipsf6703fa2015-09-01 05:36:47 -070034 GrStencilAndCoverTextContext(GrContext*, const SkSurfaceProps&);
jvanverth8c27a182014-10-14 08:45:50 -070035
robertphillips6ee690e2015-12-02 08:57:50 -080036 bool canDraw(const SkPaint& skPaint, const SkMatrix&) override {
37 return this->internalCanDraw(skPaint);
38 }
cdaltoncdd79072015-10-05 15:37:35 -070039
40 bool internalCanDraw(const SkPaint&);
jvanverth8c27a182014-10-14 08:45:50 -070041
robertphillipsf6703fa2015-09-01 05:36:47 -070042 void onDrawText(GrDrawContext*, GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
cdaltone68f7362015-03-25 14:02:37 -070043 const SkMatrix& viewMatrix,
44 const char text[], size_t byteLength,
cdaltoncdd79072015-10-05 15:37:35 -070045 SkScalar x, SkScalar y, const SkIRect& clipBounds) override;
robertphillipsf6703fa2015-09-01 05:36:47 -070046 void onDrawPosText(GrDrawContext*, GrRenderTarget*,
47 const GrClip&, const GrPaint&, const SkPaint&,
cdaltone68f7362015-03-25 14:02:37 -070048 const SkMatrix& viewMatrix,
49 const char text[], size_t byteLength,
50 const SkScalar pos[], int scalarsPerPosition,
cdaltoncdd79072015-10-05 15:37:35 -070051 const SkPoint& offset, const SkIRect& clipBounds) override;
52 void drawTextBlob(GrDrawContext*, GrRenderTarget*, const GrClip&, const SkPaint&,
53 const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x, SkScalar y,
54 SkDrawFilter*, const SkIRect& clipBounds) override;
jvanverth8c27a182014-10-14 08:45:50 -070055
cdalton02015e52015-10-05 15:28:20 -070056 class FallbackBlobBuilder;
57
cdalton3bd909a2015-10-05 14:57:20 -070058 class TextRun {
59 public:
60 TextRun(const SkPaint& fontAndStroke);
61 ~TextRun();
62
cdalton8585dd22015-10-08 08:04:09 -070063 void setText(const char text[], size_t byteLength, SkScalar x, SkScalar y);
cdalton3bd909a2015-10-05 14:57:20 -070064
cdalton8585dd22015-10-08 08:04:09 -070065 void setPosText(const char text[], size_t byteLength, const SkScalar pos[],
66 int scalarsPerPosition, const SkPoint& offset);
cdalton3bd909a2015-10-05 14:57:20 -070067
cdalton8585dd22015-10-08 08:04:09 -070068 void draw(GrContext*, GrDrawContext*, GrPipelineBuilder*, GrColor, const SkMatrix&,
cdaltoncdd79072015-10-05 15:37:35 -070069 SkScalar x, SkScalar y, const SkIRect& clipBounds,
70 GrTextContext* fallbackTextContext, const SkPaint& originalSkPaint) const;
71
cdalton8585dd22015-10-08 08:04:09 -070072 void releaseGlyphCache() const;
73
74 size_t computeSizeInCache() const;
cdalton3bd909a2015-10-05 14:57:20 -070075
76 private:
cdalton8585dd22015-10-08 08:04:09 -070077 SkGlyphCache* getGlyphCache() const;
78 GrPathRange* createGlyphs(GrContext*) const;
cdalton02015e52015-10-05 15:28:20 -070079 void appendGlyph(const SkGlyph&, const SkPoint&, FallbackBlobBuilder*);
cdalton3bd909a2015-10-05 14:57:20 -070080
81 GrStrokeInfo fStroke;
82 SkPaint fFont;
83 SkScalar fTextRatio;
84 float fTextInverseRatio;
cdalton3bd909a2015-10-05 14:57:20 -070085 bool fUsingRawGlyphPaths;
cdalton8585dd22015-10-08 08:04:09 -070086 GrUniqueKey fGlyphPathsKey;
cdaltoncdd79072015-10-05 15:37:35 -070087 int fTotalGlyphCount;
cdalton3bd909a2015-10-05 14:57:20 -070088 SkAutoTUnref<GrPathRangeDraw> fDraw;
cdalton02015e52015-10-05 15:28:20 -070089 SkAutoTUnref<const SkTextBlob> fFallbackTextBlob;
cdalton8585dd22015-10-08 08:04:09 -070090 mutable SkGlyphCache* fDetachedGlyphCache;
91 mutable uint32_t fLastDrawnGlyphsID;
cdaltoncdd79072015-10-05 15:37:35 -070092 mutable SkMatrix fLocalMatrixTemplate;
cdalton3bd909a2015-10-05 14:57:20 -070093 };
kkinnunenc6cb56f2014-06-24 00:12:27 -070094
cdaltoncdd79072015-10-05 15:37:35 -070095 // Text blobs/caches.
96
bsalomonf045d602015-11-18 19:01:12 -080097 class TextBlob : public SkTLList<TextRun, 1> {
cdaltoncdd79072015-10-05 15:37:35 -070098 public:
99 typedef SkTArray<uint32_t, true> Key;
100
101 static const Key& GetKey(const TextBlob* blob) { return blob->key(); }
102
103 static uint32_t Hash(const Key& key) {
104 SkASSERT(key.count() > 1); // 1-length keys should be using the blob-id hash map.
105 return SkChecksum::Murmur3(key.begin(), sizeof(uint32_t) * key.count());
106 }
107
cdalton8585dd22015-10-08 08:04:09 -0700108 TextBlob(uint32_t blobId, const SkTextBlob* skBlob, const SkPaint& skPaint)
109 : fKey(&blobId, 1) { this->init(skBlob, skPaint); }
cdaltoncdd79072015-10-05 15:37:35 -0700110
cdalton8585dd22015-10-08 08:04:09 -0700111 TextBlob(const Key& key, const SkTextBlob* skBlob, const SkPaint& skPaint)
cdaltoncdd79072015-10-05 15:37:35 -0700112 : fKey(key) {
113 // 1-length keys are unterstood to be the blob id and must use the other constructor.
114 SkASSERT(fKey.count() > 1);
cdalton8585dd22015-10-08 08:04:09 -0700115 this->init(skBlob, skPaint);
cdaltoncdd79072015-10-05 15:37:35 -0700116 }
117
118 const Key& key() const { return fKey; }
119
cdalton8585dd22015-10-08 08:04:09 -0700120 size_t cpuMemorySize() const { return fCpuMemorySize; }
cdaltoncdd79072015-10-05 15:37:35 -0700121
122 private:
cdalton8585dd22015-10-08 08:04:09 -0700123 void init(const SkTextBlob*, const SkPaint&);
cdaltoncdd79072015-10-05 15:37:35 -0700124
125 const SkSTArray<1, uint32_t, true> fKey;
cdalton8585dd22015-10-08 08:04:09 -0700126 size_t fCpuMemorySize;
cdaltoncdd79072015-10-05 15:37:35 -0700127
128 SK_DECLARE_INTERNAL_LLIST_INTERFACE(TextBlob);
129 };
130
131 const TextBlob& findOrCreateTextBlob(const SkTextBlob*, const SkPaint&);
132 void purgeToFit(const TextBlob&);
133
134 SkTHashMap<uint32_t, TextBlob*> fBlobIdCache;
135 SkTHashTable<TextBlob*, const TextBlob::Key&, TextBlob> fBlobKeyCache;
136 SkTInternalLList<TextBlob> fLRUList;
cdalton8585dd22015-10-08 08:04:09 -0700137 size_t fCacheSize;
cdaltoncdd79072015-10-05 15:37:35 -0700138
bsalomon1fcc01c2015-09-09 09:48:06 -0700139 typedef GrTextContext INHERITED;
kkinnunenc6cb56f2014-06-24 00:12:27 -0700140};
141
142#endif