- Return old code for handling parameters to GetCharacterPlacement (+

fix heap overrun in it). New code did not correctly match the Windows
  behaviour.
- Amend the BiDi algorithm so that many strings will now produce quite
  readable output.
This commit is contained in:
Shachar Shemesh 2002-09-04 18:49:36 +00:00 committed by Alexandre Julliard
parent ca14f24af4
commit 8551a8f3fb

View file

@ -1924,24 +1924,18 @@ GetCharacterPlacementA(HDC hdc, LPCSTR lpString, INT uCount,
memcpy(&resultsW, lpResults, sizeof(resultsW)); memcpy(&resultsW, lpResults, sizeof(resultsW));
lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp); lpStringW = FONT_mbtowc(hdc, lpString, uCount, &uCountW, &font_cp);
if( dwFlags&GCP_REORDER ) if(lpResults->lpOutString)
{ resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*uCountW);
/* If the REORDER flag is not set, this field is ignored anyways */
if(lpResults->lpOutString)
resultsW.lpOutString = HeapAlloc(GetProcessHeap(), 0, uCountW);
else
resultsW.lpOutString = NULL;
}
ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags); ret = GetCharacterPlacementW(hdc, lpStringW, uCountW, nMaxExtent, &resultsW, dwFlags);
if(lpResults->lpOutString) { if(lpResults->lpOutString) {
if(font_cp != CP_SYMBOL) if(font_cp != CP_SYMBOL)
WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW, WideCharToMultiByte(font_cp, 0, resultsW.lpOutString, uCountW,
lpResults->lpOutString, uCount, NULL, NULL ); lpResults->lpOutString, uCount, NULL, NULL );
else else
for(i = 0; i < uCount; i++) for(i = 0; i < uCount; i++)
lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i]; lpResults->lpOutString[i] = (CHAR)resultsW.lpOutString[i];
} }
HeapFree(GetProcessHeap(), 0, lpStringW); HeapFree(GetProcessHeap(), 0, lpStringW);
@ -2002,9 +1996,23 @@ GetCharacterPlacementW(
/* return number of initialized fields */ /* return number of initialized fields */
lpResults->nGlyphs = nSet; lpResults->nGlyphs = nSet;
if(dwFlags==0)
{
/* 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)
for(i=0; i<nSet && lpString[i]!=0; ++i )
lpResults->lpOutString[i]=lpString[i];
if(lpResults->lpOrder)
{
for(i = 0; i < nSet; i++)
lpResults->lpOrder[i] = i;
}
}
if((dwFlags&GCP_REORDER)!=0) if((dwFlags&GCP_REORDER)!=0)
{ {
/* MSDN says lpOutString and lpOrder are ignored if GCP_REORDER not set */
WORD *pwCharType; WORD *pwCharType;
int run_end; int run_end;
/* Keep a static table that translates the C2 types to something meaningful */ /* Keep a static table that translates the C2 types to something meaningful */
@ -2027,7 +2035,10 @@ GetCharacterPlacementW(
/* The complete and correct (at least according to MS) BiDi algorythm is not /* The complete and correct (at least according to MS) BiDi algorythm is not
* yet implemented here. Instead, we just make sure that consecutive runs of * yet implemented here. Instead, we just make sure that consecutive runs of
* the same direction (or neutral) are ordered correctly * the same direction (or neutral) are ordered correctly. We also assign Neutrals
* that are between runs of opposing directions the base (ok, always LTR) dir.
* While this is a LONG way from a BiDi algorithm, it does produce more or less
* readable results.
*/ */
for( i=0; i<uCount; i+=run_end ) for( i=0; i<uCount; i+=run_end )
{ {
@ -2057,6 +2068,14 @@ GetCharacterPlacementW(
} else } else
{ {
/* A RTL run */ /* A RTL run */
/* Since, at this stage, the paragraph context is always LTR,
* remove any neutrals from the end of this run.
*/
if( chardir[pwCharType[i]]!=0 )
while( chardir[pwCharType[i+run_end-1]]==0 )
--run_end;
if(lpResults->lpOutString) if(lpResults->lpOutString)
{ {
int j; int j;