Sophie

Sophie

distrib > Mandriva > 2007.1 > i586 > media > main-updates-src > by-pkgid > 560a66f8a53021b4b9b753c8581c58a8 > files > 27

mozilla-firefox-2.0.0.13-1.1mdv2007.1.src.rpm

--- mozilla/gfx/src/gtk/nsFontMetricsPango.h.pango-underline	2005-05-02 22:48:30.000000000 +0200
+++ mozilla/gfx/src/gtk/nsFontMetricsPango.h	2006-01-05 11:55:19.000000000 +0100
@@ -90,13 +90,23 @@
                                      { aHeight = mMaxHeight; 
                                        return NS_OK; };
 
+#ifdef FONT_LEADING_APIS_V2
+    NS_IMETHOD GetInternalLeading    (nscoord &aLeading)
+                                     { aLeading = mInternalLeading;
+                                       return NS_OK; };
+
+    NS_IMETHOD GetExternalLeading    (nscoord &aLeading)
+                                     { aLeading = mExternalLeading;
+                                       return NS_OK; };
+#else
     NS_IMETHOD GetNormalLineHeight   (nscoord &aHeight)
-                                     { aHeight = mEmHeight + mLeading;
+                                     { aHeight = mEmHeight + mInternalLeading;
                                        return NS_OK; };
 
     NS_IMETHOD GetLeading            (nscoord &aLeading)
-                                     { aLeading = mLeading; 
+                                     { aLeading = mInternalLeading;
                                        return NS_OK; };
+#endif
 
     NS_IMETHOD GetEmHeight           (nscoord &aHeight)
                                      { aHeight = mEmHeight; 
@@ -252,7 +262,8 @@
     nscoord                  mUnderlineOffset;
     nscoord                  mUnderlineSize;
     nscoord                  mMaxHeight;
-    nscoord                  mLeading;
+    nscoord                  mInternalLeading;
+    nscoord                  mExternalLeading;
     nscoord                  mEmHeight;
     nscoord                  mEmAscent;
     nscoord                  mEmDescent;
--- mozilla/gfx/src/gtk/nsFontMetricsPango.cpp.pango-underline	2006-01-05 11:55:19.000000000 +0100
+++ mozilla/gfx/src/gtk/nsFontMetricsPango.cpp	2006-01-05 18:23:12.000000000 +0100
@@ -68,6 +68,12 @@
 
 static PRLogModuleInfo            *gPangoFontLog;
 static int                         gNumInstances;
+static PRBool                      gDoingLineheightFixup = PR_FALSE;
+static nsIAtom*                    gJA = nsnull;
+static nsIAtom*                    gKO = nsnull;
+static nsIAtom*                    gZHCN = nsnull;
+static nsIAtom*                    gZHTW = nsnull;
+static nsIAtom*                    gZHHK = nsnull;
 
 // Defines
 
@@ -158,6 +164,10 @@
 
 NS_IMPL_ISUPPORTS1(nsFontMetricsPango, nsIFontMetrics)
 
+#define IsCJKLangGroupAtom(a) ((a) == gJA || (a) == gKO || (a) == gZHCN || \
+                               (a) == gZHTW || (a) == gZHHK)
+
+
 // nsIFontMetrics impl
 
 NS_IMETHODIMP
@@ -184,6 +194,41 @@
     prefService = do_GetService(NS_PREF_CONTRACTID);
     if (!prefService)
         return NS_ERROR_FAILURE;
+
+    // if we do not include/compensate external leading in calculating normal 
+    // line height, we don't set gDoingLineheightFixup either to keep old behavior.
+    // These code should be eliminated in future when we choose to stay with 
+    // one normal lineheight calculation method.
+    PRInt32 intPref;
+    if (NS_SUCCEEDED(prefService->GetIntPref(
+        "browser.display.normal_lineheight_calc_control", &intPref)))
+         gDoingLineheightFixup = (intPref != 0);
+
+    gJA = NS_NewAtom("ja");
+    if (!gJA) {
+        FreeGlobals();
+        return NS_ERROR_OUT_OF_MEMORY;
+    }
+    gKO = NS_NewAtom("ko");
+    if (!gKO) {
+        FreeGlobals();
+        return NS_ERROR_OUT_OF_MEMORY;
+    }
+    gZHCN = NS_NewAtom("zh-CN");
+    if (!gZHCN) {
+        FreeGlobals();
+        return NS_ERROR_OUT_OF_MEMORY;
+    }
+    gZHTW = NS_NewAtom("zh-TW");
+    if (!gZHTW) {
+        FreeGlobals();
+        return NS_ERROR_OUT_OF_MEMORY;
+    }
+    gZHHK = NS_NewAtom("zh-HK");
+    if (!gZHHK) {
+        FreeGlobals();
+        return NS_ERROR_OUT_OF_MEMORY;
+    }
         
     nsXPIDLCString value;
     const char* langGroup;
@@ -301,19 +346,26 @@
     val = -MOZ_FT_TRUNC(face->size->metrics.descender);
     mMaxDescent = NSToIntRound(val * f);
 
-    nscoord lineHeight = mMaxAscent + mMaxDescent;
+    // mMaxHeight (needs ascent and descent)
+    mMaxHeight = mMaxAscent + mMaxDescent;
 
-    // mLeading (needs ascent and descent and EM height) 
-    if (lineHeight > mEmHeight)
-        mLeading = lineHeight - mEmHeight;
-    else
-        mLeading = 0;
+    // mExternalLeading (needs MaxHeight and base2base dist. (xftFont->height))
+    val = MOZ_FT_TRUNC (face->size->metrics.height);
+    if (NSToIntRound (val * f) > mMaxHeight) {
+        mExternalLeading = NSToIntRound (val * f) - mMaxHeight;
+    }
+    else {
+        mExternalLeading = 0;
+    }
 
-    // mMaxHeight (needs ascent and descent)
-    mMaxHeight = lineHeight;
+    // mInternalLeading (needs ascent, descent and EM height) 
+    if (mMaxHeight > mEmHeight)
+        mInternalLeading = mMaxHeight - mEmHeight;
+    else
+        mInternalLeading = 0;
 
     // mEmAscent (needs maxascent, EM height, ascent and descent)
-    mEmAscent = nscoord(mMaxAscent * mEmHeight / lineHeight);
+    mEmAscent = nscoord(mMaxAscent * mEmHeight / mMaxHeight);
 
     // mEmDescent (needs EM height and EM ascent
     mEmDescent = mEmHeight - mEmAscent;
@@ -354,29 +406,99 @@
         mXHeight = nscoord(((float)mMaxAscent) * 0.56 * f);
     }
 
-    // mUnderlineOffset (offset for underlines)
-    val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_position,
-                                         face->size->metrics.y_scale);
-    if (val) {
-        mUnderlineOffset = NSToIntRound(val * f);
+    // mUnderlineSize (thickness of an underline)
+    float rawUlSize = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_thickness, 
+                      face->size->metrics.y_scale);
+    if (rawUlSize) {
+        mUnderlineSize = nscoord(PR_MAX(f, NSToIntRound(rawUlSize * f)));
     }
     else {
-        mUnderlineOffset =
-            -NSToIntRound(PR_MAX(1, floor(0.1 *
-                MOZ_FT_TRUNC(face->size->metrics.height) + 0.5)) * f);
+        val = MOZ_FT_TRUNC(face->size->metrics.height);
+        mUnderlineSize =
+            NSToIntRound(PR_MAX(1, floor(0.05 * val + 0.5)) * f);
     }
 
