Unravel Engine C++ Reference
Loading...
Searching...
No Matches
text_metrics.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2013 Jeremie Roy. All rights reserved.
3 * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
4 */
5
6#include "text_metrics.h"
7#include "utf8.h"
8
9namespace gfx
10{
11text_metrics::text_metrics(font_manager* manager) : manager_(manager)
12{
13 clear_text();
14}
15
17{
18 width_ = height_ = x_ = line_height_ = line_gap_ = 0;
19}
20void text_metrics::append_text(font_handle font_handle, const char* string, const char* end)
21{
22 if(end == nullptr)
23 {
24 end = string + bx::strLen(string);
25 }
26 BX_ASSERT(end >= string, "");
27
28 const font_info& font = manager_->get_font_info(font_handle);
29
30 if(font.line_gap > line_gap_)
31 {
32 line_gap_ = font.line_gap;
33 }
34
35 if((font.ascender - font.descender) > line_height_)
36 {
37 height_ -= line_height_;
38 line_height_ = font.ascender - font.descender;
39 height_ += line_height_;
40 }
41
42 code_point codepoint = 0;
43 code_point previous_codepoint = 0;
44
45 uint32_t state = 0;
46
47 for(; *string && string < end; ++string)
48 {
49 if(!utf8_decode(&state, &codepoint, *string))
50 {
51 const glyph_info* glyph = manager_->get_glyph_info(font_handle, codepoint);
52 if(nullptr != glyph)
53 {
54 if(codepoint == L'\n')
55 {
56 height_ += line_gap_ + font.ascender - font.descender;
57 line_gap_ = font.line_gap;
58 line_height_ = font.ascender - font.descender;
59 x_ = 0;
60 }
61
62 float kerning = manager_->get_kerning(font_handle, previous_codepoint, codepoint);
63 x_ += kerning + glyph->advance_x;
64 if(x_ > width_)
65 {
66 width_ = x_;
67 }
68 }
69 else
70 {
71 BX_ASSERT(false, "Glyph not found");
72 }
73
74 previous_codepoint = codepoint;
75 }
76 }
77
78 BX_ASSERT(state == UTF8_ACCEPT, "The string is not well-formed");
79}
80
82 : line_height_(info.ascender - info.descender + info.line_gap)
83{
84}
85
86auto text_line_metrics::get_line_count(const bx::StringView& str) const -> uint32_t
87{
88 code_point codepoint = 0;
89 uint32_t state = 0;
90 uint32_t line_count = 1;
91 for(const char* ptr = str.getPtr(); ptr != str.getTerm(); ++ptr)
92 {
93 if(utf8_decode(&state, &codepoint, *ptr) == UTF8_ACCEPT)
94 {
95 if(codepoint == L'\n')
96 {
97 ++line_count;
98 }
99 }
100 }
101
102 BX_ASSERT(state == UTF8_ACCEPT, "The string is not well-formed");
103 return line_count;
104}
105
106void text_line_metrics::get_sub_text(const bx::StringView& str,
107 uint32_t first_line,
108 uint32_t last_line,
109 const char*& begin,
110 const char*& end)
111{
112 code_point codepoint = 0;
113 uint32_t state = 0;
114 uint32_t current_line = 0;
115
116 const char* ptr = str.getPtr();
117
118 while(ptr != str.getTerm() && (current_line < first_line))
119 {
120 for(; ptr != str.getTerm(); ++ptr)
121 {
122 if(utf8_decode(&state, &codepoint, *ptr) == UTF8_ACCEPT)
123 {
124 if(codepoint == L'\n')
125 {
126 ++current_line;
127 ++ptr;
128 break;
129 }
130 }
131 }
132 }
133
134 BX_ASSERT(state == UTF8_ACCEPT, "The string is not well-formed");
135 begin = ptr;
136
137 while(ptr != str.getTerm() && (current_line < last_line))
138 {
139 for(; ptr != str.getTerm(); ++ptr)
140 {
141 if(utf8_decode(&state, &codepoint, *ptr) == UTF8_ACCEPT)
142 {
143 if(codepoint == L'\n')
144 {
145 ++current_line;
146 ++ptr;
147 break;
148 }
149 }
150 }
151 }
152
153 BX_ASSERT(state == UTF8_ACCEPT, "The string is not well-formed");
154 end = ptr;
155}
156
157} // namespace gfx
auto get_glyph_info(font_handle handle, code_point code_point) -> const glyph_info *
auto get_kerning(font_handle handle, code_point prev_code_point, code_point code_point) -> float
auto get_font_info(font_handle handle) const -> const font_info &
text_line_metrics(const font_info &info)
auto get_line_count(const bx::StringView &str) const -> uint32_t
Return the number of text line in the given text.
void get_sub_text(const bx::StringView &str, uint32_t first_line, uint32_t last_line, const char *&begin, const char *&end)
Return the first and last character visible in the [first_line, last_line] range.
auto clear_text() -> void
Clear the width and height of the measured text.
auto append_text(font_handle handle, const char *str, const char *end=nullptr) -> void
Append an ASCII/utf-8 string to the metrics helper.
text_metrics(font_manager *manager)
#define UTF8_ACCEPT
Definition utf8.h:9
ImGui::Font::Enum font
Definition hub.cpp:24
uint32_t code_point
Unicode value of a character.
encoder * begin()
Definition graphics.cpp:265
void end(encoder *_encoder)
Definition graphics.cpp:270
A structure that describe a glyph.
uint32_t utf8_decode(uint32_t *_state, uint32_t *_codep, uint8_t _ch)
Definition utf8.cpp:46