Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(659)

Side by Side Diff: src/gpu/GrTextStrike.cpp

Issue 41213003: Hook in rough distance field support for fonts (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "GrAtlas.h" 8 #include "GrAtlas.h"
9 #include "GrGpu.h" 9 #include "GrGpu.h"
10 #include "GrRectanizer.h" 10 #include "GrRectanizer.h"
11 #include "GrTextStrike.h" 11 #include "GrTextStrike.h"
12 #include "GrTextStrike_impl.h" 12 #include "GrTextStrike_impl.h"
13 #include "SkString.h" 13 #include "SkString.h"
14 14
15 SK_DEFINE_INST_COUNT(GrFontScaler) 15 SK_DEFINE_INST_COUNT(GrFontScaler)
16 SK_DEFINE_INST_COUNT(GrKey) 16 SK_DEFINE_INST_COUNT(GrKey)
17 17
18 /////////////////////////////////////////////////////////////////////////////// 18 ///////////////////////////////////////////////////////////////////////////////
19 19
20 #define FONT_CACHE_STATS 0 20 #define FONT_CACHE_STATS 0
21 #if FONT_CACHE_STATS 21 #if FONT_CACHE_STATS
22 static int g_PurgeCount = 0; 22 static int g_PurgeCount = 0;
23 #endif 23 #endif
24 24
25 void edtaa2(unsigned char *img, int w, int h, short *distx, short *disty, float *dist);
26
25 GrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) { 27 GrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) {
26 gpu->ref(); 28 gpu->ref();
27 for (int i = 0; i < kMaskFormatCount; ++i) { 29 for (int i = 0; i < kMaskFormatCount; ++i) {
28 fAtlasMgr[i] = NULL; 30 fAtlasMgr[i] = NULL;
29 } 31 }
30 32
31 fHead = fTail = NULL; 33 fHead = fTail = NULL;
32 } 34 }
33 35
34 GrFontCache::~GrFontCache() { 36 GrFontCache::~GrFontCache() {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 ++gDumpCount; 189 ++gDumpCount;
188 } 190 }
189 #endif 191 #endif
190 192
191 /////////////////////////////////////////////////////////////////////////////// 193 ///////////////////////////////////////////////////////////////////////////////
192 194
193 #ifdef SK_DEBUG 195 #ifdef SK_DEBUG
194 static int gCounter; 196 static int gCounter;
195 #endif 197 #endif
196 198
199 #define DISTANCE_FIELD_PAD 4
200 #define DISTANCE_FIELD_RANGE (4.f)
201
197 /* 202 /*
198 The text strike is specific to a given font/style/matrix setup, which is 203 The text strike is specific to a given font/style/matrix setup, which is
199 represented by the GrHostFontScaler object we are given in getGlyph(). 204 represented by the GrHostFontScaler object we are given in getGlyph().
200 205
201 We map a 32bit glyphID to a GrGlyph record, which in turn points to a 206 We map a 32bit glyphID to a GrGlyph record, which in turn points to a
202 atlas and a position within that texture. 207 atlas and a position within that texture.
203 */ 208 */
204 209
205 GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key, 210 GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
206 GrMaskFormat format, 211 GrMaskFormat format,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 } 245 }
241 246
242 GrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed, 247 GrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed,
243 GrFontScaler* scaler) { 248 GrFontScaler* scaler) {
244 SkIRect bounds; 249 SkIRect bounds;
245 if (!scaler->getPackedGlyphBounds(packed, &bounds)) { 250 if (!scaler->getPackedGlyphBounds(packed, &bounds)) {
246 return NULL; 251 return NULL;
247 } 252 }
248 253
249 GrGlyph* glyph = fPool.alloc(); 254 GrGlyph* glyph = fPool.alloc();
255 // expand bounds to hold full distance field data
256 if (fUseDistanceField) {
257 bounds.fLeft -= DISTANCE_FIELD_PAD;
258 bounds.fRight += DISTANCE_FIELD_PAD;
259 bounds.fTop -= DISTANCE_FIELD_PAD;
260 bounds.fBottom += DISTANCE_FIELD_PAD;
261 }
250 glyph->init(packed, bounds); 262 glyph->init(packed, bounds);
251 fCache.insert(packed, glyph); 263 fCache.insert(packed, glyph);
252 return glyph; 264 return glyph;
253 } 265 }
254 266
255 bool GrTextStrike::removeUnusedPlots() { 267 bool GrTextStrike::removeUnusedPlots() {
256 fCache.getArray().visitAll(invalidate_glyph); 268 fCache.getArray().visitAll(invalidate_glyph);
257 return fAtlasMgr->removeUnusedPlots(&fAtlas); 269 return fAtlasMgr->removeUnusedPlots(&fAtlas);
258 } 270 }
259 271
272
260 bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) { 273 bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
261 #if 0 // testing hack to force us to flush our cache often 274 #if 0 // testing hack to force us to flush our cache often
262 static int gCounter; 275 static int gCounter;
263 if ((++gCounter % 10) == 0) return false; 276 if ((++gCounter % 10) == 0) return false;
264 #endif 277 #endif
265 278
266 SkASSERT(glyph); 279 SkASSERT(glyph);
267 SkASSERT(scaler); 280 SkASSERT(scaler);
268 SkASSERT(fCache.contains(glyph)); 281 SkASSERT(fCache.contains(glyph));
269 SkASSERT(NULL == glyph->fPlot); 282 SkASSERT(NULL == glyph->fPlot);
270 283
271 SkAutoRef ar(scaler); 284 SkAutoRef ar(scaler);
272 285
273 int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat); 286 int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat);
274 size_t size = glyph->fBounds.area() * bytesPerPixel; 287
275 SkAutoSMalloc<1024> storage(size); 288 GrPlot* plot;
276 if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(), 289 if (fUseDistanceField) {
277 glyph->height(), 290 SkASSERT(1 == bytesPerPixel);
278 glyph->width() * bytesPerPixel, 291
279 storage.get())) { 292 // we've already expanded the glyph dimensions to match the final size
280 return false; 293 // but must shrink back down to get the packed glyph data
294 int dfwidth = glyph->width();
295 int dfheight = glyph->height();
296 int width = dfwidth - 2*DISTANCE_FIELD_PAD;
297 int height = dfheight - 2*DISTANCE_FIELD_PAD;
298 size_t stride = width*bytesPerPixel;
299
300 size_t size = width * height * bytesPerPixel;
301 SkAutoSMalloc<1024> storage(size);
302 if (!scaler->getPackedGlyphImage(glyph->fPackedID, width, height, stride , storage.get())) {
303 return false;
304 }
305
306 // alloc storage for distance field glyph
307 size_t dfsize = dfwidth * dfheight * bytesPerPixel;
308 SkAutoSMalloc<1024> dfstorage(dfsize);
309
310 // copy glyph into distance field storage
311 memset(dfstorage.get(), 0, dfsize);
312
313 unsigned char* ptr = (unsigned char*) storage.get();
314 unsigned char* dfptr = (unsigned char*) dfstorage.get();
315 size_t dfstride = dfwidth*bytesPerPixel;
316 dfptr += DISTANCE_FIELD_PAD*dfstride;
317 dfptr += DISTANCE_FIELD_PAD*bytesPerPixel;
318
319 for (int i = 0; i < height; ++i) {
320 memcpy(dfptr, ptr, stride);
321
322 dfptr += dfstride;
323 ptr += stride;
324 }
325
326 // generate distance field data
327 short* distx = new short[dfwidth*dfheight];
328 short* disty = new short[dfwidth*dfheight];
329 float* outerdist = new float[dfwidth*dfheight];
330 dfptr = (unsigned char*) dfstorage.get();
331 edtaa2(dfptr, dfwidth, dfheight, distx, disty, outerdist);
332
333 for (int i = 0; i < dfwidth*dfheight; ++i) {
334 *dfptr++ = 255 - *dfptr;
335 }
336 float* innerdist = new float[dfwidth*dfheight];
337 dfptr = (unsigned char*) dfstorage.get();
338 edtaa2(dfptr, dfwidth, dfheight, distx, disty, innerdist);
339
340 for (int i = 0; i < dfwidth*dfheight; ++i) {
341 unsigned char val;
342 float outerval = outerdist[i];
343 if (outerval < 0.0f) { outerval = 0.0f; }
344 float innerval = innerdist[i];
345 if (innerval < 0.0f) { innerval = 0.0f; }
346 float dist = outerval - innerval;
347 if (dist <= -DISTANCE_FIELD_RANGE) {
348 val = 255;
349 } else if (dist > DISTANCE_FIELD_RANGE) {
350 val = 0;
351 } else {
352 val = (unsigned char)((DISTANCE_FIELD_RANGE-dist)*128.f/DISTANCE _FIELD_RANGE);
353 }
354 *dfptr++ = val;
355 }
356
357 delete [] distx;
358 delete [] disty;
359 delete [] innerdist;
360 delete [] outerdist;
361
362 // copy to atlas
363 plot = fAtlasMgr->addToAtlas(&fAtlas, dfwidth, dfheight, dfstorage.get() ,
364 &glyph->fAtlasLocation);
365
366 } else {
367 size_t size = glyph->fBounds.area() * bytesPerPixel;
368 SkAutoSMalloc<1024> storage(size);
369 if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
370 glyph->height(),
371 glyph->width() * bytesPerPixel,
372 storage.get())) {
373 return false;
374 }
375
376 plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(), glyph->height(), s torage.get(),
377 &glyph->fAtlasLocation);
281 } 378 }
282 379
283 GrPlot* plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(),
284 glyph->height(), storage.get(),
285 &glyph->fAtlasLocation);
286 if (NULL == plot) { 380 if (NULL == plot) {
287 return false; 381 return false;
288 } 382 }
289 383
290 glyph->fPlot = plot; 384 glyph->fPlot = plot;
291 return true; 385 return true;
292 } 386 }
387
388
389 //////////////////////////////////////////////////////////////////////////////// //////
390
391 /*
392 * A hairy function to approximate the distance to an edge in a certain pixel,
393 * with consideration to both the direction to the pixel, the local gradient
394 * at that pixel and its greyscale value.
395 * This function is complicated enough to warrant a function call for each
396 * evaluation. Inlining it with a macro would only obfuscate the code.
397 */
398 static float distaa2(unsigned char *img, int w, int c, int xc, int yc, int xi, i nt yi)
399 {
400 float di, df, gx, gy, a, a1, temp;
401
402 a = (float)(img[c-xc-yc*w])/255.f; // Grayscale value at the edge pixel pointe d to
403 if(a < 0.0f) a = 0.0f; // Clip grayscale values outside the range [0,1]
404 if(a == 0.0f) return 1000000.0f; // Not an object pixel, return "very far" ("d on't know yet")
405 if(a > 1.0) a = 1.0f;
406 df = 0.5f-a; // Linear function is correct if gx==0 or gy==0
407
408 gx = (float)abs(xi); // Move to first quadrant gx>=0, gy>=0 (sign symmetry)
409 gy = (float)abs(yi);
410 di = sqrtf(gx*gx+gy*gy); // Length of integer vector, like a traditional EDT
411 if ((gx > 0) && (gy > 0)) { // Neither gx nor gy are zero
412 gx = gx / di;
413 gy = gy / di;
414 if(gx<gy) { // Move to first octant gx >= gy (transposition symmetry)
415 temp = gx;
416 gx = gy;
417 gy = temp;
418 }
419 a1 = 0.5f*gy/gx; // area of corner triangle
420 if (a < a1) // 0 <= a < a1, square root characteristic
421 df = 0.5f*(gx + gy) - sqrtf(2.0f*a*gx*gy);
422 else if (a <= (1.0f-a1)) // a1 <= a <= 1-a1, linear characteristic
423 df = (0.5f-a)*gx;
424 else // a1 < a <= 1, square root characteristic
425 df = -0.5f*(gx + gy) + sqrtf(2.0f*(1.0f-a)*gx*gy);
426 }
427 return di + df; // Negative at edge pixels (di=0) with a>0.5 (df<0)
428 }
429
430 // Shorthand macro: add ubiquitous parameters dist, img and w and call distaa2()
431 #define DISTAA2(c,xc,yc,xi,yi) (distaa2(img, w, c, xc, yc, xi, yi))
432
433 static void edtaa2(unsigned char *img, int w, int h, short *distx, short *disty, float *dist)
434 {
435 int x, y, i, c;
436 int offset_u, offset_ur, offset_r, offset_rd,
437 offset_d, offset_dl, offset_l, offset_lu;
438 float olddist, newdist;
439 int cdistx, cdisty, newdistx, newdisty;
440 int changed;
441
442 /* Initialize index offsets for the current image width */
443 offset_u = -w;
444 offset_ur = -w+1;
445 offset_r = 1;
446 offset_rd = w+1;
447 offset_d = w;
448 offset_dl = w-1;
449 offset_l = -1;
450 offset_lu = -w-1;
451
452 /* Initialize the distance images */
453 for(i=0; i<w*h; i++) {
454 float val = (float)(img[i])/255.f;
455 distx[i] = 0; // At first, all pixels point to
456 disty[i] = 0; // themselves as the closest known.
457 if(val == 0)
458 {
459 dist[i]= 1000000.0f; // Big value, means "not set yet"
460 }
461 else if (val < 1.0f) {
462 dist[i] = 0.5f-val; // Reasonable local guess
463 }
464 else {
465 dist[i]= 0.0f; // Inside the object
466 }
467 }
468
469 /* Perform the transformation */
470 do
471 {
472 changed = 0;
473
474 /* Scan rows, except first row */
475 for(y=1; y<h; y++)
476 {
477
478 /* move index to leftmost pixel of current row */
479 i = y*w;
480
481 /* scan right, propagate distances from above & left */
482
483 /* Leftmost pixel is special, has no left neighbors */
484 olddist = dist[i];
485 if(olddist > 0) // If non-zero distance or not set yet
486 {
487 c = i + offset_u; // Index of candidate for testing
488 cdistx = distx[c];
489 cdisty = disty[c];
490 newdistx = cdistx;
491 newdisty = cdisty+1;
492 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
493 if(newdist < olddist)
494 {
495 distx[i]=newdistx;
496 disty[i]=newdisty;
497 dist[i]=newdist;
498 olddist=newdist;
499 changed = 1;
500 }
501
502 c = i+offset_ur;
503 cdistx = distx[c];
504 cdisty = disty[c];
505 newdistx = cdistx-1;
506 newdisty = cdisty+1;
507 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
508 if(newdist < olddist)
509 {
510 distx[i]=newdistx;
511 disty[i]=newdisty;
512 dist[i]=newdist;
513 changed = 1;
514 }
515 }
516 i++;
517
518 /* Middle pixels have all neighbors */
519 for(x=1; x<w-1; x++, i++)
520 {
521 olddist = dist[i];
522 if(olddist <= 0) continue; // No need to update further
523
524 c = i+offset_l;
525 cdistx = distx[c];
526 cdisty = disty[c];
527 newdistx = cdistx+1;
528 newdisty = cdisty;
529 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
530 if(newdist < olddist)
531 {
532 distx[i]=newdistx;
533 disty[i]=newdisty;
534 dist[i]=newdist;
535 olddist=newdist;
536 changed = 1;
537 }
538
539 c = i+offset_lu;
540 cdistx = distx[c];
541 cdisty = disty[c];
542 newdistx = cdistx+1;
543 newdisty = cdisty+1;
544 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
545 if(newdist < olddist)
546 {
547 distx[i]=newdistx;
548 disty[i]=newdisty;
549 dist[i]=newdist;
550 olddist=newdist;
551 changed = 1;
552 }
553
554 c = i+offset_u;
555 cdistx = distx[c];
556 cdisty = disty[c];
557 newdistx = cdistx;
558 newdisty = cdisty+1;
559 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
560 if(newdist < olddist)
561 {
562 distx[i]=newdistx;
563 disty[i]=newdisty;
564 dist[i]=newdist;
565 olddist=newdist;
566 changed = 1;
567 }
568
569 c = i+offset_ur;
570 cdistx = distx[c];
571 cdisty = disty[c];
572 newdistx = cdistx-1;
573 newdisty = cdisty+1;
574 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
575 if(newdist < olddist)
576 {
577 distx[i]=newdistx;
578 disty[i]=newdisty;
579 dist[i]=newdist;
580 changed = 1;
581 }
582 }
583
584 /* Rightmost pixel of row is special, has no right neighbors */
585 olddist = dist[i];
586 if(olddist > 0) // If not already zero distance
587 {
588 c = i+offset_l;
589 cdistx = distx[c];
590 cdisty = disty[c];
591 newdistx = cdistx+1;
592 newdisty = cdisty;
593 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
594 if(newdist < olddist)
595 {
596 distx[i]=newdistx;
597 disty[i]=newdisty;
598 dist[i]=newdist;
599 olddist=newdist;
600 changed = 1;
601 }
602
603 c = i+offset_lu;
604 cdistx = distx[c];
605 cdisty = disty[c];
606 newdistx = cdistx+1;
607 newdisty = cdisty+1;
608 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
609 if(newdist < olddist)
610 {
611 distx[i]=newdistx;
612 disty[i]=newdisty;
613 dist[i]=newdist;
614 olddist=newdist;
615 changed = 1;
616 }
617
618 c = i+offset_u;
619 cdistx = distx[c];
620 cdisty = disty[c];
621 newdistx = cdistx;
622 newdisty = cdisty+1;
623 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
624 if(newdist < olddist)
625 {
626 distx[i]=newdistx;
627 disty[i]=newdisty;
628 dist[i]=newdist;
629 changed = 1;
630 }
631 }
632
633 /* Move index to second rightmost pixel of current row. */
634 /* Rightmost pixel is skipped, it has no right neighbor. */
635 i = y*w + w-2;
636
637 /* scan left, propagate distance from right */
638 for(x=w-2; x>=0; x--, i--)
639 {
640 olddist = dist[i];
641 if(olddist <= 0) continue; // Already zero distance
642
643 c = i+offset_r;
644 cdistx = distx[c];
645 cdisty = disty[c];
646 newdistx = cdistx-1;
647 newdisty = cdisty;
648 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
649 if(newdist < olddist)
650 {
651 distx[i]=newdistx;
652 disty[i]=newdisty;
653 dist[i]=newdist;
654 changed = 1;
655 }
656 }
657 }
658
659 /* Scan rows in reverse order, except last row */
660 for(y=h-2; y>=0; y--)
661 {
662 /* move index to rightmost pixel of current row */
663 i = y*w + w-1;
664
665 /* Scan left, propagate distances from below & right */
666
667 /* Rightmost pixel is special, has no right neighbors */
668 olddist = dist[i];
669 if(olddist > 0) // If not already zero distance
670 {
671 c = i+offset_d;
672 cdistx = distx[c];
673 cdisty = disty[c];
674 newdistx = cdistx;
675 newdisty = cdisty-1;
676 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
677 if(newdist < olddist)
678 {
679 distx[i]=newdistx;
680 disty[i]=newdisty;
681 dist[i]=newdist;
682 olddist=newdist;
683 changed = 1;
684 }
685
686 c = i+offset_dl;
687 cdistx = distx[c];
688 cdisty = disty[c];
689 newdistx = cdistx+1;
690 newdisty = cdisty-1;
691 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
692 if(newdist < olddist)
693 {
694 distx[i]=newdistx;
695 disty[i]=newdisty;
696 dist[i]=newdist;
697 changed = 1;
698 }
699 }
700 i--;
701
702 /* Middle pixels have all neighbors */
703 for(x=w-2; x>0; x--, i--)
704 {
705 olddist = dist[i];
706 if(olddist <= 0) continue; // Already zero distance
707
708 c = i+offset_r;
709 cdistx = distx[c];
710 cdisty = disty[c];
711 newdistx = cdistx-1;
712 newdisty = cdisty;
713 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
714 if(newdist < olddist)
715 {
716 distx[i]=newdistx;
717 disty[i]=newdisty;
718 dist[i]=newdist;
719 olddist=newdist;
720 changed = 1;
721 }
722
723 c = i+offset_rd;
724 cdistx = distx[c];
725 cdisty = disty[c];
726 newdistx = cdistx-1;
727 newdisty = cdisty-1;
728 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
729 if(newdist < olddist)
730 {
731 distx[i]=newdistx;
732 disty[i]=newdisty;
733 dist[i]=newdist;
734 olddist=newdist;
735 changed = 1;
736 }
737
738 c = i+offset_d;
739 cdistx = distx[c];
740 cdisty = disty[c];
741 newdistx = cdistx;
742 newdisty = cdisty-1;
743 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
744 if(newdist < olddist)
745 {
746 distx[i]=newdistx;
747 disty[i]=newdisty;
748 dist[i]=newdist;
749 olddist=newdist;
750 changed = 1;
751 }
752
753 c = i+offset_dl;
754 cdistx = distx[c];
755 cdisty = disty[c];
756 newdistx = cdistx+1;
757 newdisty = cdisty-1;
758 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
759 if(newdist < olddist)
760 {
761 distx[i]=newdistx;
762 disty[i]=newdisty;
763 dist[i]=newdist;
764 changed = 1;
765 }
766 }
767 /* Leftmost pixel is special, has no left neighbors */
768 olddist = dist[i];
769 if(olddist > 0) // If not already zero distance
770 {
771 c = i+offset_r;
772 cdistx = distx[c];
773 cdisty = disty[c];
774 newdistx = cdistx-1;
775 newdisty = cdisty;
776 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
777 if(newdist < olddist)
778 {
779 distx[i]=newdistx;
780 disty[i]=newdisty;
781 dist[i]=newdist;
782 olddist=newdist;
783 changed = 1;
784 }
785
786 c = i+offset_rd;
787 cdistx = distx[c];
788 cdisty = disty[c];
789 newdistx = cdistx-1;
790 newdisty = cdisty-1;
791 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
792 if(newdist < olddist)
793 {
794 distx[i]=newdistx;
795 disty[i]=newdisty;
796 dist[i]=newdist;
797 olddist=newdist;
798 changed = 1;
799 }
800
801 c = i+offset_d;
802 cdistx = distx[c];
803 cdisty = disty[c];
804 newdistx = cdistx;
805 newdisty = cdisty-1;
806 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
807 if(newdist < olddist)
808 {
809 distx[i]=newdistx;
810 disty[i]=newdisty;
811 dist[i]=newdist;
812 changed = 1;
813 }
814 }
815
816 /* Move index to second leftmost pixel of current row. */
817 /* Leftmost pixel is skipped, it has no left neighbor. */
818 i = y*w + 1;
819 for(x=1; x<w; x++, i++)
820 {
821 /* scan right, propagate distance from left */
822 olddist = dist[i];
823 if(olddist <= 0) continue; // Already zero distance
824
825 c = i+offset_l;
826 cdistx = distx[c];
827 cdisty = disty[c];
828 newdistx = cdistx+1;
829 newdisty = cdisty;
830 newdist = DISTAA2(c, cdistx, cdisty, newdistx, newdisty);
831 if(newdist < olddist)
832 {
833 distx[i]=newdistx;
834 disty[i]=newdisty;
835 dist[i]=newdist;
836 changed = 1;
837 }
838 }
839 }
840 }
841 while(changed); // Sweep until no more updates are made
842
843 /* The transformation is completed. */
844
845 }
846
OLDNEW
« src/core/SkDraw.cpp ('K') | « src/gpu/GrTextStrike.h ('k') | src/gpu/GrTextStrike_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698