From 959b717b46c00930a66fb8959d3469c0b63f3e66 Mon Sep 17 00:00:00 2001 From: Frederico Linhares Date: Mon, 24 Apr 2023 13:32:39 -0300 Subject: fixt Improve text rendering --- src/vk/character.cpp | 23 ++++++++++++++++------- src/vk/character.hpp | 4 ++-- src/vk/texture.cpp | 35 +++++++++++++++++++++-------------- 3 files changed, 39 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/vk/character.cpp b/src/vk/character.cpp index 04ddb0c..e5eb87f 100644 --- a/src/vk/character.cpp +++ b/src/vk/character.cpp @@ -61,19 +61,28 @@ load_image(void *obj) error = FT_Render_Glyph(self->face->glyph, FT_RENDER_MODE_NORMAL); if(error) throw CommandError{"failed to render glyph"}; + self->character->bearing_x = self->face->glyph->bitmap_left; + self->character->bearing_y = self->face->glyph->bitmap_top; + self->character->advance = (self->face->glyph->advance.x >> 6); self->character->width = self->face->glyph->bitmap.width; self->character->height = self->face->glyph->bitmap.rows; self->character->mip_levels = 1; - self->character->bearing_x = self->face->glyph->bitmap_left; - self->character->bearing_y = self->face->glyph->bitmap_top; - self->character->advance = self->face->glyph->bitmap.width; // self->face->glyph->advance.x; + + // Character is a white-space. + if(self->character->width <= 0) + { + self->character->image = VK_NULL_HANDLE; + self->character->device_memory = VK_NULL_HANDLE; + + return; + } auto image_size{static_cast( self->face->glyph->bitmap.width * self->face->glyph->bitmap.rows * num_channels)}; { // Create the data for the image buffer - source_image_raw.resize(image_size); + source_image_raw.resize(image_size, 0); for(auto y{0}; y < self->face->glyph->bitmap.width; y++) { @@ -83,11 +92,11 @@ load_image(void *obj) x * num_channels; auto glyph_coord = y * self->face->glyph->bitmap.rows + x; // Red - source_image_raw[image_coord] = 0; + source_image_raw[image_coord] = 255; // Green - source_image_raw[image_coord + 1] = 0; + source_image_raw[image_coord + 1] = 255; // Blue - source_image_raw[image_coord + 2] = 0; + source_image_raw[image_coord + 2] = 255; // Alpha source_image_raw[image_coord + 3] = self->face->glyph->bitmap.buffer[glyph_coord]; diff --git a/src/vk/character.hpp b/src/vk/character.hpp index c1dfc79..82ada49 100644 --- a/src/vk/character.hpp +++ b/src/vk/character.hpp @@ -31,8 +31,8 @@ struct Character { VkImage image; VkDeviceMemory device_memory; - uint32_t width, height, bearing_x, bearing_y, advance; - uint32_t mip_levels; + int32_t bearing_y, bearing_x; + uint32_t width, height, advance, mip_levels; Character(FT_Face face, uint32_t character_code); ~Character(); diff --git a/src/vk/texture.cpp b/src/vk/texture.cpp index 93bfe61..c699ecc 100644 --- a/src/vk/texture.cpp +++ b/src/vk/texture.cpp @@ -247,12 +247,11 @@ const CommandChain image_loader{ struct CharacterToDraw { - int pos_x, pos_y; + int pos_x; std::shared_ptr character; - CharacterToDraw(int x, int y, std::shared_ptr character): + CharacterToDraw(int x, std::shared_ptr character): pos_x{x}, - pos_y{y}, character{character} {}; }; @@ -261,6 +260,7 @@ struct TextTextureBuilder: public ImageBuilder { VK::Font *font; const char* str; + uint32_t max_bearing_y; std::vector chars_to_draw; TextTextureBuilder(VK::Texture *texture, VK::Font *font, const char* str): @@ -276,31 +276,35 @@ load_text_proportions(void *obj) { auto self = static_cast(obj); - uint32_t texture_width, texture_height; + uint32_t texture_width{0}, texture_descender{0}; auto unicode_text{VK::Character::str_to_unicode(self->str)}; - texture_width = 0; - texture_height = 0; + auto first_image{self->font->character(unicode_text[0])}; + if(first_image->bearing_x < 0) texture_width = - first_image->bearing_x; + + self->max_bearing_y = 0; self->chars_to_draw.reserve(unicode_text.size()); { // Calculate image size int max_height; for(auto char_code : unicode_text) { - auto char_image = self->font->character(char_code); + auto char_image{self->font->character(char_code)}; + uint32_t descender{char_image->height - char_image->bearing_y}; uint32_t pos_x{texture_width + char_image->bearing_x}; - uint32_t pos_y{char_image->height - char_image->bearing_y}; - self->chars_to_draw.emplace_back(pos_x, pos_y, char_image); + if(char_image->image != VK_NULL_HANDLE) + self->chars_to_draw.emplace_back(pos_x, char_image); - if(char_image->height > texture_height) - texture_height = char_image->height; + if(char_image->bearing_y > self->max_bearing_y) + self->max_bearing_y = char_image->bearing_y; + if(descender > texture_descender) texture_descender = descender; texture_width += char_image->advance; } } self->texture->width = texture_width; - self->texture->height = texture_height; + self->texture->height = self->max_bearing_y + texture_descender; self->texture->mip_levels = 1; } @@ -323,7 +327,7 @@ load_text_image(void *obj) pixels[image_coord] = 0; // Red pixels[image_coord + 1] = 0; // Green pixels[image_coord + 2] = 0; // Blue - pixels[image_coord + 3] = 255; // Alpha + pixels[image_coord + 3] = 0; // Alpha } } VK::SourceBuffer source_image_buffer{ @@ -392,7 +396,10 @@ load_text_image(void *obj) image_copy.srcSubresource = source_subresources; image_copy.srcOffset = {0, 0, 0}; image_copy.dstSubresource = destination_subresources; - image_copy.dstOffset = {to_draw.pos_x, to_draw.pos_y, 0}; + image_copy.dstOffset = { + to_draw.pos_x, + (int)(self->max_bearing_y - to_draw.character->bearing_y), + 0}; image_copy.extent = { to_draw.character->width, to_draw.character->height, 1}; -- cgit v1.2.3