fix bug 128263. let ATSUI to render Unicode surrogate characters. r=nhotta sr=sfraser

This commit is contained in:
ftang%netscape.com 2002-08-16 00:54:03 +00:00
Родитель 712b0456f7
Коммит df9eacc272
4 изменённых файлов: 136 добавлений и 19 удалений

Просмотреть файл

@ -374,7 +374,8 @@ void nsATSUIToolkit::PrepareToDraw(CGrafPtr aPort, nsIDeviceContext* aContext)
//
//------------------------------------------------------------------------
void nsATSUIToolkit::StartDraw(
const PRUnichar *aCharPt,
const PRUnichar *aCharPt,
PRUint32 aLen,
short aSize, short aFontNum,
PRBool aBold, PRBool aItalic, nscolor aColor, ATSUTextLayout& oLayout)
{
@ -390,7 +391,7 @@ void nsATSUIToolkit::StartDraw(
// text here, we should explicitly invalidate any existing caches
::ATSUClearLayoutCache(oLayout, kATSUFromTextBeginning);
err = ATSUSetTextPointerLocation( oLayout, (ConstUniCharArrayPtr)aCharPt, 0, 1, 1);
err = ::ATSUSetTextPointerLocation( oLayout, (ConstUniCharArrayPtr)aCharPt, 0, aLen, aLen);
if (noErr != err) {
NS_WARNING("ATSUSetTextPointerLocation failed");
oLayout = nsnull;
@ -404,7 +405,8 @@ void nsATSUIToolkit::StartDraw(
//------------------------------------------------------------------------
nsresult
nsATSUIToolkit::GetTextDimensions(
const PRUnichar *aCharPt,
const PRUnichar *aCharPt,
PRUint32 aLen,
nsTextDimensions& oDim,
short aSize, short aFontNum,
PRBool aBold, PRBool aItalic, nscolor aColor)
@ -415,7 +417,7 @@ nsATSUIToolkit::GetTextDimensions(
StPortSetter setter(mPort);
ATSUTextLayout aTxtLayout;
StartDraw(aCharPt, aSize, aFontNum, aBold, aItalic, aColor, aTxtLayout);
StartDraw(aCharPt, aLen, aSize, aFontNum, aBold, aItalic, aColor, aTxtLayout);
if (nsnull == aTxtLayout)
return NS_ERROR_FAILURE;
@ -423,7 +425,7 @@ nsATSUIToolkit::GetTextDimensions(
ATSUTextMeasurement after;
ATSUTextMeasurement ascent;
ATSUTextMeasurement descent;
err = ATSUMeasureText(aTxtLayout, 0, 1, NULL, &after, &ascent, &descent);
err = ::ATSUMeasureText(aTxtLayout, 0, aLen, NULL, &after, &ascent, &descent);
if (noErr != err)
{
NS_WARNING("ATSUMeasureText failed");
@ -445,6 +447,7 @@ nsATSUIToolkit::GetTextDimensions(
nsresult
nsATSUIToolkit::GetBoundingMetrics(
const PRUnichar *aCharPt,
PRUint32 aLen,
nsBoundingMetrics &oBoundingMetrics,
short aSize, short aFontNum,
PRBool aBold, PRBool aItalic,
@ -456,7 +459,7 @@ nsATSUIToolkit::GetBoundingMetrics(
StPortSetter setter(mPort);
ATSUTextLayout aTxtLayout;
StartDraw(aCharPt, aSize, aFontNum, aBold, aItalic, aColor, aTxtLayout);
StartDraw(aCharPt, aLen, aSize, aFontNum, aBold, aItalic, aColor, aTxtLayout);
if(nsnull == aTxtLayout)
return NS_ERROR_FAILURE;
@ -496,6 +499,7 @@ nsATSUIToolkit::GetBoundingMetrics(
nsresult
nsATSUIToolkit::DrawString(
const PRUnichar *aCharPt,
PRUint32 aLen,
PRInt32 x, PRInt32 y,
short &oWidth,
short aSize, short aFontNum,
@ -509,19 +513,19 @@ nsATSUIToolkit::DrawString(
ATSUTextLayout aTxtLayout;
StartDraw(aCharPt, aSize, aFontNum, aBold, aItalic, aColor, aTxtLayout);
StartDraw(aCharPt, aLen, aSize, aFontNum, aBold, aItalic, aColor, aTxtLayout);
if (nsnull == aTxtLayout)
return NS_ERROR_FAILURE;
OSStatus err = noErr;
ATSUTextMeasurement iAfter;
err = ATSUMeasureText( aTxtLayout, 0, 1, NULL, &iAfter, NULL, NULL );
err = ::ATSUMeasureText( aTxtLayout, 0, aLen, NULL, &iAfter, NULL, NULL );
if (noErr != err) {
NS_WARNING("ATSUMeasureText failed");
return NS_ERROR_FAILURE;
}
err = ATSUDrawText(aTxtLayout, 0, 1, Long2Fix(x), Long2Fix(y));
err = ::ATSUDrawText(aTxtLayout, 0, aLen, Long2Fix(x), Long2Fix(y));
if (noErr != err) {
NS_WARNING("ATSUDrawText failed");
return NS_ERROR_FAILURE;

Просмотреть файл

@ -74,20 +74,20 @@ public:
void PrepareToDraw(CGrafPtr aPort, nsIDeviceContext* aContext);
nsresult GetTextDimensions(const PRUnichar *aCharPt, nsTextDimensions &oDim,
nsresult GetTextDimensions(const PRUnichar *aCharPt, PRUint32 aLen, nsTextDimensions &oDim,
short aSize, short fontNum, PRBool aBold,
PRBool aItalic, nscolor aColor);
nsresult DrawString(const PRUnichar *aCharPt, PRInt32 x, PRInt32 y, short &oWidth,
nsresult DrawString(const PRUnichar *aCharPt, PRUint32 aLen, PRInt32 x, PRInt32 y, short &oWidth,
short aSize, short fontNum, PRBool aBold, PRBool aItalic,
nscolor aColor);
#ifdef MOZ_MATHML
nsresult GetBoundingMetrics(const PRUnichar *aCharPt, nsBoundingMetrics &aBoundingMetrics,
nsresult GetBoundingMetrics(const PRUnichar *aCharPt, PRUint32 aLen, nsBoundingMetrics &aBoundingMetrics,
short aSize, short fontNum, PRBool aBold,
PRBool aItalic, nscolor aColor);
#endif // MOZ_MATHML
private:
void StartDraw(const PRUnichar *aCharPt, short aSize, short fontNum, PRBool aBold,
void StartDraw(const PRUnichar *aCharPt, PRUint32 aLen, short aSize, short fontNum, PRBool aBold,
PRBool aItalic, nscolor aColor, ATSUTextLayout& oLayout);
ATSUTextLayout GetTextLayout(short aFontNum, short aSize, PRBool aBold,

Просмотреть файл

@ -46,6 +46,8 @@
#include "nsCarbonHelpers.h"
#include "nsISaveAsCharset.h"
#include "nsIComponentManager.h"
#include "nsUnicharUtils.h"
#include "nsMacUnicodeFontInfo.h"
#include "nsICharRepresentable.h"
@ -420,13 +422,13 @@ nsUnicodeRenderingToolkit::ATSUIFallbackGetDimensions(
rep = (*aCharPt) - 0x2325;
else
rep = (*aCharPt) - 0x2308;
res = mATSUIToolkit.GetTextDimensions(gSymbolReplacement+rep, oDim, aSize,
res = mATSUIToolkit.GetTextDimensions(gSymbolReplacement+rep, 1, oDim, aSize,
origFontNum,
aBold, aItalic, aColor);
}
else
{
res = mATSUIToolkit.GetTextDimensions(aCharPt, oDim, aSize,
res = mATSUIToolkit.GetTextDimensions(aCharPt, 1, oDim, aSize,
origFontNum,
aBold, aItalic, aColor);
}
@ -495,13 +497,13 @@ nsUnicodeRenderingToolkit::ATSUIFallbackGetBoundingMetrics(
rep = (*aCharPt) - 0x2325;
else
rep = (*aCharPt) - 0x2308;
res = mATSUIToolkit.GetBoundingMetrics(gSymbolReplacement+rep, oBoundingMetrics, aSize,
res = mATSUIToolkit.GetBoundingMetrics(gSymbolReplacement+rep, 1, oBoundingMetrics, aSize,
origFontNum,
aBold, aItalic, aColor);
}
else
{
res = mATSUIToolkit.GetBoundingMetrics(aCharPt, oBoundingMetrics, aSize,
res = mATSUIToolkit.GetBoundingMetrics(aCharPt, 1, oBoundingMetrics, aSize,
origFontNum,
aBold, aItalic, aColor);
}
@ -570,11 +572,11 @@ PRBool nsUnicodeRenderingToolkit :: ATSUIFallbackDrawChar(
rep = (*aCharPt) - 0x2325;
else
rep = (*aCharPt) - 0x2308;
res = mATSUIToolkit.DrawString(gSymbolReplacement+rep, x, y, oWidth, aSize,
res = mATSUIToolkit.DrawString(gSymbolReplacement+rep, 1, x, y, oWidth, aSize,
origFontNum,
aBold, aItalic, aColor);
} else {
res = mATSUIToolkit.DrawString(aCharPt, x, y, oWidth, aSize,
res = mATSUIToolkit.DrawString(aCharPt, 1, x, y, oWidth, aSize,
origFontNum,
aBold, aItalic, aColor);
}
@ -613,6 +615,45 @@ PRBool nsUnicodeRenderingToolkit :: ATSUIFallbackDrawChar(
return PR_FALSE;
}
PRBool nsUnicodeRenderingToolkit :: SurrogateGetDimensions(
const PRUnichar *aSurrogatePt, nsTextDimensions& oDim, short origFontNum,
short aSize, PRBool aBold, PRBool aItalic, nscolor aColor)
{
nsresult res;
mATSUIToolkit.PrepareToDraw(mPort, mContext );
res = mATSUIToolkit.GetTextDimensions(aSurrogatePt, 2, oDim, aSize,
origFontNum,
aBold, aItalic, aColor);
return NS_SUCCEEDED(res);
}
PRBool nsUnicodeRenderingToolkit :: SurrogateDrawChar(
const PRUnichar *aSurrogatePt, PRInt32 x, PRInt32 y, short& oWidth, short origFontNum,
short aSize, PRBool aBold, PRBool aItalic, nscolor aColor)
{
nsresult res;
mATSUIToolkit.PrepareToDraw(mPort, mContext );
res = mATSUIToolkit.DrawString(aSurrogatePt, 2, x, y, oWidth, aSize,
origFontNum,
aBold, aItalic, aColor);
return NS_SUCCEEDED(res);
}
#ifdef MOZ_MATHML
PRBool nsUnicodeRenderingToolkit :: SurrogateGetBoundingMetrics(
const PRUnichar *aSurrogatePt, nsBoundingMetrics& oBoundingMetrics, short origFontNum,
short aSize, PRBool aBold, PRBool aItalic, nscolor aColor)
{
nsresult res;
mATSUIToolkit.PrepareToDraw(mPort, mContext );
res = mATSUIToolkit.GetBoundingMetrics(aSurrogatePt, 2, oBoundingMetrics, aSize,
origFontNum,
aBold, aItalic, aColor);
return NS_SUCCEEDED(res);
}
#endif
static const char question[] = "<?>";
//------------------------------------------------------------------------
@ -1275,6 +1316,27 @@ nsUnicodeRenderingToolkit::GetTextSegmentDimensions(
PRBool fallbackDone = PR_FALSE;
segDim.Clear();
if (IS_HIGH_SURROGATE(*aString) &&
((processLen+1) < aLength) &&
IS_LOW_SURROGATE(*(aString+1)))
{
const nsFont *font;
mGS->mFontMetrics->GetFont(font);
fallbackDone = SurrogateGetDimensions(aString, segDim, fontNum,
font->size,
(font->weight > NS_FONT_WEIGHT_NORMAL),
((NS_FONT_STYLE_ITALIC == font->style) ||
(NS_FONT_STYLE_OBLIQUE == font->style)),
mGS->mColor );
if (fallbackDone)
{
oDim.Combine(segDim);
// for fallback measure/drawing, we always do one char a time.
aString += 2;
processLen += 2;
continue;
}
}
#ifndef DISABLE_TEC_FALLBACK
// Fallback by try different Script code
if (! IS_SKIP_TEC_FALLBACK(*aString))
@ -1441,6 +1503,31 @@ nsUnicodeRenderingToolkit::GetTextSegmentBoundingMetrics(
PRBool fallbackDone = PR_FALSE;
segBoundingMetrics.Clear();
if (IS_HIGH_SURROGATE(*aString) &&
((processLen+1) < aLength) &&
IS_LOW_SURROGATE(*(aString+1)) )
{
const nsFont *font;
mGS->mFontMetrics->GetFont(font);
fallbackDone = SurrogateGetBoundingMetrics(aString, segBoundingMetrics, fontNum,
font->size,
(font->weight > NS_FONT_WEIGHT_NORMAL),
((NS_FONT_STYLE_ITALIC == font->style) ||
(NS_FONT_STYLE_OBLIQUE == font->style)),
mGS->mColor );
if (fallbackDone)
{
if (firstTime) {
firstTime = PR_FALSE;
oBoundingMetrics = segBoundingMetrics;
}
else
oBoundingMetrics += segBoundingMetrics;
aString += 2;
processLen += 2;
continue;
}
}
#ifndef DISABLE_TEC_FALLBACK
if (! IS_SKIP_TEC_FALLBACK(*aString))
fallbackDone = TECFallbackGetBoundingMetrics(aString, segBoundingMetrics, fontNum, fontMapping);
@ -1558,6 +1645,26 @@ nsresult nsUnicodeRenderingToolkit :: DrawTextSegment(
{
PRBool fallbackDone = PR_FALSE;
if (IS_HIGH_SURROGATE(*aString) &&
((processLen+1) < aLength) &&
IS_LOW_SURROGATE(*(aString+1)) )
{
const nsFont *font;
mGS->mFontMetrics->GetFont(font);
fallbackDone = SurrogateDrawChar(aString, x, y, thisWidth, fontNum,
font->size,
(font->weight > NS_FONT_WEIGHT_NORMAL),
((NS_FONT_STYLE_ITALIC == font->style) || (NS_FONT_STYLE_OBLIQUE == font->style)),
mGS->mColor );
if (fallbackDone)
{
textWidth += thisWidth;
x += thisWidth;
aString += 2;
processLen += 2;
continue;
}
}
#ifndef DISABLE_TEC_FALLBACK
// Fallback by try different Script code
if (! IS_SKIP_TEC_FALLBACK(*aString))

Просмотреть файл

@ -84,6 +84,10 @@ private:
short aSize, PRBool aBold, PRBool aItalic, nscolor aColor);
PRBool ATSUIFallbackDrawChar(const PRUnichar *pChar, PRInt32 x, PRInt32 y, short& oWidth, short fontNum,
short aSize, PRBool aBold, PRBool aItalic, nscolor aColor);
PRBool SurrogateGetDimensions(const PRUnichar *aSurrogatePt, nsTextDimensions& oWidth, short fontNum,
short aSize, PRBool aBold, PRBool aItalic, nscolor aColor);
PRBool SurrogateDrawChar(const PRUnichar *aSurrogatePt, PRInt32 x, PRInt32 y, short& oWidth, short fontNum,
short aSize, PRBool aBold, PRBool aItalic, nscolor aColor);
PRBool UPlusFallbackGetWidth(const PRUnichar *pChar, short& oWidth);
PRBool UPlusFallbackDrawChar(const PRUnichar *pChar, PRInt32 x, PRInt32 y, short& oWidth);
@ -115,6 +119,8 @@ private:
short fontNum, nsUnicodeFontMappingMac& fontMapping);
PRBool ATSUIFallbackGetBoundingMetrics(const PRUnichar *pChar, nsBoundingMetrics& oBoundingMetrics, short fontNum,
short aSize, PRBool aBold, PRBool aItalic, nscolor aColor);
PRBool SurrogateGetBoundingMetrics(const PRUnichar *aSurrogatePt, nsBoundingMetrics& oBoundingMetrics, short fontNum,
short aSize, PRBool aBold, PRBool aItalic, nscolor aColor);
void GetScriptTextBoundingMetrics(const char* aText, ByteCount aLen, ScriptCode aScript, nsBoundingMetrics& oBoundingMetrics);
nsresult GetTextSegmentBoundingMetrics(const PRUnichar *aString, PRUint32 aLength, short fontNum,
nsUnicodeFontMappingMac& fontMapping, nsBoundingMetrics& oBoundingMetrics);