summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFrederico Linhares <fred@linhares.blue>2023-04-24 13:32:39 -0300
committerFrederico Linhares <fred@linhares.blue>2023-04-24 13:32:39 -0300
commit959b717b46c00930a66fb8959d3469c0b63f3e66 (patch)
treeff03dc62b3b06929af4545c02d385320828b2229 /src
parent66cb556fb6f87d195aacf8a25ffafb86d524da19 (diff)
fixt Improve text rendering
Diffstat (limited to 'src')
-rw-r--r--src/vk/character.cpp23
-rw-r--r--src/vk/character.hpp4
-rw-r--r--src/vk/texture.cpp35
3 files changed, 39 insertions, 23 deletions
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<size_t>(
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<VK::Character> character;
- CharacterToDraw(int x, int y, std::shared_ptr<VK::Character> character):
+ CharacterToDraw(int x, std::shared_ptr<VK::Character> 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<CharacterToDraw> 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<TextTextureBuilder*>(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};