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

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

Issue 178543007: Add new module for distance field generation. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix warning 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 | « src/core/SkDistanceFieldGen.cpp ('k') | third_party/edtaa/LICENSE » ('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 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 #if SK_DISTANCEFIELD_FONTS 15 #if SK_DISTANCEFIELD_FONTS
16 #include "edtaa3.h" 16 #include "SkDistanceFieldGen.h"
17 #endif 17 #endif
18 18
19 /////////////////////////////////////////////////////////////////////////////// 19 ///////////////////////////////////////////////////////////////////////////////
20 20
21 #define FONT_CACHE_STATS 0 21 #define FONT_CACHE_STATS 0
22 #if FONT_CACHE_STATS 22 #if FONT_CACHE_STATS
23 static int g_PurgeCount = 0; 23 static int g_PurgeCount = 0;
24 #endif 24 #endif
25 25
26 GrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) { 26 GrFontCache::GrFontCache(GrGpu* gpu) : fGpu(gpu) {
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 } 192 }
193 #endif 193 #endif
194 194
195 /////////////////////////////////////////////////////////////////////////////// 195 ///////////////////////////////////////////////////////////////////////////////
196 196
197 #ifdef SK_DEBUG 197 #ifdef SK_DEBUG
198 static int gCounter; 198 static int gCounter;
199 #endif 199 #endif
200 200
201 #if SK_DISTANCEFIELD_FONTS 201 #if SK_DISTANCEFIELD_FONTS
202 #define DISTANCE_FIELD_PAD 4 202 // this acts as the max magnitude for the distance field,
203 #define DISTANCE_FIELD_RANGE (4.0) 203 // as well as the pad we need around the glyph
204 #define DISTANCE_FIELD_RANGE 4
204 #endif 205 #endif
205 206
206 /* 207 /*
207 The text strike is specific to a given font/style/matrix setup, which is 208 The text strike is specific to a given font/style/matrix setup, which is
208 represented by the GrHostFontScaler object we are given in getGlyph(). 209 represented by the GrHostFontScaler object we are given in getGlyph().
209 210
210 We map a 32bit glyphID to a GrGlyph record, which in turn points to a 211 We map a 32bit glyphID to a GrGlyph record, which in turn points to a
211 atlas and a position within that texture. 212 atlas and a position within that texture.
212 */ 213 */
213 214
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 GrFontScaler* scaler) { 247 GrFontScaler* scaler) {
247 SkIRect bounds; 248 SkIRect bounds;
248 if (!scaler->getPackedGlyphBounds(packed, &bounds)) { 249 if (!scaler->getPackedGlyphBounds(packed, &bounds)) {
249 return NULL; 250 return NULL;
250 } 251 }
251 252
252 GrGlyph* glyph = fPool.alloc(); 253 GrGlyph* glyph = fPool.alloc();
253 #if SK_DISTANCEFIELD_FONTS 254 #if SK_DISTANCEFIELD_FONTS
254 // expand bounds to hold full distance field data 255 // expand bounds to hold full distance field data
255 if (fUseDistanceField) { 256 if (fUseDistanceField) {
256 bounds.fLeft -= DISTANCE_FIELD_PAD; 257 bounds.fLeft -= DISTANCE_FIELD_RANGE;
257 bounds.fRight += DISTANCE_FIELD_PAD; 258 bounds.fRight += DISTANCE_FIELD_RANGE;
258 bounds.fTop -= DISTANCE_FIELD_PAD; 259 bounds.fTop -= DISTANCE_FIELD_RANGE;
259 bounds.fBottom += DISTANCE_FIELD_PAD; 260 bounds.fBottom += DISTANCE_FIELD_RANGE;
260 } 261 }
261 #endif 262 #endif
262 glyph->init(packed, bounds); 263 glyph->init(packed, bounds);
263 fCache.insert(packed, glyph); 264 fCache.insert(packed, glyph);
264 return glyph; 265 return glyph;
265 } 266 }
266 267
267 void GrTextStrike::removePlot(const GrPlot* plot) { 268 void GrTextStrike::removePlot(const GrPlot* plot) {
268 SkTDArray<GrGlyph*>& glyphArray = fCache.getArray(); 269 SkTDArray<GrGlyph*>& glyphArray = fCache.getArray();
269 for (int i = 0; i < glyphArray.count(); ++i) { 270 for (int i = 0; i < glyphArray.count(); ++i) {
(...skipping 17 matching lines...) Expand all
287 SkASSERT(fCache.contains(glyph)); 288 SkASSERT(fCache.contains(glyph));
288 SkASSERT(NULL == glyph->fPlot); 289 SkASSERT(NULL == glyph->fPlot);
289 290
290 SkAutoRef ar(scaler); 291 SkAutoRef ar(scaler);
291 292
292 int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat); 293 int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat);
293 294
294 GrPlot* plot; 295 GrPlot* plot;
295 #if SK_DISTANCEFIELD_FONTS 296 #if SK_DISTANCEFIELD_FONTS
296 if (fUseDistanceField) { 297 if (fUseDistanceField) {
297 SkASSERT(1 == bytesPerPixel);
298
299 // we've already expanded the glyph dimensions to match the final size 298 // we've already expanded the glyph dimensions to match the final size
300 // but must shrink back down to get the packed glyph data 299 // but must shrink back down to get the packed glyph data
301 int dfWidth = glyph->width(); 300 int dfWidth = glyph->width();
302 int dfHeight = glyph->height(); 301 int dfHeight = glyph->height();
303 int width = dfWidth - 2*DISTANCE_FIELD_PAD; 302 int width = dfWidth - 2*DISTANCE_FIELD_RANGE;
304 int height = dfHeight - 2*DISTANCE_FIELD_PAD; 303 int height = dfHeight - 2*DISTANCE_FIELD_RANGE;
305 size_t stride = width*bytesPerPixel; 304 int stride = width*bytesPerPixel;
306 305
307 size_t size = width * height * bytesPerPixel; 306 size_t size = width * height * bytesPerPixel;
308 SkAutoSMalloc<1024> storage(size); 307 SkAutoSMalloc<1024> storage(size);
309 if (!scaler->getPackedGlyphImage(glyph->fPackedID, width, height, stride , storage.get())) { 308 if (!scaler->getPackedGlyphImage(glyph->fPackedID, width, height, stride , storage.get())) {
310 return false; 309 return false;
311 } 310 }
312 311
313 // alloc storage for distance field glyph 312 // alloc storage for distance field glyph
314 size_t dfSize = dfWidth * dfHeight * bytesPerPixel; 313 size_t dfSize = dfWidth * dfHeight * bytesPerPixel;
315 SkAutoSMalloc<1024> dfStorage(dfSize); 314 SkAutoSMalloc<1024> dfStorage(dfSize);
315
316 if (1 == bytesPerPixel) {
317 (void) SkGenerateDistanceFieldFromImage((unsigned char*)dfStorage.ge t(),
318 (unsigned char*)storage.get( ),
319 width, height, DISTANCE_FIEL D_RANGE);
320 } else {
321 // TODO: Fix color emoji
322 // for now, copy glyph into distance field storage
323 // this is not correct, but it won't crash
324 sk_bzero(dfStorage.get(), dfSize);
325 unsigned char* ptr = (unsigned char*) storage.get();
326 unsigned char* dfPtr = (unsigned char*) dfStorage.get();
327 size_t dfStride = dfWidth*bytesPerPixel;
328 dfPtr += DISTANCE_FIELD_RANGE*dfStride;
329 dfPtr += DISTANCE_FIELD_RANGE*bytesPerPixel;
316 330
317 // copy glyph into distance field storage 331 for (int i = 0; i < height; ++i) {
318 sk_bzero(dfStorage.get(), dfSize); 332 memcpy(dfPtr, ptr, stride);
319 333
320 unsigned char* ptr = (unsigned char*) storage.get(); 334 dfPtr += dfStride;
321 unsigned char* dfPtr = (unsigned char*) dfStorage.get(); 335 ptr += stride;
322 size_t dfStride = dfWidth*bytesPerPixel;
323 dfPtr += DISTANCE_FIELD_PAD*dfStride;
324 dfPtr += DISTANCE_FIELD_PAD*bytesPerPixel;
325
326 for (int i = 0; i < height; ++i) {
327 memcpy(dfPtr, ptr, stride);
328
329 dfPtr += dfStride;
330 ptr += stride;
331 }
332
333 // generate distance field data
334 SkAutoSMalloc<1024> distXStorage(dfWidth*dfHeight*sizeof(short));
335 SkAutoSMalloc<1024> distYStorage(dfWidth*dfHeight*sizeof(short));
336 SkAutoSMalloc<1024> outerDistStorage(dfWidth*dfHeight*sizeof(double));
337 SkAutoSMalloc<1024> innerDistStorage(dfWidth*dfHeight*sizeof(double));
338 SkAutoSMalloc<1024> gxStorage(dfWidth*dfHeight*sizeof(double));
339 SkAutoSMalloc<1024> gyStorage(dfWidth*dfHeight*sizeof(double));
340
341 short* distX = (short*) distXStorage.get();
342 short* distY = (short*) distYStorage.get();
343 double* outerDist = (double*) outerDistStorage.get();
344 double* innerDist = (double*) innerDistStorage.get();
345 double* gx = (double*) gxStorage.get();
346 double* gy = (double*) gyStorage.get();
347
348 dfPtr = (unsigned char*) dfStorage.get();
349 EDTAA::computegradient(dfPtr, dfWidth, dfHeight, gx, gy);
350 EDTAA::edtaa3(dfPtr, gx, gy, dfWidth, dfHeight, distX, distY, outerDist) ;
351
352 for (int i = 0; i < dfWidth*dfHeight; ++i) {
353 *dfPtr = 255 - *dfPtr;
354 dfPtr++;
355 }
356 dfPtr = (unsigned char*) dfStorage.get();
357 sk_bzero(gx, sizeof(double)*dfWidth*dfHeight);
358 sk_bzero(gy, sizeof(double)*dfWidth*dfHeight);
359 EDTAA::computegradient(dfPtr, dfWidth, dfHeight, gx, gy);
360 EDTAA::edtaa3(dfPtr, gx, gy, dfWidth, dfHeight, distX, distY, innerDist) ;
361
362 for (int i = 0; i < dfWidth*dfHeight; ++i) {
363 unsigned char val;
364 double outerval = outerDist[i];
365 if (outerval < 0.0) {
366 outerval = 0.0;
367 } 336 }
368 double innerval = innerDist[i];
369 if (innerval < 0.0) {
370 innerval = 0.0;
371 }
372 double dist = outerval - innerval;
373 if (dist <= -DISTANCE_FIELD_RANGE) {
374 val = 255;
375 } else if (dist > DISTANCE_FIELD_RANGE) {
376 val = 0;
377 } else {
378 val = (unsigned char)((DISTANCE_FIELD_RANGE-dist)*128.0/DISTANCE _FIELD_RANGE);
379 }
380 *dfPtr++ = val;
381 } 337 }
382 338
383 // copy to atlas 339 // copy to atlas
384 plot = fAtlasMgr->addToAtlas(&fAtlas, dfWidth, dfHeight, dfStorage.get() , 340 plot = fAtlasMgr->addToAtlas(&fAtlas, dfWidth, dfHeight, dfStorage.get() ,
385 &glyph->fAtlasLocation); 341 &glyph->fAtlasLocation);
386 342
387 } else { 343 } else {
388 #endif 344 #endif
389 size_t size = glyph->fBounds.area() * bytesPerPixel; 345 size_t size = glyph->fBounds.area() * bytesPerPixel;
390 SkAutoSMalloc<1024> storage(size); 346 SkAutoSMalloc<1024> storage(size);
(...skipping 11 matching lines...) Expand all
402 } 358 }
403 #endif 359 #endif
404 360
405 if (NULL == plot) { 361 if (NULL == plot) {
406 return false; 362 return false;
407 } 363 }
408 364
409 glyph->fPlot = plot; 365 glyph->fPlot = plot;
410 return true; 366 return true;
411 } 367 }
OLDNEW
« no previous file with comments | « src/core/SkDistanceFieldGen.cpp ('k') | third_party/edtaa/LICENSE » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698