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 32 MinikinFontFreeType::MinikinFontFreeType(FT_Face typeface) : 33 mTypeface(typeface) { 34 mUniqueId = sIdCounter++; 35 } 36 37 MinikinFontFreeType::~MinikinFontFreeType() { 38 FT_Done_Face(mTypeface); 39 } 40 41 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 47 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 56 void MinikinFontFreeType::GetBounds(MinikinRect* bounds, uint32_t glyph_id, 57 const MinikinPaint& paint) const { 58 // TODO: NYI 59 } 60 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 71 int32_t MinikinFontFreeType::GetUniqueId() const { 72 return mUniqueId; 73 } 74 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 96 MinikinFontFreeType* MinikinFontFreeType::GetFreeType() { 97 return this; 98 } 99 100 } // namespace android 101