1ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien#include <SkTypeface.h>
2ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien#include <SkPaint.h>
3ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien
4ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien#include <minikin/MinikinFont.h>
5ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien#include "MinikinSkia.h"
6ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien
7ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Leviennamespace android {
8ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien
9ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph LevienMinikinFontSkia::MinikinFontSkia(SkTypeface *typeface) :
106c60831cfce24b0749f50f37231e0a56d8fd4b85Seigo Nonaka    MinikinFont(typeface->uniqueID()),
11ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    mTypeface(typeface) {
12ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien}
13ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien
14ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph LevienMinikinFontSkia::~MinikinFontSkia() {
15ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    SkSafeUnref(mTypeface);
16ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien}
17ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien
18d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levienstatic void MinikinFontSkia_SetSkiaPaint(SkTypeface* typeface, SkPaint* skPaint, const MinikinPaint& paint) {
19d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    skPaint->setTypeface(typeface);
20d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    skPaint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
21d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    // TODO: set more paint parameters from Minikin
22d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    skPaint->setTextSize(paint.size);
23d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien}
24d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien
25ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levienfloat MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id,
26ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    const MinikinPaint &paint) const {
27d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    SkPaint skPaint;
28ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    uint16_t glyph16 = glyph_id;
29ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    SkScalar skWidth;
30d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
31d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    skPaint.getTextWidths(&glyph16, sizeof(glyph16), &skWidth, NULL);
32d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien#ifdef VERBOSE
33d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    ALOGD("width for typeface %d glyph %d = %f", mTypeface->uniqueID(), glyph_id
34d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien#endif
35ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    return skWidth;
36ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien}
37ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien
38d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levienvoid MinikinFontSkia::GetBounds(MinikinRect* bounds, uint32_t glyph_id,
39d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    const MinikinPaint& paint) const {
40d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    SkPaint skPaint;
41d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    uint16_t glyph16 = glyph_id;
42d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    SkRect skBounds;
43d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
44d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    skPaint.getTextWidths(&glyph16, sizeof(glyph16), NULL, &skBounds);
45d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    bounds->mLeft = skBounds.fLeft;
46d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    bounds->mTop = skBounds.fTop;
47d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    bounds->mRight = skBounds.fRight;
48d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien    bounds->mBottom = skBounds.fBottom;
49d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien}
50d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien
5129abb82198868908ece4600284fa8b7d3ed73f3bRaph Levienconst void* MinikinFontSkia::GetTable(uint32_t tag, size_t* size, MinikinDestroyFunc* destroy) {
5229abb82198868908ece4600284fa8b7d3ed73f3bRaph Levien    // we don't have a buffer to the font data, copy to own buffer
5329abb82198868908ece4600284fa8b7d3ed73f3bRaph Levien    const size_t tableSize = mTypeface->getTableSize(tag);
5429abb82198868908ece4600284fa8b7d3ed73f3bRaph Levien    *size = tableSize;
5529abb82198868908ece4600284fa8b7d3ed73f3bRaph Levien    if (tableSize == 0) {
5629abb82198868908ece4600284fa8b7d3ed73f3bRaph Levien        return nullptr;
57ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    }
5829abb82198868908ece4600284fa8b7d3ed73f3bRaph Levien    void* buf = malloc(tableSize);
5929abb82198868908ece4600284fa8b7d3ed73f3bRaph Levien    if (buf == nullptr) {
6029abb82198868908ece4600284fa8b7d3ed73f3bRaph Levien        return nullptr;
6129abb82198868908ece4600284fa8b7d3ed73f3bRaph Levien    }
6229abb82198868908ece4600284fa8b7d3ed73f3bRaph Levien    mTypeface->getTableData(tag, 0, tableSize, buf);
6329abb82198868908ece4600284fa8b7d3ed73f3bRaph Levien    *destroy = free;
6429abb82198868908ece4600284fa8b7d3ed73f3bRaph Levien    return buf;
65ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien}
66ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien
67ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph LevienSkTypeface *MinikinFontSkia::GetSkTypeface() {
68ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien    return mTypeface;
69ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien}
70ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien
71ecc2d34ac23a497988f21e5f415b53c007b9d8c5Raph Levien}
72