mirror of
https://github.com/reactos/reactos.git
synced 2026-06-09 17:33:50 +08:00
[NTGDI][FREETYPE][SDK] Rewrite NtGdiGetCharABCWidthsW (#8704)
Refactor and improve readability. JIRA issue: CORE-20505 - Add GreGetCharABCWidthsW helper function. - Rewrite NtGdiGetCharABCWidthsW by using GreGetCharABCWidthsW.
This commit is contained in:
committed by
GitHub
parent
4b75ec5508
commit
e6328fbf1e
@@ -1678,7 +1678,7 @@ APIENTRY
|
||||
NtGdiGetCharABCWidthsW(
|
||||
_In_ HDC hdc,
|
||||
_In_ UINT wchFirst,
|
||||
_In_ ULONG cwch,
|
||||
_In_ UINT cwch,
|
||||
_In_reads_opt_(cwch) PCWCH pwch,
|
||||
_In_ FLONG fl,
|
||||
_Out_writes_bytes_(cwch * sizeof(ABC)) PVOID pvBuf);
|
||||
|
||||
@@ -1370,3 +1370,64 @@ Cleanup:
|
||||
ExFreePoolWithTag(pSafePwc, GDITAG_TEXT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This function is called from GetCharABCWidthsA/W/I and GetCharABCWidthsFloatA/W. */
|
||||
BOOL NTAPI
|
||||
NtGdiGetCharABCWidthsW(
|
||||
_In_ HDC hDC,
|
||||
_In_ UINT FirstChar,
|
||||
_In_ UINT Count,
|
||||
_In_reads_opt_(Count) PCWCH UnSafepwch,
|
||||
_In_ FLONG fl,
|
||||
_Out_writes_bytes_(Count * sizeof(ABC)) PVOID Buffer)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
PVOID SafeBuff = NULL;
|
||||
PWCHAR Safepwch = NULL;
|
||||
ULONG cbABCs;
|
||||
NTSTATUS Status;
|
||||
WCHAR Stackpwch[28];
|
||||
ABC StackABCs[28];
|
||||
|
||||
if (!Buffer || (UnSafepwch && !Count) || Count > MAX_TEXT_BUFFER / sizeof(ABC))
|
||||
return FALSE;
|
||||
|
||||
if (UnSafepwch)
|
||||
{
|
||||
UINT pwchSize = Count * sizeof(WCHAR);
|
||||
if (Count <= _countof(Stackpwch))
|
||||
Safepwch = Stackpwch;
|
||||
else
|
||||
Safepwch = ExAllocatePoolWithTag(PagedPool, pwchSize, GDITAG_TEXT);
|
||||
|
||||
if (!Safepwch)
|
||||
return FALSE;
|
||||
|
||||
Status = MmCopyFromCaller(Safepwch, UnSafepwch, pwchSize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
cbABCs = Count * sizeof(ABC);
|
||||
if (Count <= _countof(StackABCs))
|
||||
SafeBuff = StackABCs;
|
||||
else
|
||||
SafeBuff = ExAllocatePoolWithTag(PagedPool, cbABCs, GDITAG_TEXT);
|
||||
|
||||
if (!SafeBuff)
|
||||
goto Cleanup;
|
||||
|
||||
ret = GreGetCharABCWidthsW(hDC, FirstChar, Count, Safepwch, fl, SafeBuff);
|
||||
if (ret)
|
||||
{
|
||||
Status = MmCopyToCaller(Buffer, SafeBuff, cbABCs);
|
||||
ret = NT_SUCCESS(Status);
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
if (SafeBuff && SafeBuff != StackABCs)
|
||||
ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
|
||||
if (Safepwch && Safepwch != Stackpwch)
|
||||
ExFreePoolWithTag(Safepwch, GDITAG_TEXT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -7449,95 +7449,68 @@ cleanup:
|
||||
return Result;
|
||||
}
|
||||
|
||||
static BOOL FASTCALL IntSelectFaceCharmap(FT_Face face)
|
||||
{
|
||||
if (face->charmap)
|
||||
return TRUE;
|
||||
|
||||
FT_CharMap charmap, found = NULL;
|
||||
for (UINT i = 0; i < (UINT)face->num_charmaps; i++)
|
||||
{
|
||||
charmap = face->charmaps[i];
|
||||
if (charmap->encoding != 0)
|
||||
{
|
||||
found = charmap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found && FT_IS_SFNT(face)) // Not found and (TrueType or OpenType)?
|
||||
{
|
||||
DPRINT1("WARNING: Could not find desired charmap!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
IntLockFreeType();
|
||||
FT_Set_Charmap(face, found);
|
||||
IntUnLockFreeType();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
APIENTRY
|
||||
NtGdiGetCharABCWidthsW(
|
||||
* @implemented
|
||||
*/
|
||||
BOOL APIENTRY
|
||||
GreGetCharABCWidthsW(
|
||||
_In_ HDC hDC,
|
||||
_In_ UINT FirstChar,
|
||||
_In_ ULONG Count,
|
||||
_In_reads_opt_(Count) PCWCH UnSafepwch,
|
||||
_In_ UINT Count,
|
||||
_In_reads_opt_(Count) PCWCH Safepwch,
|
||||
_In_ FLONG fl,
|
||||
_Out_writes_bytes_(Count * sizeof(ABC)) PVOID Buffer)
|
||||
_Out_writes_bytes_(Count * sizeof(ABC)) PVOID SafeBuffer)
|
||||
{
|
||||
LPABC SafeBuff;
|
||||
LPABCFLOAT SafeBuffF = NULL;
|
||||
PABC SafeBuffI;
|
||||
PABCFLOAT SafeBuffF;
|
||||
PDC dc;
|
||||
PDC_ATTR pdcattr;
|
||||
PTEXTOBJ TextObj;
|
||||
PFONTGDI FontGDI;
|
||||
FT_Face face;
|
||||
FT_CharMap charmap, found = NULL;
|
||||
UINT i, glyph_index, BufferSize;
|
||||
HFONT hFont = 0;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PWCHAR Safepwch = NULL;
|
||||
LOGFONTW *plf;
|
||||
|
||||
if (!Buffer)
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (UnSafepwch)
|
||||
{
|
||||
UINT pwchSize = Count * sizeof(WCHAR);
|
||||
Safepwch = ExAllocatePoolWithTag(PagedPool, pwchSize, GDITAG_TEXT);
|
||||
|
||||
if(!Safepwch)
|
||||
{
|
||||
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForRead(UnSafepwch, pwchSize, 1);
|
||||
RtlCopyMemory(Safepwch, UnSafepwch, pwchSize);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if(Safepwch)
|
||||
ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
|
||||
|
||||
SetLastNtError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BufferSize = Count * sizeof(ABC); // Same size!
|
||||
SafeBuff = ExAllocatePoolWithTag(PagedPool, BufferSize, GDITAG_TEXT);
|
||||
if (!fl) SafeBuffF = (LPABCFLOAT) SafeBuff;
|
||||
if (SafeBuff == NULL)
|
||||
{
|
||||
if(Safepwch)
|
||||
ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
|
||||
|
||||
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
UINT i, glyph_index;
|
||||
HFONT hFont = NULL;
|
||||
PLOGFONTW plf;
|
||||
|
||||
dc = DC_LockDc(hDC);
|
||||
if (dc == NULL)
|
||||
{
|
||||
ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
|
||||
|
||||
if(Safepwch)
|
||||
ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
|
||||
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pdcattr = dc->pdcattr;
|
||||
hFont = pdcattr->hlfntNew;
|
||||
TextObj = RealizeFontInit(hFont);
|
||||
@@ -7546,11 +7519,6 @@ NtGdiGetCharABCWidthsW(
|
||||
|
||||
if (TextObj == NULL)
|
||||
{
|
||||
ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
|
||||
|
||||
if(Safepwch)
|
||||
ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
|
||||
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -7558,33 +7526,11 @@ NtGdiGetCharABCWidthsW(
|
||||
FontGDI = ObjToGDI(TextObj->Font, FONT);
|
||||
|
||||
face = FontGDI->SharedFace->Face;
|
||||
if (face->charmap == NULL)
|
||||
if (!IntSelectFaceCharmap(face))
|
||||
{
|
||||
for (i = 0; i < (UINT)face->num_charmaps; i++)
|
||||
{
|
||||
charmap = face->charmaps[i];
|
||||
if (charmap->encoding != 0)
|
||||
{
|
||||
found = charmap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
DPRINT1("WARNING: Could not find desired charmap!\n");
|
||||
ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
|
||||
|
||||
if(Safepwch)
|
||||
ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
|
||||
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
IntLockFreeType();
|
||||
FT_Set_Charmap(face, found);
|
||||
IntUnLockFreeType();
|
||||
TEXTOBJ_UnlockText(TextObj);
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
|
||||
@@ -7594,18 +7540,20 @@ NtGdiGetCharABCWidthsW(
|
||||
IntRequestFontSize(dc, FontGDI, plf->lfWidth, plf->lfHeight);
|
||||
FT_Set_Transform(face, NULL, NULL);
|
||||
|
||||
if (!fl)
|
||||
SafeBuffF = SafeBuffer;
|
||||
else
|
||||
SafeBuffI = SafeBuffer;
|
||||
|
||||
for (i = FirstChar; i < FirstChar+Count; i++)
|
||||
{
|
||||
int adv, lsb, bbx, left, right;
|
||||
|
||||
if (Safepwch)
|
||||
{
|
||||
glyph_index = get_glyph_index_flagged(face, Safepwch[i - FirstChar], (fl & GCABCW_INDICES));
|
||||
}
|
||||
else
|
||||
{
|
||||
glyph_index = get_glyph_index_flagged(face, i, (fl & GCABCW_INDICES));
|
||||
}
|
||||
|
||||
FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
|
||||
|
||||
left = (INT)face->glyph->metrics.horiBearingX & -64;
|
||||
@@ -7628,27 +7576,15 @@ NtGdiGetCharABCWidthsW(
|
||||
}
|
||||
else
|
||||
{
|
||||
SafeBuff[i - FirstChar].abcA = lsb;
|
||||
SafeBuff[i - FirstChar].abcB = bbx;
|
||||
SafeBuff[i - FirstChar].abcC = adv - lsb - bbx;
|
||||
SafeBuffI[i - FirstChar].abcA = lsb;
|
||||
SafeBuffI[i - FirstChar].abcB = bbx;
|
||||
SafeBuffI[i - FirstChar].abcC = adv - lsb - bbx;
|
||||
}
|
||||
}
|
||||
|
||||
IntUnLockFreeType();
|
||||
TEXTOBJ_UnlockText(TextObj);
|
||||
Status = MmCopyToCaller(Buffer, SafeBuff, BufferSize);
|
||||
|
||||
ExFreePoolWithTag(SafeBuff, GDITAG_TEXT);
|
||||
|
||||
if(Safepwch)
|
||||
ExFreePoolWithTag(Safepwch , GDITAG_TEXT);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastNtError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DPRINT("NtGdiGetCharABCWidths Worked!\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -7669,7 +7605,6 @@ GreGetCharWidthW(
|
||||
PTEXTOBJ TextObj;
|
||||
PFONTGDI FontGDI;
|
||||
FT_Face face;
|
||||
FT_CharMap charmap, found = NULL;
|
||||
UINT i, glyph_index;
|
||||
HFONT hFont = 0;
|
||||
LOGFONTW *plf;
|
||||
@@ -7697,33 +7632,11 @@ GreGetCharWidthW(
|
||||
FontGDI = ObjToGDI(TextObj->Font, FONT);
|
||||
|
||||
face = FontGDI->SharedFace->Face;
|
||||
if (face->charmap == NULL)
|
||||
if (!IntSelectFaceCharmap(face))
|
||||
{
|
||||
// FIXME: Select better charmap
|
||||
for (i = 0; i < (UINT)face->num_charmaps; i++)
|
||||
{
|
||||
charmap = face->charmaps[i];
|
||||
if (charmap->encoding != 0)
|
||||
{
|
||||
found = charmap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found && FT_IS_SFNT(face)) // Not found and (TrueType or OpenType)?
|
||||
{
|
||||
DPRINT1("WARNING: Could not find desired charmap!\n");
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
TEXTOBJ_UnlockText(TextObj);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
IntLockFreeType();
|
||||
FT_Set_Charmap(face, found);
|
||||
IntUnLockFreeType();
|
||||
}
|
||||
TEXTOBJ_UnlockText(TextObj);
|
||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
plf = &TextObj->logfont.elfEnumLogfontEx.elfLogFont;
|
||||
|
||||
@@ -173,5 +173,14 @@ GreGetCharWidthW(
|
||||
_In_ UINT FirstChar,
|
||||
_In_ UINT Count,
|
||||
_In_reads_opt_(Count) PCWCH Safepwc,
|
||||
_In_ ULONG fl,
|
||||
_In_ FLONG fl,
|
||||
_Out_writes_bytes_(Count * sizeof(INT)) PVOID pTmpBuffer);
|
||||
|
||||
BOOL APIENTRY
|
||||
GreGetCharABCWidthsW(
|
||||
_In_ HDC hDC,
|
||||
_In_ UINT FirstChar,
|
||||
_In_ UINT Count,
|
||||
_In_reads_opt_(Count) PCWCH Safepwch,
|
||||
_In_ FLONG fl,
|
||||
_Out_writes_bytes_(Count * sizeof(ABC)) PVOID SafeBuffer);
|
||||
|
||||
Reference in New Issue
Block a user