MinikinFontFreeType.cpp revision d133eab2a1a59ce4a5b1b3db04ec00dc0dbdf349
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