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 28namespace android { 29 30int32_t MinikinFontFreeType::sIdCounter = 0; 31 32MinikinFontFreeType::MinikinFontFreeType(FT_Face typeface) : 33 MinikinFont(sIdCounter++), 34 mTypeface(typeface) { 35} 36 37MinikinFontFreeType::~MinikinFontFreeType() { 38 FT_Done_Face(mTypeface); 39} 40 41float MinikinFontFreeType::GetHorizontalAdvance(uint32_t glyph_id, 42 const MinikinPaint &paint) const { 43 FT_Set_Pixel_Sizes(mTypeface, 0, paint.size); 44 FT_UInt32 flags = FT_LOAD_DEFAULT; // TODO: respect hinting settings 45 FT_Fixed advance; 46 FT_Get_Advance(mTypeface, glyph_id, flags, &advance); 47 return advance * (1.0 / 65536); 48} 49 50void MinikinFontFreeType::GetBounds(MinikinRect* /* bounds */, uint32_t /* glyph_id*/, 51 const MinikinPaint& /* paint */) const { 52 // TODO: NYI 53} 54 55const void* MinikinFontFreeType::GetTable(uint32_t tag, size_t* size, MinikinDestroyFunc* destroy) { 56 FT_ULong ftsize = 0; 57 FT_Error error = FT_Load_Sfnt_Table(mTypeface, tag, 0, nullptr, &ftsize); 58 if (error != 0) { 59 return nullptr; 60 } 61 FT_Byte* buf = reinterpret_cast<FT_Byte*>(malloc(ftsize)); 62 if (buf == nullptr) { 63 return nullptr; 64 } 65 error = FT_Load_Sfnt_Table(mTypeface, tag, 0, buf, &ftsize); 66 if (error != 0) { 67 free(buf); 68 return nullptr; 69 } 70 *destroy = free; 71 *size = ftsize; 72 return buf; 73} 74 75bool MinikinFontFreeType::Render(uint32_t glyph_id, const MinikinPaint& /* paint */, 76 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 96MinikinFontFreeType* MinikinFontFreeType::GetFreeType() { 97 return this; 98} 99 100} // namespace android 101