- Implement GetGlyphIndicesA/W with update changes ported from Wine.

- Tested with Abiword 2.4.1. I think the text file did not load the first time, now it does load.


svn path=/trunk/; revision=30212
This commit is contained in:
James Tabor 2007-11-06 07:12:45 +00:00
parent 06ccf45dd1
commit 4be86e70e0
5 changed files with 151 additions and 63 deletions

View file

@ -235,24 +235,6 @@ UpdateICMRegKeyA(
return FALSE; return FALSE;
} }
/*
* @unimplemented
*/
DWORD
STDCALL
GetGlyphIndicesA(
HDC hdc,
LPCSTR lpstr,
int c,
LPWORD pgi,
DWORD fl
)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/* /*
* @implemented * @implemented
*/ */

View file

@ -297,24 +297,6 @@ bMakePathNameW(LPWSTR lpBuffer,LPCWSTR lpFileName,LPWSTR *lpFilePart,DWORD unkno
return 0; return 0;
} }
/*
* @unimplemented
*/
DWORD
STDCALL
GetGlyphIndicesW(
HDC hdc,
LPCWSTR lpstr,
int c,
LPWORD pgi,
DWORD fl
)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/* /*
* @implemented * @implemented
*/ */

View file

@ -90,15 +90,18 @@ static void FONT_TextMetricWToA(const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA )
/*********************************************************************** /***********************************************************************
* FONT_mbtowc * FONT_mbtowc
* *
* Returns a Unicode translation of str. If count is -1 then str is * Returns a Unicode translation of str using the charset of the
* assumed to be '\0' terminated, otherwise it contains the number of * currently selected font in hdc. If count is -1 then str is assumed
* bytes to convert. If plenW is non-NULL, on return it will point to * to be '\0' terminated, otherwise it contains the number of bytes to
* the number of WCHARs that have been written. The caller should free * convert. If plenW is non-NULL, on return it will point to the
* the returned LPWSTR from the process heap itself. * number of WCHARs that have been written. If pCP is non-NULL, on
* return it will point to the codepage used in the conversion. The
* caller should free the returned LPWSTR from the process heap
* itself.
*/ */
static LPWSTR FONT_mbtowc(LPCSTR str, INT count, INT *plenW) static LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP)
{ {
UINT cp = CP_ACP; UINT cp = CP_ACP; // GdiGetCodePage( hdc );
INT lenW; INT lenW;
LPWSTR strW; LPWSTR strW;
@ -108,6 +111,7 @@ static LPWSTR FONT_mbtowc(LPCSTR str, INT count, INT *plenW)
MultiByteToWideChar(cp, 0, str, count, strW, lenW); MultiByteToWideChar(cp, 0, str, count, strW, lenW);
DPRINT1("mapped %s -> %s \n", str, strW); DPRINT1("mapped %s -> %s \n", str, strW);
if(plenW) *plenW = lenW; if(plenW) *plenW = lenW;
if(pCP) *pCP = cp;
return strW; return strW;
} }
@ -458,7 +462,7 @@ DPRINT1("GCW32A iFirstChar %x\n",iFirstChar);
for(i = 0; i < count; i++) for(i = 0; i < count; i++)
str[i] = (BYTE)(iFirstChar + i); str[i] = (BYTE)(iFirstChar + i);
wstr = FONT_mbtowc(str, count, &wlen); wstr = FONT_mbtowc(NULL, str, count, &wlen, NULL);
for(i = 0; i < wlen; i++) for(i = 0; i < wlen; i++)
{ {
@ -570,7 +574,7 @@ GetCharacterPlacementW(
} }
/*if(lpResults->lpGlyphs) /*if(lpResults->lpGlyphs)
GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);*/ NtGdiGetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);*/
if (GetTextExtentPoint32W(hdc, lpString, uCount, &size)) if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
ret = MAKELONG(size.cx, size.cy); ret = MAKELONG(size.cx, size.cy);
@ -632,6 +636,28 @@ DPRINT1("GCABCWFA iFirstChar %x\n",iFirstChar);
return NtGdiGetCharABCWidthsFloat ( hdc, iFirstChar, iLastChar, lpABCF ); return NtGdiGetCharABCWidthsFloat ( hdc, iFirstChar, iLastChar, lpABCF );
} }
/*
* @implemented
*/
DWORD
STDCALL
GetGlyphIndicesA(
HDC hdc,
LPCSTR lpstr,
INT count,
LPWORD pgi,
DWORD flags
)
{
DWORD Ret;
WCHAR *lpstrW;
INT countW;
lpstrW = FONT_mbtowc(hdc, lpstr, count, &countW, NULL);
Ret = NtGdiGetGlyphIndicesW(hdc, lpstrW, countW, pgi, flags);
HeapFree(GetProcessHeap(), 0, lpstrW);
return Ret;
}
/* /*
* @implemented * @implemented
@ -664,7 +690,7 @@ GetGlyphOutlineA(
len = 1; len = 1;
mbchs[0] = (uChar & 0xff); mbchs[0] = (uChar & 0xff);
} }
p = FONT_mbtowc(mbchs, len, NULL); p = FONT_mbtowc(NULL, mbchs, len, NULL, NULL);
c = p[0]; c = p[0];
} else } else
c = uChar; c = uChar;

View file

@ -2391,6 +2391,121 @@ NtGdiGetFontLanguageInfo(HDC hDC)
return 0; return 0;
} }
/*
* @implemented
*/
DWORD
STDCALL
NtGdiGetGlyphIndicesW(
IN HDC hdc,
IN OPTIONAL LPWSTR UnSafepwc,
IN INT cwc,
OUT OPTIONAL LPWORD UnSafepgi,
IN DWORD iMode)
{
PDC dc;
PTEXTOBJ TextObj;
PFONTGDI FontGDI;
HFONT hFont = 0;
NTSTATUS Status = STATUS_SUCCESS;
OUTLINETEXTMETRICW *potm;
INT i;
FT_Face face;
WCHAR DefChar = 0, tmDefaultChar;
PWSTR Buffer = NULL;
ULONG Size;
if ((!UnSafepwc) && (!UnSafepgi)) return cwc;
dc = DC_LockDc(hdc);
if (!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return GDI_ERROR;
}
hFont = dc->Dc_Attr.hlfntNew;
TextObj = TEXTOBJ_LockText(hFont);
DC_UnlockDc(dc);
if (!TextObj)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return GDI_ERROR;
}
FontGDI = ObjToGDI(TextObj->Font, FONT);
TEXTOBJ_UnlockText(TextObj);
Buffer = ExAllocatePoolWithTag(PagedPool, cwc*sizeof(WORD), TAG_GDITEXT);
if (!Buffer)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return GDI_ERROR;
}
Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
potm = ExAllocatePoolWithTag(PagedPool, Size, TAG_GDITEXT);
if (!potm)
{
Status = ERROR_NOT_ENOUGH_MEMORY;
goto ErrorRet;
}
IntGetOutlineTextMetrics(FontGDI, Size, potm);
tmDefaultChar = potm->otmTextMetrics.tmDefaultChar; // May need this.
ExFreePool(potm);
if (iMode & GGI_MARK_NONEXISTING_GLYPHS) DefChar = 0x001f; /* Indicate non existence */
_SEH_TRY
{
ProbeForRead(UnSafepwc,
sizeof(PWSTR),
1);
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if (!NT_SUCCESS(Status)) goto ErrorRet;
IntLockFreeType;
face = FontGDI->face;
for (i = 0; i < cwc; i++)
{
Buffer[i] = FT_Get_Char_Index(face, UnSafepwc[i]);
if (Buffer[i] == 0)
{
if (!DefChar) DefChar = tmDefaultChar;
Buffer[i] = DefChar;
}
}
IntUnLockFreeType;
_SEH_TRY
{
ProbeForWrite(UnSafepgi,
sizeof(WORD),
1);
RtlCopyMemory(UnSafepgi,
Buffer,
cwc*sizeof(WORD));
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
ErrorRet:
ExFreePool(Buffer);
if (NT_SUCCESS(Status)) return cwc;
SetLastWin32Error(Status);
return GDI_ERROR;
}
static static
void void
FTVectorToPOINTFX(FT_Vector *vec, POINTFX *pt) FTVectorToPOINTFX(FT_Vector *vec, POINTFX *pt)

View file

@ -2658,23 +2658,6 @@ NtGdiGetSpoolMessage( DWORD u1,
return 0; return 0;
} }
/*
* @unimplemented
*/
DWORD
STDCALL
NtGdiGetGlyphIndicesW(
IN HDC hdc,
IN OPTIONAL LPWSTR pwc,
IN INT cwc,
OUT OPTIONAL LPWORD pgi,
IN DWORD iMode)
{
UNIMPLEMENTED;
return 0;
}
/* /*
* @unimplemented * @unimplemented
*/ */