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

Side by Side Diff: src/ports/SkFontHost_FreeType_common.cpp

Issue 2139703002: Rotate emoji with FreeType. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Remove whitespace. Created 4 years, 5 months 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
« no previous file with comments | « src/ports/SkFontHost_FreeType_common.h ('k') | no next file » | 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 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 * FT_PIXEL_MODE_GRAY N Y NR N Y 170 * FT_PIXEL_MODE_GRAY N Y NR N Y
171 * FT_PIXEL_MODE_GRAY2 NP NP NR NP NP 171 * FT_PIXEL_MODE_GRAY2 NP NP NR NP NP
172 * FT_PIXEL_MODE_GRAY4 NP NP NR NP NP 172 * FT_PIXEL_MODE_GRAY4 NP NP NR NP NP
173 * FT_PIXEL_MODE_LCD NP NP NR NP NP 173 * FT_PIXEL_MODE_LCD NP NP NR NP NP
174 * FT_PIXEL_MODE_LCD_V NP NP NR NP NP 174 * FT_PIXEL_MODE_LCD_V NP NP NR NP NP
175 * FT_PIXEL_MODE_BGRA N N NR Y N 175 * FT_PIXEL_MODE_BGRA N N NR Y N
176 * 176 *
177 * TODO: All of these N need to be Y or otherwise ruled out. 177 * TODO: All of these N need to be Y or otherwise ruled out.
178 */ 178 */
179 static void copyFTBitmap(const FT_Bitmap& srcFTBitmap, SkMask& dstMask) { 179 static void copyFTBitmap(const FT_Bitmap& srcFTBitmap, SkMask& dstMask) {
180 SkASSERT(dstMask.fBounds.width() == static_cast<int>(srcFTBitmap.width)); 180 SkASSERTF(dstMask.fBounds.width() == static_cast<int>(srcFTBitmap.width),
181 SkASSERT(dstMask.fBounds.height() == static_cast<int>(srcFTBitmap.rows)); 181 "dstMask.fBounds.width() = %d\n"
182 "static_cast<int>(srcFTBitmap.width) = %d",
183 dstMask.fBounds.width(),
184 static_cast<int>(srcFTBitmap.width)
185 );
186 SkASSERTF(dstMask.fBounds.height() == static_cast<int>(srcFTBitmap.rows),
187 "dstMask.fBounds.height() = %d\n"
188 "static_cast<int>(srcFTBitmap.rows) = %d",
189 dstMask.fBounds.height(),
190 static_cast<int>(srcFTBitmap.rows)
191 );
182 192
183 const uint8_t* src = reinterpret_cast<const uint8_t*>(srcFTBitmap.buffer); 193 const uint8_t* src = reinterpret_cast<const uint8_t*>(srcFTBitmap.buffer);
184 const FT_Pixel_Mode srcFormat = static_cast<FT_Pixel_Mode>(srcFTBitmap.pixel _mode); 194 const FT_Pixel_Mode srcFormat = static_cast<FT_Pixel_Mode>(srcFTBitmap.pixel _mode);
185 // FT_Bitmap::pitch is an int and allowed to be negative. 195 // FT_Bitmap::pitch is an int and allowed to be negative.
186 const int srcPitch = srcFTBitmap.pitch; 196 const int srcPitch = srcFTBitmap.pitch;
187 const size_t srcRowBytes = SkTAbs(srcPitch); 197 const size_t srcRowBytes = SkTAbs(srcPitch);
188 198
189 uint8_t* dst = dstMask.fImage; 199 uint8_t* dst = dstMask.fImage;
190 const SkMask::Format dstFormat = static_cast<SkMask::Format>(dstMask.fFormat ); 200 const SkMask::Format dstFormat = static_cast<SkMask::Format>(dstMask.fFormat );
191 const size_t dstRowBytes = dstMask.fRowBytes; 201 const size_t dstRowBytes = dstMask.fRowBytes;
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 case SkMask::kLCD16_Format: 337 case SkMask::kLCD16_Format:
328 return kAlpha_8_SkColorType; 338 return kAlpha_8_SkColorType;
329 case SkMask::kARGB32_Format: 339 case SkMask::kARGB32_Format:
330 return kN32_SkColorType; 340 return kN32_SkColorType;
331 default: 341 default:
332 SkDEBUGFAIL("unsupported destination SkBitmap::Config"); 342 SkDEBUGFAIL("unsupported destination SkBitmap::Config");
333 return kAlpha_8_SkColorType; 343 return kAlpha_8_SkColorType;
334 } 344 }
335 } 345 }
336 346
337 void SkScalerContext_FreeType_Base::generateGlyphImage(FT_Face face, const SkGly ph& glyph) { 347 void SkScalerContext_FreeType_Base::generateGlyphImage(
348 FT_Face face,
349 const SkGlyph& glyph,
350 const SkMatrix& bitmapTransform)
351 {
338 const bool doBGR = SkToBool(fRec.fFlags & SkScalerContext::kLCD_BGROrder_Fla g); 352 const bool doBGR = SkToBool(fRec.fFlags & SkScalerContext::kLCD_BGROrder_Fla g);
339 const bool doVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Fl ag); 353 const bool doVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Fl ag);
340 354
341 switch ( face->glyph->format ) { 355 switch ( face->glyph->format ) {
342 case FT_GLYPH_FORMAT_OUTLINE: { 356 case FT_GLYPH_FORMAT_OUTLINE: {
343 FT_Outline* outline = &face->glyph->outline; 357 FT_Outline* outline = &face->glyph->outline;
344 FT_BBox bbox; 358 FT_BBox bbox;
345 FT_Bitmap target; 359 FT_Bitmap target;
346 360
347 int dx = 0, dy = 0; 361 int dx = 0, dy = 0;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 SkASSERT(FT_PIXEL_MODE_MONO == pixel_mode || 409 SkASSERT(FT_PIXEL_MODE_MONO == pixel_mode ||
396 FT_PIXEL_MODE_GRAY == pixel_mode || 410 FT_PIXEL_MODE_GRAY == pixel_mode ||
397 FT_PIXEL_MODE_BGRA == pixel_mode); 411 FT_PIXEL_MODE_BGRA == pixel_mode);
398 412
399 // These are the only formats this ScalerContext should request. 413 // These are the only formats this ScalerContext should request.
400 SkASSERT(SkMask::kBW_Format == maskFormat || 414 SkASSERT(SkMask::kBW_Format == maskFormat ||
401 SkMask::kA8_Format == maskFormat || 415 SkMask::kA8_Format == maskFormat ||
402 SkMask::kARGB32_Format == maskFormat || 416 SkMask::kARGB32_Format == maskFormat ||
403 SkMask::kLCD16_Format == maskFormat); 417 SkMask::kLCD16_Format == maskFormat);
404 418
405 if (fRec.fFlags & SkScalerContext::kEmbolden_Flag &&
406 !(face->style_flags & FT_STYLE_FLAG_BOLD))
407 {
408 FT_GlyphSlot_Own_Bitmap(face->glyph);
409 FT_Bitmap_Embolden(face->glyph->library, &face->glyph->bitmap,
410 kBitmapEmboldenStrength, 0);
411 }
412
413 // If no scaling needed, directly copy glyph bitmap. 419 // If no scaling needed, directly copy glyph bitmap.
414 if (glyph.fWidth == face->glyph->bitmap.width && 420 if (bitmapTransform.isIdentity()) {
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; 421 SkMask dstMask;
420 glyph.toMask(&dstMask); 422 glyph.toMask(&dstMask);
421 copyFTBitmap(face->glyph->bitmap, dstMask); 423 copyFTBitmap(face->glyph->bitmap, dstMask);
422 break; 424 break;
423 } 425 }
424 426
425 // Otherwise, scale the bitmap. 427 // Otherwise, scale the bitmap.
426 428
427 // Copy the FT_Bitmap into an SkBitmap (either A8 or ARGB) 429 // Copy the FT_Bitmap into an SkBitmap (either A8 or ARGB)
428 SkBitmap unscaledBitmap; 430 SkBitmap unscaledBitmap;
431 // TODO: mark this as sRGB when the blits will be sRGB.
429 unscaledBitmap.allocPixels(SkImageInfo::Make(face->glyph->bitmap.wid th, 432 unscaledBitmap.allocPixels(SkImageInfo::Make(face->glyph->bitmap.wid th,
430 face->glyph->bitmap.row s, 433 face->glyph->bitmap.row s,
431 SkColorType_for_FTPixel Mode(pixel_mode), 434 SkColorType_for_FTPixel Mode(pixel_mode),
432 kPremul_SkAlphaType)); 435 kPremul_SkAlphaType));
433 436
434 SkMask unscaledBitmapAlias; 437 SkMask unscaledBitmapAlias;
435 unscaledBitmapAlias.fImage = reinterpret_cast<uint8_t*>(unscaledBitm ap.getPixels()); 438 unscaledBitmapAlias.fImage = reinterpret_cast<uint8_t*>(unscaledBitm ap.getPixels());
436 unscaledBitmapAlias.fBounds.set(0, 0, unscaledBitmap.width(), unscal edBitmap.height()); 439 unscaledBitmapAlias.fBounds.set(0, 0, unscaledBitmap.width(), unscal edBitmap.height());
437 unscaledBitmapAlias.fRowBytes = unscaledBitmap.rowBytes(); 440 unscaledBitmapAlias.fRowBytes = unscaledBitmap.rowBytes();
438 unscaledBitmapAlias.fFormat = SkMaskFormat_for_SkColorType(unscaledB itmap.colorType()); 441 unscaledBitmapAlias.fFormat = SkMaskFormat_for_SkColorType(unscaledB itmap.colorType());
439 copyFTBitmap(face->glyph->bitmap, unscaledBitmapAlias); 442 copyFTBitmap(face->glyph->bitmap, unscaledBitmapAlias);
440 443
441 // Wrap the glyph's mask in a bitmap, unless the glyph's mask is BW or LCD. 444 // Wrap the glyph's mask in a bitmap, unless the glyph's mask is BW or LCD.
442 // BW requires an A8 target for resizing, which can then be down sam pled. 445 // BW requires an A8 target for resizing, which can then be down sam pled.
443 // LCD should use a 4x A8 target, which will then be down sampled. 446 // LCD should use a 4x A8 target, which will then be down sampled.
444 // For simplicity, LCD uses A8 and is replicated. 447 // For simplicity, LCD uses A8 and is replicated.
445 int bitmapRowBytes = 0; 448 int bitmapRowBytes = 0;
446 if (SkMask::kBW_Format != maskFormat && SkMask::kLCD16_Format != mas kFormat) { 449 if (SkMask::kBW_Format != maskFormat && SkMask::kLCD16_Format != mas kFormat) {
447 bitmapRowBytes = glyph.rowBytes(); 450 bitmapRowBytes = glyph.rowBytes();
448 } 451 }
449 SkBitmap dstBitmap; 452 SkBitmap dstBitmap;
453 // TODO: mark this as sRGB when the blits will be sRGB.
450 dstBitmap.setInfo(SkImageInfo::Make(glyph.fWidth, glyph.fHeight, 454 dstBitmap.setInfo(SkImageInfo::Make(glyph.fWidth, glyph.fHeight,
451 SkColorType_for_SkMaskFormat(mas kFormat), 455 SkColorType_for_SkMaskFormat(mas kFormat),
452 kPremul_SkAlphaType), 456 kPremul_SkAlphaType),
453 bitmapRowBytes); 457 bitmapRowBytes);
454 if (SkMask::kBW_Format == maskFormat || SkMask::kLCD16_Format == mas kFormat) { 458 if (SkMask::kBW_Format == maskFormat || SkMask::kLCD16_Format == mas kFormat) {
455 dstBitmap.allocPixels(); 459 dstBitmap.allocPixels();
456 } else { 460 } else {
457 dstBitmap.setPixels(glyph.fImage); 461 dstBitmap.setPixels(glyph.fImage);
458 } 462 }
459 463
460 // Scale unscaledBitmap into dstBitmap. 464 // Scale unscaledBitmap into dstBitmap.
461 SkCanvas canvas(dstBitmap); 465 SkCanvas canvas(dstBitmap);
466 #ifdef SK_SHOW_TEXT_BLIT_COVERAGE
467 canvas.clear(0x33FF0000);
468 #else
462 canvas.clear(SK_ColorTRANSPARENT); 469 canvas.clear(SK_ColorTRANSPARENT);
463 canvas.scale(SkIntToScalar(glyph.fWidth) / SkIntToScalar(face->glyph ->bitmap.width), 470 #endif
464 SkIntToScalar(glyph.fHeight) / SkIntToScalar(face->glyp h->bitmap.rows)); 471 canvas.translate(-glyph.fLeft, -glyph.fTop);
472 canvas.concat(bitmapTransform);
473 canvas.translate(face->glyph->bitmap_left, -face->glyph->bitmap_top) ;
474
465 SkPaint paint; 475 SkPaint paint;
466 paint.setFilterQuality(kMedium_SkFilterQuality); 476 paint.setFilterQuality(kMedium_SkFilterQuality);
467 canvas.drawBitmap(unscaledBitmap, 0, 0, &paint); 477 canvas.drawBitmap(unscaledBitmap, 0, 0, &paint);
468 478
469 // If the destination is BW or LCD, convert from A8. 479 // If the destination is BW or LCD, convert from A8.
470 if (SkMask::kBW_Format == maskFormat) { 480 if (SkMask::kBW_Format == maskFormat) {
471 // Copy the A8 dstBitmap into the A1 glyph.fImage. 481 // Copy the A8 dstBitmap into the A1 glyph.fImage.
472 SkMask dstMask; 482 SkMask dstMask;
473 glyph.toMask(&dstMask); 483 glyph.toMask(&dstMask);
474 packA8ToA1(dstMask, dstBitmap.getAddr8(0, 0), dstBitmap.rowBytes ()); 484 packA8ToA1(dstMask, dstBitmap.getAddr8(0, 0), dstBitmap.rowBytes ());
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 566
557 FT_Error err = FT_Outline_Decompose(&face->glyph->outline, &funcs, path); 567 FT_Error err = FT_Outline_Decompose(&face->glyph->outline, &funcs, path);
558 568
559 if (err != 0) { 569 if (err != 0) {
560 path->reset(); 570 path->reset();
561 return; 571 return;
562 } 572 }
563 573
564 path->close(); 574 path->close();
565 } 575 }
OLDNEW
« no previous file with comments | « src/ports/SkFontHost_FreeType_common.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698