| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 "GrDistanceFieldTextContext.h" | 8 #include "GrDistanceFieldTextContext.h" |
| 9 #include "GrAtlas.h" | 9 #include "GrAtlas.h" |
| 10 #include "GrBitmapTextContext.h" | 10 #include "GrBitmapTextContext.h" |
| 11 #include "GrDrawTarget.h" | 11 #include "GrDrawTarget.h" |
| 12 #include "GrDrawTargetCaps.h" | 12 #include "GrDrawTargetCaps.h" |
| 13 #include "GrFontScaler.h" | 13 #include "GrFontScaler.h" |
| 14 #include "GrGpu.h" | 14 #include "GrGpu.h" |
| 15 #include "GrIndexBuffer.h" | 15 #include "GrIndexBuffer.h" |
| 16 #include "GrStrokeInfo.h" | 16 #include "GrStrokeInfo.h" |
| 17 #include "GrTexturePriv.h" | 17 #include "GrTexturePriv.h" |
| 18 #include "GrTextStrike.h" | 18 #include "GrTextStrike.h" |
| 19 #include "GrTextStrike_impl.h" | 19 #include "GrTextStrike_impl.h" |
| 20 | 20 |
| 21 #include "SkAutoKern.h" |
| 21 #include "SkColorFilter.h" | 22 #include "SkColorFilter.h" |
| 22 #include "SkDistanceFieldGen.h" | 23 #include "SkDistanceFieldGen.h" |
| 23 #include "SkDraw.h" | 24 #include "SkDraw.h" |
| 24 #include "SkGlyphCache.h" | 25 #include "SkGlyphCache.h" |
| 25 #include "SkGpuDevice.h" | 26 #include "SkGpuDevice.h" |
| 26 #include "SkPath.h" | 27 #include "SkPath.h" |
| 27 #include "SkRTConf.h" | 28 #include "SkRTConf.h" |
| 28 #include "SkStrokeRec.h" | 29 #include "SkStrokeRec.h" |
| 29 #include "effects/GrDistanceFieldTextureEffect.h" | 30 #include "effects/GrDistanceFieldTextureEffect.h" |
| 30 | 31 |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 (*gammaTexture)->config(), data.get(), 0, | 206 (*gammaTexture)->config(), data.get(), 0, |
| 206 GrContext::kDontFlush_PixelOpsFlag); | 207 GrContext::kDontFlush_PixelOpsFlag); |
| 207 } | 208 } |
| 208 } | 209 } |
| 209 | 210 |
| 210 void GrDistanceFieldTextContext::onDrawText(const GrPaint& paint, const SkPaint&
skPaint, | 211 void GrDistanceFieldTextContext::onDrawText(const GrPaint& paint, const SkPaint&
skPaint, |
| 211 const char text[], size_t byteLength, | 212 const char text[], size_t byteLength, |
| 212 SkScalar x, SkScalar y) { | 213 SkScalar x, SkScalar y) { |
| 213 SkASSERT(byteLength == 0 || text != NULL); | 214 SkASSERT(byteLength == 0 || text != NULL); |
| 214 | 215 |
| 215 // nothing to draw or can't draw | 216 // nothing to draw |
| 216 if (text == NULL || byteLength == 0 /* no raster clip? || fRC->isEmpty()*/ | 217 if (text == NULL || byteLength == 0) { |
| 217 || fSkPaint.getRasterizer()) { | |
| 218 return; | 218 return; |
| 219 } | 219 } |
| 220 | 220 |
| 221 this->init(paint, skPaint); | 221 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); |
| 222 SkAutoGlyphCache autoCache(skPaint, &fDeviceProperties, NULL); |
| 223 SkGlyphCache* cache = autoCache.getCache(); |
| 222 | 224 |
| 223 SkScalar sizeRatio = fTextRatio; | 225 SkTArray<SkScalar> positions; |
| 224 | 226 |
| 225 SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc(); | 227 const char* textPtr = text; |
| 226 | 228 SkFixed stopX = 0; |
| 227 SkAutoGlyphCacheNoGamma autoCache(fSkPaint, &fDeviceProperties, NULL); | 229 SkFixed stopY = 0; |
| 228 SkGlyphCache* cache = autoCache.getCache(); | 230 SkFixed origin; |
| 229 GrFontScaler* fontScaler = GetGrFontScaler(cache); | 231 switch (skPaint.getTextAlign()) { |
| 230 | 232 case SkPaint::kRight_Align: origin = SK_Fixed1; break; |
| 231 setup_gamma_texture(fContext, cache, fDeviceProperties, &fGammaTexture); | 233 case SkPaint::kCenter_Align: origin = SK_FixedHalf; break; |
| 232 | 234 case SkPaint::kLeft_Align: origin = 0; break; |
| 233 // need to measure first | 235 default: SkFAIL("Invalid paint origin"); return; |
| 234 // TODO - generate positions and pre-load cache as well? | |
| 235 const char* stop = text + byteLength; | |
| 236 if (fSkPaint.getTextAlign() != SkPaint::kLeft_Align) { | |
| 237 SkFixed stopX = 0; | |
| 238 SkFixed stopY = 0; | |
| 239 | |
| 240 const char* textPtr = text; | |
| 241 while (textPtr < stop) { | |
| 242 // don't need x, y here, since all subpixel variants will have the | |
| 243 // same advance | |
| 244 const SkGlyph& glyph = glyphCacheProc(cache, &textPtr, 0, 0); | |
| 245 | |
| 246 stopX += glyph.fAdvanceX; | |
| 247 stopY += glyph.fAdvanceY; | |
| 248 } | |
| 249 SkASSERT(textPtr == stop); | |
| 250 | |
| 251 SkScalar alignX = SkFixedToScalar(stopX)*sizeRatio; | |
| 252 SkScalar alignY = SkFixedToScalar(stopY)*sizeRatio; | |
| 253 | |
| 254 if (fSkPaint.getTextAlign() == SkPaint::kCenter_Align) { | |
| 255 alignX = SkScalarHalf(alignX); | |
| 256 alignY = SkScalarHalf(alignY); | |
| 257 } | |
| 258 | |
| 259 x -= alignX; | |
| 260 y -= alignY; | |
| 261 } | 236 } |
| 262 | 237 |
| 263 SkFixed fx = SkScalarToFixed(x); | 238 SkAutoKern autokern; |
| 264 SkFixed fy = SkScalarToFixed(y); | 239 const char* stop = text + byteLength; |
| 265 SkFixed fixedScale = SkScalarToFixed(sizeRatio); | 240 while (textPtr < stop) { |
| 266 while (text < stop) { | 241 // don't need x, y here, since all subpixel variants will have the |
| 267 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 242 // same advance |
| 243 const SkGlyph& glyph = glyphCacheProc(cache, &textPtr, 0, 0); |
| 268 | 244 |
| 269 if (glyph.fWidth) { | 245 SkFixed width = glyph.fAdvanceX + autokern.adjust(glyph); |
| 270 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), | 246 positions.push_back(SkFixedToScalar(stopX + SkFixedMul_portable(origin,
width))); |
| 271 glyph.getSubXFixed(), | |
| 272 glyph.getSubYFixed()), | |
| 273 fx, | |
| 274 fy, | |
| 275 fontScaler); | |
| 276 } | |
| 277 | 247 |
| 278 fx += SkFixedMul_portable(glyph.fAdvanceX, fixedScale); | 248 SkFixed height = glyph.fAdvanceY; |
| 279 fy += SkFixedMul_portable(glyph.fAdvanceY, fixedScale); | 249 positions.push_back(SkFixedToScalar(stopY + SkFixedMul_portable(origin,
height))); |
| 250 |
| 251 stopX += width; |
| 252 stopY += height; |
| 280 } | 253 } |
| 254 SkASSERT(textPtr == stop); |
| 281 | 255 |
| 282 this->finish(); | 256 // now adjust starting point depending on alignment |
| 257 SkScalar alignX = SkFixedToScalar(stopX); |
| 258 SkScalar alignY = SkFixedToScalar(stopY); |
| 259 if (skPaint.getTextAlign() == SkPaint::kCenter_Align) { |
| 260 alignX = SkScalarHalf(alignX); |
| 261 alignY = SkScalarHalf(alignY); |
| 262 } else if (skPaint.getTextAlign() == SkPaint::kLeft_Align) { |
| 263 alignX = 0; |
| 264 alignY = 0; |
| 265 } |
| 266 x -= alignX; |
| 267 y -= alignY; |
| 268 SkPoint offset = SkPoint::Make(x, y); |
| 269 |
| 270 this->drawPosText(paint, skPaint, text, byteLength, positions.begin(), 2, of
fset); |
| 283 } | 271 } |
| 284 | 272 |
| 285 void GrDistanceFieldTextContext::onDrawPosText(const GrPaint& paint, const SkPai
nt& skPaint, | 273 void GrDistanceFieldTextContext::onDrawPosText(const GrPaint& paint, const SkPai
nt& skPaint, |
| 286 const char text[], size_t byteLengt
h, | 274 const char text[], size_t byteLengt
h, |
| 287 const SkScalar pos[], int scalarsPe
rPosition, | 275 const SkScalar pos[], int scalarsPe
rPosition, |
| 288 const SkPoint& offset) { | 276 const SkPoint& offset) { |
| 289 | 277 |
| 290 SkASSERT(byteLength == 0 || text != NULL); | 278 SkASSERT(byteLength == 0 || text != NULL); |
| 291 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); | 279 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); |
| 292 | 280 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 319 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), | 307 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), |
| 320 glyph.getSubXFixed(), | 308 glyph.getSubXFixed(), |
| 321 glyph.getSubYFixed()), | 309 glyph.getSubYFixed()), |
| 322 SkScalarToFixed(x), | 310 SkScalarToFixed(x), |
| 323 SkScalarToFixed(y), | 311 SkScalarToFixed(y), |
| 324 fontScaler); | 312 fontScaler); |
| 325 } | 313 } |
| 326 pos += scalarsPerPosition; | 314 pos += scalarsPerPosition; |
| 327 } | 315 } |
| 328 } else { | 316 } else { |
| 329 int alignShift = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ? 1 :
0; | 317 SkScalar alignMul = SkPaint::kCenter_Align == fSkPaint.getTextAlign() ?
SK_ScalarHalf |
| 318 :
SK_Scalar1; |
| 330 while (text < stop) { | 319 while (text < stop) { |
| 331 // the last 2 parameters are ignored | 320 // the last 2 parameters are ignored |
| 332 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); | 321 const SkGlyph& glyph = glyphCacheProc(cache, &text, 0, 0); |
| 333 | 322 |
| 334 if (glyph.fWidth) { | 323 if (glyph.fWidth) { |
| 335 SkScalar x = offset.x() + pos[0]; | 324 SkScalar x = offset.x() + pos[0]; |
| 336 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; | 325 SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0)
; |
| 337 | 326 |
| 327 SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX)*alignMul*fT
extRatio; |
| 328 SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY)*alignMul*fT
extRatio; |
| 329 |
| 338 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), | 330 this->appendGlyph(GrGlyph::Pack(glyph.getGlyphID(), |
| 339 glyph.getSubXFixed(), | 331 glyph.getSubXFixed(), |
| 340 glyph.getSubYFixed()), | 332 glyph.getSubYFixed()), |
| 341 SkScalarToFixed(x) - (glyph.fAdvanceX >> align
Shift), | 333 SkScalarToFixed(x - advanceX), |
| 342 SkScalarToFixed(y) - (glyph.fAdvanceY >> align
Shift), | 334 SkScalarToFixed(y - advanceY), |
| 343 fontScaler); | 335 fontScaler); |
| 344 } | 336 } |
| 345 pos += scalarsPerPosition; | 337 pos += scalarsPerPosition; |
| 346 } | 338 } |
| 347 } | 339 } |
| 348 | 340 |
| 349 this->finish(); | 341 this->finish(); |
| 350 } | 342 } |
| 351 | 343 |
| 352 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { | 344 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) { |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 fVertexBounds.setLargestInverted(); | 673 fVertexBounds.setLargestInverted(); |
| 682 } | 674 } |
| 683 } | 675 } |
| 684 | 676 |
| 685 inline void GrDistanceFieldTextContext::finish() { | 677 inline void GrDistanceFieldTextContext::finish() { |
| 686 this->flush(); | 678 this->flush(); |
| 687 | 679 |
| 688 GrTextContext::finish(); | 680 GrTextContext::finish(); |
| 689 } | 681 } |
| 690 | 682 |
| OLD | NEW |