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

Side by Side Diff: src/core/SkDistanceFieldGen.cpp

Issue 208893003: More distance field improvements (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Slightly faster clearing of temp glyph buffer Created 6 years, 9 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
« no previous file with comments | « no previous file | src/gpu/GrDistanceFieldTextContext.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "SkDistanceFieldGen.h" 8 #include "SkDistanceFieldGen.h"
9 #include "SkPoint.h" 9 #include "SkPoint.h"
10 10
(...skipping 10 matching lines...) Expand all
21 kTop_NeighborFlag = 0x08, 21 kTop_NeighborFlag = 0x08,
22 kTopRight_NeighborFlag = 0x10, 22 kTopRight_NeighborFlag = 0x10,
23 kBottomLeft_NeighborFlag = 0x20, 23 kBottomLeft_NeighborFlag = 0x20,
24 kBottom_NeighborFlag = 0x40, 24 kBottom_NeighborFlag = 0x40,
25 kBottomRight_NeighborFlag = 0x80, 25 kBottomRight_NeighborFlag = 0x80,
26 kAll_NeighborFlags = 0xff, 26 kAll_NeighborFlags = 0xff,
27 27
28 kNeighborFlagCount = 8 28 kNeighborFlagCount = 8
29 }; 29 };
30 30
31 // We treat an "edge" as a place where we cross from black to non-black, or vice versa. 31 // We treat an "edge" as a place where we cross from >=128 to <128, or vice vers a, or
32 // where we have two non-zero pixels that are <128.
32 // 'neighborFlags' is used to limit the directions in which we test to avoid ind exing 33 // 'neighborFlags' is used to limit the directions in which we test to avoid ind exing
33 // outside of the image 34 // outside of the image
34 static bool found_edge(const unsigned char* imagePtr, int width, int neighborFla gs) { 35 static bool found_edge(const unsigned char* imagePtr, int width, int neighborFla gs) {
35 // the order of these should match the neighbor flags above 36 // the order of these should match the neighbor flags above
36 const int kNum8ConnectedNeighbors = 8; 37 const int kNum8ConnectedNeighbors = 8;
37 const int offsets[8] = {-1, 1, -width-1, -width, -width+1, width-1, width, w idth+1 }; 38 const int offsets[8] = {-1, 1, -width-1, -width, -width+1, width-1, width, w idth+1 };
38 SkASSERT(kNum8ConnectedNeighbors == kNeighborFlagCount); 39 SkASSERT(kNum8ConnectedNeighbors == kNeighborFlagCount);
39 40
40 // search for an edge 41 // search for an edge
41 bool currVal = (*imagePtr != 0); 42 unsigned char currVal = *imagePtr;
43 unsigned char currCheck = (currVal >> 7);
42 for (int i = 0; i < kNum8ConnectedNeighbors; ++i) { 44 for (int i = 0; i < kNum8ConnectedNeighbors; ++i) {
43 bool checkVal; 45 unsigned char neighborVal;
44 if ((1 << i) & neighborFlags) { 46 if ((1 << i) & neighborFlags) {
45 const unsigned char* checkPtr = imagePtr + offsets[i]; 47 const unsigned char* checkPtr = imagePtr + offsets[i];
46 checkVal = (*checkPtr != 0); 48 neighborVal = *checkPtr;
47 } else { 49 } else {
48 checkVal = false; 50 neighborVal = 0;
49 } 51 }
50 SkASSERT(checkVal == 0 || checkVal == 1); 52 unsigned char neighborCheck = (neighborVal >> 7);
51 SkASSERT(currVal == 0 || currVal == 1); 53 SkASSERT(currCheck == 0 || currCheck == 1);
52 if (checkVal != currVal) { 54 SkASSERT(neighborCheck == 0 || neighborCheck == 1);
55 // if sharp transition
56 if (currCheck != neighborCheck ||
57 // or both <128 and >0
58 (!currCheck && !neighborCheck && currVal && neighborVal)) {
53 return true; 59 return true;
54 } 60 }
55 } 61 }
56 62
57 return false; 63 return false;
58 } 64 }
59 65
60 static void init_glyph_data(DFData* data, unsigned char* edges, const unsigned c har* image, 66 static void init_glyph_data(DFData* data, unsigned char* edges, const unsigned c har* image,
61 int dataWidth, int dataHeight, 67 int dataWidth, int dataHeight,
62 int imageWidth, int imageHeight, 68 int imageWidth, int imageHeight,
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 // create temp data 348 // create temp data
343 size_t dataSize = dataWidth*dataHeight*sizeof(DFData); 349 size_t dataSize = dataWidth*dataHeight*sizeof(DFData);
344 SkAutoSMalloc<1024> dfStorage(dataSize); 350 SkAutoSMalloc<1024> dfStorage(dataSize);
345 DFData* dataPtr = (DFData*) dfStorage.get(); 351 DFData* dataPtr = (DFData*) dfStorage.get();
346 sk_bzero(dataPtr, dataSize); 352 sk_bzero(dataPtr, dataSize);
347 353
348 SkAutoSMalloc<1024> edgeStorage(dataWidth*dataHeight*sizeof(char)); 354 SkAutoSMalloc<1024> edgeStorage(dataWidth*dataHeight*sizeof(char));
349 unsigned char* edgePtr = (unsigned char*) edgeStorage.get(); 355 unsigned char* edgePtr = (unsigned char*) edgeStorage.get();
350 sk_bzero(edgePtr, dataWidth*dataHeight*sizeof(char)); 356 sk_bzero(edgePtr, dataWidth*dataHeight*sizeof(char));
351 357
358 SkAutoSMalloc<1024> copyStorage((width+2)*(height+2)*sizeof(char));
359 unsigned char* copyPtr = (unsigned char*) copyStorage.get();
360
361 // we copy our source image into a padded copy to ensure we catch edge trans itions
362 // around the outside
363 const unsigned char* currImage = image;
364 sk_bzero(copyPtr, (width+2)*sizeof(char));
365 unsigned char* currCopy = copyPtr + width + 2;
366 for (int i = 0; i < height; ++i) {
367 *currCopy++ = 0;
368 memcpy(currCopy, currImage, width*sizeof(char));
369 currImage += width;
370 currCopy += width;
371 *currCopy++ = 0;
372 }
373 sk_bzero(currCopy, (width+2)*sizeof(char));
374
352 // copy glyph into distance field storage 375 // copy glyph into distance field storage
353 init_glyph_data(dataPtr, edgePtr, image, 376 init_glyph_data(dataPtr, edgePtr, copyPtr,
354 dataWidth, dataHeight, 377 dataWidth, dataHeight,
355 width, height, pad); 378 width+2, height+2, pad-1);
356 379
357 // create initial distance data, particularly at edges 380 // create initial distance data, particularly at edges
358 init_distances(dataPtr, edgePtr, dataWidth, dataHeight); 381 init_distances(dataPtr, edgePtr, dataWidth, dataHeight);
359 382
360 // now perform Euclidean distance transform to propagate distances 383 // now perform Euclidean distance transform to propagate distances
361 384
362 // forwards in y 385 // forwards in y
363 DFData* currData = dataPtr+dataWidth+1; // skip outer buffer 386 DFData* currData = dataPtr+dataWidth+1; // skip outer buffer
364 unsigned char* currEdge = edgePtr+dataWidth+1; 387 unsigned char* currEdge = edgePtr+dataWidth+1;
365 for (int j = 1; j < dataHeight-1; ++j) { 388 for (int j = 1; j < dataHeight-1; ++j) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 currEdge -= dataWidth-1; 442 currEdge -= dataWidth-1;
420 } 443 }
421 444
422 // copy results to final distance field data 445 // copy results to final distance field data
423 currData = dataPtr + dataWidth+1; 446 currData = dataPtr + dataWidth+1;
424 currEdge = edgePtr + dataWidth+1; 447 currEdge = edgePtr + dataWidth+1;
425 unsigned char *dfPtr = distanceField; 448 unsigned char *dfPtr = distanceField;
426 for (int j = 1; j < dataHeight-1; ++j) { 449 for (int j = 1; j < dataHeight-1; ++j) {
427 for (int i = 1; i < dataWidth-1; ++i) { 450 for (int i = 1; i < dataWidth-1; ++i) {
428 #if DUMP_EDGE 451 #if DUMP_EDGE
429 unsigned char val = sk_float_round2int(255*currData->fAlpha); 452 float alpha = currData->fAlpha;
453 float edge = 0.0f;
430 if (*currEdge) { 454 if (*currEdge) {
431 val = 128; 455 edge = 0.25f;
432 } 456 }
457 // blend with original image
458 float result = alpha + (1.0f-alpha)*edge;
459 unsigned char val = sk_float_round2int(255*result);
433 *dfPtr++ = val; 460 *dfPtr++ = val;
434 #else 461 #else
435 float dist; 462 float dist;
436 if (currData->fAlpha > 0.5f) { 463 if (currData->fAlpha > 0.5f) {
437 dist = -SkScalarSqrt(currData->fDistSq); 464 dist = -SkScalarSqrt(currData->fDistSq);
438 } else { 465 } else {
439 dist = SkScalarSqrt(currData->fDistSq); 466 dist = SkScalarSqrt(currData->fDistSq);
440 } 467 }
441 *dfPtr++ = pack_distance_field_val(dist, (float)distanceMagnitude); 468 *dfPtr++ = pack_distance_field_val(dist, (float)distanceMagnitude);
442 #endif 469 #endif
443 ++currData; 470 ++currData;
444 ++currEdge; 471 ++currEdge;
445 } 472 }
446 currData += 2; 473 currData += 2;
447 currEdge += 2; 474 currEdge += 2;
448 } 475 }
449 476
450 return true; 477 return true;
451 } 478 }
OLDNEW
« no previous file with comments | « no previous file | src/gpu/GrDistanceFieldTextContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698