1 /*
2 * Copyright (C) 2013 The Android Open Source Project
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 // Implementation of MinikinFont abstraction specialized for FreeType
18
19 #include <stdint.h>
20
21 #include <ft2build.h>
22 #include FT_FREETYPE_H
23 #include FT_TRUETYPE_TABLES_H
24 #include FT_ADVANCES_H
25
26 #include <minikin/MinikinFontFreeType.h>
27
28 namespace android {
29
30 int32_t MinikinFontFreeType::sIdCounter = 0;
31
MinikinFontFreeType(FT_Face typeface)32 MinikinFontFreeType::MinikinFontFreeType(FT_Face typeface) :
33 mTypeface(typeface) {
34 mUniqueId = sIdCounter++;
35 }
36
~MinikinFontFreeType()37 MinikinFontFreeType::~MinikinFontFreeType() {
38 FT_Done_Face(mTypeface);
39 }
40
GetGlyph(uint32_t codepoint,uint32_t * glyph) const41 bool MinikinFontFreeType::GetGlyph(uint32_t codepoint, uint32_t *glyph) const {
42 FT_UInt glyph_index = FT_Get_Char_Index(mTypeface, codepoint);
43 *glyph = glyph_index;
44 return !!glyph_index;
45 }
46
GetHorizontalAdvance(uint32_t glyph_id,const MinikinPaint & paint) const47 float MinikinFontFreeType::GetHorizontalAdvance(uint32_t glyph_id,
48 const MinikinPaint &paint) const {
49 FT_Set_Pixel_Sizes(mTypeface, 0, paint.size);
50 FT_UInt32 flags = FT_LOAD_DEFAULT; // TODO: respect hinting settings
51 FT_Fixed advance;
52 FT_Error error = FT_Get_Advance(mTypeface, glyph_id, flags, &advance);
53 return advance * (1.0 / 65536);
54 }
55
GetBounds(MinikinRect * bounds,uint32_t glyph_id,const MinikinPaint & paint) const56 void MinikinFontFreeType::GetBounds(MinikinRect* bounds, uint32_t glyph_id,
57 const MinikinPaint& paint) const {
58 // TODO: NYI
59 }
60
GetTable(uint32_t tag,uint8_t * buf,size_t * size)61 bool MinikinFontFreeType::GetTable(uint32_t tag, uint8_t *buf, size_t *size) {
62 FT_ULong ftsize = *size;
63 FT_Error error = FT_Load_Sfnt_Table(mTypeface, tag, 0, buf, &ftsize);
64 if (error != 0) {
65 return false;
66 }
67 *size = ftsize;
68 return true;
69 }
70
GetUniqueId() const71 int32_t MinikinFontFreeType::GetUniqueId() const {
72 return mUniqueId;
73 }
74
Render(uint32_t glyph_id,const MinikinPaint & paint,GlyphBitmap * result)75 bool MinikinFontFreeType::Render(uint32_t glyph_id,
76 const MinikinPaint &paint, GlyphBitmap *result) {
77 FT_Error error;
78 FT_Int32 load_flags = FT_LOAD_DEFAULT; // TODO: respect hinting settings
79 error = FT_Load_Glyph(mTypeface, glyph_id, load_flags);
80 if (error != 0) {
81 return false;
82 }
83 error = FT_Render_Glyph(mTypeface->glyph, FT_RENDER_MODE_NORMAL);
84 if (error != 0) {
85 return false;
86 }
87 FT_Bitmap &bitmap = mTypeface->glyph->bitmap;
88 result->buffer = bitmap.buffer;
89 result->width = bitmap.width;
90 result->height = bitmap.rows;
91 result->left = mTypeface->glyph->bitmap_left;
92 result->top = mTypeface->glyph->bitmap_top;
93 return true;
94 }
95
GetFreeType()96 MinikinFontFreeType* MinikinFontFreeType::GetFreeType() {
97 return this;
98 }
99
100 } // namespace android
101