OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrStencilAndCoverTextContext.h" | 8 #include "GrStencilAndCoverTextContext.h" |
9 #include "GrAtlasTextContext.h" | 9 #include "GrAtlasTextContext.h" |
10 #include "GrDrawContext.h" | 10 #include "GrDrawContext.h" |
11 #include "GrDrawTarget.h" | 11 #include "GrDrawTarget.h" |
12 #include "GrPath.h" | 12 #include "GrPath.h" |
13 #include "GrPathRange.h" | 13 #include "GrPathRange.h" |
14 #include "GrResourceProvider.h" | 14 #include "GrResourceProvider.h" |
15 #include "GrTextUtils.h" | |
15 #include "SkAutoKern.h" | 16 #include "SkAutoKern.h" |
16 #include "SkDraw.h" | 17 #include "SkDraw.h" |
17 #include "SkDrawProcs.h" | 18 #include "SkDrawProcs.h" |
18 #include "SkGlyphCache.h" | 19 #include "SkGlyphCache.h" |
19 #include "SkGpuDevice.h" | 20 #include "SkGpuDevice.h" |
20 #include "SkGrPriv.h" | 21 #include "SkGrPriv.h" |
21 #include "SkPath.h" | 22 #include "SkPath.h" |
22 #include "SkTextBlobRunIterator.h" | 23 #include "SkTextBlobRunIterator.h" |
23 #include "SkTextMapStateProc.h" | 24 #include "SkTextMapStateProc.h" |
24 #include "SkTextFormatParams.h" | 25 #include "SkTextFormatParams.h" |
25 | 26 |
26 #include "batches/GrDrawPathBatch.h" | 27 #include "batches/GrDrawPathBatch.h" |
27 | 28 |
28 template<typename Key, typename Val> static void delete_hash_map_entry(const Key &, Val* val) { | 29 template<typename Key, typename Val> static void delete_hash_map_entry(const Key &, Val* val) { |
29 SkASSERT(*val); | 30 SkASSERT(*val); |
30 delete *val; | 31 delete *val; |
31 } | 32 } |
32 | 33 |
33 template<typename T> static void delete_hash_table_entry(T* val) { | 34 template<typename T> static void delete_hash_table_entry(T* val) { |
34 SkASSERT(*val); | 35 SkASSERT(*val); |
35 delete *val; | 36 delete *val; |
36 } | 37 } |
37 | 38 |
38 GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(GrContext* context, | 39 GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(GrContext* context, |
39 const SkSurfaceProps& surfaceProps) | 40 const SkSurfaceProps& surfaceProps) |
40 : INHERITED(context, surfaceProps), | 41 : INHERITED(context, surfaceProps), |
robertphillips
2016/02/10 18:28:45
, fFallbackTextContext(nullptr) - just for parano
joshualitt
2016/02/10 20:06:05
Acknowledged.
| |
41 fCacheSize(0) { | 42 fCacheSize(0) { |
42 } | 43 } |
43 | 44 |
44 GrStencilAndCoverTextContext* | 45 GrStencilAndCoverTextContext* |
45 GrStencilAndCoverTextContext::Create(GrContext* context, const SkSurfaceProps& s urfaceProps) { | 46 GrStencilAndCoverTextContext::Create(GrContext* context, const SkSurfaceProps& s urfaceProps) { |
46 GrStencilAndCoverTextContext* textContext = | 47 GrStencilAndCoverTextContext* textContext = |
47 new GrStencilAndCoverTextContext(context, surfaceProps); | 48 new GrStencilAndCoverTextContext(context, surfaceProps); |
48 textContext->fFallbackTextContext = GrAtlasTextContext::Create(context, surf aceProps); | 49 textContext->fFallbackTextContext = GrAtlasTextContext::Create(context, surf aceProps); |
49 | 50 |
50 return textContext; | 51 return textContext; |
51 } | 52 } |
52 | 53 |
53 GrStencilAndCoverTextContext::~GrStencilAndCoverTextContext() { | 54 GrStencilAndCoverTextContext::~GrStencilAndCoverTextContext() { |
55 delete fFallbackTextContext; | |
54 fBlobIdCache.foreach(delete_hash_map_entry<uint32_t, TextBlob*>); | 56 fBlobIdCache.foreach(delete_hash_map_entry<uint32_t, TextBlob*>); |
55 fBlobKeyCache.foreach(delete_hash_table_entry<TextBlob*>); | 57 fBlobKeyCache.foreach(delete_hash_table_entry<TextBlob*>); |
56 } | 58 } |
57 | 59 |
58 bool GrStencilAndCoverTextContext::internalCanDraw(const SkPaint& skPaint) { | 60 bool GrStencilAndCoverTextContext::internalCanDraw(const SkPaint& skPaint) { |
59 if (skPaint.getRasterizer()) { | 61 if (skPaint.getRasterizer()) { |
60 return false; | 62 return false; |
61 } | 63 } |
62 if (skPaint.getMaskFilter()) { | 64 if (skPaint.getMaskFilter()) { |
63 return false; | 65 return false; |
64 } | 66 } |
65 if (SkPathEffect* pe = skPaint.getPathEffect()) { | 67 if (SkPathEffect* pe = skPaint.getPathEffect()) { |
66 if (pe->asADash(nullptr) != SkPathEffect::kDash_DashType) { | 68 if (pe->asADash(nullptr) != SkPathEffect::kDash_DashType) { |
67 return false; | 69 return false; |
68 } | 70 } |
69 } | 71 } |
70 // No hairlines. They would require new paths with customized strokes for ev ery new draw matrix. | 72 // No hairlines. They would require new paths with customized strokes for ev ery new draw matrix. |
71 return SkPaint::kStroke_Style != skPaint.getStyle() || 0 != skPaint.getStrok eWidth(); | 73 return SkPaint::kStroke_Style != skPaint.getStyle() || 0 != skPaint.getStrok eWidth(); |
72 } | 74 } |
73 | 75 |
74 void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* dc, | 76 void GrStencilAndCoverTextContext::drawText(GrDrawContext* dc, |
75 const GrClip& clip, | 77 const GrClip& clip, const GrPaint& p aint, |
76 const GrPaint& paint, | 78 const SkPaint& skPaint, const SkMatr ix& viewMatrix, |
77 const SkPaint& skPaint, | 79 const char text[], size_t byteLength , |
78 const SkMatrix& viewMatrix, | 80 SkScalar x, SkScalar y, const SkIRec t& clipBounds) { |
79 const char text[], | 81 if (fContext->abandoned()) { |
80 size_t byteLength, | 82 return; |
81 SkScalar x, SkScalar y, | 83 } else if (this->canDraw(skPaint, viewMatrix)) { |
82 const SkIRect& clipBounds) { | 84 TextRun run(skPaint); |
83 TextRun run(skPaint); | 85 GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip) ; |
84 GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip); | 86 run.setText(text, byteLength, x, y); |
85 run.setText(text, byteLength, x, y); | 87 run.draw(fContext, dc, &pipelineBuilder, paint.getColor(), viewMatrix, 0 , 0, clipBounds, |
86 run.draw(fContext, dc, &pipelineBuilder, paint.getColor(), viewMatrix, 0, 0, clipBounds, | 88 fFallbackTextContext, skPaint); |
87 fFallbackTextContext, skPaint); | 89 return; |
90 } else if (fFallbackTextContext->canDraw(skPaint, viewMatrix)) { | |
91 fFallbackTextContext->drawText(dc, clip, paint, skPaint, viewMatrix, tex t, | |
92 byteLength, x, y, clipBounds); | |
93 return; | |
94 } | |
95 | |
96 // fall back to drawing as a path | |
97 GrTextUtils::DrawTextAsPath(fContext, dc, clip, skPaint, viewMatrix, text, b yteLength, x, y, | |
98 clipBounds); | |
88 } | 99 } |
89 | 100 |
90 void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* dc, | 101 void GrStencilAndCoverTextContext::drawPosText(GrDrawContext* dc, |
91 const GrClip& clip, | 102 const GrClip& clip, |
92 const GrPaint& paint, | 103 const GrPaint& paint, |
93 const SkPaint& skPaint, | 104 const SkPaint& skPaint, |
94 const SkMatrix& viewMatrix, | 105 const SkMatrix& viewMatrix, |
95 const char text[], | 106 const char text[], |
96 size_t byteLength, | 107 size_t byteLength, |
97 const SkScalar pos[], | 108 const SkScalar pos[], |
98 int scalarsPerPosition, | 109 int scalarsPerPosition, |
99 const SkPoint& offset, | 110 const SkPoint& offset, |
100 const SkIRect& clipBounds) { | 111 const SkIRect& clipBounds) { |
101 TextRun run(skPaint); | 112 if (fContext->abandoned()) { |
102 GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip); | 113 return; |
103 run.setPosText(text, byteLength, pos, scalarsPerPosition, offset); | 114 } else if (this->canDraw(skPaint, viewMatrix)) { |
104 run.draw(fContext, dc, &pipelineBuilder, paint.getColor(), viewMatrix, 0, 0, clipBounds, | 115 TextRun run(skPaint); |
105 fFallbackTextContext, skPaint); | 116 GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip) ; |
117 run.setPosText(text, byteLength, pos, scalarsPerPosition, offset); | |
118 run.draw(fContext, dc, &pipelineBuilder, paint.getColor(), viewMatrix, 0 , 0, clipBounds, | |
119 fFallbackTextContext, skPaint); | |
120 return; | |
121 } else if (fFallbackTextContext->canDraw(skPaint, viewMatrix)) { | |
122 fFallbackTextContext->drawPosText(dc, clip, paint, skPaint, viewMatrix, | |
123 text, byteLength, pos, | |
124 scalarsPerPosition, offset, clipBounds ); | |
125 return; | |
126 } | |
127 | |
128 // fall back to drawing as a path | |
129 GrTextUtils::DrawPosTextAsPath(fContext, dc, fSurfaceProps, clip, skPaint, v iewMatrix, text, | |
130 byteLength, pos, scalarsPerPosition, offset, clipBounds); | |
106 } | 131 } |
107 | 132 |
108 void GrStencilAndCoverTextContext::drawTextBlob(GrDrawContext* dc, | 133 void GrStencilAndCoverTextContext::drawTextBlob(GrDrawContext* dc, |
109 const GrClip& clip, const SkPain t& skPaint, | 134 const GrClip& clip, const SkPain t& skPaint, |
110 const SkMatrix& viewMatrix, | 135 const SkMatrix& viewMatrix, |
111 const SkTextBlob* skBlob, SkScal ar x, SkScalar y, | 136 const SkTextBlob* skBlob, SkScal ar x, SkScalar y, |
112 SkDrawFilter* drawFilter, | 137 SkDrawFilter* drawFilter, |
113 const SkIRect& clipBounds) { | 138 const SkIRect& clipBounds) { |
139 if (fContext->abandoned()) { | |
140 return; | |
141 } | |
142 | |
114 if (!this->internalCanDraw(skPaint)) { | 143 if (!this->internalCanDraw(skPaint)) { |
115 fFallbackTextContext->drawTextBlob(dc, clip, skPaint, viewMatrix, skBlob , x, y, | 144 fFallbackTextContext->drawTextBlob(dc, clip, skPaint, viewMatrix, skBlob , x, y, |
116 drawFilter, clipBounds); | 145 drawFilter, clipBounds); |
117 return; | 146 return; |
118 } | 147 } |
119 | 148 |
120 if (drawFilter || skPaint.getPathEffect()) { | 149 if (drawFilter || skPaint.getPathEffect()) { |
121 // This draw can't be cached. | 150 // This draw can't be cached. |
robertphillips
2016/02/10 18:28:45
This doesn't seem quite right ...
joshualitt
2016/02/10 20:06:05
Acknowledged.
| |
122 INHERITED::drawTextBlob(dc, clip, skPaint, viewMatrix, skBlob, x, y, dra wFilter, | 151 fFallbackTextContext->drawTextBlob(dc, clip, skPaint, viewMatrix, skBlob , x, y, drawFilter, |
123 clipBounds); | 152 clipBounds); |
124 return; | 153 return; |
125 } | 154 } |
126 | 155 |
127 if (fContext->abandoned()) { | |
128 return; | |
129 } | |
130 | |
131 GrPaint paint; | 156 GrPaint paint; |
132 if (!SkPaintToGrPaint(fContext, skPaint, viewMatrix, &paint)) { | 157 if (!SkPaintToGrPaint(fContext, skPaint, viewMatrix, &paint)) { |
133 return; | 158 return; |
134 } | 159 } |
135 | 160 |
136 const TextBlob& blob = this->findOrCreateTextBlob(skBlob, skPaint); | 161 const TextBlob& blob = this->findOrCreateTextBlob(skBlob, skPaint); |
137 GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip); | 162 GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip); |
138 | 163 |
139 TextBlob::Iter iter(blob); | 164 TextBlob::Iter iter(blob); |
140 for (TextRun* run = iter.get(); run; run = iter.next()) { | 165 for (TextRun* run = iter.get(); run; run = iter.next()) { |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
607 } | 632 } |
608 | 633 |
609 const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfNeed ed(int *count) { | 634 const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfNeed ed(int *count) { |
610 *count = fCount; | 635 *count = fCount; |
611 if (fCount) { | 636 if (fCount) { |
612 this->flush(); | 637 this->flush(); |
613 return fBuilder->build(); | 638 return fBuilder->build(); |
614 } | 639 } |
615 return nullptr; | 640 return nullptr; |
616 } | 641 } |
OLD | NEW |