📄 font.c
字号:
HDC hdc,
UINT uChar,
UINT uFormat,
LPGLYPHMETRICS lpgm,
DWORD cbBuffer,
LPVOID lpvBuffer,
CONST MAT2 *lpmat2
)
{
LPWSTR p = NULL;
DWORD ret;
UINT c;
DPRINT1("GetGlyphOutlineA uChar %x\n", uChar);
if(!(uFormat & GGO_GLYPH_INDEX)) {
int len;
char mbchs[2];
if(uChar > 0xff) { /* but, 2 bytes character only */
len = 2;
mbchs[0] = (uChar & 0xff00) >> 8;
mbchs[1] = (uChar & 0xff);
} else {
len = 1;
mbchs[0] = (uChar & 0xff);
}
p = FONT_mbtowc(mbchs, len, NULL);
c = p[0];
} else
c = uChar;
ret = NtGdiGetGlyphOutline(hdc, c, uFormat, lpgm, cbBuffer, lpvBuffer, (CONST LPMAT2)lpmat2, TRUE);
HeapFree(GetProcessHeap(), 0, p);
return ret;
}
/*
* @implemented
*/
DWORD
STDCALL
GetGlyphOutlineW(
HDC hdc,
UINT uChar,
UINT uFormat,
LPGLYPHMETRICS lpgm,
DWORD cbBuffer,
LPVOID lpvBuffer,
CONST MAT2 *lpmat2
)
{
DPRINT1("GetGlyphOutlineW uChar %x\n", uChar);
return NtGdiGetGlyphOutline ( hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, (CONST LPMAT2)lpmat2, TRUE);
}
/*
* @implemented
*/
UINT
APIENTRY
GetOutlineTextMetricsA(
HDC hdc,
UINT cbData,
LPOUTLINETEXTMETRICA lpOTM
)
{
char buf[512], *ptr;
UINT ret, needed;
OUTLINETEXTMETRICW *lpOTMW = (OUTLINETEXTMETRICW *)buf;
OUTLINETEXTMETRICA *output = lpOTM;
INT left, len;
if((ret = GetOutlineTextMetricsW(hdc, 0, NULL)) == 0)
return 0;
if(ret > sizeof(buf))
lpOTMW = HeapAlloc(GetProcessHeap(), 0, ret);
GetOutlineTextMetricsW(hdc, ret, lpOTMW);
needed = sizeof(OUTLINETEXTMETRICA);
if(lpOTMW->otmpFamilyName)
needed += WideCharToMultiByte(CP_ACP, 0,
(WCHAR*)((char*)lpOTMW + (int)lpOTMW->otmpFamilyName), -1,
NULL, 0, NULL, NULL);
if(lpOTMW->otmpFaceName)
needed += WideCharToMultiByte(CP_ACP, 0,
(WCHAR*)((char*)lpOTMW + (int)lpOTMW->otmpFaceName), -1,
NULL, 0, NULL, NULL);
if(lpOTMW->otmpStyleName)
needed += WideCharToMultiByte(CP_ACP, 0,
(WCHAR*)((char*)lpOTMW + (int)lpOTMW->otmpStyleName), -1,
NULL, 0, NULL, NULL);
if(lpOTMW->otmpFullName)
needed += WideCharToMultiByte(CP_ACP, 0,
(WCHAR*)((char*)lpOTMW + (int)lpOTMW->otmpFullName), -1,
NULL, 0, NULL, NULL);
if(!lpOTM) {
ret = needed;
goto end;
}
DPRINT("needed = %d\n", needed);
if(needed > cbData)
/* Since the supplied buffer isn't big enough, we'll alloc one
that is and memcpy the first cbData bytes into the lpOTM at
the end. */
output = HeapAlloc(GetProcessHeap(), 0, needed);
ret = output->otmSize = min(needed, cbData);
FONT_TextMetricWToA( &lpOTMW->otmTextMetrics, &output->otmTextMetrics );
output->otmFiller = 0;
output->otmPanoseNumber = lpOTMW->otmPanoseNumber;
output->otmfsSelection = lpOTMW->otmfsSelection;
output->otmfsType = lpOTMW->otmfsType;
output->otmsCharSlopeRise = lpOTMW->otmsCharSlopeRise;
output->otmsCharSlopeRun = lpOTMW->otmsCharSlopeRun;
output->otmItalicAngle = lpOTMW->otmItalicAngle;
output->otmEMSquare = lpOTMW->otmEMSquare;
output->otmAscent = lpOTMW->otmAscent;
output->otmDescent = lpOTMW->otmDescent;
output->otmLineGap = lpOTMW->otmLineGap;
output->otmsCapEmHeight = lpOTMW->otmsCapEmHeight;
output->otmsXHeight = lpOTMW->otmsXHeight;
output->otmrcFontBox = lpOTMW->otmrcFontBox;
output->otmMacAscent = lpOTMW->otmMacAscent;
output->otmMacDescent = lpOTMW->otmMacDescent;
output->otmMacLineGap = lpOTMW->otmMacLineGap;
output->otmusMinimumPPEM = lpOTMW->otmusMinimumPPEM;
output->otmptSubscriptSize = lpOTMW->otmptSubscriptSize;
output->otmptSubscriptOffset = lpOTMW->otmptSubscriptOffset;
output->otmptSuperscriptSize = lpOTMW->otmptSuperscriptSize;
output->otmptSuperscriptOffset = lpOTMW->otmptSuperscriptOffset;
output->otmsStrikeoutSize = lpOTMW->otmsStrikeoutSize;
output->otmsStrikeoutPosition = lpOTMW->otmsStrikeoutPosition;
output->otmsUnderscoreSize = lpOTMW->otmsUnderscoreSize;
output->otmsUnderscorePosition = lpOTMW->otmsUnderscorePosition;
ptr = (char*)(output + 1);
left = needed - sizeof(*output);
if(lpOTMW->otmpFamilyName) {
output->otmpFamilyName = (LPSTR)(ptr - (char*)output);
len = WideCharToMultiByte(CP_ACP, 0,
(WCHAR*)((char*)lpOTMW + (int)lpOTMW->otmpFamilyName), -1,
ptr, left, NULL, NULL);
left -= len;
ptr += len;
} else
output->otmpFamilyName = 0;
if(lpOTMW->otmpFaceName) {
output->otmpFaceName = (LPSTR)(ptr - (char*)output);
len = WideCharToMultiByte(CP_ACP, 0,
(WCHAR*)((char*)lpOTMW + (int)lpOTMW->otmpFaceName), -1,
ptr, left, NULL, NULL);
left -= len;
ptr += len;
} else
output->otmpFaceName = 0;
if(lpOTMW->otmpStyleName) {
output->otmpStyleName = (LPSTR)(ptr - (char*)output);
len = WideCharToMultiByte(CP_ACP, 0,
(WCHAR*)((char*)lpOTMW + (int)lpOTMW->otmpStyleName), -1,
ptr, left, NULL, NULL);
left -= len;
ptr += len;
} else
output->otmpStyleName = 0;
if(lpOTMW->otmpFullName) {
output->otmpFullName = (LPSTR)(ptr - (char*)output);
len = WideCharToMultiByte(CP_ACP, 0,
(WCHAR*)((char*)lpOTMW + (int)lpOTMW->otmpFullName), -1,
ptr, left, NULL, NULL);
left -= len;
} else
output->otmpFullName = 0;
assert(left == 0);
if(output != lpOTM) {
memcpy(lpOTM, output, cbData);
HeapFree(GetProcessHeap(), 0, output);
/* check if the string offsets really fit into the provided size */
/* FIXME: should we check string length as well? */
if ((UINT_PTR)lpOTM->otmpFamilyName >= lpOTM->otmSize)
lpOTM->otmpFamilyName = 0; /* doesn't fit */
if ((UINT_PTR)lpOTM->otmpFaceName >= lpOTM->otmSize)
lpOTM->otmpFaceName = 0; /* doesn't fit */
if ((UINT_PTR)lpOTM->otmpStyleName >= lpOTM->otmSize)
lpOTM->otmpStyleName = 0; /* doesn't fit */
if ((UINT_PTR)lpOTM->otmpFullName >= lpOTM->otmSize)
lpOTM->otmpFullName = 0; /* doesn't fit */
}
end:
if(lpOTMW != (OUTLINETEXTMETRICW *)buf)
HeapFree(GetProcessHeap(), 0, lpOTMW);
return ret;
}
/*
* @implemented
*/
UINT
APIENTRY
GetOutlineTextMetricsW(
HDC hdc,
UINT cbData,
LPOUTLINETEXTMETRICW lpOTM
)
{
return NtGdiGetOutlineTextMetrics(hdc, cbData, lpOTM);
}
/*
* @implemented
*/
HFONT
STDCALL
CreateFontIndirectA(
CONST LOGFONTA *lplf
)
{
LOGFONTW tlf;
if (lplf)
{
LogFontA2W(&tlf, lplf);
return NtGdiCreateFontIndirect(&tlf);
}
else return NtGdiCreateFontIndirect(NULL);
}
/*
* @implemented
*/
HFONT
STDCALL
CreateFontIndirectW(
CONST LOGFONTW *lplf
)
{
return NtGdiCreateFontIndirect((CONST LPLOGFONTW)lplf);
}
/*
* @implemented
*/
HFONT
STDCALL
CreateFontA(
int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int fnWeight,
DWORD fdwItalic,
DWORD fdwUnderline,
DWORD fdwStrikeOut,
DWORD fdwCharSet,
DWORD fdwOutputPrecision,
DWORD fdwClipPrecision,
DWORD fdwQuality,
DWORD fdwPitchAndFamily,
LPCSTR lpszFace
)
{
ANSI_STRING StringA;
UNICODE_STRING StringU;
HFONT ret;
RtlInitAnsiString(&StringA, (LPSTR)lpszFace);
RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
ret = CreateFontW(nHeight, nWidth, nEscapement, nOrientation, fnWeight, fdwItalic, fdwUnderline, fdwStrikeOut,
fdwCharSet, fdwOutputPrecision, fdwClipPrecision, fdwQuality, fdwPitchAndFamily, StringU.Buffer);
RtlFreeUnicodeString(&StringU);
return ret;
}
/*
* @implemented
*/
HFONT
STDCALL
CreateFontW(
int nHeight,
int nWidth,
int nEscapement,
int nOrientation,
int nWeight,
DWORD fnItalic,
DWORD fdwUnderline,
DWORD fdwStrikeOut,
DWORD fdwCharSet,
DWORD fdwOutputPrecision,
DWORD fdwClipPrecision,
DWORD fdwQuality,
DWORD fdwPitchAndFamily,
LPCWSTR lpszFace
)
{
return NtGdiCreateFont(nHeight, nWidth, nEscapement, nOrientation, nWeight, fnItalic, fdwUnderline, fdwStrikeOut,
fdwCharSet, fdwOutputPrecision, fdwClipPrecision, fdwQuality, fdwPitchAndFamily, lpszFace);
}
/*
* @implemented
*/
BOOL
STDCALL
CreateScalableFontResourceW(
DWORD fdwHidden,
LPCWSTR lpszFontRes,
LPCWSTR lpszFontFile,
LPCWSTR lpszCurrentPath
)
{
return NtGdiCreateScalableFontResource ( fdwHidden,
lpszFontRes,
lpszFontFile,
lpszCurrentPath );
}
/*
* @implemented
*/
BOOL
STDCALL
CreateScalableFontResourceA(
DWORD fdwHidden,
LPCSTR lpszFontRes,
LPCSTR lpszFontFile,
LPCSTR lpszCurrentPath
)
{
NTSTATUS Status;
LPWSTR lpszFontResW, lpszFontFileW, lpszCurrentPathW;
BOOL rc = FALSE;
Status = HEAP_strdupA2W ( &lpszFontResW, lpszFontRes );
if (!NT_SUCCESS (Status))
SetLastError (RtlNtStatusToDosError(Status));
else
{
Status = HEAP_strdupA2W ( &lpszFontFileW, lpszFontFile );
if (!NT_SUCCESS (Status))
SetLastError (RtlNtStatusToDosError(Status));
else
{
Status = HEAP_strdupA2W ( &lpszCurrentPathW, lpszCurrentPath );
if (!NT_SUCCESS (Status))
SetLastError (RtlNtStatusToDosError(Status));
else
{
rc = NtGdiCreateScalableFontResource ( fdwHidden,
lpszFontResW,
lpszFontFileW,
lpszCurrentPathW );
HEAP_free ( lpszCurrentPathW );
}
HEAP_free ( lpszFontFileW );
}
HEAP_free ( lpszFontResW );
}
return rc;
}
/*
* @implemented
*/
int
STDCALL
AddFontResourceExW ( LPCWSTR lpszFilename, DWORD fl, PVOID pvReserved )
{
UNICODE_STRING Filename;
/* FIXME handle fl parameter */
RtlInitUnicodeString(&Filename, lpszFilename);
return NtGdiAddFontResource ( &Filename, fl );
}
/*
* @implemented
*/
int
STDCALL
AddFontResourceExA ( LPCSTR lpszFilename, DWORD fl, PVOID pvReserved )
{
NTSTATUS Status;
PWSTR FilenameW;
int rc = 0;
Status = HEAP_strdupA2W ( &FilenameW, lpszFilename );
if ( !NT_SUCCESS (Status) )
SetLastError (RtlNtStatusToDosError(Status));
else
{
rc = AddFontResourceExW ( FilenameW, fl, pvReserved );
HEAP_free ( FilenameW );
}
return rc;
}
/*
* @implemented
*/
int
STDCALL
AddFontResourceA ( LPCSTR lpszFilename )
{
return AddFontResourceExA ( lpszFilename, 0, 0 );
}
/*
* @implemented
*/
int
STDCALL
AddFontResourceW ( LPCWSTR lpszFilename )
{
return AddFontResourceExW ( lpszFilename, 0, 0 );
}
/*
* @implemented
*/
BOOL
STDCALL
RemoveFontResourceW(
LPCWSTR lpFileName
)
{
return NtGdiRemoveFontResource ( lpFileName );
}
/*
* @implemented
*/
BOOL
STDCALL
RemoveFontResourceA(
LPCSTR lpFileName
)
{
NTSTATUS Status;
LPWSTR lpFileNameW;
BOOL rc = 0;
Status = HEAP_strdupA2W ( &lpFileNameW, lpFileName );
if (!NT_SUCCESS (Status))
SetLastError (RtlNtStatusToDosError(Status));
else
{
rc = NtGdiRemoveFontResource ( lpFileNameW );
HEAP_free ( lpFileNameW );
}
return rc;
}
/***********************************************************************
* GdiGetCharDimensions
*
* Gets the average width of the characters in the English alphabet.
*
* PARAMS
* hdc [I] Handle to the device context to measure on.
* lptm [O] Pointer to memory to store the text metrics into.
* height [O] On exit, the maximum height of characters in the English alphabet.
*
* RETURNS
* The average width of characters in the English alphabet.
*
* NOTES
* This function is used by the dialog manager to get the size of a dialog
* unit. It should also be used by other pieces of code that need to know
* the size of a dialog unit in logical units without having access to the
* window handle of the dialog.
* Windows caches the font metrics from this function, but we don't and
* there doesn't appear to be an immediate advantage to do so.
*
* SEE ALSO
* GetTextExtentPointW, GetTextMetricsW, MapDialogRect.
*
* Despite most of MSDN insisting that the horizontal base unit is
* tmAveCharWidth it isn't. Knowledge base article Q145994
* "HOWTO: Calculate Dialog Units When Not Using the System Font",
* says that we should take the average of the 52 English upper and lower
* case characters.
*/
/*
* @implemented
*/
DWORD
STDCALL
GdiGetCharDimensions(HDC hdc, LPTEXTMETRICW lptm, LONG *height)
{
SIZE sz;
static const WCHAR alphabet[] = {
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
if(lptm && !GetTextMetricsW(hdc, lptm)) return 0;
if(!GetTextExtentPointW(hdc, alphabet, 52, &sz)) return 0;
if (height) *height = sz.cy;
return (sz.cx / 26 + 1) / 2;
}
/*
* @unimplemented
*/
int
STDCALL
EnumFontsW(
HDC hDC,
LPCWSTR lpFaceName,
FONTENUMPROCW FontFunc,
LPARAM lParam
)
{
#if 0
return NtGdiEnumFonts ( hDC, lpFaceName, FontFunc, lParam );
#else
return EnumFontFamiliesW( hDC, lpFaceName, FontFunc, lParam );
#endif
}
/*
* @unimplemented
*/
int
STDCALL
EnumFontsA (
HDC hDC,
LPCSTR lpFaceName,
FONTENUMPROCA FontFunc,
LPARAM lParam
)
{
#if 0
NTSTATUS Status;
LPWSTR lpFaceNameW;
int rc = 0;
Status = HEAP_strdupA2W ( &lpFaceNameW, lpFaceName );
if (!NT_SUCCESS (Status))
SetLastError (RtlNtStatusToDosError(Status));
else
{
rc = NtGdiEnumFonts ( hDC, lpFaceNameW, FontFunc, lParam );
HEAP_free ( lpFaceNameW );
}
return rc;
#else
return EnumFontFamiliesA( hDC, lpFaceName, FontFunc, lParam );
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -