PageRenderTime 355ms CodeModel.GetById 160ms app.highlight 17ms RepoModel.GetById 175ms app.codeStats 0ms

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