OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 Google Inc. All rights reserved. | 2 * Copyright (c) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 24 matching lines...) Expand all Loading... |
35 #include "hb.h" | 35 #include "hb.h" |
36 #if OS(MACOSX) | 36 #if OS(MACOSX) |
37 #include "hb-coretext.h" | 37 #include "hb-coretext.h" |
38 #endif | 38 #endif |
39 #include "SkPaint.h" | 39 #include "SkPaint.h" |
40 #include "SkPath.h" | 40 #include "SkPath.h" |
41 #include "SkPoint.h" | 41 #include "SkPoint.h" |
42 #include "SkRect.h" | 42 #include "SkRect.h" |
43 #include "SkTypeface.h" | 43 #include "SkTypeface.h" |
44 #include "SkUtils.h" | 44 #include "SkUtils.h" |
| 45 #include "platform/fonts/FontCache.h" |
45 #include "platform/fonts/FontPlatformData.h" | 46 #include "platform/fonts/FontPlatformData.h" |
46 #include "platform/fonts/SimpleFontData.h" | 47 #include "platform/fonts/SimpleFontData.h" |
47 #include "platform/fonts/shaping/HarfBuzzShaper.h" | 48 #include "platform/fonts/shaping/HarfBuzzShaper.h" |
48 #include "wtf/HashMap.h" | 49 #include "wtf/HashMap.h" |
49 | 50 |
50 namespace blink { | 51 namespace blink { |
51 | 52 |
52 const hb_tag_t HarfBuzzFace::vertTag = HB_TAG('v', 'e', 'r', 't'); | 53 const hb_tag_t HarfBuzzFace::vertTag = HB_TAG('v', 'e', 'r', 't'); |
53 const hb_tag_t HarfBuzzFace::vrt2Tag = HB_TAG('v', 'r', 't', '2'); | 54 const hb_tag_t HarfBuzzFace::vrt2Tag = HB_TAG('v', 'r', 't', '2'); |
54 | 55 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 if (m_scriptForVerticalText == HB_SCRIPT_INVALID) | 139 if (m_scriptForVerticalText == HB_SCRIPT_INVALID) |
139 m_scriptForVerticalText = findScriptForVerticalGlyphSubstitution(m_face)
; | 140 m_scriptForVerticalText = findScriptForVerticalGlyphSubstitution(m_face)
; |
140 hb_buffer_set_script(buffer, m_scriptForVerticalText); | 141 hb_buffer_set_script(buffer, m_scriptForVerticalText); |
141 } | 142 } |
142 | 143 |
143 struct HarfBuzzFontData { | 144 struct HarfBuzzFontData { |
144 HarfBuzzFontData(WTF::HashMap<uint32_t, uint16_t>* glyphCacheForFaceCacheEnt
ry) | 145 HarfBuzzFontData(WTF::HashMap<uint32_t, uint16_t>* glyphCacheForFaceCacheEnt
ry) |
145 : m_glyphCacheForFaceCacheEntry(glyphCacheForFaceCacheEntry) | 146 : m_glyphCacheForFaceCacheEntry(glyphCacheForFaceCacheEntry) |
146 { } | 147 { } |
147 SkPaint m_paint; | 148 SkPaint m_paint; |
| 149 RefPtr<SimpleFontData> m_simpleFontData; |
148 WTF::HashMap<uint32_t, uint16_t>* m_glyphCacheForFaceCacheEntry; | 150 WTF::HashMap<uint32_t, uint16_t>* m_glyphCacheForFaceCacheEntry; |
149 }; | 151 }; |
150 | 152 |
151 static hb_position_t SkiaScalarToHarfBuzzPosition(SkScalar value) | 153 static hb_position_t SkiaScalarToHarfBuzzPosition(SkScalar value) |
152 { | 154 { |
153 return SkScalarToFixed(value); | 155 return SkScalarToFixed(value); |
154 } | 156 } |
155 | 157 |
156 static void SkiaGetGlyphWidthAndExtents(SkPaint* paint, hb_codepoint_t codepoint
, hb_position_t* width, hb_glyph_extents_t* extents) | 158 static void SkiaGetGlyphWidthAndExtents(SkPaint* paint, hb_codepoint_t codepoint
, hb_position_t* width, hb_glyph_extents_t* extents) |
157 { | 159 { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 return advance; | 206 return advance; |
205 } | 207 } |
206 | 208 |
207 static hb_bool_t harfBuzzGetGlyphHorizontalOrigin(hb_font_t* hbFont, void* fontD
ata, hb_codepoint_t glyph, hb_position_t* x, hb_position_t* y, void* userData) | 209 static hb_bool_t harfBuzzGetGlyphHorizontalOrigin(hb_font_t* hbFont, void* fontD
ata, hb_codepoint_t glyph, hb_position_t* x, hb_position_t* y, void* userData) |
208 { | 210 { |
209 // Just return true, following the way that HarfBuzz-FreeType | 211 // Just return true, following the way that HarfBuzz-FreeType |
210 // implementation does. | 212 // implementation does. |
211 return true; | 213 return true; |
212 } | 214 } |
213 | 215 |
| 216 static hb_bool_t harfBuzzGetGlyphVerticalOrigin(hb_font_t* hbFont, void* fontDat
a, hb_codepoint_t glyph, hb_position_t* x, hb_position_t* y, void* userData) |
| 217 { |
| 218 HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData)
; |
| 219 const OpenTypeVerticalData* verticalData = hbFontData->m_simpleFontData->ver
ticalData(); |
| 220 if (!verticalData) |
| 221 return false; |
| 222 |
| 223 float result[] = { 0, 0 }; |
| 224 Glyph theGlyph = glyph; |
| 225 verticalData->getVerticalTranslationsForGlyphs(hbFontData->m_simpleFontData.
get(), &theGlyph, 1, result); |
| 226 *x = SkiaScalarToHarfBuzzPosition(-result[0]); |
| 227 *y = SkiaScalarToHarfBuzzPosition(-result[1]); |
| 228 return true; |
| 229 } |
| 230 |
| 231 static hb_position_t harfBuzzGetGlyphVerticalAdvance(hb_font_t* hbFont, void* fo
ntData, hb_codepoint_t glyph, void* userData) |
| 232 { |
| 233 HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData)
; |
| 234 const OpenTypeVerticalData* verticalData = hbFontData->m_simpleFontData->ver
ticalData(); |
| 235 if (!verticalData) |
| 236 return SkiaScalarToHarfBuzzPosition(hbFontData->m_simpleFontData->fontMe
trics().height()); |
| 237 |
| 238 Glyph theGlyph = glyph; |
| 239 float advanceHeight = verticalData->advanceHeight(hbFontData->m_simpleFontDa
ta.get(), theGlyph); |
| 240 return SkiaScalarToHarfBuzzPosition(SkFloatToScalar(advanceHeight)); |
| 241 } |
| 242 |
214 static hb_position_t harfBuzzGetGlyphHorizontalKerning(hb_font_t*, void* fontDat
a, hb_codepoint_t leftGlyph, hb_codepoint_t rightGlyph, void*) | 243 static hb_position_t harfBuzzGetGlyphHorizontalKerning(hb_font_t*, void* fontDat
a, hb_codepoint_t leftGlyph, hb_codepoint_t rightGlyph, void*) |
215 { | 244 { |
216 HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData)
; | 245 HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData)
; |
217 if (hbFontData->m_paint.isVerticalText()) { | 246 if (hbFontData->m_paint.isVerticalText()) { |
218 // We don't support cross-stream kerning | 247 // We don't support cross-stream kerning |
219 return 0; | 248 return 0; |
220 } | 249 } |
221 | 250 |
222 SkTypeface* typeface = hbFontData->m_paint.getTypeface(); | 251 SkTypeface* typeface = hbFontData->m_paint.getTypeface(); |
223 | 252 |
224 const uint16_t glyphs[2] = { static_cast<uint16_t>(leftGlyph), static_cast<u
int16_t>(rightGlyph) }; | 253 const uint16_t glyphs[2] = { static_cast<uint16_t>(leftGlyph), static_cast<u
int16_t>(rightGlyph) }; |
225 int32_t kerningAdjustments[1] = { 0 }; | 254 int32_t kerningAdjustments[1] = { 0 }; |
226 | 255 |
227 if (typeface->getKerningPairAdjustments(glyphs, 2, kerningAdjustments)) { | 256 if (typeface->getKerningPairAdjustments(glyphs, 2, kerningAdjustments)) { |
228 SkScalar upm = SkIntToScalar(typeface->getUnitsPerEm()); | 257 SkScalar upm = SkIntToScalar(typeface->getUnitsPerEm()); |
229 SkScalar size = hbFontData->m_paint.getTextSize(); | 258 SkScalar size = hbFontData->m_paint.getTextSize(); |
230 return SkiaScalarToHarfBuzzPosition(SkScalarMulDiv(SkIntToScalar(kerning
Adjustments[0]), size, upm)); | 259 return SkiaScalarToHarfBuzzPosition(SkScalarMulDiv(SkIntToScalar(kerning
Adjustments[0]), size, upm)); |
231 } | 260 } |
232 | 261 |
233 return 0; | 262 return 0; |
234 } | 263 } |
235 | 264 |
236 | |
237 static hb_bool_t harfBuzzGetGlyphExtents(hb_font_t* hbFont, void* fontData, hb_c
odepoint_t glyph, hb_glyph_extents_t* extents, void* userData) | 265 static hb_bool_t harfBuzzGetGlyphExtents(hb_font_t* hbFont, void* fontData, hb_c
odepoint_t glyph, hb_glyph_extents_t* extents, void* userData) |
238 { | 266 { |
239 HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData)
; | 267 HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData)
; |
240 | 268 |
241 SkiaGetGlyphWidthAndExtents(&hbFontData->m_paint, glyph, 0, extents); | 269 SkiaGetGlyphWidthAndExtents(&hbFontData->m_paint, glyph, 0, extents); |
242 return true; | 270 return true; |
243 } | 271 } |
244 | 272 |
245 static hb_font_funcs_t* harfBuzzSkiaGetFontFuncs() | 273 static hb_font_funcs_t* harfBuzzSkiaGetFontFuncs() |
246 { | 274 { |
247 static hb_font_funcs_t* harfBuzzSkiaFontFuncs = 0; | 275 static hb_font_funcs_t* harfBuzzSkiaFontFuncs = 0; |
248 | 276 |
249 // We don't set callback functions which we can't support. | 277 // We don't set callback functions which we can't support. |
250 // HarfBuzz will use the fallback implementation if they aren't set. | 278 // HarfBuzz will use the fallback implementation if they aren't set. |
251 if (!harfBuzzSkiaFontFuncs) { | 279 if (!harfBuzzSkiaFontFuncs) { |
252 harfBuzzSkiaFontFuncs = hb_font_funcs_create(); | 280 harfBuzzSkiaFontFuncs = hb_font_funcs_create(); |
253 hb_font_funcs_set_glyph_func(harfBuzzSkiaFontFuncs, harfBuzzGetGlyph, 0,
0); | 281 hb_font_funcs_set_glyph_func(harfBuzzSkiaFontFuncs, harfBuzzGetGlyph, 0,
0); |
254 hb_font_funcs_set_glyph_h_advance_func(harfBuzzSkiaFontFuncs, harfBuzzGe
tGlyphHorizontalAdvance, 0, 0); | 282 hb_font_funcs_set_glyph_h_advance_func(harfBuzzSkiaFontFuncs, harfBuzzGe
tGlyphHorizontalAdvance, 0, 0); |
255 hb_font_funcs_set_glyph_h_kerning_func(harfBuzzSkiaFontFuncs, harfBuzzGe
tGlyphHorizontalKerning, 0, 0); | 283 hb_font_funcs_set_glyph_h_kerning_func(harfBuzzSkiaFontFuncs, harfBuzzGe
tGlyphHorizontalKerning, 0, 0); |
256 hb_font_funcs_set_glyph_h_origin_func(harfBuzzSkiaFontFuncs, harfBuzzGet
GlyphHorizontalOrigin, 0, 0); | 284 hb_font_funcs_set_glyph_h_origin_func(harfBuzzSkiaFontFuncs, harfBuzzGet
GlyphHorizontalOrigin, 0, 0); |
| 285 hb_font_funcs_set_glyph_v_advance_func(harfBuzzSkiaFontFuncs, harfBuzzGe
tGlyphVerticalAdvance, 0, 0); |
| 286 hb_font_funcs_set_glyph_v_origin_func(harfBuzzSkiaFontFuncs, harfBuzzGet
GlyphVerticalOrigin, 0, 0); |
257 hb_font_funcs_set_glyph_extents_func(harfBuzzSkiaFontFuncs, harfBuzzGetG
lyphExtents, 0, 0); | 287 hb_font_funcs_set_glyph_extents_func(harfBuzzSkiaFontFuncs, harfBuzzGetG
lyphExtents, 0, 0); |
258 hb_font_funcs_make_immutable(harfBuzzSkiaFontFuncs); | 288 hb_font_funcs_make_immutable(harfBuzzSkiaFontFuncs); |
259 } | 289 } |
260 return harfBuzzSkiaFontFuncs; | 290 return harfBuzzSkiaFontFuncs; |
261 } | 291 } |
262 | 292 |
263 #if !OS(MACOSX) | 293 #if !OS(MACOSX) |
264 static hb_blob_t* harfBuzzSkiaGetTable(hb_face_t* face, hb_tag_t tag, void* user
Data) | 294 static hb_blob_t* harfBuzzSkiaGetTable(hb_face_t* face, hb_tag_t tag, void* user
Data) |
265 { | 295 { |
266 SkTypeface* typeface = reinterpret_cast<SkTypeface*>(userData); | 296 SkTypeface* typeface = reinterpret_cast<SkTypeface*>(userData); |
(...skipping 30 matching lines...) Expand all Loading... |
297 hb_face_t* face = hb_face_create_for_tables(harfBuzzSkiaGetTable, m_platform
Data->typeface(), 0); | 327 hb_face_t* face = hb_face_create_for_tables(harfBuzzSkiaGetTable, m_platform
Data->typeface(), 0); |
298 #endif | 328 #endif |
299 ASSERT(face); | 329 ASSERT(face); |
300 return face; | 330 return face; |
301 } | 331 } |
302 | 332 |
303 hb_font_t* HarfBuzzFace::createFont() | 333 hb_font_t* HarfBuzzFace::createFont() |
304 { | 334 { |
305 HarfBuzzFontData* hbFontData = new HarfBuzzFontData(m_glyphCacheForFaceCache
Entry); | 335 HarfBuzzFontData* hbFontData = new HarfBuzzFontData(m_glyphCacheForFaceCache
Entry); |
306 m_platformData->setupPaint(&hbFontData->m_paint); | 336 m_platformData->setupPaint(&hbFontData->m_paint); |
| 337 hbFontData->m_simpleFontData = FontCache::fontCache()->fontDataFromFontPlatf
ormData(m_platformData); |
| 338 ASSERT(hbFontData->m_simpleFontData); |
307 hb_font_t* font = hb_font_create(m_face); | 339 hb_font_t* font = hb_font_create(m_face); |
308 hb_font_set_funcs(font, harfBuzzSkiaGetFontFuncs(), hbFontData, destroyHarfB
uzzFontData); | 340 hb_font_set_funcs(font, harfBuzzSkiaGetFontFuncs(), hbFontData, destroyHarfB
uzzFontData); |
309 float size = m_platformData->size(); | 341 float size = m_platformData->size(); |
310 int scale = SkiaScalarToHarfBuzzPosition(size); | 342 int scale = SkiaScalarToHarfBuzzPosition(size); |
311 hb_font_set_scale(font, scale, scale); | 343 hb_font_set_scale(font, scale, scale); |
312 hb_font_make_immutable(font); | 344 hb_font_make_immutable(font); |
313 return font; | 345 return font; |
314 } | 346 } |
315 | 347 |
316 } // namespace blink | 348 } // namespace blink |
OLD | NEW |