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

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: Replace magic number 32 with constant; fix comment in shader; fix Linux compiler error. Created 7 years, 1 month 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
« no previous file with comments | « src/gpu/GrTextStrike.h ('k') | src/gpu/GrTextStrike_impl.h » ('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
16 #include "edtaa3.h"
17 #endif
18
15 SK_DEFINE_INST_COUNT(GrFontScaler) 19 SK_DEFINE_INST_COUNT(GrFontScaler)
16 SK_DEFINE_INST_COUNT(GrKey) 20 SK_DEFINE_INST_COUNT(GrKey)
17 21
18 /////////////////////////////////////////////////////////////////////////////// 22 ///////////////////////////////////////////////////////////////////////////////
19 23
20 #define FONT_CACHE_STATS 0 24 #define FONT_CACHE_STATS 0
21 #if FONT_CACHE_STATS 25 #if FONT_CACHE_STATS
22 static int g_PurgeCount = 0; 26 static int g_PurgeCount = 0;
23 #endif 27 #endif
24 28
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 ++gDumpCount; 190 ++gDumpCount;
187 } 191 }
188 #endif 192 #endif
189 193
190 /////////////////////////////////////////////////////////////////////////////// 194 ///////////////////////////////////////////////////////////////////////////////
191 195
192 #ifdef SK_DEBUG 196 #ifdef SK_DEBUG
193 static int gCounter; 197 static int gCounter;
194 #endif 198 #endif
195 199
200 #if SK_DISTANCEFIELD_FONTS
201 #define DISTANCE_FIELD_PAD 4
202 #define DISTANCE_FIELD_RANGE (4.0)
203 #endif
204
196 /* 205 /*
197 The text strike is specific to a given font/style/matrix setup, which is 206 The text strike is specific to a given font/style/matrix setup, which is
198 represented by the GrHostFontScaler object we are given in getGlyph(). 207 represented by the GrHostFontScaler object we are given in getGlyph().
199 208
200 We map a 32bit glyphID to a GrGlyph record, which in turn points to a 209 We map a 32bit glyphID to a GrGlyph record, which in turn points to a
201 atlas and a position within that texture. 210 atlas and a position within that texture.
202 */ 211 */
203 212
204 GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key, 213 GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
205 GrMaskFormat format, 214 GrMaskFormat format,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 } 248 }
240 249
241 GrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed, 250 GrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed,
242 GrFontScaler* scaler) { 251 GrFontScaler* scaler) {
243 SkIRect bounds; 252 SkIRect bounds;
244 if (!scaler->getPackedGlyphBounds(packed, &bounds)) { 253 if (!scaler->getPackedGlyphBounds(packed, &bounds)) {
245 return NULL; 254 return NULL;
246 } 255 }
247 256
248 GrGlyph* glyph = fPool.alloc(); 257 GrGlyph* glyph = fPool.alloc();
258 #if SK_DISTANCEFIELD_FONTS
259 // expand bounds to hold full distance field data
260 if (fUseDistanceField) {
261 bounds.fLeft -= DISTANCE_FIELD_PAD;
262 bounds.fRight += DISTANCE_FIELD_PAD;
263 bounds.fTop -= DISTANCE_FIELD_PAD;
264 bounds.fBottom += DISTANCE_FIELD_PAD;
265 }
266 #endif
249 glyph->init(packed, bounds); 267 glyph->init(packed, bounds);
250 fCache.insert(packed, glyph); 268 fCache.insert(packed, glyph);
251 return glyph; 269 return glyph;
252 } 270 }
253 271
254 bool GrTextStrike::removeUnusedPlots() { 272 bool GrTextStrike::removeUnusedPlots() {
255 fCache.getArray().visitAll(invalidate_glyph); 273 fCache.getArray().visitAll(invalidate_glyph);
256 return fAtlasMgr->removeUnusedPlots(&fAtlas); 274 return fAtlasMgr->removeUnusedPlots(&fAtlas);
257 } 275 }
258 276
277
259 bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) { 278 bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
260 #if 0 // testing hack to force us to flush our cache often 279 #if 0 // testing hack to force us to flush our cache often
261 static int gCounter; 280 static int gCounter;
262 if ((++gCounter % 10) == 0) return false; 281 if ((++gCounter % 10) == 0) return false;
263 #endif 282 #endif
264 283
265 SkASSERT(glyph); 284 SkASSERT(glyph);
266 SkASSERT(scaler); 285 SkASSERT(scaler);
267 SkASSERT(fCache.contains(glyph)); 286 SkASSERT(fCache.contains(glyph));
268 SkASSERT(NULL == glyph->fPlot); 287 SkASSERT(NULL == glyph->fPlot);
269 288
270 SkAutoRef ar(scaler); 289 SkAutoRef ar(scaler);
271 290
272 int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat); 291 int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat);
273 size_t size = glyph->fBounds.area() * bytesPerPixel; 292
274 SkAutoSMalloc<1024> storage(size); 293 GrPlot* plot;
275 if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(), 294 #if SK_DISTANCEFIELD_FONTS
276 glyph->height(), 295 if (fUseDistanceField) {
277 glyph->width() * bytesPerPixel, 296 SkASSERT(1 == bytesPerPixel);
278 storage.get())) { 297
279 return false; 298 // we've already expanded the glyph dimensions to match the final size
299 // but must shrink back down to get the packed glyph data
300 int dfWidth = glyph->width();
301 int dfHeight = glyph->height();
302 int width = dfWidth - 2*DISTANCE_FIELD_PAD;
303 int height = dfHeight - 2*DISTANCE_FIELD_PAD;
304 size_t stride = width*bytesPerPixel;
305
306 size_t size = width * height * bytesPerPixel;
307 SkAutoSMalloc<1024> storage(size);
308 if (!scaler->getPackedGlyphImage(glyph->fPackedID, width, height, stride , storage.get())) {
309 return false;
310 }
311
312 // alloc storage for distance field glyph
313 size_t dfSize = dfWidth * dfHeight * bytesPerPixel;
314 SkAutoSMalloc<1024> dfStorage(dfSize);
315
316 // copy glyph into distance field storage
317 sk_bzero(dfStorage.get(), dfSize);
318
319 unsigned char* ptr = (unsigned char*) storage.get();
320 unsigned char* dfPtr = (unsigned char*) dfStorage.get();
321 size_t dfStride = dfWidth*bytesPerPixel;
322 dfPtr += DISTANCE_FIELD_PAD*dfStride;
323 dfPtr += DISTANCE_FIELD_PAD*bytesPerPixel;
324
325 for (int i = 0; i < height; ++i) {
326 memcpy(dfPtr, ptr, stride);
327
328 dfPtr += dfStride;
329 ptr += stride;
330 }
331
332 // generate distance field data
333 SkAutoSMalloc<1024> distXStorage(dfWidth*dfHeight*sizeof(short));
334 SkAutoSMalloc<1024> distYStorage(dfWidth*dfHeight*sizeof(short));
335 SkAutoSMalloc<1024> outerDistStorage(dfWidth*dfHeight*sizeof(double));
336 SkAutoSMalloc<1024> innerDistStorage(dfWidth*dfHeight*sizeof(double));
337 SkAutoSMalloc<1024> gxStorage(dfWidth*dfHeight*sizeof(double));
338 SkAutoSMalloc<1024> gyStorage(dfWidth*dfHeight*sizeof(double));
339
340 short* distX = (short*) distXStorage.get();
341 short* distY = (short*) distYStorage.get();
342 double* outerDist = (double*) outerDistStorage.get();
343 double* innerDist = (double*) innerDistStorage.get();
344 double* gx = (double*) gxStorage.get();
345 double* gy = (double*) gyStorage.get();
346
347 dfPtr = (unsigned char*) dfStorage.get();
348 EDTAA::computegradient(dfPtr, dfWidth, dfHeight, gx, gy);
349 EDTAA::edtaa3(dfPtr, gx, gy, dfWidth, dfHeight, distX, distY, outerDist) ;
350
351 for (int i = 0; i < dfWidth*dfHeight; ++i) {
352 *dfPtr = 255 - *dfPtr;
353 dfPtr++;
354 }
355 dfPtr = (unsigned char*) dfStorage.get();
356 sk_bzero(gx, sizeof(double)*dfWidth*dfHeight);
357 sk_bzero(gy, sizeof(double)*dfWidth*dfHeight);
358 EDTAA::computegradient(dfPtr, dfWidth, dfHeight, gx, gy);
359 EDTAA::edtaa3(dfPtr, gx, gy, dfWidth, dfHeight, distX, distY, innerDist) ;
360
361 for (int i = 0; i < dfWidth*dfHeight; ++i) {
362 unsigned char val;
363 double outerval = outerDist[i];
364 if (outerval < 0.0) {
365 outerval = 0.0;
366 }
367 double innerval = innerDist[i];
368 if (innerval < 0.0) {
369 innerval = 0.0;
370 }
371 double dist = outerval - innerval;
372 if (dist <= -DISTANCE_FIELD_RANGE) {
373 val = 255;
374 } else if (dist > DISTANCE_FIELD_RANGE) {
375 val = 0;
376 } else {
377 val = (unsigned char)((DISTANCE_FIELD_RANGE-dist)*128.0/DISTANCE _FIELD_RANGE);
378 }
379 *dfPtr++ = val;
380 }
381
382 // copy to atlas
383 plot = fAtlasMgr->addToAtlas(&fAtlas, dfWidth, dfHeight, dfStorage.get() ,
384 &glyph->fAtlasLocation);
385
386 } else {
387 #endif
388 size_t size = glyph->fBounds.area() * bytesPerPixel;
389 SkAutoSMalloc<1024> storage(size);
390 if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
391 glyph->height(),
392 glyph->width() * bytesPerPixel,
393 storage.get())) {
394 return false;
395 }
396
397 plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(),
398 glyph->height(), storage.get(),
399 &glyph->fAtlasLocation);
400 #if SK_DISTANCEFIELD_FONTS
280 } 401 }
402 #endif
281 403
282 GrPlot* plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(),
283 glyph->height(), storage.get(),
284 &glyph->fAtlasLocation);
285 if (NULL == plot) { 404 if (NULL == plot) {
286 return false; 405 return false;
287 } 406 }
288 407
289 glyph->fPlot = plot; 408 glyph->fPlot = plot;
290 return true; 409 return true;
291 } 410 }
411
OLDNEW
« no previous file with comments | « 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