main.c (5809B)
1 /* By Justin Meiners (2013) */ 2 /* font and image utilties from nothings.org */ 3 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <stdint.h> 7 #include <X11/Xlib.h> 8 #include <X11/Xutil.h> 9 #include <X11/Xos.h> 10 11 /* is c the start of a utf8 sequence? */ 12 #define isutf(c) (((c)&0xC0)!=0x80) 13 14 static const uint32_t offsetsFromUTF8[6] = { 15 0x00000000UL, 0x00003080UL, 0x000E2080UL, 16 0x03C82080UL, 0xFA082080UL, 0x82082080UL 17 }; 18 19 /* next character without NUL character terminator */ 20 uint32_t u8_nextmemchar(const char *s, size_t *i) 21 { 22 uint32_t ch = 0; 23 size_t sz = 0; 24 do { 25 ch <<= 6; 26 ch += (unsigned char)s[(*i)++]; 27 sz++; 28 } while (!isutf(s[*i])); 29 ch -= offsetsFromUTF8[sz-1]; 30 31 return ch; 32 } 33 34 void u8_dec(const char *s, size_t *i) 35 { 36 (void)(isutf(s[--(*i)]) || isutf(s[--(*i)]) || isutf(s[--(*i)]) || --(*i)); 37 } 38 39 #define STB_TRUETYPE_IMPLEMENTATION 40 #include "stb_truetype.h" /* http://nothings.org/stb/stb_truetype.h */ 41 42 Pixmap ltk_draw_text(const unsigned char *text, int line_height, XColor color, XColor background) 43 { 44 /* Get width of text */ 45 int w; 46 } 47 48 int main(int argc, const char * argv[]) 49 { 50 51 Display *display; 52 int screen; 53 Window window; 54 GC gc; 55 56 unsigned long black, white; 57 Colormap colormap; 58 display = XOpenDisplay((char *)0); 59 screen = DefaultScreen(display); 60 colormap = DefaultColormap(display, screen); 61 black = BlackPixel(display, screen); 62 white = WhitePixel(display, screen); 63 window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0, 1366, 512, 0, black, white); 64 XSetStandardProperties(display, window, "Random Window", NULL, None, NULL, 0, NULL); 65 XSelectInput(display, window, ExposureMask|ButtonPressMask|KeyPressMask); 66 gc = XCreateGC(display, window, 0, 0); 67 XSetBackground(display, gc, black); 68 XSetForeground(display, gc, black); 69 XClearWindow(display, window); 70 XMapRaised(display, window); 71 72 /* load font file */ 73 FILE *f; 74 long len; 75 char *file_contents; 76 f = fopen("font1.ttf", "rb"); 77 fseek(f, 0, SEEK_END); 78 len = ftell(f); 79 fseek(f, 0, SEEK_SET); 80 file_contents = malloc(len + 1); 81 fread(file_contents, 1, len, f); 82 file_contents[len] = '\0'; 83 fclose(f); 84 unsigned char *fontBuffer = file_contents; 85 86 /* prepare font */ 87 stbtt_fontinfo info; 88 if (!stbtt_InitFont(&info, fontBuffer, 0)) 89 { 90 printf("failed\n"); 91 } 92 93 int b_w = 1366; /* bitmap width */ 94 int b_h = 100; /* bitmap height */ 95 int l_h = 100; /* line height */ 96 97 /* create a bitmap for the phrase */ 98 unsigned char *bitmap = malloc(b_w * b_h); 99 100 /* calculate font scaling */ 101 float scale = stbtt_ScaleForPixelHeight(&info, l_h); 102 103 //uint8_t *word = "ہمارے بارے میں"; 104 //char *word = "Hello"; 105 uint8_t *word = "sfsdf"; 106 107 int x = 0; 108 109 int ascent, descent, lineGap; 110 stbtt_GetFontVMetrics(&info, &ascent, &descent, &lineGap); 111 112 ascent *= scale; 113 descent *= scale; 114 115 Pixmap pix = XCreatePixmap(display, window, b_w, l_h, 24); 116 XColor green; 117 XParseColor(display, colormap, "#00FFFF", &green); 118 XAllocColor(display, colormap, &green); 119 XColor green1; 120 XParseColor(display, colormap, "#FF0000", &green1); 121 XAllocColor(display, colormap, &green1); 122 123 size_t i = 0; 124 int length = strlen(word); 125 uint32_t target; 126 uint32_t target1; 127 unsigned char *bob; 128 int x1, y1, xoff, yoff; 129 while (i < length) 130 { 131 target = u8_nextmemchar(word, &i); 132 if (!target) break; 133 /* get bounding box for character (may be offset to account for chars that dip above or below the line */ 134 int c_x1, c_y1, c_x2, c_y2; 135 stbtt_GetCodepointBitmapBox(&info, target, scale, scale, &c_x1, &c_y1, &c_x2, &c_y2); 136 137 /* compute y (different characters have different heights */ 138 int y = ascent + c_y1; 139 140 /* render character (stride and offset is important here) */ 141 int byteOffset = x + (y * b_w); 142 bob = stbtt_GetCodepointBitmap(&info, scale, scale, target, &x1, &y1, &xoff, &yoff); 143 // stbtt_MakeCodepointBitmap(&info, bitmap + byteOffset, c_x2 - c_x1, c_y2 - c_y1, b_w, scale, scale, target); 144 145 for (int i = 0; i < y1; i++) 146 { 147 for (int j = 0; j < x1; j++) 148 { 149 XSetForeground(display, gc, (bob[i * x1 + j] / 255.0) * black + ((255 - bob[i * x1 + j]) / 255.0) * white); 150 XDrawPoint(display, pix, gc, x + j, i); 151 } 152 } 153 154 /* how wide is this character */ 155 int ax; 156 stbtt_GetCodepointHMetrics(&info, target, &ax, 0); 157 x += ax * scale; 158 159 /* add kerning */ 160 target1 = u8_nextmemchar(word, &i); 161 if (!target1) break; 162 u8_dec(word, &i); 163 int kern; 164 kern = stbtt_GetCodepointKernAdvance(&info, target, target1); 165 x += kern * scale; 166 } 167 /* save out a 1 channel image */ 168 /*stbi_write_png("out.png", b_w, b_h, 1, bitmap, b_w);*/ 169 XSetForeground(display, gc, white); 170 /* 171 Pixmap pix = XCreatePixmapFromBitmapData(display, window, bitmap, b_w, b_h, white, black, 24); 172 */ 173 XCopyArea(display, pix, window, gc, 0, 0, b_w, b_h, 0, 0); 174 175 XEvent event; 176 KeySym key; 177 char text[255]; 178 179 while(1) 180 { 181 XNextEvent(display, &event); 182 if (event.type == KeyPress && XLookupString(&event.xkey, text, 255, &key, 0) == 1) 183 { 184 XCopyArea(display, pix, window, gc, 0, 0, b_w, b_h, 0, 0); 185 if (text[0] == 'q') 186 { 187 XFreeGC(display, gc); 188 XFreeColormap(display, colormap); 189 XDestroyWindow(display, window); 190 XCloseDisplay(display); 191 exit(0); 192 } 193 } 194 } 195 196 free(fontBuffer); 197 free(bitmap); 198 199 return 0; 200 }