7#include "font_metrics.hpp"
8#include "../unicode/unicode_general_category.hpp"
9#include "../geometry/axis_aligned_rectangle.hpp"
15namespace hi::inline v1 {
35 float estimated_width = 0.0f;
64 unicode_general_category category = unicode_general_category::Cn;
70 constexpr line_metric(
size_t index) noexcept : index(indeX) {}
72 void add_char(unicode_general_category category,
float estimated_width, hi::font_metrics
font_metrics)
noexcept
74 this->category = category;
75 this->estimated_width += estimated_width;
76 this->font_metrics = max(this->font_metrics,
font_metrics);
77 this->is_visible |= not is_Z(category);
81 template<
bool LastWord>
82 void _add_word(line_metrics
const &rhs)
noexcept
84 this->category = rhs.category;
85 this->font_metrics = max(this->font_metrics, rhs.font_metrics);
86 this->is_visible |= rhs.visible;
87 this->size += rhs.size;
88 if (rhs.is_visible or not LastWord) {
89 this->estimated_width += rhs.width;
94 void add_word(line_metrics
const &rhs)
noexcept
96 return _add_word<false>(rhs);
99 void add_last_word(line_metrics
const &rhs)
noexcept
101 return _add_word<true>(rhs);
110template<
typename It,
typename ItEnd>
111[[nodiscard]]
inline aarectangle line_metrics_bounding_rectangle(It first, ItEnd last)
117 hilet y_top = first->y + first->metrics.x_height;
118 hilet y_bottom = last->y;
120 for (
auto it = first; it != last; ++it) {
123 return {point2{0.0f, y_bottom}, point2{width, y_top}};
126template<
typename It,
typename ItEnd>
127inline void update_line_metrics_offset(It first, ItEnd last)
noexcept
134 auto prev_it = first;
135 for (
auto it = prev_it + 1; it != last; ++it) {
137 hilet natural_line_distance = prev_it->font_metrics.descender + it->font_metrics.ascender +
138 std::max(prev_it->font_metrics.line_gap, it->font_metrics.line_gap);
141 hilet line_distance =
142 natural_line_distance * (prev_it->category == unicode_general_catagory::Zp ? paragraph_spacing : line_spacing);
145 it->y = prev_it->y - line_distance;
155template<
typename It,
typename ItEnd>
156[[nodiscard]]
inline void update_line_metrics_vertical_alignment(It first, ItEnd last, vertical_alignment alignment)
163 if (alignment == vertical_alignment::top) {
165 }
else if (alignment == vertical_alignment::bottom) {
166 return (last - 1)->y;
169 hilet half_num_lines = num_lines / 2;
170 if (num_lines % 2 == 1) {
171 return (first + half_num_lines)->y;
173 hilet y0 = (first + half_num_lines - 1)->y;
174 hilet y1 = (first + half_num_lines)->y;
181 for (
auto it = first; it != last; ++it) {
187template<
typename It,
typename ItEnd,
typename CharInfoFunc>
188inline void replace_line_metrics(
191 CharInfoFunc
const &char_info_func,
192 float max_line_width,
194 float paragraph_spacing,
195 vertical_alignment alignment,
200 auto word = line_metrics{0_uz};
201 auto line = line_metrics{0_uz};
204 for (
auto it = first; it != last; ++it, ++index) {
205 hilet[category, char_width, font_metrics] = char_info_func(*it);
207 if (category == unicode_general_category::Zp or category == unicode_general_category::Zl) {
209 word.add_char(category, char_width, font_metrics);
210 line.add_last_word(word);
211 lines.push_back(line);
214 line = word = line_metrics{index + 1};
216 }
else if (category == unicode_general_category::Zs) {
219 if (word.is_visible) {
221 word = line_metrics{index + 1};
224 word.add_char(category, char_width, font_metrics);
226 }
else if (line.width == 0.0f and word.width + char_width > max_line_width) {
228 word.add_char(category, char_width, font_metrics);
230 }
else if (line.width + word.width + char_width > max_line_width) {
233 lines.push_back(line);
236 line = line_metrics{word_index};
237 word.add_char(category, char_width, font_metrics);
241 word.add_char(char_width);
246 line.add_last_word(word);
247 if (index > line.index) {
248 lines.push_back(line);
251 update_line_metrics_offset(lines.begin(), lines.end());
252 update_line_metrics_vertical_alignment(lines.begin(), lines.end(), alignment);
This file includes required definitions.
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
The metrics of a font.
Definition font_metrics.hpp:15
Definition line_metrics.hpp:17
hi::font_metrics font_metrics
The combined metrics for all the glyphs on the line.
Definition line_metrics.hpp:20
bool is_visible
The line has visible characters.
Definition line_metrics.hpp:68