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 */, 18);
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}