/src/os/windows/ftk_font_win32.c

http://ftk.googlecode.com/ · C · 185 lines · 156 code · 29 blank · 0 comment · 27 complexity · 0ee8cefd3d432dcca74630c19c22156f MD5 · raw file

  1. #include "ftk_log.h"
  2. #include "ftk_util.h"
  3. #include "ftk_font_win32.h"
  4. typedef struct _PrivInfo
  5. {
  6. HDC hdc;
  7. HFONT hfont;
  8. HFONT old_hfont;
  9. int data_size;
  10. char* buf;
  11. char* data;
  12. int size;
  13. char* filename;
  14. }PrivInfo;
  15. static Ret ftk_font_win32_load(FtkFont* thiz, const char* filename, int bold, int italic, size_t size)
  16. {
  17. LOGFONT lf;
  18. DECL_PRIV(thiz, priv);
  19. ftk_logd("%s: win32 font: %s\n", __func__, filename);
  20. priv->hdc = CreateCompatibleDC(NULL);
  21. if (priv->hdc == NULL) {
  22. ftk_loge("%s: CreateCompatibleDC() failed\n", __func__);
  23. return RET_FAIL;
  24. }
  25. SetMapperFlags(priv->hdc, 0);
  26. SetMapMode(priv->hdc, MM_TEXT);
  27. memset(&lf, 0, sizeof(LOGFONT));
  28. lf.lfCharSet = DEFAULT_CHARSET;
  29. lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  30. lf.lfOutPrecision = OUT_OUTLINE_PRECIS;
  31. lf.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
  32. lf.lfQuality = PROOF_QUALITY;
  33. lf.lfItalic = (BYTE) (italic ? TRUE:FALSE);
  34. lf.lfWeight = bold ? FW_BOLD:FW_NORMAL;
  35. lf.lfWidth = size;
  36. lf.lfHeight = size;
  37. strcpy(lf.lfFaceName, "??");
  38. priv->hfont = CreateFontIndirect(&lf);
  39. if (priv->hfont == NULL) {
  40. ftk_loge("%s: CreateFontIndirect() failed\n", __func__);
  41. DeleteDC(priv->hdc);
  42. return RET_FAIL;
  43. }
  44. priv->old_hfont = SelectObject(priv->hdc, priv->hfont);
  45. if (priv->old_hfont == NULL) {
  46. ftk_loge("%s: SelectObject() failed\n", __func__);
  47. DeleteObject(priv->hfont);
  48. DeleteDC(priv->hdc);
  49. return RET_FAIL;
  50. }
  51. return RET_OK;
  52. }
  53. static int ftk_font_win32_height(FtkFont* thiz)
  54. {
  55. DECL_PRIV(thiz, priv);
  56. return priv->size;
  57. }
  58. static Ret ftk_font_win32_lookup (FtkFont* thiz, unsigned short code, FtkGlyph* glyph)
  59. {
  60. int i, j, k, n;
  61. char unicode[8], ansi[8];
  62. unsigned int c;
  63. MAT2 mat = {{0,1}, {0,0}, {0,0}, {0,1}};
  64. GLYPHMETRICS gm;
  65. DECL_PRIV(thiz, priv);
  66. memset(unicode, 0, sizeof(unicode));
  67. memcpy(unicode, &code, sizeof(code));
  68. memset(ansi, 0, sizeof(ansi));
  69. if (WideCharToMultiByte(CP_ACP, 0, (LPCWSTR) unicode, -1, (LPSTR) ansi, sizeof(ansi), NULL, NULL) == 0) {
  70. ftk_loge("%s: WideCharToMultiByte() failed\n", __func__);
  71. return RET_FAIL;
  72. }
  73. c = 0;
  74. if (ansi[1] != '\0') {
  75. *((char *) &c) = ansi[1];
  76. *(((char *) &c) + 1) = ansi[0];
  77. } else {
  78. *((char *) &c) = ansi[0];
  79. }
  80. if (GetGlyphOutline(priv->hdc, c, GGO_BITMAP, &gm, priv->data_size, priv->buf, &mat) == GDI_ERROR) {
  81. ftk_loge("%s: GetGlyphOutline() failed\n", __func__);
  82. return RET_FAIL;
  83. }
  84. #if 0
  85. ftk_logd("GetGlyphOutline: %s %d %d %d %d %d %d\n", ansi, gm.gmBlackBoxX, gm.gmBlackBoxY, gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y, gm.gmCellIncX, gm.gmCellIncY);
  86. #endif
  87. n = ((gm.gmBlackBoxX + 31) >> 5) << 2;
  88. for (i = 0; i < (int) gm.gmBlackBoxY; i++) {
  89. for (j = 0; j < n; j++) {
  90. unsigned char c = priv->buf[i * n + j];
  91. for (k = 0; k < 8; k++) {
  92. if (c & (0x80 >> k)) {
  93. priv->data[i * n * 8 + j * 8 + k] = 0xFF;
  94. } else {
  95. priv->data[i * n * 8 + j * 8 + k] = 0;
  96. }
  97. }
  98. }
  99. }
  100. if (gm.gmCellIncX > priv->size) {
  101. glyph->x = (gm.gmBlackBoxX - gm.gmCellIncX) - 10;
  102. } else {
  103. glyph->x = -(gm.gmBlackBoxX + gm.gmCellIncX);
  104. }
  105. glyph->y = (char) gm.gmptGlyphOrigin.y;
  106. glyph->w = n * 8;
  107. glyph->h = gm.gmBlackBoxY;
  108. glyph->data = priv->data;
  109. glyph->code = code;
  110. return RET_OK;
  111. }
  112. void ftk_font_win32_destroy(FtkFont* thiz)
  113. {
  114. if(thiz != NULL)
  115. {
  116. DECL_PRIV(thiz, priv);
  117. FTK_FREE(priv->filename);
  118. FTK_FREE(priv->buf);
  119. FTK_FREE(priv->data);
  120. SelectObject(priv->hdc, priv->old_hfont);
  121. DeleteObject(priv->hfont);
  122. DeleteDC(priv->hdc);
  123. FTK_ZFREE(thiz, sizeof(FtkFont) + sizeof(PrivInfo));
  124. }
  125. return;
  126. }
  127. FtkFont* ftk_font_create(const char* filename, FtkFontDesc* font_desc)
  128. {
  129. FtkFont* thiz = NULL;
  130. int size = ftk_font_desc_get_size(font_desc);
  131. int bold = ftk_font_desc_is_bold(font_desc);
  132. int italic = ftk_font_desc_is_italic(font_desc);
  133. return_val_if_fail(filename != NULL, NULL);
  134. size = 12;
  135. thiz = FTK_ZALLOC(sizeof(FtkFont) + sizeof(PrivInfo));
  136. if(thiz != NULL)
  137. {
  138. DECL_PRIV(thiz, priv);
  139. thiz->height = ftk_font_win32_height;
  140. thiz->lookup = ftk_font_win32_lookup;
  141. thiz->destroy= ftk_font_win32_destroy;
  142. if(ftk_font_win32_load(thiz, filename, bold, italic, size) != RET_OK)
  143. {
  144. FTK_ZFREE(thiz, sizeof(FtkFont) + sizeof(PrivInfo));
  145. }
  146. else
  147. {
  148. priv->size = size;
  149. priv->filename = FTK_STRDUP(filename);
  150. priv->data_size = 128 * 128;
  151. priv->buf = FTK_ALLOC(priv->data_size);
  152. priv->data = FTK_ALLOC(priv->data_size);
  153. }
  154. }
  155. return thiz;
  156. }