/*
|
/*
|
* Copyright (c) 2000 Greg Haerr <greg@censoft.com>
|
* Copyright (c) 2000 Greg Haerr <greg@censoft.com>
|
* GetTextExtent*Point by Roman Guseynov
|
* GetTextExtent*Point by Roman Guseynov
|
* Original contributions by Shane Nay
|
* Original contributions by Shane Nay
|
*
|
*
|
* Win32 API upper level font selection routines
|
* Win32 API upper level font selection routines
|
*/
|
*/
|
#include "windows.h"
|
#include "windows.h"
|
#include "wintern.h"
|
#include "wintern.h"
|
#include "device.h"
|
#include "device.h"
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <string.h>
|
|
|
HFONT WINAPI
|
HFONT WINAPI
|
CreateFont(int nHeight, int nWidth, int nEscapement, int nOrientation,
|
CreateFont(int nHeight, int nWidth, int nEscapement, int nOrientation,
|
int fnWeight, DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut,
|
int fnWeight, DWORD fdwItalic, DWORD fdwUnderline, DWORD fdwStrikeOut,
|
DWORD fdwCharSet,DWORD fdwOutputPrecision,DWORD fdwClipPrecision,
|
DWORD fdwCharSet,DWORD fdwOutputPrecision,DWORD fdwClipPrecision,
|
DWORD fdwQuality, DWORD fdwPitchAndFamily, LPCSTR lpszFace)
|
DWORD fdwQuality, DWORD fdwPitchAndFamily, LPCSTR lpszFace)
|
{
|
{
|
LOGFONT lf;
|
LOGFONT lf;
|
|
|
lf.lfHeight = nHeight;
|
lf.lfHeight = nHeight;
|
lf.lfWidth = nWidth;
|
lf.lfWidth = nWidth;
|
lf.lfEscapement = nEscapement;
|
lf.lfEscapement = nEscapement;
|
lf.lfOrientation = nOrientation;
|
lf.lfOrientation = nOrientation;
|
lf.lfWeight = fnWeight;
|
lf.lfWeight = fnWeight;
|
lf.lfItalic = fdwItalic;
|
lf.lfItalic = fdwItalic;
|
lf.lfUnderline = fdwUnderline;
|
lf.lfUnderline = fdwUnderline;
|
lf.lfStrikeOut = fdwStrikeOut;
|
lf.lfStrikeOut = fdwStrikeOut;
|
lf.lfCharSet = fdwCharSet;
|
lf.lfCharSet = fdwCharSet;
|
lf.lfOutPrecision = fdwOutputPrecision;
|
lf.lfOutPrecision = fdwOutputPrecision;
|
lf.lfClipPrecision = fdwClipPrecision;
|
lf.lfClipPrecision = fdwClipPrecision;
|
lf.lfQuality = fdwQuality;
|
lf.lfQuality = fdwQuality;
|
lf.lfPitchAndFamily = fdwPitchAndFamily;
|
lf.lfPitchAndFamily = fdwPitchAndFamily;
|
strncpy(lf.lfFaceName, lpszFace, sizeof(lf.lfFaceName));
|
strncpy(lf.lfFaceName, lpszFace, sizeof(lf.lfFaceName));
|
|
|
return CreateFontIndirect(&lf);
|
return CreateFontIndirect(&lf);
|
}
|
}
|
|
|
HFONT WINAPI
|
HFONT WINAPI
|
CreateFontIndirect(CONST LOGFONT *lplf)
|
CreateFontIndirect(CONST LOGFONT *lplf)
|
{
|
{
|
MWFONTOBJ * hfont;
|
MWFONTOBJ * hfont;
|
int family, pitch;
|
int family, pitch;
|
MWLOGFONT mwlf;
|
MWLOGFONT mwlf;
|
char szFacename[32];
|
char szFacename[32];
|
|
|
/* create a gdi font object*/
|
/* create a gdi font object*/
|
hfont = GdItemNew(MWFONTOBJ);
|
hfont = GdItemNew(MWFONTOBJ);
|
if(!hfont)
|
if(!hfont)
|
return NULL;
|
return NULL;
|
hfont->hdr.type = OBJ_FONT;
|
hfont->hdr.type = OBJ_FONT;
|
hfont->hdr.stockobj = FALSE;
|
hfont->hdr.stockobj = FALSE;
|
|
|
/* convert LOGFONT to MWLOGFONT*/
|
/* convert LOGFONT to MWLOGFONT*/
|
memset(&mwlf, 0, sizeof(mwlf));
|
memset(&mwlf, 0, sizeof(mwlf));
|
mwlf.lfHeight = lplf->lfHeight;
|
mwlf.lfHeight = lplf->lfHeight;
|
mwlf.lfWidth = lplf->lfWidth;
|
mwlf.lfWidth = lplf->lfWidth;
|
mwlf.lfEscapement = lplf->lfEscapement;
|
mwlf.lfEscapement = lplf->lfEscapement;
|
mwlf.lfOrientation = lplf->lfOrientation;
|
mwlf.lfOrientation = lplf->lfOrientation;
|
mwlf.lfWeight = lplf->lfWeight;
|
mwlf.lfWeight = lplf->lfWeight;
|
mwlf.lfItalic = lplf->lfItalic;
|
mwlf.lfItalic = lplf->lfItalic;
|
mwlf.lfUnderline = lplf->lfUnderline;
|
mwlf.lfUnderline = lplf->lfUnderline;
|
mwlf.lfStrikeOut = lplf->lfStrikeOut;
|
mwlf.lfStrikeOut = lplf->lfStrikeOut;
|
mwlf.lfCharSet = lplf->lfCharSet;
|
mwlf.lfCharSet = lplf->lfCharSet;
|
mwlf.lfOutPrecision = lplf->lfOutPrecision;
|
mwlf.lfOutPrecision = lplf->lfOutPrecision;
|
mwlf.lfClipPrecision = lplf->lfClipPrecision;
|
mwlf.lfClipPrecision = lplf->lfClipPrecision;
|
mwlf.lfQuality = lplf->lfQuality;
|
mwlf.lfQuality = lplf->lfQuality;
|
strncpy(mwlf.lfFaceName, lplf->lfFaceName, sizeof(mwlf.lfFaceName));
|
strncpy(mwlf.lfFaceName, lplf->lfFaceName, sizeof(mwlf.lfFaceName));
|
|
|
family = lplf->lfPitchAndFamily & 0xf0;
|
family = lplf->lfPitchAndFamily & 0xf0;
|
switch(family) {
|
switch(family) {
|
case FF_DONTCARE:
|
case FF_DONTCARE:
|
break;
|
break;
|
case FF_ROMAN:
|
case FF_ROMAN:
|
mwlf.lfRoman = 1;
|
mwlf.lfRoman = 1;
|
mwlf.lfSerif = 1;
|
mwlf.lfSerif = 1;
|
break;
|
break;
|
case FF_SWISS:
|
case FF_SWISS:
|
mwlf.lfSansSerif = 1;
|
mwlf.lfSansSerif = 1;
|
break;
|
break;
|
case FF_MODERN:
|
case FF_MODERN:
|
mwlf.lfModern = 1;
|
mwlf.lfModern = 1;
|
break;
|
break;
|
}
|
}
|
|
|
pitch = lplf->lfPitchAndFamily & 0x0f;
|
pitch = lplf->lfPitchAndFamily & 0x0f;
|
switch(pitch) {
|
switch(pitch) {
|
case DEFAULT_PITCH:
|
case DEFAULT_PITCH:
|
break;
|
break;
|
case FIXED_PITCH:
|
case FIXED_PITCH:
|
case MONO_FONT:
|
case MONO_FONT:
|
mwlf.lfMonospace = 1;
|
mwlf.lfMonospace = 1;
|
break;
|
break;
|
case VARIABLE_PITCH:
|
case VARIABLE_PITCH:
|
mwlf.lfProportional = 1;
|
mwlf.lfProportional = 1;
|
break;
|
break;
|
}
|
}
|
/*mwlf.lfOblique = 0;*/
|
/*mwlf.lfOblique = 0;*/
|
/*mwlf.lfSmallCaps = 0;*/
|
/*mwlf.lfSmallCaps = 0;*/
|
/*mwlf.lfPitch = 0;*/
|
/*mwlf.lfPitch = 0;*/
|
|
|
/* select a font based on facename, bold/italic and height*/
|
/* select a font based on facename, bold/italic and height*/
|
strncpy(szFacename, lplf->lfFaceName, sizeof(szFacename));
|
strncpy(szFacename, lplf->lfFaceName, sizeof(szFacename));
|
if (lplf->lfWeight==FW_BOLD)
|
if (lplf->lfWeight==FW_BOLD)
|
strcat(szFacename, "B");
|
strcat(szFacename, "B");
|
if (lplf->lfItalic)
|
if (lplf->lfItalic)
|
strcat(szFacename, "I");
|
strcat(szFacename, "I");
|
hfont->pfont = GdCreateFont(&scrdev, szFacename, lplf->lfHeight, &mwlf);
|
hfont->pfont = GdCreateFont(&scrdev, szFacename, lplf->lfHeight, &mwlf);
|
|
|
return (HFONT)hfont;
|
return (HFONT)hfont;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
GetTextMetrics(HDC hdc, LPTEXTMETRIC lptm)
|
GetTextMetrics(HDC hdc, LPTEXTMETRIC lptm)
|
{
|
{
|
MWFONTINFO fi;
|
MWFONTINFO fi;
|
|
|
if(!hdc)
|
if(!hdc)
|
return FALSE;
|
return FALSE;
|
|
|
GdGetFontInfo(hdc->font->pfont, &fi);
|
GdGetFontInfo(hdc->font->pfont, &fi);
|
|
|
/* FIXME many items are guessed for the time being*/
|
/* FIXME many items are guessed for the time being*/
|
lptm->tmHeight = fi.height;
|
lptm->tmHeight = fi.height;
|
|
|
/* reversed for kaffe port
|
/* reversed for kaffe port
|
lptm->tmAscent = fi.height - fi.baseline;
|
lptm->tmAscent = fi.height - fi.baseline;
|
lptm->tmDescent= fi.baseline;
|
lptm->tmDescent= fi.baseline;
|
*/
|
*/
|
|
|
lptm->tmDescent = fi.height - fi.baseline;
|
lptm->tmDescent = fi.height - fi.baseline;
|
lptm->tmAscent= fi.baseline;
|
lptm->tmAscent= fi.baseline;
|
lptm->tmInternalLeading = 0;
|
lptm->tmInternalLeading = 0;
|
lptm->tmExternalLeading = 0;
|
lptm->tmExternalLeading = 0;
|
lptm->tmAveCharWidth = fi.widths['x'];
|
lptm->tmAveCharWidth = fi.widths['x'];
|
lptm->tmMaxCharWidth = fi.maxwidth;
|
lptm->tmMaxCharWidth = fi.maxwidth;
|
lptm->tmWeight = FW_NORMAL;
|
lptm->tmWeight = FW_NORMAL;
|
lptm->tmOverhang = 0;
|
lptm->tmOverhang = 0;
|
lptm->tmDigitizedAspectX = fi.maxwidth;
|
lptm->tmDigitizedAspectX = fi.maxwidth;
|
lptm->tmDigitizedAspectY = fi.height;
|
lptm->tmDigitizedAspectY = fi.height;
|
lptm->tmFirstChar = 32;
|
lptm->tmFirstChar = 32;
|
lptm->tmLastChar = 255;
|
lptm->tmLastChar = 255;
|
lptm->tmDefaultChar = '?';
|
lptm->tmDefaultChar = '?';
|
lptm->tmBreakChar = 0;
|
lptm->tmBreakChar = 0;
|
lptm->tmItalic = 0;
|
lptm->tmItalic = 0;
|
lptm->tmUnderlined = 0;
|
lptm->tmUnderlined = 0;
|
lptm->tmStruckOut = 0;
|
lptm->tmStruckOut = 0;
|
/* note that win32 has the TMPF_FIXED_PITCH flags REVERSED...*/
|
/* note that win32 has the TMPF_FIXED_PITCH flags REVERSED...*/
|
lptm->tmPitchAndFamily = fi.fixed?
|
lptm->tmPitchAndFamily = fi.fixed?
|
FF_DONTCARE: (FF_DONTCARE | TMPF_FIXED_PITCH);
|
FF_DONTCARE: (FF_DONTCARE | TMPF_FIXED_PITCH);
|
lptm->tmCharSet = OEM_CHARSET;
|
lptm->tmCharSet = OEM_CHARSET;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
GetCharWidth(HDC hdc, UINT iFirstChar, UINT iLastChar, LPINT lpBuffer)
|
GetCharWidth(HDC hdc, UINT iFirstChar, UINT iLastChar, LPINT lpBuffer)
|
{
|
{
|
int i;
|
int i;
|
int j = 0;
|
int j = 0;
|
MWFONTINFO fi;
|
MWFONTINFO fi;
|
|
|
if(!hdc || iLastChar < iFirstChar)
|
if(!hdc || iLastChar < iFirstChar)
|
return FALSE;
|
return FALSE;
|
|
|
GdGetFontInfo(hdc->font->pfont, &fi);
|
GdGetFontInfo(hdc->font->pfont, &fi);
|
for(i=iFirstChar; i <= iLastChar; ++i)
|
for(i=iFirstChar; i <= iLastChar; ++i)
|
if(i < fi.firstchar || i > fi.lastchar || i > 255)
|
if(i < fi.firstchar || i > fi.lastchar || i > 255)
|
lpBuffer[j++] = 0;
|
lpBuffer[j++] = 0;
|
else lpBuffer[j++] = fi.widths[i];
|
else lpBuffer[j++] = fi.widths[i];
|
lpBuffer[j++] = fi.widths[i];
|
lpBuffer[j++] = fi.widths[i];
|
|
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
GetTextExtentPoint(
|
GetTextExtentPoint(
|
HDC hdc, /* handle to DC*/
|
HDC hdc, /* handle to DC*/
|
LPCTSTR lpszStr, /* character string*/
|
LPCTSTR lpszStr, /* character string*/
|
int cchString, /* number of characters*/
|
int cchString, /* number of characters*/
|
LPSIZE lpSize) /* string dimensions*/
|
LPSIZE lpSize) /* string dimensions*/
|
{
|
{
|
int width = 1, height = 1, baseline = 0;
|
int width = 1, height = 1, baseline = 0;
|
|
|
if (lpSize) {
|
if (lpSize) {
|
lpSize->cx = 0;
|
lpSize->cx = 0;
|
lpSize->cy = 0;
|
lpSize->cy = 0;
|
}
|
}
|
if (!hdc || !lpszStr || !cchString || !lpSize)
|
if (!hdc || !lpszStr || !cchString || !lpSize)
|
return FALSE;
|
return FALSE;
|
GdGetTextSize(hdc->font->pfont, lpszStr, cchString, &width, &height,
|
GdGetTextSize(hdc->font->pfont, lpszStr, cchString, &width, &height,
|
&baseline, MWTF_UTF8);
|
&baseline, MWTF_UTF8);
|
lpSize->cx = width;
|
lpSize->cx = width;
|
lpSize->cy = height;
|
lpSize->cy = height;
|
|
|
/*printf("<MWIN>: lpszStr=\"%s\", cchString=%d, lpsize->cx=%d, lpSize->cy=%d\n", lpszStr, cchString, lpSize->cx, lpSize->cy);*/
|
/*printf("<MWIN>: lpszStr=\"%s\", cchString=%d, lpsize->cx=%d, lpSize->cy=%d\n", lpszStr, cchString, lpSize->cx, lpSize->cy);*/
|
return TRUE;
|
return TRUE;
|
}
|
}
|
|
|
BOOL WINAPI
|
BOOL WINAPI
|
GetTextExtentExPoint(HDC hdc, /* handle to DC*/
|
GetTextExtentExPoint(HDC hdc, /* handle to DC*/
|
LPCTSTR lpszStr, /* character string*/
|
LPCTSTR lpszStr, /* character string*/
|
int cchString, /* number of characters*/
|
int cchString, /* number of characters*/
|
int nMaxExtent, /* maximum width of formatted string*/
|
int nMaxExtent, /* maximum width of formatted string*/
|
LPINT lpnFit, /* maximum number of characters*/
|
LPINT lpnFit, /* maximum number of characters*/
|
LPINT alpDx, /* array of partial string widths*/
|
LPINT alpDx, /* array of partial string widths*/
|
LPSIZE lpSize) /* string dimensions*/
|
LPSIZE lpSize) /* string dimensions*/
|
|
|
{
|
{
|
int attr,width=0,height=0;
|
int attr,width=0,height=0;
|
|
|
if(!hdc || !lpszStr)
|
if(!hdc || !lpszStr)
|
return FALSE;
|
return FALSE;
|
if (cchString<0)
|
if (cchString<0)
|
cchString = strlen((char *)lpszStr);
|
cchString = strlen((char *)lpszStr);
|
attr=hdc->font->pfont->fontattr;
|
attr=hdc->font->pfont->fontattr;
|
if (attr&FS_FREETYPE)
|
if (attr&FS_FREETYPE)
|
{
|
{
|
if (GdGetTextSizeEx(hdc->font->pfont,lpszStr,cchString,
|
if (GdGetTextSizeEx(hdc->font->pfont,lpszStr,cchString,
|
nMaxExtent,lpnFit,alpDx,&width,&height,NULL,MWTF_UTF8))
|
nMaxExtent,lpnFit,alpDx,&width,&height,NULL,MWTF_UTF8))
|
{
|
{
|
lpSize->cx=width;
|
lpSize->cx=width;
|
lpSize->cy=height;
|
lpSize->cy=height;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
return FALSE;
|
return FALSE;
|
}
|
}
|
else
|
else
|
{
|
{
|
SIZE sz;
|
SIZE sz;
|
int i;
|
int i;
|
|
|
if (!GetTextExtentPoint(hdc, lpszStr, cchString, lpSize))
|
if (!GetTextExtentPoint(hdc, lpszStr, cchString, lpSize))
|
return FALSE;
|
return FALSE;
|
if ((!nMaxExtent)||(!lpnFit)||(!alpDx))
|
if ((!nMaxExtent)||(!lpnFit)||(!alpDx))
|
return TRUE;
|
return TRUE;
|
for (i=0; i<cchString; i++) {
|
for (i=0; i<cchString; i++) {
|
if (!GetTextExtentPoint(hdc, lpszStr, i+1, &sz))
|
if (!GetTextExtentPoint(hdc, lpszStr, i+1, &sz))
|
return FALSE;
|
return FALSE;
|
if (sz.cx <= nMaxExtent)
|
if (sz.cx <= nMaxExtent)
|
alpDx[i] = sz.cx;
|
alpDx[i] = sz.cx;
|
else {
|
else {
|
(*lpnFit) = i;
|
(*lpnFit) = i;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
}
|
}
|
(*lpnFit) = cchString;
|
(*lpnFit) = cchString;
|
return TRUE;
|
return TRUE;
|
}
|
}
|
}
|
}
|
|
|