1 2 /* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #include "SkScalerContext.h" 11 #include "SkColorPriv.h" 12 #include "SkDescriptor.h" 13 #include "SkDraw.h" 14 #include "SkFontHost.h" 15 #include "SkGlyph.h" 16 #include "SkMaskFilter.h" 17 #include "SkMaskGamma.h" 18 #include "SkOrderedReadBuffer.h" 19 #include "SkOrderedWriteBuffer.h" 20 #include "SkPathEffect.h" 21 #include "SkRasterizer.h" 22 #include "SkRasterClip.h" 23 #include "SkStroke.h" 24 #include "SkThread.h" 25 26 #ifdef SK_BUILD_FOR_ANDROID 27 #include "SkTypeface_android.h" 28 #endif 29 30 #define ComputeBWRowBytes(width) (((unsigned)(width) + 7) >> 3) 31 32 void SkGlyph::toMask(SkMask* mask) const { 33 SkASSERT(mask); 34 35 mask->fImage = (uint8_t*)fImage; 36 mask->fBounds.set(fLeft, fTop, fLeft + fWidth, fTop + fHeight); 37 mask->fRowBytes = this->rowBytes(); 38 mask->fFormat = static_cast<SkMask::Format>(fMaskFormat); 39 } 40 41 size_t SkGlyph::computeImageSize() const { 42 const size_t size = this->rowBytes() * fHeight; 43 44 switch (fMaskFormat) { 45 case SkMask::k3D_Format: 46 return 3 * size; 47 default: 48 return size; 49 } 50 } 51 52 void SkGlyph::zeroMetrics() { 53 fAdvanceX = 0; 54 fAdvanceY = 0; 55 fWidth = 0; 56 fHeight = 0; 57 fTop = 0; 58 fLeft = 0; 59 fRsbDelta = 0; 60 fLsbDelta = 0; 61 } 62 63 /////////////////////////////////////////////////////////////////////////////// 64 65 #ifdef SK_DEBUG 66 #define DUMP_RECx 67 #endif 68 69 static SkFlattenable* load_flattenable(const SkDescriptor* desc, uint32_t tag, 70 SkFlattenable::Type ft) { 71 SkFlattenable* obj = NULL; 72 uint32_t len; 73 const void* data = desc->findEntry(tag, &len); 74 75 if (data) { 76 SkOrderedReadBuffer buffer(data, len); 77 obj = buffer.readFlattenable(ft); 78 SkASSERT(buffer.offset() == buffer.size()); 79 } 80 return obj; 81 } 82 83 SkScalerContext::SkScalerContext(SkTypeface* typeface, const SkDescriptor* desc) 84 : fRec(*static_cast<const Rec*>(desc->findEntry(kRec_SkDescriptorTag, NULL))) 85 86 , fBaseGlyphCount(0) 87 , fTypeface(SkRef(typeface)) 88 , fPathEffect(static_cast<SkPathEffect*>(load_flattenable(desc, kPathEffect_SkDescriptorTag, 89 SkFlattenable::kSkPathEffect_Type))) 90 , fMaskFilter(static_cast<SkMaskFilter*>(load_flattenable(desc, kMaskFilter_SkDescriptorTag, 91 SkFlattenable::kSkMaskFilter_Type))) 92 , fRasterizer(static_cast<SkRasterizer*>(load_flattenable(desc, kRasterizer_SkDescriptorTag, 93 SkFlattenable::kSkRasterizer_Type))) 94 // Initialize based on our settings. Subclasses can also force this. 95 , fGenerateImageFromPath(fRec.fFrameWidth > 0 || fPathEffect != NULL || fRasterizer != NULL) 96 97 , fNextContext(NULL) 98 99 , fPreBlend(fMaskFilter ? SkMaskGamma::PreBlend() : SkScalerContext::GetMaskPreBlend(fRec)) 100 , fPreBlendForFilter(fMaskFilter ? SkScalerContext::GetMaskPreBlend(fRec) 101 : SkMaskGamma::PreBlend()) 102 { 103 #ifdef DUMP_REC 104 desc->assertChecksum(); 105 SkDebugf("SkScalarContext checksum %x count %d length %d\n", 106 desc->getChecksum(), desc->getCount(), desc->getLength()); 107 SkDebugf(" textsize %g prescale %g preskew %g post [%g %g %g %g]\n", 108 rec->fTextSize, rec->fPreScaleX, rec->fPreSkewX, rec->fPost2x2[0][0], 109 rec->fPost2x2[0][1], rec->fPost2x2[1][0], rec->fPost2x2[1][1]); 110 SkDebugf(" frame %g miter %g hints %d framefill %d format %d join %d\n", 111 rec->fFrameWidth, rec->fMiterLimit, rec->fHints, rec->fFrameAndFill, 112 rec->fMaskFormat, rec->fStrokeJoin); 113 SkDebugf(" pathEffect %x maskFilter %x\n", 114 desc->findEntry(kPathEffect_SkDescriptorTag, NULL), 115 desc->findEntry(kMaskFilter_SkDescriptorTag, NULL)); 116 #endif 117 #ifdef SK_BUILD_FOR_ANDROID 118 uint32_t len; 119 const void* data = desc->findEntry(kAndroidOpts_SkDescriptorTag, &len); 120 if (data) { 121 SkOrderedReadBuffer buffer(data, len); 122 fPaintOptionsAndroid.unflatten(buffer); 123 SkASSERT(buffer.offset() == buffer.size()); 124 } 125 #endif 126 } 127 128 SkScalerContext::~SkScalerContext() { 129 SkDELETE(fNextContext); 130 131 SkSafeUnref(fPathEffect); 132 SkSafeUnref(fMaskFilter); 133 SkSafeUnref(fRasterizer); 134 } 135 136 // Return the context associated with the next logical typeface, or NULL if 137 // there are no more entries in the fallback chain. 138 SkScalerContext* SkScalerContext::allocNextContext() const { 139 #ifdef SK_BUILD_FOR_ANDROID 140 SkTypeface* newFace = SkAndroidNextLogicalTypeface(fRec.fFontID, 141 fRec.fOrigFontID, 142 fPaintOptionsAndroid); 143 if (0 == newFace) { 144 return NULL; 145 } 146 147 SkAutoTUnref<SkTypeface> aur(newFace); 148 uint32_t newFontID = newFace->uniqueID(); 149 150 SkOrderedWriteBuffer androidBuffer(128); 151 fPaintOptionsAndroid.flatten(androidBuffer); 152 153 SkAutoDescriptor ad(sizeof(fRec) + androidBuffer.size() + SkDescriptor::ComputeOverhead(2)); 154 SkDescriptor* desc = ad.getDesc(); 155 156 desc->init(); 157 SkScalerContext::Rec* newRec = 158 (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag, 159 sizeof(fRec), &fRec); 160 androidBuffer.writeToMemory(desc->addEntry(kAndroidOpts_SkDescriptorTag, 161 androidBuffer.size(), NULL)); 162 163 newRec->fFontID = newFontID; 164 desc->computeChecksum(); 165 166 return newFace->createScalerContext(desc); 167 #else 168 return NULL; 169 #endif 170 } 171 172 /* Return the next context, creating it if its not already created, but return 173 NULL if the fonthost says there are no more fonts to fallback to. 174 */ 175 SkScalerContext* SkScalerContext::getNextContext() { 176 SkScalerContext* next = fNextContext; 177 // if next is null, then either it isn't cached yet, or we're at the 178 // end of our possible chain 179 if (NULL == next) { 180 next = this->allocNextContext(); 181 if (NULL == next) { 182 return NULL; 183 } 184 // next's base is our base + our local count 185 next->setBaseGlyphCount(fBaseGlyphCount + this->getGlyphCount()); 186 // cache the answer 187 fNextContext = next; 188 } 189 return next; 190 } 191 192 SkScalerContext* SkScalerContext::getGlyphContext(const SkGlyph& glyph) { 193 unsigned glyphID = glyph.getGlyphID(); 194 SkScalerContext* ctx = this; 195 for (;;) { 196 unsigned count = ctx->getGlyphCount(); 197 if (glyphID < count) { 198 break; 199 } 200 glyphID -= count; 201 ctx = ctx->getNextContext(); 202 if (NULL == ctx) { 203 // SkDebugf("--- no context for glyph %x\n", glyph.getGlyphID()); 204 // just return the original context (this) 205 return this; 206 } 207 } 208 return ctx; 209 } 210 211 SkScalerContext* SkScalerContext::getContextFromChar(SkUnichar uni, 212 uint16_t* glyphID) { 213 SkScalerContext* ctx = this; 214 for (;;) { 215 const uint16_t glyph = ctx->generateCharToGlyph(uni); 216 if (glyph) { 217 if (NULL != glyphID) { 218 *glyphID = glyph; 219 } 220 break; // found it 221 } 222 ctx = ctx->getNextContext(); 223 if (NULL == ctx) { 224 return NULL; 225 } 226 } 227 return ctx; 228 } 229 230 #ifdef SK_BUILD_FOR_ANDROID 231 SkFontID SkScalerContext::findTypefaceIdForChar(SkUnichar uni) { 232 SkScalerContext* ctx = this->getContextFromChar(uni, NULL); 233 if (NULL != ctx) { 234 return ctx->fRec.fFontID; 235 } else { 236 return 0; 237 } 238 } 239 240 /* This loops through all available fallback contexts (if needed) until it 241 finds some context that can handle the unichar and return it. 242 243 As this is somewhat expensive operation, it should only be done on the first 244 char of a run. 245 */ 246 unsigned SkScalerContext::getBaseGlyphCount(SkUnichar uni) { 247 SkScalerContext* ctx = this->getContextFromChar(uni, NULL); 248 if (NULL != ctx) { 249 return ctx->fBaseGlyphCount; 250 } else { 251 SkDEBUGF(("--- no context for char %x\n", uni)); 252 return this->fBaseGlyphCount; 253 } 254 } 255 #endif 256 257 /* This loops through all available fallback contexts (if needed) until it 258 finds some context that can handle the unichar. If all fail, returns 0 259 */ 260 uint16_t SkScalerContext::charToGlyphID(SkUnichar uni) { 261 262 uint16_t tempID; 263 SkScalerContext* ctx = this->getContextFromChar(uni, &tempID); 264 if (NULL == ctx) { 265 return 0; // no more contexts, return missing glyph 266 } 267 // add the ctx's base, making glyphID unique for chain of contexts 268 unsigned glyphID = tempID + ctx->fBaseGlyphCount; 269 // check for overflow of 16bits, since our glyphID cannot exceed that 270 if (glyphID > 0xFFFF) { 271 glyphID = 0; 272 } 273 return SkToU16(glyphID); 274 } 275 276 SkUnichar SkScalerContext::glyphIDToChar(uint16_t glyphID) { 277 SkScalerContext* ctx = this; 278 unsigned rangeEnd = 0; 279 do { 280 unsigned rangeStart = rangeEnd; 281 282 rangeEnd += ctx->getGlyphCount(); 283 if (rangeStart <= glyphID && glyphID < rangeEnd) { 284 return ctx->generateGlyphToChar(glyphID - rangeStart); 285 } 286 ctx = ctx->getNextContext(); 287 } while (NULL != ctx); 288 return 0; 289 } 290 291 void SkScalerContext::getAdvance(SkGlyph* glyph) { 292 // mark us as just having a valid advance 293 glyph->fMaskFormat = MASK_FORMAT_JUST_ADVANCE; 294 // we mark the format before making the call, in case the impl 295 // internally ends up calling its generateMetrics, which is OK 296 // albeit slower than strictly necessary 297 this->getGlyphContext(*glyph)->generateAdvance(glyph); 298 } 299 300 void SkScalerContext::getMetrics(SkGlyph* glyph) { 301 this->getGlyphContext(*glyph)->generateMetrics(glyph); 302 303 // for now we have separate cache entries for devkerning on and off 304 // in the future we might share caches, but make our measure/draw 305 // code make the distinction. Thus we zap the values if the caller 306 // has not asked for them. 307 if ((fRec.fFlags & SkScalerContext::kDevKernText_Flag) == 0) { 308 // no devkern, so zap the fields 309 glyph->fLsbDelta = glyph->fRsbDelta = 0; 310 } 311 312 // if either dimension is empty, zap the image bounds of the glyph 313 if (0 == glyph->fWidth || 0 == glyph->fHeight) { 314 glyph->fWidth = 0; 315 glyph->fHeight = 0; 316 glyph->fTop = 0; 317 glyph->fLeft = 0; 318 glyph->fMaskFormat = 0; 319 return; 320 } 321 322 if (fGenerateImageFromPath) { 323 SkPath devPath, fillPath; 324 SkMatrix fillToDevMatrix; 325 326 this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix); 327 328 if (fRasterizer) { 329 SkMask mask; 330 331 if (fRasterizer->rasterize(fillPath, fillToDevMatrix, NULL, 332 fMaskFilter, &mask, 333 SkMask::kJustComputeBounds_CreateMode)) { 334 glyph->fLeft = mask.fBounds.fLeft; 335 glyph->fTop = mask.fBounds.fTop; 336 glyph->fWidth = SkToU16(mask.fBounds.width()); 337 glyph->fHeight = SkToU16(mask.fBounds.height()); 338 } else { 339 goto SK_ERROR; 340 } 341 } else { 342 // just use devPath 343 SkIRect ir; 344 devPath.getBounds().roundOut(&ir); 345 346 if (ir.isEmpty() || !ir.is16Bit()) { 347 goto SK_ERROR; 348 } 349 glyph->fLeft = ir.fLeft; 350 glyph->fTop = ir.fTop; 351 glyph->fWidth = SkToU16(ir.width()); 352 glyph->fHeight = SkToU16(ir.height()); 353 354 if (glyph->fWidth > 0) { 355 switch (fRec.fMaskFormat) { 356 case SkMask::kLCD16_Format: 357 case SkMask::kLCD32_Format: 358 glyph->fWidth += 2; 359 glyph->fLeft -= 1; 360 break; 361 default: 362 break; 363 } 364 } 365 } 366 } 367 368 if (SkMask::kARGB32_Format != glyph->fMaskFormat) { 369 glyph->fMaskFormat = fRec.fMaskFormat; 370 } 371 372 // If we are going to create the mask, then we cannot keep the color 373 if ((fGenerateImageFromPath || fMaskFilter) && 374 SkMask::kARGB32_Format == glyph->fMaskFormat) { 375 glyph->fMaskFormat = SkMask::kA8_Format; 376 } 377 378 if (fMaskFilter) { 379 SkMask src, dst; 380 SkMatrix matrix; 381 382 glyph->toMask(&src); 383 fRec.getMatrixFrom2x2(&matrix); 384 385 src.fImage = NULL; // only want the bounds from the filter 386 if (fMaskFilter->filterMask(&dst, src, matrix, NULL)) { 387 if (dst.fBounds.isEmpty() || !dst.fBounds.is16Bit()) { 388 goto SK_ERROR; 389 } 390 SkASSERT(dst.fImage == NULL); 391 glyph->fLeft = dst.fBounds.fLeft; 392 glyph->fTop = dst.fBounds.fTop; 393 glyph->fWidth = SkToU16(dst.fBounds.width()); 394 glyph->fHeight = SkToU16(dst.fBounds.height()); 395 glyph->fMaskFormat = dst.fFormat; 396 } 397 } 398 return; 399 400 SK_ERROR: 401 // draw nothing 'cause we failed 402 glyph->fLeft = 0; 403 glyph->fTop = 0; 404 glyph->fWidth = 0; 405 glyph->fHeight = 0; 406 // put a valid value here, in case it was earlier set to 407 // MASK_FORMAT_JUST_ADVANCE 408 glyph->fMaskFormat = fRec.fMaskFormat; 409 } 410 411 #define SK_SHOW_TEXT_BLIT_COVERAGE 0 412 413 static void applyLUTToA8Mask(const SkMask& mask, const uint8_t* lut) { 414 uint8_t* SK_RESTRICT dst = (uint8_t*)mask.fImage; 415 unsigned rowBytes = mask.fRowBytes; 416 417 for (int y = mask.fBounds.height() - 1; y >= 0; --y) { 418 for (int x = mask.fBounds.width() - 1; x >= 0; --x) { 419 dst[x] = lut[dst[x]]; 420 } 421 dst += rowBytes; 422 } 423 } 424 425 template<bool APPLY_PREBLEND> 426 static void pack4xHToLCD16(const SkBitmap& src, const SkMask& dst, 427 const SkMaskGamma::PreBlend& maskPreBlend) { 428 #define SAMPLES_PER_PIXEL 4 429 #define LCD_PER_PIXEL 3 430 SkASSERT(SkBitmap::kA8_Config == src.config()); 431 SkASSERT(SkMask::kLCD16_Format == dst.fFormat); 432 433 const int sample_width = src.width(); 434 const int height = src.height(); 435 436 uint16_t* dstP = (uint16_t*)dst.fImage; 437 size_t dstRB = dst.fRowBytes; 438 // An N tap FIR is defined by 439 // out[n] = coeff[0]*x[n] + coeff[1]*x[n-1] + ... + coeff[N]*x[n-N] 440 // or 441 // out[n] = sum(i, 0, N, coeff[i]*x[n-i]) 442 443 // The strategy is to use one FIR (different coefficients) for each of r, g, and b. 444 // This means using every 4th FIR output value of each FIR and discarding the rest. 445 // The FIRs are aligned, and the coefficients reach 5 samples to each side of their 'center'. 446 // (For r and b this is technically incorrect, but the coeffs outside round to zero anyway.) 447 448 // These are in some fixed point repesentation. 449 // Adding up to more than one simulates ink spread. 450 // For implementation reasons, these should never add up to more than two. 451 452 // Coefficients determined by a gausian where 5 samples = 3 std deviations (0x110 'contrast'). 453 // Calculated using tools/generate_fir_coeff.py 454 // With this one almost no fringing is ever seen, but it is imperceptibly blurry. 455 // The lcd smoothed text is almost imperceptibly different from gray, 456 // but is still sharper on small stems and small rounded corners than gray. 457 // This also seems to be about as wide as one can get and only have a three pixel kernel. 458 // TODO: caculate these at runtime so parameters can be adjusted (esp contrast). 459 static const unsigned int coefficients[LCD_PER_PIXEL][SAMPLES_PER_PIXEL*3] = { 460 //The red subpixel is centered inside the first sample (at 1/6 pixel), and is shifted. 461 { 0x03, 0x0b, 0x1c, 0x33, 0x40, 0x39, 0x24, 0x10, 0x05, 0x01, 0x00, 0x00, }, 462 //The green subpixel is centered between two samples (at 1/2 pixel), so is symetric 463 { 0x00, 0x02, 0x08, 0x16, 0x2b, 0x3d, 0x3d, 0x2b, 0x16, 0x08, 0x02, 0x00, }, 464 //The blue subpixel is centered inside the last sample (at 5/6 pixel), and is shifted. 465 { 0x00, 0x00, 0x01, 0x05, 0x10, 0x24, 0x39, 0x40, 0x33, 0x1c, 0x0b, 0x03, }, 466 }; 467 468 for (int y = 0; y < height; ++y) { 469 const uint8_t* srcP = src.getAddr8(0, y); 470 471 // TODO: this fir filter implementation is straight forward, but slow. 472 // It should be possible to make it much faster. 473 for (int sample_x = -4, pixel_x = 0; sample_x < sample_width + 4; sample_x += 4, ++pixel_x) { 474 int fir[LCD_PER_PIXEL] = { 0 }; 475 for (int sample_index = SkMax32(0, sample_x - 4), coeff_index = sample_index - (sample_x - 4) 476 ; sample_index < SkMin32(sample_x + 8, sample_width) 477 ; ++sample_index, ++coeff_index) 478 { 479 int sample_value = srcP[sample_index]; 480 for (int subpxl_index = 0; subpxl_index < LCD_PER_PIXEL; ++subpxl_index) { 481 fir[subpxl_index] += coefficients[subpxl_index][coeff_index] * sample_value; 482 } 483 } 484 for (int subpxl_index = 0; subpxl_index < LCD_PER_PIXEL; ++subpxl_index) { 485 fir[subpxl_index] /= 0x100; 486 fir[subpxl_index] = SkMin32(fir[subpxl_index], 255); 487 } 488 489 U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(fir[0], maskPreBlend.fR); 490 U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(fir[1], maskPreBlend.fG); 491 U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(fir[2], maskPreBlend.fB); 492 #if SK_SHOW_TEXT_BLIT_COVERAGE 493 r = SkMax32(r, 10); g = SkMax32(g, 10); b = SkMax32(b, 10); 494 #endif 495 dstP[pixel_x] = SkPack888ToRGB16(r, g, b); 496 } 497 dstP = (uint16_t*)((char*)dstP + dstRB); 498 } 499 } 500 501 template<bool APPLY_PREBLEND> 502 static void pack4xHToLCD32(const SkBitmap& src, const SkMask& dst, 503 const SkMaskGamma::PreBlend& maskPreBlend) { 504 SkASSERT(SkBitmap::kA8_Config == src.config()); 505 SkASSERT(SkMask::kLCD32_Format == dst.fFormat); 506 507 const int width = dst.fBounds.width(); 508 const int height = dst.fBounds.height(); 509 SkPMColor* dstP = (SkPMColor*)dst.fImage; 510 size_t dstRB = dst.fRowBytes; 511 512 for (int y = 0; y < height; ++y) { 513 const uint8_t* srcP = src.getAddr8(0, y); 514 515 // TODO: need to use fir filter here as well. 516 for (int x = 0; x < width; ++x) { 517 U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(*srcP++, maskPreBlend.fR); 518 U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(*srcP++, maskPreBlend.fG); 519 U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(*srcP++, maskPreBlend.fB); 520 dstP[x] = SkPackARGB32(0xFF, r, g, b); 521 } 522 dstP = (SkPMColor*)((char*)dstP + dstRB); 523 } 524 } 525 526 static inline int convert_8_to_1(unsigned byte) { 527 SkASSERT(byte <= 0xFF); 528 return byte >> 7; 529 } 530 531 static uint8_t pack_8_to_1(const uint8_t alpha[8]) { 532 unsigned bits = 0; 533 for (int i = 0; i < 8; ++i) { 534 bits <<= 1; 535 bits |= convert_8_to_1(alpha[i]); 536 } 537 return SkToU8(bits); 538 } 539 540 static void packA8ToA1(const SkMask& mask, const uint8_t* src, size_t srcRB) { 541 const int height = mask.fBounds.height(); 542 const int width = mask.fBounds.width(); 543 const int octs = width >> 3; 544 const int leftOverBits = width & 7; 545 546 uint8_t* dst = mask.fImage; 547 const int dstPad = mask.fRowBytes - SkAlign8(width)/8; 548 SkASSERT(dstPad >= 0); 549 550 const int srcPad = srcRB - width; 551 SkASSERT(srcPad >= 0); 552 553 for (int y = 0; y < height; ++y) { 554 for (int i = 0; i < octs; ++i) { 555 *dst++ = pack_8_to_1(src); 556 src += 8; 557 } 558 if (leftOverBits > 0) { 559 unsigned bits = 0; 560 int shift = 7; 561 for (int i = 0; i < leftOverBits; ++i, --shift) { 562 bits |= convert_8_to_1(*src++) << shift; 563 } 564 *dst++ = bits; 565 } 566 src += srcPad; 567 dst += dstPad; 568 } 569 } 570 571 static void generateMask(const SkMask& mask, const SkPath& path, 572 const SkMaskGamma::PreBlend& maskPreBlend) { 573 SkPaint paint; 574 575 int srcW = mask.fBounds.width(); 576 int srcH = mask.fBounds.height(); 577 int dstW = srcW; 578 int dstH = srcH; 579 int dstRB = mask.fRowBytes; 580 581 SkMatrix matrix; 582 matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft), 583 -SkIntToScalar(mask.fBounds.fTop)); 584 585 SkBitmap::Config config = SkBitmap::kA8_Config; 586 paint.setAntiAlias(SkMask::kBW_Format != mask.fFormat); 587 switch (mask.fFormat) { 588 case SkMask::kBW_Format: 589 dstRB = 0; // signals we need a copy 590 break; 591 case SkMask::kA8_Format: 592 break; 593 case SkMask::kLCD16_Format: 594 case SkMask::kLCD32_Format: 595 // TODO: trigger off LCD orientation 596 dstW = 4*dstW - 8; 597 matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1), 598 -SkIntToScalar(mask.fBounds.fTop)); 599 matrix.postScale(SkIntToScalar(4), SK_Scalar1); 600 dstRB = 0; // signals we need a copy 601 break; 602 default: 603 SkDEBUGFAIL("unexpected mask format"); 604 } 605 606 SkRasterClip clip; 607 clip.setRect(SkIRect::MakeWH(dstW, dstH)); 608 609 SkBitmap bm; 610 bm.setConfig(config, dstW, dstH, dstRB); 611 612 if (0 == dstRB) { 613 if (!bm.allocPixels()) { 614 // can't allocate offscreen, so empty the mask and return 615 sk_bzero(mask.fImage, mask.computeImageSize()); 616 return; 617 } 618 bm.lockPixels(); 619 } else { 620 bm.setPixels(mask.fImage); 621 } 622 sk_bzero(bm.getPixels(), bm.getSafeSize()); 623 624 SkDraw draw; 625 draw.fRC = &clip; 626 draw.fClip = &clip.bwRgn(); 627 draw.fMatrix = &matrix; 628 draw.fBitmap = &bm; 629 draw.drawPath(path, paint); 630 631 switch (mask.fFormat) { 632 case SkMask::kBW_Format: 633 packA8ToA1(mask, bm.getAddr8(0, 0), bm.rowBytes()); 634 break; 635 case SkMask::kA8_Format: 636 if (maskPreBlend.isApplicable()) { 637 applyLUTToA8Mask(mask, maskPreBlend.fG); 638 } 639 break; 640 case SkMask::kLCD16_Format: 641 if (maskPreBlend.isApplicable()) { 642 pack4xHToLCD16<true>(bm, mask, maskPreBlend); 643 } else { 644 pack4xHToLCD16<false>(bm, mask, maskPreBlend); 645 } 646 break; 647 case SkMask::kLCD32_Format: 648 if (maskPreBlend.isApplicable()) { 649 pack4xHToLCD32<true>(bm, mask, maskPreBlend); 650 } else { 651 pack4xHToLCD32<false>(bm, mask, maskPreBlend); 652 } 653 break; 654 default: 655 break; 656 } 657 } 658 659 static void extract_alpha(const SkMask& dst, 660 const SkPMColor* srcRow, size_t srcRB) { 661 int width = dst.fBounds.width(); 662 int height = dst.fBounds.height(); 663 int dstRB = dst.fRowBytes; 664 uint8_t* dstRow = dst.fImage; 665 666 for (int y = 0; y < height; ++y) { 667 for (int x = 0; x < width; ++x) { 668 dstRow[x] = SkGetPackedA32(srcRow[x]); 669 } 670 // zero any padding on each row 671 for (int x = width; x < dstRB; ++x) { 672 dstRow[x] = 0; 673 } 674 dstRow += dstRB; 675 srcRow = (const SkPMColor*)((const char*)srcRow + srcRB); 676 } 677 } 678 679 void SkScalerContext::getImage(const SkGlyph& origGlyph) { 680 const SkGlyph* glyph = &origGlyph; 681 SkGlyph tmpGlyph; 682 683 // in case we need to call generateImage on a mask-format that is different 684 // (i.e. larger) than what our caller allocated by looking at origGlyph. 685 SkAutoMalloc tmpGlyphImageStorage; 686 687 // If we are going to draw-from-path, then we cannot generate color, since 688 // the path only makes a mask. This case should have been caught up in 689 // generateMetrics(). 690 SkASSERT(!fGenerateImageFromPath || 691 SkMask::kARGB32_Format != origGlyph.fMaskFormat); 692 693 if (fMaskFilter) { // restore the prefilter bounds 694 tmpGlyph.init(origGlyph.fID); 695 696 // need the original bounds, sans our maskfilter 697 SkMaskFilter* mf = fMaskFilter; 698 fMaskFilter = NULL; // temp disable 699 this->getMetrics(&tmpGlyph); 700 fMaskFilter = mf; // restore 701 702 // we need the prefilter bounds to be <= filter bounds 703 SkASSERT(tmpGlyph.fWidth <= origGlyph.fWidth); 704 SkASSERT(tmpGlyph.fHeight <= origGlyph.fHeight); 705 706 if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat) { 707 tmpGlyph.fImage = origGlyph.fImage; 708 } else { 709 tmpGlyphImageStorage.reset(tmpGlyph.computeImageSize()); 710 tmpGlyph.fImage = tmpGlyphImageStorage.get(); 711 } 712 glyph = &tmpGlyph; 713 } 714 715 if (fGenerateImageFromPath) { 716 SkPath devPath, fillPath; 717 SkMatrix fillToDevMatrix; 718 SkMask mask; 719 720 this->internalGetPath(*glyph, &fillPath, &devPath, &fillToDevMatrix); 721 glyph->toMask(&mask); 722 723 if (fRasterizer) { 724 mask.fFormat = SkMask::kA8_Format; 725 sk_bzero(glyph->fImage, mask.computeImageSize()); 726 727 if (!fRasterizer->rasterize(fillPath, fillToDevMatrix, NULL, 728 fMaskFilter, &mask, 729 SkMask::kJustRenderImage_CreateMode)) { 730 return; 731 } 732 if (fPreBlend.isApplicable()) { 733 applyLUTToA8Mask(mask, fPreBlend.fG); 734 } 735 } else { 736 SkASSERT(SkMask::kARGB32_Format != mask.fFormat); 737 generateMask(mask, devPath, fPreBlend); 738 } 739 } else { 740 this->getGlyphContext(*glyph)->generateImage(*glyph); 741 } 742 743 if (fMaskFilter) { 744 SkMask srcM, dstM; 745 SkMatrix matrix; 746 747 // the src glyph image shouldn't be 3D 748 SkASSERT(SkMask::k3D_Format != glyph->fMaskFormat); 749 750 SkAutoSMalloc<32*32> a8storage; 751 glyph->toMask(&srcM); 752 if (SkMask::kARGB32_Format == srcM.fFormat) { 753 // now we need to extract the alpha-channel from the glyph's image 754 // and copy it into a temp buffer, and then point srcM at that temp. 755 srcM.fFormat = SkMask::kA8_Format; 756 srcM.fRowBytes = SkAlign4(srcM.fBounds.width()); 757 size_t size = srcM.computeImageSize(); 758 a8storage.reset(size); 759 srcM.fImage = (uint8_t*)a8storage.get(); 760 extract_alpha(srcM, 761 (const SkPMColor*)glyph->fImage, glyph->rowBytes()); 762 } 763 764 fRec.getMatrixFrom2x2(&matrix); 765 766 if (fMaskFilter->filterMask(&dstM, srcM, matrix, NULL)) { 767 int width = SkFastMin32(origGlyph.fWidth, dstM.fBounds.width()); 768 int height = SkFastMin32(origGlyph.fHeight, dstM.fBounds.height()); 769 int dstRB = origGlyph.rowBytes(); 770 int srcRB = dstM.fRowBytes; 771 772 const uint8_t* src = (const uint8_t*)dstM.fImage; 773 uint8_t* dst = (uint8_t*)origGlyph.fImage; 774 775 if (SkMask::k3D_Format == dstM.fFormat) { 776 // we have to copy 3 times as much 777 height *= 3; 778 } 779 780 // clean out our glyph, since it may be larger than dstM 781 //sk_bzero(dst, height * dstRB); 782 783 while (--height >= 0) { 784 memcpy(dst, src, width); 785 src += srcRB; 786 dst += dstRB; 787 } 788 SkMask::FreeImage(dstM.fImage); 789 790 if (fPreBlendForFilter.isApplicable()) { 791 applyLUTToA8Mask(srcM, fPreBlendForFilter.fG); 792 } 793 } 794 } 795 } 796 797 void SkScalerContext::getPath(const SkGlyph& glyph, SkPath* path) { 798 this->internalGetPath(glyph, NULL, path, NULL); 799 } 800 801 void SkScalerContext::getFontMetrics(SkPaint::FontMetrics* fm) { 802 // All of this complexity should go away when we change generateFontMetrics 803 // to just take one parameter (since it knows if it is vertical or not) 804 SkPaint::FontMetrics* mx = NULL; 805 SkPaint::FontMetrics* my = NULL; 806 if (fRec.fFlags & kVertical_Flag) { 807 mx = fm; 808 } else { 809 my = fm; 810 } 811 this->generateFontMetrics(mx, my); 812 } 813 814 SkUnichar SkScalerContext::generateGlyphToChar(uint16_t glyph) { 815 return 0; 816 } 817 818 /////////////////////////////////////////////////////////////////////////////// 819 820 void SkScalerContext::internalGetPath(const SkGlyph& glyph, SkPath* fillPath, 821 SkPath* devPath, SkMatrix* fillToDevMatrix) { 822 SkPath path; 823 824 this->getGlyphContext(glyph)->generatePath(glyph, &path); 825 826 if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) { 827 SkFixed dx = glyph.getSubXFixed(); 828 SkFixed dy = glyph.getSubYFixed(); 829 if (dx | dy) { 830 path.offset(SkFixedToScalar(dx), SkFixedToScalar(dy)); 831 } 832 } 833 834 if (fRec.fFrameWidth > 0 || fPathEffect != NULL) { 835 // need the path in user-space, with only the point-size applied 836 // so that our stroking and effects will operate the same way they 837 // would if the user had extracted the path themself, and then 838 // called drawPath 839 SkPath localPath; 840 SkMatrix matrix, inverse; 841 842 fRec.getMatrixFrom2x2(&matrix); 843 if (!matrix.invert(&inverse)) { 844 // assume fillPath and devPath are already empty. 845 return; 846 } 847 path.transform(inverse, &localPath); 848 // now localPath is only affected by the paint settings, and not the canvas matrix 849 850 SkStrokeRec rec(SkStrokeRec::kFill_InitStyle); 851 852 if (fRec.fFrameWidth > 0) { 853 rec.setStrokeStyle(fRec.fFrameWidth, 854 SkToBool(fRec.fFlags & kFrameAndFill_Flag)); 855 // glyphs are always closed contours, so cap type is ignored, 856 // so we just pass something. 857 rec.setStrokeParams(SkPaint::kButt_Cap, 858 (SkPaint::Join)fRec.fStrokeJoin, 859 fRec.fMiterLimit); 860 } 861 862 if (fPathEffect) { 863 SkPath effectPath; 864 if (fPathEffect->filterPath(&effectPath, localPath, &rec, NULL)) { 865 localPath.swap(effectPath); 866 } 867 } 868 869 if (rec.needToApply()) { 870 SkPath strokePath; 871 if (rec.applyToPath(&strokePath, localPath)) { 872 localPath.swap(strokePath); 873 } 874 } 875 876 // now return stuff to the caller 877 if (fillToDevMatrix) { 878 *fillToDevMatrix = matrix; 879 } 880 if (devPath) { 881 localPath.transform(matrix, devPath); 882 } 883 if (fillPath) { 884 fillPath->swap(localPath); 885 } 886 } else { // nothing tricky to do 887 if (fillToDevMatrix) { 888 fillToDevMatrix->reset(); 889 } 890 if (devPath) { 891 if (fillPath == NULL) { 892 devPath->swap(path); 893 } else { 894 *devPath = path; 895 } 896 } 897 898 if (fillPath) { 899 fillPath->swap(path); 900 } 901 } 902 903 if (devPath) { 904 devPath->updateBoundsCache(); 905 } 906 if (fillPath) { 907 fillPath->updateBoundsCache(); 908 } 909 } 910 911 912 void SkScalerContextRec::getMatrixFrom2x2(SkMatrix* dst) const { 913 dst->setAll(fPost2x2[0][0], fPost2x2[0][1], 0, 914 fPost2x2[1][0], fPost2x2[1][1], 0, 915 0, 0, SkScalarToPersp(SK_Scalar1)); 916 } 917 918 void SkScalerContextRec::getLocalMatrix(SkMatrix* m) const { 919 SkPaint::SetTextMatrix(m, fTextSize, fPreScaleX, fPreSkewX); 920 } 921 922 void SkScalerContextRec::getSingleMatrix(SkMatrix* m) const { 923 this->getLocalMatrix(m); 924 925 // now concat the device matrix 926 SkMatrix deviceMatrix; 927 this->getMatrixFrom2x2(&deviceMatrix); 928 m->postConcat(deviceMatrix); 929 } 930 931 SkAxisAlignment SkComputeAxisAlignmentForHText(const SkMatrix& matrix) { 932 SkASSERT(!matrix.hasPerspective()); 933 934 if (0 == matrix[SkMatrix::kMSkewY]) { 935 return kX_SkAxisAlignment; 936 } 937 if (0 == matrix[SkMatrix::kMScaleX]) { 938 return kY_SkAxisAlignment; 939 } 940 return kNone_SkAxisAlignment; 941 } 942 943 /////////////////////////////////////////////////////////////////////////////// 944 945 #include "SkFontHost.h" 946 947 class SkScalerContext_Empty : public SkScalerContext { 948 public: 949 SkScalerContext_Empty(SkTypeface* face, const SkDescriptor* desc) 950 : SkScalerContext(face, desc) {} 951 952 protected: 953 virtual unsigned generateGlyphCount() SK_OVERRIDE { 954 return 0; 955 } 956 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE { 957 return 0; 958 } 959 virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE { 960 glyph->zeroMetrics(); 961 } 962 virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE { 963 glyph->zeroMetrics(); 964 } 965 virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE {} 966 virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE {} 967 virtual void generateFontMetrics(SkPaint::FontMetrics* mx, 968 SkPaint::FontMetrics* my) SK_OVERRIDE { 969 if (mx) { 970 sk_bzero(mx, sizeof(*mx)); 971 } 972 if (my) { 973 sk_bzero(my, sizeof(*my)); 974 } 975 } 976 }; 977 978 extern SkScalerContext* SkCreateColorScalerContext(const SkDescriptor* desc); 979 980 SkScalerContext* SkTypeface::createScalerContext(const SkDescriptor* desc, 981 bool allowFailure) const { 982 SkScalerContext* c = this->onCreateScalerContext(desc); 983 984 if (!c && !allowFailure) { 985 c = SkNEW_ARGS(SkScalerContext_Empty, 986 (const_cast<SkTypeface*>(this), desc)); 987 } 988 return c; 989 } 990