mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 10:33:33 +00:00
check in performance improved unicode rendering for mac. Use TEC convert to script code before calling ATSUI to improve peroformance
This commit is contained in:
parent
e11fb63db9
commit
6339be6419
Binary file not shown.
@ -212,127 +212,6 @@ PRBool nsATSUIUtils::IsAvailable()
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------
|
||||
// ConvertToMacRoman
|
||||
//--------------------------------
|
||||
|
||||
PRBool nsATSUIUtils::ConvertToMacRoman(const PRUnichar *aString, PRUint32 aLength, char* macroman, PRBool onlyAllowASCII)
|
||||
{
|
||||
static char map[0x80] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xCA, 0xC1, 0xA2, 0xA3, 0x00, 0xB4, 0x00, 0xA4, 0xAC, 0xA9, 0xBB, 0xC7, 0xC2, 0xD0, 0xA8, 0xF8,
|
||||
0xA1, 0xB1, 0x00, 0x00, 0xAB, 0xB5, 0xA6, 0xE1, 0xFC, 0x00, 0xBC, 0xC8, 0x00, 0x00, 0x00, 0xC0,
|
||||
0xCB, 0xE7, 0xE5, 0xCC, 0x80, 0x81, 0xAE, 0x82, 0xE9, 0x83, 0xE6, 0xE8, 0xED, 0xEA, 0xEB, 0xEC,
|
||||
0x00, 0x84, 0xF1, 0xEE, 0xEF, 0xCD, 0x85, 0x78, 0xAF, 0xF4, 0xF2, 0xF3, 0x86, 0x00, 0x00, 0xA7,
|
||||
0x88, 0x87, 0x89, 0x8B, 0x8A, 0x8C, 0xBE, 0x8D, 0x8F, 0x8E, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95,
|
||||
0x00, 0x96, 0x98, 0x97, 0x99, 0x9B, 0x9A, 0xD6, 0xBF, 0x9D, 0x9C, 0x9E, 0x9F, 0x00, 0x00, 0xD8
|
||||
|
||||
};
|
||||
static char g2010map[0x40] = {
|
||||
0x00,0x00,0x00,0xd0,0xd1,0x00,0x00,0x00,0xd4,0xd5,0xe2,0x00,0xd2,0xd3,0xe3,0x00,
|
||||
0xa0,0xe0,0xa5,0x00,0x00,0x00,0xc9,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xe4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0xdd,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x05,0x00,0xda,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
const PRUnichar *u = aString;
|
||||
char *c = macroman;
|
||||
if (onlyAllowASCII)
|
||||
{
|
||||
for (PRUint32 i = 0 ; i < aLength ; i++)
|
||||
{
|
||||
if ((*u) & 0xFF80)
|
||||
return PR_FALSE;
|
||||
*c++ = *u++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// XXX we should clean up these by calling the Unicode Converter after cata add x-mac-roman converters there.
|
||||
for (PRUint32 i = 0 ; i < aLength ; i++)
|
||||
{
|
||||
if ((*u) & 0xFF80)
|
||||
{
|
||||
char ch;
|
||||
switch ((*u) & 0xFF00)
|
||||
{
|
||||
case 0x0000:
|
||||
ch = map[(*u) & 0x007F];
|
||||
break;
|
||||
|
||||
case 0x2000:
|
||||
if (0x2202 == *u)
|
||||
{
|
||||
ch = 0xDB;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*u < 0x2013) || ( *u > 0x2044))
|
||||
return PR_FALSE;
|
||||
ch = g2010map[*u - 0x2010];
|
||||
if( 0 == ch)
|
||||
return PR_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2100:
|
||||
if (0x2122 == *u) ch = 0xAA;
|
||||
else if (0x2126 == *u) ch = 0xBD;
|
||||
else return PR_FALSE;
|
||||
break;
|
||||
|
||||
case 0x2200:
|
||||
switch (*u)
|
||||
{
|
||||
case 0x2202: ch = 0xB6; break;
|
||||
case 0x2206: ch = 0xBD; break;
|
||||
case 0x220F: ch = 0xC6; break;
|
||||
case 0x2211: ch = 0xB8; break;
|
||||
case 0x221A: ch = 0xB7; break;
|
||||
case 0x221E: ch = 0xC3; break;
|
||||
case 0x222B: ch = 0xBA; break;
|
||||
case 0x2248: ch = 0xC5; break;
|
||||
case 0x2260: ch = 0xAD; break;
|
||||
case 0x2264: ch = 0xB2; break;
|
||||
case 0x2265: ch = 0xB3; break;
|
||||
default: return PR_FALSE;
|
||||
};
|
||||
break;
|
||||
|
||||
case 0x2500:
|
||||
if (0x25CA == *u) ch = 0xD7;
|
||||
else return PR_FALSE;
|
||||
break;
|
||||
|
||||
case 0xF800:
|
||||
if (0xF8FF == *u) ch = 0xF0;
|
||||
else return PR_FALSE;
|
||||
break;
|
||||
|
||||
case 0xFB00:
|
||||
if (0xFB01 == *u) ch = 0xDE;
|
||||
else if( 0xFB02 == *u) ch = 0xDF;
|
||||
else return PR_FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
return PR_FALSE;
|
||||
}
|
||||
u++;
|
||||
if (ch == 0)
|
||||
return PR_FALSE;
|
||||
*c++ = ch;
|
||||
}
|
||||
else
|
||||
{
|
||||
*c++ = *u++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
@ -342,26 +221,6 @@ PRBool nsATSUIUtils::ConvertToMacRoman(const PRUnichar *aString, PRUint32 aLengt
|
||||
nsATSUIToolkit::nsATSUIToolkit()
|
||||
{
|
||||
nsATSUIUtils::Initialize();
|
||||
|
||||
mLastTextLayout = nsnull;
|
||||
mFontOrColorChanged = PR_TRUE;
|
||||
mGS = nsnull;
|
||||
mPort = nsnull;
|
||||
mContext = nsnull;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// PrepareToDraw
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
void nsATSUIToolkit::PrepareToDraw(PRBool aFontOrColorChanged, nsGraphicState* aGS, GrafPtr aPort, nsIDeviceContext* aContext)
|
||||
{
|
||||
mFontOrColorChanged |= aFontOrColorChanged;
|
||||
mGS = aGS;
|
||||
mPort = aPort;
|
||||
mContext = aContext;
|
||||
}
|
||||
|
||||
|
||||
@ -372,204 +231,226 @@ void nsATSUIToolkit::PrepareToDraw(PRBool aFontOrColorChanged, nsGraphicState* a
|
||||
|
||||
#define FloatToFixed(a) ((Fixed)((float)(a) * fixed1))
|
||||
|
||||
ATSUTextLayout nsATSUIToolkit::GetTextLayout()
|
||||
//------------------------------------------------------------------------
|
||||
ATSUTextLayout nsATSUIToolkit::GetTextLayout(short aFontNum, short aSize, PRBool aBold, PRBool aItalic, nscolor aColor)
|
||||
{
|
||||
if (!mFontOrColorChanged)
|
||||
return mLastTextLayout;
|
||||
mFontOrColorChanged = false;
|
||||
|
||||
ATSUTextLayout txLayout = nsnull;
|
||||
OSStatus err;
|
||||
|
||||
nsFont *font;
|
||||
nsFontHandle fontNum;
|
||||
mGS->mFontMetrics->GetFont(font);
|
||||
mGS->mFontMetrics->GetFontHandle(fontNum);
|
||||
PRBool aBold = font->weight > NS_FONT_WEIGHT_NORMAL;
|
||||
PRBool aItalic = (NS_FONT_STYLE_ITALIC == font->style) || (NS_FONT_STYLE_OBLIQUE == font->style);
|
||||
|
||||
if (!nsATSUIUtils::gTxLayoutCache->Get((short)fontNum, font->size, aBold, aItalic, mGS->mColor, &txLayout))
|
||||
{
|
||||
UniChar dmy[1];
|
||||
err = ATSUCreateTextLayoutWithTextPtr (dmy, 0,0,0,0,NULL, NULL, &txLayout);
|
||||
|
||||
NS_ASSERTION(noErr == err, "ATSUCreateTextLayoutWithTextPtr failed");
|
||||
|
||||
ATSUStyle theStyle;
|
||||
err = ATSUCreateStyle(&theStyle);
|
||||
NS_ASSERTION(noErr == err, "ATSUCreateStyle failed");
|
||||
|
||||
ATSUAttributeTag theTag[3];
|
||||
ByteCount theValueSize[3];
|
||||
ATSUAttributeValuePtr theValue[3];
|
||||
|
||||
//--- Font ID & Face -----
|
||||
ATSUFontID atsuFontID;
|
||||
if (nsATSUIUtils::gTxLayoutCache->Get(aFontNum, aSize, aBold, aItalic, aColor, &txLayout))
|
||||
return txLayout;
|
||||
|
||||
err = ATSUFONDtoFontID((short)fontNum, (StyleField)((aBold ? bold : normal) | (aItalic ? italic : normal)), &atsuFontID);
|
||||
NS_ASSERTION(noErr == err, "ATSUFONDtoFontID failed");
|
||||
UniChar dmy[1];
|
||||
err = ::ATSUCreateTextLayoutWithTextPtr (dmy, 0,0,0,0,NULL, NULL, &txLayout);
|
||||
if(noErr != err) {
|
||||
NS_WARNING("ATSUCreateTextLayoutWithTextPtr failed");
|
||||
goto errorDone;
|
||||
}
|
||||
|
||||
theTag[0] = kATSUFontTag;
|
||||
theValueSize[0] = (ByteCount) sizeof(ATSUFontID);
|
||||
theValue[0] = (ATSUAttributeValuePtr) &atsuFontID;
|
||||
//--- Font ID & Face -----
|
||||
|
||||
//--- Size -----
|
||||
float dev2app;
|
||||
short fontsize = font->size;
|
||||
ATSUStyle theStyle;
|
||||
err = ::ATSUCreateStyle(&theStyle);
|
||||
if(noErr != err) {
|
||||
NS_WARNING("ATSUCreateStyle failed");
|
||||
goto errorDoneDestroyTextLayout;
|
||||
}
|
||||
|
||||
mContext->GetDevUnitsToAppUnits(dev2app);
|
||||
Fixed size = FloatToFixed( roundf(float(fontsize) / dev2app));
|
||||
if( FixRound ( size ) < 9 && !nsDeviceContextMac::DisplayVerySmallFonts())
|
||||
size = X2Fix(9);
|
||||
ATSUAttributeTag theTag[3];
|
||||
ByteCount theValueSize[3];
|
||||
ATSUAttributeValuePtr theValue[3];
|
||||
|
||||
theTag[1] = kATSUSizeTag;
|
||||
theValueSize[1] = (ByteCount) sizeof(Fixed);
|
||||
theValue[1] = (ATSUAttributeValuePtr) &size;
|
||||
//--- Size -----
|
||||
|
||||
//--- Color -----
|
||||
RGBColor color;
|
||||
//--- Font ID & Face -----
|
||||
ATSUFontID atsuFontID;
|
||||
|
||||
err = ::ATSUFONDtoFontID(aFontNum, (StyleField)((aBold ? bold : normal) | (aItalic ? italic : normal)), &atsuFontID);
|
||||
if(noErr != err) {
|
||||
NS_WARNING("ATSUFONDtoFontID failed");
|
||||
goto errorDoneDestroyStyle;
|
||||
}
|
||||
|
||||
theTag[0] = kATSUFontTag;
|
||||
theValueSize[0] = (ByteCount) sizeof(ATSUFontID);
|
||||
theValue[0] = (ATSUAttributeValuePtr) &atsuFontID;
|
||||
//--- Font ID & Face -----
|
||||
|
||||
//--- Size -----
|
||||
float dev2app;
|
||||
short fontsize = aSize;
|
||||
|
||||
#define COLOR8TOCOLOR16(color8) ((color8 << 8) | color8)
|
||||
mContext->GetDevUnitsToAppUnits(dev2app);
|
||||
Fixed size = FloatToFixed( roundf(float(fontsize) / dev2app));
|
||||
if( FixRound ( size ) < 9 && !nsDeviceContextMac::DisplayVerySmallFonts())
|
||||
size = X2Fix(9);
|
||||
|
||||
color.red = COLOR8TOCOLOR16(NS_GET_R(mGS->mColor));
|
||||
color.green = COLOR8TOCOLOR16(NS_GET_G(mGS->mColor));
|
||||
color.blue = COLOR8TOCOLOR16(NS_GET_B(mGS->mColor));
|
||||
theTag[2] = kATSUColorTag;
|
||||
theValueSize[2] = (ByteCount) sizeof(RGBColor);
|
||||
theValue[2] = (ATSUAttributeValuePtr) &color;
|
||||
//--- Color -----
|
||||
theTag[1] = kATSUSizeTag;
|
||||
theValueSize[1] = (ByteCount) sizeof(Fixed);
|
||||
theValue[1] = (ATSUAttributeValuePtr) &size;
|
||||
//--- Size -----
|
||||
|
||||
//--- Color -----
|
||||
RGBColor color;
|
||||
|
||||
err = ATSUSetAttributes(theStyle, 3, theTag, theValueSize, theValue);
|
||||
NS_ASSERTION(noErr == err, "ATSUSetAttributes failed");
|
||||
|
||||
err = ATSUSetRunStyle(txLayout, theStyle, kATSUFromTextBeginning, kATSUToTextEnd);
|
||||
NS_ASSERTION(noErr == err, "ATSUSetRunStyle failed");
|
||||
#define COLOR8TOCOLOR16(color8) ((color8 << 8) | color8)
|
||||
|
||||
color.red = COLOR8TOCOLOR16(NS_GET_R(aColor));
|
||||
color.green = COLOR8TOCOLOR16(NS_GET_G(aColor));
|
||||
color.blue = COLOR8TOCOLOR16(NS_GET_B(aColor));
|
||||
theTag[2] = kATSUColorTag;
|
||||
theValueSize[2] = (ByteCount) sizeof(RGBColor);
|
||||
theValue[2] = (ATSUAttributeValuePtr) &color;
|
||||
//--- Color -----
|
||||
|
||||
err = ::ATSUSetAttributes(theStyle, 3, theTag, theValueSize, theValue);
|
||||
if(noErr != err) {
|
||||
NS_WARNING("ATSUSetAttributes failed");
|
||||
goto errorDoneDestroyStyle;
|
||||
}
|
||||
|
||||
err = ::ATSUSetRunStyle(txLayout, theStyle, kATSUFromTextBeginning, kATSUToTextEnd);
|
||||
if(noErr != err) {
|
||||
NS_WARNING("ATSUSetRunStyle failed");
|
||||
goto errorDoneDestroyStyle;
|
||||
}
|
||||
|
||||
err = ::ATSUSetTransientFontMatching(txLayout, true);
|
||||
if(noErr != err) {
|
||||
NS_WARNING( "ATSUSetTransientFontMatching failed");
|
||||
goto errorDoneDestroyStyle;
|
||||
}
|
||||
|
||||
nsATSUIUtils::gTxLayoutCache->Set(aFontNum, aSize, aBold, aItalic, aColor, txLayout);
|
||||
|
||||
okDone:
|
||||
return txLayout;
|
||||
|
||||
|
||||
err = ATSUSetTransientFontMatching(txLayout, true);
|
||||
NS_ASSERTION(noErr == err, "ATSUSetTransientFontMatching failed");
|
||||
|
||||
nsATSUIUtils::gTxLayoutCache->Set((short)fontNum, font->size, aBold, aItalic, mGS->mColor, txLayout);
|
||||
}
|
||||
mLastTextLayout = txLayout;
|
||||
return mLastTextLayout;
|
||||
errorDoneDestroyStyle:
|
||||
err = ::ATSUDisposeStyle(theStyle);
|
||||
errorDoneDestroyTextLayout:
|
||||
err = ::ATSUDisposeTextLayout(txLayout);
|
||||
errorDone:
|
||||
return nsnull;
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
// PrepareToDraw
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
void nsATSUIToolkit::PrepareToDraw(GrafPtr aPort, nsIDeviceContext* aContext)
|
||||
{
|
||||
mPort = aPort;
|
||||
mContext = aContext;
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
// StartDraw
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
void nsATSUIToolkit::StartDraw(
|
||||
const PRUnichar *aCharPt,
|
||||
short aSize, short aFontNum,
|
||||
PRBool aBold, PRBool aItalic, nscolor aColor,
|
||||
GrafPtr& oSavePort, ATSUTextLayout& oLayout)
|
||||
{
|
||||
::GetPort(&oSavePort);
|
||||
::SetPort(mPort);
|
||||
|
||||
OSStatus err = noErr;
|
||||
oLayout = GetTextLayout(aFontNum, aSize, aBold, aItalic, aColor);
|
||||
if (nsnull == oLayout) {
|
||||
NS_WARNING("GetTextLayout return nsnull");
|
||||
return;
|
||||
}
|
||||
|
||||
err = ATSUSetTextPointerLocation( oLayout, (ConstUniCharArrayPtr)aCharPt, 0, 1, 1);
|
||||
if(noErr != err) {
|
||||
NS_WARNING("ATSUSetTextPointerLocation failed");
|
||||
oLayout = nsnull;
|
||||
}
|
||||
return;
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
// EndDraw
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
void nsATSUIToolkit::EndDraw(GrafPtr aSavePort)
|
||||
{
|
||||
::SetPort(aSavePort);
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
// GetWidth
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP nsATSUIToolkit::GetWidth(const PRUnichar *aString, PRUint32 aLength,
|
||||
nscoord &aWidth, PRInt32 *aFontID)
|
||||
NS_IMETHODIMP nsATSUIToolkit::GetWidth(
|
||||
const PRUnichar *aCharPt,
|
||||
short& oWidth,
|
||||
short aSize, short aFontNum,
|
||||
PRBool aBold, PRBool aItalic, nscolor aColor)
|
||||
{
|
||||
oWidth = 0;
|
||||
if (!nsATSUIUtils::IsAvailable())
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsresult res = NS_OK;
|
||||
|
||||
nsresult res = NS_ERROR_FAILURE;
|
||||
GrafPtr savePort;
|
||||
::GetPort(&savePort);
|
||||
::SetPort(mPort);
|
||||
|
||||
OSStatus err = noErr;
|
||||
ATSUTextLayout aTxtLayout = GetTextLayout();
|
||||
err = ATSUSetTextPointerLocation( aTxtLayout, (ConstUniCharArrayPtr)aString, 0, aLength, aLength);
|
||||
NS_ASSERTION(noErr == err, "ATSUSetTextPointerLocation failed");
|
||||
|
||||
ATSUTextMeasurement iAfter;
|
||||
err = ATSUMeasureText( aTxtLayout, 0, aLength, NULL, &iAfter, NULL, NULL );
|
||||
NS_ASSERTION(noErr == err, "ATSUMeasureText failed");
|
||||
ATSUTextLayout aTxtLayout;
|
||||
|
||||
float dev2app;
|
||||
mContext->GetDevUnitsToAppUnits(dev2app);
|
||||
aWidth = NSToCoordRound(Fix2Long(FixMul(iAfter , X2Fix(dev2app))));
|
||||
|
||||
::SetPort(savePort);
|
||||
StartDraw(aCharPt, aSize, aFontNum, aBold, aItalic, aColor , savePort, aTxtLayout);
|
||||
if (nsnull == aTxtLayout)
|
||||
goto done;
|
||||
|
||||
OSStatus err = noErr;
|
||||
ATSUTextMeasurement iAfter;
|
||||
err = ATSUMeasureText( aTxtLayout, 0, 1, NULL, &iAfter, NULL, NULL );
|
||||
if(noErr != err) {
|
||||
NS_WARNING("ATSUMeasureText failed");
|
||||
goto done1;
|
||||
}
|
||||
oWidth = FixRound(iAfter);
|
||||
res = NS_OK;
|
||||
done1:
|
||||
EndDraw(savePort);
|
||||
done:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// DrawString
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP nsATSUIToolkit::DrawString(const PRUnichar *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY, PRInt32 aFontID,
|
||||
const nscoord* aSpacing)
|
||||
NS_IMETHODIMP nsATSUIToolkit::DrawString(
|
||||
const PRUnichar *aCharPt,
|
||||
PRInt32 x, PRInt32 y,
|
||||
short &oWidth,
|
||||
short aSize, short aFontNum,
|
||||
PRBool aBold, PRBool aItalic, nscolor aColor)
|
||||
{
|
||||
oWidth = 0;
|
||||
if (!nsATSUIUtils::IsAvailable())
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsresult res = NS_OK;
|
||||
|
||||
nsresult res = NS_ERROR_FAILURE;
|
||||
GrafPtr savePort;
|
||||
::GetPort(&savePort);
|
||||
::SetPort(mPort);
|
||||
|
||||
OSStatus err = noErr;
|
||||
ATSUTextLayout aTxtLayout;
|
||||
|
||||
PRInt32 x = aX;
|
||||
PRInt32 y = aY;
|
||||
if (mGS->mFontMetrics)
|
||||
{
|
||||
// set native font and attributes
|
||||
//SetPortTextState();
|
||||
StartDraw(aCharPt, aSize, aFontNum, aBold, aItalic, aColor , savePort, aTxtLayout);
|
||||
if (nsnull == aTxtLayout)
|
||||
goto done;
|
||||
|
||||
OSStatus err = noErr;
|
||||
ATSUTextMeasurement iAfter;
|
||||
err = ATSUMeasureText( aTxtLayout, 0, 1, NULL, &iAfter, NULL, NULL );
|
||||
if(noErr != err) {
|
||||
NS_WARNING("ATSUMeasureText failed");
|
||||
goto done1;
|
||||
}
|
||||
err = ATSUDrawText( aTxtLayout, 0, 1, Long2Fix(x), Long2Fix(y));
|
||||
if(noErr != err) {
|
||||
NS_WARNING("ATSUDrawText failed");
|
||||
goto done1;
|
||||
}
|
||||
oWidth = FixRound(iAfter);
|
||||
res = NS_OK;
|
||||
|
||||
// substract ascent since drawing specifies baseline
|
||||
nscoord ascent = 0;
|
||||
mGS->mFontMetrics->GetMaxAscent(ascent);
|
||||
y += ascent;
|
||||
}
|
||||
mGS->mTMatrix->TransformCoord(&x,&y);
|
||||
|
||||
ATSUTextLayout aTxtLayout = GetTextLayout();
|
||||
if (NULL == aSpacing)
|
||||
{
|
||||
err = ATSUSetTextPointerLocation( aTxtLayout, (ConstUniCharArrayPtr)aString, 0, aLength, aLength);
|
||||
NS_ASSERTION(noErr == err, "ATSUSetTextPointerLocation failed");
|
||||
err = ATSUDrawText( aTxtLayout, 0, aLength, Long2Fix(x), Long2Fix(y));
|
||||
NS_ASSERTION(noErr == err, "ATSUMeasureText failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aLength < 500)
|
||||
{
|
||||
int spacing[500];
|
||||
mGS->mTMatrix->ScaleXCoords(aSpacing, aLength, spacing);
|
||||
for (PRInt32 i = 0; i < aLength; i++)
|
||||
{
|
||||
err = ATSUSetTextPointerLocation( aTxtLayout, (ConstUniCharArrayPtr)aString+i, 0, 1, 1);
|
||||
NS_ASSERTION(noErr == err, "ATSUSetTextPointerLocation failed");
|
||||
err = ATSUDrawText( aTxtLayout, 0, 1, Long2Fix(x), Long2Fix(y));
|
||||
NS_ASSERTION(noErr == err, "ATSUMeasureText failed");
|
||||
x += spacing[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int *spacing = new int[aLength];
|
||||
NS_ASSERTION(NULL != spacing, "memalloc failed");
|
||||
if (spacing)
|
||||
{
|
||||
mGS->mTMatrix->ScaleXCoords(aSpacing, aLength, spacing);
|
||||
for (PRInt32 i = 0; i < aLength; i++)
|
||||
{
|
||||
err = ATSUSetTextPointerLocation( aTxtLayout, (ConstUniCharArrayPtr)aString+i, 0, 1, 1);
|
||||
NS_ASSERTION(noErr == err, "ATSUSetTextPointerLocation failed");
|
||||
err = ATSUDrawText( aTxtLayout, 0, 1, Long2Fix(x), Long2Fix(y));
|
||||
NS_ASSERTION(noErr == err, "ATSUMeasureText failed");
|
||||
x += spacing[i];
|
||||
}
|
||||
delete[] spacing;
|
||||
}
|
||||
else
|
||||
res = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
::SetPort(savePort);
|
||||
done1:
|
||||
EndDraw(savePort);
|
||||
done:
|
||||
return res;
|
||||
}
|
||||
|
@ -23,21 +23,18 @@
|
||||
#include "nsCRT.h"
|
||||
#include "nsError.h"
|
||||
#include "nsCoord.h"
|
||||
#include "nsColor.h"
|
||||
#include <ATSUnicode.h>
|
||||
|
||||
|
||||
class ATSUILayoutCache;
|
||||
class nsDrawingSurfaceMac;
|
||||
class nsIDeviceContext;
|
||||
class nsGraphicState;
|
||||
|
||||
|
||||
class nsATSUIUtils
|
||||
{
|
||||
public:
|
||||
static void Initialize();
|
||||
static PRBool IsAvailable();
|
||||
static PRBool ConvertToMacRoman(const PRUnichar *aString, PRUint32 aLength, char* macroman, PRBool onlyAllowASCII);
|
||||
|
||||
static ATSUILayoutCache* gTxLayoutCache;
|
||||
|
||||
@ -54,19 +51,22 @@ public:
|
||||
nsATSUIToolkit();
|
||||
~nsATSUIToolkit() {};
|
||||
|
||||
void PrepareToDraw(PRBool aFontOrColorChanged, nsGraphicState* aGS, GrafPtr aPort, nsIDeviceContext* aContext);
|
||||
|
||||
NS_IMETHOD GetWidth(const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth, PRInt32 *aFontID);
|
||||
NS_IMETHOD DrawString(const PRUnichar *aString, PRUint32 aLength, nscoord aX, nscoord aY, PRInt32 aFontID, const nscoord* aSpacing);
|
||||
void PrepareToDraw(GrafPtr aPort, nsIDeviceContext* aContext);
|
||||
|
||||
NS_IMETHOD GetWidth(const PRUnichar *aCharPt, short &oWidth,
|
||||
short aSize, short fontNum, PRBool aBold, PRBool aItalic, nscolor aColor);
|
||||
NS_IMETHOD DrawString(const PRUnichar *aCharPt, PRInt32 x, PRInt32 y, short &oWidth,
|
||||
short aSize, short fontNum, PRBool aBold, PRBool aItalic, nscolor aColor);
|
||||
|
||||
private:
|
||||
ATSUTextLayout GetTextLayout();
|
||||
void StartDraw(const PRUnichar *aCharPt, short aSize, short fontNum, PRBool aBold, PRBool aItalic, nscolor aColor,
|
||||
GrafPtr& oSavePort, ATSUTextLayout& oLayout);
|
||||
void EndDraw(GrafPtr aSavePort);
|
||||
ATSUTextLayout GetTextLayout(short aFontNum, short aSize, PRBool aBold, PRBool aItalic, nscolor aColor);
|
||||
|
||||
private:
|
||||
ATSUTextLayout mLastTextLayout;
|
||||
PRBool mFontOrColorChanged;
|
||||
nsGraphicState* mGS;
|
||||
GrafPtr mPort;
|
||||
GrafPtr mPort;
|
||||
|
||||
nsIDeviceContext* mContext;
|
||||
};
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "nsFontMetricsMac.h"
|
||||
#include "nsDeviceContextMac.h"
|
||||
#include "nsUnicodeFontMappingMac.h"
|
||||
|
||||
static NS_DEFINE_IID(kIFontMetricsIID, NS_IFONT_METRICS_IID);
|
||||
|
||||
@ -31,6 +32,7 @@ nsFontMetricsMac :: nsFontMetricsMac()
|
||||
NS_INIT_REFCNT();
|
||||
mFont = nsnull;
|
||||
mFontNum = BAD_FONT_NUM;
|
||||
mFontMapping = nsnull;
|
||||
}
|
||||
|
||||
nsFontMetricsMac :: ~nsFontMetricsMac()
|
||||
@ -85,6 +87,18 @@ NS_IMETHODIMP nsFontMetricsMac :: Init(const nsFont& aFont, nsIDeviceContext* aC
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsUnicodeFontMappingMac* nsFontMetricsMac :: GetUnicodeFontMapping()
|
||||
{
|
||||
// we should pass the documentCharset from the nsIDocument level and
|
||||
// the lang attribute from the tag level to here.
|
||||
// XXX hard code to some value till peterl pass them down.
|
||||
nsAutoString lang("de, zh_TW, ja, fr");
|
||||
nsAutoString documentCharset("ISO-8859-1");
|
||||
if(! mFontMapping)
|
||||
mFontMapping = nsUnicodeFontMappingMac::GetCachedInstance(mFont, mContext,documentCharset, lang);
|
||||
return mFontMapping;
|
||||
}
|
||||
|
||||
|
||||
static void MapGenericFamilyToFont(const nsString& aGenericFamily, nsString& aFontFace)
|
||||
{
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "nsUnitConversion.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
#include "nsCRT.h"
|
||||
class nsUnicodeFontMappingMac;
|
||||
|
||||
class nsFontMetricsMac : public nsIFontMetrics
|
||||
{
|
||||
@ -54,17 +55,19 @@ public:
|
||||
NS_IMETHOD GetWidths(const nscoord *&aWidths);
|
||||
NS_IMETHOD GetFont(const nsFont *&aFont);
|
||||
NS_IMETHOD GetFontHandle(nsFontHandle& aHandle);
|
||||
|
||||
virtual nsresult GetSpaceWidth(nscoord &aSpaceWidth);
|
||||
|
||||
// fill a native TextStyle record with the font, size and style (not color)
|
||||
static void GetNativeTextStyle(nsIFontMetrics& inMetrics,
|
||||
const nsIDeviceContext& inDevContext, TextStyle &outStyle);
|
||||
|
||||
|
||||
nsUnicodeFontMappingMac* GetUnicodeFontMapping();
|
||||
|
||||
protected:
|
||||
void RealizeFont();
|
||||
|
||||
short mFontNum;
|
||||
nsUnicodeFontMappingMac *mFontMapping;
|
||||
nscoord mHeight;
|
||||
nscoord mAscent;
|
||||
nscoord mDescent;
|
||||
|
@ -15,6 +15,7 @@
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "nsRenderingContextMac.h"
|
||||
#include "nsDeviceContextMac.h"
|
||||
@ -33,12 +34,13 @@
|
||||
#include <FixMath.h>
|
||||
#include <Gestalt.h>
|
||||
|
||||
#define STACK_TREASHOLD 1000
|
||||
|
||||
#define DrawingSurface nsDrawingSurfaceMac
|
||||
|
||||
static NS_DEFINE_IID(kRenderingContextIID, NS_IRENDERING_CONTEXT_IID);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
nsRenderingContextMac::nsRenderingContextMac()
|
||||
{
|
||||
@ -55,7 +57,7 @@ nsRenderingContextMac::nsRenderingContextMac()
|
||||
mGS = nsnull;
|
||||
|
||||
mGSStack = new nsVoidArray();
|
||||
|
||||
|
||||
mChanges = kFontChanged | kColorChanged;
|
||||
}
|
||||
|
||||
@ -718,9 +720,9 @@ NS_IMETHODIMP nsRenderingContextMac :: SetColor(nscolor aColor)
|
||||
thecolor.blue = COLOR8TOCOLOR16(NS_GET_B(aColor));
|
||||
::RGBForeColor(&thecolor);
|
||||
mGS->mColor = aColor ;
|
||||
|
||||
|
||||
mChanges |= kColorChanged;
|
||||
|
||||
|
||||
EndDraw();
|
||||
return NS_OK;
|
||||
}
|
||||
@ -759,8 +761,8 @@ NS_IMETHODIMP nsRenderingContextMac :: SetFont(const nsFont& aFont)
|
||||
|
||||
if (mContext)
|
||||
mContext->GetMetricsFor(aFont, mGS->mFontMetrics);
|
||||
mChanges |= kFontChanged;
|
||||
|
||||
mChanges |= kFontChanged;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -771,7 +773,7 @@ NS_IMETHODIMP nsRenderingContextMac :: SetFont(nsIFontMetrics *aFontMetrics)
|
||||
NS_IF_RELEASE(mGS->mFontMetrics);
|
||||
mGS->mFontMetrics = aFontMetrics;
|
||||
NS_IF_ADDREF(mGS->mFontMetrics);
|
||||
mChanges |= kFontChanged;
|
||||
mChanges |= kFontChanged;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1112,7 +1114,6 @@ NS_IMETHODIMP nsRenderingContextMac :: FillArc(nscoord aX, nscoord aY, nscoord a
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
@ -1183,53 +1184,30 @@ nsRenderingContextMac :: GetWidth(const char* aString, PRUint32 aLength, nscoord
|
||||
|
||||
NS_IMETHODIMP nsRenderingContextMac :: GetWidth(const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth, PRInt32 *aFontID)
|
||||
{
|
||||
// First, let's try to convert the Unicode string to MacRoman
|
||||
// and measure it as a C-string by using QuickDraw
|
||||
StartDraw();
|
||||
nsresult res = NS_OK;
|
||||
res = SetPortTextState();
|
||||
if(NS_FAILED(res))
|
||||
goto end_of_func;
|
||||
|
||||
nsresult res = NS_OK;
|
||||
char buffer[500];
|
||||
char* buf = (aLength <= 500 ? buffer : new char[aLength]);
|
||||
if (!buf)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_PRECONDITION(mGS->mFontMetrics != nsnull, "No font metrics in SetPortTextState");
|
||||
|
||||
if (nsnull == mGS->mFontMetrics) {
|
||||
res = NS_ERROR_NULL_POINTER;
|
||||
goto end_of_func;
|
||||
}
|
||||
res = mUnicodeRenderingToolkit.PrepareToDraw(mP2T, mContext, mGS,mPort);
|
||||
if(NS_SUCCEEDED(res))
|
||||
res = mUnicodeRenderingToolkit.GetWidth(aString, aLength, aWidth, aFontID);
|
||||
|
||||
end_of_func:
|
||||
EndDraw();
|
||||
return res;
|
||||
|
||||
PRBool isMacRomanFont = PR_TRUE; // XXX we need to set up this value latter.
|
||||
PRBool useQD = nsATSUIUtils::ConvertToMacRoman(aString, aLength, buf, ! isMacRomanFont);
|
||||
|
||||
if (useQD)
|
||||
res = GetWidth(buf, aLength, aWidth);
|
||||
|
||||
if (buf != buffer)
|
||||
delete[] buf;
|
||||
|
||||
if (useQD)
|
||||
return res;
|
||||
|
||||
|
||||
// If the string cannot be converted to MacRoman, let's draw it by using ATSUI.
|
||||
// If ATSUI is not available, measure the C-string without conversion.
|
||||
|
||||
if (nsATSUIUtils::IsAvailable())
|
||||
{
|
||||
mATSUIToolkit.PrepareToDraw((mChanges & (kFontChanged | kColorChanged) != 0), mGS, mPort, mContext);
|
||||
res = mATSUIToolkit.GetWidth(aString, aLength, aWidth, aFontID);
|
||||
}
|
||||
else
|
||||
{
|
||||
// XXX Unicode Broken!!! We should use TEC here to convert Unicode to different script run
|
||||
nsString nsStr;
|
||||
nsStr.SetString(aString, aLength);
|
||||
char* cStr = nsStr.ToNewCString();
|
||||
|
||||
res = GetWidth(cStr, aLength, aWidth);
|
||||
|
||||
delete[] cStr;
|
||||
if (nsnull != aFontID)
|
||||
*aFontID = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma mark -
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
@ -1261,8 +1239,8 @@ NS_IMETHODIMP nsRenderingContextMac :: DrawString(const char *aString, PRUint32
|
||||
::DrawText(aString,0,aLength);
|
||||
else
|
||||
{
|
||||
int buffer[500];
|
||||
int* spacing = (aLength <= 500 ? buffer : new int[aLength]);
|
||||
int buffer[STACK_TREASHOLD];
|
||||
int* spacing = (aLength <= STACK_TREASHOLD ? buffer : new int[aLength]);
|
||||
if (spacing)
|
||||
{
|
||||
mGS->mTMatrix->ScaleXCoords(aSpacing, aLength, spacing);
|
||||
@ -1286,54 +1264,33 @@ NS_IMETHODIMP nsRenderingContextMac :: DrawString(const char *aString, PRUint32
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
NS_IMETHODIMP nsRenderingContextMac :: DrawString(const PRUnichar *aString, PRUint32 aLength,
|
||||
nscoord aX, nscoord aY, PRInt32 aFontID,
|
||||
const nscoord* aSpacing)
|
||||
{
|
||||
// First, let's try to convert the Unicode string to MacRoman
|
||||
// and draw it as a C-string by using QuickDraw
|
||||
|
||||
nsresult res = NS_OK;
|
||||
char buffer[500];
|
||||
char* buf = (aLength <= 500 ? buffer : new char[aLength]);
|
||||
if (!buf)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
StartDraw();
|
||||
|
||||
PRBool isMacRomanFont = PR_TRUE; // XXX we need to set up this value latter.
|
||||
PRBool useQD = nsATSUIUtils::ConvertToMacRoman(aString, aLength, buf, ! isMacRomanFont);
|
||||
nsresult res = NS_OK;
|
||||
res = SetPortTextState();
|
||||
if(NS_FAILED(res))
|
||||
goto end_of_func;
|
||||
|
||||
if (useQD)
|
||||
res = DrawString(buf, aLength, aX, aY, aSpacing);
|
||||
NS_PRECONDITION(mGS->mFontMetrics != nsnull, "No font metrics in SetPortTextState");
|
||||
|
||||
if (nsnull == mGS->mFontMetrics) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
goto end_of_func;
|
||||
}
|
||||
res = mUnicodeRenderingToolkit.PrepareToDraw(mP2T, mContext, mGS,mPort);
|
||||
if(NS_SUCCEEDED(res))
|
||||
res = mUnicodeRenderingToolkit.DrawString(aString, aLength, aX, aY, aFontID, aSpacing);
|
||||
|
||||
if (buf != buffer)
|
||||
delete[] buf;
|
||||
end_of_func:
|
||||
|
||||
if (useQD)
|
||||
return res;
|
||||
|
||||
|
||||
// If the string cannot be converted to MacRoman, let's draw it by using ATSUI.
|
||||
// If ATSUI is not available, draw the C-string without conversion.
|
||||
|
||||
if (nsATSUIUtils::IsAvailable())
|
||||
{
|
||||
mATSUIToolkit.PrepareToDraw((mChanges & (kFontChanged | kColorChanged) != 0), mGS, mPort, mContext);
|
||||
res = mATSUIToolkit.DrawString(aString, aLength, aX, aY, aFontID, aSpacing);
|
||||
}
|
||||
else
|
||||
{
|
||||
// XXX Unicode Broken!!! We should use TEC here to convert Unicode to different script run
|
||||
nsString nsStr;
|
||||
nsStr.SetString(aString, aLength);
|
||||
char* cStr = nsStr.ToNewCString();
|
||||
|
||||
res = DrawString(cStr, aLength, aX, aY, aSpacing);
|
||||
|
||||
delete[] cStr;
|
||||
}
|
||||
return res;
|
||||
EndDraw();
|
||||
return res;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
@ -21,8 +21,9 @@
|
||||
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsDrawingSurfaceMac.h"
|
||||
#include "nsATSUIUtils.h"
|
||||
#include "nsUnicodeRenderingToolkit.h"
|
||||
#include <QDOffscreen.h>
|
||||
#include <UnicodeConverter.h>
|
||||
|
||||
class nsIFontMetrics;
|
||||
class nsIDeviceContext;
|
||||
@ -33,10 +34,11 @@ class nsVoidArray;
|
||||
|
||||
class nsGraphicState;
|
||||
class DrawingSurface; // a surface is a combination of a port and a graphic state
|
||||
|
||||
class nsUnicodeFallbackCache;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
class nsRenderingContextMac : public nsIRenderingContext
|
||||
{
|
||||
public:
|
||||
@ -137,13 +139,12 @@ protected:
|
||||
{
|
||||
::SetPort(mOldPort);
|
||||
}
|
||||
typedef enum {
|
||||
kFontChanged = (1 << 0),
|
||||
kColorChanged = (1 << 1)
|
||||
} styleChanges;
|
||||
|
||||
|
||||
typedef enum {
|
||||
kFontChanged = (1 << 0),
|
||||
kColorChanged = (1 << 1)
|
||||
} styleChanges;
|
||||
|
||||
|
||||
protected:
|
||||
float mP2T; // Pixel to Twip conversion factor
|
||||
@ -157,10 +158,9 @@ protected:
|
||||
|
||||
GrafPtr mPort; // current grafPort - shortcut for mCurrentSurface->GetPort()
|
||||
nsGraphicState * mGS; // current graphic state - shortcut for mCurrentSurface->GetGS()
|
||||
|
||||
nsUnicodeRenderingToolkit mUnicodeRenderingToolkit;
|
||||
nsVoidArray * mGSStack; // GraphicStates stack, used for PushState/PopState
|
||||
PRInt8 mChanges;
|
||||
nsATSUIToolkit mATSUIToolkit;
|
||||
};
|
||||
|
||||
|
||||
|
@ -22,14 +22,14 @@
|
||||
#include <UnicodeConverter.h>
|
||||
class nsUnicodeFallbackCache;
|
||||
class nsIDeviceContext;
|
||||
class GraphicState;
|
||||
class nsGraphicState;
|
||||
|
||||
class nsUnicodeRenderingToolkit
|
||||
{
|
||||
nsUnicodeRenderingToolkit() {};
|
||||
~nsUnicodeRenderingToolkit() {};
|
||||
public:
|
||||
NS_IMETHOD PrepareToDraw(float aP2T, nsIDeviceContext* aContext, GraphicState* aGS, GrafPtr aPort);
|
||||
NS_IMETHOD PrepareToDraw(float aP2T, nsIDeviceContext* aContext, nsGraphicState* aGS, GrafPtr aPort);
|
||||
NS_IMETHOD GetWidth(const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth,
|
||||
PRInt32 *aFontID);
|
||||
NS_IMETHOD DrawString(const PRUnichar *aString, PRUint32 aLength, nscoord aX, nscoord aY,
|
||||
@ -61,7 +61,7 @@ private:
|
||||
private:
|
||||
float mP2T; // Pixel to Twip conversion factor
|
||||
nsIDeviceContext * mContext;
|
||||
GraphicState * mGS; // current graphic state - shortcut for mCurrentSurface->GetGS()
|
||||
nsGraphicState * mGS; // current graphic state - shortcut for mCurrentSurface->GetGS()
|
||||
|
||||
GrafPtr mPort; // current grafPort - shortcut for mCurrentSurface->GetPort()
|
||||
nsATSUIToolkit mATSUIToolkit;
|
||||
|
Loading…
Reference in New Issue
Block a user