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

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: Rebase against current; build with older FreeTypes. Created 7 years 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
19 22
23 // FT_LOAD_COLOR and the corresponding FT_Pixel_Mode::FT_PIXEL_MODE_BGRA
24 // were introduced in FreeType 2.5.0.
25 // The following may be removed once FreeType 2.5.0 is required to build.
26 #ifndef FT_LOAD_COLOR
27 # define FT_LOAD_COLOR ( 1L << 20 )
28 # define FT_PIXEL_MODE_BGRA 7
29 #endif
30
20 static FT_Pixel_Mode compute_pixel_mode(SkMask::Format format) { 31 static FT_Pixel_Mode compute_pixel_mode(SkMask::Format format) {
21 switch (format) { 32 switch (format) {
22 case SkMask::kBW_Format: 33 case SkMask::kBW_Format:
23 return FT_PIXEL_MODE_MONO; 34 return FT_PIXEL_MODE_MONO;
24 case SkMask::kA8_Format: 35 case SkMask::kA8_Format:
25 default: 36 default:
26 return FT_PIXEL_MODE_GRAY; 37 return FT_PIXEL_MODE_GRAY;
27 } 38 }
28 } 39 }
29 40
(...skipping 23 matching lines...) Expand all
53 } else { 64 } else {
54 SkASSERT(glyph.fHeight == bitmap.rows); 65 SkASSERT(glyph.fHeight == bitmap.rows);
55 } 66 }
56 67
57 uint16_t* dst = reinterpret_cast<uint16_t*>(glyph.fImage); 68 uint16_t* dst = reinterpret_cast<uint16_t*>(glyph.fImage);
58 const size_t dstRB = glyph.rowBytes(); 69 const size_t dstRB = glyph.rowBytes();
59 const int width = glyph.fWidth; 70 const int width = glyph.fWidth;
60 const uint8_t* src = bitmap.buffer; 71 const uint8_t* src = bitmap.buffer;
61 72
62 switch (bitmap.pixel_mode) { 73 switch (bitmap.pixel_mode) {
63 case FT_PIXEL_MODE_MONO: { 74 case FT_PIXEL_MODE_MONO:
64 for (int y = 0; y < glyph.fHeight; ++y) { 75 for (int y = 0; y < glyph.fHeight; ++y) {
65 for (int x = 0; x < width; ++x) { 76 for (int x = 0; x < width; ++x) {
66 dst[x] = -bittst(src, x); 77 dst[x] = -bittst(src, x);
67 } 78 }
68 dst = (uint16_t*)((char*)dst + dstRB); 79 dst = (uint16_t*)((char*)dst + dstRB);
69 src += bitmap.pitch; 80 src += bitmap.pitch;
70 } 81 }
71 } break; 82 break;
72 case FT_PIXEL_MODE_GRAY: { 83 case FT_PIXEL_MODE_GRAY:
73 for (int y = 0; y < glyph.fHeight; ++y) { 84 for (int y = 0; y < glyph.fHeight; ++y) {
74 for (int x = 0; x < width; ++x) { 85 for (int x = 0; x < width; ++x) {
75 dst[x] = grayToRGB16(src[x]); 86 dst[x] = grayToRGB16(src[x]);
76 } 87 }
77 dst = (uint16_t*)((char*)dst + dstRB); 88 dst = (uint16_t*)((char*)dst + dstRB);
78 src += bitmap.pitch; 89 src += bitmap.pitch;
79 } 90 }
80 } break; 91 break;
81 default: { 92 default:
82 SkASSERT(lcdIsVert || (glyph.fWidth * 3 == bitmap.width)); 93 SkASSERT(lcdIsVert || (glyph.fWidth * 3 == bitmap.width));
83 for (int y = 0; y < glyph.fHeight; y++) { 94 for (int y = 0; y < glyph.fHeight; y++) {
84 if (lcdIsVert) { // vertical stripes 95 if (lcdIsVert) { // vertical stripes
85 const uint8_t* srcR = src; 96 const uint8_t* srcR = src;
86 const uint8_t* srcG = srcR + bitmap.pitch; 97 const uint8_t* srcG = srcR + bitmap.pitch;
87 const uint8_t* srcB = srcG + bitmap.pitch; 98 const uint8_t* srcB = srcG + bitmap.pitch;
88 if (lcdIsBGR) { 99 if (lcdIsBGR) {
89 SkTSwap(srcR, srcB); 100 SkTSwap(srcR, srcB);
90 } 101 }
91 for (int x = 0; x < width; x++) { 102 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), 119 dst[x] = packTriple(sk_apply_lut_if<APPLY_PREBLEND>( triple[0], tableR),
109 sk_apply_lut_if<APPLY_PREBLEND>( triple[1], tableG), 120 sk_apply_lut_if<APPLY_PREBLEND>( triple[1], tableG),
110 sk_apply_lut_if<APPLY_PREBLEND>( triple[2], tableB)); 121 sk_apply_lut_if<APPLY_PREBLEND>( triple[2], tableB));
111 triple += 3; 122 triple += 3;
112 } 123 }
113 } 124 }
114 src += bitmap.pitch; 125 src += bitmap.pitch;
115 } 126 }
116 dst = (uint16_t*)((char*)dst + dstRB); 127 dst = (uint16_t*)((char*)dst + dstRB);
117 } 128 }
118 } break; 129 break;
130 }
131 }
132
133 // copies an FT_Bitmap's pixel data into a buffer with identical dimensions
134 static void copyFTBitmap(const FT_Bitmap& srcFTBitmap, SkMask& dstMask) {
135 const uint8_t* src = reinterpret_cast<const uint8_t*>(srcFTBitmap.buffer);
136 uint8_t* dst = dstMask.fImage;
137 const SkMask::Format dstFormat = static_cast<SkMask::Format>(dstMask.fFormat );
138 size_t dstRowBytes = dstMask.fRowBytes;
139 size_t width = srcFTBitmap.width;
140 size_t height = srcFTBitmap.rows;
141 size_t srcRowBytes = srcFTBitmap.pitch;
142
143 if ((SkMask::kA8_Format == dstFormat &&
144 FT_PIXEL_MODE_GRAY == srcFTBitmap.pixel_mode) ||
145 (SkMask::kBW_Format == dstFormat &&
146 FT_PIXEL_MODE_MONO == srcFTBitmap.pixel_mode)) {
147 // TODO: test 1bpp bitmap font into kBW_Format glyph
148 size_t minRowBytes = SkMin32(srcRowBytes, dstRowBytes);
149 size_t extraRowBytes = dstRowBytes - minRowBytes;
150 for (int y = height - 1; y >= 0; --y) {
151 memcpy(dst, src, minRowBytes);
152 memset(dst + minRowBytes, 0, extraRowBytes);
153 src += srcRowBytes;
154 dst += dstRowBytes;
155 }
156 } else if (SkMask::kA8_Format == dstFormat &&
157 FT_PIXEL_MODE_MONO == srcFTBitmap.pixel_mode) {
158 // TODO: test 1bpp bitmap font into kA8_Format glyph
159 for (size_t y = 0; y < height; ++y) {
160 uint8_t byte = 0;
161 int bits = 0;
162 const uint8_t* src_row = src;
163 uint8_t* dst_row = dst;
164 for (size_t x = 0; x < width; ++x) {
165 if (!bits) {
166 byte = *src_row++;
167 bits = 8;
168 }
169 *dst_row++ = byte & 0x80 ? 0xff : 0;
170 bits--;
171 byte <<= 1;
172 }
173 src += srcRowBytes;
174 dst += dstRowBytes;
175 }
176 } else if (SkMask::kARGB32_Format == dstFormat &&
177 FT_PIXEL_MODE_BGRA == srcFTBitmap.pixel_mode) {
178 size_t minWidth = SkMin32(width, SkMin32(srcRowBytes, dstRowBytes) / 4);
179 size_t extraRowBytes = dstRowBytes - (4 * minWidth);
180 for (size_t y = 0; y < height; ++y) {
181 const uint8_t* src_row = src;
182 uint8_t* dst_row = dst;
183 for (size_t x = 0; x < minWidth; ++x) {
184 uint8_t blue = *src_row++;
185 uint8_t green = *src_row++;
186 uint8_t red = *src_row++;
187 uint8_t alpha = *src_row++;
188 *dst_row++ = red;
189 *dst_row++ = green;
190 *dst_row++ = blue;
191 *dst_row++ = alpha;
192 }
193 memset(dst_row, 0, extraRowBytes);
194 src += srcRowBytes;
195 dst += dstRowBytes;
196 }
197 } else {
198 SkDEBUGFAIL("unsupported combination of FT_PIXEL_MODE and SkMask::Format ");
199 }
200 }
201
202 inline SkMask::Format skFormatForFTPixelMode(FT_Pixel_Mode pixel_mode) {
203 switch (pixel_mode) {
204 case FT_PIXEL_MODE_GRAY:
205 return SkMask::kA8_Format;
206 case FT_PIXEL_MODE_MONO:
207 return SkMask::kBW_Format;
208 case FT_PIXEL_MODE_BGRA:
209 return SkMask::kARGB32_Format;
210 default:
211 SkDEBUGFAIL("unsupported FT_PIXEL_MODE");
212 return SkMask::kA8_Format;
213 }
214 }
215
216 inline SkBitmap::Config skConfigForFTPixelMode(FT_Pixel_Mode pixel_mode) {
217 switch (pixel_mode) {
218 case FT_PIXEL_MODE_GRAY:
219 return SkBitmap::kA8_Config;
220 case FT_PIXEL_MODE_MONO:
221 return SkBitmap::kA1_Config;
222 case FT_PIXEL_MODE_BGRA:
223 return SkBitmap::kARGB_8888_Config;
224 default:
225 SkDEBUGFAIL("unsupported FT_PIXEL_MODE");
226 return SkBitmap::kA8_Config;
227 }
228 }
229
230 inline SkBitmap::Config skConfigForFormat(SkMask::Format format) {
231 switch (format) {
232 case SkMask::kA8_Format:
233 return SkBitmap::kA8_Config;
234 case SkMask::kBW_Format:
235 return SkBitmap::kA1_Config;
236 case SkMask::kARGB32_Format:
237 return SkBitmap::kARGB_8888_Config;
238 default:
239 SkDEBUGFAIL("unsupported FT_PIXEL_MODE");
240 return SkBitmap::kA8_Config;
119 } 241 }
120 } 242 }
121 243
122 void SkScalerContext_FreeType_Base::generateGlyphImage(FT_Face face, const SkGly ph& glyph) { 244 void SkScalerContext_FreeType_Base::generateGlyphImage(FT_Face face, const SkGly ph& glyph) {
123 const bool doBGR = SkToBool(fRec.fFlags & SkScalerContext::kLCD_BGROrder_Fla g); 245 const bool doBGR = SkToBool(fRec.fFlags & SkScalerContext::kLCD_BGROrder_Fla g);
124 const bool doVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Fl ag); 246 const bool doVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Fl ag);
125 247
126 switch ( face->glyph->format ) { 248 switch ( face->glyph->format ) {
127 case FT_GLYPH_FORMAT_OUTLINE: { 249 case FT_GLYPH_FORMAT_OUTLINE: {
128 FT_Outline* outline = &face->glyph->outline; 250 FT_Outline* outline = &face->glyph->outline;
129 FT_BBox bbox; 251 FT_BBox bbox;
130 FT_Bitmap target; 252 FT_Bitmap target;
131 253
132 if (fRec.fFlags & SkScalerContext::kEmbolden_Flag) { 254 if (fRec.fFlags & SkScalerContext::kEmbolden_Flag &&
255 !(face->style_flags & FT_STYLE_FLAG_BOLD)) {
133 emboldenOutline(face, outline); 256 emboldenOutline(face, outline);
134 } 257 }
135 258
136 int dx = 0, dy = 0; 259 int dx = 0, dy = 0;
137 if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) { 260 if (fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag) {
138 dx = SkFixedToFDot6(glyph.getSubXFixed()); 261 dx = SkFixedToFDot6(glyph.getSubXFixed());
139 dy = SkFixedToFDot6(glyph.getSubYFixed()); 262 dy = SkFixedToFDot6(glyph.getSubYFixed());
140 // negate dy since freetype-y-goes-up and skia-y-goes-down 263 // negate dy since freetype-y-goes-up and skia-y-goes-down
141 dy = -dy; 264 dy = -dy;
142 } 265 }
(...skipping 16 matching lines...) Expand all
159 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB) ; 282 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB) ;
160 } else { 283 } else {
161 copyFT2LCD16<false>(glyph, face->glyph->bitmap, doBGR, doVer t, 284 copyFT2LCD16<false>(glyph, face->glyph->bitmap, doBGR, doVer t,
162 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB ); 285 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB );
163 } 286 }
164 } else { 287 } else {
165 target.width = glyph.fWidth; 288 target.width = glyph.fWidth;
166 target.rows = glyph.fHeight; 289 target.rows = glyph.fHeight;
167 target.pitch = glyph.rowBytes(); 290 target.pitch = glyph.rowBytes();
168 target.buffer = reinterpret_cast<uint8_t*>(glyph.fImage); 291 target.buffer = reinterpret_cast<uint8_t*>(glyph.fImage);
169 target.pixel_mode = compute_pixel_mode( 292 target.pixel_mode = compute_pixel_mode( (SkMask::Format)fRec.fMa skFormat);
170 (SkMask::Format)fRec.fMaskFormat );
171 target.num_grays = 256; 293 target.num_grays = 256;
172 294
173 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight); 295 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
174 FT_Outline_Get_Bitmap(face->glyph->library, outline, &target); 296 FT_Outline_Get_Bitmap(face->glyph->library, outline, &target);
175 } 297 }
176 } break; 298 }
299 break;
177 300
178 case FT_GLYPH_FORMAT_BITMAP: { 301 case FT_GLYPH_FORMAT_BITMAP:
179 if (fRec.fFlags & SkScalerContext::kEmbolden_Flag) { 302 if (fRec.fFlags & SkScalerContext::kEmbolden_Flag &&
303 !(face->style_flags & FT_STYLE_FLAG_BOLD)) {
180 FT_GlyphSlot_Own_Bitmap(face->glyph); 304 FT_GlyphSlot_Own_Bitmap(face->glyph);
181 FT_Bitmap_Embolden(face->glyph->library, &face->glyph->bitmap, k BitmapEmboldenStrength, 0); 305 FT_Bitmap_Embolden(face->glyph->library, &face->glyph->bitmap,
306 kBitmapEmboldenStrength, 0);
182 } 307 }
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 308
188 const uint8_t* src = (const uint8_t*)face->glyph->bitmap.buffer; 309 if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
189 uint8_t* dst = (uint8_t*)glyph.fImage; 310 // special-case kLCD16_Format - no scaling currently supported
190 311 SkASSERT_CONTINUE(glyph.fWidth == face->glyph->bitmap.width);
191 if (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY || 312 SkASSERT_CONTINUE(glyph.fHeight == face->glyph->bitmap.rows);
192 (face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO && 313 SkASSERT_CONTINUE(glyph.fTop == -face->glyph->bitmap_top);
193 glyph.fMaskFormat == SkMask::kBW_Format)) { 314 SkASSERT_CONTINUE(glyph.fLeft == face->glyph->bitmap_left);
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()) { 315 if (fPreBlend.isApplicable()) {
229 copyFT2LCD16<true>(glyph, face->glyph->bitmap, doBGR, doVert , 316 copyFT2LCD16<true>(glyph, face->glyph->bitmap, doBGR, doVert ,
230 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB) ; 317 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;
bungeman-skia 2013/11/27 00:04:49 This scaling code is incorrect for two reasons. Fi
330 FT_Pixel_Mode pixel_mode =
331 static_cast<FT_Pixel_Mode>(face->glyph->bitmap.pixel _mode);
332 unscaledBitmap.setConfig(skConfigForFTPixelMode(pixel_mode),
333 face->glyph->bitmap.width,
334 face->glyph->bitmap.rows);
335 unscaledBitmap.allocPixels();
336 SkMask dstMask;
337 dstMask.fImage = reinterpret_cast<uint8_t*>(unscaledBitmap.g etPixels());
338 dstMask.fRowBytes = unscaledBitmap.rowBytes();
339 dstMask.fFormat = skFormatForFTPixelMode(pixel_mode);
340 copyFTBitmap(face->glyph->bitmap, dstMask);
341 // wrap the destination SkGlyph's image data into a bitmap
342 SkBitmap dstBitmap;
343 SkMask::Format maskFormat = static_cast<SkMask::Format>(glyp h.fMaskFormat);
344 dstBitmap.setConfig(skConfigForFormat(maskFormat),
345 glyph.fWidth, glyph.fHeight, glyph.rowBytes());
346 dstBitmap.setPixels(glyph.fImage);
347 // scale unscaledBitmap into dstBitmap
348 SkCanvas canvas(dstBitmap);
349 canvas.clear(SK_ColorTRANSPARENT);
350 canvas.scale(SkIntToScalar(glyph.fWidth)
351 / SkIntToScalar(face->glyph->bitmap.width),
352 SkIntToScalar(glyph.fHeight)
353 / SkIntToScalar(face->glyph->bitmap.rows));
354 SkPaint paint;
355 paint.setFilterLevel(SkPaint::kLow_FilterLevel);
356 canvas.drawBitmap(unscaledBitmap, 0, 0, &paint);
357 } else {
358 // no scaling needed - directly copy glyph data
359 SkMask dstMask;
360 glyph.toMask(&dstMask);
361 copyFTBitmap(face->glyph->bitmap, dstMask);
362 }
237 } 363 }
238 } break; 364 break;
239 365
240 default: 366 default:
241 SkDEBUGFAIL("unknown glyph format"); 367 SkDEBUGFAIL("unknown glyph format");
242 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight); 368 memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
243 return; 369 return;
244 } 370 }
245 371
246 // We used to always do this pre-USE_COLOR_LUMINANCE, but with colorlum, 372 // We used to always do this pre-USE_COLOR_LUMINANCE, but with colorlum,
247 // it is optional 373 // it is optional
248 #if defined(SK_GAMMA_APPLY_TO_A8) 374 #if defined(SK_GAMMA_APPLY_TO_A8)
249 if (SkMask::kA8_Format == glyph.fMaskFormat && fPreBlend.isApplicable()) { 375 if (SkMask::kA8_Format == glyph.fMaskFormat && fPreBlend.isApplicable()) {
250 uint8_t* SK_RESTRICT dst = (uint8_t*)glyph.fImage; 376 uint8_t* SK_RESTRICT dst = (uint8_t*)glyph.fImage;
251 unsigned rowBytes = glyph.rowBytes(); 377 unsigned rowBytes = glyph.rowBytes();
252 378
253 for (int y = glyph.fHeight - 1; y >= 0; --y) { 379 for (int y = glyph.fHeight - 1; y >= 0; --y) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 path->close(); 444 path->close();
319 } 445 }
320 446
321 void SkScalerContext_FreeType_Base::emboldenOutline(FT_Face face, FT_Outline* ou tline) 447 void SkScalerContext_FreeType_Base::emboldenOutline(FT_Face face, FT_Outline* ou tline)
322 { 448 {
323 FT_Pos strength; 449 FT_Pos strength;
324 strength = FT_MulFix(face->units_per_EM, face->size->metrics.y_scale) 450 strength = FT_MulFix(face->units_per_EM, face->size->metrics.y_scale)
325 / 24; 451 / 24;
326 FT_Outline_Embolden(outline, strength); 452 FT_Outline_Embolden(outline, strength);
327 } 453 }
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