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

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: Minor fixes for GrDistanceFieldTextContext. 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
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 GR_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 GR_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 GR_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 GR_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
robertphillips 2013/11/05 15:30:26 dfWidth/dfHeight?
jvanverth1 2013/11/05 17:09:22 Done.
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
robertphillips 2013/11/05 15:30:26 dfSize?
jvanverth1 2013/11/05 17:09:22 Done.
313 size_t dfsize = dfwidth * dfheight * bytesPerPixel;
314 SkAutoSMalloc<1024> dfstorage(dfsize);
315
316 // copy glyph into distance field storage
317 memset(dfstorage.get(), 0, dfsize);
bsalomon 2013/11/05 15:28:52 not a blocker, but there is an sk_bzero, not sure
jvanverth1 2013/11/05 17:09:22 Done.
318
319 unsigned char* ptr = (unsigned char*) storage.get();
robertphillips 2013/11/05 15:30:26 dfPtr?
jvanverth1 2013/11/05 17:09:22 Done.
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
robertphillips 2013/11/05 15:30:26 distX\distY? outerDist? some form of SkNEW? some s
jvanverth1 2013/11/05 17:09:22 Done.
333 short* distx = new short[dfwidth*dfheight];
bsalomon 2013/11/05 15:28:52 SkNEW(), SkDELETE()
jvanverth1 2013/11/05 17:09:22 Done.
334 short* disty = new short[dfwidth*dfheight];
335 double* outerdist = new double[dfwidth*dfheight];
336 double* gx = new double[dfwidth*dfheight];
337 double* gy = new double[dfwidth*dfheight];
338 dfptr = (unsigned char*) dfstorage.get();
robertphillips 2013/11/05 15:30:26 is it possible to namespace these guys to make it
339 computegradient(dfptr, dfwidth, dfheight, gx, gy);
340 edtaa3(dfptr, gx, gy, dfwidth, dfheight, distx, disty, outerdist);
341
342 for (int i = 0; i < dfwidth*dfheight; ++i) {
343 *dfptr++ = 255 - *dfptr;
344 }
345 double* innerdist = new double[dfwidth*dfheight];
346 dfptr = (unsigned char*) dfstorage.get();
347 memset(gx, 0, sizeof(double)*dfwidth*dfheight);
348 memset(gy, 0, sizeof(double)*dfwidth*dfheight);
349 computegradient(dfptr, dfwidth, dfheight, gx, gy);
350 edtaa3(dfptr, gx, gy, dfwidth, dfheight, distx, disty, innerdist);
351
352 for (int i = 0; i < dfwidth*dfheight; ++i) {
353 unsigned char val;
354 double outerval = outerdist[i];
robertphillips 2013/11/05 15:30:26 newlines on {}s?
jvanverth1 2013/11/05 17:09:22 Done.
355 if (outerval < 0.0) { outerval = 0.0; }
356 double innerval = innerdist[i];
357 if (innerval < 0.0) { innerval = 0.0; }
358 double dist = outerval - innerval;
359 if (dist <= -DISTANCE_FIELD_RANGE) {
360 val = 255;
361 } else if (dist > DISTANCE_FIELD_RANGE) {
362 val = 0;
363 } else {
364 val = (unsigned char)((DISTANCE_FIELD_RANGE-dist)*128.0/DISTANCE _FIELD_RANGE);
365 }
366 *dfptr++ = val;
367 }
368
369 delete [] distx;
370 delete [] disty;
371 delete [] innerdist;
372 delete [] outerdist;
373
374 // copy to atlas
375 plot = fAtlasMgr->addToAtlas(&fAtlas, dfwidth, dfheight, dfstorage.get() ,
robertphillips 2013/11/05 15:30:26 indent?
jvanverth1 2013/11/05 17:09:22 Done.
376 &glyph->fAtlasLocation);
377
378 } else {
379 #endif
380 size_t size = glyph->fBounds.area() * bytesPerPixel;
381 SkAutoSMalloc<1024> storage(size);
382 if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(),
383 glyph->height(),
384 glyph->width() * bytesPerPixel,
385 storage.get())) {
386 return false;
387 }
388
389 plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(), glyph->height(), s torage.get(),
robertphillips 2013/11/05 15:30:26 indent?
jvanverth1 2013/11/05 17:09:22 Done.
390 &glyph->fAtlasLocation);
391 #if GR_DISTANCEFIELD_FONTS
280 } 392 }
393 #endif
281 394
282 GrPlot* plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(),
283 glyph->height(), storage.get(),
284 &glyph->fAtlasLocation);
285 if (NULL == plot) { 395 if (NULL == plot) {
286 return false; 396 return false;
287 } 397 }
288 398
289 glyph->fPlot = plot; 399 glyph->fPlot = plot;
290 return true; 400 return true;
291 } 401 }
402
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698