| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2010 Google Inc. | 2 * Copyright 2010 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 "GrTextContext.h" | 8 #include "GrTextContext.h" |
| 9 #include "GrContext.h" | |
| 10 #include "GrFontScaler.h" | 9 #include "GrFontScaler.h" |
| 11 #include "GrTextUtils.h" | |
| 12 | 10 |
| 13 #include "SkDrawFilter.h" | |
| 14 #include "SkGlyphCache.h" | 11 #include "SkGlyphCache.h" |
| 15 #include "SkGrPriv.h" | |
| 16 #include "SkTextBlobRunIterator.h" | |
| 17 | 12 |
| 18 GrTextContext::GrTextContext(GrContext* context, const SkSurfaceProps& surfacePr
ops) | 13 GrTextContext::GrTextContext(GrContext* context, const SkSurfaceProps& surfacePr
ops) |
| 19 : fFallbackTextContext(nullptr) | 14 : fContext(context) |
| 20 , fContext(context) | |
| 21 , fSurfaceProps(surfaceProps) { | 15 , fSurfaceProps(surfaceProps) { |
| 22 } | 16 } |
| 23 | 17 |
| 24 GrTextContext::~GrTextContext() { | |
| 25 delete fFallbackTextContext; | |
| 26 } | |
| 27 | |
| 28 void GrTextContext::drawText(GrDrawContext* dc, | |
| 29 const GrClip& clip, const GrPaint& paint, | |
| 30 const SkPaint& skPaint, const SkMatrix& viewMatrix, | |
| 31 const char text[], size_t byteLength, | |
| 32 SkScalar x, SkScalar y, const SkIRect& clipBounds)
{ | |
| 33 if (fContext->abandoned()) { | |
| 34 return; | |
| 35 } | |
| 36 | |
| 37 GrTextContext* textContext = this; | |
| 38 do { | |
| 39 if (textContext->canDraw(skPaint, viewMatrix)) { | |
| 40 textContext->onDrawText(dc, clip, paint, skPaint, viewMatrix, | |
| 41 text, byteLength, x, y, clipBounds); | |
| 42 return; | |
| 43 } | |
| 44 textContext = textContext->fFallbackTextContext; | |
| 45 } while (textContext); | |
| 46 | |
| 47 // fall back to drawing as a path | |
| 48 GrTextUtils::DrawTextAsPath(fContext, dc, clip, skPaint, viewMatrix, text, b
yteLength, x, y, | |
| 49 clipBounds); | |
| 50 } | |
| 51 | |
| 52 void GrTextContext::drawPosText(GrDrawContext* dc, | |
| 53 const GrClip& clip, const GrPaint& paint, | |
| 54 const SkPaint& skPaint, const SkMatrix& viewMatr
ix, | |
| 55 const char text[], size_t byteLength, | |
| 56 const SkScalar pos[], int scalarsPerPosition, | |
| 57 const SkPoint& offset, const SkIRect& clipBounds
) { | |
| 58 if (fContext->abandoned()) { | |
| 59 return; | |
| 60 } | |
| 61 | |
| 62 GrTextContext* textContext = this; | |
| 63 do { | |
| 64 if (textContext->canDraw(skPaint, viewMatrix)) { | |
| 65 textContext->onDrawPosText(dc, clip, paint, skPaint, viewMatrix, | |
| 66 text, byteLength, pos, | |
| 67 scalarsPerPosition, offset, clipBounds); | |
| 68 return; | |
| 69 } | |
| 70 textContext = textContext->fFallbackTextContext; | |
| 71 } while (textContext); | |
| 72 | |
| 73 // fall back to drawing as a path | |
| 74 GrTextUtils::DrawPosTextAsPath(fContext, dc, fSurfaceProps, clip, skPaint, v
iewMatrix, text, | |
| 75 byteLength, pos, scalarsPerPosition, offset,
clipBounds); | |
| 76 } | |
| 77 | |
| 78 bool GrTextContext::ShouldDisableLCD(const SkPaint& paint) { | 18 bool GrTextContext::ShouldDisableLCD(const SkPaint& paint) { |
| 79 if (!SkXfermode::AsMode(paint.getXfermode(), nullptr) || | 19 if (!SkXfermode::AsMode(paint.getXfermode(), nullptr) || |
| 80 paint.getMaskFilter() || | 20 paint.getMaskFilter() || |
| 81 paint.getRasterizer() || | 21 paint.getRasterizer() || |
| 82 paint.getPathEffect() || | 22 paint.getPathEffect() || |
| 83 paint.isFakeBoldText() || | 23 paint.isFakeBoldText() || |
| 84 paint.getStyle() != SkPaint::kFill_Style) | 24 paint.getStyle() != SkPaint::kFill_Style) |
| 85 { | 25 { |
| 86 return true; | 26 return true; |
| 87 } | 27 } |
| 88 return false; | 28 return false; |
| 89 } | 29 } |
| 90 | 30 |
| 91 uint32_t GrTextContext::FilterTextFlags(const SkSurfaceProps& surfaceProps, cons
t SkPaint& paint) { | 31 uint32_t GrTextContext::FilterTextFlags(const SkSurfaceProps& surfaceProps, cons
t SkPaint& paint) { |
| 92 uint32_t flags = paint.getFlags(); | 32 uint32_t flags = paint.getFlags(); |
| 93 | 33 |
| 94 if (!paint.isLCDRenderText() || !paint.isAntiAlias()) { | 34 if (!paint.isLCDRenderText() || !paint.isAntiAlias()) { |
| 95 return flags; | 35 return flags; |
| 96 } | 36 } |
| 97 | 37 |
| 98 if (kUnknown_SkPixelGeometry == surfaceProps.pixelGeometry() || ShouldDisabl
eLCD(paint)) { | 38 if (kUnknown_SkPixelGeometry == surfaceProps.pixelGeometry() || ShouldDisabl
eLCD(paint)) { |
| 99 flags &= ~SkPaint::kLCDRenderText_Flag; | 39 flags &= ~SkPaint::kLCDRenderText_Flag; |
| 100 flags |= SkPaint::kGenA8FromLCD_Flag; | 40 flags |= SkPaint::kGenA8FromLCD_Flag; |
| 101 } | 41 } |
| 102 | 42 |
| 103 return flags; | 43 return flags; |
| 104 } | 44 } |
| 105 | 45 |
| 106 void GrTextContext::drawTextBlob(GrDrawContext* dc, | |
| 107 const GrClip& clip, const SkPaint& skPaint, | |
| 108 const SkMatrix& viewMatrix, const SkTextBlob* b
lob, | |
| 109 SkScalar x, SkScalar y, | |
| 110 SkDrawFilter* drawFilter, const SkIRect& clipBo
unds) { | |
| 111 SkPaint runPaint = skPaint; | |
| 112 | |
| 113 SkTextBlobRunIterator it(blob); | |
| 114 for (;!it.done(); it.next()) { | |
| 115 size_t textLen = it.glyphCount() * sizeof(uint16_t); | |
| 116 const SkPoint& offset = it.offset(); | |
| 117 // applyFontToPaint() always overwrites the exact same attributes, | |
| 118 // so it is safe to not re-seed the paint for this reason. | |
| 119 it.applyFontToPaint(&runPaint); | |
| 120 | |
| 121 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ
e)) { | |
| 122 // A false return from filter() means we should abort the current dr
aw. | |
| 123 runPaint = skPaint; | |
| 124 continue; | |
| 125 } | |
| 126 | |
| 127 runPaint.setFlags(FilterTextFlags(fSurfaceProps, runPaint)); | |
| 128 | |
| 129 GrPaint grPaint; | |
| 130 if (!SkPaintToGrPaint(fContext, runPaint, viewMatrix, &grPaint)) { | |
| 131 return; | |
| 132 } | |
| 133 | |
| 134 switch (it.positioning()) { | |
| 135 case SkTextBlob::kDefault_Positioning: | |
| 136 this->drawText(dc, clip, grPaint, runPaint, viewMatrix, (const char
*)it.glyphs(), | |
| 137 textLen, x + offset.x(), y + offset.y(), clipBounds); | |
| 138 break; | |
| 139 case SkTextBlob::kHorizontal_Positioning: | |
| 140 this->drawPosText(dc, clip, grPaint, runPaint, viewMatrix, (const ch
ar*)it.glyphs(), | |
| 141 textLen, it.pos(), 1, SkPoint::Make(x, y + offset.
y()), clipBounds); | |
| 142 break; | |
| 143 case SkTextBlob::kFull_Positioning: | |
| 144 this->drawPosText(dc, clip, grPaint, runPaint, viewMatrix, (const ch
ar*)it.glyphs(), | |
| 145 textLen, it.pos(), 2, SkPoint::Make(x, y), clipBou
nds); | |
| 146 break; | |
| 147 default: | |
| 148 SkFAIL("unhandled positioning mode"); | |
| 149 } | |
| 150 | |
| 151 if (drawFilter) { | |
| 152 // A draw filter may change the paint arbitrarily, so we must re-see
d in this case. | |
| 153 runPaint = skPaint; | |
| 154 } | |
| 155 } | |
| 156 } | |
| 157 | |
| 158 static void GlyphCacheAuxProc(void* data) { | 46 static void GlyphCacheAuxProc(void* data) { |
| 159 GrFontScaler* scaler = (GrFontScaler*)data; | 47 GrFontScaler* scaler = (GrFontScaler*)data; |
| 160 SkSafeUnref(scaler); | 48 SkSafeUnref(scaler); |
| 161 } | 49 } |
| 162 | 50 |
| 163 GrFontScaler* GrTextContext::GetGrFontScaler(SkGlyphCache* cache) { | 51 GrFontScaler* GrTextContext::GetGrFontScaler(SkGlyphCache* cache) { |
| 164 void* auxData; | 52 void* auxData; |
| 165 GrFontScaler* scaler = nullptr; | 53 GrFontScaler* scaler = nullptr; |
| 166 | 54 |
| 167 if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) { | 55 if (cache->getAuxProcData(GlyphCacheAuxProc, &auxData)) { |
| 168 scaler = (GrFontScaler*)auxData; | 56 scaler = (GrFontScaler*)auxData; |
| 169 } | 57 } |
| 170 if (nullptr == scaler) { | 58 if (nullptr == scaler) { |
| 171 scaler = new GrFontScaler(cache); | 59 scaler = new GrFontScaler(cache); |
| 172 cache->setAuxProc(GlyphCacheAuxProc, scaler); | 60 cache->setAuxProc(GlyphCacheAuxProc, scaler); |
| 173 } | 61 } |
| 174 | 62 |
| 175 return scaler; | 63 return scaler; |
| 176 } | 64 } |
| OLD | NEW |