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

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

Issue 23684041: improve bitmap font support (FreeType only) (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: fix silly transcription error Created 7 years, 1 month 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 | Annotate | Revision Log
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"
10 #include "SkCanvas.h"
11 #include "SkColor.h"
9 #include "SkColorPriv.h" 12 #include "SkColorPriv.h"
10 #include "SkFDot6.h" 13 #include "SkFDot6.h"
11 #include "SkFontHost_FreeType_common.h" 14 #include "SkFontHost_FreeType_common.h"
12 #include "SkPath.h" 15 #include "SkPath.h"
13 16
14 #include <ft2build.h> 17 #include <ft2build.h>
15 #include FT_OUTLINE_H 18 #include FT_OUTLINE_H
16 #include FT_BITMAP_H 19 #include FT_BITMAP_H
17 // In the past, FT_GlyphSlot_Own_Bitmap was defined in this header file. 20 // In the past, FT_GlyphSlot_Own_Bitmap was defined in this header file.
18 #include FT_SYNTHESIS_H 21 #include FT_SYNTHESIS_H
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 } else { 56 } else {
54 SkASSERT(glyph.fHeight == bitmap.rows); 57 SkASSERT(glyph.fHeight == bitmap.rows);
55 } 58 }
56 59
57 uint16_t* dst = reinterpret_cast<uint16_t*>(glyph.fImage); 60 uint16_t* dst = reinterpret_cast<uint16_t*>(glyph.fImage);
58 const size_t dstRB = glyph.rowBytes(); 61 const size_t dstRB = glyph.rowBytes();
59 const int width = glyph.fWidth; 62 const int width = glyph.fWidth;
60 const uint8_t* src = bitmap.buffer; 63 const uint8_t* src = bitmap.buffer;
61 64
62 switch (bitmap.pixel_mode) { 65 switch (bitmap.pixel_mode) {
63 case FT_PIXEL_MODE_MONO: { 66 case FT_PIXEL_MODE_MONO:
64 for (int y = 0; y < glyph.fHeight; ++y) { 67 for (int y = 0; y < glyph.fHeight; ++y) {
65 for (int x = 0; x < width; ++x) { 68 for (int x = 0; x < width; ++x) {
66 dst[x] = -bittst(src, x); 69 dst[x] = -bittst(src, x);
67 } 70 }
68 dst = (uint16_t*)((char*)dst + dstRB); 71 dst = (uint16_t*)((char*)dst + dstRB);
69 src += bitmap.pitch; 72 src += bitmap.pitch;
70 } 73 }
71 } break; 74 break;
72 case FT_PIXEL_MODE_GRAY: { 75 case FT_PIXEL_MODE_GRAY:
73 for (int y = 0; y < glyph.fHeight; ++y) { 76 for (int y = 0; y < glyph.fHeight; ++y) {
74 for (int x = 0; x < width; ++x) { 77 for (int x = 0; x < width; ++x) {
75 dst[x] = grayToRGB16(src[x]); 78 dst[x] = grayToRGB16(src[x]);
76 } 79 }
77 dst = (uint16_t*)((char*)dst + dstRB); 80 dst = (uint16_t*)((char*)dst + dstRB);
78 src += bitmap.pitch; 81 src += bitmap.pitch;
79 } 82 }
80 } break; 83 break;
81 default: { 84 default:
82 SkASSERT(lcdIsVert || (glyph.fWidth * 3 == bitmap.width)); 85 SkASSERT(lcdIsVert || (glyph.fWidth * 3 == bitmap.width));
83 for (int y = 0; y < glyph.fHeight; y++) { 86 for (int y = 0; y < glyph.fHeight; y++) {
84 if (lcdIsVert) { // vertical stripes 87 if (lcdIsVert) { // vertical stripes
85 const uint8_t* srcR = src; 88 const uint8_t* srcR = src;
86 const uint8_t* srcG = srcR + bitmap.pitch; 89 const uint8_t* srcG = srcR + bitmap.pitch;
87 const uint8_t* srcB = srcG + bitmap.pitch; 90 const uint8_t* srcB = srcG + bitmap.pitch;
88 if (lcdIsBGR) { 91 if (lcdIsBGR) {
89 SkTSwap(srcR, srcB); 92 SkTSwap(srcR, srcB);
90 } 93 }
91 for (int x = 0; x < width; x++) { 94 for (int x = 0; x < width; x++) {
(...skipping 16 matching lines...) Expand all
108 dst[x] = packTriple(sk_apply_lut_if<APPLY_PREBLEND>( triple[0], tableR), 111 dst[x] = packTriple(sk_apply_lut_if<APPLY_PREBLEND>( triple[0], tableR),
109 sk_apply_lut_if<APPLY_PREBLEND>( triple[1], tableG), 112 sk_apply_lut_if<APPLY_PREBLEND>( triple[1], tableG),
110 sk_apply_lut_if<APPLY_PREBLEND>( triple[2], tableB)); 113 sk_apply_lut_if<APPLY_PREBLEND>( triple[2], tableB));
111 triple += 3; 114 triple += 3;
112 } 115 }
113 } 116 }
114 src += bitmap.pitch; 117 src += bitmap.pitch;
115 } 118 }
116 dst = (uint16_t*)((char*)dst + dstRB); 119 dst = (uint16_t*)((char*)dst + dstRB);
117 } 120 }
118 } break; 121 break;
119 } 122 }
120 } 123 }
121 124
125 // copies an FT_Bitmap's pixel data into a buffer with identical dimensions
126 static void copyFTBitmap(const FT_Bitmap& srcFTBitmap, uint8_t* dst, uint8_t dst Format,
reed1 2013/11/13 20:21:46 Why are we passing uint8_t for the format type, in
reed1 2013/11/13 20:21:46 Since we are copying into a bitmap, why not pass i
violets 2013/11/19 18:38:06 SkGlyph::fMaskFormat, the value being passed into
violets 2013/11/19 18:38:06 One of the two calls to this function passes in gl
reed1 2013/11/20 21:52:12 I think that may be worth it, allowing us to have
reed1 2013/11/20 21:52:12 Ah, good point. Creating a bitmap just for that do
127 size_t dstRowBytes) {
128 const uint8_t* src = reinterpret_cast<const uint8_t*>(srcFTBitmap.buffer);
129 size_t width = srcFTBitmap.width;
130 size_t height = srcFTBitmap.rows;
131 size_t srcRowBytes = srcFTBitmap.pitch;
132
133 if ((SkMask::kA8_Format == dstFormat &&
134 FT_PIXEL_MODE_GRAY == srcFTBitmap.pixel_mode) ||
135 (SkMask::kBW_Format == dstFormat &&
136 FT_PIXEL_MODE_MONO == srcFTBitmap.pixel_mode)) {
137 // TODO: test 1bpp bitmap font into kBW_Format glyph
138 size_t minRowBytes = SkMin32(srcRowBytes, dstRowBytes);
139 size_t extraRowBytes = dstRowBytes - minRowBytes;
140 for (int y = height - 1; y >= 0; --y) {
141 memcpy(dst, src, minRowBytes);
142 memset(dst + minRowBytes, 0, extraRowBytes);
143 src += srcRowBytes;
144 dst += dstRowBytes;
145 }
146 } else if (SkMask::kA8_Format == dstFormat &&
147 FT_PIXEL_MODE_MONO == srcFTBitmap.pixel_mode) {
148 // TODO: test 1bpp bitmap font into kA8_Format glyph
149 for (size_t y = 0; y < height; ++y) {
150 uint8_t byte = 0;
151 int bits = 0;
152 const uint8_t* src_row = src;
153 uint8_t* dst_row = dst;
154 for (size_t x = 0; x < width; ++x) {
155 if (!bits) {
156 byte = *src_row++;
157 bits = 8;
158 }
159 *dst_row++ = byte & 0x80 ? 0xff : 0;
160 bits--;
161 byte <<= 1;
162 }
163 src += srcRowBytes;
164 dst += dstRowBytes;
165 }
166 #ifdef FT_LOAD_COLOR
167 } else if (SkMask::kARGB32_Format == dstFormat &&
168 FT_PIXEL_MODE_BGRA == srcFTBitmap.pixel_mode) {
169 size_t minWidth = SkMin32(width, SkMin32(srcRowBytes, dstRowBytes) / 4);
170 size_t extraRowBytes = dstRowBytes - (4 * minWidth);
171 for (size_t y = 0; y < height; ++y) {
172 const uint8_t* src_row = src;
173 uint8_t* dst_row = dst;
174 for (size_t x = 0; x < minWidth; ++x) {
175 uint8_t blue = *src_row++;
176 uint8_t green = *src_row++;
177 uint8_t red = *src_row++;
178 uint8_t alpha = *src_row++;
179 *dst_row++ = red;
180 *dst_row++ = green;
181 *dst_row++ = blue;
182 *dst_row++ = alpha;
183 }
184 memset(dst_row, 0, extraRowBytes);
185 src += srcRowBytes;
186 dst += dstRowBytes;
187 }
188 #endif
189 } else {
190 SkDEBUGFAIL("unsupported combination of FT_PIXEL_MODE and SkMask::Format ");
191 }
192 }
193
194 inline uint8_t skFormatForFTPixelMode(char pixel_mode) {
reed1 2013/11/13 20:21:46 1. Shouldn't this return SkMask::Format, instead o
violets 2013/11/19 18:38:06 1. I think that this should return the same type a
reed1 2013/11/20 21:52:12 I still vote for a named type, at least for the re
195 switch (pixel_mode) {
196 case FT_PIXEL_MODE_GRAY:
197 return SkMask::kA8_Format;
198 case FT_PIXEL_MODE_MONO:
199 return SkMask::kBW_Format;
200 #ifdef FT_LOAD_COLOR
201 case FT_PIXEL_MODE_BGRA:
202 return SkMask::kARGB32_Format;
203 #endif
204 default:
205 SkDEBUGFAIL("unsupported FT_PIXEL_MODE");
206 return SkMask::kA8_Format;
207 }
208 }
209
210 inline SkBitmap::Config skConfigForFTPixelMode(char pixel_mode) {
reed1 2013/11/13 20:21:46 What is the type of pixel_mode? Is there an enum f
violets 2013/11/19 18:38:06 pixel_mode is type "char". There is an associated
211 switch (pixel_mode) {
212 case FT_PIXEL_MODE_GRAY:
213 return SkBitmap::kA8_Config;
214 case FT_PIXEL_MODE_MONO:
215 return SkBitmap::kA1_Config;
216 #ifdef FT_LOAD_COLOR
217 case FT_PIXEL_MODE_BGRA:
218 return SkBitmap::kARGB_8888_Config;
219 #endif
220 default:
221 SkDEBUGFAIL("unsupported FT_PIXEL_MODE");
222 return SkBitmap::kA8_Config;
223 }
224 }
225
226 inline SkBitmap::Config skConfigForFormat(uint8_t format) {
reed1 2013/11/13 20:21:46 Can we declare format to be SkMask::Format ?
violets 2013/11/19 18:38:06 We can, but the uint8_t data that we pass into thi
reed1 2013/11/20 21:52:12 I do. I'm also fine if we had a helper to SkGlyph
227 switch (format) {
228 case SkMask::kA8_Format:
229 return SkBitmap::kA8_Config;
230 case SkMask::kBW_Format:
231 return SkBitmap::kA1_Config;
232 #ifdef FT_LOAD_COLOR
233 case SkMask::kARGB32_Format:
234 return SkBitmap::kARGB_8888_Config;
235 #endif
236 default:
237 SkDEBUGFAIL("unsupported FT_PIXEL_MODE");
238 return SkBitmap::kA8_Config;
239 }
240 }
241
122 void SkScalerContext_FreeType_Base::generateGlyphImage(FT_Face face, const SkGly ph& glyph) { 242 void SkScalerContext_FreeType_Base::generateGlyphImage(FT_Face face, const SkGly ph& glyph) {
123 const bool doBGR = SkToBool(fRec.fFlags & SkScalerContext::kLCD_BGROrder_Fla g); 243 const bool doBGR = SkToBool(fRec.fFlags & SkScalerContext::kLCD_BGROrder_Fla g);
124 const bool doVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Fl ag); 244 const bool doVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Fl ag);
125 245
126 switch ( face->glyph->format ) { 246 switch ( face->glyph->format ) {
127 case FT_GLYPH_FORMAT_OUTLINE: { 247 case FT_GLYPH_FORMAT_OUTLINE:
128 FT_Outline* outline = &face->glyph->outline; 248 {
bungeman-skia 2013/11/15 00:19:48 This introduces an unnecessary amount of indentati
violets 2013/11/19 18:38:06 Done.
129 FT_BBox bbox; 249 FT_Outline* outline = &face->glyph->outline;
130 FT_Bitmap target; 250 FT_BBox bbox;
251 FT_Bitmap target;
131 252
132 if (fRec.fFlags & SkScalerContext::kEmbolden_Flag) { 253 if (fRec.fFlags & SkScalerContext::kEmbolden_Flag &&
133 emboldenOutline(face, outline); 254 !(face->style_flags & FT_STYLE_FLAG_BOLD)) {
255 emboldenOutline(face, outline);
256 }
257
258 int dx = 0, dy = 0;
259 if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
260 dx = SkFixedToFDot6(glyph.getSubXFixed());
261 dy = SkFixedToFDot6(glyph.getSubYFixed());
262 // negate dy since freetype-y-goes-up and skia-y-goes-down
263 dy = -dy;
264 }
265 FT_Outline_Get_CBox(outline, &bbox);
266 /*
267 what we really want to do for subpixel is
268 offset(dx, dy)
269 compute_bounds
270 offset(bbox & !63)
271 but that is two calls to offset, so we do the following, whi ch
272 achieves the same thing with only one offset call.
273 */
274 FT_Outline_Translate(outline, dx - ((bbox.xMin + dx) & ~63),
275 dy - ((bbox.yMin + dy) & ~63));
276
277 if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
278 FT_Render_Glyph(face->glyph,
279 doVert ? FT_RENDER_MODE_LCD_V : FT_RENDER_MO DE_LCD);
280 if (fPreBlend.isApplicable()) {
281 copyFT2LCD16<true>(glyph, face->glyph->bitmap, doBGR, do Vert,
282 fPreBlend.fR, fPreBlend.fG, fPreBlend .fB);
283 } else {
284 copyFT2LCD16<false>(glyph, face->glyph->bitmap, doBGR, d oVert,
285 fPreBlend.fR, fPreBlend.fG, fPreBlen d.fB);
286 }
287 } else {
288 target.width = glyph.fWidth;
289 target.rows = glyph.fHeight;
290 target.pitch = glyph.rowBytes();
291 target.buffer = reinterpret_cast<uint8_t*>(glyph.fImage);
292 target.pixel_mode = compute_pixel_mode(
293 (SkMask::Format)fRec.fMaskFo rmat);
294 target.num_grays = 256;
295
296 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
297 FT_Outline_Get_Bitmap(face->glyph->library, outline, &target );
298 }
299 }
300 break;
301
302 case FT_GLYPH_FORMAT_BITMAP:
303 if (fRec.fFlags & SkScalerContext::kEmbolden_Flag &&
304 !(face->style_flags & FT_STYLE_FLAG_BOLD)) {
305 FT_GlyphSlot_Own_Bitmap(face->glyph);
306 FT_Bitmap_Embolden(face->glyph->library, &face->glyph->bitmap, k BitmapEmboldenStrength, 0);
134 } 307 }
135 308
136 int dx = 0, dy = 0;
137 if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
138 dx = SkFixedToFDot6(glyph.getSubXFixed());
139 dy = SkFixedToFDot6(glyph.getSubYFixed());
140 // negate dy since freetype-y-goes-up and skia-y-goes-down
141 dy = -dy;
142 }
143 FT_Outline_Get_CBox(outline, &bbox);
144 /*
145 what we really want to do for subpixel is
146 offset(dx, dy)
147 compute_bounds
148 offset(bbox & !63)
149 but that is two calls to offset, so we do the following, which
150 achieves the same thing with only one offset call.
151 */
152 FT_Outline_Translate(outline, dx - ((bbox.xMin + dx) & ~63),
153 dy - ((bbox.yMin + dy) & ~63));
154
155 if (SkMask::kLCD16_Format == glyph.fMaskFormat) { 309 if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
156 FT_Render_Glyph(face->glyph, doVert ? FT_RENDER_MODE_LCD_V : FT_ RENDER_MODE_LCD); 310 // special-case kLCD16_Format - no scaling currently supported
311 SkASSERT_CONTINUE(glyph.fWidth == face->glyph->bitmap.width);
312 SkASSERT_CONTINUE(glyph.fHeight == face->glyph->bitmap.rows);
313 SkASSERT_CONTINUE(glyph.fTop == -face->glyph->bitmap_top);
314 SkASSERT_CONTINUE(glyph.fLeft == face->glyph->bitmap_left);
157 if (fPreBlend.isApplicable()) { 315 if (fPreBlend.isApplicable()) {
158 copyFT2LCD16<true>(glyph, face->glyph->bitmap, doBGR, doVert , 316 copyFT2LCD16<true>(glyph, face->glyph->bitmap, doBGR, doVert ,
159 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB) ; 317 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB) ;
160 } else {
161 copyFT2LCD16<false>(glyph, face->glyph->bitmap, doBGR, doVer t,
162 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB );
163 }
164 } else {
165 target.width = glyph.fWidth;
166 target.rows = glyph.fHeight;
167 target.pitch = glyph.rowBytes();
168 target.buffer = reinterpret_cast<uint8_t*>(glyph.fImage);
169 target.pixel_mode = compute_pixel_mode(
170 (SkMask::Format)fRec.fMaskFormat );
171 target.num_grays = 256;
172
173 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
174 FT_Outline_Get_Bitmap(face->glyph->library, outline, &target);
175 }
176 } break;
177
178 case FT_GLYPH_FORMAT_BITMAP: {
179 if (fRec.fFlags & SkScalerContext::kEmbolden_Flag) {
180 FT_GlyphSlot_Own_Bitmap(face->glyph);
181 FT_Bitmap_Embolden(face->glyph->library, &face->glyph->bitmap, k BitmapEmboldenStrength, 0);
182 }
183 SkASSERT_CONTINUE(glyph.fWidth == face->glyph->bitmap.width);
184 SkASSERT_CONTINUE(glyph.fHeight == face->glyph->bitmap.rows);
185 SkASSERT_CONTINUE(glyph.fTop == -face->glyph->bitmap_top);
186 SkASSERT_CONTINUE(glyph.fLeft == face->glyph->bitmap_left);
187
188 const uint8_t* src = (const uint8_t*)face->glyph->bitmap.buffer;
189 uint8_t* dst = (uint8_t*)glyph.fImage;
190
191 if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY ||
192 (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO &&
193 glyph.fMaskFormat == SkMask::kBW_Format)) {
194 unsigned srcRowBytes = face->glyph->bitmap.pitch;
195 unsigned dstRowBytes = glyph.rowBytes();
196 unsigned minRowBytes = SkMin32(srcRowBytes, dstRowBytes);
197 unsigned extraRowBytes = dstRowBytes - minRowBytes;
198
199 for (int y = face->glyph->bitmap.rows - 1; y >= 0; --y) {
200 memcpy(dst, src, minRowBytes);
201 memset(dst + minRowBytes, 0, extraRowBytes);
202 src += srcRowBytes;
203 dst += dstRowBytes;
204 }
205 } else if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO &&
206 glyph.fMaskFormat == SkMask::kA8_Format) {
207 for (int y = 0; y < face->glyph->bitmap.rows; ++y) {
208 uint8_t byte = 0;
209 int bits = 0;
210 const uint8_t* src_row = src;
211 uint8_t* dst_row = dst;
212
213 for (int x = 0; x < face->glyph->bitmap.width; ++x) {
214 if (!bits) {
215 byte = *src_row++;
216 bits = 8;
217 }
218
219 *dst_row++ = byte & 0x80 ? 0xff : 0;
220 bits--;
221 byte <<= 1;
222 }
223
224 src += face->glyph->bitmap.pitch;
225 dst += glyph.rowBytes();
226 }
227 } else if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
228 if (fPreBlend.isApplicable()) {
229 copyFT2LCD16<true>(glyph, face->glyph->bitmap, doBGR, doVert ,
230 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB) ;
231 } else { 318 } else {
232 copyFT2LCD16<false>(glyph, face->glyph->bitmap, doBGR, doVer t, 319 copyFT2LCD16<false>(glyph, face->glyph->bitmap, doBGR, doVer t,
233 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB ); 320 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB );
234 } 321 }
235 } else { 322 } else {
236 SkDEBUGFAIL("unknown glyph bitmap transform needed"); 323 if (glyph.fWidth != face->glyph->bitmap.width ||
324 glyph.fHeight != face->glyph->bitmap.rows ||
325 glyph.fTop != -face->glyph->bitmap_top ||
326 glyph.fLeft != face->glyph->bitmap_left) {
327 // glyph image needs scaling
328 // start by copying FT2 image into an SkBitmap
329 SkBitmap unscaledBitmap;
330 unscaledBitmap.setConfig(skConfigForFTPixelMode(face->glyph- >bitmap.pixel_mode),
331 face->glyph->bitmap.width,
332 face->glyph->bitmap.rows);
333 unscaledBitmap.allocPixels();
334 copyFTBitmap(face->glyph->bitmap,
335 reinterpret_cast<uint8_t*>(unscaledBitmap.getPi xels()),
336 skFormatForFTPixelMode(face->glyph->bitmap.pixe l_mode),
337 unscaledBitmap.rowBytes());
338 // wrap the destination SkGlyph's image data into a bitmap
339 SkBitmap dstBitmap;
340 dstBitmap.setConfig(skConfigForFormat(glyph.fMaskFormat),
341 glyph.fWidth, glyph.fHeight, glyph.rowBytes());
342 dstBitmap.setPixels(glyph.fImage);
343 // scale unscaledBitmap into dstBitmap
344 SkCanvas canvas(dstBitmap);
345 canvas.clear(SK_ColorTRANSPARENT);
346 canvas.scale(SkIntToScalar(glyph.fWidth)
347 / SkIntToScalar(face->glyph->bitmap.width),
348 SkIntToScalar(glyph.fHeight)
349 / SkIntToScalar(face->glyph->bitmap.rows));
350 SkPaint paint;
351 paint.setFilterLevel(SkPaint::kLow_FilterLevel);
352 canvas.drawBitmap(unscaledBitmap, 0, 0, &paint);
353 } else {
354 // no scaling needed - directly copy glyph data
355 copyFTBitmap(face->glyph->bitmap, reinterpret_cast<uint8_t*> (glyph.fImage),
356 glyph.fMaskFormat, glyph.rowBytes());
357 }
237 } 358 }
238 } break; 359 break;
239 360
240 default: 361 default:
241 SkDEBUGFAIL("unknown glyph format"); 362 SkDEBUGFAIL("unknown glyph format");
242 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight); 363 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
243 return; 364 return;
244 } 365 }
245 366
246 // We used to always do this pre-USE_COLOR_LUMINANCE, but with colorlum, 367 // We used to always do this pre-USE_COLOR_LUMINANCE, but with colorlum,
247 // it is optional 368 // it is optional
248 #if defined(SK_GAMMA_APPLY_TO_A8) 369 #if defined(SK_GAMMA_APPLY_TO_A8)
249 if (SkMask::kA8_Format == glyph.fMaskFormat && fPreBlend.isApplicable()) { 370 if (SkMask::kA8_Format == glyph.fMaskFormat && fPreBlend.isApplicable()) {
250 uint8_t* SK_RESTRICT dst = (uint8_t*)glyph.fImage; 371 uint8_t* SK_RESTRICT dst = (uint8_t*)glyph.fImage;
251 unsigned rowBytes = glyph.rowBytes(); 372 unsigned rowBytes = glyph.rowBytes();
252 373
253 for (int y = glyph.fHeight - 1; y >= 0; --y) { 374 for (int y = glyph.fHeight - 1; y >= 0; --y) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 path->close(); 439 path->close();
319 } 440 }
320 441
321 void SkScalerContext_FreeType_Base::emboldenOutline(FT_Face face, FT_Outline* ou tline) 442 void SkScalerContext_FreeType_Base::emboldenOutline(FT_Face face, FT_Outline* ou tline)
322 { 443 {
323 FT_Pos strength; 444 FT_Pos strength;
324 strength = FT_MulFix(face->units_per_EM, face->size->metrics.y_scale) 445 strength = FT_MulFix(face->units_per_EM, face->size->metrics.y_scale)
325 / 24; 446 / 24;
326 FT_Outline_Embolden(outline, strength); 447 FT_Outline_Embolden(outline, strength);
327 } 448 }
OLDNEW
« src/ports/SkFontHost_FreeType.cpp ('K') | « src/ports/SkFontHost_FreeType.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698