OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006-2012 The Android Open Source Project | 2 * Copyright 2006-2012 The Android Open Source Project |
3 * Copyright 2012 Mozilla Foundation | 3 * Copyright 2012 Mozilla Foundation |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 case SkMask::kLCD16_Format: | 327 case SkMask::kLCD16_Format: |
328 return kAlpha_8_SkColorType; | 328 return kAlpha_8_SkColorType; |
329 case SkMask::kARGB32_Format: | 329 case SkMask::kARGB32_Format: |
330 return kN32_SkColorType; | 330 return kN32_SkColorType; |
331 default: | 331 default: |
332 SkDEBUGFAIL("unsupported destination SkBitmap::Config"); | 332 SkDEBUGFAIL("unsupported destination SkBitmap::Config"); |
333 return kAlpha_8_SkColorType; | 333 return kAlpha_8_SkColorType; |
334 } | 334 } |
335 } | 335 } |
336 | 336 |
337 void SkScalerContext_FreeType_Base::generateGlyphImage( | 337 void SkScalerContext_FreeType_Base::generateGlyphImage(FT_Face face, const SkGly
ph& glyph) { |
338 FT_Face face, | |
339 const SkGlyph& glyph, | |
340 const SkMatrix& bitmapTransform) | |
341 { | |
342 const bool doBGR = SkToBool(fRec.fFlags & SkScalerContext::kLCD_BGROrder_Fla
g); | 338 const bool doBGR = SkToBool(fRec.fFlags & SkScalerContext::kLCD_BGROrder_Fla
g); |
343 const bool doVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Fl
ag); | 339 const bool doVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Fl
ag); |
344 | 340 |
345 switch ( face->glyph->format ) { | 341 switch ( face->glyph->format ) { |
346 case FT_GLYPH_FORMAT_OUTLINE: { | 342 case FT_GLYPH_FORMAT_OUTLINE: { |
347 FT_Outline* outline = &face->glyph->outline; | 343 FT_Outline* outline = &face->glyph->outline; |
348 FT_BBox bbox; | 344 FT_BBox bbox; |
349 FT_Bitmap target; | 345 FT_Bitmap target; |
350 | 346 |
351 int dx = 0, dy = 0; | 347 int dx = 0, dy = 0; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 | 404 |
409 if (fRec.fFlags & SkScalerContext::kEmbolden_Flag && | 405 if (fRec.fFlags & SkScalerContext::kEmbolden_Flag && |
410 !(face->style_flags & FT_STYLE_FLAG_BOLD)) | 406 !(face->style_flags & FT_STYLE_FLAG_BOLD)) |
411 { | 407 { |
412 FT_GlyphSlot_Own_Bitmap(face->glyph); | 408 FT_GlyphSlot_Own_Bitmap(face->glyph); |
413 FT_Bitmap_Embolden(face->glyph->library, &face->glyph->bitmap, | 409 FT_Bitmap_Embolden(face->glyph->library, &face->glyph->bitmap, |
414 kBitmapEmboldenStrength, 0); | 410 kBitmapEmboldenStrength, 0); |
415 } | 411 } |
416 | 412 |
417 // If no scaling needed, directly copy glyph bitmap. | 413 // If no scaling needed, directly copy glyph bitmap. |
418 if (bitmapTransform.isIdentity()) { | 414 if (glyph.fWidth == face->glyph->bitmap.width && |
| 415 glyph.fHeight == face->glyph->bitmap.rows && |
| 416 glyph.fTop == -face->glyph->bitmap_top && |
| 417 glyph.fLeft == face->glyph->bitmap_left) |
| 418 { |
419 SkMask dstMask; | 419 SkMask dstMask; |
420 glyph.toMask(&dstMask); | 420 glyph.toMask(&dstMask); |
421 copyFTBitmap(face->glyph->bitmap, dstMask); | 421 copyFTBitmap(face->glyph->bitmap, dstMask); |
422 break; | 422 break; |
423 } | 423 } |
424 | 424 |
425 // Otherwise, scale the bitmap. | 425 // Otherwise, scale the bitmap. |
426 | 426 |
427 // Copy the FT_Bitmap into an SkBitmap (either A8 or ARGB) | 427 // Copy the FT_Bitmap into an SkBitmap (either A8 or ARGB) |
428 SkBitmap unscaledBitmap; | 428 SkBitmap unscaledBitmap; |
429 // TODO: mark this as sRGB when the blits will be sRGB. | |
430 unscaledBitmap.allocPixels(SkImageInfo::Make(face->glyph->bitmap.wid
th, | 429 unscaledBitmap.allocPixels(SkImageInfo::Make(face->glyph->bitmap.wid
th, |
431 face->glyph->bitmap.row
s, | 430 face->glyph->bitmap.row
s, |
432 SkColorType_for_FTPixel
Mode(pixel_mode), | 431 SkColorType_for_FTPixel
Mode(pixel_mode), |
433 kPremul_SkAlphaType)); | 432 kPremul_SkAlphaType)); |
434 | 433 |
435 SkMask unscaledBitmapAlias; | 434 SkMask unscaledBitmapAlias; |
436 unscaledBitmapAlias.fImage = reinterpret_cast<uint8_t*>(unscaledBitm
ap.getPixels()); | 435 unscaledBitmapAlias.fImage = reinterpret_cast<uint8_t*>(unscaledBitm
ap.getPixels()); |
437 unscaledBitmapAlias.fBounds.set(0, 0, unscaledBitmap.width(), unscal
edBitmap.height()); | 436 unscaledBitmapAlias.fBounds.set(0, 0, unscaledBitmap.width(), unscal
edBitmap.height()); |
438 unscaledBitmapAlias.fRowBytes = unscaledBitmap.rowBytes(); | 437 unscaledBitmapAlias.fRowBytes = unscaledBitmap.rowBytes(); |
439 unscaledBitmapAlias.fFormat = SkMaskFormat_for_SkColorType(unscaledB
itmap.colorType()); | 438 unscaledBitmapAlias.fFormat = SkMaskFormat_for_SkColorType(unscaledB
itmap.colorType()); |
440 copyFTBitmap(face->glyph->bitmap, unscaledBitmapAlias); | 439 copyFTBitmap(face->glyph->bitmap, unscaledBitmapAlias); |
441 | 440 |
442 // Wrap the glyph's mask in a bitmap, unless the glyph's mask is BW
or LCD. | 441 // Wrap the glyph's mask in a bitmap, unless the glyph's mask is BW
or LCD. |
443 // BW requires an A8 target for resizing, which can then be down sam
pled. | 442 // BW requires an A8 target for resizing, which can then be down sam
pled. |
444 // LCD should use a 4x A8 target, which will then be down sampled. | 443 // LCD should use a 4x A8 target, which will then be down sampled. |
445 // For simplicity, LCD uses A8 and is replicated. | 444 // For simplicity, LCD uses A8 and is replicated. |
446 int bitmapRowBytes = 0; | 445 int bitmapRowBytes = 0; |
447 if (SkMask::kBW_Format != maskFormat && SkMask::kLCD16_Format != mas
kFormat) { | 446 if (SkMask::kBW_Format != maskFormat && SkMask::kLCD16_Format != mas
kFormat) { |
448 bitmapRowBytes = glyph.rowBytes(); | 447 bitmapRowBytes = glyph.rowBytes(); |
449 } | 448 } |
450 SkBitmap dstBitmap; | 449 SkBitmap dstBitmap; |
451 // TODO: mark this as sRGB when the blits will be sRGB. | |
452 dstBitmap.setInfo(SkImageInfo::Make(glyph.fWidth, glyph.fHeight, | 450 dstBitmap.setInfo(SkImageInfo::Make(glyph.fWidth, glyph.fHeight, |
453 SkColorType_for_SkMaskFormat(mas
kFormat), | 451 SkColorType_for_SkMaskFormat(mas
kFormat), |
454 kPremul_SkAlphaType), | 452 kPremul_SkAlphaType), |
455 bitmapRowBytes); | 453 bitmapRowBytes); |
456 if (SkMask::kBW_Format == maskFormat || SkMask::kLCD16_Format == mas
kFormat) { | 454 if (SkMask::kBW_Format == maskFormat || SkMask::kLCD16_Format == mas
kFormat) { |
457 dstBitmap.allocPixels(); | 455 dstBitmap.allocPixels(); |
458 } else { | 456 } else { |
459 dstBitmap.setPixels(glyph.fImage); | 457 dstBitmap.setPixels(glyph.fImage); |
460 } | 458 } |
461 | 459 |
462 // Scale unscaledBitmap into dstBitmap. | 460 // Scale unscaledBitmap into dstBitmap. |
463 SkCanvas canvas(dstBitmap); | 461 SkCanvas canvas(dstBitmap); |
464 #ifdef SK_SHOW_TEXT_BLIT_COVERAGE | |
465 canvas.clear(0x33FF0000); | |
466 #else | |
467 canvas.clear(SK_ColorTRANSPARENT); | 462 canvas.clear(SK_ColorTRANSPARENT); |
468 #endif | 463 canvas.scale(SkIntToScalar(glyph.fWidth) / SkIntToScalar(face->glyph
->bitmap.width), |
469 canvas.translate(-glyph.fLeft, -glyph.fTop); | 464 SkIntToScalar(glyph.fHeight) / SkIntToScalar(face->glyp
h->bitmap.rows)); |
470 canvas.concat(bitmapTransform); | |
471 canvas.translate(face->glyph->bitmap_left, -face->glyph->bitmap_top)
; | |
472 | |
473 SkPaint paint; | 465 SkPaint paint; |
474 paint.setFilterQuality(kMedium_SkFilterQuality); | 466 paint.setFilterQuality(kMedium_SkFilterQuality); |
475 canvas.drawBitmap(unscaledBitmap, 0, 0, &paint); | 467 canvas.drawBitmap(unscaledBitmap, 0, 0, &paint); |
476 | 468 |
477 // If the destination is BW or LCD, convert from A8. | 469 // If the destination is BW or LCD, convert from A8. |
478 if (SkMask::kBW_Format == maskFormat) { | 470 if (SkMask::kBW_Format == maskFormat) { |
479 // Copy the A8 dstBitmap into the A1 glyph.fImage. | 471 // Copy the A8 dstBitmap into the A1 glyph.fImage. |
480 SkMask dstMask; | 472 SkMask dstMask; |
481 glyph.toMask(&dstMask); | 473 glyph.toMask(&dstMask); |
482 packA8ToA1(dstMask, dstBitmap.getAddr8(0, 0), dstBitmap.rowBytes
()); | 474 packA8ToA1(dstMask, dstBitmap.getAddr8(0, 0), dstBitmap.rowBytes
()); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 | 556 |
565 FT_Error err = FT_Outline_Decompose(&face->glyph->outline, &funcs, path); | 557 FT_Error err = FT_Outline_Decompose(&face->glyph->outline, &funcs, path); |
566 | 558 |
567 if (err != 0) { | 559 if (err != 0) { |
568 path->reset(); | 560 path->reset(); |
569 return; | 561 return; |
570 } | 562 } |
571 | 563 |
572 path->close(); | 564 path->close(); |
573 } | 565 } |
OLD | NEW |