1#include <SkTypeface.h>
2#include <SkPaint.h>
3
4#include <minikin/MinikinFont.h>
5#include "MinikinSkia.h"
6
7namespace android {
8
9MinikinFontSkia::MinikinFontSkia(SkTypeface *typeface) :
10    mTypeface(typeface) {
11}
12
13MinikinFontSkia::~MinikinFontSkia() {
14    SkSafeUnref(mTypeface);
15}
16
17bool MinikinFontSkia::GetGlyph(uint32_t codepoint, uint32_t *glyph) const {
18    SkPaint paint;
19    paint.setTypeface(mTypeface);
20    paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
21    uint16_t glyph16;
22    paint.textToGlyphs(&codepoint, sizeof(codepoint), &glyph16);
23    *glyph  = glyph16;
24    //printf("glyph for U+%04x = %d\n", codepoint, glyph16);
25    return !!glyph;
26}
27
28static void MinikinFontSkia_SetSkiaPaint(SkTypeface* typeface, SkPaint* skPaint, const MinikinPaint& paint) {
29    skPaint->setTypeface(typeface);
30    skPaint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
31    // TODO: set more paint parameters from Minikin
32    skPaint->setTextSize(paint.size);
33}
34
35float MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id,
36    const MinikinPaint &paint) const {
37    SkPaint skPaint;
38    uint16_t glyph16 = glyph_id;
39    SkScalar skWidth;
40    MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
41    skPaint.getTextWidths(&glyph16, sizeof(glyph16), &skWidth, NULL);
42#ifdef VERBOSE
43    ALOGD("width for typeface %d glyph %d = %f", mTypeface->uniqueID(), glyph_id
44#endif
45    return skWidth;
46}
47
48void MinikinFontSkia::GetBounds(MinikinRect* bounds, uint32_t glyph_id,
49    const MinikinPaint& paint) const {
50    SkPaint skPaint;
51    uint16_t glyph16 = glyph_id;
52    SkRect skBounds;
53    MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
54    skPaint.getTextWidths(&glyph16, sizeof(glyph16), NULL, &skBounds);
55    bounds->mLeft = skBounds.fLeft;
56    bounds->mTop = skBounds.fTop;
57    bounds->mRight = skBounds.fRight;
58    bounds->mBottom = skBounds.fBottom;
59}
60
61bool MinikinFontSkia::GetTable(uint32_t tag, uint8_t *buf, size_t *size) {
62    if (buf == NULL) {
63        const size_t tableSize = mTypeface->getTableSize(tag);
64        *size = tableSize;
65        return tableSize != 0;
66    } else {
67        const size_t actualSize = mTypeface->getTableData(tag, 0, *size, buf);
68        *size = actualSize;
69        return actualSize != 0;
70    }
71}
72
73SkTypeface *MinikinFontSkia::GetSkTypeface() {
74    return mTypeface;
75}
76
77int32_t MinikinFontSkia::GetUniqueId() const {
78    return mTypeface->uniqueID();
79}
80
81}
82