<rdar://problem/9084761> REGRESSION (r73993): Default Arabic line spacing has gotten...
[WebKit-https.git] / Source / WebCore / platform / graphics / mac / SimpleFontDataMac.mm
index 29fb9a07b44ab1d0246dcbac27bc90188c7bfb4e..f34d53bc369d1fb2b57fbbff3a9128481a4827c5 100644 (file)
@@ -241,6 +241,7 @@ void SimpleFontData::platformInit()
     NSString *familyName = [m_platformData.font() familyName];
     if ([familyName isEqualToString:@"Times"] || [familyName isEqualToString:@"Helvetica"] || [familyName isEqualToString:@"Courier"])
         ascent += floorf(((ascent + descent) * 0.15f) + 0.5f);
     NSString *familyName = [m_platformData.font() familyName];
     if ([familyName isEqualToString:@"Times"] || [familyName isEqualToString:@"Helvetica"] || [familyName isEqualToString:@"Courier"])
         ascent += floorf(((ascent + descent) * 0.15f) + 0.5f);
+#if defined(BUILDING_ON_LEOPARD)
     else if ([familyName isEqualToString:@"Geeza Pro"]) {
         // Geeza Pro has glyphs that draw slightly above the ascent or far below the descent. Adjust
         // those vertical metrics to better match reality, so that diacritics at the bottom of one line
     else if ([familyName isEqualToString:@"Geeza Pro"]) {
         // Geeza Pro has glyphs that draw slightly above the ascent or far below the descent. Adjust
         // those vertical metrics to better match reality, so that diacritics at the bottom of one line
@@ -248,6 +249,7 @@ void SimpleFontData::platformInit()
         ascent *= 1.08f;
         descent *= 2.f;
     }
         ascent *= 1.08f;
         descent *= 2.f;
     }
+#endif
 
     // Compute and store line spacing, before the line metrics hacks are applied.
     m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
 
     // Compute and store line spacing, before the line metrics hacks are applied.
     m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
@@ -259,49 +261,32 @@ void SimpleFontData::platformInit()
         descent = 3;
     }
     
         descent = 3;
     }
     
