blob: dab71e057859f798ca3258ce390055d1aee57fad [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"
cdaltoncdd46822015-12-08 10:48:31 -080017#include "batches/GrDrawPathBatch.h"
kkinnunenc6cb56f2014-06-24 00:12:27 -070018
19class GrTextStrike;
20class GrPath;
robertphillipsfcf78292015-06-19 11:49:52 -070021class SkSurfaceProps;
kkinnunenc6cb56f2014-06-24 00:12:27 -070022
23/*
24 * This class implements text rendering using stencil and cover path rendering
25 * (by the means of GrDrawTarget::drawPath).
26 * This class exposes the functionality through GrTextContext interface.
27 */
28class GrStencilAndCoverTextContext : public GrTextContext {
29public:
robertphillipsf6703fa2015-09-01 05:36:47 -070030 static GrStencilAndCoverTextContext* Create(GrContext*, const SkSurfaceProps&);
jvanverth8c27a182014-10-14 08:45:50 -070031
kkinnunenc6cb56f2014-06-24 00:12:27 -070032 virtual ~GrStencilAndCoverTextContext();
33
kkinnunenc6cb56f2014-06-24 00:12:27 -070034private:
robertphillipsf6703fa2015-09-01 05:36:47 -070035 GrStencilAndCoverTextContext(GrContext*, const SkSurfaceProps&);
jvanverth8c27a182014-10-14 08:45:50 -070036
robertphillips6ee690e2015-12-02 08:57:50 -080037 bool canDraw(const SkPaint& skPaint, const SkMatrix&) override {
38 return this->internalCanDraw(skPaint);
39 }
cdaltoncdd79072015-10-05 15:37:35 -070040
41 bool internalCanDraw(const SkPaint&);
jvanverth8c27a182014-10-14 08:45:50 -070042
robertphillips433625e2015-12-04 06:58:16 -080043 void onDrawText(GrDrawContext*, const GrClip&, const GrPaint&, const SkPaint&,
cdaltone68f7362015-03-25 14:02:37 -070044 const SkMatrix& viewMatrix,
45 const char text[], size_t byteLength,
cdaltoncdd79072015-10-05 15:37:35 -070046 SkScalar x, SkScalar y, const SkIRect& clipBounds) override;
robertphillips433625e2015-12-04 06:58:16 -080047 void onDrawPosText(GrDrawContext*,
robertphillipsf6703fa2015-09-01 05:36:47 -070048 const GrClip&, const GrPaint&, const SkPaint&,
cdaltone68f7362015-03-25 14:02:37 -070049 const SkMatrix& viewMatrix,
50 const char text[], size_t byteLength,
51 const SkScalar pos[], int scalarsPerPosition,
cdaltoncdd79072015-10-05 15:37:35 -070052 const SkPoint& offset, const SkIRect& clipBounds) override;
robertphillips433625e2015-12-04 06:58:16 -080053 void drawTextBlob(GrDrawContext*, const GrClip&, const SkPaint&,
cdaltoncdd79072015-10-05 15:37:35 -070054 const SkMatrix& viewMatrix, const SkTextBlob*, SkScalar x, SkScalar y,
55 SkDrawFilter*, const SkIRect& clipBounds) override;
jvanverth8c27a182014-10-14 08:45:50 -070056
cdalton02015e52015-10-05 15:28:20 -070057 class FallbackBlobBuilder;
58
cdalton3bd909a2015-10-05 14:57:20 -070059 class TextRun {
60 public:
61 TextRun(const SkPaint& fontAndStroke);
62 ~TextRun();
63
cdalton8585dd22015-10-08 08:04:09 -070064 void setText(const char text[], size_t byteLength, SkScalar x, SkScalar y);
cdalton3bd909a2015-10-05 14:57:20 -070065
cdalton8585dd22015-10-08 08:04:09 -070066 void setPosText(const char text[], size_t byteLength, const SkScalar pos[],
67 int scalarsPerPosition, const SkPoint& offset);
cdalton3bd909a2015-10-05 14:57:20 -070068
cdalton8585dd22015-10-08 08:04:09 -070069 void draw(GrContext*, GrDrawContext*, GrPipelineBuilder*, GrColor, const SkMatrix&,
cdaltoncdd79072015-10-05 15:37:35 -070070 SkScalar x, SkScalar y, const SkIRect& clipBounds,
71 GrTextContext* fallbackTextContext, const SkPaint& originalSkPaint) const;
72
cdalton8585dd22015-10-08 08:04:09 -070073 void releaseGlyphCache() const;
74
75 size_t computeSizeInCache() const;
cdalton3bd909a2015-10-05 14:57:20 -070076
77 private:
cdaltoncdd46822015-12-08 10:48:31 -080078 typedef GrDrawPathRangeBatch::InstanceData InstanceData;
79
cdalton8585dd22015-10-08 08:04:09 -070080 SkGlyphCache* getGlyphCache() const;
81 GrPathRange* createGlyphs(GrContext*) const;
cdalton02015e52015-10-05 15:28:20 -070082 void appendGlyph(const SkGlyph&, const SkPoint&, FallbackBlobBuilder*);
cdalton3bd909a2015-10-05 14:57:20 -070083
84 GrStrokeInfo fStroke;
85 SkPaint fFont;
86 SkScalar fTextRatio;
87 float fTextInverseRatio;
cdalton3bd909a2015-10-05 14:57:20 -070088 bool fUsingRawGlyphPaths;
cdalton8585dd22015-10-08 08:04:09 -070089 GrUniqueKey fGlyphPathsKey;
cdaltoncdd79072015-10-05 15:37:35 -070090 int fTotalGlyphCount;
cdaltoncdd46822015-12-08 10:48:31 -080091 SkAutoTUnref<InstanceData> fInstanceData;
92 int fFallbackGlyphCount;
cdalton02015e52015-10-05 15:28:20 -070093 SkAutoTUnref<const SkTextBlob> fFallbackTextBlob;
cdalton8585dd22015-10-08 08:04:09 -070094 mutable SkGlyphCache* fDetachedGlyphCache;
95 mutable uint32_t fLastDrawnGlyphsID;
cdalton3bd909a2015-10-05 14:57:20 -070096 };
kkinnunenc6cb56f2014-06-24 00:12:27 -070097
cdaltoncdd79072015-10-05 15:37:35 -070098 // Text blobs/caches.
99
bsalomonf045d602015-11-18 19:01:12 -0800100 class TextBlob : public SkTLList<TextRun, 1> {
cdaltoncdd79072015-10-05 15:37:35 -0700101 public:
102 typedef SkTArray<uint32_t, true> Key;
103
104 static const Key& GetKey(const TextBlob* blob) { return blob->key(); }
105
106 static uint32_t Hash(const Key& key) {
107 SkASSERT(key.count() > 1); // 1-length keys should be using the blob-id hash map.
108 return SkChecksum::Murmur3(key.begin(), sizeof(uint32_t) * key.count());
109 }
110
cdalton8585dd22015-10-08 08:04:09 -0700111 TextBlob(uint32_t blobId, const SkTextBlob* skBlob, const SkPaint& skPaint)
112 : fKey(&blobId, 1) { this->init(skBlob, skPaint); }
cdaltoncdd79072015-10-05 15:37:35 -0700113
cdalton8585dd22015-10-08 08:04:09 -0700114 TextBlob(const Key& key, const SkTextBlob* skBlob, const SkPaint& skPaint)
cdaltoncdd79072015-10-05 15:37:35 -0700115 : fKey(key) {
116 // 1-length keys are unterstood to be the blob id and must use the other constructor.
117 SkASSERT(fKey.count() > 1);
cdalton8585dd22015-10-08 08:04:09 -0700118 this->init(skBlob, skPaint);
cdaltoncdd79072015-10-05 15:37:35 -0700119 }
120
121 const Key& key() const { return fKey; }
122
cdalton8585dd22015-10-08 08:04:09 -0700123 size_t cpuMemorySize() const { return fCpuMemorySize; }
cdaltoncdd79072015-10-05 15:37:35 -0700124
125 private:
cdalton8585dd22015-10-08 08:04:09 -0700126 void init(const SkTextBlob*, const SkPaint&);
cdaltoncdd79072015-10-05 15:37:35 -0700127
128 const SkSTArray<1, uint32_t, true> fKey;
cdalton8585dd22015-10-08 08:04:09 -0700129 size_t fCpuMemorySize;
cdaltoncdd79072015-10-05 15:37:35 -0700130
131 SK_DECLARE_INTERNAL_LLIST_INTERFACE(TextBlob);
132 };
133
134 const TextBlob& findOrCreateTextBlob(const SkTextBlob*, const SkPaint&);
135 void purgeToFit(const TextBlob&);
136
137 SkTHashMap<uint32_t, TextBlob*> fBlobIdCache;
138 SkTHashTable<TextBlob*, const TextBlob::Key&, TextBlob> fBlobKeyCache;
139 SkTInternalLList<TextBlob> fLRUList;
cdalton8585dd22015-10-08 08:04:09 -0700140 size_t fCacheSize;
cdaltoncdd79072015-10-05 15:37:35 -0700141
bsalomon1fcc01c2015-09-09 09:48:06 -0700142 typedef GrTextContext INHERITED;
kkinnunenc6cb56f2014-06-24 00:12:27 -0700143};
144
145#endif