| OLD | NEW |
| 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" |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 ++gDumpCount; | 207 ++gDumpCount; |
| 208 } | 208 } |
| 209 #endif | 209 #endif |
| 210 | 210 |
| 211 /////////////////////////////////////////////////////////////////////////////// | 211 /////////////////////////////////////////////////////////////////////////////// |
| 212 | 212 |
| 213 #ifdef SK_DEBUG | 213 #ifdef SK_DEBUG |
| 214 static int gCounter; | 214 static int gCounter; |
| 215 #endif | 215 #endif |
| 216 | 216 |
| 217 // this acts as the max magnitude for the distance field, | |
| 218 // as well as the pad we need around the glyph | |
| 219 #define DISTANCE_FIELD_RANGE 4 | |
| 220 | |
| 221 /* | 217 /* |
| 222 The text strike is specific to a given font/style/matrix setup, which is | 218 The text strike is specific to a given font/style/matrix setup, which is |
| 223 represented by the GrHostFontScaler object we are given in getGlyph(). | 219 represented by the GrHostFontScaler object we are given in getGlyph(). |
| 224 | 220 |
| 225 We map a 32bit glyphID to a GrGlyph record, which in turn points to a | 221 We map a 32bit glyphID to a GrGlyph record, which in turn points to a |
| 226 atlas and a position within that texture. | 222 atlas and a position within that texture. |
| 227 */ | 223 */ |
| 228 | 224 |
| 229 GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key, | 225 GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key, |
| 230 GrMaskFormat format, | 226 GrMaskFormat format, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 253 | 249 |
| 254 #ifdef SK_DEBUG | 250 #ifdef SK_DEBUG |
| 255 gCounter -= 1; | 251 gCounter -= 1; |
| 256 // GrPrintf("~GrTextStrike %p %d\n", this, gCounter); | 252 // GrPrintf("~GrTextStrike %p %d\n", this, gCounter); |
| 257 #endif | 253 #endif |
| 258 } | 254 } |
| 259 | 255 |
| 260 GrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed, | 256 GrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed, |
| 261 GrFontScaler* scaler) { | 257 GrFontScaler* scaler) { |
| 262 SkIRect bounds; | 258 SkIRect bounds; |
| 263 if (!scaler->getPackedGlyphBounds(packed, &bounds)) { | 259 if (fUseDistanceField) { |
| 264 return NULL; | 260 if (!scaler->getPackedGlyphDFBounds(packed, &bounds)) { |
| 261 return NULL; |
| 262 } |
| 263 } else { |
| 264 if (!scaler->getPackedGlyphBounds(packed, &bounds)) { |
| 265 return NULL; |
| 266 } |
| 265 } | 267 } |
| 266 | 268 |
| 267 GrGlyph* glyph = fPool.alloc(); | 269 GrGlyph* glyph = fPool.alloc(); |
| 268 // expand bounds to hold full distance field data | |
| 269 // + room for bilerp | |
| 270 int pad = DISTANCE_FIELD_RANGE+1; | |
| 271 if (fUseDistanceField) { | |
| 272 bounds.fLeft -= pad; | |
| 273 bounds.fRight += pad; | |
| 274 bounds.fTop -= pad; | |
| 275 bounds.fBottom += pad; | |
| 276 } | |
| 277 glyph->init(packed, bounds); | 270 glyph->init(packed, bounds); |
| 278 fCache.insert(packed, glyph); | 271 fCache.insert(packed, glyph); |
| 279 return glyph; | 272 return glyph; |
| 280 } | 273 } |
| 281 | 274 |
| 282 void GrTextStrike::removePlot(const GrPlot* plot) { | 275 void GrTextStrike::removePlot(const GrPlot* plot) { |
| 283 SkTDArray<GrGlyph*>& glyphArray = fCache.getArray(); | 276 SkTDArray<GrGlyph*>& glyphArray = fCache.getArray(); |
| 284 for (int i = 0; i < glyphArray.count(); ++i) { | 277 for (int i = 0; i < glyphArray.count(); ++i) { |
| 285 if (plot == glyphArray[i]->fPlot) { | 278 if (plot == glyphArray[i]->fPlot) { |
| 286 glyphArray[i]->fPlot = NULL; | 279 glyphArray[i]->fPlot = NULL; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 299 | 292 |
| 300 SkASSERT(glyph); | 293 SkASSERT(glyph); |
| 301 SkASSERT(scaler); | 294 SkASSERT(scaler); |
| 302 SkASSERT(fCache.contains(glyph)); | 295 SkASSERT(fCache.contains(glyph)); |
| 303 SkASSERT(NULL == glyph->fPlot); | 296 SkASSERT(NULL == glyph->fPlot); |
| 304 | 297 |
| 305 SkAutoRef ar(scaler); | 298 SkAutoRef ar(scaler); |
| 306 | 299 |
| 307 int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat); | 300 int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat); |
| 308 | 301 |
| 309 GrPlot* plot; | 302 size_t size = glyph->fBounds.area() * bytesPerPixel; |
| 303 SkAutoSMalloc<1024> storage(size); |
| 310 if (fUseDistanceField) { | 304 if (fUseDistanceField) { |
| 311 // we've already expanded the glyph dimensions to match the final size | 305 if (!scaler->getPackedGlyphDFImage(glyph->fPackedID, glyph->width(), |
| 312 // but must shrink back down to get the packed glyph data | 306 glyph->height(), |
| 313 int dfWidth = glyph->width(); | 307 storage.get())) { |
| 314 int dfHeight = glyph->height(); | |
| 315 int pad = DISTANCE_FIELD_RANGE+1; | |
| 316 int width = dfWidth - 2*pad; | |
| 317 int height = dfHeight - 2*pad; | |
| 318 int stride = width*bytesPerPixel; | |
| 319 | |
| 320 size_t size = width * height * bytesPerPixel; | |
| 321 SkAutoSMalloc<1024> storage(size); | |
| 322 if (!scaler->getPackedGlyphImage(glyph->fPackedID, width, height, stride
, storage.get())) { | |
| 323 return false; | 308 return false; |
| 324 } | 309 } |
| 325 | |
| 326 // alloc storage for distance field glyph | |
| 327 size_t dfSize = dfWidth * dfHeight * bytesPerPixel; | |
| 328 SkAutoSMalloc<1024> dfStorage(dfSize); | |
| 329 | |
| 330 if (1 == bytesPerPixel) { | |
| 331 (void) SkGenerateDistanceFieldFromImage((unsigned char*)dfStorage.ge
t(), | |
| 332 (unsigned char*)storage.get(
), | |
| 333 width, height, DISTANCE_FIEL
D_RANGE); | |
| 334 } else { | |
| 335 // distance fields should only be used to represent alpha masks | |
| 336 SkASSERT(false); | |
| 337 return false; | |
| 338 } | |
| 339 | |
| 340 // copy to atlas | |
| 341 plot = fAtlasMgr->addToAtlas(&fAtlas, dfWidth, dfHeight, dfStorage.get()
, | |
| 342 &glyph->fAtlasLocation); | |
| 343 | |
| 344 } else { | 310 } else { |
| 345 size_t size = glyph->fBounds.area() * bytesPerPixel; | |
| 346 SkAutoSMalloc<1024> storage(size); | |
| 347 if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(), | 311 if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(), |
| 348 glyph->height(), | 312 glyph->height(), |
| 349 glyph->width() * bytesPerPixel, | 313 glyph->width() * bytesPerPixel, |
| 350 storage.get())) { | 314 storage.get())) { |
| 351 return false; | 315 return false; |
| 352 } | 316 } |
| 317 } |
| 353 | 318 |
| 354 plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(), | 319 GrPlot* plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(), |
| 355 glyph->height(), storage.get(), | 320 glyph->height(), storage.get(), |
| 356 &glyph->fAtlasLocation); | 321 &glyph->fAtlasLocation); |
| 357 } | |
| 358 | 322 |
| 359 if (NULL == plot) { | 323 if (NULL == plot) { |
| 360 return false; | 324 return false; |
| 361 } | 325 } |
| 362 | 326 |
| 363 glyph->fPlot = plot; | 327 glyph->fPlot = plot; |
| 364 return true; | 328 return true; |
| 365 } | 329 } |
| OLD | NEW |