-    if (m_orientation == Vertical) {
-        // Ignore vertical orientation when the font doesn't support vertical metrics.
+    if (platformData().orientation() == Vertical && !isTextOrientationFallback()) {
         // The check doesn't look neat but this is what AppKit does for vertical writing...
         RetainPtr<CFArrayRef> tableTags(AdoptCF, CTFontCopyAvailableTables(m_platformData.ctFont(), kCTFontTableOptionExcludeSynthetic));
         CFIndex numTables = CFArrayGetCount(tableTags.get());
         // The check doesn't look neat but this is what AppKit does for vertical writing...
         RetainPtr<CFArrayRef> tableTags(AdoptCF, CTFontCopyAvailableTables(m_platformData.ctFont(), kCTFontTableOptionExcludeSynthetic));
         CFIndex numTables = CFArrayGetCount(tableTags.get());
-        bool found = false;
         for (CFIndex index = 0; index < numTables; ++index) {
             CTFontTableTag tag = (CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(tableTags.get(), index);
             if (tag == kCTFontTableVhea || tag == kCTFontTableVORG) {
         for (CFIndex index = 0; index < numTables; ++index) {
             CTFontTableTag tag = (CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(tableTags.get(), index);
             if (tag == kCTFontTableVhea || tag == kCTFontTableVORG) {
-                found = true;
+                m_hasVerticalGlyphs = true;
                 break;
             }
         }
                 break;
             }
         }
-
-        if (found == false)
-            m_orientation = Horizontal;
     }
 
     float xHeight;
 
     }
 
     float xHeight;
 
-    // Measure the actual character "x", because AppKit synthesizes X height rather than getting it from the font.
-    // Unfortunately, NSFont will round this for us so we don't quite get the right value.
-    GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
-    NSGlyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0;
-    if (xGlyph) {
-        CGRect xBox = platformBoundsForGlyph(xGlyph);
-        // Use the maximum of either width or height because "x" is nearly square
-        // and web pages that foolishly use this metric for width will be laid out
-        // poorly if we return an accurate height. Classic case is Times 13 point,
-        // which has an "x" that is 7x6 pixels.
-        xHeight = static_cast<float>(max(CGRectGetMaxX(xBox), -CGRectGetMinY(xBox)));
-    } else {
-#ifndef BUILDING_ON_TIGER
-        xHeight = static_cast<float>(CGFontGetXHeight(m_platformData.cgFont())) / unitsPerEm;
-#else
-        xHeight = m_platformData.font() ? [m_platformData.font() xHeight] : 0;
-#endif
-        // CGFontGetXHeight() returns a wrong value for "Apple Symbols" font (a float close to 0, but not strictly 0).
-        // The following code makes a guess for xHeight in that case.
-        // The int cast is a workaround for the "almost" zero value returned by CGFontGetXHeight().
-        if (!static_cast<int>(xHeight) && ascent)
-            xHeight = 2 * ascent / 3;
-    }
+    if (platformData().orientation() == Horizontal) {
+        // Measure the actual character "x", since it's possible for it to extend below the baseline, and we need the
+        // reported x-height to only include the portion of the glyph that is above the baseline.
+        GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
+        NSGlyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0;
+        if (xGlyph)
+            xHeight = -CGRectGetMinY(platformBoundsForGlyph(xGlyph));
+        else
+            xHeight = scaleEmToUnits(CGFontGetXHeight(m_platformData.cgFont()), unitsPerEm) * pointSize;
+    } else
+        xHeight = verticalRightOrientationFontData()->fontMetrics().xHeight();
 
     m_fontMetrics.setUnitsPerEm(unitsPerEm);
     m_fontMetrics.setAscent(ascent);
 
     m_fontMetrics.setUnitsPerEm(unitsPerEm);
     m_fontMetrics.setAscent(ascent);
@@ -394,7 +379,7 @@ SimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescri
 
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
     float size = m_platformData.size() * scaleFactor;
 
     BEGIN_BLOCK_OBJC_EXCEPTIONS;
     float size = m_platformData.size() * scaleFactor;
-    FontPlatformData scaledFontData([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toSize:size], size);
+    FontPlatformData scaledFontData([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toSize:size], size, false, false, m_platformData.orientation());
 
     // AppKit resets the type information (screen/printer) when you convert a font to a different size.
     // We have to fix up the font that we're handed back.
 
     // AppKit resets the type information (screen/printer) when you convert a font to a different size.
     // We have to fix up the font that we're handed back.
@@ -474,17 +459,8 @@ void SimpleFontData::determinePitch()
 FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
 {
     FloatRect boundingBox;
 FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
 {
     FloatRect boundingBox;
-#ifndef BUILDING_ON_TIGER
-    boundingBox = CTFontGetBoundingRectsForGlyphs(m_platformData.ctFont(),
-                    orientation() == Vertical ? kCTFontVerticalOrientation : kCTFontHorizontalOrientation, &glyph, 0, 1);
-    boundingBox.setY(-boundingBox.bottom());
-#else
-    // FIXME: Custom fonts don't have NSFonts, so this function doesn't compute correct bounds for these on Tiger.
-    if (!m_platformData.font())
-        return boundingBox;
-    boundingBox = [m_platformData.font() boundingRectForGlyph:glyph];
-    boundingBox.setY(-boundingBox.bottom());
-#endif
+    boundingBox = CTFontGetBoundingRectsForGlyphs(m_platformData.ctFont(), platformData().orientation() == Vertical ? kCTFontVerticalOrientation : kCTFontHorizontalOrientation, &glyph, 0, 1);
+    boundingBox.setY(-boundingBox.maxY());
     if (m_syntheticBoldOffset)
         boundingBox.setWidth(boundingBox.width() + m_syntheticBoldOffset);
 
     if (m_syntheticBoldOffset)
         boundingBox.setWidth(boundingBox.width() + m_syntheticBoldOffset);
 
@@ -494,7 +470,7 @@ FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
 float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
 {
     CGSize advance;
 float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
 {
     CGSize advance;
-    if (orientation() == Horizontal || m_isBrokenIdeographFont) {
+    if (platformData().orientation() == Horizontal || m_isBrokenIdeographFallback) {
         NSFont* font = platformData().font();
         float pointSize = platformData().m_size;
         CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
         NSFont* font = platformData().font();
         float pointSize = platformData().m_size;
         CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);