fork(1) download
  1. // copyright ◆en3PGsfOXo http://t...content-available-to-author-only...h.net/test/read.cgi/tech/1363042502/
  2.  
  3. #include <windows.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6.  
  7. BYTE *gflg = "AQv/8AIYH8k5JMkBA/ACCxeSSSQBA/ABDP/4ARLJ+SACEyDkknySAAIDB/8=";
  8. BYTE *glyf = "AAwASAU7AAD/OgAAAAAC2f0ZAAAAAP0n/zoAAAAABdEAxgAAAAD9uALnAAAAAAJI"
  9. "AMYAAAAgAGUEYAIb/MkAAAAA/5kAPv9nADb/zwA0/9AAj//QAFYAAAByAAAA5wBb"
  10. "ADEALAAKAAAAAP8z/6H/2P86/8r/kwAA/uoAAP7IAS0AAAEVAAABEgErAUIA9AAA"
  11. "AOIAAAD1/vgAAP8N/0kAKv//AJT/bQCi/2oAAP9pAAD/Tf9O//T/fAAEAGwBdwAA"
  12. "/0QAAAAABhQAvAAAABgAbwRxAi4AAP7v/uj+xP8VAAD/EwAA/ukBPAAAAREAAAER"
  13. "ARcBPQDtAAAA6wAAARj+w/8+/u8AAADZ/1YA0/9pAAD/ZwAA/1f/LQAA/ycAAP8u"
  14. "AKr/JwCYAAAAlgAAAKsA1wAEACwCPwEd/ub9cf9uAAAArgKPAA0AdwY2BF3+3fuj"
  15. "/1IAAP7hA13+4/yj/1MAAP7aBF0AxAAAAM38nwEXA2EAmwAAAR78nwDCA2EAEwBy"
  16. "A3IDkP/2AAD/1gAK/7EACf/KAAD/qQAA/17/s/+1/8MAAPzn/0QAAAAABF0AvAAA"
  17. "AAD/WwBwAFoAqwBLAFkAAAAxAAAALP/7ACz/+QAhAGQEQwAA/0QAAAAAAHX/r/+6"
  18. "/1D/sv+ZAAD/OAAA/xUBNAAAAREAAACOAFEA3gBFAE4ARABMALUAUABhAAAAWAAA"
  19. "AIj/2wBL/9kAAAHkALwAAP9E+v8AAAKB/7QAIv+IABr/uQAA/2IAAP9Q/yQAAP82"
  20. "AAD/OQCI/zEAlgAAAFAAAACkAEcACAAhAgMF0f/m+8n/VgAA/+QENwDW+i//NAAA"
  21. "AAAA0wDMAAA=";
  22. int glyf_len = 0;
  23.  
  24. int b64decode(BYTE *dst, size_t *dst_size, BYTE *src, int src_size)
  25. {
  26. static BYTE b64o[80] = {
  27. 62, 0, 62, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0,
  28. 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  29. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
  30. 0, 0, 0, 62, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
  31. 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
  32. int i, words = src_size/4, oversize = *dst_size+2, lasti = oversize/3-1;
  33. if(src_size % 4) return 1;
  34. if(*dst_size < words * 3) return 2;
  35. for(i = 0; i <= lasti; i++){
  36. int j;
  37. BYTE c[4];
  38. for(j = 0; j < sizeof(c); j++)
  39. c[j] = b64o[(src[i * sizeof(c) + j] - '+') % sizeof(b64o)];
  40. dst[i * 3 + 0] = ((c[0] << 2) & 0x00fc) | ((c[1] >> 4) & 0x03);
  41. if(i < lasti || oversize % 3)
  42. dst[i * 3 + 1] = ((c[1] << 4) & 0x00f0) | ((c[2] >> 2) & 0x0f);
  43. if(i < lasti || (oversize % 3) == 2)
  44. dst[i * 3 + 2] = ((c[2] << 6) & 0x00c0) | (c[3] & 0x3f);
  45. }
  46. if(src[src_size - 1] == '='){
  47. --(*dst_size);
  48. if(src[src_size - 2] == '=') --(*dst_size);
  49. }
  50. return 0;
  51. }
  52.  
  53. int initGlyph(BYTE *str)
  54. {
  55. int len = (strlen(str) >> 2) * 3;
  56. if(b64decode(str, &len, str, strlen(str))) return 0;
  57. return len;
  58. }
  59.  
  60. int b2h(BYTE *b)
  61. {
  62. return (short)((b[0] << 8) | b[1]);
  63. }
  64.  
  65. int getGlyphData(BYTE **epoc, BYTE **flags, int **xcoords, int **ycoords,
  66. int *numepoc, char ch)
  67. {
  68. int i, j, k, pos = 0, num = 0, code = 0, fpos = 0, epnum = 0, fnum = 0;
  69. *epoc = *flags = NULL, *xcoords = *ycoords = NULL, *numepoc = 0;
  70. while(pos < glyf_len){
  71. num = b2h(&glyf[pos]), code = b2h(&glyf[pos + 2]);
  72. epnum = gflg[fpos], fnum = (num + 7) / 8;
  73. if(code == ch){
  74. *epoc = (BYTE *)malloc(*numepoc = epnum);
  75. if(!*epoc) break;
  76. for(i = 0; i < epnum; ++i) (*epoc)[i] = gflg[fpos + 1 + i];
  77. *flags = (BYTE *)malloc(num);
  78. if(!*flags) break;
  79. for(i = 0, k = 0; i < fnum; ++i){
  80. BYTE b = gflg[fpos + 1 + epnum + i];
  81. BYTE m = 0x80;
  82. for(j = 0; j < 8 - (i == fnum - 1 ? fnum * 8 - num : 0); ++j, m >>= 1)
  83. (*flags)[k++] = b & m ? 1 : 0;
  84. }
  85. break;
  86. }
  87. pos += (num + 1) * 4;
  88. fpos += epnum + fnum + 1;
  89. }
  90. if(!*epoc || !*flags) return 0;
  91. *xcoords = (int *)malloc(num * sizeof(int));
  92. *ycoords = (int *)malloc(num * sizeof(int));
  93. if(!*xcoords || !*ycoords) return 0;
  94. for(i = 0; i < num; ++i){
  95. (*xcoords)[i] = (i ? (*xcoords)[i-1] : 0) + b2h(&glyf[pos + (i+1)*4]);
  96. (*ycoords)[i] = (i ? (*ycoords)[i-1] : 0) + b2h(&glyf[pos + (i+1)*4 + 2]);
  97. }
  98. return num;
  99. }
  100.  
  101. int drawGlyph(HDC hdc, int scale, int szx, int szy, int ox, int oy,
  102. int *w, int *h, int ch)
  103. {
  104. BYTE *epoc, *flags;
  105. int *xcoords, *ycoords, numepoc, i, j;
  106. int numflags = getGlyphData(&epoc, &flags, &xcoords, &ycoords, &numepoc, ch);
  107. *w = 80, *h = 160;
  108. if(!numflags) return 0;
  109. for(j = 0; j < numepoc; ++j){
  110. int px, py, k = j ? epoc[j - 1] + 1 : 0;
  111. for(i = k; i <= epoc[j]; ++i){
  112. int flg = flags[i], x = xcoords[i], y = ycoords[i];
  113. int r = i == k ? 4 : 3;
  114. COLORREF col = flg & 0x01 ? RGB(0, 0, 255) : RGB(255, 0, 0);
  115. HPEN hpen = CreatePen(PS_SOLID, 1, col);
  116. HPEN hopen = (HPEN)SelectObject(hdc, hpen);
  117. HBRUSH hbrush, hobrush;
  118. if(i == k) hbrush = CreateSolidBrush(RGB(0, 255, 0));
  119. else hbrush = (HBRUSH)GetStockObject(HOLLOW_BRUSH);
  120. hobrush = (HBRUSH)SelectObject(hdc, hbrush);
  121. Ellipse(hdc, ox - r + x / scale, szy - (oy - r + y / scale),
  122. ox + r + x / scale, szy - (oy + r + y / scale));
  123. SelectObject(hdc, hobrush);
  124. if(i == k) DeleteObject(hbrush);
  125. SelectObject(hdc, hopen);
  126. DeleteObject(hpen);
  127. if(i != k) stroke(hdc, scale, szx, szy, ox, oy, px, py, x, y);
  128. px = x, py = y;
  129. }
  130. stroke(hdc, scale, szx, szy, ox, oy, px, py, xcoords[k], ycoords[k]);
  131. }
  132. if(epoc) free(epoc);
  133. if(flags) free(flags);
  134. if(xcoords) free(xcoords);
  135. if(ycoords) free(ycoords);
  136. return 0;
  137. }
  138.  
  139. int stroke(HDC hdc, int scale, int szx, int szy, int ox, int oy,
  140. int xs, int ys, int xe, int ye)
  141. {
  142. POINT p;
  143. MoveToEx(hdc, ox + xs / scale, szy - (oy + ys / scale), &p);
  144. LineTo(hdc, ox + xe / scale, szy - (oy + ye / scale));
  145. return 0;
  146. }
  147.  
  148. int drawStrokes(int scale, int ofx, int ofy, int spx, int spy, char *str)
  149. {
  150. int szx, szy, ox = ofx, oy = ofy;
  151. char *p;
  152. HWND hwnd = GetDesktopWindow();
  153. HDC hdc = GetDC(hwnd);
  154. HPEN hpen = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
  155. HPEN hopen = (HPEN)SelectObject(hdc, hpen);
  156. RECT rc;
  157. GetClientRect(hwnd, &rc);
  158. szx = rc.right - rc.left, szy = rc.bottom - rc.top;
  159. for(p = str; *p; ++p){
  160. int w, h;
  161. drawGlyph(hdc, scale, szx, szy, ox, oy, &w, &h, *p);
  162. if(*p == '\n') ox = ofx, oy -= h + spy;
  163. else ox += w + spx;
  164. }
  165. SelectObject(hdc, hopen);
  166. DeleteObject(hpen);
  167. ReleaseDC(hwnd, hdc);
  168. return 0;
  169. }
  170.  
  171. int main(int ac, char **av)
  172. {
  173. if(!initGlyph(gflg)) fprintf(stderr, "error 1");
  174. if(!(glyf_len = initGlyph(glyf))) fprintf(stderr, "error 2");
  175. drawStrokes(10, 120, 480, 40, 40, "Hello,\nworld!");
  176. return 0;
  177. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty