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