Android-cuttlefish cvd tool
font_rendering.h
Go to the documentation of this file.
1/*
2 *
3 * Copyright 2019, The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#ifndef TEEUI_LIBTEEUI_FONT_RENDERING_H_
19#define TEEUI_LIBTEEUI_FONT_RENDERING_H_
20
21#include <ft2build.h>
22#include FT_FREETYPE_H
23#include <freetype/ftglyph.h>
24
25#include "utils.h"
26#include <tuple>
27
28#include <type_traits>
29
30#include "utf8range.h"
31
32namespace teeui {
33
34template <typename T> struct HandleDelete;
35
36template <typename T, typename Deleter = HandleDelete<T>> class Handle {
37 public:
38 Handle() : handle_(nullptr) {}
39 explicit Handle(T handle) : handle_(handle) {}
40 Handle(const Handle&) = delete;
41 Handle& operator=(const Handle&) = delete;
42
43 Handle(Handle&& other) {
44 handle_ = other.handle_;
45 other.handle_ = nullptr;
46 }
47
49 if (&rhs != this) {
50 auto dummy = handle_;
51 handle_ = rhs.handle_;
52 rhs.handle_ = dummy;
53 }
54 return *this;
55 }
56
58 if (handle_) Deleter()(handle_);
59 }
60
61 operator bool() const { return handle_ != nullptr; }
62 T operator*() const { return handle_; }
63 const T operator->() const { return handle_; }
64 T operator->() { return handle_; }
65
66 private:
68};
69
70template<typename T>
72
73#define MAP_HANDLE_DELETER(type, deleter) \
74 template <> struct HandleDelete<type> { \
75 void operator()(type h) { deleter(h); } \
76 }
77
78MAP_HANDLE_DELETER(FT_Face, FT_Done_Face);
79MAP_HANDLE_DELETER(FT_Library, FT_Done_FreeType);
80
81
82bool isBreakable(unsigned long codePoint);
83bool isNewline(unsigned long codePoint);
84
85template <typename CharIterator> class UTF8WordRange {
87
88 public:
89 UTF8WordRange(CharIterator begin, CharIterator end) : range_(begin, end) {}
90 explicit UTF8WordRange(const UTF8Range<CharIterator>& range) : range_(range) {}
91 UTF8WordRange() = default;
92 UTF8WordRange(const UTF8WordRange&) = default;
96
98 class Iter {
101
102 public:
103 Iter() : begin_{} {}
105 Iter(const Iter& rhs) : begin_(rhs.begin_), end_(rhs.end_) {}
106 Iter& operator=(const Iter& rhs) {
107 begin_ = rhs.begin_;
108 end_ = rhs.end_;
109 return *this;
110 }
111 UTF8Iterator operator*() const { return begin_; }
113 if (begin_ == end_) return *this;
114 bool prevBreaking = isBreakable(begin_.codePoint());
115 // checkAndUpdate detects edges between breakable and non breakable characters.
116 // As a result the iterator stops on the first character of a word or whitespace
117 // sequence.
118 auto checkAndUpdate = [&](unsigned long cp) {
119 bool current = isBreakable(cp);
120 bool result = prevBreaking == current;
121 prevBreaking = current;
122 return result;
123 };
124 do {
125 ++begin_;
126 } while (begin_ != end_ && checkAndUpdate(begin_.codePoint()));
127 return *this;
128 }
130 Iter dummy = *this;
131 ++(*this);
132 return dummy;
133 }
134 bool operator==(const Iter& rhs) const { return begin_ == rhs.begin_; }
135 bool operator!=(const Iter& rhs) const { return !(*this == rhs); }
136 };
137 Iter begin() const { return Iter(range_.begin(), range_.end()); }
138 Iter end() const { return Iter(range_.end(), range_.end()); }
139};
140
141class TextContext;
142
143using GlyphIndex = unsigned int;
144
145class TextFace {
148 bool hasKerning_ = false;
149
150 public:
151 Error setCharSize(signed long char_size, unsigned int dpi);
153 GlyphIndex getCharIndex(unsigned long codePoint);
156
157 Error drawGlyph(const Vec2d<pxs>& pos, const PixelDrawer& drawPixel) {
158 FT_Bitmap* bitmap = &face_->glyph->bitmap;
159 uint8_t* rowBuffer = bitmap->buffer;
160 Vec2d<pxs> offset{face_->glyph->bitmap_left, -face_->glyph->bitmap_top};
161 auto bPos = pos + offset;
162 for (unsigned y = 0; y < bitmap->rows; ++y) {
163 for (unsigned x = 0; x < bitmap->width; ++x) {
164 Color alpha = 0;
165 switch (bitmap->pixel_mode) {
166 case FT_PIXEL_MODE_GRAY:
167 alpha = rowBuffer[x];
168 alpha *= 256;
169 alpha /= bitmap->num_grays;
170 alpha <<= 24;
171 break;
172 case FT_PIXEL_MODE_LCD:
173 case FT_PIXEL_MODE_BGRA:
174 case FT_PIXEL_MODE_NONE:
175 case FT_PIXEL_MODE_LCD_V:
176 case FT_PIXEL_MODE_MONO:
177 case FT_PIXEL_MODE_GRAY2:
178 case FT_PIXEL_MODE_GRAY4:
179 default:
181 }
182 if (drawPixel(bPos.x().count() + x, bPos.y().count() + y, alpha)) {
184 }
185 }
186 rowBuffer += bitmap->pitch;
187 }
188 return Error::OK;
189 }
190
191 Vec2d<pxs> advance() const;
192 Vec2d<pxs> kern(GlyphIndex previous) const;
193 optional<Box<pxs>> getGlyphBBox() const;
194};
195
198
199 public:
200 static std::tuple<Error, TextContext> create();
201
202 template <typename Buffer>
203 std::tuple<Error, TextFace> loadFace(const Buffer& data, signed long face_index = 0) {
204 std::tuple<Error, TextFace> result;
205 auto& [rc, tface] = result;
207 if (!library_) return result;
208 FT_Face face;
209 auto error = FT_New_Memory_Face(*library_, data.data(), data.size(), face_index, &face);
211 if (error) return result;
212 tface.face_ = Handle(face);
213 tface.hasKerning_ = FT_HAS_KERNING(face);
214 rc = Error::OK;
215 return result;
216 }
217};
218
219std::tuple<Error, Box<pxs>, UTF8Range<const char*>>
220findLongestWordSequence(TextFace* face, const UTF8Range<const char*>& text,
221 const Box<pxs>& boundingBox);
222Error drawText(TextFace* face, const UTF8Range<const char*>& text, const PixelDrawer& drawPixel,
223 PxPoint pen);
224
225} // namespace teeui
226
227#endif // TEEUI_LIBTEEUI_FONT_RENDERING_H_
Definition: error.h:26
@ FaceNotLoaded
Definition: error.h:31
@ NotInitialized
Definition: error.h:30
@ OK
Definition: error.h:29
@ OutOfBoundsDrawing
Definition: error.h:37
@ UnsupportedPixelFormat
Definition: error.h:36
Definition: font_rendering.h:36
Handle(T handle)
Definition: font_rendering.h:39
const T operator->() const
Definition: font_rendering.h:63
~Handle()
Definition: font_rendering.h:57
T handle_
Definition: font_rendering.h:67
T operator*() const
Definition: font_rendering.h:62
Handle(const Handle &)=delete
T operator->()
Definition: font_rendering.h:64
Handle & operator=(const Handle &)=delete
Handle()
Definition: font_rendering.h:38
Handle(Handle &&other)
Definition: font_rendering.h:43
Handle & operator=(Handle &&rhs)
Definition: font_rendering.h:48
Definition: font_rendering.h:196
Handle< FT_Library > library_
Definition: font_rendering.h:197
static std::tuple< Error, TextContext > create()
Definition: font_rendering.cpp:122
std::tuple< Error, TextFace > loadFace(const Buffer &data, signed long face_index=0)
Definition: font_rendering.h:203
Definition: font_rendering.h:145
GlyphIndex getCharIndex(unsigned long codePoint)
Definition: font_rendering.cpp:75
Error drawGlyph(const Vec2d< pxs > &pos, const PixelDrawer &drawPixel)
Definition: font_rendering.h:157
bool hasKerning_
Definition: font_rendering.h:148
optional< Box< pxs > > getGlyphBBox() const
Definition: font_rendering.cpp:111
friend TextContext
Definition: font_rendering.h:146
Vec2d< pxs > advance() const
Definition: font_rendering.cpp:96
Error loadGlyph(GlyphIndex index)
Definition: font_rendering.cpp:80
Vec2d< pxs > kern(GlyphIndex previous) const
Definition: font_rendering.cpp:100
Error renderGlyph()
Definition: font_rendering.cpp:88
Error setCharSize(signed long char_size, unsigned int dpi)
Definition: font_rendering.cpp:60
Error setCharSizeInPix(pxs size)
Definition: font_rendering.cpp:67
Handle< FT_Face > face_
Definition: font_rendering.h:147
Definition: utf8range.h:75
Definition: utf8range.h:30
Definition: font_rendering.h:98
bool operator!=(const Iter &rhs) const
Definition: font_rendering.h:135
Iter & operator=(const Iter &rhs)
Definition: font_rendering.h:106
Iter & operator++()
Definition: font_rendering.h:112
Iter(const Iter &rhs)
Definition: font_rendering.h:105
UTF8Iterator begin_
Definition: font_rendering.h:99
UTF8Iterator end_
Definition: font_rendering.h:100
Iter(UTF8Iterator begin, UTF8Iterator end)
Definition: font_rendering.h:104
Iter()
Definition: font_rendering.h:103
UTF8Iterator operator*() const
Definition: font_rendering.h:111
Iter operator++(int)
Definition: font_rendering.h:129
bool operator==(const Iter &rhs) const
Definition: font_rendering.h:134
Definition: font_rendering.h:85
UTF8WordRange & operator=(const UTF8WordRange &)=default
Iter begin() const
Definition: font_rendering.h:137
UTF8WordRange(CharIterator begin, CharIterator end)
Definition: font_rendering.h:89
UTF8WordRange(const UTF8Range< CharIterator > &range)
Definition: font_rendering.h:90
UTF8WordRange(UTF8WordRange &&)=default
UTF8WordRange(const UTF8WordRange &)=default
UTF8WordRange & operator=(UTF8WordRange &&)=default
Iter end() const
Definition: font_rendering.h:138
typename UTF8Range< CharIterator >::Iter UTF8Iterator
Definition: font_rendering.h:97
UTF8Range< CharIterator > range_
Definition: font_rendering.h:86
static const char *const text[]
Definition: ext2_err.c:10
#define error(format, args...)
Definition: fec_private.h:201
char data[Size]
Definition: incremental_server.cpp:1
uint32_t size
Definition: io.h:2
Definition: layout.h:28
Error drawText(TextFace *face, const UTF8Range< const char * > &text, const PixelDrawer &drawPixel, PxPoint pen)
Definition: font_rendering.cpp:217
Callback< Error(uint32_t, uint32_t, Color)> PixelDrawer
Definition: utils.h:885
bool isNewline(unsigned long codePoint)
Definition: font_rendering.cpp:56
Point< pxs > PxPoint
Definition: utils.h:603
Handle(T handle) -> Handle< T, HandleDelete< T > >
MAP_HANDLE_DELETER(FT_Face, FT_Done_Face)
unsigned int GlyphIndex
Definition: font_rendering.h:143
std::tuple< Error, Box< pxs >, UTF8Range< const char * > > findLongestWordSequence(TextFace *face, const UTF8Range< const char * > &text, const Box< pxs > &boundingBox)
Definition: font_rendering.cpp:135
uint32_t Color
Definition: utils.h:594
bool isBreakable(unsigned long codePoint)
Definition: font_rendering.cpp:22
Definition: utils.h:860
Definition: font_rendering.h:34