summaryrefslogtreecommitdiff
path: root/src/vk/character.cpp
diff options
context:
space:
mode:
authorFrederico Linhares <fred@linhares.blue>2024-05-08 17:56:29 -0300
committerFrederico Linhares <fred@linhares.blue>2024-05-08 17:56:29 -0300
commit43821b0cffc5aa419c0218992f06f8962ae54a13 (patch)
tree97bdbbf710a78e6dcb181d92dd83e98d8b329c6d /src/vk/character.cpp
parent70e156d47346ae3198c623e0af75e5703f894db3 (diff)
refa Rename graphical engine to BluCat
Diffstat (limited to 'src/vk/character.cpp')
-rw-r--r--src/vk/character.cpp274
1 files changed, 0 insertions, 274 deletions
diff --git a/src/vk/character.cpp b/src/vk/character.cpp
deleted file mode 100644
index e5eb87f..0000000
--- a/src/vk/character.cpp
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright 2022-2023 Frederico de Oliveira Linhares
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "character.hpp"
-
-#include "../command.hpp"
-#include "../core.hpp"
-#include "font.hpp"
-#include "image.hpp"
-#include "source_buffer.hpp"
-
-namespace
-{
-
-struct CharacterBuilder
-{
- VK::Character *character;
- FT_Face face;
- uint32_t character_code;
-
- CharacterBuilder(
- VK::Character *character, FT_Face face, uint32_t character_code);
-};
-
-CharacterBuilder::CharacterBuilder(
- VK::Character *character, FT_Face face, uint32_t character_code):
- character{character},
- face{face},
- character_code{character_code}
-{
-}
-
-// TODO: creating one image with one device memory for each character is
-// ineficient
-void
-load_image(void *obj)
-{
- auto self = static_cast<CharacterBuilder*>(obj);
-
- FT_Error error;
- std::vector<uint8_t> source_image_raw;
- const int num_channels = 4; // all images are converted to RGBA
- auto glyph_index{FT_Get_Char_Index(self->face, self->character_code)};
-
- error = FT_Load_Glyph(self->face, glyph_index, FT_LOAD_DEFAULT);
- if(error) throw CommandError{"failed to load glyph"};
-
- 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;
-
- // 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, 0);
-
- for(auto y{0}; y < self->face->glyph->bitmap.width; y++)
- {
- for(auto x{0}; x < self->face->glyph->bitmap.rows; x++)
- {
- auto image_coord = y * self->face->glyph->bitmap.rows * num_channels +
- x * num_channels;
- auto glyph_coord = y * self->face->glyph->bitmap.rows + x;
- // Red
- source_image_raw[image_coord] = 255;
- // Green
- source_image_raw[image_coord + 1] = 255;
- // Blue
- source_image_raw[image_coord + 2] = 255;
- // Alpha
- source_image_raw[image_coord + 3] =
- self->face->glyph->bitmap.buffer[glyph_coord];
- }
- }
- }
-
- VK::SourceBuffer source_image_buffer{
- cg_core.vk_device_with_swapchain, source_image_raw.data(),
- image_size};
-
- { // Create Vulkan image.
- try
- {
- VkExtent3D vk_extent3d;
- vk_extent3d.width = self->face->glyph->bitmap.width;
- vk_extent3d.height = self->face->glyph->bitmap.rows;
- vk_extent3d.depth = 1;
-
- VK::Image::create(
- cg_core.vk_device_with_swapchain,
- &self->character->image,
- &self->character->device_memory,
- VK_FORMAT_R8G8B8A8_UNORM,
- vk_extent3d,
- self->character->mip_levels,
- VK_IMAGE_TILING_OPTIMAL,
- VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
- }
- catch(VK::Image::Error error)
- {
- throw CommandError{error.what()};
- }
- }
-
- { // Copy image from buffer into image.
- auto queue_family{cg_core.vk_device_with_swapchain->
- get_queue_family_with_presentation()};
- auto queue{queue_family->get_queue()};
- VK::CommandPool command_pool{queue_family, 1};
- VkCommandBuffer vk_command_buffer{command_pool.command_buffers[0]};
-
- queue.submit_one_time_command(vk_command_buffer, [&](){
- VK::Image::move_image_state(
- vk_command_buffer, self->character->image, VK_FORMAT_R8G8B8A8_UNORM,
- 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_HOST_BIT,
- VK_PIPELINE_STAGE_TRANSFER_BIT);
-
- VkBufferImageCopy image_copy;
- image_copy.bufferOffset = 0;
- image_copy.bufferRowLength = 0;
- image_copy.bufferImageHeight = 0;
- image_copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
- image_copy.imageSubresource.mipLevel = 0;
- image_copy.imageSubresource.baseArrayLayer = 0;
- image_copy.imageSubresource.layerCount = 1;
- image_copy.imageOffset = {0, 0, 0};
- image_copy.imageExtent = {
- self->character->width, self->character->height, 1};
-
- vkCmdCopyBufferToImage(
- vk_command_buffer, source_image_buffer.buffer, self->character->image,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &image_copy);
-
- VK::Image::move_image_state(
- vk_command_buffer, self->character->image, VK_FORMAT_R8G8B8A8_UNORM,
- VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
- VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
- VK_PIPELINE_STAGE_TRANSFER_BIT,
- VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
- });
- }
-}
-
-void
-unload_image(void *obj)
-{
- auto self = static_cast<CharacterBuilder*>(obj);
-
- vkDestroyImage(
- cg_core.vk_device_with_swapchain->device, self->character->image, nullptr);
- vkFreeMemory(
- cg_core.vk_device_with_swapchain->device, self->character->device_memory,
- nullptr);
-}
-
-const CommandChain loader{
- {&load_image, &unload_image}
-};
-
-}
-
-namespace VK
-{
-
-Character::Character(FT_Face face, uint32_t character_code)
-{
- CharacterBuilder character_builder(this, face, character_code);
- loader.execute(&character_builder);
-}
-
-Character::~Character()
-{
- CharacterBuilder character_builder(this, nullptr, 0);
- loader.revert(&character_builder);
-}
-
-std::vector<uint32_t>
-Character::str_to_unicode(const char* str)
-{
- std::vector<uint32_t> unicode_text;
- int text_width{0};
- int text_height{0};
-
- { // Reserve memory
- int size{0};
- for(auto i{0}; str[i] != '\0'; i++)
- if((str[i] & 0b11000000) != 0b10000000) size++;
- unicode_text.reserve(size);
- }
-
- for(auto i{0}; str[i] != '\0'; i++)
- {
- int num_bytes;
- uint32_t codepoint{0};
-
- if(str[i] >= 0 && str[i] < 127)
- { // Normal ASCI character, 1-byte.
- num_bytes = 1;
- codepoint = str[i];
- }
- else if((str[i] & 0xE0) == 0xC0)
- { // 2-byte character.
- num_bytes = 2;
- codepoint += ((str[i] & 0b00011111) << 6);
- }
- else if((str[i] & 0xF0) == 0xE0)
- { // 3-byte character.
- num_bytes = 3;
- codepoint += ((str[i] & 0b00001111) << 12);
- }
- else if((str[i] & 0xF8) == 0xF0)
- { // 4-byte character.
- num_bytes = 4;
- codepoint += ((str[i] & 0b00000111) << 18);
- }
- else
- { // FIXME: Add support to 5-byte and 6-byte characters.
- }
-
- switch (num_bytes)
- {
- case 4:
- i++;
- codepoint += ((str[i] & 0b00111111) << 12);
- case 3:
- i++;
- codepoint += ((str[i] & 0b00111111) << 6);
- case 2:
- i++;
- codepoint += (str[i] & 0b00111111);
- case 1:
- default:
- break;
- }
-
- unicode_text.push_back(codepoint);
- }
-
- return unicode_text;
-}
-
-}