You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
928 lines
28 KiB
928 lines
28 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: nlsconv.c *
|
|
* *
|
|
* DBCS specific routines *
|
|
* *
|
|
* Created: 15-Mar-1994 15:56:30 *
|
|
* Author: Gerrit van Wingerden [gerritv] *
|
|
* *
|
|
* Copyright (c) 1994-1999 Microsoft Corporation *
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
UINT fFontAssocStatus = 0;
|
|
|
|
BYTE cLowTrailByteSet1 = 0xff;
|
|
BYTE cHighTrailByteSet1 = 0x0;
|
|
BYTE cLowTrailByteSet2 = 0xff;
|
|
BYTE cHighTrailByteSet2 = 0x0;
|
|
|
|
/******************************Public*Routine******************************\
|
|
* *
|
|
* DBCS Trailling Byte validate check functions. *
|
|
* *
|
|
\**************************************************************************/
|
|
|
|
|
|
#define IS_DBCS_TRAIL_BYTE(Char) (\
|
|
((Char >= cLowTrailByteSet1) && (Char <= cHighTrailByteSet1)) \
|
|
||((Char >= cLowTrailByteSet2) && (Char <= cHighTrailByteSet2)) \
|
|
)
|
|
|
|
/**************************************************************************\
|
|
* *
|
|
* SHIFT-JIS (Japanese) character set : CodePage 932 *
|
|
* *
|
|
* Valid LeadByte Range | Valid TailByte Range *
|
|
* -----------------------+--------------------- *
|
|
* From -> To | From -> To *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - *
|
|
* 0x81 -> 0x9F | 0x40 -> 0xFC *
|
|
* 0xE0 -> 0xFC | *
|
|
* *
|
|
\**************************************************************************/
|
|
|
|
/**************************************************************************\
|
|
* *
|
|
* WANSANG (Korean) character set : CodePage 949 *
|
|
* *
|
|
* Valid LeadByte Range | Valid TailByte Range *
|
|
* -----------------------+--------------------- *
|
|
* From -> To | From -> To *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - *
|
|
* 0xA1 -> 0xAC | 0x40 -> 0xFC *
|
|
* 0xB0 -> 0xC8 | *
|
|
* 0xCA -> 0xFD | *
|
|
* *
|
|
\**************************************************************************/
|
|
|
|
/**************************************************************************\
|
|
* *
|
|
* GB2312 (PRC Chinese) character set : CodePage 936 *
|
|
* *
|
|
* Valid LeadByte Range | Valid TailByte Range *
|
|
* -----------------------+--------------------- *
|
|
* From -> To | From -> To *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - *
|
|
* 0xA1 -> 0xA9 | 0xA1 -> 0xFE *
|
|
* 0xB0 -> 0xF7 | *
|
|
* *
|
|
\**************************************************************************/
|
|
|
|
/**************************************************************************\
|
|
* *
|
|
* Big 5 (Taiwan,Hong Kong Chinese) character set : CodePage 950 *
|
|
* *
|
|
* Valid LeadByte Range | Valid TailByte Range *
|
|
* -----------------------+--------------------- *
|
|
* From -> To | From -> To *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - *
|
|
* 0x81 -> 0xFE | 0x40 -> 0x7E *
|
|
* | 0xA1 -> 0xFE *
|
|
* *
|
|
\**************************************************************************/
|
|
|
|
/******************************Public*Routine******************************\
|
|
* vSetCheckDBCSTrailByte()
|
|
*
|
|
* This function setup function for the DBCS trailling byte validation of
|
|
* specified character with specified Fareast codepage.
|
|
*
|
|
* Thu-15-Feb-1996 11:59:00 -by- Gerrit van Wingerden
|
|
* Moved function pointer out of CFONT and into a global variable.
|
|
*
|
|
* Wed 20-Dec-1994 10:00:00 -by- Hideyuki Nagase [hideyukn]
|
|
* Write it.
|
|
\**************************************************************************/
|
|
|
|
VOID vSetCheckDBCSTrailByte(DWORD dwCodePage)
|
|
{
|
|
switch( dwCodePage )
|
|
{
|
|
case 932:
|
|
cLowTrailByteSet1 = (CHAR) 0x40;
|
|
cHighTrailByteSet1 = (CHAR) 0xfc;
|
|
cLowTrailByteSet2 = (CHAR) 0x40;
|
|
cHighTrailByteSet2 = (CHAR) 0xfc;
|
|
break;
|
|
|
|
case 949:
|
|
cLowTrailByteSet1 = (CHAR) 0x40;
|
|
cHighTrailByteSet1 = (CHAR) 0xfc;
|
|
cLowTrailByteSet2 = (CHAR) 0x40;
|
|
cHighTrailByteSet2 = (CHAR) 0xfc;
|
|
break;
|
|
|
|
case 936:
|
|
cLowTrailByteSet1 = (CHAR) 0xa1;
|
|
cHighTrailByteSet1 = (CHAR) 0xfe;
|
|
cLowTrailByteSet2 = (CHAR) 0xa1;
|
|
cHighTrailByteSet2 = (CHAR) 0xfe;
|
|
break;
|
|
|
|
case 950:
|
|
cLowTrailByteSet1 = (CHAR) 0x40;
|
|
cHighTrailByteSet1 = (CHAR) 0x7e;
|
|
cLowTrailByteSet2 = (CHAR) 0xa1;
|
|
cHighTrailByteSet2 = (CHAR) 0xfe;
|
|
break;
|
|
|
|
default:
|
|
cLowTrailByteSet1 = (CHAR) 0xff;
|
|
cHighTrailByteSet1 = (CHAR) 0x0;
|
|
cLowTrailByteSet2 = (CHAR) 0xff;
|
|
cHighTrailByteSet2 = (CHAR) 0x0;
|
|
WARNING("GDI32!INVALID DBCS codepage\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* bComputeCharWidthsDBCS
|
|
*
|
|
* Client side version of GetCharWidth for DBCS fonts
|
|
*
|
|
* Wed 18-Aug-1993 10:00:00 -by- Gerrit van Wingerden [gerritv]
|
|
* Stole it and converted for DBCS use.
|
|
*
|
|
* Sat 16-Jan-1993 04:27:19 -by- Charles Whitmer [chuckwh]
|
|
* Wrote bComputeCharWidths on which this is based.
|
|
\**************************************************************************/
|
|
|
|
BOOL bComputeCharWidthsDBCS
|
|
(
|
|
CFONT *pcf,
|
|
UINT iFirst,
|
|
UINT iLast,
|
|
ULONG fl,
|
|
PVOID pv
|
|
)
|
|
{
|
|
USHORT *ps;
|
|
USHORT ausWidths[256];
|
|
UINT ii, cc;
|
|
|
|
if( iLast - iFirst > 0xFF )
|
|
{
|
|
WARNING("bComputeCharWidthsDBCS iLast - iFirst > 0xFF" );
|
|
return(FALSE);
|
|
}
|
|
|
|
if( iLast < iFirst )
|
|
{
|
|
WARNING("bComputeCharWidthsDBCS iLast < iFirst" );
|
|
return(FALSE);
|
|
}
|
|
|
|
// We want to compute the same widths that would be computed if
|
|
// vSetUpUnicodeStringx were called with this first and last and then
|
|
// GetCharWidthsW was called. The logic may be wierd but I assume it is
|
|
// there for Win 3.1J char widths compatability. To do this first fill
|
|
// in the plain widths in ausWidths and then do all the neccesary
|
|
// computation on them.
|
|
|
|
if ( gpwcDBCSCharSet[(UCHAR)(iFirst>>8)] == 0xFFFF )
|
|
{
|
|
for( cc = 0 ; cc <= iLast - iFirst; cc++ )
|
|
{
|
|
// If this is a legitimate DBCS character then use
|
|
// MaxCharInc.
|
|
|
|
ausWidths[cc] = pcf->wd.sDBCSInc;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( ii = (iFirst & 0x00FF), cc = 0; ii <= (iLast & 0x00FF); cc++, ii++ )
|
|
{
|
|
// Just treat everything as a single byte unless we
|
|
// encounter a DBCS lead byte which we will treat as a
|
|
// default character.
|
|
|
|
if( gpwcDBCSCharSet[ii] == 0xFFFF )
|
|
{
|
|
ausWidths[cc] = pcf->wd.sDefaultInc;
|
|
}
|
|
else
|
|
{
|
|
ausWidths[cc] = pcf->sWidth[ii];
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (fl & (GCW_INT | GCW_16BIT))
|
|
{
|
|
case GCW_INT: // Get LONG widths.
|
|
{
|
|
LONG *pl = (LONG *) pv;
|
|
LONG fxOverhang = 0;
|
|
|
|
// Check for Win 3.1 compatibility.
|
|
|
|
if (fl & GCW_WIN3)
|
|
fxOverhang = pcf->wd.sOverhang;
|
|
|
|
// Do the trivial no-transform case.
|
|
|
|
if (bIsOneSixteenthEFLOAT(pcf->efDtoWBaseline))
|
|
{
|
|
fxOverhang += 8; // To round the final result.
|
|
|
|
// for (ii=iFirst; ii<=iLast; ii++)
|
|
// *pl++ = (pcf->sWidth[ii] + fxOverhang) >> 4;
|
|
|
|
ps = ausWidths;
|
|
ii = iLast - iFirst;
|
|
unroll_1:
|
|
switch(ii)
|
|
{
|
|
default:
|
|
pl[4] = (ps[4] + fxOverhang) >> 4;
|
|
case 3:
|
|
pl[3] = (ps[3] + fxOverhang) >> 4;
|
|
case 2:
|
|
pl[2] = (ps[2] + fxOverhang) >> 4;
|
|
case 1:
|
|
pl[1] = (ps[1] + fxOverhang) >> 4;
|
|
case 0:
|
|
pl[0] = (ps[0] + fxOverhang) >> 4;
|
|
}
|
|
if (ii > 4)
|
|
{
|
|
ii -= 5;
|
|
pl += 5;
|
|
ps += 5;
|
|
goto unroll_1;
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
// Otherwise use the back transform.
|
|
|
|
else
|
|
{
|
|
for (ii=0; ii<=iLast-iFirst; ii++)
|
|
*pl++ = lCvt(pcf->efDtoWBaseline,ausWidths[ii] + fxOverhang);
|
|
return(TRUE);
|
|
}
|
|
}
|
|
|
|
case GCW_INT+GCW_16BIT: // Get SHORT widths.
|
|
{
|
|
USHORT *psDst = (USHORT *) pv;
|
|
USHORT fsOverhang = 0;
|
|
|
|
// Check for Win 3.1 compatibility.
|
|
|
|
if (fl & GCW_WIN3)
|
|
fsOverhang = pcf->wd.sOverhang;
|
|
|
|
// Do the trivial no-transform case.
|
|
|
|
if (bIsOneSixteenthEFLOAT(pcf->efDtoWBaseline))
|
|
{
|
|
fsOverhang += 8; // To round the final result.
|
|
|
|
// for (ii=iFirst; ii<=iLast; ii++)
|
|
// *psDst++ = (pcf->sWidth[ii] + fsOverhang) >> 4;
|
|
|
|
ps = ausWidths;
|
|
ii = iLast - iFirst;
|
|
unroll_2:
|
|
switch(ii)
|
|
{
|
|
default:
|
|
psDst[4] = (ps[4] + fsOverhang) >> 4;
|
|
case 3:
|
|
psDst[3] = (ps[3] + fsOverhang) >> 4;
|
|
case 2:
|
|
psDst[2] = (ps[2] + fsOverhang) >> 4;
|
|
case 1:
|
|
psDst[1] = (ps[1] + fsOverhang) >> 4;
|
|
case 0:
|
|
psDst[0] = (ps[0] + fsOverhang) >> 4;
|
|
}
|
|
if (ii > 4)
|
|
{
|
|
ii -= 5;
|
|
psDst += 5;
|
|
ps += 5;
|
|
goto unroll_2;
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
// Otherwise use the back transform.
|
|
|
|
else
|
|
{
|
|
for (ii=0; ii<=iLast-iFirst; ii++)
|
|
{
|
|
*psDst++ = (USHORT)
|
|
lCvt
|
|
(
|
|
pcf->efDtoWBaseline,
|
|
(LONG) (ausWidths[ii] + fsOverhang)
|
|
);
|
|
}
|
|
return(TRUE);
|
|
}
|
|
}
|
|
|
|
case 0: // Get FLOAT widths.
|
|
{
|
|
LONG *pe = (LONG *) pv; // Cheat to avoid expensive copies.
|
|
EFLOAT_S efWidth,efWidthLogical;
|
|
|
|
for (ii=0; ii<=iLast-iFirst; ii++)
|
|
{
|
|
vFxToEf((LONG) ausWidths[ii],efWidth);
|
|
vMulEFLOAT(efWidthLogical,efWidth,pcf->efDtoWBaseline);
|
|
*pe++ = lEfToF(efWidthLogical);
|
|
}
|
|
return(TRUE);
|
|
}
|
|
}
|
|
RIP("bComputeCharWidths: Don't come here!\n");
|
|
return(FALSE);
|
|
}
|
|
|
|
BOOL bIsDBCSString
|
|
(
|
|
LPCSTR psz,
|
|
int cc
|
|
)
|
|
{
|
|
int ii;
|
|
BYTE *pc;
|
|
|
|
pc = (BYTE *) psz;
|
|
|
|
cc--; // do not go off the edge !
|
|
|
|
for (ii=0; ii<cc; ii++)
|
|
{
|
|
// if DBCS lead byte add in DBCS width
|
|
|
|
if((gpwcDBCSCharSet[pc[ii]] == 0xFFFF)) // is this a DBCS LeadByte
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* bComputeTextExtentDBCS (pldc,pcf,psz,cc,fl,psizl)
|
|
*
|
|
* A quick function to compute text extents on the client side for DBCS
|
|
* fonts.
|
|
*
|
|
* Tue 17-Aug-1993 10:00:00 -by- Gerrit van Wingerden [gerritv]
|
|
* Stole it and converted for DBCS use.
|
|
*
|
|
* Thu 14-Jan-1993 04:00:57 -by- Charles Whitmer [chuckwh]
|
|
* Wrote bComputeTextExtent from which this was stolen.
|
|
\**************************************************************************/
|
|
|
|
BOOL bComputeTextExtentDBCS
|
|
(
|
|
PDC_ATTR pDcAttr,
|
|
CFONT *pcf,
|
|
LPCSTR psz,
|
|
int cc,
|
|
UINT fl,
|
|
SIZE *psizl
|
|
)
|
|
{
|
|
LONG fxBasicExtent;
|
|
INT lTextExtra,lBreakExtra,cBreak;
|
|
INT cChars = 0;
|
|
int ii;
|
|
BYTE *pc;
|
|
FIX fxCharExtra = 0;
|
|
FIX fxBreakExtra;
|
|
FIX fxExtra = 0;
|
|
|
|
lTextExtra = pDcAttr->lTextExtra;
|
|
lBreakExtra = pDcAttr->lBreakExtra;
|
|
cBreak = pDcAttr->cBreak;
|
|
|
|
pc = (BYTE *) psz;
|
|
|
|
// Compute the basic extent.
|
|
|
|
fxBasicExtent = 0;
|
|
pc = (BYTE *) psz;
|
|
|
|
for (ii=0; ii<cc; ii++)
|
|
{
|
|
// if DBCS lead byte add in DBCS width
|
|
|
|
if( /* Check the string has two bytes or more ? */
|
|
cc - ii - 1 &&
|
|
/* Check Is this a DBCS LeadByte ? */
|
|
gpwcDBCSCharSet[*pc] == 0xFFFF &&
|
|
/* Check Is this a DBCS TrailByte ? */
|
|
IS_DBCS_TRAIL_BYTE((*(pc+sizeof(CHAR))))
|
|
)
|
|
{
|
|
ii++;
|
|
pc += 2;
|
|
fxBasicExtent += pcf->wd.sDBCSInc;
|
|
}
|
|
else
|
|
{
|
|
fxBasicExtent += pcf->sWidth[*pc++];
|
|
}
|
|
|
|
cChars += 1;
|
|
}
|
|
|
|
// Adjust for CharExtra.
|
|
|
|
if (lTextExtra)
|
|
{
|
|
int cNoBackup = 0;
|
|
|
|
fxCharExtra = lCvt(pcf->efM11,lTextExtra);
|
|
|
|
if( fxCharExtra < 0 )
|
|
{
|
|
// the layout code won't backup a characters past it's origin regardless
|
|
// of the value of iTextCharExtra so figure out for how many values
|
|
// we will need to ignore fxCharExtra
|
|
|
|
if( pcf->wd.sCharInc == 0 )
|
|
{
|
|
for( ii = 0; ii < cc; ii++ )
|
|
{
|
|
if( gpwcDBCSCharSet[(BYTE)psz[ii]] == 0xFFFF )
|
|
{
|
|
if( pcf->wd.sDBCSInc + fxCharExtra <= 0 )
|
|
{
|
|
cNoBackup += 1;
|
|
}
|
|
ii++;
|
|
}
|
|
else
|
|
{
|
|
if( pcf->sWidth[(BYTE)psz[ii]] + fxCharExtra <= 0 )
|
|
{
|
|
cNoBackup += 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
if( pcf->wd.sCharInc + fxCharExtra <= 0 )
|
|
{
|
|
cNoBackup = cChars;
|
|
}
|
|
}
|
|
|
|
if ( (fl & GGTE_WIN3_EXTENT) && (pcf->hdc == 0)
|
|
&& (!(pcf->flInfo & FM_INFO_TECH_STROKE)) )
|
|
fxExtra = fxCharExtra * ((lTextExtra > 0) ? cChars : (cChars - 1));
|
|
else
|
|
fxExtra = fxCharExtra * ( cChars - cNoBackup );
|
|
}
|
|
|
|
// Adjust for lBreakExtra.
|
|
|
|
if (lBreakExtra && cBreak)
|
|
{
|
|
fxBreakExtra = lCvt(pcf->efM11,lBreakExtra) / cBreak;
|
|
|
|
// Windows won't let us back up over a break. Set up the BreakExtra
|
|
// to just cancel out what we've already got.
|
|
|
|
if (fxBreakExtra + pcf->wd.sBreak + fxCharExtra < 0)
|
|
fxBreakExtra = -(pcf->wd.sBreak + fxCharExtra);
|
|
|
|
// Add it up for all breaks.
|
|
|
|
pc = (BYTE *) psz;
|
|
for (ii=0; ii<cc; ii++)
|
|
{
|
|
if (gpwcDBCSCharSet[*pc] == 0xFFFF)
|
|
{
|
|
ii++;
|
|
pc += 2;
|
|
}
|
|
else if (*pc++ == pcf->wd.iBreak)
|
|
{
|
|
fxExtra += fxBreakExtra;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add in the extra stuff.
|
|
|
|
fxBasicExtent += fxExtra;
|
|
|
|
// Add in the overhang for font simulations.
|
|
|
|
if (fl & GGTE_WIN3_EXTENT)
|
|
fxBasicExtent += pcf->wd.sOverhang;
|
|
|
|
// Transform the result to logical coordinates.
|
|
|
|
if (bIsOneSixteenthEFLOAT(pcf->efDtoWBaseline))
|
|
psizl->cx = (fxBasicExtent + 8) >> 4;
|
|
else
|
|
psizl->cx = lCvt(pcf->efDtoWBaseline,fxBasicExtent);
|
|
|
|
psizl->cy = pcf->lHeight;
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/******************************Public*Routine*****************************\
|
|
* QueryFontAssocStatus() *
|
|
* *
|
|
* History: *
|
|
* 05-Jan-1994 -by- Pi-Sui Hsu [pisuih] *
|
|
* Wrote it. *
|
|
\*************************************************************************/
|
|
|
|
UINT APIENTRY QueryFontAssocStatus( VOID )
|
|
{
|
|
return(fFontAssocStatus);
|
|
}
|
|
|
|
INT APIENTRY GetFontAssocStatus( HDC hdc )
|
|
{
|
|
if(hdc == NULL)
|
|
{
|
|
return(0);
|
|
}
|
|
else
|
|
{
|
|
return(NtGdiQueryFontAssocInfo(hdc));
|
|
}
|
|
}
|
|
|
|
|
|
BOOL bToUnicodeNx(LPWSTR pwsz, LPCSTR psz, DWORD c, UINT codepage)
|
|
{
|
|
|
|
if(fFontAssocStatus &&
|
|
((codepage == GetACP() || codepage == CP_ACP)) &&
|
|
((c == 1) || ((c == 2 && *(psz) && *((LPCSTR)(psz + 1)) == '\0'))))
|
|
{
|
|
//
|
|
// If this function is called with only 1 char, and font association
|
|
// is enabled, we should forcely convert the chars to Unicode with
|
|
// codepage 1252.
|
|
// This is for enabling to output Latin-1 chars ( > 0x80 in Ansi codepage )
|
|
// Because, normally font association is enabled, we have no way to output
|
|
// those charactres, then we provide the way, if user call TextOutA() with
|
|
// A character and ansi font, we tempotary disable font association.
|
|
// This might be Windows 3.1 (Korean/Taiwanese) version compatibility..
|
|
//
|
|
|
|
codepage = 1252;
|
|
}
|
|
|
|
if(MultiByteToWideChar(codepage, 0, psz, c, pwsz, c))
|
|
{
|
|
return(TRUE);
|
|
}
|
|
else
|
|
{
|
|
GdiSetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* vSetUpUnicodeStringx
|
|
*
|
|
* Effects:
|
|
*
|
|
* Warnings:
|
|
*
|
|
* History:
|
|
* 14-Mar-1993 -by- Hideyuki Nagase [hideyukn]
|
|
* Change hardcoded default character to defulat char is given as a parameter.
|
|
*
|
|
* 01-Mar-1993 -by- Takao Kitano [takaok]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL bSetUpUnicodeStringDBCS
|
|
(
|
|
IN UINT iFirst, // first ansi char
|
|
IN UINT iLast, // last char
|
|
IN PUCHAR puchTmp, // temporary buffer
|
|
OUT PWCHAR pwc, // output fuffer with a unicode string
|
|
IN UINT uiCodePage, // ansi codepage
|
|
IN CHAR chDefaultChar // default character
|
|
)
|
|
{
|
|
PUCHAR puchBuf;
|
|
BOOL bRet = FALSE;
|
|
|
|
puchBuf = puchTmp;
|
|
|
|
if(IsDBCSLeadByteEx(uiCodePage,(UCHAR)(iFirst >> 8)))
|
|
{
|
|
|
|
// This is DBCS character strings.
|
|
|
|
for (; iFirst <= iLast; iFirst++ )
|
|
{
|
|
*puchBuf++ = (UCHAR)(iFirst >> 8);
|
|
*puchBuf++ = (UCHAR)(iFirst);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
// This is SBCS character strings.
|
|
// if Hi-byte of iFirst is not valid DBCS LeadByte , we use only
|
|
// lo-byte of it.
|
|
|
|
for ( ; iFirst <= iLast; iFirst++ )
|
|
{
|
|
|
|
// If this SBCS code in LeadByte area . It replce with default
|
|
// character
|
|
|
|
if ( IsDBCSLeadByteEx(uiCodePage,(UCHAR)iFirst) )
|
|
*puchBuf++ = chDefaultChar;
|
|
else
|
|
*puchBuf++ = (UCHAR)iFirst;
|
|
}
|
|
}
|
|
|
|
//Sundown: safe to truncate to DWORD since puchBug - puchTmp won't exceed iLast
|
|
bRet = bToUnicodeNx(pwc, puchTmp, (DWORD)(puchBuf - puchTmp), uiCodePage);
|
|
|
|
return(bRet);
|
|
}
|
|
|
|
|
|
BOOL IsValidDBCSRange( UINT iFirst , UINT iLast )
|
|
{
|
|
// DBCS & SBCS char parameter checking for DBCS font
|
|
|
|
if( iFirst > 0x00ff )
|
|
{
|
|
// DBCS char checking for DBCS font
|
|
if (
|
|
// Check limit
|
|
(iFirst > 0xffff) || (iLast > 0xffff) ||
|
|
|
|
// DBCSLeadByte shoud be same
|
|
(iFirst & 0xff00) != (iLast & 0xff00) ||
|
|
|
|
// DBCSTrailByte of the First should be >= one of the Last
|
|
(iFirst & 0x00ff) > (iLast & 0x00ff)
|
|
)
|
|
{
|
|
return(FALSE);
|
|
}
|
|
}
|
|
|
|
// DBCS char checking for DBCS font
|
|
|
|
else if( (iFirst > iLast) || (iLast & 0xffffff00) )
|
|
{
|
|
return(FALSE);
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
/******************************Private*Routine*****************************\
|
|
* GetCurrentDefaultChar()
|
|
*
|
|
* History:
|
|
*
|
|
* Mon 15-Mar-1993 18:14:00 -by- Hideyuki Nagase
|
|
* wrote it.
|
|
***************************************************************************/
|
|
|
|
BYTE GetCurrentDefaultChar(HDC hdc)
|
|
{
|
|
|
|
// WINBUG 365031 4-10-2001 pravins Consider optimization in GetCurrentDeafultChar
|
|
//
|
|
// Old Comment:
|
|
// - This is slow for now. We should cache this value locally in the dcattr
|
|
// but want to get other things working for now. [gerritv] 2-22-96
|
|
|
|
TEXTMETRICA tma;
|
|
|
|
GetTextMetricsA( hdc , &tma );
|
|
|
|
return(tma.tmDefaultChar);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
* ConvertDxArray(UINT, char*, INT*, UINT, INT*)
|
|
*
|
|
* Tue 27-Feb-1996 23:45:00 -by- Gerrit van Wingerden [gerritv]
|
|
*
|
|
***************************************************************************/
|
|
|
|
void ConvertDxArray(UINT CodePage,
|
|
char *pDBCSString,
|
|
INT *pDxDBCS,
|
|
UINT Count,
|
|
INT *pDxUnicode,
|
|
BOOL bPdy
|
|
)
|
|
{
|
|
char *pDBCSStringEnd;
|
|
|
|
if (!bPdy)
|
|
{
|
|
|
|
for(pDBCSStringEnd = pDBCSString + Count;
|
|
pDBCSString < pDBCSStringEnd;
|
|
)
|
|
{
|
|
if(IsDBCSLeadByteEx(CodePage,*pDBCSString))
|
|
{
|
|
pDBCSString += 2;
|
|
*pDxUnicode = *pDxDBCS++;
|
|
*pDxUnicode += *pDxDBCS++;
|
|
}
|
|
else
|
|
{
|
|
pDBCSString += 1;
|
|
*pDxUnicode = *pDxDBCS++;
|
|
}
|
|
|
|
pDxUnicode += 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
POINTL *pdxdyUnicode = (POINTL *)pDxUnicode;
|
|
POINTL *pdxdyDBCS = (POINTL *)pDxDBCS;
|
|
|
|
for(pDBCSStringEnd = pDBCSString + Count;
|
|
pDBCSString < pDBCSStringEnd;
|
|
)
|
|
{
|
|
if(IsDBCSLeadByteEx(CodePage,*pDBCSString))
|
|
{
|
|
pDBCSString += 2;
|
|
*pdxdyUnicode = *pdxdyDBCS++;
|
|
pdxdyUnicode->x += pdxdyDBCS->x;
|
|
pdxdyUnicode->y += pdxdyDBCS->y;
|
|
pdxdyDBCS++;
|
|
}
|
|
else
|
|
{
|
|
pDBCSString += 1;
|
|
*pdxdyUnicode = *pdxdyDBCS++;
|
|
}
|
|
|
|
pdxdyUnicode++;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ULONG APIENTRY EudcLoadLinkW
|
|
(
|
|
LPCWSTR pBaseFaceName,
|
|
LPCWSTR pEudcFontPath,
|
|
INT iPriority,
|
|
INT iFontLinkType
|
|
)
|
|
{
|
|
return(NtGdiEudcLoadUnloadLink(pBaseFaceName,
|
|
(pBaseFaceName) ? wcslen(pBaseFaceName) : 0,
|
|
pEudcFontPath,
|
|
wcslen(pEudcFontPath),
|
|
iPriority,
|
|
iFontLinkType,
|
|
TRUE));
|
|
}
|
|
|
|
|
|
|
|
BOOL APIENTRY EudcUnloadLinkW
|
|
(
|
|
LPCWSTR pBaseFaceName,
|
|
LPCWSTR pEudcFontPath
|
|
)
|
|
{
|
|
return(NtGdiEudcLoadUnloadLink(pBaseFaceName,
|
|
(pBaseFaceName) ? wcslen(pBaseFaceName) : 0,
|
|
pEudcFontPath,
|
|
wcslen(pEudcFontPath),
|
|
0,
|
|
0,
|
|
FALSE));
|
|
|
|
}
|
|
|
|
|
|
|
|
ULONG APIENTRY GetEUDCTimeStampExW
|
|
(
|
|
LPCWSTR pBaseFaceName
|
|
)
|
|
{
|
|
return(NtGdiGetEudcTimeStampEx((LPWSTR) pBaseFaceName,
|
|
(pBaseFaceName) ? wcslen(pBaseFaceName) : 0,
|
|
FALSE));
|
|
|
|
}
|
|
|
|
|
|
ULONG APIENTRY GetEUDCTimeStamp()
|
|
{
|
|
return(NtGdiGetEudcTimeStampEx(NULL,0,TRUE));
|
|
}
|
|
|
|
UINT
|
|
GetStringBitmapW(
|
|
HDC hdc,
|
|
LPWSTR pwc,
|
|
UINT cwc,
|
|
UINT cbData,
|
|
BYTE *pSB
|
|
)
|
|
{
|
|
if(cwc != 1)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
return(NtGdiGetStringBitmapW(hdc,pwc,1,(PBYTE) pSB,cbData));
|
|
}
|
|
|
|
|
|
UINT
|
|
GetStringBitmapA(
|
|
HDC hdc,
|
|
LPSTR pc,
|
|
UINT cch,
|
|
UINT cbData,
|
|
BYTE *pSB
|
|
)
|
|
{
|
|
WCHAR Character[2];
|
|
|
|
if(cch > 2 )
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
|
|
if(MultiByteToWideChar(CP_ACP,0,pc,cch,Character,2)!=1)
|
|
{
|
|
return(0);
|
|
}
|
|
|
|
return(GetStringBitmapW(hdc,Character,1,cbData,pSB));
|
|
}
|
|
|
|
|
|
DWORD FontAssocHack(DWORD dwCodePage, CHAR *psz, UINT c)
|
|
{
|
|
// If a Text function is called with only 1 char, and font association
|
|
// is enabled, we should forcely convert the chars to Unicode with
|
|
// codepage 1252.
|
|
// This is for enabling to output Latin-1 chars ( > 0x80 in Ansi codepage )
|
|
// Because, normally font association is enabled, we have no way to output
|
|
// those charactres, then we provide the way, if user call TextOutA() with
|
|
// A character and ansi font, we tempotary disable font association.
|
|
// This might be Windows 3.1 (Korean/Taiwanese) version compatibility..
|
|
|
|
|
|
ASSERTGDI(fFontAssocStatus,
|
|
"FontAssocHack called with FontAssocStatus turned off\n");
|
|
|
|
if(((dwCodePage == GetACP() || dwCodePage == CP_ACP)) &&
|
|
((c == 1) || ((c == 2 && *(psz) && *((LPCSTR)(psz + 1)) == '\0'))))
|
|
{
|
|
return(1252);
|
|
}
|
|
else
|
|
{
|
|
return(dwCodePage);
|
|
}
|
|
}
|