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) diff --git a/include/font-chef/character-mapping.h b/include/font-chef/character-mapping.h index bc7636b..4578c98 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 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..e760c20 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 line_count; + + /** + * @brief How many glphs were produced + */ + uint32_t glyph_count; +}; + /** * @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..498f7da 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.glyph_count); + result.line_count = r.line_count; return result; } }; diff --git a/include/font-chef/render-result.hpp b/include/font-chef/render-result.hpp index ec932c7..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 /** @@ -33,6 +32,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,8 +53,7 @@ namespace fc { * @sa fc::font::render */ render_result(fc_font * font = nullptr, std::vector && mapping = {}) //NOLINT - : mapping(mapping), font(font) { - ::printf("construct render result"); + : mapping(mapping), font(font), line_count(0) { }; /** @@ -58,7 +61,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 +74,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 +115,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..1d71591 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.glyph_count, 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.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 d17922e..fc680cd 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, @@ -104,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, @@ -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,18 +164,13 @@ 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; + struct fc_render_result result = { + .line_count = 1, + .glyph_count = (uint32_t) target_index + }; + + return result; } struct fc_font_size fc_get_font_size(struct fc_font const * font) { @@ -229,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, @@ -238,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.line_count = fc_wrap(mapping, result.glyph_count, (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 8db156a..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; } -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) { +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; @@ -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) {