-    // mUnderlineSize (thickness of an underline)
-    val = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_thickness,
-                                         face->size->metrics.y_scale);
-    if (val) {
-        mUnderlineSize = nscoord(PR_MAX(f, NSToIntRound(val * f)));
+    // mUnderlineOffset (offset for underlines)
+    float rawUlOffset = CONVERT_DESIGN_UNITS_TO_PIXELS(face->underline_position, 
+                        face->size->metrics.y_scale);
+    /*if (PR_LOG_TEST(gXftFontLoad, PR_LOG_DEBUG)) {
+        printf ("raw underline pos=%d, y_scale=%ld, scaled=%f\n",
+            face->underline_position, long(face->size->metrics.y_scale), rawUlOffset);
+    }*/
+    
+    nscoord RaiseBaseline = 0; 
+    if (gDoingLineheightFixup && IsCJKLangGroupAtom(mLangGroup.get())) {
+           nscoord Leading = mInternalLeading + mExternalLeading;
+           val = MOZ_FT_TRUNC (face->size->metrics.height);
+           nscoord rawOffset = rawUlOffset ? NSToIntRound(rawUlOffset * f) :
+                     -NSToIntRound(PR_MAX(1, floor(0.1 * val + 0.5)) * f);
+           nscoord expectOffset = PR_MAX(2 * mUnderlineSize, -rawOffset);
+
+           if (mEmDescent >= (mUnderlineSize + expectOffset)) {
+              mUnderlineOffset = -expectOffset;
+           }
+           else if (mMaxDescent >= (mUnderlineSize + expectOffset)) {
+              mUnderlineOffset = -expectOffset;
+           }
+           else if (mMaxDescent >= 2 * mUnderlineSize + nscoord(f)) {
+              mUnderlineOffset = -mUnderlineSize - nscoord(f);
+           }
+           else if (Leading >= (mUnderlineSize + expectOffset)) { //nead raise baseline 
+              RaiseBaseline = (mUnderlineSize + expectOffset) - mEmDescent;
+              RaiseBaseline = (RaiseBaseline + nscoord(f) - 1)/nscoord(f);
+              mUnderlineOffset = -expectOffset;
+           }
+           else {
+              mExternalLeading += (mUnderlineSize + expectOffset) - Leading;
+              mMaxDescent += (mUnderlineSize + expectOffset) - Leading;
+              mMaxHeight = mMaxAscent + mMaxDescent;
+              val = MOZ_FT_TRUNC (face->size->metrics.height);
+              if (NSToIntRound (val * f) > mMaxHeight) {
+                 mExternalLeading = NSToIntRound (val * f) - mMaxHeight;
+              }
+              else {
+                 mExternalLeading = 0;
+              }
+              if (mMaxHeight > mEmHeight)
+                  mInternalLeading = mMaxHeight - mEmHeight;
+              else
+                  mInternalLeading = 0;
+              mEmAscent = nscoord(mMaxAscent * mEmHeight / mMaxHeight);
+              mEmDescent = mEmHeight - mEmAscent;
+              mUnderlineOffset = -expectOffset;
+           }
+           if (mEmDescent + mUnderlineOffset >= 2*mUnderlineSize)
+               mUnderlineOffset -= mUnderlineSize;
     }
     else {
-        mUnderlineSize =
-            NSToIntRound(PR_MAX(1,
-               floor(0.05 * MOZ_FT_TRUNC(face->size->metrics.height) + 0.5)) * f);
+        if (rawUlOffset) {
+            mUnderlineOffset = NSToIntRound(rawUlOffset * f);
+        }
+        else {
+            val = MOZ_FT_TRUNC (face->size->metrics.height);
+            mUnderlineOffset =
+                -NSToIntRound(PR_MAX(1, floor(0.1 * val + 0.5)) * f);
+        }
     }
+    // The underline position specified in CJK fonts works well for 
+    // Latin letters, but doesn't work as well for CJK characters (see
+    // bug 218032). For CJK characters, the descent position is preferred.
+    // However, we cannot do the adjustment per character basis 
+    // (that would results in a 'zigzaged' undeline). In addition, 
+    // the underline position specified in non-CJK fonts works well
+    // for all glyphs in them so that we should leave it alone.
+    // Therefore, the underline position is adjusted  only if the langGroup
+    // of a font is CJK and enough space available for the adjustment.
+
+    // Baseline need to be raised so that underline will stay 
+    // within boundary. 
+
+    if (RaiseBaseline) {
+        mEmAscent -= RaiseBaseline;
+        mEmDescent += RaiseBaseline;
+        mMaxAscent -= RaiseBaseline;
+        mMaxDescent += RaiseBaseline;
+     }
 
     // mSuperscriptOffset
     if (os2 && os2->ySuperscriptYOffset) {
@@ -1564,6 +1686,11 @@
 void
 FreeGlobals(void)
 {
+    NS_IF_RELEASE(gJA);
+    NS_IF_RELEASE(gKO);
+    NS_IF_RELEASE(gZHCN);
+    NS_IF_RELEASE(gZHTW);
+    NS_IF_RELEASE(gZHHK);
 }
 
 /* static */