OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 Google Inc. All rights reserved. | 2 * Copyright (c) 2012 Google Inc. All rights reserved. |
3 * Copyright (c) 2014 BlackBerry Limited. All rights reserved. | 3 * Copyright (c) 2014 BlackBerry Limited. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 namespace blink { | 48 namespace blink { |
49 | 49 |
50 // Our implementation of the callbacks which HarfBuzz requires by using Skia | 50 // Our implementation of the callbacks which HarfBuzz requires by using Skia |
51 // calls. See the HarfBuzz source for references about what these callbacks do. | 51 // calls. See the HarfBuzz source for references about what these callbacks do. |
52 | 52 |
53 struct HarfBuzzFontData { | 53 struct HarfBuzzFontData { |
54 HarfBuzzFontData(WTF::HashMap<uint32_t, uint16_t>* glyphCacheForFaceCacheEnt
ry) | 54 HarfBuzzFontData(WTF::HashMap<uint32_t, uint16_t>* glyphCacheForFaceCacheEnt
ry) |
55 : m_glyphCacheForFaceCacheEntry(glyphCacheForFaceCacheEntry) | 55 : m_glyphCacheForFaceCacheEntry(glyphCacheForFaceCacheEntry) |
56 { } | 56 { } |
57 SkPaint m_paint; | 57 SkPaint m_paint; |
| 58 RefPtr<SimpleFontData> m_simpleFontData; |
58 WTF::HashMap<uint32_t, uint16_t>* m_glyphCacheForFaceCacheEntry; | 59 WTF::HashMap<uint32_t, uint16_t>* m_glyphCacheForFaceCacheEntry; |
59 }; | 60 }; |
60 | 61 |
61 static hb_position_t SkiaScalarToHarfBuzzPosition(SkScalar value) | 62 static hb_position_t SkiaScalarToHarfBuzzPosition(SkScalar value) |
62 { | 63 { |
63 return SkScalarToFixed(value); | 64 return SkScalarToFixed(value); |
64 } | 65 } |
65 | 66 |
66 static void SkiaGetGlyphWidthAndExtents(SkPaint* paint, hb_codepoint_t codepoint
, hb_position_t* width, hb_glyph_extents_t* extents) | 67 static void SkiaGetGlyphWidthAndExtents(SkPaint* paint, hb_codepoint_t codepoint
, hb_position_t* width, hb_glyph_extents_t* extents) |
67 { | 68 { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 return advance; | 115 return advance; |
115 } | 116 } |
116 | 117 |
117 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) | 118 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) |
118 { | 119 { |
119 // Just return true, following the way that HarfBuzz-FreeType | 120 // Just return true, following the way that HarfBuzz-FreeType |
120 // implementation does. | 121 // implementation does. |
121 return true; | 122 return true; |
122 } | 123 } |
123 | 124 |
| 125 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) |
| 126 { |
| 127 HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData)
; |
| 128 const OpenTypeVerticalData* verticalData = hbFontData->m_simpleFontData->ver
ticalData(); |
| 129 if (!verticalData) |
| 130 return false; |
| 131 |
| 132 float result[] = { 0, 0 }; |
| 133 Glyph theGlyph = glyph; |
| 134 verticalData->getVerticalTranslationsForGlyphs(hbFontData->m_simpleFontData.
get(), &theGlyph, 1, result); |
| 135 *x = SkiaScalarToHarfBuzzPosition(-result[0]); |
| 136 *y = SkiaScalarToHarfBuzzPosition(-result[1]); |
| 137 return true; |
| 138 } |
| 139 |
| 140 static hb_position_t harfBuzzGetGlyphVerticalAdvance(hb_font_t* hbFont, void* fo
ntData, hb_codepoint_t glyph, void* userData) |
| 141 { |
| 142 HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData)
; |
| 143 const OpenTypeVerticalData* verticalData = hbFontData->m_simpleFontData->ver
ticalData(); |
| 144 if (!verticalData) |
| 145 return SkiaScalarToHarfBuzzPosition(hbFontData->m_simpleFontData->fontMe
trics().height()); |
| 146 |
| 147 Glyph theGlyph = glyph; |
| 148 float advanceHeight = verticalData->advanceHeight(hbFontData->m_simpleFontDa
ta.get(), theGlyph); |
| 149 return SkiaScalarToHarfBuzzPosition(SkFloatToScalar(advanceHeight)); |
| 150 } |
| 151 |
124 static hb_position_t harfBuzzGetGlyphHorizontalKerning(hb_font_t*, void* fontDat
a, hb_codepoint_t leftGlyph, hb_codepoint_t rightGlyph, void*) | 152 static hb_position_t harfBuzzGetGlyphHorizontalKerning(hb_font_t*, void* fontDat
a, hb_codepoint_t leftGlyph, hb_codepoint_t rightGlyph, void*) |
125 { | 153 { |
126 HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData)
; | 154 HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData)
; |
127 if (hbFontData->m_paint.isVerticalText()) { | 155 if (hbFontData->m_paint.isVerticalText()) { |
128 // We don't support cross-stream kerning | 156 // We don't support cross-stream kerning |
129 return 0; | 157 return 0; |
130 } | 158 } |
131 | 159 |
132 SkTypeface* typeface = hbFontData->m_paint.getTypeface(); | 160 SkTypeface* typeface = hbFontData->m_paint.getTypeface(); |
133 | 161 |
134 const uint16_t glyphs[2] = { static_cast<uint16_t>(leftGlyph), static_cast<u
int16_t>(rightGlyph) }; | 162 const uint16_t glyphs[2] = { static_cast<uint16_t>(leftGlyph), static_cast<u
int16_t>(rightGlyph) }; |
135 int32_t kerningAdjustments[1] = { 0 }; | 163 int32_t kerningAdjustments[1] = { 0 }; |
136 | 164 |
137 if (typeface->getKerningPairAdjustments(glyphs, 2, kerningAdjustments)) { | 165 if (typeface->getKerningPairAdjustments(glyphs, 2, kerningAdjustments)) { |
138 SkScalar upm = SkIntToScalar(typeface->getUnitsPerEm()); | |
139 SkScalar size = hbFontData->m_paint.getTextSize(); | |
140 return SkiaScalarToHarfBuzzPosition(SkScalarMulDiv(SkIntToScalar(kerning
Adjustments[0]), size, upm)); | |
141 } | |
142 | |
143 return 0; | |
144 } | |
145 | |
146 static hb_position_t harfBuzzGetGlyphVerticalKerning(hb_font_t*, void* fontData,
hb_codepoint_t topGlyph, hb_codepoint_t bottomGlyph, void*) | |
147 { | |
148 HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData)
; | |
149 if (!hbFontData->m_paint.isVerticalText()) { | |
150 // We don't support cross-stream kerning | |
151 return 0; | |
152 } | |
153 | |
154 SkTypeface* typeface = hbFontData->m_paint.getTypeface(); | |
155 | |
156 const uint16_t glyphs[2] = { static_cast<uint16_t>(topGlyph), static_cast<ui
nt16_t>(bottomGlyph) }; | |
157 int32_t kerningAdjustments[1] = { 0 }; | |
158 | |
159 if (typeface->getKerningPairAdjustments(glyphs, 2, kerningAdjustments)) { | |
160 SkScalar upm = SkIntToScalar(typeface->getUnitsPerEm()); | 166 SkScalar upm = SkIntToScalar(typeface->getUnitsPerEm()); |
161 SkScalar size = hbFontData->m_paint.getTextSize(); | 167 SkScalar size = hbFontData->m_paint.getTextSize(); |
162 return SkiaScalarToHarfBuzzPosition(SkScalarMulDiv(SkIntToScalar(kerning
Adjustments[0]), size, upm)); | 168 return SkiaScalarToHarfBuzzPosition(SkScalarMulDiv(SkIntToScalar(kerning
Adjustments[0]), size, upm)); |
163 } | 169 } |
164 | 170 |
165 return 0; | 171 return 0; |
166 } | 172 } |
167 | 173 |
168 static hb_bool_t harfBuzzGetGlyphExtents(hb_font_t* hbFont, void* fontData, hb_c
odepoint_t glyph, hb_glyph_extents_t* extents, void* userData) | 174 static hb_bool_t harfBuzzGetGlyphExtents(hb_font_t* hbFont, void* fontData, hb_c
odepoint_t glyph, hb_glyph_extents_t* extents, void* userData) |
169 { | 175 { |
170 HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData)
; | 176 HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData)
; |
171 | 177 |
172 SkiaGetGlyphWidthAndExtents(&hbFontData->m_paint, glyph, 0, extents); | 178 SkiaGetGlyphWidthAndExtents(&hbFontData->m_paint, glyph, 0, extents); |
173 return true; | 179 return true; |
174 } | 180 } |
175 | 181 |
176 static hb_font_funcs_t* harfBuzzSkiaGetFontFuncs() | 182 static hb_font_funcs_t* harfBuzzSkiaGetFontFuncs() |
177 { | 183 { |
178 static hb_font_funcs_t* harfBuzzSkiaFontFuncs = 0; | 184 static hb_font_funcs_t* harfBuzzSkiaFontFuncs = 0; |
179 | 185 |
180 // We don't set callback functions which we can't support. | 186 // We don't set callback functions which we can't support. |
181 // HarfBuzz will use the fallback implementation if they aren't set. | 187 // HarfBuzz will use the fallback implementation if they aren't set. |
182 if (!harfBuzzSkiaFontFuncs) { | 188 if (!harfBuzzSkiaFontFuncs) { |
183 harfBuzzSkiaFontFuncs = hb_font_funcs_create(); | 189 harfBuzzSkiaFontFuncs = hb_font_funcs_create(); |
184 hb_font_funcs_set_glyph_func(harfBuzzSkiaFontFuncs, harfBuzzGetGlyph, 0,
0); | 190 hb_font_funcs_set_glyph_func(harfBuzzSkiaFontFuncs, harfBuzzGetGlyph, 0,
0); |
185 hb_font_funcs_set_glyph_h_advance_func(harfBuzzSkiaFontFuncs, harfBuzzGe
tGlyphHorizontalAdvance, 0, 0); | 191 hb_font_funcs_set_glyph_h_advance_func(harfBuzzSkiaFontFuncs, harfBuzzGe
tGlyphHorizontalAdvance, 0, 0); |
186 hb_font_funcs_set_glyph_h_kerning_func(harfBuzzSkiaFontFuncs, harfBuzzGe
tGlyphHorizontalKerning, 0, 0); | 192 hb_font_funcs_set_glyph_h_kerning_func(harfBuzzSkiaFontFuncs, harfBuzzGe
tGlyphHorizontalKerning, 0, 0); |
187 hb_font_funcs_set_glyph_h_origin_func(harfBuzzSkiaFontFuncs, harfBuzzGet
GlyphHorizontalOrigin, 0, 0); | 193 hb_font_funcs_set_glyph_h_origin_func(harfBuzzSkiaFontFuncs, harfBuzzGet
GlyphHorizontalOrigin, 0, 0); |
188 hb_font_funcs_set_glyph_v_kerning_func(harfBuzzSkiaFontFuncs, harfBuzzGe
tGlyphVerticalKerning, 0, 0); | 194 hb_font_funcs_set_glyph_v_advance_func(harfBuzzSkiaFontFuncs, harfBuzzGe
tGlyphVerticalAdvance, 0, 0); |
| 195 hb_font_funcs_set_glyph_v_origin_func(harfBuzzSkiaFontFuncs, harfBuzzGet
GlyphVerticalOrigin, 0, 0); |
189 hb_font_funcs_set_glyph_extents_func(harfBuzzSkiaFontFuncs, harfBuzzGetG
lyphExtents, 0, 0); | 196 hb_font_funcs_set_glyph_extents_func(harfBuzzSkiaFontFuncs, harfBuzzGetG
lyphExtents, 0, 0); |
190 hb_font_funcs_make_immutable(harfBuzzSkiaFontFuncs); | 197 hb_font_funcs_make_immutable(harfBuzzSkiaFontFuncs); |
191 } | 198 } |
192 return harfBuzzSkiaFontFuncs; | 199 return harfBuzzSkiaFontFuncs; |
193 } | 200 } |
194 | 201 |
195 static hb_blob_t* harfBuzzSkiaGetTable(hb_face_t* face, hb_tag_t tag, void* user
Data) | 202 static hb_blob_t* harfBuzzSkiaGetTable(hb_face_t* face, hb_tag_t tag, void* user
Data) |
196 { | 203 { |
197 SkTypeface* typeface = reinterpret_cast<SkTypeface*>(userData); | 204 SkTypeface* typeface = reinterpret_cast<SkTypeface*>(userData); |
198 | 205 |
(...skipping 23 matching lines...) Expand all Loading... |
222 { | 229 { |
223 hb_face_t* face = hb_face_create_for_tables(harfBuzzSkiaGetTable, m_platform
Data->typeface(), 0); | 230 hb_face_t* face = hb_face_create_for_tables(harfBuzzSkiaGetTable, m_platform
Data->typeface(), 0); |
224 ASSERT(face); | 231 ASSERT(face); |
225 return face; | 232 return face; |
226 } | 233 } |
227 | 234 |
228 hb_font_t* HarfBuzzFace::createFont() | 235 hb_font_t* HarfBuzzFace::createFont() |
229 { | 236 { |
230 HarfBuzzFontData* hbFontData = new HarfBuzzFontData(m_glyphCacheForFaceCache
Entry); | 237 HarfBuzzFontData* hbFontData = new HarfBuzzFontData(m_glyphCacheForFaceCache
Entry); |
231 m_platformData->setupPaint(&hbFontData->m_paint); | 238 m_platformData->setupPaint(&hbFontData->m_paint); |
| 239 // FIXME: We should be using an existing SimpleFontData instance here, |
| 240 // or move the fontMetrics() implementation to FontPlatformData. |
| 241 hbFontData->m_simpleFontData = SimpleFontData::create(*m_platformData); |
232 hb_font_t* font = hb_font_create(m_face); | 242 hb_font_t* font = hb_font_create(m_face); |
233 hb_font_set_funcs(font, harfBuzzSkiaGetFontFuncs(), hbFontData, destroyHarfB
uzzFontData); | 243 hb_font_set_funcs(font, harfBuzzSkiaGetFontFuncs(), hbFontData, destroyHarfB
uzzFontData); |
234 float size = m_platformData->size(); | 244 float size = m_platformData->size(); |
235 int scale = SkiaScalarToHarfBuzzPosition(size); | 245 int scale = SkiaScalarToHarfBuzzPosition(size); |
236 hb_font_set_scale(font, scale, scale); | 246 hb_font_set_scale(font, scale, scale); |
237 hb_font_make_immutable(font); | 247 hb_font_make_immutable(font); |
238 return font; | 248 return font; |
239 } | 249 } |
240 | 250 |
241 } // namespace blink | 251 } // namespace blink |
OLD | NEW |