fork 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. #define SHOW_MARK 1
  8.  
  9. char *TITLE = "glyf";
  10. BYTE *gflg = "AQv/8AIYH8k5JMkBA/ACCxeSSSQBA/ABDP/4ARLJ+SACEyDkknySAAIDB/8=";
  11. BYTE *glyf = "AAwASAU7AAD/OgAAAAAC2f0ZAAAAAP0n/zoAAAAABdEAxgAAAAD9uALnAAAAAAJI"
  12. "AMYAAAAgAGUEYAIb/MkAAAAA/5kAPv9nADb/zwA0/9AAj//QAFYAAAByAAAA5wBb"
  13. "ADEALAAKAAAAAP8z/6H/2P86/8r/kwAA/uoAAP7IAS0AAAEVAAABEgErAUIA9AAA"
  14. "AOIAAAD1/vgAAP8N/0kAKv//AJT/bQCi/2oAAP9pAAD/Tf9O//T/fAAEAGwBdwAA"
  15. "/0QAAAAABhQAvAAAABgAbwRxAi4AAP7v/uj+xP8VAAD/EwAA/ukBPAAAAREAAAER"
  16. "ARcBPQDtAAAA6wAAARj+w/8+/u8AAADZ/1YA0/9pAAD/ZwAA/1f/LQAA/ycAAP8u"
  17. "AKr/JwCYAAAAlgAAAKsA1wAEACwCPwEd/ub9cf9uAAAArgKPAA0AdwY2BF3+3fuj"
  18. "/1IAAP7hA13+4/yj/1MAAP7aBF0AxAAAAM38nwEXA2EAmwAAAR78nwDCA2EAEwBy"
  19. "A3IDkP/2AAD/1gAK/7EACf/KAAD/qQAA/17/s/+1/8MAAPzn/0QAAAAABF0AvAAA"
  20. "AAD/WwBwAFoAqwBLAFkAAAAxAAAALP/7ACz/+QAhAGQEQwAA/0QAAAAAAHX/r/+6"
  21. "/1D/sv+ZAAD/OAAA/xUBNAAAAREAAACOAFEA3gBFAE4ARABMALUAUABhAAAAWAAA"
  22. "AIj/2wBL/9kAAAHkALwAAP9E+v8AAAKB/7QAIv+IABr/uQAA/2IAAP9Q/yQAAP82"
  23. "AAD/OQCI/zEAlgAAAFAAAACkAEcACAAhAgMF0f/m+8n/VgAA/+QENwDW+i//NAAA"
  24. "AAAA0wDMAAA=";
  25. int glyf_len = 0;
  26.  
  27. typedef struct _CurvePoint {
  28. BYTE flg;
  29. int x, y;
  30. } CurvePoint;
  31.  
  32. typedef struct _DrawInfo {
  33. HDC hdc;
  34. int szx, szy, ox, oy, spx, spy, scale;
  35. int state;
  36. } DrawInfo;
  37.  
  38. int scalex(DrawInfo *di, int x)
  39. {
  40. return di->ox + x / di->scale;
  41. }
  42.  
  43. int scaley(DrawInfo *di, int y)
  44. {
  45. return di->szy - (di->oy + y / di->scale);
  46. }
  47.  
  48. int b64decode(BYTE *dst, size_t *dst_size, BYTE *src, int src_size)
  49. {
  50. static BYTE b64o[80] = {
  51. 62, 0, 62, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0,
  52. 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  53. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
  54. 0, 0, 0, 62, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
  55. 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
  56. int i, words = src_size/4, oversize = *dst_size+2, lasti = oversize/3-1;
  57. if(src_size % 4) return 1;
  58. if(*dst_size < words * 3) return 2;
  59. for(i = 0; i <= lasti; i++){
  60. int j;
  61. BYTE c[4];
  62. for(j = 0; j < sizeof(c); j++)
  63. c[j] = b64o[(src[i * sizeof(c) + j] - '+') % sizeof(b64o)];
  64. dst[i * 3 + 0] = ((c[0] << 2) & 0x00fc) | ((c[1] >> 4) & 0x03);
  65. if(i < lasti || oversize % 3)
  66. dst[i * 3 + 1] = ((c[1] << 4) & 0x00f0) | ((c[2] >> 2) & 0x0f);
  67. if(i < lasti || (oversize % 3) == 2)
  68. dst[i * 3 + 2] = ((c[2] << 6) & 0x00c0) | (c[3] & 0x3f);
  69. }
  70. if(src[src_size - 1] == '='){
  71. --(*dst_size);
  72. if(src[src_size - 2] == '=') --(*dst_size);
  73. }
  74. return 0;
  75. }
  76.  
  77. int initGlyph(BYTE *str)
  78. {
  79. int len = (strlen(str) >> 2) * 3;
  80. if(b64decode(str, &len, str, strlen(str))) return 0;
  81. return len;
  82. }
  83.  
  84. short b2h(BYTE *b)
  85. {
  86. return (short)((b[0] << 8) | b[1]);
  87. }
  88.  
  89. int getGlyphData(CurvePoint **cp, BYTE **epoc, int *numepoc, char ch)
  90. {
  91. int i, j, k, pos = 0, num = 0, code = 0, fpos = 0, epnum = 0, fnum = 0;
  92. *cp = NULL, *epoc = NULL, *numepoc = 0;
  93. while(pos < glyf_len){
  94. num = b2h(&glyf[pos]), code = b2h(&glyf[pos + 2]);
  95. epnum = gflg[fpos], fnum = (num + 7) / 8;
  96. if(code == ch){
  97. if(!(*cp = (CurvePoint *)malloc(num * sizeof(CurvePoint)))) break;
  98. if(!(*epoc = (BYTE *)malloc(*numepoc = epnum))) break;
  99. for(i = 0; i < epnum; ++i) (*epoc)[i] = gflg[fpos + 1 + i];
  100. for(i = 0, k = 0; i < fnum; ++i){
  101. BYTE b = gflg[fpos + 1 + epnum + i];
  102. BYTE m = 0x80;
  103. for(j = 0; j < 8 - (i == fnum - 1 ? fnum * 8 - num : 0); ++j, m >>= 1)
  104. (*cp)[k++].flg = b & m ? 1 : 0;
  105. }
  106. for(i = 0; i < num; ++i){
  107. (*cp)[i].x = (i ? (*cp)[i-1].x : 0) + b2h(&glyf[pos + (i+1)*4]);
  108. (*cp)[i].y = (i ? (*cp)[i-1].y : 0) + b2h(&glyf[pos + (i+1)*4 + 2]);
  109. }
  110. return num;
  111. }
  112. pos += (num + 1) * 4;
  113. fpos += epnum + fnum + 1;
  114. }
  115. return 0;
  116. }
  117.  
  118. int drawGlyph(DrawInfo *di, int *w, int *h, int ch)
  119. {
  120. CurvePoint *cp;
  121. BYTE *epoc;
  122. int numepoc, i, j;
  123. int numflags = getGlyphData(&cp, &epoc, &numepoc, ch);
  124. *w = 80, *h = 160;
  125. if(numflags){
  126. BeginPath(di->hdc);
  127. SetBkMode(di->hdc, TRANSPARENT);
  128. for(j = 0; j < numepoc; ++j){
  129. CurvePoint prv;
  130. int k = j ? epoc[j - 1] + 1 : 0;
  131. for(i = k; i <= epoc[j]; ++i){
  132. CurvePoint cur = cp[i];
  133. di->state = i - k;
  134. if(i == k && !(cur.flg & 0x01))
  135. MessageBox(NULL, "off curve first", TITLE, MB_ICONEXCLAMATION|IDOK);
  136. if(i != k)
  137. if(curve(di, &prv, &cur, &cp[i == epoc[j] ? k : i + 1])) continue;
  138. prv = cur;
  139. }
  140. di->state = i - k;
  141. curve(di, &prv, &cp[k], &cp[k + 1]);
  142. }
  143. EndPath(di->hdc);
  144. FillPath(di->hdc);
  145. if(SHOW_MARK){
  146. for(j = 0; j < numepoc; ++j){
  147. int k = j ? epoc[j - 1] + 1 : 0;
  148. for(i = k; i <= epoc[j]; ++i){
  149. CurvePoint cur = cp[i];
  150. int r = i == k ? 4 : 3;
  151. COLORREF col = cur.flg & 0x01 ? RGB(0, 0, 255) : RGB(255, 0, 0);
  152. HPEN hpen = CreatePen(PS_SOLID, 1, col);
  153. HPEN hopen = (HPEN)SelectObject(di->hdc, hpen);
  154. HBRUSH hbrush, hobrush;
  155. if(i == k) hbrush = CreateSolidBrush(RGB(0, 255, 0));
  156. else hbrush = (HBRUSH)GetStockObject(HOLLOW_BRUSH);
  157. hobrush = (HBRUSH)SelectObject(di->hdc, hbrush);
  158. Ellipse(di->hdc, scalex(di, cur.x) - r, scaley(di, cur.y) + r,
  159. scalex(di, cur.x) + r, scaley(di, cur.y) - r);
  160. SelectObject(di->hdc, hobrush);
  161. if(i == k) DeleteObject(hbrush);
  162. SelectObject(di->hdc, hopen);
  163. DeleteObject(hpen);
  164. }
  165. }
  166. }
  167. }
  168. if(cp) free(cp);
  169. if(epoc) free(epoc);
  170. return 0;
  171. }
  172.  
  173. int bezier(DrawInfo *di, int px, int py, int x, int y, int nx, int ny)
  174. {
  175. #if 0
  176. int t, m = ((nx - px) * (nx - px) + (ny - py) * (ny - py)) / 5000;
  177. if(di->state == 1)
  178. MoveToEx(di->hdc, scalex(di, px), scaley(di, py), NULL);
  179. for(t = 1; t < m; ++t){
  180. float f = t / (float)m;
  181. float a[] = {(1 - f) * (1 - f), 2 * f * (1 - f), f * f};
  182. int tx = a[0] * px + a[1] * x + a[2] * nx;
  183. int ty = a[0] * py + a[1] * y + a[2] * ny;
  184. LineTo(di->hdc, scalex(di, tx), scaley(di, ty));
  185. }
  186. LineTo(di->hdc, scalex(di, nx), scaley(di, ny));
  187. #else
  188. int i;
  189. POINT lppt[4];
  190. lppt[0].x = px, lppt[0].y = py;
  191. lppt[1].x = px + (x - px) * 2 / 3, lppt[1].y = py + (y - py) * 2 / 3;
  192. lppt[2].x = lppt[1].x + (nx - px) / 3, lppt[2].y = lppt[1].y + (ny - py) / 3;
  193. lppt[3].x = nx, lppt[3].y = ny;
  194. for(i = 0; i < sizeof(lppt) / sizeof(lppt[0]); ++i){
  195. lppt[i].x = scalex(di, lppt[i].x);
  196. lppt[i].y = scaley(di, lppt[i].y);
  197. }
  198. if(di->state == 1)
  199. MoveToEx(di->hdc, scalex(di, px), scaley(di, py), NULL);
  200. PolyBezierTo(di->hdc, lppt + 1, (sizeof(lppt) - 1) / sizeof(lppt[0]));
  201. #endif
  202. return 0;
  203. }
  204.  
  205. int curve(DrawInfo *di, CurvePoint *prv, CurvePoint *cur, CurvePoint *nxt)
  206. {
  207. if(cur->flg & 0x01){
  208. if(!(prv->flg & 0x01))
  209. MessageBox(NULL, "off curve bug", TITLE, MB_ICONEXCLAMATION|IDOK);
  210. stroke(di, prv->x, prv->y, cur->x, cur->y);
  211. return 0;
  212. }
  213. if(nxt->flg & 0x01){
  214. bezier(di, prv->x, prv->y, cur->x, cur->y, nxt->x, nxt->y);
  215. *prv = *nxt;
  216. return !0;
  217. }else{
  218. int mx = (cur->x + nxt->x) / 2, my = (cur->y + nxt->y) / 2;
  219. bezier(di, prv->x, prv->y, cur->x, cur->y, mx, my);
  220. prv->flg = 1, prv->x = mx, prv->y = my;
  221. return !0;
  222. }
  223. }
  224.  
  225. int stroke(DrawInfo *di, int xs, int ys, int xe, int ye)
  226. {
  227. if(di->state == 1){
  228. POINT p;
  229. MoveToEx(di->hdc, scalex(di, xs), scaley(di, ys), &p);
  230. }
  231. LineTo(di->hdc, scalex(di, xe), scaley(di, ye));
  232. return 0;
  233. }
  234.  
  235. int drawStrokes(DrawInfo *di, COLORREF foreground_color, char *str)
  236. {
  237. int ox = di->ox, oy = di->oy;
  238. HPEN hpen = CreatePen(PS_SOLID, 1, foreground_color);
  239. HPEN hopen = (HPEN)SelectObject(di->hdc, hpen);
  240. HBRUSH hbrush = CreateSolidBrush(foreground_color);
  241. HBRUSH hobrush = (HBRUSH)SelectObject(di->hdc, hbrush);
  242. char *p;
  243. for(p = str; *p; ++p){
  244. int w, h;
  245. drawGlyph(di, &w, &h, *p);
  246. if(*p == '\n') di->ox = ox, di->oy -= h + di->spy;
  247. else di->ox += w + di->spx;
  248. }
  249. DeleteObject(SelectObject(di->hdc, hobrush));
  250. DeleteObject(SelectObject(di->hdc, hopen));
  251. return 0;
  252. }
  253.  
  254. int drawCallback(HDC hdc, int szx, int szy, COLORREF transparent_color)
  255. {
  256. DrawInfo di = {hdc, szx, szy, 120, szy - 400, 40, 40, 10, 0};
  257. HPEN hpen = CreatePen(PS_SOLID, 1, transparent_color);
  258. HPEN hopen = (HPEN)SelectObject(hdc, hpen);
  259. HBRUSH hbrush = CreateSolidBrush(transparent_color);
  260. HBRUSH hobrush = (HBRUSH)SelectObject(hdc, hbrush);
  261. Rectangle(hdc, 0, 0, szx, szy);
  262. drawStrokes(&di, RGB(0, 255, 0), "Hello,\nworld!");
  263. DeleteObject(SelectObject(hdc, hobrush));
  264. DeleteObject(SelectObject(hdc, hopen));
  265. return 0;
  266. }
  267.  
  268. int drawTransparent(HDC hdc, int x, int y, int w, int h,
  269. HDC hmdc, int szx, int szy,
  270. COLORREF transparent_color, int (*callback)(HDC, int, int, COLORREF))
  271. {
  272. HDC hndc = CreateCompatibleDC(hmdc);
  273. HBITMAP hnbmp = CreateBitmap(szx, szy, 1, 1, NULL);
  274. HBITMAP honbmp = (HBITMAP)SelectObject(hndc, hnbmp);
  275. HDC hgndc = CreateCompatibleDC(hmdc);
  276. HBITMAP hgnbmp = CreateCompatibleBitmap(hmdc, szx, szy);
  277. HBITMAP hognbmp = (HBITMAP)SelectObject(hgndc, hgnbmp);
  278. HDC hpdc = CreateCompatibleDC(hmdc);
  279. HBITMAP hpbmp = CreateBitmap(szx, szy, 1, 1, NULL);
  280. HBITMAP hopbmp = (HBITMAP)SelectObject(hpdc, hpbmp);
  281. COLORREF hocol = SetBkColor(hmdc, transparent_color);
  282. callback(hmdc, szx, szy, transparent_color);
  283. BitBlt(hndc, 0, 0, szx, szy, hmdc, 0, 0, SRCCOPY);
  284. BitBlt(hgndc, 0, 0, szx, szy, hndc, 0, 0, SRCCOPY);
  285. BitBlt(hpdc, 0, 0, szx, szy, hndc, 0, 0, NOTSRCCOPY);
  286. SetBkColor(hmdc, hocol);
  287. BitBlt(hmdc, 0, 0, szx, szy, hpdc, 0, 0, SRCAND);
  288. BitBlt(hdc, x, y, w, h, hgndc, 0, 0, SRCAND);
  289. BitBlt(hdc, x, y, w, h, hmdc, 0, 0, SRCPAINT);
  290. DeleteObject(SelectObject(hpdc, hopbmp));
  291. DeleteDC(hpdc);
  292. DeleteObject(SelectObject(hgndc, hognbmp));
  293. DeleteDC(hgndc);
  294. DeleteObject(SelectObject(hndc, honbmp));
  295. DeleteDC(hndc);
  296. return 0;
  297. }
  298.  
  299. BOOL versionCheck(DWORD major, DWORD minor, DWORD spmajor)
  300. {
  301. OSVERSIONINFO osvi;
  302. ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
  303. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  304. GetVersionEx(&osvi);
  305. if(osvi.dwMajorVersion > major) return TRUE;
  306. if(osvi.dwMajorVersion < major) return FALSE;
  307. if(osvi.dwMinorVersion > minor) return TRUE;
  308. if(osvi.dwMinorVersion < minor) return FALSE;
  309. if(spmajor && osvi.dwPlatformId == VER_PLATFORM_WIN32_NT){
  310. BOOL spCheck = FALSE;
  311. HKEY hkey;
  312. if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  313. "SYSTEM\\CurrentControlSet\\Control\\Windows",
  314. 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS){
  315. DWORD CSDVersion, sz = sizeof(DWORD);
  316. if(RegQueryValueEx(hkey, "CSDVersion", NULL, NULL,
  317. (BYTE *)&CSDVersion, &sz) == ERROR_SUCCESS)
  318. spCheck = LOWORD(CSDVersion) >= spmajor;
  319. RegCloseKey(hkey);
  320. }
  321. return spCheck;
  322. }
  323. return TRUE;
  324. }
  325.  
  326. int main(int ac, char **av)
  327. {
  328. if(!versionCheck(4, 0, 3)) fprintf(stderr, "error 0");
  329. if(!initGlyph(gflg)) fprintf(stderr, "error 1");
  330. if(!(glyf_len = initGlyph(glyf))) fprintf(stderr, "error 2");
  331. {
  332. HWND hwnd = GetDesktopWindow();
  333. HDC hdc = GetDC(hwnd);
  334. RECT rc;
  335. GetClientRect(hwnd, &rc);
  336. {
  337. int szx = rc.right - rc.left, szy = rc.bottom - rc.top;
  338. HDC hmdc = CreateCompatibleDC(hdc);
  339. HBITMAP hbmp = CreateCompatibleBitmap(hdc, szx, szy);
  340. HBITMAP hobmp = (HBITMAP)SelectObject(hmdc, hbmp);
  341. BitBlt(hmdc, 0, 0, szx, szy, hdc, 0, 0, SRCCOPY); // for Aero
  342. drawTransparent(hdc, 0, 0, szx, szy, hmdc, szx, szy,
  343. RGB(255, 255, 0), drawCallback);
  344. DeleteObject(SelectObject(hmdc, hobmp));
  345. DeleteDC(hmdc);
  346. }
  347. ReleaseDC(hwnd, hdc);
  348. }
  349. return 0;
  350. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty