1bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien/* 2bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * Copyright (C) 2013 The Android Open Source Project 3bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * 4bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * Licensed under the Apache License, Version 2.0 (the "License"); 5bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * you may not use this file except in compliance with the License. 6bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * You may obtain a copy of the License at 7bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * 8bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * http://www.apache.org/licenses/LICENSE-2.0 9bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * 10bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * Unless required by applicable law or agreed to in writing, software 11bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * distributed under the License is distributed on an "AS IS" BASIS, 12bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * See the License for the specific language governing permissions and 14bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien * limitations under the License. 15bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien */ 16bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 17bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien// Implementation of MinikinFont abstraction specialized for FreeType 18bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 19bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien#include <stdint.h> 20bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 21bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien#include <ft2build.h> 22bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien#include FT_FREETYPE_H 23bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien#include FT_TRUETYPE_TABLES_H 24bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien#include FT_ADVANCES_H 25bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 26bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien#include <minikin/MinikinFontFreeType.h> 27bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 28bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Leviennamespace android { 29bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 30bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levienint32_t MinikinFontFreeType::sIdCounter = 0; 31bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 32bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph LevienMinikinFontFreeType::MinikinFontFreeType(FT_Face typeface) : 33bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien mTypeface(typeface) { 34bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien mUniqueId = sIdCounter++; 35bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien} 36bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 37bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph LevienMinikinFontFreeType::~MinikinFontFreeType() { 38bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien FT_Done_Face(mTypeface); 39bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien} 40bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 41bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levienbool MinikinFontFreeType::GetGlyph(uint32_t codepoint, uint32_t *glyph) const { 42bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien FT_UInt glyph_index = FT_Get_Char_Index(mTypeface, codepoint); 43bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien *glyph = glyph_index; 44bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien return !!glyph_index; 45bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien} 46bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 47bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levienfloat MinikinFontFreeType::GetHorizontalAdvance(uint32_t glyph_id, 48bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien const MinikinPaint &paint) const { 49bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien FT_Set_Pixel_Sizes(mTypeface, 0, paint.size); 50bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien FT_UInt32 flags = FT_LOAD_DEFAULT; // TODO: respect hinting settings 51bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien FT_Fixed advance; 52bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien FT_Error error = FT_Get_Advance(mTypeface, glyph_id, flags, &advance); 53bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien return advance * (1.0 / 65536); 54bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien} 55bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 56d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levienvoid MinikinFontFreeType::GetBounds(MinikinRect* bounds, uint32_t glyph_id, 57d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien const MinikinPaint& paint) const { 58d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien // TODO: NYI 59d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien} 60d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien 61bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levienbool MinikinFontFreeType::GetTable(uint32_t tag, uint8_t *buf, size_t *size) { 62bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien FT_ULong ftsize = *size; 63bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien FT_Error error = FT_Load_Sfnt_Table(mTypeface, tag, 0, buf, &ftsize); 64bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien if (error != 0) { 65bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien return false; 66bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien } 67bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien *size = ftsize; 68bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien return true; 69bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien} 70bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 71bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levienint32_t MinikinFontFreeType::GetUniqueId() const { 72bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien return mUniqueId; 73bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien} 74bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 75bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levienbool MinikinFontFreeType::Render(uint32_t glyph_id, 76bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien const MinikinPaint &paint, GlyphBitmap *result) { 77bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien FT_Error error; 78bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien FT_Int32 load_flags = FT_LOAD_DEFAULT; // TODO: respect hinting settings 79bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien error = FT_Load_Glyph(mTypeface, glyph_id, load_flags); 80bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien if (error != 0) { 81bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien return false; 82bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien } 83bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien error = FT_Render_Glyph(mTypeface->glyph, FT_RENDER_MODE_NORMAL); 84bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien if (error != 0) { 85bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien return false; 86bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien } 87bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien FT_Bitmap &bitmap = mTypeface->glyph->bitmap; 88bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien result->buffer = bitmap.buffer; 89bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien result->width = bitmap.width; 90bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien result->height = bitmap.rows; 91bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien result->left = mTypeface->glyph->bitmap_left; 92bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien result->top = mTypeface->glyph->bitmap_top; 93bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien return true; 94bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien} 95bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 96bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph LevienMinikinFontFreeType* MinikinFontFreeType::GetFreeType() { 97bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien return this; 98bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien} 99bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 100bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien} // namespace android 101