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:
ftang%netscape.com 1999-05-12 22:30:10 +00:00
parent e11fb63db9
commit 6339be6419
8 changed files with 275 additions and 420 deletions

Binary file not shown.

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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)
{

View File

@ -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;

View File

@ -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;
}
//------------------------------------------------------------------------

View File

@ -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;
};

View File

@ -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;