ltkx

GUI toolkit for X11 (WIP)
git clone git://lumidify.org/ltkx.git
Log | Files | Refs | README | LICENSE

new.c (3813B)


      1 #define STB_TRUETYPE_IMPLEMENTATION
      2 #include "stb_truetype.h"
      3 #define STB_IMAGE_WRITE_IMPLEMENTATION
      4 #include "stb_image_write.h"
      5 #include <harfbuzz/hb.h>
      6 #include <harfbuzz/hb-ot.h>
      7 
      8 char *ltk_load_file(const char *path, size_t *len)
      9 {
     10         FILE *f;
     11         char *contents;
     12         f = fopen(path, "rb");
     13         fseek(f, 0, SEEK_END);
     14         *len = ftell(f);
     15         fseek(f, 0, SEEK_SET);
     16         contents = malloc(*len + 1);
     17         fread(contents, 1, *len, f);
     18         contents[*len] = '\0';
     19         fclose(f);
     20         return contents;
     21 }
     22 
     23 int main(int argc, char *argv[])
     24 {
     25    stbtt_fontinfo font;
     26    hb_blob_t *blob;
     27    hb_face_t *face;
     28    size_t filelen = 0;
     29    char *filedata = ltk_load_file("NotoNastaliqUrdu-Regular.ttf", &filelen);
     30 
     31    if (filedata == 0) exit(1);
     32    if (!stbtt_InitFont(&font, filedata, stbtt_GetFontOffsetForIndex(filedata,0))) exit(1);
     33 
     34    int height = 32;
     35    int font_scale = stbtt_ScaleForPixelHeight(&font, height);
     36 
     37    blob = hb_blob_create((const char *)filedata, (unsigned int)filelen, HB_MEMORY_MODE_READONLY, NULL, NULL);
     38    if (!blob) exit(1);
     39    face = hb_face_create(blob, 0);
     40    if (!face) exit(1);
     41    hb_blob_destroy(blob); // face keeps its ref.
     42 
     43    hb_font_t *hb_font = hb_font_create(face);
     44    if (!hb_font) exit(1);
     45    hb_face_destroy(face); // font keeps ref
     46 
     47    // stb_truetype only does TrueType/OpenType which HB supports natively
     48    hb_ot_font_set_funcs(hb_font);
     49 
     50    int x = 0;
     51    int y = 0;
     52    const char *msg = "ہمارے بارے میں";
     53 
     54    hb_buffer_t *buf;
     55    hb_glyph_info_t *ginf;
     56    hb_glyph_position_t *gpos;
     57    unsigned int len = 0;
     58 
     59    buf = hb_buffer_create();
     60    if (!buf) exit(1);
     61 
     62    // set up the buffer
     63    hb_buffer_set_flags(buf, HB_BUFFER_FLAG_BOT | HB_BUFFER_FLAG_EOT); // beginning and end of text both
     64    hb_buffer_add_utf8(buf, msg, -1, 0, -1);
     65 
     66    hb_buffer_guess_segment_properties(buf);
     67 
     68    // shape it
     69    hb_shape(hb_font, buf, NULL, 0);
     70 
     71    ginf = hb_buffer_get_glyph_infos(buf, &len);
     72    gpos = hb_buffer_get_glyph_positions(buf, &len);
     73    if ((!ginf || !gpos) && len) exit(1);
     74 
     75    int width = 0;
     76    for (int i = 0; i < len; i++) {
     77 	width += gpos[i].x_advance * font_scale;
     78    }
     79 
     80    unsigned char *bitmap = calloc((width + 100) * (height + 100), sizeof(unsigned char));
     81 
     82         int ascent, descent, line_gap;
     83         stbtt_GetFontVMetrics(&font, &ascent, &descent, &line_gap);
     84         ascent *= font_scale;
     85         descent *= font_scale;
     86 
     87         int ax, x1, y1, x2, y2, byte_offset, kern_advance;
     88 	unsigned char *b;
     89 	for (int i = 0; i < len; i++)
     90         {
     91 		hb_glyph_info_t *gi = &ginf[i];
     92 		hb_glyph_position_t *gp = &gpos[i];
     93                 stbtt_GetGlyphBitmapBox(&font, gi->codepoint, font_scale, font_scale, &x1, &y1, &x2, &y2);
     94                 y = ascent + y1;
     95                 byte_offset = x + (y  * width);
     96                 b = stbtt_GetGlyphBitmap(&font, font_scale, font_scale, gi->codepoint, &x1, &y1, &x2, &y2);
     97 		int h = y2 - y1;
     98 		int x = x2 - x1;
     99 		for (int i = 0; i < height; i++)
    100 		{
    101 			for (int j = 0; j < width; j++)
    102 			{
    103                                 bitmap[(yb + i) * (width + 100) + (xb + j)] = bitmap[(yb + i) * (width + 100) + (xb + j)] + b[i * w + j];
    104 				if (bitmap[(yb + i) * (width + 100) + (xb + j)] > 255) bitmap[(yb + i) * (width + 100) + (xb + j)] = 255;
    105 			}
    106 		}
    107 		free(b);
    108 
    109                 stbtt_GetGlyphHMetrics(&font, gi->codepoint, &ax, 0);
    110                 x += ax * font_scale;
    111 
    112 		if (i < len - 1) {
    113                 kern_advance = stbtt_GetGlyphKernAdvance(&font, gi->codepoint, &ginf[i + 1]->codepoint);
    114                 x += kern_advance * font_scale;
    115         }
    116 
    117         return bitmap;
    118    }
    119 
    120    printf("sfsdf\n");
    121    stbi_write_png("test.png", width + 100, height + 100, 3, bitmap, sizeof(char) * width);
    122    
    123    hb_buffer_destroy(buf);
    124    hb_font_destroy(hb_font);
    125    return 0;
    126 }