10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch/* 20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (c) 2009 Google Inc. All rights reserved. 30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Redistribution and use in source and binary forms, with or without 50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * modification, are permitted provided that the following conditions are 60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * met: 70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * * Redistributions of source code must retain the above copyright 90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * notice, this list of conditions and the following disclaimer. 100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * * Redistributions in binary form must reproduce the above 110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * copyright notice, this list of conditions and the following disclaimer 120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * in the documentation and/or other materials provided with the 130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * distribution. 140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * * Neither the name of Google Inc. nor the names of its 150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * contributors may be used to endorse or promote products derived from 160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * this software without specific prior written permission. 170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch */ 300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "config.h" 320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "FontPlatformData.h" 340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "wtf/OwnArrayPtr.h" 350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SkFontHost.h" 370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SkPaint.h" 380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SkPath.h" 390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SkPoint.h" 400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SkRect.h" 415abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "SkUtils.h" 420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochextern "C" { 440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "harfbuzz-shaper.h" 450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// This file implements the callbacks which Harfbuzz requires by using Skia 480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch// calls. See the Harfbuzz source for references about what these callbacks do. 490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochnamespace WebCore { 510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic HB_Fixed SkiaScalarToHarfbuzzFixed(SkScalar value) 530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // HB_Fixed is a 26.6 fixed point format. 550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return value * 64; 560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic HB_Bool stringToGlyphs(HB_Font hbFont, const HB_UChar16* characters, hb_uint32 length, HB_Glyph* glyphs, hb_uint32* glyphsSize, HB_Bool isRTL) 590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FontPlatformData* font = reinterpret_cast<FontPlatformData*>(hbFont->userData); 610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SkPaint paint; 620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch font->setupPaint(&paint); 640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); 655abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 665abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick unsigned codepoints = 0; 675abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick for (hb_uint32 i = 0; i < length; i++) { 685abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (!SkUTF16_IsHighSurrogate(characters[i])) 695abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick codepoints++; 705abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick if (codepoints > *glyphsSize) 715abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick return 0; 725abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick } 735abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick 740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch int numGlyphs = paint.textToGlyphs(characters, length * sizeof(uint16_t), reinterpret_cast<uint16_t*>(glyphs)); 750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // HB_Glyph is 32-bit, but Skia outputs only 16-bit numbers. So our 770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // |glyphs| array needs to be converted. 780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (int i = numGlyphs - 1; i >= 0; --i) { 790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch uint16_t value; 800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // We use a memcpy to avoid breaking strict aliasing rules. 810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch memcpy(&value, reinterpret_cast<char*>(glyphs) + sizeof(uint16_t) * i, sizeof(uint16_t)); 820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch glyphs[i] = value; 830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *glyphsSize = numGlyphs; 860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return 1; 870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void glyphsToAdvances(HB_Font hbFont, const HB_Glyph* glyphs, hb_uint32 numGlyphs, HB_Fixed* advances, int flags) 900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FontPlatformData* font = reinterpret_cast<FontPlatformData*>(hbFont->userData); 920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SkPaint paint; 930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch font->setupPaint(&paint); 950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block OwnArrayPtr<uint16_t> glyphs16 = adoptArrayPtr(new uint16_t[numGlyphs]); 980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!glyphs16.get()) 990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return; 1000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (unsigned i = 0; i < numGlyphs; ++i) 1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch glyphs16[i] = glyphs[i]; 1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch paint.getTextWidths(glyphs16.get(), numGlyphs * sizeof(uint16_t), reinterpret_cast<SkScalar*>(advances)); 1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // The |advances| values which Skia outputs are SkScalars, which are floats 1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // in Chromium. However, Harfbuzz wants them in 26.6 fixed point format. 1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // These two formats are both 32-bits long. 1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (unsigned i = 0; i < numGlyphs; ++i) { 1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch float value; 1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // We use a memcpy to avoid breaking strict aliasing rules. 1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch memcpy(&value, reinterpret_cast<char*>(advances) + sizeof(float) * i, sizeof(float)); 1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch advances[i] = SkiaScalarToHarfbuzzFixed(value); 1120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic HB_Bool canRender(HB_Font hbFont, const HB_UChar16* characters, hb_uint32 length) 1160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FontPlatformData* font = reinterpret_cast<FontPlatformData*>(hbFont->userData); 1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SkPaint paint; 1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch font->setupPaint(&paint); 1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); 1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block OwnArrayPtr<uint16_t> glyphs16 = adoptArrayPtr(new uint16_t[length]); 1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!glyphs16.get()) 1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return 0; 1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch int numGlyphs = paint.textToGlyphs(characters, length * sizeof(uint16_t), glyphs16.get()); 1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch bool canRender = true; 1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (int i = 0; i < numGlyphs; ++i) { 1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!glyphs16[i]) { 1310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch canRender = false; 1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch break; 1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 1350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return canRender; 1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic HB_Error getOutlinePoint(HB_Font hbFont, HB_Glyph glyph, int flags, hb_uint32 point, HB_Fixed* xPos, HB_Fixed* yPos, hb_uint32* resultingNumPoints) 1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FontPlatformData* font = reinterpret_cast<FontPlatformData*>(hbFont->userData); 1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SkPaint paint; 1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (flags & HB_ShaperFlag_UseDesignMetrics) 1450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return HB_Err_Invalid_Argument; // This is requesting pre-hinted positions. We can't support this. 1460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch font->setupPaint(&paint); 1480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch uint16_t glyph16 = glyph; 1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SkPath path; 1510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch paint.getTextPath(&glyph16, sizeof(glyph16), 0, 0, &path); 15221939df44de1705786c545cd1bf519d47250322dBen Murdoch int numPoints = path.getPoints(0, 0); 153bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen if (point >= static_cast<unsigned>(numPoints)) 1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return HB_Err_Invalid_SubTable; 1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SkPoint* points = reinterpret_cast<SkPoint*>(fastMalloc(sizeof(SkPoint) * (point + 1))); 1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!points) 1570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return HB_Err_Invalid_SubTable; 1580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Skia does let us get a single point from the path. 1590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch path.getPoints(points, point + 1); 1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *xPos = SkiaScalarToHarfbuzzFixed(points[point].fX); 1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *yPos = SkiaScalarToHarfbuzzFixed(points[point].fY); 1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *resultingNumPoints = numPoints; 1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch fastFree(points); 1640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return HB_Err_Ok; 1660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic void getGlyphMetrics(HB_Font hbFont, HB_Glyph glyph, HB_GlyphMetrics* metrics) 1690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FontPlatformData* font = reinterpret_cast<FontPlatformData*>(hbFont->userData); 1710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SkPaint paint; 1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch font->setupPaint(&paint); 1740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 1750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch uint16_t glyph16 = glyph; 1760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SkScalar width; 1770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SkRect bounds; 1780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch paint.getTextWidths(&glyph16, sizeof(glyph16), &width, &bounds); 1790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 180d0825bca7fe65beaee391d30da42e937db621564Steve Block metrics->x = SkiaScalarToHarfbuzzFixed(bounds.fLeft); 181d0825bca7fe65beaee391d30da42e937db621564Steve Block metrics->y = SkiaScalarToHarfbuzzFixed(bounds.fTop); 182d0825bca7fe65beaee391d30da42e937db621564Steve Block metrics->width = SkiaScalarToHarfbuzzFixed(bounds.width()); 183d0825bca7fe65beaee391d30da42e937db621564Steve Block metrics->height = SkiaScalarToHarfbuzzFixed(bounds.height()); 184d0825bca7fe65beaee391d30da42e937db621564Steve Block 185d0825bca7fe65beaee391d30da42e937db621564Steve Block metrics->xOffset = SkiaScalarToHarfbuzzFixed(width); 1860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // We can't actually get the |y| correct because Skia doesn't export 1870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // the vertical advance. However, nor we do ever render vertical text at 1880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // the moment so it's unimportant. 189d0825bca7fe65beaee391d30da42e937db621564Steve Block metrics->yOffset = 0; 1900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 1910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic HB_Fixed getFontMetric(HB_Font hbFont, HB_FontMetric metric) 1930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 1940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FontPlatformData* font = reinterpret_cast<FontPlatformData*>(hbFont->userData); 1950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SkPaint paint; 1960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 1970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch font->setupPaint(&paint); 1980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SkPaint::FontMetrics skiaMetrics; 1990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch paint.getFontMetrics(&skiaMetrics); 2000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch switch (metric) { 2020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch case HB_FontAscent: 2030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return SkiaScalarToHarfbuzzFixed(-skiaMetrics.fAscent); 2040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // We don't support getting the rest of the metrics and Harfbuzz doesn't seem to need them. 2050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch default: 2060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return 0; 2070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 2090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochHB_FontClass harfbuzzSkiaClass = { 2110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch stringToGlyphs, 2120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch glyphsToAdvances, 2130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch canRender, 2140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch getOutlinePoint, 2150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch getGlyphMetrics, 2160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch getFontMetric, 2170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}; 2180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochHB_Error harfbuzzSkiaGetTable(void* voidface, const HB_Tag tag, HB_Byte* buffer, HB_UInt* len) 2200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{ 2210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FontPlatformData* font = reinterpret_cast<FontPlatformData*>(voidface); 2220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch const size_t tableSize = SkFontHost::GetTableSize(font->uniqueID(), tag); 2240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!tableSize) 2250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return HB_Err_Invalid_Argument; 2260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // If Harfbuzz specified a NULL buffer then it's asking for the size of the table. 2270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!buffer) { 2280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *len = tableSize; 2290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return HB_Err_Ok; 2300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 2310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (*len < tableSize) 2330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return HB_Err_Invalid_Argument; 2340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch SkFontHost::GetTableData(font->uniqueID(), tag, 0, tableSize, buffer); 2350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return HB_Err_Ok; 2360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} 2370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 2380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} // namespace WebCore 239