| 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 |