From d577d991b97ae2b5ee1af23641bcffc3f83af5b2 Mon Sep 17 00:00:00 2001 From: Pixel Date: Wed, 4 Nov 2009 11:56:41 -0800 Subject: Initial import. Contains the im, cd and iup librairies, and a "working" Makefile for them under linux. --- iup/src/win/iupwin_font.c | 342 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 342 insertions(+) create mode 100755 iup/src/win/iupwin_font.c (limited to 'iup/src/win/iupwin_font.c') diff --git a/iup/src/win/iupwin_font.c b/iup/src/win/iupwin_font.c new file mode 100755 index 0000000..659e2d9 --- /dev/null +++ b/iup/src/win/iupwin_font.c @@ -0,0 +1,342 @@ +/** \file + * \brief Windows Font mapping + * + * See Copyright Notice in "iup.h" + */ + + +#include +#include + +#include + +#include "iup.h" + +#include "iup_str.h" +#include "iup_array.h" +#include "iup_attrib.h" +#include "iup_object.h" +#include "iup_drv.h" +#include "iup_drvfont.h" +#include "iup_assert.h" + +#include "iupwin_drv.h" +#include "iupwin_info.h" + + +typedef struct IwinFont_ +{ + char standardfont[200]; + HFONT hFont; + int charwidth, charheight; +} IwinFont; + +static Iarray* win_fonts = NULL; + +static IwinFont* winFindFont(const char *standardfont) +{ + HFONT hFont; + int height_pixels; + char typeface[50] = ""; + int height = 8; + int is_bold = 0, + is_italic = 0, + is_underline = 0, + is_strikeout = 0; + int res = iupwinGetScreenRes(); + int i, count = iupArrayCount(win_fonts); + const char* mapped_name; + + /* Check if the standardfont already exists in cache */ + IwinFont* fonts = (IwinFont*)iupArrayGetData(win_fonts); + for (i = 0; i < count; i++) + { + if (iupStrEqualNoCase(standardfont, fonts[i].standardfont)) + return &fonts[i]; + } + + /* parse the old format first */ + if (!iupFontParseWin(standardfont, typeface, &height, &is_bold, &is_italic, &is_underline, &is_strikeout)) + { + if (!iupFontParsePango(standardfont, typeface, &height, &is_bold, &is_italic, &is_underline, &is_strikeout)) + return NULL; + } + + mapped_name = iupFontGetWinName(typeface); + if (mapped_name) + strcpy(typeface, mapped_name); + + /* get in pixels */ + if (height < 0) + height_pixels = height; /* already in pixels */ + else + height_pixels = -IUPWIN_PT2PIXEL(height, res); + + if (height_pixels == 0) + return NULL; + + hFont = CreateFont(height_pixels, + 0,0,0, + (is_bold) ? FW_BOLD : FW_NORMAL, + is_italic, + is_underline, + is_strikeout, + DEFAULT_CHARSET,OUT_TT_PRECIS, + CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, + FF_DONTCARE|DEFAULT_PITCH, + typeface); + if (!hFont) + return NULL; + + /* create room in the array */ + fonts = (IwinFont*)iupArrayInc(win_fonts); + + strcpy(fonts[i].standardfont, standardfont); + fonts[i].hFont = hFont; + + { + TEXTMETRIC tm; + HDC hdc = GetDC(NULL); + HFONT oldfont = SelectObject(hdc, hFont); + + GetTextMetrics(hdc, &tm); + + SelectObject(hdc, oldfont); + ReleaseDC(NULL, hdc); + + fonts[i].charwidth = tm.tmAveCharWidth; + fonts[i].charheight = tm.tmHeight; + } + + return &fonts[i]; +} + +static void winFontFromLogFont(LOGFONT* logfont, char * font) +{ + int is_bold = (logfont->lfWeight == FW_NORMAL)? 0: 1; + int is_italic = logfont->lfItalic; + int is_underline = logfont->lfUnderline; + int is_strikeout = logfont->lfStrikeOut; + int height_pixels = logfont->lfHeight; /* negative value */ + int res = iupwinGetScreenRes(); + int height = IUPWIN_PIXEL2PT(-height_pixels, res); /* return in points */ + + sprintf(font, "%s, %s%s%s%s %d", logfont->lfFaceName, + is_bold?"Bold ":"", + is_italic?"Italic ":"", + is_underline?"Underline ":"", + is_strikeout?"Strikeout ":"", + height); +} + +char* iupdrvGetSystemFont(void) +{ + static char systemfont[200] = ""; + NONCLIENTMETRICS ncm; + ncm.cbSize = sizeof(NONCLIENTMETRICS); + if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, FALSE)) + winFontFromLogFont(&ncm.lfMessageFont, systemfont); + else + strcpy(systemfont, "Tahoma, 10"); + return systemfont; +} + +char* iupwinFindHFont(HFONT hFont) +{ + int i, count = iupArrayCount(win_fonts); + + /* Check if the standardfont already exists in cache */ + IwinFont* fonts = (IwinFont*)iupArrayGetData(win_fonts); + for (i = 0; i < count; i++) + { + if (hFont == fonts[i].hFont) + return fonts[i].standardfont; + } + + return NULL; +} + +HFONT iupwinGetHFont(const char* value) +{ + IwinFont* winfont = winFindFont(value); + if (!winfont) + return NULL; + else + return winfont->hFont; +} + +static IwinFont* winFontCreateNativeFont(Ihandle *ih, const char* value) +{ + IwinFont* winfont = winFindFont(value); + if (!winfont) + { + iupERROR1("Failed to create Font: %s", value); + return NULL; + } + + iupAttribSetStr(ih, "_IUP_WINFONT", (char*)winfont); + return winfont; +} + +static IwinFont* winFontGet(Ihandle *ih) +{ + IwinFont* winfont = (IwinFont*)iupAttribGet(ih, "_IUP_WINFONT"); + if (!winfont) + winfont = winFontCreateNativeFont(ih, iupGetFontAttrib(ih)); + return winfont; +} + +char* iupwinGetHFontAttrib(Ihandle *ih) +{ + IwinFont* winfont = winFontGet(ih); + if (!winfont) + return NULL; + else + return (char*)winfont->hFont; +} + +int iupdrvSetStandardFontAttrib(Ihandle* ih, const char* value) +{ + IwinFont* winfont = winFontCreateNativeFont(ih, value); + if (!winfont) + return 1; + + /* If FONT is changed, must update the SIZE attribute */ + iupBaseUpdateSizeFromFont(ih); + + /* FONT attribute must be able to be set before mapping, + so the font is enable for size calculation. */ + if (ih->handle && (ih->iclass->nativetype != IUP_TYPEVOID)) + SendMessage(ih->handle, WM_SETFONT, (WPARAM)winfont->hFont, MAKELPARAM(TRUE,0)); + + return 1; +} + +static HDC winFontGetDC(Ihandle* ih) +{ + if (ih->iclass->nativetype == IUP_TYPEVOID) + return GetDC(NULL); + else + return GetDC(ih->handle); /* handle can be NULL here */ +} + +static void winFontReleaseDC(Ihandle* ih, HDC hdc) +{ + if (ih->iclass->nativetype == IUP_TYPEVOID) + ReleaseDC(NULL, hdc); + else + ReleaseDC(ih->handle, hdc); /* handle can be NULL here */ +} + +void iupdrvFontGetMultiLineStringSize(Ihandle* ih, const char* str, int *w, int *h) +{ + int num_lin, max_w; + + IwinFont* winfont = winFontGet(ih); + if (!winfont) + { + if (w) *w = 0; + if (h) *h = 0; + return; + } + + if (!str) + { + if (w) *w = 0; + if (h) *h = winfont->charheight * 1; + return; + } + + max_w = 0; + num_lin = 1; + if (str[0]) + { + SIZE size; + int len; + const char *nextstr; + const char *curstr = str; + + HDC hdc = winFontGetDC(ih); + HFONT oldhfont = SelectObject(hdc, winfont->hFont); + + do + { + nextstr = iupStrNextLine(curstr, &len); + GetTextExtentPoint32(hdc, curstr, len, &size); + max_w = iupMAX(max_w, size.cx); + + curstr = nextstr; + if (*nextstr) + num_lin++; + } while(*nextstr); + + SelectObject(hdc, oldhfont); + winFontReleaseDC(ih, hdc); + } + + if (w) *w = max_w; + if (h) *h = winfont->charheight*num_lin; +} + +int iupdrvFontGetStringWidth(Ihandle* ih, const char* str) +{ + HDC hdc; + HFONT oldhfont, hFont; + SIZE size; + int len; + char* line_end; + + if (!str || str[0]==0) + return 0; + + hFont = (HFONT)iupwinGetHFontAttrib(ih); + if (!hFont) + return 0; + + hdc = winFontGetDC(ih); + oldhfont = SelectObject(hdc, hFont); + + line_end = strchr(str, '\n'); + if (line_end) + len = line_end-str; + else + len = strlen(str); + + GetTextExtentPoint32(hdc, str, len, &size); + + SelectObject(hdc, oldhfont); + winFontReleaseDC(ih, hdc); + + return size.cx; +} + +void iupdrvFontGetCharSize(Ihandle* ih, int *charwidth, int *charheight) +{ + IwinFont* winfont = winFontGet(ih); + if (!winfont) + { + if (charwidth) *charwidth = 0; + if (charheight) *charheight = 0; + return; + } + + if (charwidth) *charwidth = winfont->charwidth; + if (charheight) *charheight = winfont->charheight; +} + +void iupdrvFontInit(void) +{ + win_fonts = iupArrayCreate(50, sizeof(IwinFont)); +} + +void iupdrvFontFinish(void) +{ + int i, count = iupArrayCount(win_fonts); + IwinFont* fonts = (IwinFont*)iupArrayGetData(win_fonts); + for (i = 0; i < count; i++) + { + DeleteObject(fonts[i].hFont); + fonts[i].hFont = NULL; + } + iupArrayDestroy(win_fonts); +} -- cgit v1.2.3