1 /*
2  * Copyright 2006-2012 The Android Open Source Project
3  * Copyright 2012 Mozilla Foundation
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 #include "include/core/SkBitmap.h"
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkColor.h"
12 #include "include/core/SkPath.h"
13 #include "include/private/SkColorData.h"
14 #include "include/private/SkTo.h"
15 #include "src/core/SkFDot6.h"
16 #include "src/ports/SkFontHost_FreeType_common.h"
17 
18 #include <utility>
19 
20 #include <ft2build.h>
21 #include FT_FREETYPE_H
22 #include FT_BITMAP_H
23 #ifdef FT_COLOR_H
24 #   include FT_COLOR_H
25 #endif
26 #include FT_IMAGE_H
27 #include FT_OUTLINE_H
28 // In the past, FT_GlyphSlot_Own_Bitmap was defined in this header file.
29 #include FT_SYNTHESIS_H
30 
31 // FT_LOAD_COLOR and the corresponding FT_Pixel_Mode::FT_PIXEL_MODE_BGRA
32 // were introduced in FreeType 2.5.0.
33 // The following may be removed once FreeType 2.5.0 is required to build.
34 #ifndef FT_LOAD_COLOR
35 #    define FT_LOAD_COLOR ( 1L << 20 )
36 #    define FT_PIXEL_MODE_BGRA 7
37 #endif
38 
39 #ifdef SK_DEBUG
SkTraceFtrGetError(int e)40 const char* SkTraceFtrGetError(int e) {
41     switch ((FT_Error)e) {
42         #undef FTERRORS_H_
43         #define FT_ERRORDEF( e, v, s ) case v: return s;
44         #define FT_ERROR_START_LIST
45         #define FT_ERROR_END_LIST
46         #include FT_ERRORS_H
47         #undef FT_ERRORDEF
48         #undef FT_ERROR_START_LIST
49         #undef FT_ERROR_END_LIST
50         default: return "";
51     }
52 }
53 #endif  // SK_DEBUG
54 
55 namespace {
56 
compute_pixel_mode(SkMask::Format format)57 FT_Pixel_Mode compute_pixel_mode(SkMask::Format format) {
58     switch (format) {
59         case SkMask::kBW_Format:
60             return FT_PIXEL_MODE_MONO;
61         case SkMask::kA8_Format:
62         default:
63             return FT_PIXEL_MODE_GRAY;
64     }
65 }
66 
67 ///////////////////////////////////////////////////////////////////////////////
68 
packTriple(U8CPU r,U8CPU g,U8CPU b)69 uint16_t packTriple(U8CPU r, U8CPU g, U8CPU b) {
70 #ifdef SK_SHOW_TEXT_BLIT_COVERAGE
71     r = std::max(r, (U8CPU)0x40);
72     g = std::max(g, (U8CPU)0x40);
73     b = std::max(b, (U8CPU)0x40);
74 #endif
75     return SkPack888ToRGB16(r, g, b);
76 }
77 
grayToRGB16(U8CPU gray)78 uint16_t grayToRGB16(U8CPU gray) {
79 #ifdef SK_SHOW_TEXT_BLIT_COVERAGE
80     gray = std::max(gray, (U8CPU)0x40);
81 #endif
82     return SkPack888ToRGB16(gray, gray, gray);
83 }
84 
bittst(const uint8_t data[],int bitOffset)85 int bittst(const uint8_t data[], int bitOffset) {
86     SkASSERT(bitOffset >= 0);
87     int lowBit = data[bitOffset >> 3] >> (~bitOffset & 7);
88     return lowBit & 1;
89 }
90 
91 /**
92  *  Copies a FT_Bitmap into an SkMask with the same dimensions.
93  *
94  *  FT_PIXEL_MODE_MONO
95  *  FT_PIXEL_MODE_GRAY
96  *  FT_PIXEL_MODE_LCD
97  *  FT_PIXEL_MODE_LCD_V
98  */
99 template<bool APPLY_PREBLEND>
copyFT2LCD16(const FT_Bitmap & bitmap,const SkMask & mask,int lcdIsBGR,const uint8_t * tableR,const uint8_t * tableG,const uint8_t * tableB)100 void copyFT2LCD16(const FT_Bitmap& bitmap, const SkMask& mask, int lcdIsBGR,
101                   const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB)
102 {
103     SkASSERT(SkMask::kLCD16_Format == mask.fFormat);
104     if (FT_PIXEL_MODE_LCD != bitmap.pixel_mode) {
105         SkASSERT(mask.fBounds.width() == static_cast<int>(bitmap.width));
106     }
107     if (FT_PIXEL_MODE_LCD_V != bitmap.pixel_mode) {
108         SkASSERT(mask.fBounds.height() == static_cast<int>(bitmap.rows));
109     }
110 
111     const uint8_t* src = bitmap.buffer;
112     uint16_t* dst = reinterpret_cast<uint16_t*>(mask.fImage);
113     const size_t dstRB = mask.fRowBytes;
114 
115     const int width = mask.fBounds.width();
116     const int height = mask.fBounds.height();
117 
118     switch (bitmap.pixel_mode) {
119         case FT_PIXEL_MODE_MONO:
120             for (int y = height; y --> 0;) {
121                 for (int x = 0; x < width; ++x) {
122                     dst[x] = -bittst(src, x);
123                 }
124                 dst = (uint16_t*)((char*)dst + dstRB);
125                 src += bitmap.pitch;
126             }
127             break;
128         case FT_PIXEL_MODE_GRAY:
129             for (int y = height; y --> 0;) {
130                 for (int x = 0; x < width; ++x) {
131                     dst[x] = grayToRGB16(src[x]);
132                 }
133                 dst = (uint16_t*)((char*)dst + dstRB);
134                 src += bitmap.pitch;
135             }
136             break;
137         case FT_PIXEL_MODE_LCD:
138             SkASSERT(3 * mask.fBounds.width() == static_cast<int>(bitmap.width));
139             for (int y = height; y --> 0;) {
140                 const uint8_t* triple = src;
141                 if (lcdIsBGR) {
142                     for (int x = 0; x < width; x++) {
143                         dst[x] = packTriple(sk_apply_lut_if<APPLY_PREBLEND>(triple[2], tableR),
144                                             sk_apply_lut_if<APPLY_PREBLEND>(triple[1], tableG),
145                                             sk_apply_lut_if<APPLY_PREBLEND>(triple[0], tableB));
146                         triple += 3;
147                     }
148                 } else {
149                     for (int x = 0; x < width; x++) {
150                         dst[x] = packTriple(sk_apply_lut_if<APPLY_PREBLEND>(triple[0], tableR),
151                                             sk_apply_lut_if<APPLY_PREBLEND>(triple[1], tableG),
152                                             sk_apply_lut_if<APPLY_PREBLEND>(triple[2], tableB));
153                         triple += 3;
154                     }
155                 }
156                 src += bitmap.pitch;
157                 dst = (uint16_t*)((char*)dst + dstRB);
158             }
159             break;
160         case FT_PIXEL_MODE_LCD_V:
161             SkASSERT(3 * mask.fBounds.height() == static_cast<int>(bitmap.rows));
162             for (int y = height; y --> 0;) {
163                 const uint8_t* srcR = src;
164                 const uint8_t* srcG = srcR + bitmap.pitch;
165                 const uint8_t* srcB = srcG + bitmap.pitch;
166                 if (lcdIsBGR) {
167                     using std::swap;
168                     swap(srcR, srcB);
169                 }
170                 for (int x = 0; x < width; x++) {
171                     dst[x] = packTriple(sk_apply_lut_if<APPLY_PREBLEND>(*srcR++, tableR),
172                                         sk_apply_lut_if<APPLY_PREBLEND>(*srcG++, tableG),
173                                         sk_apply_lut_if<APPLY_PREBLEND>(*srcB++, tableB));
174                 }
175                 src += 3 * bitmap.pitch;
176                 dst = (uint16_t*)((char*)dst + dstRB);
177             }
178             break;
179         default:
180             SkDEBUGF("FT_Pixel_Mode %d", bitmap.pixel_mode);
181             SkDEBUGFAIL("unsupported FT_Pixel_Mode for LCD16");
182             break;
183     }
184 }
185 
186 /**
187  *  Copies a FT_Bitmap into an SkMask with the same dimensions.
188  *
189  *  Yes, No, Never Requested, Never Produced
190  *
191  *                        kBW kA8 k3D kARGB32 kLCD16
192  *  FT_PIXEL_MODE_MONO     Y   Y  NR     N       Y
193  *  FT_PIXEL_MODE_GRAY     N   Y  NR     N       Y
194  *  FT_PIXEL_MODE_GRAY2   NP  NP  NR    NP      NP
195  *  FT_PIXEL_MODE_GRAY4   NP  NP  NR    NP      NP
196  *  FT_PIXEL_MODE_LCD     NP  NP  NR    NP      NP
197  *  FT_PIXEL_MODE_LCD_V   NP  NP  NR    NP      NP
198  *  FT_PIXEL_MODE_BGRA     N   N  NR     Y       N
199  *
200  *  TODO: All of these N need to be Y or otherwise ruled out.
201  */
copyFTBitmap(const FT_Bitmap & srcFTBitmap,SkMask & dstMask)202 void copyFTBitmap(const FT_Bitmap& srcFTBitmap, SkMask& dstMask) {
203     SkASSERTF(dstMask.fBounds.width() == static_cast<int>(srcFTBitmap.width),
204               "dstMask.fBounds.width() = %d\n"
205               "static_cast<int>(srcFTBitmap.width) = %d",
206               dstMask.fBounds.width(),
207               static_cast<int>(srcFTBitmap.width)
208     );
209     SkASSERTF(dstMask.fBounds.height() == static_cast<int>(srcFTBitmap.rows),
210               "dstMask.fBounds.height() = %d\n"
211               "static_cast<int>(srcFTBitmap.rows) = %d",
212               dstMask.fBounds.height(),
213               static_cast<int>(srcFTBitmap.rows)
214     );
215 
216     const uint8_t* src = reinterpret_cast<const uint8_t*>(srcFTBitmap.buffer);
217     const FT_Pixel_Mode srcFormat = static_cast<FT_Pixel_Mode>(srcFTBitmap.pixel_mode);
218     // FT_Bitmap::pitch is an int and allowed to be negative.
219     const int srcPitch = srcFTBitmap.pitch;
220     const size_t srcRowBytes = SkTAbs(srcPitch);
221 
222     uint8_t* dst = dstMask.fImage;
223     const SkMask::Format dstFormat = static_cast<SkMask::Format>(dstMask.fFormat);
224     const size_t dstRowBytes = dstMask.fRowBytes;
225 
226     const size_t width = srcFTBitmap.width;
227     const size_t height = srcFTBitmap.rows;
228 
229     if (SkMask::kLCD16_Format == dstFormat) {
230         copyFT2LCD16<false>(srcFTBitmap, dstMask, false, nullptr, nullptr, nullptr);
231         return;
232     }
233 
234     if ((FT_PIXEL_MODE_MONO == srcFormat && SkMask::kBW_Format == dstFormat) ||
235         (FT_PIXEL_MODE_GRAY == srcFormat && SkMask::kA8_Format == dstFormat))
236     {
237         size_t commonRowBytes = std::min(srcRowBytes, dstRowBytes);
238         for (size_t y = height; y --> 0;) {
239             memcpy(dst, src, commonRowBytes);
240             src += srcPitch;
241             dst += dstRowBytes;
242         }
243     } else if (FT_PIXEL_MODE_MONO == srcFormat && SkMask::kA8_Format == dstFormat) {
244         for (size_t y = height; y --> 0;) {
245             uint8_t byte = 0;
246             int bits = 0;
247             const uint8_t* src_row = src;
248             uint8_t* dst_row = dst;
249             for (size_t x = width; x --> 0;) {
250                 if (0 == bits) {
251                     byte = *src_row++;
252                     bits = 8;
253                 }
254                 *dst_row++ = byte & 0x80 ? 0xff : 0x00;
255                 bits--;
256                 byte <<= 1;
257             }
258             src += srcPitch;
259             dst += dstRowBytes;
260         }
261     } else if (FT_PIXEL_MODE_BGRA == srcFormat && SkMask::kARGB32_Format == dstFormat) {
262         // FT_PIXEL_MODE_BGRA is pre-multiplied.
263         for (size_t y = height; y --> 0;) {
264             const uint8_t* src_row = src;
265             SkPMColor* dst_row = reinterpret_cast<SkPMColor*>(dst);
266             for (size_t x = 0; x < width; ++x) {
267                 uint8_t b = *src_row++;
268                 uint8_t g = *src_row++;
269                 uint8_t r = *src_row++;
270                 uint8_t a = *src_row++;
271                 *dst_row++ = SkPackARGB32(a, r, g, b);
272 #ifdef SK_SHOW_TEXT_BLIT_COVERAGE
273                 *(dst_row-1) = SkFourByteInterp256(*(dst_row-1), SK_ColorWHITE, 0x40);
274 #endif
275             }
276             src += srcPitch;
277             dst += dstRowBytes;
278         }
279     } else {
280         SkDEBUGF("FT_Pixel_Mode %d, SkMask::Format %d\n", srcFormat, dstFormat);
281         SkDEBUGFAIL("unsupported combination of FT_Pixel_Mode and SkMask::Format");
282     }
283 }
284 
convert_8_to_1(unsigned byte)285 inline int convert_8_to_1(unsigned byte) {
286     SkASSERT(byte <= 0xFF);
287     // Arbitrary decision that making the cutoff at 1/4 instead of 1/2 in general looks better.
288     return (byte >> 6) != 0;
289 }
290 
pack_8_to_1(const uint8_t alpha[8])291 uint8_t pack_8_to_1(const uint8_t alpha[8]) {
292     unsigned bits = 0;
293     for (int i = 0; i < 8; ++i) {
294         bits <<= 1;
295         bits |= convert_8_to_1(alpha[i]);
296     }
297     return SkToU8(bits);
298 }
299 
packA8ToA1(const SkMask & mask,const uint8_t * src,size_t srcRB)300 void packA8ToA1(const SkMask& mask, const uint8_t* src, size_t srcRB) {
301     const int height = mask.fBounds.height();
302     const int width = mask.fBounds.width();
303     const int octs = width >> 3;
304     const int leftOverBits = width & 7;
305 
306     uint8_t* dst = mask.fImage;
307     const int dstPad = mask.fRowBytes - SkAlign8(width)/8;
308     SkASSERT(dstPad >= 0);
309 
310     const int srcPad = srcRB - width;
311     SkASSERT(srcPad >= 0);
312 
313     for (int y = 0; y < height; ++y) {
314         for (int i = 0; i < octs; ++i) {
315             *dst++ = pack_8_to_1(src);
316             src += 8;
317         }
318         if (leftOverBits > 0) {
319             unsigned bits = 0;
320             int shift = 7;
321             for (int i = 0; i < leftOverBits; ++i, --shift) {
322                 bits |= convert_8_to_1(*src++) << shift;
323             }
324             *dst++ = bits;
325         }
326         src += srcPad;
327         dst += dstPad;
328     }
329 }
330 
SkMaskFormat_for_SkColorType(SkColorType colorType)331 inline SkMask::Format SkMaskFormat_for_SkColorType(SkColorType colorType) {
332     switch (colorType) {
333         case kAlpha_8_SkColorType:
334             return SkMask::kA8_Format;
335         case kN32_SkColorType:
336             return SkMask::kARGB32_Format;
337         default:
338             SkDEBUGFAIL("unsupported SkBitmap::Config");
339             return SkMask::kA8_Format;
340     }
341 }
342 
SkColorType_for_FTPixelMode(FT_Pixel_Mode pixel_mode)343 inline SkColorType SkColorType_for_FTPixelMode(FT_Pixel_Mode pixel_mode) {
344     switch (pixel_mode) {
345         case FT_PIXEL_MODE_MONO:
346         case FT_PIXEL_MODE_GRAY:
347             return kAlpha_8_SkColorType;
348         case FT_PIXEL_MODE_BGRA:
349             return kN32_SkColorType;
350         default:
351             SkDEBUGFAIL("unsupported FT_PIXEL_MODE");
352             return kAlpha_8_SkColorType;
353     }
354 }
355 
SkColorType_for_SkMaskFormat(SkMask::Format format)356 inline SkColorType SkColorType_for_SkMaskFormat(SkMask::Format format) {
357     switch (format) {
358         case SkMask::kBW_Format:
359         case SkMask::kA8_Format:
360         case SkMask::kLCD16_Format:
361             return kAlpha_8_SkColorType;
362         case SkMask::kARGB32_Format:
363             return kN32_SkColorType;
364         default:
365             SkDEBUGFAIL("unsupported destination SkBitmap::Config");
366             return kAlpha_8_SkColorType;
367     }
368 }
369 
370 }  // namespace
371 
generateGlyphImage(FT_Face face,const SkGlyph & glyph,const SkMatrix & bitmapTransform)372 void SkScalerContext_FreeType_Base::generateGlyphImage(
373     FT_Face face,
374     const SkGlyph& glyph,
375     const SkMatrix& bitmapTransform)
376 {
377     const bool doBGR = SkToBool(fRec.fFlags & SkScalerContext::kLCD_BGROrder_Flag);
378     const bool doVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
379 
380     switch ( face->glyph->format ) {
381         case FT_GLYPH_FORMAT_OUTLINE: {
382             FT_Outline* outline = &face->glyph->outline;
383 
384             int dx = 0, dy = 0;
385             if (this->isSubpixel()) {
386                 dx = SkFixedToFDot6(glyph.getSubXFixed());
387                 dy = SkFixedToFDot6(glyph.getSubYFixed());
388                 // negate dy since freetype-y-goes-up and skia-y-goes-down
389                 dy = -dy;
390             }
391 
392             memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
393 
394 #ifdef FT_COLOR_H
395             if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
396                 SkBitmap dstBitmap;
397                 // TODO: mark this as sRGB when the blits will be sRGB.
398                 dstBitmap.setInfo(SkImageInfo::Make(glyph.fWidth, glyph.fHeight,
399                                                     kN32_SkColorType,
400                                                     kPremul_SkAlphaType),
401                                                     glyph.rowBytes());
402                 dstBitmap.setPixels(glyph.fImage);
403 
404                 // Scale unscaledBitmap into dstBitmap.
405                 SkCanvas canvas(dstBitmap);
406 #ifdef SK_SHOW_TEXT_BLIT_COVERAGE
407                 canvas.clear(0x33FF0000);
408 #else
409                 canvas.clear(SK_ColorTRANSPARENT);
410 #endif
411                 canvas.translate(-glyph.fLeft, -glyph.fTop);
412 
413                 if (this->isSubpixel()) {
414                     canvas.translate(SkFixedToScalar(glyph.getSubXFixed()),
415                                      SkFixedToScalar(glyph.getSubYFixed()));
416                 }
417 
418                 SkPaint paint;
419                 paint.setAntiAlias(true);
420 
421                 FT_Color *palette;
422                 FT_Error err = FT_Palette_Select(face, 0, &palette);
423                 if (err) {
424                     SK_TRACEFTR(err, "Could not get palette from %s fontFace.", face->family_name);
425                     return;
426                 }
427                 FT_LayerIterator layerIterator;
428                 layerIterator.p  = NULL;
429                 FT_Bool haveLayers = false;
430                 FT_UInt layerGlyphIndex;
431                 FT_UInt layerColorIndex;
432 
433                 while (FT_Get_Color_Glyph_Layer(face, glyph.getGlyphID(), &layerGlyphIndex,
434                                                 &layerColorIndex,
435                                                 &layerIterator)) {
436                     haveLayers = true;
437                     if (layerColorIndex == 0xFFFF) {
438                         paint.setColor(SK_ColorBLACK);
439                     } else {
440                         SkColor color = SkColorSetARGB(palette[layerColorIndex].alpha,
441                                                        palette[layerColorIndex].red,
442                                                        palette[layerColorIndex].green,
443                                                        palette[layerColorIndex].blue);
444                         paint.setColor(color);
445                     }
446                     SkPath path;
447                     if (this->generateFacePath(face, layerGlyphIndex, &path)) {
448                         canvas.drawPath(path, paint);
449                     }
450                 }
451 
452                 if (!haveLayers) {
453                     SK_TRACEFTR(err, "Could not get layers from %s fontFace.", face->family_name);
454                     return;
455                 }
456             } else
457 #endif
458             if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
459                 FT_Outline_Translate(outline, dx, dy);
460                 FT_Error err = FT_Render_Glyph(face->glyph, doVert ? FT_RENDER_MODE_LCD_V :
461                                                                      FT_RENDER_MODE_LCD);
462                 if (err) {
463                     SK_TRACEFTR(err, "Could not render glyph %x.", face->glyph);
464                     return;
465                 }
466 
467                 SkMask mask = glyph.mask();
468 #ifdef SK_SHOW_TEXT_BLIT_COVERAGE
469                 memset(mask.fImage, 0x80, mask.fBounds.height() * mask.fRowBytes);
470 #endif
471                 FT_GlyphSlotRec& ftGlyph = *face->glyph;
472 
473                 if (!SkIRect::Intersects(mask.fBounds,
474                                          SkIRect::MakeXYWH( ftGlyph.bitmap_left,
475                                                            -ftGlyph.bitmap_top,
476                                                             ftGlyph.bitmap.width,
477                                                             ftGlyph.bitmap.rows)))
478                 {
479                     return;
480                 }
481 
482                 // If the FT_Bitmap extent is larger, discard bits of the bitmap outside the mask.
483                 // If the SkMask extent is larger, shrink mask to fit bitmap (clearing discarded).
484                 unsigned char* origBuffer = ftGlyph.bitmap.buffer;
485                 // First align the top left (origin).
486                 if (-ftGlyph.bitmap_top < mask.fBounds.fTop) {
487                     int32_t topDiff = mask.fBounds.fTop - (-ftGlyph.bitmap_top);
488                     ftGlyph.bitmap.buffer += ftGlyph.bitmap.pitch * topDiff;
489                     ftGlyph.bitmap.rows -= topDiff;
490                     ftGlyph.bitmap_top = -mask.fBounds.fTop;
491                 }
492                 if (ftGlyph.bitmap_left < mask.fBounds.fLeft) {
493                     int32_t leftDiff = mask.fBounds.fLeft - ftGlyph.bitmap_left;
494                     ftGlyph.bitmap.buffer += leftDiff;
495                     ftGlyph.bitmap.width -= leftDiff;
496                     ftGlyph.bitmap_left = mask.fBounds.fLeft;
497                 }
498                 if (mask.fBounds.fTop < -ftGlyph.bitmap_top) {
499                     mask.fImage += mask.fRowBytes * (-ftGlyph.bitmap_top - mask.fBounds.fTop);
500                     mask.fBounds.fTop = -ftGlyph.bitmap_top;
501                 }
502                 if (mask.fBounds.fLeft < ftGlyph.bitmap_left) {
503                     mask.fImage += sizeof(uint16_t) * (ftGlyph.bitmap_left - mask.fBounds.fLeft);
504                     mask.fBounds.fLeft = ftGlyph.bitmap_left;
505                 }
506                 // Origins aligned, clean up the width and height.
507                 int ftVertScale = (doVert ? 3 : 1);
508                 int ftHoriScale = (doVert ? 1 : 3);
509                 if (mask.fBounds.height() * ftVertScale < SkToInt(ftGlyph.bitmap.rows)) {
510                     ftGlyph.bitmap.rows = mask.fBounds.height() * ftVertScale;
511                 }
512                 if (mask.fBounds.width() * ftHoriScale < SkToInt(ftGlyph.bitmap.width)) {
513                     ftGlyph.bitmap.width = mask.fBounds.width() * ftHoriScale;
514                 }
515                 if (SkToInt(ftGlyph.bitmap.rows) < mask.fBounds.height() * ftVertScale) {
516                     mask.fBounds.fBottom = mask.fBounds.fTop + ftGlyph.bitmap.rows / ftVertScale;
517                 }
518                 if (SkToInt(ftGlyph.bitmap.width) < mask.fBounds.width() * ftHoriScale) {
519                     mask.fBounds.fRight = mask.fBounds.fLeft + ftGlyph.bitmap.width / ftHoriScale;
520                 }
521                 if (fPreBlend.isApplicable()) {
522                     copyFT2LCD16<true>(ftGlyph.bitmap, mask, doBGR,
523                                        fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
524                 } else {
525                     copyFT2LCD16<false>(ftGlyph.bitmap, mask, doBGR,
526                                         fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
527                 }
528                 // Restore the buffer pointer so FreeType can properly free it.
529                 ftGlyph.bitmap.buffer = origBuffer;
530             } else {
531                 FT_BBox     bbox;
532                 FT_Bitmap   target;
533                 FT_Outline_Get_CBox(outline, &bbox);
534                 /*
535                     what we really want to do for subpixel is
536                         offset(dx, dy)
537                         compute_bounds
538                         offset(bbox & !63)
539                     but that is two calls to offset, so we do the following, which
540                     achieves the same thing with only one offset call.
541                 */
542                 FT_Outline_Translate(outline, dx - ((bbox.xMin + dx) & ~63),
543                                               dy - ((bbox.yMin + dy) & ~63));
544 
545                 target.width = glyph.fWidth;
546                 target.rows = glyph.fHeight;
547                 target.pitch = glyph.rowBytes();
548                 target.buffer = reinterpret_cast<uint8_t*>(glyph.fImage);
549                 target.pixel_mode = compute_pixel_mode( (SkMask::Format)glyph.fMaskFormat);
550                 target.num_grays = 256;
551 
552                 FT_Outline_Get_Bitmap(face->glyph->library, outline, &target);
553 #ifdef SK_SHOW_TEXT_BLIT_COVERAGE
554                 for (int y = 0; y < glyph.fHeight; ++y) {
555                     for (int x = 0; x < glyph.fWidth; ++x) {
556                         uint8_t& a = ((uint8_t*)glyph.fImage)[(glyph.rowBytes() * y) + x];
557                         a = std::max<uint8_t>(a, 0x20);
558                     }
559                 }
560 #endif
561             }
562         } break;
563 
564         case FT_GLYPH_FORMAT_BITMAP: {
565             FT_Pixel_Mode pixel_mode = static_cast<FT_Pixel_Mode>(face->glyph->bitmap.pixel_mode);
566             SkMask::Format maskFormat = static_cast<SkMask::Format>(glyph.fMaskFormat);
567 
568             // Assume that the other formats do not exist.
569             SkASSERT(FT_PIXEL_MODE_MONO == pixel_mode ||
570                      FT_PIXEL_MODE_GRAY == pixel_mode ||
571                      FT_PIXEL_MODE_BGRA == pixel_mode);
572 
573             // These are the only formats this ScalerContext should request.
574             SkASSERT(SkMask::kBW_Format == maskFormat ||
575                      SkMask::kA8_Format == maskFormat ||
576                      SkMask::kARGB32_Format == maskFormat ||
577                      SkMask::kLCD16_Format == maskFormat);
578 
579             // If no scaling needed, directly copy glyph bitmap.
580             if (bitmapTransform.isIdentity()) {
581                 SkMask dstMask = glyph.mask();
582                 copyFTBitmap(face->glyph->bitmap, dstMask);
583                 break;
584             }
585 
586             // Otherwise, scale the bitmap.
587 
588             // Copy the FT_Bitmap into an SkBitmap (either A8 or ARGB)
589             SkBitmap unscaledBitmap;
590             // TODO: mark this as sRGB when the blits will be sRGB.
591             unscaledBitmap.allocPixels(SkImageInfo::Make(face->glyph->bitmap.width,
592                                                          face->glyph->bitmap.rows,
593                                                          SkColorType_for_FTPixelMode(pixel_mode),
594                                                          kPremul_SkAlphaType));
595 
596             SkMask unscaledBitmapAlias;
597             unscaledBitmapAlias.fImage = reinterpret_cast<uint8_t*>(unscaledBitmap.getPixels());
598             unscaledBitmapAlias.fBounds.setWH(unscaledBitmap.width(), unscaledBitmap.height());
599             unscaledBitmapAlias.fRowBytes = unscaledBitmap.rowBytes();
600             unscaledBitmapAlias.fFormat = SkMaskFormat_for_SkColorType(unscaledBitmap.colorType());
601             copyFTBitmap(face->glyph->bitmap, unscaledBitmapAlias);
602 
603             // Wrap the glyph's mask in a bitmap, unless the glyph's mask is BW or LCD.
604             // BW requires an A8 target for resizing, which can then be down sampled.
605             // LCD should use a 4x A8 target, which will then be down sampled.
606             // For simplicity, LCD uses A8 and is replicated.
607             int bitmapRowBytes = 0;
608             if (SkMask::kBW_Format != maskFormat && SkMask::kLCD16_Format != maskFormat) {
609                 bitmapRowBytes = glyph.rowBytes();
610             }
611             SkBitmap dstBitmap;
612             // TODO: mark this as sRGB when the blits will be sRGB.
613             dstBitmap.setInfo(SkImageInfo::Make(glyph.fWidth, glyph.fHeight,
614                                                 SkColorType_for_SkMaskFormat(maskFormat),
615                                                 kPremul_SkAlphaType),
616                               bitmapRowBytes);
617             if (SkMask::kBW_Format == maskFormat || SkMask::kLCD16_Format == maskFormat) {
618                 dstBitmap.allocPixels();
619             } else {
620                 dstBitmap.setPixels(glyph.fImage);
621             }
622 
623             // Scale unscaledBitmap into dstBitmap.
624             SkCanvas canvas(dstBitmap);
625 #ifdef SK_SHOW_TEXT_BLIT_COVERAGE
626             canvas.clear(0x33FF0000);
627 #else
628             canvas.clear(SK_ColorTRANSPARENT);
629 #endif
630             canvas.translate(-glyph.fLeft, -glyph.fTop);
631             canvas.concat(bitmapTransform);
632             canvas.translate(face->glyph->bitmap_left, -face->glyph->bitmap_top);
633 
634             SkPaint paint;
635             // Using kMedium FilterQuality will cause mipmaps to be generated. Use
636             // kLow when the results will be roughly the same in order to avoid
637             // the mipmap generation cost.
638             // See skbug.com/6967
639             if (bitmapTransform.getMinScale() < 0.5) {
640                 paint.setFilterQuality(kMedium_SkFilterQuality);
641             } else {
642                 paint.setFilterQuality(kLow_SkFilterQuality);
643             }
644             canvas.drawBitmap(unscaledBitmap, 0, 0, &paint);
645 
646             // If the destination is BW or LCD, convert from A8.
647             if (SkMask::kBW_Format == maskFormat) {
648                 // Copy the A8 dstBitmap into the A1 glyph.fImage.
649                 SkMask dstMask = glyph.mask();
650                 packA8ToA1(dstMask, dstBitmap.getAddr8(0, 0), dstBitmap.rowBytes());
651             } else if (SkMask::kLCD16_Format == maskFormat) {
652                 // Copy the A8 dstBitmap into the LCD16 glyph.fImage.
653                 uint8_t* src = dstBitmap.getAddr8(0, 0);
654                 uint16_t* dst = reinterpret_cast<uint16_t*>(glyph.fImage);
655                 for (int y = dstBitmap.height(); y --> 0;) {
656                     for (int x = 0; x < dstBitmap.width(); ++x) {
657                         dst[x] = grayToRGB16(src[x]);
658                     }
659                     dst = (uint16_t*)((char*)dst + glyph.rowBytes());
660                     src += dstBitmap.rowBytes();
661                 }
662             }
663 
664         } break;
665 
666         default:
667             SkDEBUGFAIL("unknown glyph format");
668             memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
669             return;
670     }
671 
672 // We used to always do this pre-USE_COLOR_LUMINANCE, but with colorlum,
673 // it is optional
674 #if defined(SK_GAMMA_APPLY_TO_A8)
675     if (SkMask::kA8_Format == glyph.fMaskFormat && fPreBlend.isApplicable()) {
676         uint8_t* SK_RESTRICT dst = (uint8_t*)glyph.fImage;
677         unsigned rowBytes = glyph.rowBytes();
678 
679         for (int y = glyph.fHeight - 1; y >= 0; --y) {
680             for (int x = glyph.fWidth - 1; x >= 0; --x) {
681                 dst[x] = fPreBlend.fG[dst[x]];
682             }
683             dst += rowBytes;
684         }
685     }
686 #endif
687 }
688 
689 ///////////////////////////////////////////////////////////////////////////////
690 
691 namespace {
692 
693 class SkFTGeometrySink {
694     SkPath* fPath;
695     bool fStarted;
696     FT_Vector fCurrent;
697 
goingTo(const FT_Vector * pt)698     void goingTo(const FT_Vector* pt) {
699         if (!fStarted) {
700             fStarted = true;
701             fPath->moveTo(SkFDot6ToScalar(fCurrent.x), -SkFDot6ToScalar(fCurrent.y));
702         }
703         fCurrent = *pt;
704     }
705 
currentIsNot(const FT_Vector * pt)706     bool currentIsNot(const FT_Vector* pt) {
707         return fCurrent.x != pt->x || fCurrent.y != pt->y;
708     }
709 
Move(const FT_Vector * pt,void * ctx)710     static int Move(const FT_Vector* pt, void* ctx) {
711         SkFTGeometrySink& self = *(SkFTGeometrySink*)ctx;
712         if (self.fStarted) {
713             self.fPath->close();
714             self.fStarted = false;
715         }
716         self.fCurrent = *pt;
717         return 0;
718     }
719 
Line(const FT_Vector * pt,void * ctx)720     static int Line(const FT_Vector* pt, void* ctx) {
721         SkFTGeometrySink& self = *(SkFTGeometrySink*)ctx;
722         if (self.currentIsNot(pt)) {
723             self.goingTo(pt);
724             self.fPath->lineTo(SkFDot6ToScalar(pt->x), -SkFDot6ToScalar(pt->y));
725         }
726         return 0;
727     }
728 
Quad(const FT_Vector * pt0,const FT_Vector * pt1,void * ctx)729     static int Quad(const FT_Vector* pt0, const FT_Vector* pt1, void* ctx) {
730         SkFTGeometrySink& self = *(SkFTGeometrySink*)ctx;
731         if (self.currentIsNot(pt0) || self.currentIsNot(pt1)) {
732             self.goingTo(pt1);
733             self.fPath->quadTo(SkFDot6ToScalar(pt0->x), -SkFDot6ToScalar(pt0->y),
734                                SkFDot6ToScalar(pt1->x), -SkFDot6ToScalar(pt1->y));
735         }
736         return 0;
737     }
738 
Cubic(const FT_Vector * pt0,const FT_Vector * pt1,const FT_Vector * pt2,void * ctx)739     static int Cubic(const FT_Vector* pt0, const FT_Vector* pt1, const FT_Vector* pt2, void* ctx) {
740         SkFTGeometrySink& self = *(SkFTGeometrySink*)ctx;
741         if (self.currentIsNot(pt0) || self.currentIsNot(pt1) || self.currentIsNot(pt2)) {
742             self.goingTo(pt2);
743             self.fPath->cubicTo(SkFDot6ToScalar(pt0->x), -SkFDot6ToScalar(pt0->y),
744                                 SkFDot6ToScalar(pt1->x), -SkFDot6ToScalar(pt1->y),
745                                 SkFDot6ToScalar(pt2->x), -SkFDot6ToScalar(pt2->y));
746         }
747         return 0;
748     }
749 
750 public:
SkFTGeometrySink(SkPath * path)751     SkFTGeometrySink(SkPath* path) : fPath{path}, fStarted{false}, fCurrent{0,0} {}
752 
753     static constexpr const FT_Outline_Funcs Funcs{
754         /*move_to =*/ SkFTGeometrySink::Move,
755         /*line_to =*/ SkFTGeometrySink::Line,
756         /*conic_to =*/ SkFTGeometrySink::Quad,
757         /*cubic_to =*/ SkFTGeometrySink::Cubic,
758         /*shift = */ 0,
759         /*delta =*/ 0,
760     };
761 };
762 
763 }  // namespace
764 
generateGlyphPath(FT_Face face,SkPath * path)765 bool SkScalerContext_FreeType_Base::generateGlyphPath(FT_Face face, SkPath* path) {
766     SkFTGeometrySink sink{path};
767     FT_Error err = FT_Outline_Decompose(&face->glyph->outline, &SkFTGeometrySink::Funcs, &sink);
768 
769     if (err != 0) {
770         path->reset();
771         return false;
772     }
773 
774     path->close();
775     return true;
776 }
777 
generateFacePath(FT_Face face,SkGlyphID glyphID,SkPath * path)778 bool SkScalerContext_FreeType_Base::generateFacePath(FT_Face face, SkGlyphID glyphID, SkPath* path) {
779     uint32_t flags = 0; //fLoadGlyphFlags;
780     flags |= FT_LOAD_NO_BITMAP; // ignore embedded bitmaps so we're sure to get the outline
781     flags &= ~FT_LOAD_RENDER;   // don't scan convert (we just want the outline)
782 
783     FT_Error err = FT_Load_Glyph(face, glyphID, flags);
784     if (err != 0) {
785         path->reset();
786         return false;
787     }
788 
789     if (!generateGlyphPath(face, path)) {
790         path->reset();
791         return false;
792     }
793     return true;
794 }
795