src/text.c
  1#include "alba.h"
  2
  3#include <pthread.h>
  4
  5#include "freetype/ftglyph.h"
  6
  7#include "internal.h"
  8
  9extern char _binary_Roboto_Regular_ttf_start[];
 10extern char _binary_Roboto_Regular_ttf_end[];
 11
 12static FT_Library freetype = NULL;
 13static FT_Face roboto = NULL;
 14Atlas atlas;
 15pthread_mutex_t freetype_mutex = PTHREAD_MUTEX_INITIALIZER;
 16
 17void initialize_freetype()
 18{
 19    // already initialized
 20    if (freetype != NULL) return;
 21
 22    pthread_mutex_lock(&freetype_mutex);
 23    if (FT_Init_FreeType(&freetype))
 24    {
 25        printf("fatal error: initializeing FreeType failed");
 26        pthread_mutex_unlock(&freetype_mutex);
 27        exit(1);
 28    }
 29
 30    FT_Error error = FT_New_Memory_Face(
 31        freetype,
 32        _binary_Roboto_Regular_ttf_start,
 33        _binary_Roboto_Regular_ttf_end - _binary_Roboto_Regular_ttf_start,
 34        0, // face index
 35        &roboto
 36    );
 37    if (error)
 38    {
 39        printf("error: cound not load built in Roboto font");
 40    }
 41    error = FT_Set_Pixel_Sizes(roboto, 0 /* width, same as height */, 16);
 42    if (error)
 43    {
 44        printf("error: cound not set Roboto face size");
 45    }
 46
 47    atlas = atlas_new(1024);
 48
 49    pthread_mutex_unlock(&freetype_mutex);
 50}
 51
 52WGPUTexture create_texture(const AlbaWindow* window, const uint64_t width, const uint64_t height, const void* data)
 53{
 54    WGPUTextureDescriptor texture_options = {0};
 55    texture_options.usage = WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst;
 56    texture_options.format = WGPUTextureFormat_RGBA8UnormSrgb;
 57    texture_options.dimension = WGPUTextureDimension_2D;
 58    texture_options.size.width = width;
 59    texture_options.size.height = height;
 60    texture_options.size.depthOrArrayLayers = 1;
 61    texture_options.sampleCount = 1;
 62    texture_options.mipLevelCount = 1;
 63    const WGPUTexture texture = wgpuDeviceCreateTexture(window->device, &texture_options);
 64
 65    WGPUImageCopyTexture destination = {0};
 66    destination.texture = texture;
 67    destination.aspect = WGPUTextureAspect_All;
 68    WGPUTextureDataLayout source = {0};
 69    source.bytesPerRow = 4 * width;
 70    source.rowsPerImage = height;
 71    wgpuQueueWriteTexture(window->queue, &destination, data, width * height * 4, &source, &texture_options.size);
 72
 73    return texture;
 74}
 75
 76void draw_text(AlbaWindow* window, const float x, const float y, uint64_t length, const char* text)
 77{
 78    initialize_freetype();
 79
 80    if (length == 0)
 81    {
 82        length = strlen(text);
 83    }
 84
 85    pthread_mutex_lock(&freetype_mutex);
 86    for (uint64_t i = 0; i < length; i++)
 87    {
 88        atlas_append(&atlas, roboto, text[i]); // TODO: unicode
 89    }
 90    pthread_mutex_unlock(&freetype_mutex);
 91
 92    // FT_Error error = FT_Load_Char(roboto, '7', FT_LOAD_RENDER);
 93    // printf("%d\n", roboto->glyph->bitmap.width);
 94    // error = FT_Load_Char(roboto, 'l', FT_LOAD_RENDER);
 95    // printf("%d\n", roboto->glyph->bitmap.width);
 96    // error = FT_Load_Char(roboto, 'm', FT_LOAD_RENDER);
 97    // printf("%d\n", roboto->glyph->bitmap.width);
 98
 99    atlas_generate_image(&atlas);
100}