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_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