From a39dd382ac3054d060fd951b64c12041e63b7def Mon Sep 17 00:00:00 2001 From: Leonardo Date: Thu, 17 Sep 2020 00:58:55 -0300 Subject: [PATCH 1/5] makes wrapping return the actual line count --- include/font-chef/character-mapping.h | 3 ++- src/font-chef/font.c | 17 ----------------- src/font-chef/render-result.c | 4 ++-- 3 files changed, 4 insertions(+), 20 deletions(-) diff --git a/include/font-chef/character-mapping.h b/include/font-chef/character-mapping.h index bc7636b..22b425a 100644 --- a/include/font-chef/character-mapping.h +++ b/include/font-chef/character-mapping.h @@ -84,11 +84,12 @@ FONT_CHEF_EXPORT struct fc_rect fc_text_bounds(struct fc_character_mapping const * @param line_height The space between the topmost pixel in the line to the bottomost pixel in the line (this includes characters in the line itself) * @param space_width The width of a space character * @param alignment Which aligment should lines follow + * @return The line count in the text * @sa ::fc_render_wrapped * @sa fc::render_result::wrap * @sa fc_get_space_metrics */ -FONT_CHEF_EXPORT extern void fc_wrap( +FONT_CHEF_EXPORT extern size_t fc_wrap( struct fc_character_mapping mapping[], size_t count, float line_width, diff --git a/src/font-chef/font.c b/src/font-chef/font.c index d17922e..fd75b25 100644 --- a/src/font-chef/font.c +++ b/src/font-chef/font.c @@ -6,8 +6,6 @@ #include -#define fc_fabs(x) ((float) fabs((double) x)) - struct fc_font * fc_construct( uint8_t const * font_data, struct fc_font_size font_size, @@ -154,11 +152,6 @@ int fc_render( m->codepoint = decode.codepoint; - /* stores the top offset to add it later to the mappings, to make sure - * that rendering starts at 0 */ -// if ((dst->top < top_offset) || target_index == 0) -// top_offset = dst->top; - /* checks to see if there is kerning to add to the next character, and * sets it to be used in the next iteration */ kern = 0; @@ -171,16 +164,6 @@ int fc_render( } } - /* characters are rendered around a baseline, which was set to 0 when - * fc_cook was called. the following loop goes through all glyph - * mappings and adjusts them to remove the "empty" space on top caused - * by that. */ -// top_offset = fc_fabs(top_offset); -// for (size_t i = 0; i < target_index; i++) { -// mapping[i].target.top += top_offset; -// mapping[i].target.bottom += top_offset; -// } - /* end of the loop, target_index will be the amount of decoded glyphs */ return (int) target_index; } diff --git a/src/font-chef/render-result.c b/src/font-chef/render-result.c index 8db156a..1c35d0b 100644 --- a/src/font-chef/render-result.c +++ b/src/font-chef/render-result.c @@ -29,7 +29,7 @@ float fc_text_segment_width(struct fc_text_segment const * segment, struct fc_ch return mapping[segment->last].target.right - mapping[segment->first].target.left; } -void fc_wrap(struct fc_character_mapping mapping[], size_t glyph_count, float line_width, float line_height, float space_width, enum fc_alignment aligment) { +size_t fc_wrap(struct fc_character_mapping mapping[], size_t glyph_count, float line_width, float line_height, float space_width, enum fc_alignment aligment) { struct fc_text_segment * words = calloc(sizeof(*words), glyph_count); struct fc_text_segment * lines = calloc(sizeof(*lines), glyph_count); size_t word_count = 0; @@ -67,7 +67,6 @@ void fc_wrap(struct fc_character_mapping mapping[], size_t glyph_count, float li current_word->last = i; word_count += 1; } - } /* identify lines */ @@ -123,6 +122,7 @@ void fc_wrap(struct fc_character_mapping mapping[], size_t glyph_count, float li } free(words); free(lines); + return line_count; } void fc_move(struct fc_character_mapping * mapping, size_t count, float left, float baseline) { From 78d4c64b822c46c0475832e7f35f6b7beabf2c93 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Thu, 17 Sep 2020 01:17:13 -0300 Subject: [PATCH 2/5] wraps rendering result in its own struct --- include/font-chef/character-mapping.h | 2 +- include/font-chef/font.h | 23 ++++++++++++++++++++--- include/font-chef/font.hpp | 5 +++-- include/font-chef/render-result.hpp | 12 +++++++++--- src/examples/c/main.c | 6 +++--- src/font-chef/font.c | 17 +++++++++++------ src/font-chef/render-result.c | 2 +- 7 files changed, 48 insertions(+), 19 deletions(-) diff --git a/include/font-chef/character-mapping.h b/include/font-chef/character-mapping.h index 22b425a..4578c98 100644 --- a/include/font-chef/character-mapping.h +++ b/include/font-chef/character-mapping.h @@ -89,7 +89,7 @@ FONT_CHEF_EXPORT struct fc_rect fc_text_bounds(struct fc_character_mapping const * @sa fc::render_result::wrap * @sa fc_get_space_metrics */ -FONT_CHEF_EXPORT extern size_t fc_wrap( +FONT_CHEF_EXPORT extern uint32_t fc_wrap( struct fc_character_mapping mapping[], size_t count, float line_width, diff --git a/include/font-chef/font.h b/include/font-chef/font.h index a10374c..6bd2706 100644 --- a/include/font-chef/font.h +++ b/include/font-chef/font.h @@ -43,6 +43,21 @@ struct fc_pixels { struct fc_size dimensions; }; +/** + * @brief A structure holding the result of a call to `fc_render` or `fc_render_wrapped` + */ +struct fc_render_result { + /** + * @brief How many lines were produced + */ + uint32_t lines; + + /** + * @brief How many glphs were produced + */ + uint32_t glyphs; +}; + /** * @struct fc_font @@ -191,9 +206,10 @@ FONT_CHEF_EXPORT extern void fc_cook(struct fc_font * font); * @param byte_count How many bytes are there in the character array * @param mapping An array of `fc_character_mapping` values that * must be at least `byte_count` long. - * @return the actual number of glyphs to be rendered. + * @return how many glyphs and lines were produced + * @sa ::fc_render_result */ -FONT_CHEF_EXPORT extern int fc_render( +FONT_CHEF_EXPORT extern struct fc_render_result fc_render( struct fc_font const * font, unsigned char const * text, size_t byte_count, @@ -216,11 +232,12 @@ FONT_CHEF_EXPORT extern int fc_render( * @param alignment Which aligment should lines follow * @param mapping An array of `fc_character_mapping` values that * must be at least `byte_count` long. + * @return how many glyphs and lines were produced * @sa ::fc_render * @sa ::fc_wrap * @sa fc::render_result::wrap */ -FONT_CHEF_EXPORT int fc_render_wrapped( +FONT_CHEF_EXPORT struct fc_render_result fc_render_wrapped( struct fc_font const * font, unsigned char const * text, size_t byte_count, diff --git a/include/font-chef/font.hpp b/include/font-chef/font.hpp index 038aae2..f575f83 100644 --- a/include/font-chef/font.hpp +++ b/include/font-chef/font.hpp @@ -209,8 +209,9 @@ namespace fc { result.font = data; std::vector & mapping = result.mapping; if (mapping.size() < text.length()) mapping.resize(text.length()); - size_t count = fc_render(data, (uint8_t *) text.data(), text.size(), mapping.data()); - mapping.resize(count); + struct fc_render_result r = fc_render(data, (uint8_t *) text.data(), text.size(), mapping.data()); + mapping.resize(r.glyphs); + result.line_count = r.lines; return result; } }; diff --git a/include/font-chef/render-result.hpp b/include/font-chef/render-result.hpp index ec932c7..0c2cc77 100644 --- a/include/font-chef/render-result.hpp +++ b/include/font-chef/render-result.hpp @@ -33,6 +33,11 @@ namespace fc { */ std::vector<::fc_character_mapping> mapping; + /** + * @brief How many lines were produced + */ + uint32_t line_count; + /** * @brief A pointer to the ::fc_font used to generate this mapping */ @@ -49,7 +54,7 @@ namespace fc { * @sa fc::font::render */ render_result(fc_font * font = nullptr, std::vector && mapping = {}) //NOLINT - : mapping(mapping), font(font) { + : mapping(mapping), font(font), line_count(0) { ::printf("construct render result"); }; @@ -58,7 +63,7 @@ namespace fc { * @param other A rvalue (moveable) ref to a fc::render_result instance */ render_result(render_result && other) noexcept - : mapping(std::move(other.mapping)), font(other.font) { + : mapping(std::move(other.mapping)), font(other.font), line_count(other.line_count) { other.font = nullptr; }; @@ -71,6 +76,7 @@ namespace fc { if (this == &other) return *this; this->mapping = std::move(other.mapping); this->font = other.font; + this->line_count = other.line_count; other.font = nullptr; return *this; } @@ -111,7 +117,7 @@ namespace fc { wrap(float line_width, float line_height_multiplier = 1.0f, fc_alignment alignment = fc_align_left) & { if (!font) return *this; fc_size space_metrics = fc_get_space_metrics(font); - fc_wrap( + this->line_count = fc_wrap( mapping.data(), mapping.size(), line_width, diff --git a/src/examples/c/main.c b/src/examples/c/main.c index 227b134..93d7973 100644 --- a/src/examples/c/main.c +++ b/src/examples/c/main.c @@ -20,7 +20,7 @@ int main(int argc, char const ** argv) { struct fc_character_mapping mapping[256]; const char text[] = "Hello, handsome! I mean... world!"; - int txt_glyph_count = fc_render_wrapped( + struct fc_render_result result = fc_render_wrapped( font, (uint8_t *) text, strlen(text), @@ -28,10 +28,10 @@ int main(int argc, char const ** argv) { 1.0f, fc_align_left, mapping ); - fc_move(mapping, txt_glyph_count, 0.0f, state.bounds.bottom / 2 - 20); + fc_move(mapping, result.glyphs, 0.0f, state.bounds.bottom / 2 - 20); while (update(&state)) { - for (int i = 0; i < txt_glyph_count; i++) { + for (int i = 0; i < result.glyphs; i++) { render(font_texture, mapping[i].source, mapping[i].target); } } diff --git a/src/font-chef/font.c b/src/font-chef/font.c index fd75b25..f998b30 100644 --- a/src/font-chef/font.c +++ b/src/font-chef/font.c @@ -102,7 +102,7 @@ void fc_cook(struct fc_font * font) { free(pixels_1bpp); } -int fc_render( +struct fc_render_result fc_render( struct fc_font const * font, unsigned char const * text, size_t byte_count, @@ -165,7 +165,12 @@ int fc_render( } /* end of the loop, target_index will be the amount of decoded glyphs */ - return (int) target_index; + struct fc_render_result result = { + .lines = 1, + .glyphs = (uint32_t) target_index + }; + + return result; } struct fc_font_size fc_get_font_size(struct fc_font const * font) { @@ -212,7 +217,7 @@ void fc_destruct(struct fc_font * font) { free(font); } -int fc_render_wrapped( +struct fc_render_result fc_render_wrapped( struct fc_font const * font, unsigned char const * text, size_t byte_count, @@ -221,10 +226,10 @@ int fc_render_wrapped( enum fc_alignment alignment, struct fc_character_mapping * mapping ) { - int rendered = fc_render(font, text, byte_count, mapping); + struct fc_render_result result = fc_render(font, text, byte_count, mapping); struct fc_size space_metrics = fc_get_space_metrics(font); - fc_wrap(mapping, rendered, (float) line_width, font->metrics.line_height * line_height_multiplier, space_metrics.width, alignment); - return rendered; + result.lines = fc_wrap(mapping, result.glyphs, (float) line_width, font->metrics.line_height * line_height_multiplier, space_metrics.width, alignment); + return result; } struct fc_size fc_get_space_metrics(struct fc_font const * font) { diff --git a/src/font-chef/render-result.c b/src/font-chef/render-result.c index 1c35d0b..41ccf76 100644 --- a/src/font-chef/render-result.c +++ b/src/font-chef/render-result.c @@ -29,7 +29,7 @@ float fc_text_segment_width(struct fc_text_segment const * segment, struct fc_ch return mapping[segment->last].target.right - mapping[segment->first].target.left; } -size_t fc_wrap(struct fc_character_mapping mapping[], size_t glyph_count, float line_width, float line_height, float space_width, enum fc_alignment aligment) { +uint32_t fc_wrap(struct fc_character_mapping mapping[], size_t glyph_count, float line_width, float line_height, float space_width, enum fc_alignment aligment) { struct fc_text_segment * words = calloc(sizeof(*words), glyph_count); struct fc_text_segment * lines = calloc(sizeof(*lines), glyph_count); size_t word_count = 0; From 117baa28706c3f7b2f4d88e7429c5e4183ffec1c Mon Sep 17 00:00:00 2001 From: Leonardo Date: Thu, 17 Sep 2020 01:17:32 -0300 Subject: [PATCH 3/5] code cleanup --- include/font-chef/render-result.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/font-chef/render-result.hpp b/include/font-chef/render-result.hpp index 0c2cc77..55bd596 100644 --- a/include/font-chef/render-result.hpp +++ b/include/font-chef/render-result.hpp @@ -4,7 +4,6 @@ #include "font-chef/character-mapping.h" #include "font-chef/font.h" #include -#include /** @@ -55,7 +54,6 @@ namespace fc { */ render_result(fc_font * font = nullptr, std::vector && mapping = {}) //NOLINT : mapping(mapping), font(font), line_count(0) { - ::printf("construct render result"); }; /** From 1ae7ff4b1d45d1e2daa7f2ce78545cafd1b8bd07 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Thu, 17 Sep 2020 01:22:46 -0300 Subject: [PATCH 4/5] rename fc_render_result lines and glyphs to line_count and glyph_count --- include/font-chef/font.h | 4 ++-- include/font-chef/font.hpp | 4 ++-- src/examples/c/main.c | 4 ++-- src/font-chef/font.c | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/font-chef/font.h b/include/font-chef/font.h index 6bd2706..e760c20 100644 --- a/include/font-chef/font.h +++ b/include/font-chef/font.h @@ -50,12 +50,12 @@ struct fc_render_result { /** * @brief How many lines were produced */ - uint32_t lines; + uint32_t line_count; /** * @brief How many glphs were produced */ - uint32_t glyphs; + uint32_t glyph_count; }; diff --git a/include/font-chef/font.hpp b/include/font-chef/font.hpp index f575f83..498f7da 100644 --- a/include/font-chef/font.hpp +++ b/include/font-chef/font.hpp @@ -210,8 +210,8 @@ namespace fc { std::vector & mapping = result.mapping; if (mapping.size() < text.length()) mapping.resize(text.length()); struct fc_render_result r = fc_render(data, (uint8_t *) text.data(), text.size(), mapping.data()); - mapping.resize(r.glyphs); - result.line_count = r.lines; + mapping.resize(r.glyph_count); + result.line_count = r.line_count; return result; } }; diff --git a/src/examples/c/main.c b/src/examples/c/main.c index 93d7973..1d71591 100644 --- a/src/examples/c/main.c +++ b/src/examples/c/main.c @@ -28,10 +28,10 @@ int main(int argc, char const ** argv) { 1.0f, fc_align_left, mapping ); - fc_move(mapping, result.glyphs, 0.0f, state.bounds.bottom / 2 - 20); + fc_move(mapping, result.glyph_count, 0.0f, state.bounds.bottom / 2 - 20); while (update(&state)) { - for (int i = 0; i < result.glyphs; i++) { + for (int i = 0; i < result.glyph_count; i++) { render(font_texture, mapping[i].source, mapping[i].target); } } diff --git a/src/font-chef/font.c b/src/font-chef/font.c index f998b30..fc680cd 100644 --- a/src/font-chef/font.c +++ b/src/font-chef/font.c @@ -166,8 +166,8 @@ struct fc_render_result fc_render( /* end of the loop, target_index will be the amount of decoded glyphs */ struct fc_render_result result = { - .lines = 1, - .glyphs = (uint32_t) target_index + .line_count = 1, + .glyph_count = (uint32_t) target_index }; return result; @@ -228,7 +228,7 @@ struct fc_render_result fc_render_wrapped( ) { struct fc_render_result result = fc_render(font, text, byte_count, mapping); struct fc_size space_metrics = fc_get_space_metrics(font); - result.lines = fc_wrap(mapping, result.glyphs, (float) line_width, font->metrics.line_height * line_height_multiplier, space_metrics.width, alignment); + result.line_count = fc_wrap(mapping, result.glyph_count, (float) line_width, font->metrics.line_height * line_height_multiplier, space_metrics.width, alignment); return result; } From 2c4965279f6d6a4a93ca2bf4dd26e1b01c027ae2 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Thu, 17 Sep 2020 01:23:11 -0300 Subject: [PATCH 5/5] version bump 1.1.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1daac6e..2d9740c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0063 NEW) -project(font-chef LANGUAGES C CXX VERSION 1.0.2) +project(font-chef LANGUAGES C CXX VERSION 1.1.0) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake-modules) set(CMAKE_C_STANDARD 99)