From 51b3d234ba699782eded9946d1180c43d34aac0d Mon Sep 17 00:00:00 2001 From: "ftang%netscape.com" Date: Tue, 8 Jan 2002 00:47:02 +0000 Subject: [PATCH] fix bug 117098. sr=sfraser add arabic isolated fallback . in ATSUI fallback, fallback bold/italic form to non bold/italic for arabic font. do not go through QD fallback for Arabic/Hebrew by turn off the converter. remove fake bidi code. git-svn-id: svn://10.0.0.236/trunk@111520 18797224-902f-48f8-a5cc-f745e15eee43 --- .../gfx/src/mac/nsUnicodeRenderingToolkit.cpp | 183 ++++++++++++------ 1 file changed, 127 insertions(+), 56 deletions(-) diff --git a/mozilla/gfx/src/mac/nsUnicodeRenderingToolkit.cpp b/mozilla/gfx/src/mac/nsUnicodeRenderingToolkit.cpp index c0aeec25b07..bea397e5e01 100644 --- a/mozilla/gfx/src/mac/nsUnicodeRenderingToolkit.cpp +++ b/mozilla/gfx/src/mac/nsUnicodeRenderingToolkit.cpp @@ -63,6 +63,9 @@ static NS_DEFINE_CID(kSaveAsCharsetCID, NS_SAVEASCHARSET_CID); //#define DISABLE_TRANSLITERATE_FALLBACK //#define DISABLE_UPLUS_FALLBACK +#define IS_FORMAT_CONTROL_CHARS(c) ((0x2000==((c)&0xFFF0))||(0x2028==((c)&0xFFF8))) +#define IS_CONTEXTUAL_CHARS(c) ((0x0600<=(c))&&((c)<0x1000)) +#define IS_COMBINING_CHARS(c) ((0x0300<=(c))&&((c)<0x0370)) #define QUESTION_FALLBACKSIZE 9 #define UPLUS_FALLBACKSIZE 9 @@ -124,6 +127,10 @@ static NS_DEFINE_CID(kSaveAsCharsetCID, NS_SAVEASCHARSET_CID); ) #define BAD_TEXT_ENCODING 0xFFFFFFFF + + +#define IN_ARABIC_PRESENTATION_B(a) ((0xfe70 <= (a)) && ((a) <= 0xfeff)) + //------------------------------------------------------------------------ static UnicodeToTextInfo gConverters[32] = { nsnull, nsnull, nsnull, nsnull, nsnull, nsnull, nsnull, nsnull, @@ -134,23 +141,28 @@ static UnicodeToTextInfo gConverters[32] = { //------------------------------------------------------------------------ UnicodeToTextInfo nsUnicodeRenderingToolkit :: GetConverterByScript(ScriptCode sc) { + // because the Mac QuickDraw BIDI support are quite different from other platform + // we try not to use them and use the XP BIDI feature + // those text will be drawn by ATSUI intead one character at a time + if ((sc == smArabic) || (sc == smHebrew)) + return nsnull; NS_PRECONDITION(sc < 32, "illegal script id"); - if(sc >= 32) - return nsnull; - if(gConverters[sc] != nsnull) { - return gConverters[sc]; - } - OSStatus err = noErr; + if(sc >= 32) + return nsnull; + if (gConverters[sc] != nsnull) { + return gConverters[sc]; + } + OSStatus err = noErr; - // - TextEncoding scriptEncoding; - err = ::UpgradeScriptInfoToTextEncoding(sc, kTextLanguageDontCare, kTextRegionDontCare, nsnull, &scriptEncoding); - if( noErr == err ) - err = ::CreateUnicodeToTextInfoByEncoding(scriptEncoding, &gConverters[sc] ); + // + TextEncoding scriptEncoding; + err = ::UpgradeScriptInfoToTextEncoding(sc, kTextLanguageDontCare, kTextRegionDontCare, nsnull, &scriptEncoding); + if ( noErr == err ) + err = ::CreateUnicodeToTextInfoByEncoding(scriptEncoding, &gConverters[sc] ); - if(noErr != err) - gConverters[sc] = nsnull; - return gConverters[sc]; + if (noErr != err) + gConverters[sc] = nsnull; + return gConverters[sc]; } //------------------------------------------------------------------------ #pragma mark - @@ -314,6 +326,36 @@ PRBool nsUnicodeRenderingToolkit :: TECFallbackDrawChar( //------------------------------------------------------------------------ static PRUnichar gSymbolReplacement[]={0xf8ee,0xf8f9,0xf8f0,0xf8fb,0x3008,0x3009}; +//------------------------------------------------------------------------ + +static nsresult FormBIsolated(PRUnichar aChar, nsMacUnicodeFontInfo& aInfo, PRUnichar* aOutChar) +{ + static const PRUnichar arabicisolated[]= + { + 0xFE70, 0x064B, 0xFE72, 0x064C, 0xFE74, 0x064D, 0xFE76, 0x064E, 0xFE78, 0x064F, + 0xFE7A, 0x0650, 0xFE7C, 0x0651, 0xFE7E, 0x0652, 0xFE80, 0x0621, 0xFE81, 0x0622, + 0xFE83, 0x0623, 0xFE85, 0x0624, 0xFE87, 0x0625, 0xFE89, 0x0626, 0xFE8D, 0x0627, + 0xFE8F, 0x0628, 0xFE93, 0x0629, 0xFE95, 0x062A, 0xFE99, 0x062B, 0xFE9D, 0x062C, + 0xFEA1, 0x062D, 0xFEA5, 0x062E, 0xFEA9, 0x062F, 0xFEAB, 0x0630, 0xFEAD, 0x0631, + 0xFEAF, 0x0632, 0xFEB1, 0x0633, 0xFEB5, 0x0634, 0xFEB9, 0x0635, 0xFEBD, 0x0636, + 0xFEC1, 0x0637, 0xFEC5, 0x0638, 0xFEC9, 0x0639, 0xFECD, 0x063A, 0xFED1, 0x0641, + 0xFED5, 0x0642, 0xFED9, 0x0643, 0xFEDD, 0x0644, 0xFEE1, 0x0645, 0xFEE5, 0x0646, + 0xFEE9, 0x0647, 0xFEED, 0x0648, 0xFEEF, 0x0649, 0xFEF1, 0x064A, + 0x0000 + }; + const PRUnichar* p; + for ( p= arabicisolated; *p; p += 2) { + if (aChar == *p) { + if (aInfo.HasGlyphFor(*(p+1))) { + *aOutChar = *(p+1); + return NS_OK; + } + } + } + return NS_ERROR_FAILURE; +} +//------------------------------------------------------------------------ + PRBool nsUnicodeRenderingToolkit::ATSUIFallbackGetDimensions( const PRUnichar *aCharPt, @@ -321,6 +363,7 @@ nsUnicodeRenderingToolkit::ATSUIFallbackGetDimensions( short origFontNum, short aSize, PRBool aBold, PRBool aItalic, nscolor aColor) { + nsMacUnicodeFontInfo info; if (nsATSUIUtils::IsAvailable() && (IN_STANDARD_MAC_ROMAN_FONT(*aCharPt) @@ -332,10 +375,10 @@ nsUnicodeRenderingToolkit::ATSUIFallbackGetDimensions( nsresult res; if (SPECIAL_IN_SYMBOL_FONT(*aCharPt)) { - short rep = 0; + short rep = 0; if ((*aCharPt) > 0x230b) rep = (*aCharPt) - 0x2325; - else + else rep = (*aCharPt) - 0x2308; res = mATSUIToolkit.GetTextDimensions(gSymbolReplacement+rep, oDim, aSize, origFontNum, @@ -352,6 +395,37 @@ nsUnicodeRenderingToolkit::ATSUIFallbackGetDimensions( return PR_TRUE; } } + if (IN_ARABIC_PRESENTATION_B(*aCharPt)) + { + PRUnichar isolated; + if (NS_SUCCEEDED( FormBIsolated(*aCharPt, info, &isolated))) + { + if(NS_SUCCEEDED(ATSUIFallbackGetDimensions(&isolated, oDim, origFontNum, + aSize, aBold, aItalic, aColor))) + { + return PR_TRUE; + } + } + } + + // we know some ATSUI font do not have bold, turn it off and try again + if (aBold) + { + if (NS_SUCCEEDED(ATSUIFallbackGetDimensions(aCharPt, oDim, origFontNum, + aSize, PR_FALSE, aItalic, aColor))) + { + return PR_TRUE; + } + } + // we know some ATSUI font do not have italic, turn it off and try again + if (aItalic) + { + if (NS_SUCCEEDED(ATSUIFallbackGetDimensions(aCharPt, oDim, origFontNum, + aSize, PR_FALSE, PR_FALSE, aColor))) + { + return PR_TRUE; + } + } return PR_FALSE; } //------------------------------------------------------------------------ @@ -374,11 +448,11 @@ PRBool nsUnicodeRenderingToolkit :: ATSUIFallbackDrawChar( nsresult res; if(SPECIAL_IN_SYMBOL_FONT(*aCharPt)) { - short rep = 0; - if((*aCharPt) > 0x230b) - rep = (*aCharPt) - 0x2325; - else - rep = (*aCharPt) - 0x2308; + short rep = 0; + if ((*aCharPt) > 0x230b) + rep = (*aCharPt) - 0x2325; + else + rep = (*aCharPt) - 0x2308; res = mATSUIToolkit.DrawString(gSymbolReplacement+rep, x, y, oWidth, aSize, origFontNum, aBold, aItalic, aColor); @@ -387,9 +461,38 @@ PRBool nsUnicodeRenderingToolkit :: ATSUIFallbackDrawChar( origFontNum, aBold, aItalic, aColor); } - if(NS_SUCCEEDED(res)) + if (NS_SUCCEEDED(res)) return PR_TRUE; } + if (IN_ARABIC_PRESENTATION_B(*aCharPt)) + { + PRUnichar isolated; + if (NS_SUCCEEDED( FormBIsolated(*aCharPt, info, &isolated))) { + if (NS_SUCCEEDED(ATSUIFallbackDrawChar(&isolated, x, y, oWidth, origFontNum, + aSize, aBold, aItalic, aColor))) + { + return PR_TRUE; + } + } + } + // we know some ATSUI font do not have bold, turn it off and try again + if (aBold) + { + if (NS_SUCCEEDED(ATSUIFallbackDrawChar(aCharPt, x, y, oWidth, origFontNum, + aSize, PR_FALSE, aItalic, aColor))) + { + return PR_TRUE; + } + } + // we know some ATSUI font do not have italic, turn it off and try again + if (aItalic) + { + if (NS_SUCCEEDED(ATSUIFallbackDrawChar(aCharPt, x, y, oWidth, origFontNum, + aSize, PR_FALSE, PR_FALSE, aColor))) + { + return PR_TRUE; + } + } return PR_FALSE; } static char *question = ""; @@ -1256,9 +1359,6 @@ nsUnicodeRenderingToolkit::GetTextDimensions(const PRUnichar *aString, PRUint32 return res; } -#define IS_FORMAT_CONTROL_CHARS(c) ((0x2000==((c)&0xFFF0))||(0x2028==((c)&0xFFF8))) -#define IS_CONTEXTUAL_CHARS(c) ((0x0600<=(c))&&((c)<0x1000)) -#define IS_COMBINING_CHARS(c) ((0x0300<=(c))&&((c)<0x0370)) //------------------------------------------------------------------------ nsresult @@ -1312,39 +1412,11 @@ nsUnicodeRenderingToolkit::DrawString(const PRUnichar *aString, PRUint32 aLength else // no spacing array { short thisFont, nextFont; - thisFont = fontmap->GetFontID(aString[0]); + PRUint32 start; - if (mRightToLeftText) { - // right to left - for (i = 1, start = 0; i < aLength; i++) - { - PRUnichar uch = aString[aLength - i - 1]; - if(! IS_FORMAT_CONTROL_CHARS(uch)) - { - nextFont = fontmap->GetFontID(uch); - if (thisFont != nextFont) - { - // start new font run... - PRInt32 transformedX = currentX, ignoreY = 0; - mGS->mTMatrix.TransformCoord(&transformedX, &ignoreY); - - res = DrawTextSegment(aString + aLength - i, i-start, thisFont, scriptFallbackFonts, transformedX, transformedY, thisWidth); - if (NS_FAILED(res)) - return res; - - currentX += NSToCoordRound(float(thisWidth) * mP2T); - start = i; - thisFont = nextFont; - } - } - } - - PRInt32 transformedX = currentX, ignoreY = 0; - mGS->mTMatrix.TransformCoord(&transformedX, &ignoreY); - res = DrawTextSegment(aString , aLength-start, thisFont, scriptFallbackFonts, transformedX, transformedY, thisWidth); - } else { // normal left to right + thisFont = fontmap->GetFontID(aString[0]); for (i = 1, start = 0; i < aLength; i++) { PRUnichar uch = aString[i]; @@ -1371,7 +1443,6 @@ nsUnicodeRenderingToolkit::DrawString(const PRUnichar *aString, PRUint32 aLength PRInt32 transformedX = currentX, ignoreY = 0; mGS->mTMatrix.TransformCoord(&transformedX, &ignoreY); res = DrawTextSegment(aString+start, aLength-start, thisFont, scriptFallbackFonts, transformedX, transformedY, thisWidth); - } if (NS_FAILED(res)) return res; }