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 }