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) : 336c60831cfce24b0749f50f37231e0a56d8fd4b85Seigo Nonaka MinikinFont(sIdCounter++), 34bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien mTypeface(typeface) { 35bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien} 36bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 37bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph LevienMinikinFontFreeType::~MinikinFontFreeType() { 38bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien FT_Done_Face(mTypeface); 39bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien} 40bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 41bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levienfloat MinikinFontFreeType::GetHorizontalAdvance(uint32_t glyph_id, 42bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien const MinikinPaint &paint) const { 43bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien FT_Set_Pixel_Sizes(mTypeface, 0, paint.size); 44aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien FT_UInt32 flags = FT_LOAD_DEFAULT; // TODO: respect hinting settings 45aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien FT_Fixed advance; 46cb20a2f0b366bfc16db3a489a60156dec7a9fe21Andreas Gampe FT_Get_Advance(mTypeface, glyph_id, flags, &advance); 47bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien return advance * (1.0 / 65536); 48bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien} 49bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 50bae347682989d2627081310129a5b60541ed6ad0Seigo Nonakavoid MinikinFontFreeType::GetBounds(MinikinRect* /* bounds */, uint32_t /* glyph_id*/, 51bae347682989d2627081310129a5b60541ed6ad0Seigo Nonaka const MinikinPaint& /* paint */) const { 52d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien // TODO: NYI 53d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien} 54d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349Raph Levien 55aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levienconst void* MinikinFontFreeType::GetTable(uint32_t tag, size_t* size, MinikinDestroyFunc* destroy) { 56aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien FT_ULong ftsize = 0; 57aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien FT_Error error = FT_Load_Sfnt_Table(mTypeface, tag, 0, nullptr, &ftsize); 58aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien if (error != 0) { 59aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien return nullptr; 60aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien } 61aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien FT_Byte* buf = reinterpret_cast<FT_Byte*>(malloc(ftsize)); 62aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien if (buf == nullptr) { 63aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien return nullptr; 64aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien } 65aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien error = FT_Load_Sfnt_Table(mTypeface, tag, 0, buf, &ftsize); 66aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien if (error != 0) { 67aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien free(buf); 68aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien return nullptr; 69aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien } 70aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien *destroy = free; 71aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien *size = ftsize; 72aaa4e3470270496e6eb80704eadecb2cb7c56bf0Raph Levien return buf; 73bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien} 74bcc3dc5a2591a95a57e379e27cbad69c18e91e67Raph Levien 75bae347682989d2627081310129a5b60541ed6ad0Seigo Nonakabool MinikinFontFreeType::Render(uint32_t glyph_id, const MinikinPaint& /* paint */, 76bae347682989d2627081310129a5b60541ed6ad0Seigo Nonaka 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