Chromium Code Reviews| Index: Source/core/platform/graphics/harfbuzz/HarfBuzzFaceSkia.cpp |
| diff --git a/Source/core/platform/graphics/harfbuzz/HarfBuzzFaceSkia.cpp b/Source/core/platform/graphics/harfbuzz/HarfBuzzFaceSkia.cpp |
| index 961707a3f82e6c73013a4bd0ebfb46de52ff2aee..2619edb83d0aa8cee2de930b3004bed6bf06b7f4 100644 |
| --- a/Source/core/platform/graphics/harfbuzz/HarfBuzzFaceSkia.cpp |
| +++ b/Source/core/platform/graphics/harfbuzz/HarfBuzzFaceSkia.cpp |
| @@ -1,5 +1,6 @@ |
| /* |
| * Copyright (c) 2012 Google Inc. All rights reserved. |
| + * Copyright (C) 2013 BlackBerry Limited. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| @@ -117,6 +118,50 @@ static hb_bool_t harfBuzzGetGlyphHorizontalOrigin(hb_font_t* hbFont, void* fontD |
| return true; |
| } |
| +static hb_position_t harfBuzzGetGlyphHorizontalKerning(hb_font_t*, void* fontData, hb_codepoint_t leftGlyph, hb_codepoint_t rightGlyph, void*) |
| +{ |
| + HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData); |
| + if (hbFontData->m_paint.isVerticalText()) { |
| + // We don't support cross-stream kerning |
| + return 0; |
| + } |
| + |
| + SkTypeface* typeface = hbFontData->m_paint.getTypeface(); |
| + |
| + const uint16_t glyphs[2] = { leftGlyph, rightGlyph }; |
| + int32_t kerningAdjustments[1] = { 0 }; |
| + |
| + if (typeface->getKerningPairAdjustments(glyphs, 2, kerningAdjustments)) { |
| + SkScalar upm = SkIntToScalar(typeface->getUnitsPerEm()); |
| + SkScalar size = hbFontData->m_paint.getTextSize(); |
| + return SkiaScalarToHarfBuzzPosition(SkScalarMulDiv(SkIntToScalar(kerningAdjustments[0]), size, upm)); |
| + } |
| + |
| + return 0; |
| +} |
| + |
| +static hb_position_t harfBuzzGetGlyphVerticalKerning(hb_font_t*, void* fontData, hb_codepoint_t topGlyph, hb_codepoint_t bottomGlyph, void*) |
| +{ |
| + HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData); |
| + if (!hbFontData->m_paint.isVerticalText()) { |
| + // We don't support cross-stream kerning |
| + return 0; |
| + } |
| + |
| + SkTypeface* typeface = hbFontData->m_paint.getTypeface(); |
| + |
| + const uint16_t glyphs[2] = { topGlyph, bottomGlyph }; |
| + int32_t kerningAdjustments[1] = { 0 }; |
| + |
| + if (typeface->getKerningPairAdjustments(glyphs, 2, kerningAdjustments)) { |
| + SkScalar upm = SkIntToScalar(typeface->getUnitsPerEm()); |
| + SkScalar size = hbFontData->m_paint.getTextSize(); |
| + return SkiaScalarToHarfBuzzPosition(SkScalarMulDiv(SkIntToScalar(kerningAdjustments[0]), size, upm)); |
| + } |
| + |
| + return 0; |
| +} |
| + |
| static hb_bool_t harfBuzzGetGlyphExtents(hb_font_t* hbFont, void* fontData, hb_codepoint_t glyph, hb_glyph_extents_t* extents, void* userData) |
| { |
| HarfBuzzFontData* hbFontData = reinterpret_cast<HarfBuzzFontData*>(fontData); |
| @@ -125,9 +170,24 @@ static hb_bool_t harfBuzzGetGlyphExtents(hb_font_t* hbFont, void* fontData, hb_c |
| return true; |
| } |
| -static hb_font_funcs_t* harfBuzzSkiaGetFontFuncs() |
| +static hb_font_funcs_t* harfBuzzSkiaGetFontFuncs(const TypesettingFeatures& features) |
| { |
| static hb_font_funcs_t* harfBuzzSkiaFontFuncs = 0; |
| + static hb_font_funcs_t* harfBuzzSkiaFontFuncsWithKerning = 0; // includes TrueType ("kern" table) kerning |
| + |
| + if (features & Kerning) { |
| + if (!harfBuzzSkiaFontFuncsWithKerning) { |
| + harfBuzzSkiaFontFuncsWithKerning = hb_font_funcs_create(); |
| + hb_font_funcs_set_glyph_func(harfBuzzSkiaFontFuncsWithKerning, harfBuzzGetGlyph, 0, 0); |
| + hb_font_funcs_set_glyph_h_advance_func(harfBuzzSkiaFontFuncsWithKerning, harfBuzzGetGlyphHorizontalAdvance, 0, 0); |
| + hb_font_funcs_set_glyph_h_kerning_func(harfBuzzSkiaFontFuncsWithKerning, harfBuzzGetGlyphHorizontalKerning, 0, 0); |
| + hb_font_funcs_set_glyph_h_origin_func(harfBuzzSkiaFontFuncsWithKerning, harfBuzzGetGlyphHorizontalOrigin, 0, 0); |
| + hb_font_funcs_set_glyph_v_kerning_func(harfBuzzSkiaFontFuncsWithKerning, harfBuzzGetGlyphVerticalKerning, 0, 0); |
| + hb_font_funcs_set_glyph_extents_func(harfBuzzSkiaFontFuncsWithKerning, harfBuzzGetGlyphExtents, 0, 0); |
| + hb_font_funcs_make_immutable(harfBuzzSkiaFontFuncsWithKerning); |
| + } |
| + return harfBuzzSkiaFontFuncsWithKerning; |
|
behdad_google
2013/11/15 16:26:35
This is the wrong approach to control kerning.
|
| + } |
| // We don't set callback functions which we can't support. |
| // HarfBuzz will use the fallback implementation if they aren't set. |
| @@ -175,12 +235,12 @@ hb_face_t* HarfBuzzFace::createFace() |
| return face; |
| } |
| -hb_font_t* HarfBuzzFace::createFont() |
| +hb_font_t* HarfBuzzFace::createFont(const TypesettingFeatures& features) |
| { |
| HarfBuzzFontData* hbFontData = new HarfBuzzFontData(m_glyphCacheForFaceCacheEntry); |
| m_platformData->setupPaint(&hbFontData->m_paint); |
| hb_font_t* font = hb_font_create(m_face); |
| - hb_font_set_funcs(font, harfBuzzSkiaGetFontFuncs(), hbFontData, destroyHarfBuzzFontData); |
| + hb_font_set_funcs(font, harfBuzzSkiaGetFontFuncs(features), hbFontData, destroyHarfBuzzFontData); |
| float size = m_platformData->size(); |
| int scale = SkiaScalarToHarfBuzzPosition(size); |
| hb_font_set_scale(font, scale, scale); |