1 /*
2 * Copyright 2017 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "font_skia.h"
18 #include "third_party/skia/include/core/SkFont.h"
19
20 #include <minikin/MinikinFont.h>
21
22 namespace txt {
23 namespace {
24
GetTable(hb_face_t * face,hb_tag_t tag,void * context)25 hb_blob_t* GetTable(hb_face_t* face, hb_tag_t tag, void* context) {
26 SkTypeface* typeface = reinterpret_cast<SkTypeface*>(context);
27
28 const size_t table_size = typeface->getTableSize(tag);
29 if (table_size == 0)
30 return nullptr;
31 void* buffer = malloc(table_size);
32 if (buffer == nullptr)
33 return nullptr;
34
35 size_t actual_size = typeface->getTableData(tag, 0, table_size, buffer);
36 if (table_size != actual_size) {
37 free(buffer);
38 return nullptr;
39 }
40 return hb_blob_create(reinterpret_cast<char*>(buffer), table_size,
41 HB_MEMORY_MODE_WRITABLE, buffer, free);
42 }
43
44 } // namespace
45
FontSkia(sk_sp<SkTypeface> typeface)46 FontSkia::FontSkia(sk_sp<SkTypeface> typeface)
47 : MinikinFont(typeface->uniqueID()), typeface_(std::move(typeface)) {}
48
49 FontSkia::~FontSkia() = default;
50
FontSkia_SetSkiaFont(sk_sp<SkTypeface> typeface,SkFont * skFont,const minikin::MinikinPaint & paint)51 static void FontSkia_SetSkiaFont(sk_sp<SkTypeface> typeface,
52 SkFont* skFont,
53 const minikin::MinikinPaint& paint) {
54 skFont->setTypeface(std::move(typeface));
55 // TODO: set more paint parameters from Minikin
56 skFont->setSize(paint.size);
57 }
58
GetHorizontalAdvance(uint32_t glyph_id,const minikin::MinikinPaint & paint) const59 float FontSkia::GetHorizontalAdvance(uint32_t glyph_id,
60 const minikin::MinikinPaint& paint) const {
61 SkFont skFont;
62 uint16_t glyph16 = glyph_id;
63 SkScalar skWidth;
64 FontSkia_SetSkiaFont(typeface_, &skFont, paint);
65 skFont.getWidths(&glyph16, 1, &skWidth);
66 return skWidth;
67 }
68
GetBounds(minikin::MinikinRect * bounds,uint32_t glyph_id,const minikin::MinikinPaint & paint) const69 void FontSkia::GetBounds(minikin::MinikinRect* bounds,
70 uint32_t glyph_id,
71 const minikin::MinikinPaint& paint) const {
72 SkFont skFont;
73 uint16_t glyph16 = glyph_id;
74 SkRect skBounds;
75 FontSkia_SetSkiaFont(typeface_, &skFont, paint);
76 skFont.getWidths(&glyph16, 1, NULL, &skBounds);
77 bounds->mLeft = skBounds.fLeft;
78 bounds->mTop = skBounds.fTop;
79 bounds->mRight = skBounds.fRight;
80 bounds->mBottom = skBounds.fBottom;
81 }
82
CreateHarfBuzzFace() const83 hb_face_t* FontSkia::CreateHarfBuzzFace() const {
84 return hb_face_create_for_tables(GetTable, typeface_.get(), 0);
85 }
86
GetAxes() const87 const std::vector<minikin::FontVariation>& FontSkia::GetAxes() const {
88 return variations_;
89 }
90
GetSkTypeface() const91 const sk_sp<SkTypeface>& FontSkia::GetSkTypeface() const {
92 return typeface_;
93 }
94
95 } // namespace txt
96