📄 font.c
字号:
return ret;
}
/*
* @implemented
*/
BOOL
STDCALL
GetCharWidthW (
HDC hdc,
UINT iFirstChar,
UINT iLastChar,
LPINT lpBuffer
)
{
DPRINT1("GCW32w uFirstChar %x\n",iFirstChar);
/* FIXME should be NtGdiGetCharWidthW */
return NtGdiGetCharWidth32 ( hdc, iFirstChar, iLastChar, lpBuffer );
}
/*
* @implemented
*/
DWORD
STDCALL
GetCharacterPlacementW(
HDC hdc,
LPCWSTR lpString,
INT uCount,
INT nMaxExtent,
GCP_RESULTSW *lpResults,
DWORD dwFlags
)
{
DWORD ret=0;
SIZE size;
UINT i, nSet;
if(dwFlags&(~GCP_REORDER)) DPRINT("flags 0x%08lx ignored\n", dwFlags);
if(lpResults->lpClass) DPRINT("classes not implemented\n");
if (lpResults->lpCaretPos && (dwFlags & GCP_REORDER))
DPRINT("Caret positions for complex scripts not implemented\n");
nSet = (UINT)uCount;
if(nSet > lpResults->nGlyphs)
nSet = lpResults->nGlyphs;
/* return number of initialized fields */
lpResults->nGlyphs = nSet;
/*if((dwFlags&GCP_REORDER)==0 || !BidiAvail)
{*/
/* Treat the case where no special handling was requested in a fastpath way */
/* copy will do if the GCP_REORDER flag is not set */
if(lpResults->lpOutString)
lstrcpynW( lpResults->lpOutString, lpString, nSet );
if(lpResults->lpGlyphs)
lstrcpynW( lpResults->lpGlyphs, lpString, nSet );
if(lpResults->lpOrder)
{
for(i = 0; i < nSet; i++)
lpResults->lpOrder[i] = i;
}
/*} else
{
BIDI_Reorder( lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
nSet, lpResults->lpOrder );
}*/
/* FIXME: Will use the placement chars */
if (lpResults->lpDx)
{
int c;
for (i = 0; i < nSet; i++)
{
if (NtGdiGetCharWidth32(hdc, lpString[i], lpString[i], &c))
lpResults->lpDx[i]= c;
}
}
if (lpResults->lpCaretPos && !(dwFlags & GCP_REORDER))
{
int pos = 0;
lpResults->lpCaretPos[0] = 0;
for (i = 1; i < nSet; i++)
if (GetTextExtentPoint32W(hdc, &(lpString[i - 1]), 1, &size))
lpResults->lpCaretPos[i] = (pos += size.cx);
}
/*if(lpResults->lpGlyphs)
GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);*/
if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
ret = MAKELONG(size.cx, size.cy);
return ret;
}
/*
* @unimplemented
*/
BOOL
APIENTRY
GetCharWidthFloatA(
HDC hdc,
UINT iFirstChar,
UINT iLastChar,
PFLOAT pxBuffer
)
{
/* FIXME what to do with iFirstChar and iLastChar ??? */
return NtGdiGetCharWidthFloat ( hdc, iFirstChar, iLastChar, pxBuffer );
}
/*
* @implemented
*/
BOOL
APIENTRY
GetCharABCWidthsA(
HDC hdc,
UINT uFirstChar,
UINT uLastChar,
LPABC lpabc
)
{
DPRINT1("GCABCWA uFirstChar %x\n",uFirstChar);
return NtGdiGetCharABCWidths(hdc, uFirstChar, uLastChar, lpabc);
}
/*
* @unimplemented
*/
BOOL
APIENTRY
GetCharABCWidthsFloatA(
HDC hdc,
UINT iFirstChar,
UINT iLastChar,
LPABCFLOAT lpABCF
)
{
DPRINT1("GCABCWFA iFirstChar %x\n",iFirstChar);
/* FIXME what to do with iFirstChar and iLastChar ??? */
return NtGdiGetCharABCWidthsFloat ( hdc, iFirstChar, iLastChar, lpABCF );
}
/*
* @implemented
*/
DWORD
STDCALL
GetGlyphOutlineA(
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
)
{
TMDIFF Tmd; // Should not be zero.
return NtGdiGetOutlineTextMetricsInternalW(hdc, cbData, lpOTM, &Tmd);
}
/*
* @implemented
*/
HFONT
STDCALL
CreateFontIndirectExA(const ENUMLOGFONTEXDVA *elfexd)
{
if (elfexd)
{
ENUMLOGFONTEXDVW Logfont;
EnumLogFontExW2A( (LPENUMLOGFONTEXA) elfexd,
&Logfont.elfEnumLogfontEx );
RtlCopyMemory( &Logfont.elfDesignVector,
(PVOID) &elfexd->elfDesignVector,
sizeof(DESIGNVECTOR));
return NtGdiHfontCreate( &Logfont, 0, 0, 0, NULL);
}
else return NULL;
}
/*
* @implemented
*/
HFONT
STDCALL
CreateFontIndirectExW(const ENUMLOGFONTEXDVW *elfexd)
{
/* Msdn: Note, this function ignores the elfDesignVector member in
ENUMLOGFONTEXDV.
*/
if ( elfexd )
{
return NtGdiHfontCreate((PENUMLOGFONTEXDVW) elfexd, 0, 0, 0, NULL );
}
else return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -