[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198

zimmermann at webkit.org zimmermann at webkit.org
Sun Feb 20 23:37:59 UTC 2011


The following commit has been merged in the webkit-1.3 branch:
commit e8433ccad66d48b30d4f95bd799b2ab69b010deb
Author: zimmermann at webkit.org <zimmermann at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Sat Jan 22 11:46:23 2011 +0000

    2011-01-21  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Dirk Schulze.
    
            Introduce FontMetrics abstraction
            https://bugs.webkit.org/show_bug.cgi?id=51456
    
            * src/ExternalPopupMenu.cpp: Use FontMetrics instead of Font to access the metrics.
            (WebKit::ExternalPopupMenu::getPopupMenuInfo):
            * src/WebFontImpl.cpp: Ditto.
            (WebKit::WebFontImpl::ascent):
            (WebKit::WebFontImpl::descent):
            (WebKit::WebFontImpl::height):
            (WebKit::WebFontImpl::lineSpacing):
            (WebKit::WebFontImpl::xHeight):
    2011-01-21  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Dirk Schulze.
    
            Introduce FontMetrics abstraction
            https://bugs.webkit.org/show_bug.cgi?id=51456
    
            * FullscreenVideoController.cpp: Use FontMetrics instead of Font to access the metrics.
            (FullscreenVideoController::draw):
            * WebCoreSupport/WebDragClient.cpp: Ditto.
            (WebDragClient::createDragImageForLink):
            * WebKitGraphics.cpp: Ditto.
            (FontMetrics):
    2011-01-21  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Dirk Schulze.
    
            Introduce FontMetrics abstraction
            https://bugs.webkit.org/show_bug.cgi?id=51456
    
            Encapsulate ascent/descent/lineHeight/lineGap methods in a single FontMetrics class, instead of
            having to define them in both Font & SimpleFontData. Changed to store floating point values
            as default, in order to get accurate information for small sized fonts. All these methods
            now have floating-point and integer versions. Whenever an integer variant of these functions
            is called, lroundf() is used to round the value.
    
            This makes it possible to support small font-sizes for SVG in a follow-up patch, as well
            as fixing rounding issues when using SVG Fonts.
    
            Shouldn't affect existing tests.
    
            * GNUmakefile.am: Add FontMetrics.h to build.
            * WebCore.gypi: Ditto.
            * WebCore.pro: Ditto.
            * WebCore.vcproj/WebCore.vcproj: Ditto.
            * WebCore.xcodeproj/project.pbxproj: Ditto.
            * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp: Use style->fontMetrics() instead of style->font() to access the metrics.
            (baselinePositionForAccessibilityRenderObject):
            * css/CSSPrimitiveValue.cpp:
            (WebCore::CSSPrimitiveValue::computeLengthDouble):
            * html/canvas/CanvasRenderingContext2D.cpp: Ditto.
            (WebCore::CanvasRenderingContext2D::drawTextInternal):
            * inspector/InspectorController.cpp: Ditto.
            (WebCore::InspectorController::drawElementTitle):
            * platform/chromium/PopupMenuChromium.cpp: Ditto.
            (WebCore::PopupListBox::paintRow):
            (WebCore::PopupListBox::getRowHeight):
            * platform/graphics/Font.h: Remove ascent/descent/height/lineGap/lineSpacing/xHeight/unitsPerEm accessor...
            (WebCore::Font::fontMetrics): ... and only expose a single FontMetrics object here.
            * platform/graphics/FontFastPath.cpp: Use fontMetrics() to query metrics information.
            (WebCore::Font::emphasisMarkAscent):
            (WebCore::Font::emphasisMarkDescent):
            (WebCore::Font::emphasisMarkHeight):
            (WebCore::Font::floatWidthForSimpleText):
            * platform/graphics/FontMetrics.h: Added.
            (WebCore::FontMetrics::FontMetrics): Creates a FontMetrics object, stored in SimpleFontData.
            (WebCore::FontMetrics::unitsPerEm): Returns an unsigned describing the unitsPerEm.
            (WebCore::FontMetrics::setUnitsPerEm): Sets the unitsPerEm value.
            (WebCore::FontMetrics::floatAscent): Returns the stored m_ascent float.
            (WebCore::FontMetrics::setAscent): Sets the stored m_ascent float.
            (WebCore::FontMetrics::floatDescent): Returns the stored m_descent float.
            (WebCore::FontMetrics::setDescent): Sets the stored m_descent float.
            (WebCore::FontMetrics::floatHeight): Returns floatAscent() + floatDescent().
            (WebCore::FontMetrics::floatLineGap): Returns the stored m_lineGap float.
            (WebCore::FontMetrics::setLineGap): Sets the stored m_lineGap float.
            (WebCore::FontMetrics::floatLineSpacing): Returns the stored m_lineSpacing float.
            (WebCore::FontMetrics::setLineSpacing): Sets the stored m_lineSpacing float.
            (WebCore::FontMetrics::xHeight): Returns the stored m_xHeight float (no integer version available, hence no 'float' prefix).
            (WebCore::FontMetrics::setXHeight): Sets the stored m_xHeight float.
            (WebCore::FontMetrics::ascent): Returns a rounded version of ascent().
            (WebCore::FontMetrics::descent): Ditto (for descent).
            (WebCore::FontMetrics::height): Returns ascent() + descent().
            (WebCore::FontMetrics::lineGap): Returns a rounded version of lineGap().
            (WebCore::FontMetrics::lineSpacing): Ditto (for lineSpacing).
            (WebCore::FontMetrics::reset): Nulls all members, used only by the platform variants of SimpleFontData.
            * platform/graphics/SimpleFontData.cpp: Adapt SVG Fonts code, to initialize the FontMetrics object, as the m_ascent/etc.. members are gone.
            (WebCore::SimpleFontData::SimpleFontData):
            (WebCore::SimpleFontData::initCharWidths):
            * platform/graphics/SimpleFontData.h: Remove ascent/descent/height/lineSpacing/lineGap/xHeight/unitsPerEm accessors, and members, just store a FontMetrics object and expose it.
            (WebCore::SimpleFontData::fontMetrics):
            (WebCore::SimpleFontData::avgCharWidth):
            * platform/graphics/chromium/FontChromiumWin.cpp: Use fontMetrics() to query font metrics.
            (WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::estimateTextBounds):
            (WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::drawGlyphs):
            (WebCore::TransparencyAwareFontPainter::TransparencyAwareUniscribePainter::estimateTextBounds):
            (WebCore::Font::drawComplexText):
            * platform/graphics/chromium/SimpleFontDataChromiumWin.cpp: Adapt platform code, to initialize the FontMetrics object.
            (WebCore::SimpleFontData::platformInit):
            * platform/graphics/chromium/SimpleFontDataLinux.cpp: Ditto.
            (WebCore::SimpleFontData::platformInit):
            * platform/graphics/chromium/UniscribeHelperTextRun.cpp: Use fontMetrics() to query font metrics.
            (WebCore::UniscribeHelperTextRun::UniscribeHelperTextRun):
            (WebCore::UniscribeHelperTextRun::nextWinFontData):
            * platform/graphics/freetype/SimpleFontDataFreeType.cpp: Adapt platform code, to initialize the FontMetrics object.
            (WebCore::SimpleFontData::platformInit):
            * platform/graphics/haiku/SimpleFontDataHaiku.cpp: Ditto.
            (WebCore::SimpleFontData::platformInit):
            * platform/graphics/mac/FontComplexTextMac.cpp: Use fontMetrics() to query font metrics.
            (WebCore::Font::floatWidthForComplexText):
            * platform/graphics/mac/FontMac.mm: Ditto.
            (WebCore::showGlyphsWithAdvances):
            * platform/graphics/mac/SimpleFontDataMac.mm: Adapt platform code, to initialize the FontMetrics object.
            (WebCore::SimpleFontData::platformInit):
            (WebCore::SimpleFontData::platformCharWidthInit):
            * platform/graphics/pango/SimpleFontDataPango.cpp: Ditto.
            (WebCore::SimpleFontData::platformInit):
            * platform/graphics/qt/SimpleFontDataQt.cpp: Ditto. (+ Switch to QFontMetricsF to get floating-point accurancy.)
            (WebCore::SimpleFontData::platformInit):
            * platform/graphics/win/FontCGWin.cpp: Use fontMetrics() to query font metrics.
            (WebCore::drawGDIGlyphs):
            * platform/graphics/win/FontWin.cpp: Ditto.
            (WebCore::Font::floatWidthForComplexText):
            * platform/graphics/win/SimpleFontDataCGWin.cpp: Adapt platform code, to initialize the FontMetrics object.
            (WebCore::SimpleFontData::platformInit):
            (WebCore::SimpleFontData::platformBoundsForGlyph):
            * platform/graphics/win/SimpleFontDataCairoWin.cpp: Ditto.
            (WebCore::SimpleFontData::platformInit):
            * platform/graphics/win/SimpleFontDataWin.cpp: Ditto.
            (WebCore::SimpleFontData::initGDIFont):
            * platform/graphics/wince/GraphicsContextWinCE.cpp: Use fontMetrics() to query font metrics.
            (WebCore::GraphicsContext::drawText):
            * platform/graphics/wince/SimpleFontDataWinCE.cpp: Adapt platform code, to initialize the FontMetrics object.
            (WebCore::SimpleFontData::platformInit):
            * platform/graphics/wx/SimpleFontDataWx.cpp: Ditto.
            (WebCore::SimpleFontData::platformInit):
            * platform/win/PopupMenuWin.cpp: Use style->fontMetrics() instead of style->font() to access the metrics.
            (WebCore::PopupMenuWin::calculatePositionAndSize):
            (WebCore::PopupMenuWin::paint):
            * rendering/EllipsisBox.cpp: Ditto.
            (WebCore::EllipsisBox::paint):
            (WebCore::EllipsisBox::nodeAtPoint):
            * rendering/InlineBox.cpp: Ditto.
            (WebCore::InlineBox::logicalHeight):
            * rendering/InlineFlowBox.cpp: Ditto.
            (WebCore::verticalPositionForBox):
            (WebCore::InlineFlowBox::computeLogicalBoxHeights):
            (WebCore::InlineFlowBox::placeBoxesInBlockDirection):
            * rendering/InlineTextBox.cpp: Ditto.
            (WebCore::InlineTextBox::paint):
            (WebCore::InlineTextBox::paintDecoration):
            (WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
            (WebCore::InlineTextBox::paintCompositionUnderline):
            * rendering/RenderBlock.cpp: Ditto.
            (WebCore::RenderBlock::baselinePosition):
            (WebCore::RenderBlock::firstLineBoxBaseline):
            (WebCore::RenderBlock::lastLineBoxBaseline):
            * rendering/RenderBox.cpp: Ditto.
            (WebCore::RenderBox::localCaretRect):
            * rendering/RenderEmbeddedObject.cpp: Ditto.
            (WebCore::RenderEmbeddedObject::paintReplaced):
            * rendering/RenderImage.cpp: Ditto.
            (WebCore::RenderImage::setImageSizeForAltText):
            (WebCore::RenderImage::paintReplaced):
            * rendering/RenderInline.cpp: Ditto.
            (WebCore::RenderInline::baselinePosition):
            * rendering/RenderListBox.cpp: Ditto.
            (WebCore::RenderListBox::paintItemForeground):
            (WebCore::RenderListBox::itemHeight):
            * rendering/RenderListMarker.cpp: Ditto.
            (WebCore::RenderListMarker::paint):
            (WebCore::RenderListMarker::layout):
            (WebCore::RenderListMarker::computePreferredLogicalWidths):
            (WebCore::RenderListMarker::updateMargins):
            (WebCore::RenderListMarker::getRelativeMarkerRect):
            * rendering/RenderTextControl.cpp: Ditto.
            (WebCore::RenderTextControl::paintPlaceholder):
            * rendering/RenderTextControlSingleLine.cpp: Ditto.
            (WebCore::RenderTextControlSingleLine::createInnerTextStyle):
            * rendering/RenderThemeWin.cpp: Ditto.
            (WebCore::RenderThemeWin::adjustMenuListButtonStyle):
            * rendering/mathml/RenderMathMLFraction.cpp: Ditto.
            (WebCore::RenderMathMLFraction::baselinePosition):
            * rendering/style/RenderStyle.h: Add "const FontMetrics& fontMetrics() const" accessor.
            (WebCore::InheritedFlags::fontMetrics):
            (WebCore::InheritedFlags::computedLineHeight):
            * rendering/svg/RenderSVGInlineText.cpp: Use style->fontMetrics() instead of style->font() to access the metrics.
            (WebCore::RenderSVGInlineText::positionForPoint):
            * rendering/svg/SVGInlineTextBox.cpp: Ditto.
            (WebCore::SVGInlineTextBox::selectionRectForTextFragment):
            (WebCore::positionOffsetForDecoration):
            (WebCore::SVGInlineTextBox::paintDecorationWithStyle):
            (WebCore::SVGInlineTextBox::paintTextWithShadows):
            (WebCore::SVGInlineTextBox::calculateBoundaries):
            * rendering/svg/SVGTextLayoutEngineBaseline.cpp: Ditto.
            (WebCore::SVGTextLayoutEngineBaseline::calculateBaselineShift):
            (WebCore::SVGTextLayoutEngineBaseline::calculateAlignmentBaselineShift):
            (WebCore::SVGTextLayoutEngineBaseline::calculateGlyphAdvanceAndOrientation):
            * rendering/svg/SVGTextLayoutEngineSpacing.cpp: Ditto.
            (WebCore::SVGTextLayoutEngineSpacing::calculateSVGKerning):
            * rendering/svg/SVGTextMetrics.cpp: Ditto.
            (WebCore::SVGTextMetrics::SVGTextMetrics):
            * rendering/svg/SVGTextQuery.cpp: Ditto.
            (WebCore::calculateGlyphBoundaries):
            * svg/SVGFontFaceElement.cpp:
            (WebCore::SVGFontFaceElement::unitsPerEm): Rename defaultUnitsPerEm global to gDefaultUnitsPerEm.
            * svg/SVGLength.cpp: Use style->fontMetrics() instead of style->font() to access the metrics.
            (WebCore::SVGLength::convertValueFromUserUnitsToEXS):
            (WebCore::SVGLength::convertValueFromEXSToUserUnits):
    2011-01-21  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Dirk Schulze.
    
            Introduce FontMetrics abstraction
            https://bugs.webkit.org/show_bug.cgi?id=51456
    
            * WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp: Use FontMetrics instead of Font to access the metrics.
            (WebKit::WebPopupMenu::setUpPlatformData):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76442 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index b663c82..5ef4539 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,189 @@
+2011-01-21  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        Introduce FontMetrics abstraction
+        https://bugs.webkit.org/show_bug.cgi?id=51456
+
+        Encapsulate ascent/descent/lineHeight/lineGap methods in a single FontMetrics class, instead of
+        having to define them in both Font & SimpleFontData. Changed to store floating point values
+        as default, in order to get accurate information for small sized fonts. All these methods
+        now have floating-point and integer versions. Whenever an integer variant of these functions
+        is called, lroundf() is used to round the value.
+
+        This makes it possible to support small font-sizes for SVG in a follow-up patch, as well
+        as fixing rounding issues when using SVG Fonts.
+        
+        Shouldn't affect existing tests.
+
+        * GNUmakefile.am: Add FontMetrics.h to build. 
+        * WebCore.gypi: Ditto.
+        * WebCore.pro: Ditto.
+        * WebCore.vcproj/WebCore.vcproj: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp: Use style->fontMetrics() instead of style->font() to access the metrics.
+        (baselinePositionForAccessibilityRenderObject):
+        * css/CSSPrimitiveValue.cpp:         
+        (WebCore::CSSPrimitiveValue::computeLengthDouble):
+        * html/canvas/CanvasRenderingContext2D.cpp: Ditto.
+        (WebCore::CanvasRenderingContext2D::drawTextInternal):
+        * inspector/InspectorController.cpp: Ditto.
+        (WebCore::InspectorController::drawElementTitle):
+        * platform/chromium/PopupMenuChromium.cpp: Ditto.
+        (WebCore::PopupListBox::paintRow):
+        (WebCore::PopupListBox::getRowHeight):
+        * platform/graphics/Font.h: Remove ascent/descent/height/lineGap/lineSpacing/xHeight/unitsPerEm accessor...
+        (WebCore::Font::fontMetrics): ... and only expose a single FontMetrics object here.
+        * platform/graphics/FontFastPath.cpp: Use fontMetrics() to query metrics information.
+        (WebCore::Font::emphasisMarkAscent):
+        (WebCore::Font::emphasisMarkDescent):
+        (WebCore::Font::emphasisMarkHeight):
+        (WebCore::Font::floatWidthForSimpleText):
+        * platform/graphics/FontMetrics.h: Added.
+        (WebCore::FontMetrics::FontMetrics): Creates a FontMetrics object, stored in SimpleFontData.
+        (WebCore::FontMetrics::unitsPerEm): Returns an unsigned describing the unitsPerEm.
+        (WebCore::FontMetrics::setUnitsPerEm): Sets the unitsPerEm value.
+        (WebCore::FontMetrics::floatAscent): Returns the stored m_ascent float.
+        (WebCore::FontMetrics::setAscent): Sets the stored m_ascent float.
+        (WebCore::FontMetrics::floatDescent): Returns the stored m_descent float.
+        (WebCore::FontMetrics::setDescent): Sets the stored m_descent float.
+        (WebCore::FontMetrics::floatHeight): Returns floatAscent() + floatDescent().
+        (WebCore::FontMetrics::floatLineGap): Returns the stored m_lineGap float.
+        (WebCore::FontMetrics::setLineGap): Sets the stored m_lineGap float.
+        (WebCore::FontMetrics::floatLineSpacing): Returns the stored m_lineSpacing float.
+        (WebCore::FontMetrics::setLineSpacing): Sets the stored m_lineSpacing float.
+        (WebCore::FontMetrics::xHeight): Returns the stored m_xHeight float (no integer version available, hence no 'float' prefix).
+        (WebCore::FontMetrics::setXHeight): Sets the stored m_xHeight float.
+        (WebCore::FontMetrics::ascent): Returns a rounded version of ascent().
+        (WebCore::FontMetrics::descent): Ditto (for descent).
+        (WebCore::FontMetrics::height): Returns ascent() + descent().
+        (WebCore::FontMetrics::lineGap): Returns a rounded version of lineGap().
+        (WebCore::FontMetrics::lineSpacing): Ditto (for lineSpacing).
+        (WebCore::FontMetrics::reset): Nulls all members, used only by the platform variants of SimpleFontData.
+        * platform/graphics/SimpleFontData.cpp: Adapt SVG Fonts code, to initialize the FontMetrics object, as the m_ascent/etc.. members are gone.
+        (WebCore::SimpleFontData::SimpleFontData):
+        (WebCore::SimpleFontData::initCharWidths):
+        * platform/graphics/SimpleFontData.h: Remove ascent/descent/height/lineSpacing/lineGap/xHeight/unitsPerEm accessors, and members, just store a FontMetrics object and expose it.
+        (WebCore::SimpleFontData::fontMetrics):
+        (WebCore::SimpleFontData::avgCharWidth):
+        * platform/graphics/chromium/FontChromiumWin.cpp: Use fontMetrics() to query font metrics.
+        (WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::estimateTextBounds):
+        (WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::drawGlyphs):
+        (WebCore::TransparencyAwareFontPainter::TransparencyAwareUniscribePainter::estimateTextBounds):
+        (WebCore::Font::drawComplexText):
+        * platform/graphics/chromium/SimpleFontDataChromiumWin.cpp: Adapt platform code, to initialize the FontMetrics object.
+        (WebCore::SimpleFontData::platformInit):
+        * platform/graphics/chromium/SimpleFontDataLinux.cpp: Ditto.
+        (WebCore::SimpleFontData::platformInit):
+        * platform/graphics/chromium/UniscribeHelperTextRun.cpp: Use fontMetrics() to query font metrics.
+        (WebCore::UniscribeHelperTextRun::UniscribeHelperTextRun):
+        (WebCore::UniscribeHelperTextRun::nextWinFontData):
+        * platform/graphics/freetype/SimpleFontDataFreeType.cpp: Adapt platform code, to initialize the FontMetrics object.
+        (WebCore::SimpleFontData::platformInit):
+        * platform/graphics/haiku/SimpleFontDataHaiku.cpp: Ditto.
+        (WebCore::SimpleFontData::platformInit):
+        * platform/graphics/mac/FontComplexTextMac.cpp: Use fontMetrics() to query font metrics.
+        (WebCore::Font::floatWidthForComplexText):
+        * platform/graphics/mac/FontMac.mm: Ditto.
+        (WebCore::showGlyphsWithAdvances):
+        * platform/graphics/mac/SimpleFontDataMac.mm: Adapt platform code, to initialize the FontMetrics object.
+        (WebCore::SimpleFontData::platformInit):
+        (WebCore::SimpleFontData::platformCharWidthInit):
+        * platform/graphics/pango/SimpleFontDataPango.cpp: Ditto.
+        (WebCore::SimpleFontData::platformInit):
+        * platform/graphics/qt/SimpleFontDataQt.cpp: Ditto. (+ Switch to QFontMetricsF to get floating-point accurancy.)
+        (WebCore::SimpleFontData::platformInit):
+        * platform/graphics/win/FontCGWin.cpp: Use fontMetrics() to query font metrics.
+        (WebCore::drawGDIGlyphs):
+        * platform/graphics/win/FontWin.cpp: Ditto.
+        (WebCore::Font::floatWidthForComplexText):
+        * platform/graphics/win/SimpleFontDataCGWin.cpp: Adapt platform code, to initialize the FontMetrics object.
+        (WebCore::SimpleFontData::platformInit):
+        (WebCore::SimpleFontData::platformBoundsForGlyph):
+        * platform/graphics/win/SimpleFontDataCairoWin.cpp: Ditto.
+        (WebCore::SimpleFontData::platformInit):
+        * platform/graphics/win/SimpleFontDataWin.cpp: Ditto.
+        (WebCore::SimpleFontData::initGDIFont):
+        * platform/graphics/wince/GraphicsContextWinCE.cpp: Use fontMetrics() to query font metrics.
+        (WebCore::GraphicsContext::drawText):
+        * platform/graphics/wince/SimpleFontDataWinCE.cpp: Adapt platform code, to initialize the FontMetrics object.
+        (WebCore::SimpleFontData::platformInit):
+        * platform/graphics/wx/SimpleFontDataWx.cpp: Ditto.
+        (WebCore::SimpleFontData::platformInit):
+        * platform/win/PopupMenuWin.cpp: Use style->fontMetrics() instead of style->font() to access the metrics.
+        (WebCore::PopupMenuWin::calculatePositionAndSize): 
+        (WebCore::PopupMenuWin::paint):
+        * rendering/EllipsisBox.cpp: Ditto.
+        (WebCore::EllipsisBox::paint):
+        (WebCore::EllipsisBox::nodeAtPoint):
+        * rendering/InlineBox.cpp: Ditto.
+        (WebCore::InlineBox::logicalHeight):
+        * rendering/InlineFlowBox.cpp: Ditto.
+        (WebCore::verticalPositionForBox):
+        (WebCore::InlineFlowBox::computeLogicalBoxHeights):
+        (WebCore::InlineFlowBox::placeBoxesInBlockDirection):
+        * rendering/InlineTextBox.cpp: Ditto.
+        (WebCore::InlineTextBox::paint):
+        (WebCore::InlineTextBox::paintDecoration):
+        (WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
+        (WebCore::InlineTextBox::paintCompositionUnderline):
+        * rendering/RenderBlock.cpp: Ditto.
+        (WebCore::RenderBlock::baselinePosition):
+        (WebCore::RenderBlock::firstLineBoxBaseline):
+        (WebCore::RenderBlock::lastLineBoxBaseline):
+        * rendering/RenderBox.cpp: Ditto.
+        (WebCore::RenderBox::localCaretRect):
+        * rendering/RenderEmbeddedObject.cpp: Ditto.
+        (WebCore::RenderEmbeddedObject::paintReplaced):
+        * rendering/RenderImage.cpp: Ditto.
+        (WebCore::RenderImage::setImageSizeForAltText):
+        (WebCore::RenderImage::paintReplaced):
+        * rendering/RenderInline.cpp: Ditto.
+        (WebCore::RenderInline::baselinePosition):
+        * rendering/RenderListBox.cpp: Ditto.
+        (WebCore::RenderListBox::paintItemForeground):
+        (WebCore::RenderListBox::itemHeight):
+        * rendering/RenderListMarker.cpp: Ditto.
+        (WebCore::RenderListMarker::paint):
+        (WebCore::RenderListMarker::layout):
+        (WebCore::RenderListMarker::computePreferredLogicalWidths):
+        (WebCore::RenderListMarker::updateMargins):
+        (WebCore::RenderListMarker::getRelativeMarkerRect):
+        * rendering/RenderTextControl.cpp: Ditto.
+        (WebCore::RenderTextControl::paintPlaceholder):
+        * rendering/RenderTextControlSingleLine.cpp: Ditto.
+        (WebCore::RenderTextControlSingleLine::createInnerTextStyle):
+        * rendering/RenderThemeWin.cpp: Ditto.
+        (WebCore::RenderThemeWin::adjustMenuListButtonStyle):
+        * rendering/mathml/RenderMathMLFraction.cpp: Ditto.
+        (WebCore::RenderMathMLFraction::baselinePosition):
+        * rendering/style/RenderStyle.h: Add "const FontMetrics& fontMetrics() const" accessor.
+        (WebCore::InheritedFlags::fontMetrics):
+        (WebCore::InheritedFlags::computedLineHeight):
+        * rendering/svg/RenderSVGInlineText.cpp: Use style->fontMetrics() instead of style->font() to access the metrics.
+        (WebCore::RenderSVGInlineText::positionForPoint):
+        * rendering/svg/SVGInlineTextBox.cpp: Ditto.
+        (WebCore::SVGInlineTextBox::selectionRectForTextFragment):
+        (WebCore::positionOffsetForDecoration):
+        (WebCore::SVGInlineTextBox::paintDecorationWithStyle):
+        (WebCore::SVGInlineTextBox::paintTextWithShadows):
+        (WebCore::SVGInlineTextBox::calculateBoundaries):
+        * rendering/svg/SVGTextLayoutEngineBaseline.cpp: Ditto.
+        (WebCore::SVGTextLayoutEngineBaseline::calculateBaselineShift):
+        (WebCore::SVGTextLayoutEngineBaseline::calculateAlignmentBaselineShift):
+        (WebCore::SVGTextLayoutEngineBaseline::calculateGlyphAdvanceAndOrientation):
+        * rendering/svg/SVGTextLayoutEngineSpacing.cpp: Ditto.
+        (WebCore::SVGTextLayoutEngineSpacing::calculateSVGKerning):
+        * rendering/svg/SVGTextMetrics.cpp: Ditto.
+        (WebCore::SVGTextMetrics::SVGTextMetrics):
+        * rendering/svg/SVGTextQuery.cpp: Ditto.
+        (WebCore::calculateGlyphBoundaries):
+        * svg/SVGFontFaceElement.cpp: 
+        (WebCore::SVGFontFaceElement::unitsPerEm): Rename defaultUnitsPerEm global to gDefaultUnitsPerEm.
+        * svg/SVGLength.cpp: Use style->fontMetrics() instead of style->font() to access the metrics.
+        (WebCore::SVGLength::convertValueFromUserUnitsToEXS):
+        (WebCore::SVGLength::convertValueFromEXSToUserUnits):
+
 2011-01-22  Ryosuke Niwa  <rniwa at webkit.org>
 
         Reviewed by Eric Seidel.
diff --git a/Source/WebCore/GNUmakefile.am b/Source/WebCore/GNUmakefile.am
index 0975094..c312af1 100644
--- a/Source/WebCore/GNUmakefile.am
+++ b/Source/WebCore/GNUmakefile.am
@@ -2402,6 +2402,7 @@ webcore_sources += \
 	Source/WebCore/platform/graphics/FontFamily.h \
 	Source/WebCore/platform/graphics/FontFastPath.cpp \
 	Source/WebCore/platform/graphics/Font.h \
+	Source/WebCore/platform/graphics/FontMetrics.h \
 	Source/WebCore/platform/graphics/FontOrientation.h \
 	Source/WebCore/platform/graphics/FontRenderingMode.h \
 	Source/WebCore/platform/graphics/FontSelector.h \
diff --git a/Source/WebCore/WebCore.gypi b/Source/WebCore/WebCore.gypi
index ca52804..0a418e6 100644
--- a/Source/WebCore/WebCore.gypi
+++ b/Source/WebCore/WebCore.gypi
@@ -2907,6 +2907,7 @@
             'platform/graphics/FontFamily.cpp',
             'platform/graphics/FontFamily.h',
             'platform/graphics/FontFastPath.cpp',
+            'platform/graphics/FontMetrics.h',
             'platform/graphics/FontRenderingMode.h',
             'platform/graphics/FontSelector.h',
             'platform/graphics/FontSmoothingMode.h',
diff --git a/Source/WebCore/WebCore.pro b/Source/WebCore/WebCore.pro
index 7b953f3..de4ec77 100644
--- a/Source/WebCore/WebCore.pro
+++ b/Source/WebCore/WebCore.pro
@@ -2117,6 +2117,7 @@ HEADERS += \
     platform/graphics/FontData.h \
     platform/graphics/FontDescription.h \
     platform/graphics/FontFamily.h \
+    platform/graphics/FontMetrics.h \
     platform/graphics/Font.h \
     platform/graphics/GeneratedImage.h \
     platform/graphics/Gradient.h \
diff --git a/Source/WebCore/WebCore.vcproj/WebCore.vcproj b/Source/WebCore/WebCore.vcproj/WebCore.vcproj
index f1da922..f3550c7 100755
--- a/Source/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/Source/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -26549,6 +26549,10 @@
 					>
 				</File>
 				<File
+					RelativePath="..\platform\graphics\FontMetrics.h"
+					>
+				</File>
+				<File
 					RelativePath="..\platform\graphics\FontRenderingMode.h"
 					>
 				</File>
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index 4f01530..4cf6439 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -102,6 +102,7 @@
 		083DAEA70F01A7FB00342754 /* RenderTextControlMultiLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 083DAEA30F01A7FB00342754 /* RenderTextControlMultiLine.h */; };
 		083DAEA80F01A7FB00342754 /* RenderTextControlSingleLine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 083DAEA40F01A7FB00342754 /* RenderTextControlSingleLine.cpp */; };
 		083DAEA90F01A7FB00342754 /* RenderTextControlSingleLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 083DAEA50F01A7FB00342754 /* RenderTextControlSingleLine.h */; };
+		0845680812B90DA600960A9F /* FontMetrics.h in Headers */ = {isa = PBXBuildFile; fileRef = 0845680712B90DA600960A9F /* FontMetrics.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		084A0829128D7867002DB1F1 /* SVGPathSegListPropertyTearOff.h in Headers */ = {isa = PBXBuildFile; fileRef = 084A0828128D7867002DB1F1 /* SVGPathSegListPropertyTearOff.h */; };
 		084AEBE40FB505FA0038483E /* SelectElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 084AEBE20FB505FA0038483E /* SelectElement.cpp */; };
 		084AEBE50FB505FA0038483E /* SelectElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 084AEBE30FB505FA0038483E /* SelectElement.h */; };
@@ -6416,6 +6417,7 @@
 		083DAEA30F01A7FB00342754 /* RenderTextControlMultiLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTextControlMultiLine.h; sourceTree = "<group>"; };
 		083DAEA40F01A7FB00342754 /* RenderTextControlSingleLine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTextControlSingleLine.cpp; sourceTree = "<group>"; };
 		083DAEA50F01A7FB00342754 /* RenderTextControlSingleLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTextControlSingleLine.h; sourceTree = "<group>"; };
+		0845680712B90DA600960A9F /* FontMetrics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontMetrics.h; sourceTree = "<group>"; };
 		084A0828128D7867002DB1F1 /* SVGPathSegListPropertyTearOff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGPathSegListPropertyTearOff.h; sourceTree = "<group>"; };
 		084AEBE20FB505FA0038483E /* SelectElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectElement.cpp; sourceTree = "<group>"; };
 		084AEBE30FB505FA0038483E /* SelectElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectElement.h; sourceTree = "<group>"; };
@@ -17459,6 +17461,7 @@
 				B2C3DA580D006CD600EF6F26 /* FontFamily.cpp */,
 				B2C3DA590D006CD600EF6F26 /* FontFamily.h */,
 				72626E010EF022FE00A07E20 /* FontFastPath.cpp */,
+				0845680712B90DA600960A9F /* FontMetrics.h */,
 				F7A034C3126BF6BE007DC19E /* FontOrientation.h */,
 				37ACCE410DA2980F0089E602 /* FontRenderingMode.h */,
 				B2C3DA5A0D006CD600EF6F26 /* FontSelector.h */,
@@ -20630,6 +20633,7 @@
 				B2C3DA680D006CD600EF6F26 /* FontFallbackList.h in Headers */,
 				B2C3DA6A0D006CD600EF6F26 /* FontFamily.h in Headers */,
 				A80E6CF30A1989CA007FB8C5 /* FontFamilyValue.h in Headers */,
+				0845680812B90DA600960A9F /* FontMetrics.h in Headers */,
 				F7A034C4126BF6BE007DC19E /* FontOrientation.h in Headers */,
 				B5320D6B122A24E9002D1440 /* FontPlatformData.h in Headers */,
 				37ACCE420DA2980F0089E602 /* FontRenderingMode.h in Headers */,
diff --git a/Source/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp b/Source/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
index 7489034..692decd 100644
--- a/Source/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
+++ b/Source/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
@@ -1230,8 +1230,8 @@ static int baselinePositionForAccessibilityRenderObject(RenderObject* renderObje
     // FIXME: This implementation of baselinePosition originates from RenderObject.cpp and was
     // removed in r70072. The implementation looks incorrect though, because this is not the
     // baseline of the underlying RenderObject, but of the AccessibilityRenderObject.
-    const Font& f = renderObject->firstLineStyle()->font();
-    return f.ascent() + (renderObject->firstLineStyle()->computedLineHeight() - f.height()) / 2;
+    const FontMetrics& fontMetrics = renderObject->firstLineStyle()->fontMetrics();
+    return fontMetrics.ascent() + (renderObject->firstLineStyle()->computedLineHeight() - fontMetrics.height()) / 2;
 }
 
 static AtkAttributeSet* getAttributeSetForAccessibilityObject(const AccessibilityObject* object)
diff --git a/Source/WebCore/css/CSSPrimitiveValue.cpp b/Source/WebCore/css/CSSPrimitiveValue.cpp
index ce1b87b..4fffc76 100644
--- a/Source/WebCore/css/CSSPrimitiveValue.cpp
+++ b/Source/WebCore/css/CSSPrimitiveValue.cpp
@@ -400,7 +400,7 @@ double CSSPrimitiveValue::computeLengthDouble(RenderStyle* style, RenderStyle* r
             // We really need to compute EX using fontMetrics for the original specifiedSize and not use
             // our actual constructed rendering font.
             applyZoomMultiplier = false;
-            factor = style->font().xHeight();
+            factor = style->fontMetrics().xHeight();
             break;
         case CSS_REMS:
             applyZoomMultiplier = false;
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index e029128..e87deaa 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -1760,7 +1760,8 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
         return;
 
     const Font& font = accessFont();
-    
+    const FontMetrics& fontMetrics = font.fontMetrics();
+
     // FIXME: Handle maxWidth.
     // FIXME: Need to turn off font smoothing.
 
@@ -1777,14 +1778,14 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
     switch (state().m_textBaseline) {
     case TopTextBaseline:
     case HangingTextBaseline:
-        location.setY(y + font.ascent());
+        location.setY(y + fontMetrics.ascent());
         break;
     case BottomTextBaseline:
     case IdeographicTextBaseline:
-        location.setY(y - font.descent());
+        location.setY(y - fontMetrics.descent());
         break;
     case MiddleTextBaseline:
-        location.setY(y - font.descent() + font.height() / 2);
+        location.setY(y - fontMetrics.descent() + fontMetrics.height() / 2);
         break;
     case AlphabeticTextBaseline:
     default:
@@ -1812,8 +1813,8 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
     }
 
     // The slop built in to this mask rect matches the heuristic used in FontCGWin.cpp for GDI text.
-    FloatRect textRect = FloatRect(location.x() - font.height() / 2, location.y() - font.ascent() - font.lineGap(),
-                                   width + font.height(), font.lineSpacing());
+    FloatRect textRect = FloatRect(location.x() - fontMetrics.height() / 2, location.y() - fontMetrics.ascent() - fontMetrics.lineGap(),
+                                   width + fontMetrics.height(), fontMetrics.lineSpacing());
     if (!fill)
         textRect.inflate(c->strokeThickness() / 2);
 
diff --git a/Source/WebCore/inspector/InspectorController.cpp b/Source/WebCore/inspector/InspectorController.cpp
index 8533a5f..f57610f 100644
--- a/Source/WebCore/inspector/InspectorController.cpp
+++ b/Source/WebCore/inspector/InspectorController.cpp
@@ -1345,7 +1345,7 @@ void InspectorController::drawElementTitle(GraphicsContext& context, const IntRe
     context.setFillColor(tooltipBackgroundColor, ColorSpaceDeviceRGB);
     context.drawRect(titleRect);
     context.setFillColor(tooltipFontColor, ColorSpaceDeviceRGB);
-    context.drawText(font, nodeTitleRun, IntPoint(titleRect.x() + rectInflatePx, titleRect.y() + font.height()));
+    context.drawText(font, nodeTitleRun, IntPoint(titleRect.x() + rectInflatePx, titleRect.y() + font.fontMetrics().height()));
 }
 
 void InspectorController::openInInspectedWindow(const String& url)
diff --git a/Source/WebCore/platform/chromium/PopupMenuChromium.cpp b/Source/WebCore/platform/chromium/PopupMenuChromium.cpp
index 075cef0..b0e70fd 100644
--- a/Source/WebCore/platform/chromium/PopupMenuChromium.cpp
+++ b/Source/WebCore/platform/chromium/PopupMenuChromium.cpp
@@ -980,7 +980,7 @@ void PopupListBox::paintRow(GraphicsContext* gc, const IntRect& rect, int rowInd
         textX += maxWidth - itemFont.width(textRun);
 
     // Draw the item text.
-    int textY = rowRect.y() + itemFont.ascent() + (rowRect.height() - itemFont.height()) / 2;
+    int textY = rowRect.y() + itemFont.fontMetrics().ascent() + (rowRect.height() - itemFont.fontMetrics().height()) / 2;
     gc->drawBidiText(itemFont, textRun, IntPoint(textX, textY));
 
     // We are using the left padding as the right padding includes room for the scroll-bar which
@@ -1120,7 +1120,7 @@ int PopupListBox::getRowHeight(int index)
     String icon = m_popupClient->itemIcon(index);
     RefPtr<Image> image(Image::loadPlatformResource(icon.utf8().data()));
 
-    int fontHeight = getRowFont(index).height();
+    int fontHeight = getRowFont(index).fontMetrics().height();
     int iconHeight = (image && !image->isNull()) ? image->rect().height() : 0;
 
     return max(fontHeight, iconHeight);
diff --git a/Source/WebCore/platform/graphics/Font.h b/Source/WebCore/platform/graphics/Font.h
index 2957c0a..ac1777a 100644
--- a/Source/WebCore/platform/graphics/Font.h
+++ b/Source/WebCore/platform/graphics/Font.h
@@ -43,7 +43,7 @@ namespace WebCore {
 class FloatPoint;
 class FloatRect;
 class FontData;
-class FontFallbackList;
+class FontMetrics;
 class FontPlatformData;
 class FontSelector;
 class GlyphBuffer;
@@ -54,8 +54,6 @@ class TextRun;
 
 struct GlyphData;
 
-const unsigned defaultUnitsPerEm = 1000;
-
 struct GlyphOverflow {
     GlyphOverflow()
         : left(0)
@@ -128,13 +126,7 @@ public:
     bool isPlatformFont() const { return m_isPlatformFont; }
 
     // Metrics that we query the FontFallbackList for.
-    int ascent(FontBaseline baselineType = AlphabeticBaseline) const { return primaryFont()->ascent(baselineType); }
-    int descent(FontBaseline baselineType = AlphabeticBaseline) const { return primaryFont()->descent(baselineType); }
-    int height() const { return ascent() + descent(); }
-    int lineSpacing() const { return primaryFont()->lineSpacing(); }
-    int lineGap() const { return primaryFont()->lineGap(); }
-    float xHeight() const { return primaryFont()->xHeight(); }
-    unsigned unitsPerEm() const { return primaryFont()->unitsPerEm(); }
+    const FontMetrics& fontMetrics() const { return primaryFont()->fontMetrics(); }
     int spaceWidth() const { return (int)ceilf(primaryFont()->adjustedSpaceWidth() + m_letterSpacing); }
     float tabWidth(const SimpleFontData& fontData) const { return 8 * ceilf(fontData.adjustedSpaceWidth() + letterSpacing()); }
     int emphasisMarkAscent(const AtomicString&) const;
diff --git a/Source/WebCore/platform/graphics/FontFastPath.cpp b/Source/WebCore/platform/graphics/FontFastPath.cpp
index f927c13..72784ed 100644
--- a/Source/WebCore/platform/graphics/FontFastPath.cpp
+++ b/Source/WebCore/platform/graphics/FontFastPath.cpp
@@ -252,7 +252,7 @@ int Font::emphasisMarkAscent(const AtomicString& mark) const
     if (!markFontData)
         return 0;
 
-    return markFontData->ascent();
+    return markFontData->fontMetrics().ascent();
 }
 
 int Font::emphasisMarkDescent(const AtomicString& mark) const
@@ -266,7 +266,7 @@ int Font::emphasisMarkDescent(const AtomicString& mark) const
     if (!markFontData)
         return 0;
 
-    return markFontData->descent();
+    return markFontData->fontMetrics().descent();
 }
 
 int Font::emphasisMarkHeight(const AtomicString& mark) const
@@ -280,7 +280,7 @@ int Font::emphasisMarkHeight(const AtomicString& mark) const
     if (!markFontData)
         return 0;
 
-    return markFontData->height();
+    return markFontData->fontMetrics().height();
 }
 
 float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int to, GlyphBuffer& glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
@@ -414,8 +414,8 @@ float Font::floatWidthForSimpleText(const TextRun& run, GlyphBuffer* glyphBuffer
     it.advance(run.length(), glyphBuffer);
 
     if (glyphOverflow) {
-        glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-it.minGlyphBoundingBoxY()) - ascent());
-        glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(it.maxGlyphBoundingBoxY()) - descent());
+        glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-it.minGlyphBoundingBoxY()) - fontMetrics().ascent());
+        glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(it.maxGlyphBoundingBoxY()) - fontMetrics().descent());
         glyphOverflow->left = ceilf(it.firstGlyphOverflow());
         glyphOverflow->right = ceilf(it.lastGlyphOverflow());
     }
diff --git a/Source/WebCore/platform/graphics/FontMetrics.h b/Source/WebCore/platform/graphics/FontMetrics.h
new file mode 100644
index 0000000..a101cbc
--- /dev/null
+++ b/Source/WebCore/platform/graphics/FontMetrics.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FontMetrics_h
+#define FontMetrics_h
+
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+const unsigned gDefaultUnitsPerEm = 1000;
+
+class FontMetrics {
+public:
+    FontMetrics()
+        : m_unitsPerEm(gDefaultUnitsPerEm)
+        , m_ascent(0)
+        , m_descent(0)
+        , m_lineGap(0)
+        , m_xHeight(0)
+    {
+    }
+
+    unsigned unitsPerEm() const { return m_unitsPerEm; }
+    void setUnitsPerEm(unsigned unitsPerEm) { m_unitsPerEm = unitsPerEm; }
+
+    float floatAscent(FontBaseline baselineType = AlphabeticBaseline) const
+    {
+        if (baselineType == AlphabeticBaseline)
+            return m_ascent;
+        return floatHeight() / 2;
+    }
+
+    void setAscent(float ascent) { m_ascent = ascent; }
+
+    float floatDescent(FontBaseline baselineType = AlphabeticBaseline) const
+    {
+        if (baselineType == AlphabeticBaseline)
+            return m_descent;
+        return floatHeight() / 2;
+    }
+
+    void setDescent(float descent) { m_descent = descent; }
+
+    float floatHeight(FontBaseline baselineType = AlphabeticBaseline) const
+    {
+        return floatAscent(baselineType) + floatDescent(baselineType);
+    }
+
+    float floatLineGap() const { return m_lineGap; }
+    void setLineGap(float lineGap) { m_lineGap = lineGap; }
+
+    float floatLineSpacing() const { return m_ascent + m_descent + m_lineGap; }
+
+    float xHeight() const { return m_xHeight; }
+    void setXHeight(float xHeight) { m_xHeight = xHeight; }
+
+    // Integer variants of certain metrics, used for HTML rendering.
+    int ascent(FontBaseline baselineType = AlphabeticBaseline) const
+    {
+        if (baselineType == AlphabeticBaseline)
+            return lroundf(m_ascent);
+        return height() - height() / 2;
+    }
+
+    int descent(FontBaseline baselineType = AlphabeticBaseline) const
+    {
+        if (baselineType == AlphabeticBaseline)
+            return lroundf(m_descent);
+        return height() / 2;
+    }
+
+    int height(FontBaseline baselineType = AlphabeticBaseline) const
+    {
+        return ascent(baselineType) + descent(baselineType);
+    }
+
+    int lineGap() const { return lroundf(m_lineGap); }
+
+    int lineSpacing() const
+    {
+        // This mimics the old WebCore definition of lineSpacing. Changing to lroundf(m_ascent + m_descent + m_lineGap) causes lots of 1px height differences in the DRT dumps
+        return lroundf(m_ascent) + lroundf(m_descent) + lroundf(m_lineGap);
+    }
+
+private:
+    friend class SimpleFontData;
+
+    void reset()
+    {
+        m_unitsPerEm = gDefaultUnitsPerEm;
+        m_ascent = 0;
+        m_descent = 0;
+        m_lineGap = 0;
+        m_xHeight = 0;
+    }
+
+    unsigned m_unitsPerEm;
+    float m_ascent;
+    float m_descent;
+    float m_lineGap;
+    float m_xHeight;
+};
+
+} // namespace WebCore
+
+#endif // FontMetrics_h
diff --git a/Source/WebCore/platform/graphics/SimpleFontData.cpp b/Source/WebCore/platform/graphics/SimpleFontData.cpp
index e773880..81b54f2 100644
--- a/Source/WebCore/platform/graphics/SimpleFontData.cpp
+++ b/Source/WebCore/platform/graphics/SimpleFontData.cpp
@@ -50,7 +50,6 @@ namespace WebCore {
 SimpleFontData::SimpleFontData(const FontPlatformData& platformData, bool isCustomFont, bool isLoading)
     : m_maxCharWidth(-1)
     , m_avgCharWidth(-1)
-    , m_unitsPerEm(defaultUnitsPerEm)
     , m_orientation(platformData.orientation())
     , m_platformData(platformData)
     , m_treatAsFixedPitch(false)
@@ -74,23 +73,28 @@ SimpleFontData::SimpleFontData(PassOwnPtr<SVGFontData> svgFontData, int size, bo
     , m_isBrokenIdeographFont(false)
 {
     SVGFontFaceElement* svgFontFaceElement = m_svgFontData->svgFontFaceElement();
-    m_unitsPerEm = svgFontFaceElement->unitsPerEm();
-
-    double scale = size;
-    if (m_unitsPerEm)
-        scale /= m_unitsPerEm;
-
-    m_ascent = static_cast<int>(svgFontFaceElement->ascent() * scale);
-    m_descent = static_cast<int>(svgFontFaceElement->descent() * scale);
-    m_xHeight = static_cast<int>(svgFontFaceElement->xHeight() * scale);
-    m_lineGap = 0.1f * size;
-    m_lineSpacing = m_ascent + m_descent + m_lineGap;
+    unsigned unitsPerEm = svgFontFaceElement->unitsPerEm();
+
+    float scale = size;
+    if (unitsPerEm)
+        scale /= unitsPerEm;
+
+    // FIXME: Use floating-point metrics, now that they're exposed!
+    int xHeight = static_cast<int>(svgFontFaceElement->xHeight() * scale);
+    int ascent = static_cast<int>(svgFontFaceElement->ascent() * scale);
+    int descent = static_cast<int>(svgFontFaceElement->descent() * scale);
+    int lineGap = static_cast<int>(0.1f * size);
+    m_fontMetrics.setUnitsPerEm(unitsPerEm);
+    m_fontMetrics.setAscent(ascent);
+    m_fontMetrics.setDescent(descent);
+    m_fontMetrics.setLineGap(lineGap);
+    m_fontMetrics.setXHeight(xHeight);
 
     SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement();
 
     Vector<SVGGlyphIdentifier> spaceGlyphs;
     associatedFontElement->getGlyphIdentifiersForString(String(" ", 1), spaceGlyphs);
-    m_spaceWidth = spaceGlyphs.isEmpty() ? m_xHeight : static_cast<float>(spaceGlyphs.first().horizontalAdvanceX * scale);
+    m_spaceWidth = spaceGlyphs.isEmpty() ? xHeight : static_cast<float>(spaceGlyphs.first().horizontalAdvanceX * scale);
 
     Vector<SVGGlyphIdentifier> numeralZeroGlyphs;
     associatedFontElement->getGlyphIdentifiersForString(String("0", 1), numeralZeroGlyphs);
@@ -98,7 +102,7 @@ SimpleFontData::SimpleFontData(PassOwnPtr<SVGFontData> svgFontData, int size, bo
 
     Vector<SVGGlyphIdentifier> letterWGlyphs;
     associatedFontElement->getGlyphIdentifiersForString(String("W", 1), letterWGlyphs);
-    m_maxCharWidth = letterWGlyphs.isEmpty() ? m_ascent : static_cast<float>(letterWGlyphs.first().horizontalAdvanceX * scale);
+    m_maxCharWidth = letterWGlyphs.isEmpty() ? ascent : static_cast<float>(letterWGlyphs.first().horizontalAdvanceX * scale);
 
     // FIXME: is there a way we can get the space glyph from the SVGGlyphIdentifier above?
     m_spaceGlyph = 0;
@@ -126,10 +130,11 @@ void SimpleFontData::initCharWidths()
 
     // If we can't retrieve the width of a '0', fall back to the x height.
     if (m_avgCharWidth <= 0.f)
-        m_avgCharWidth = m_xHeight;
+        m_avgCharWidth = m_fontMetrics.xHeight();
 
+    // FIXME: Use floating-point metrics, now that they're exposed!
     if (m_maxCharWidth <= 0.f)
-        m_maxCharWidth = max<float>(m_avgCharWidth, m_ascent);
+        m_maxCharWidth = max<float>(m_avgCharWidth, m_fontMetrics.ascent());
 }
 
 void SimpleFontData::platformGlyphInit()
diff --git a/Source/WebCore/platform/graphics/SimpleFontData.h b/Source/WebCore/platform/graphics/SimpleFontData.h
index 90713af..07c2bd1 100644
--- a/Source/WebCore/platform/graphics/SimpleFontData.h
+++ b/Source/WebCore/platform/graphics/SimpleFontData.h
@@ -26,6 +26,7 @@
 
 #include "FontBaseline.h"
 #include "FontData.h"
+#include "FontMetrics.h"
 #include "FontPlatformData.h"
 #include "FloatRect.h"
 #include "GlyphMetricsMap.h"
@@ -101,15 +102,9 @@ public:
     // FIXME: Use the actual metrics for fonts with vertical tables instead of just hard-coding.  If the font is horizontally oriented or
     // a broken ideographic font, then just hard-code to split ascent/descent down the middle.  Otherwise we should actually use the metrics
     // from the font itself.
-    int ascent(FontBaseline baselineType = AlphabeticBaseline) const { return baselineType == AlphabeticBaseline ? m_ascent : height() - height() / 2; }
-    int descent(FontBaseline baselineType = AlphabeticBaseline) const { return baselineType == AlphabeticBaseline ? m_descent : height() / 2; }
-    int height() const { return m_ascent + m_descent; }
-    int lineSpacing() const { return m_lineSpacing; }
-    int lineGap() const { return m_lineGap; }
+    const FontMetrics& fontMetrics() const { return m_fontMetrics; }
     float maxCharWidth() const { return m_maxCharWidth; }
     float avgCharWidth() const { return m_avgCharWidth; }
-    float xHeight() const { return m_xHeight; }
-    unsigned unitsPerEm() const { return m_unitsPerEm; }
 
     FloatRect boundsForGlyph(Glyph) const;
     float widthForGlyph(Glyph glyph) const;
@@ -211,14 +206,9 @@ private:
     float widthForGDIGlyph(Glyph glyph) const;
 #endif
 
-    int m_ascent;
-    int m_descent;
-    int m_lineSpacing;
-    int m_lineGap;
+    FontMetrics m_fontMetrics;
     float m_maxCharWidth;
     float m_avgCharWidth;
-    float m_xHeight;
-    unsigned m_unitsPerEm;
     
     FontOrientation m_orientation; // This is our supported orientation according to the tables in the font.  FontPlatformData will just always have the desired orientation.
                                    // This value represents what we actually support.
diff --git a/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
index 5da4d5a..d7c2eb6 100644
--- a/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
+++ b/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
@@ -246,10 +246,11 @@ IntRect TransparencyAwareGlyphPainter::estimateTextBounds()
     for (int i = 0; i < m_numGlyphs; i++)
         totalWidth += lroundf(m_glyphBuffer.advanceAt(m_from + i));
 
-    return IntRect(m_point.x() - (m_font->ascent() + m_font->descent()) / 2,
-                   m_point.y() - m_font->ascent() - m_font->lineGap(),
-                   totalWidth + m_font->ascent() + m_font->descent(),
-                   m_font->lineSpacing()); 
+    const FontMetrics& fontMetrics = m_font->fontMetrics();
+    return IntRect(m_point.x() - (fontMetrics.ascent() + fontMetrics.descent()) / 2,
+                   m_point.y() - fontMetrics.ascent() - fontMetrics.lineGap(),
+                   totalWidth + fontMetrics.ascent() + fontMetrics.descent(),
+                   fontMetrics.lineSpacing()); 
 }
 
 bool TransparencyAwareGlyphPainter::drawGlyphs(int numGlyphs,
@@ -270,7 +271,7 @@ bool TransparencyAwareGlyphPainter::drawGlyphs(int numGlyphs,
     // Windows' origin is the top-left of the bounding box, so we have
     // to subtract off the font ascent to get it.
     int x = lroundf(m_point.x() + startAdvance);
-    int y = lroundf(m_point.y() - m_font->ascent());
+    int y = lroundf(m_point.y() - m_font->fontMetrics().ascent());
 
     // If there is a non-blur shadow and both the fill color and shadow color 
     // are opaque, handle without skia. 
@@ -354,10 +355,11 @@ IntRect TransparencyAwareUniscribePainter::estimateTextBounds()
     // This algorithm for estimating how much extra space we need (the text may
     // go outside the selection rect) is based roughly on
     // TransparencyAwareGlyphPainter::estimateTextBounds above.
-    return IntRect(left - (m_font->ascent() + m_font->descent()) / 2,
-                   m_point.y() - m_font->ascent() - m_font->lineGap(),
-                   (right - left) + m_font->ascent() + m_font->descent(),
-                   m_font->lineSpacing());
+    const FontMetrics& fontMetrics = m_font->fontMetrics();
+    return IntRect(left - (fontMetrics.ascent() + fontMetrics.descent()) / 2,
+                   m_point.y() - fontMetrics.ascent() - fontMetrics.lineGap(),
+                   (right - left) + fontMetrics.ascent() + fontMetrics.descent(),
+                   fontMetrics.lineSpacing());
 }
 
 }  // namespace
@@ -496,14 +498,14 @@ void Font::drawComplexText(GraphicsContext* graphicsContext,
         COLORREF savedTextColor = GetTextColor(hdc);
         SetTextColor(hdc, textColor);
         state.draw(graphicsContext, hdc, static_cast<int>(point.x()) + shadowOffset.width(),
-                   static_cast<int>(point.y() - ascent()) + shadowOffset.height(), from, to);
+                   static_cast<int>(point.y() - fontMetrics().ascent()) + shadowOffset.height(), from, to);
         SetTextColor(hdc, savedTextColor); 
     }
 
     // Uniscribe counts the coordinates from the upper left, while WebKit uses
     // the baseline, so we have to subtract off the ascent.
     state.draw(graphicsContext, hdc, static_cast<int>(point.x()),
-               static_cast<int>(point.y() - ascent()), from, to);
+               static_cast<int>(point.y() - fontMetrics().ascent()), from, to);
 
     context->canvas()->endPlatformPaint();
 }
diff --git a/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp b/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
index c23c586..750a317 100644
--- a/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
+++ b/Source/WebCore/platform/graphics/chromium/SimpleFontDataChromiumWin.cpp
@@ -54,14 +54,9 @@ static inline float scaleEmToUnits(float x, int unitsPerEm)
 void SimpleFontData::platformInit()
 {
     if (!m_platformData.size()) {
-        m_ascent = 0;
-        m_descent = 0;
-        m_lineGap = 0;
-        m_lineSpacing = 0;
+        m_fontMetrics.reset();
         m_avgCharWidth = 0;
         m_maxCharWidth = 0;
-        m_xHeight = 0;
-        m_unitsPerEm = 0;
         return;
     }
 
@@ -82,10 +77,11 @@ void SimpleFontData::platformInit()
     m_avgCharWidth = textMetric.tmAveCharWidth;
     m_maxCharWidth = textMetric.tmMaxCharWidth;
 
-    m_ascent = textMetric.tmAscent;
-    m_descent = textMetric.tmDescent;
-    m_lineGap = textMetric.tmExternalLeading;
-    m_xHeight = m_ascent * 0.56f;  // Best guess for xHeight for non-Truetype fonts.
+    // FIXME: Access ascent/descent/lineGap with floating point precision.
+    float ascent = textMetric.tmAscent;
+    float descent = textMetric.tmDescent;
+    float lineGap = textMetric.tmExternalLeading;
+    float xHeight = ascent * 0.56f; // Best guess for xHeight for non-Truetype fonts.
 
     OUTLINETEXTMETRIC outlineTextMetric;
     if (GetOutlineTextMetrics(dc, sizeof(outlineTextMetric), &outlineTextMetric) > 0) {
@@ -94,10 +90,13 @@ void SimpleFontData::platformInit()
         MAT2 identityMatrix = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
         DWORD len = GetGlyphOutlineW(dc, 'x', GGO_METRICS, &glyphMetrics, 0, 0, &identityMatrix);
         if (len != GDI_ERROR && glyphMetrics.gmBlackBoxY > 0)
-            m_xHeight = static_cast<float>(glyphMetrics.gmBlackBoxY);
+            xHeight = static_cast<float>(glyphMetrics.gmBlackBoxY);
     }
 
-    m_lineSpacing = m_ascent + m_descent + m_lineGap;
+    m_fontMetrics.setAscent(ascent);
+    m_fontMetrics.setDescent(descent);
+    m_fontMetrics.setLineGap(lineGap);
+    m_fontMetrics.setXHeight(xHeight);
 
     SelectObject(dc, oldFont);
     ReleaseDC(0, dc);
diff --git a/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp b/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
index 355d837..b995a4a 100644
--- a/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
+++ b/Source/WebCore/platform/graphics/chromium/SimpleFontDataLinux.cpp
@@ -55,14 +55,9 @@ static const size_t maxVDMXTableSize = 1024 * 1024;  // 1 MB
 void SimpleFontData::platformInit()
 {
     if (!m_platformData.size()) {
-        m_ascent = 0;
-        m_descent = 0;
-        m_lineGap = 0;
-        m_lineSpacing = 0;
+        m_fontMetrics.reset();
         m_avgCharWidth = 0;
         m_maxCharWidth = 0;
-        m_xHeight = 0;
-        m_unitsPerEm = 0;
         return;
     }
 
@@ -88,26 +83,34 @@ void SimpleFontData::platformInit()
         fastFree(vdmxTable);
     }
 
+    float ascent;
+    float descent;
+
     // Beware those who step here: This code is designed to match Win32 font
     // metrics *exactly*.
     if (isVDMXValid) {
-        m_ascent = vdmxAscent;
-        m_descent = -vdmxDescent;
+        // FIXME: Access ascent/descent with floating point precision.
+        ascent = vdmxAscent;
+        descent = -vdmxDescent;
     } else {
         SkScalar height = -metrics.fAscent + metrics.fDescent + metrics.fLeading;
-        m_ascent = SkScalarRound(-metrics.fAscent);
-        m_descent = SkScalarRound(height) - m_ascent;
+        ascent = SkScalarToFloat(-metrics.fAscent);
+        descent = SkScalarToFloat(height) - ascent;
     }
 
+    m_fontMetrics.setAscent(ascent);
+    m_fontMetrics.setDescent(descent);
+
+    float xHeight;
     if (metrics.fXHeight)
-        m_xHeight = metrics.fXHeight;
+        xHeight = metrics.fXHeight;
     else {
         // hack taken from the Windows port
-        m_xHeight = static_cast<float>(m_ascent) * 0.56;
+        xHeight = ascent * 0.56f;
     }
 
-    m_lineGap = SkScalarRound(metrics.fLeading);
-    m_lineSpacing = m_ascent + m_descent + m_lineGap;
+    m_fontMetrics.setLineGap(SkScalarToFloat(metrics.fLeading));
+    m_fontMetrics.setXHeight(xHeight);
 
     if (m_orientation == Vertical) {
         static const uint32_t vheaTag = SkSetFourByteTag('v', 'h', 'e', 'a');
@@ -128,7 +131,7 @@ void SimpleFontData::platformInit()
     if (metrics.fAvgCharWidth)
         m_avgCharWidth = SkScalarRound(metrics.fAvgCharWidth);
     else {
-        m_avgCharWidth = m_xHeight;
+        m_avgCharWidth = xHeight;
 
         GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
 
diff --git a/Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp b/Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp
index aa18b4a..a411e47 100644
--- a/Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp
+++ b/Source/WebCore/platform/graphics/chromium/UniscribeHelperTextRun.cpp
@@ -51,7 +51,7 @@ UniscribeHelperTextRun::UniscribeHelperTextRun(const TextRun& run,
     setLetterSpacing(font.letterSpacing());
     setSpaceWidth(font.spaceWidth());
     setWordSpacing(font.wordSpacing());
-    setAscent(font.primaryFont()->ascent());
+    setAscent(font.fontMetrics()->ascent());
 
     init();
 
@@ -121,7 +121,7 @@ bool UniscribeHelperTextRun::nextWinFontData(
         m_hfonts.append(simpleFontData->platformData().hfont());
         m_scriptCaches.append(simpleFontData->platformData().scriptCache());
         m_fontProperties.append(simpleFontData->platformData().scriptFontProperties());
-        m_ascents.append(simpleFontData->ascent());
+        m_ascents.append(simpleFontData->fontMetrics().ascent());
     }
 
     *hfont = m_hfonts[m_fontIndex - 1];
diff --git a/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
index 97fd81a..fcbf54b 100644
--- a/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
+++ b/Source/WebCore/platform/graphics/freetype/SimpleFontDataFreeType.cpp
@@ -50,21 +50,26 @@ void SimpleFontData::platformInit()
     cairo_font_extents_t font_extents;
     cairo_text_extents_t text_extents;
     cairo_scaled_font_extents(m_platformData.scaledFont(), &font_extents);
-    m_ascent = static_cast<int>(lroundf(font_extents.ascent));
-    m_descent = static_cast<int>(lroundf(font_extents.descent));
-    m_lineSpacing = static_cast<int>(lroundf(font_extents.height));
+
+    m_fontMetrics.setAscent(font_extents.ascent);
+    m_fontMetrics.setDescent(font_extents.descent);
+
     // There seems to be some rounding error in cairo (or in how we
     // use cairo) with some fonts, like DejaVu Sans Mono, which makes
     // cairo report a height smaller than ascent + descent, which is
     // wrong and confuses WebCore's layout system. Workaround this
     // while we figure out what's going on.
-    if (m_lineSpacing < m_ascent + m_descent)
-        m_lineSpacing = m_ascent + m_descent;
+    float lineSpacing = font_extents.height;
+    if (lineSpacing < font_extents.ascent + font_extents.descent)
+        lineSpacing = font_extents.ascent + font_extents.descent;
+    m_fontMetrics.setLineGap(lineSpacing - font_extents.ascent - font_extents.descent);
+
     cairo_scaled_font_text_extents(m_platformData.scaledFont(), "x", &text_extents);
-    m_xHeight = text_extents.height;
+    m_fontMetrics.setXHeight(text_extents.height);
+
     cairo_scaled_font_text_extents(m_platformData.scaledFont(), " ", &text_extents);
     m_spaceWidth = static_cast<float>(text_extents.x_advance);
-    m_lineGap = m_lineSpacing - m_ascent - m_descent;
+    
     m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
 }
 
diff --git a/Source/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp b/Source/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
index b1e7082..468b000 100644
--- a/Source/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
+++ b/Source/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
@@ -48,11 +48,10 @@ void SimpleFontData::platformInit()
 
     font_height height;
     font->GetHeight(&height);
-    m_ascent = static_cast<int>(height.ascent);
-    m_descent = static_cast<int>(height.descent);
-    m_lineSpacing = m_ascent + m_descent;
-    m_xHeight = height.ascent * 0.56f; // Hack taken from the win port.
-    m_lineGap = height.leading;
+    m_fontMetrics.setAscent(height.ascent);
+    m_fontMetrics.setDescent(height.descent);
+    m_fontMetrics.setXHeight(height.ascent * 0.56f); // Hack taken from the win port.
+    m_fontMetrics.setLineGap(height.leading);
 }
 
 void SimpleFontData::platformCharWidthInit()
diff --git a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
index 02bac9c..865051d 100644
--- a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
+++ b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
@@ -111,8 +111,8 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
 {
     ComplexTextController controller(this, run, true, fallbackFonts);
     if (glyphOverflow) {
-        glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - ascent());
-        glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - descent());
+        glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - fontMetrics().ascent());
+        glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - fontMetrics().descent());
         glyphOverflow->left = max<int>(0, ceilf(-controller.minGlyphBoundingBoxX()));
         glyphOverflow->right = max<int>(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.totalWidth()));
     }
diff --git a/Source/WebCore/platform/graphics/mac/FontMac.mm b/Source/WebCore/platform/graphics/mac/FontMac.mm
index 8519667..f7d71ef 100644
--- a/Source/WebCore/platform/graphics/mac/FontMac.mm
+++ b/Source/WebCore/platform/graphics/mac/FontMac.mm
@@ -60,8 +60,8 @@ static void showGlyphsWithAdvances(const SimpleFontData* font, CGContextRef cont
             savedMatrix = CGContextGetTextMatrix(context);
             CGAffineTransform runMatrix = CGAffineTransformConcat(savedMatrix, rotateLeftTransform);
             // Move start point to put glyphs into original region.
-            runMatrix.tx = savedMatrix.tx + font->ascent();
-            runMatrix.ty = savedMatrix.ty + font->descent();
+            runMatrix.tx = savedMatrix.tx + font->fontMetrics().ascent();
+            runMatrix.ty = savedMatrix.ty + font->fontMetrics().descent();
             CGContextSetTextMatrix(context, runMatrix);
         }
 
diff --git a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index 92585c6..2b58e92 100644
--- a/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -218,19 +218,20 @@ void SimpleFontData::platformInit()
     int iAscent;
     int iDescent;
     int iLineGap;
+    unsigned unitsPerEm;
 #ifdef BUILDING_ON_TIGER
-    wkGetFontMetrics(m_platformData.cgFont(), &iAscent, &iDescent, &iLineGap, &m_unitsPerEm);
+    wkGetFontMetrics(m_platformData.cgFont(), &iAscent, &iDescent, &iLineGap, &unitsPerEm);
 #else
     iAscent = CGFontGetAscent(m_platformData.cgFont());
     iDescent = CGFontGetDescent(m_platformData.cgFont());
     iLineGap = CGFontGetLeading(m_platformData.cgFont());
-    m_unitsPerEm = CGFontGetUnitsPerEm(m_platformData.cgFont());
+    unitsPerEm = CGFontGetUnitsPerEm(m_platformData.cgFont());
 #endif
 
     float pointSize = m_platformData.m_size;
-    float fAscent = scaleEmToUnits(iAscent, m_unitsPerEm) * pointSize;
-    float fDescent = -scaleEmToUnits(iDescent, m_unitsPerEm) * pointSize;
-    float fLineGap = scaleEmToUnits(iLineGap, m_unitsPerEm) * pointSize;
+    float ascent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize;
+    float descent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize;
+    float lineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize;
 
     // We need to adjust Times, Helvetica, and Courier to closely match the
     // vertical metrics of their Microsoft counterparts that are the de facto
@@ -239,25 +240,20 @@ void SimpleFontData::platformInit()
     // and add it to the ascent.
     NSString *familyName = [m_platformData.font() familyName];
     if ([familyName isEqualToString:@"Times"] || [familyName isEqualToString:@"Helvetica"] || [familyName isEqualToString:@"Courier"])
-        fAscent += floorf(((fAscent + fDescent) * 0.15f) + 0.5f);
+        ascent += floorf(((ascent + descent) * 0.15f) + 0.5f);
     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
         // do not overlap diacritics at the top of the next line.
-        fAscent *= 1.08f;
-        fDescent *= 2.f;
+        ascent *= 1.08f;
+        descent *= 2.f;
     }
 
-    m_ascent = lroundf(fAscent);
-    m_descent = lroundf(fDescent);
-    m_lineGap = lroundf(fLineGap);
-    m_lineSpacing = m_ascent + m_descent + m_lineGap;
-    
     // Hack Hiragino line metrics to allow room for marked text underlines.
     // <rdar://problem/5386183>
-    if (m_descent < 3 && m_lineGap >= 3 && [familyName hasPrefix:@"Hiragino"]) {
-        m_lineGap -= 3 - m_descent;
-        m_descent = 3;
+    if (descent < 3 && lineGap >= 3 && [familyName hasPrefix:@"Hiragino"]) {
+        lineGap -= 3 - descent;
+        descent = 3;
     }
     
     if (m_orientation == Vertical) {
@@ -278,6 +274,8 @@ void SimpleFontData::platformInit()
             m_orientation = Horizontal;
     }
 
+    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();
@@ -288,21 +286,27 @@ void SimpleFontData::platformInit()
         // 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.
-        m_xHeight = static_cast<float>(max(CGRectGetMaxX(xBox), -CGRectGetMinY(xBox)));
+        xHeight = static_cast<float>(max(CGRectGetMaxX(xBox), -CGRectGetMinY(xBox)));
     } else {
 #ifndef BUILDING_ON_TIGER
-        m_xHeight = static_cast<float>(CGFontGetXHeight(m_platformData.cgFont())) / m_unitsPerEm;
+        xHeight = static_cast<float>(CGFontGetXHeight(m_platformData.cgFont())) / unitsPerEm;
 #else
-        m_xHeight = m_platformData.font() ? [m_platformData.font() xHeight] : 0;
+        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 m_xHeight in that case.
+        // 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>(m_xHeight) && fAscent)
-            m_xHeight = 2 * fAscent / 3;
+        if (!static_cast<int>(xHeight) && ascent)
+            xHeight = 2 * ascent / 3;
     }
+
+    m_fontMetrics.setUnitsPerEm(unitsPerEm);
+    m_fontMetrics.setAscent(ascent);
+    m_fontMetrics.setDescent(descent);
+    m_fontMetrics.setLineGap(lineGap);
+    m_fontMetrics.setXHeight(xHeight);
 }
-    
+
 static CFDataRef copyFontTableForTag(FontPlatformData& platformData, FourCharCode tableName)
 {
 #ifdef BUILDING_ON_TIGER
@@ -337,7 +341,7 @@ void SimpleFontData::platformCharWidthInit()
     if (os2Table && CFDataGetLength(os2Table.get()) >= 4) {
         const UInt8* os2 = CFDataGetBytePtr(os2Table.get());
         SInt16 os2AvgCharWidth = os2[2] * 256 + os2[3];
-        m_avgCharWidth = scaleEmToUnits(os2AvgCharWidth, m_unitsPerEm) * m_platformData.m_size;
+        m_avgCharWidth = scaleEmToUnits(os2AvgCharWidth, m_fontMetrics.unitsPerEm()) * m_platformData.m_size;
     }
 
     RetainPtr<CFDataRef> headTable(AdoptCF, copyFontTableForTag(m_platformData, 'head'));
@@ -348,7 +352,7 @@ void SimpleFontData::platformCharWidthInit()
         SInt16 xMin = static_cast<SInt16>(uxMin);
         SInt16 xMax = static_cast<SInt16>(uxMax);
         float diff = static_cast<float>(xMax - xMin);
-        m_maxCharWidth = scaleEmToUnits(diff, m_unitsPerEm) * m_platformData.m_size;
+        m_maxCharWidth = scaleEmToUnits(diff, m_fontMetrics.unitsPerEm()) * m_platformData.m_size;
     }
 
     // Fallback to a cross-platform estimate, which will populate these values if they are non-positive.
diff --git a/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp b/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
index d0bf836..aa37255 100644
--- a/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
+++ b/Source/WebCore/platform/graphics/pango/SimpleFontDataPango.cpp
@@ -49,21 +49,26 @@ void SimpleFontData::platformInit()
     cairo_font_extents_t font_extents;
     cairo_text_extents_t text_extents;
     cairo_scaled_font_extents(m_platformData.m_scaledFont, &font_extents);
-    m_ascent = static_cast<int>(lroundf(font_extents.ascent));
-    m_descent = static_cast<int>(lroundf(font_extents.descent));
-    m_lineSpacing = static_cast<int>(lroundf(font_extents.height));
+
+    m_fontMetrics.setAscent(font_extents.ascent);
+    m_fontMetrics.setDescent(font_extents.descent);
+
     // There seems to be some rounding error in cairo (or in how we
     // use cairo) with some fonts, like DejaVu Sans Mono, which makes
     // cairo report a height smaller than ascent + descent, which is
     // wrong and confuses WebCore's layout system. Workaround this
     // while we figure out what's going on.
-    if (m_lineSpacing < m_ascent + m_descent)
-        m_lineSpacing = m_ascent + m_descent;
+    float lineSpacing = font_extents.height;
+    if (lineSpacing < font_extents.ascent + font_extents.descent)
+        lineSpacing = font_extents.ascent + font_extents.descent;
+    m_fontMetrics.setLineGap(lineSpacing - font_extents.ascent - font_extents.descent);
+
     cairo_scaled_font_text_extents(m_platformData.m_scaledFont, "x", &text_extents);
-    m_xHeight = text_extents.height;
+    m_fontMetrics.setXHeight(text_extents.height);
+
     cairo_scaled_font_text_extents(m_platformData.m_scaledFont, " ", &text_extents);
-    m_spaceWidth =  static_cast<float>(text_extents.x_advance);
-    m_lineGap = m_lineSpacing - m_ascent - m_descent;
+    m_spaceWidth = static_cast<float>(text_extents.x_advance);
+    
     m_syntheticBoldOffset = m_platformData.syntheticBold() ? 1.0f : 0.f;
 }
 
diff --git a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
index 47ddf02..ac8fe39 100644
--- a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
+++ b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
@@ -24,7 +24,7 @@
 #include "config.h"
 #include "SimpleFontData.h"
 
-#include <QFontMetrics>
+#include <QFontMetricsF>
 
 namespace WebCore {
 
@@ -41,25 +41,18 @@ bool SimpleFontData::containsCharacters(const UChar*, int) const
 void SimpleFontData::platformInit()
 {
     if (!m_platformData.size()) {
-         m_ascent = 0;
-         m_descent = 0;
-         m_lineGap = 0;
-         m_lineSpacing = 0;
+         m_fontMetrics.reset();
          m_avgCharWidth = 0;
          m_maxCharWidth = 0;
-         m_xHeight = 0;
-         m_unitsPerEm = 0;
          return;
     }
 
-    QFontMetrics fm(m_platformData.font());
-
-    m_ascent = fm.ascent();
-    m_descent = fm.descent();
-    m_lineSpacing = fm.lineSpacing();
-    m_xHeight = fm.xHeight();
+    QFontMetricsF fm(m_platformData.font());
+    m_fontMetrics.setAscent(fm.ascent());
+    m_fontMetrics.setDescent(fm.descent());
+    m_fontMetrics.setXHeight(fm.xHeight());
+    m_fontMetrics.setLineGap(fm.leading());
     m_spaceWidth = fm.width(QLatin1Char(' '));
-    m_lineGap = fm.leading();
 }
 
 void SimpleFontData::platformGlyphInit()
diff --git a/Source/WebCore/platform/graphics/win/FontCGWin.cpp b/Source/WebCore/platform/graphics/win/FontCGWin.cpp
index 8012722..8c39d5c 100644
--- a/Source/WebCore/platform/graphics/win/FontCGWin.cpp
+++ b/Source/WebCore/platform/graphics/win/FontCGWin.cpp
@@ -167,8 +167,12 @@ static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData
         drawIntoBitmap = true;
         // We put slop into this rect, since glyphs can overflow the ascent/descent bounds and the left/right edges.
         // FIXME: Can get glyphs' optical bounds (even from CG) to get this right.
-        int lineGap = font->lineGap();
-        textRect = IntRect(point.x() - (font->ascent() + font->descent()) / 2, point.y() - font->ascent() - lineGap, totalWidth + font->ascent() + font->descent(), font->lineSpacing());
+        const FontMetrics& fontMetrics = font->fontMetrics();
+        int lineGap = fontMetrics.lineGap();
+        textRect = IntRect(point.x() - (fontMetrics.ascent() + fontMetrics.descent()) / 2,
+                           point.y() - fontMetrics.ascent() - lineGap,
+                           totalWidth + fontMetrics.ascent() + fontMetrics.descent(),
+                           fontMetrics.lineSpacing());
         bitmap.set(graphicsContext->createWindowsBitmap(textRect.size()));
         memset(bitmap->buffer(), 255, bitmap->bufferLength());
         hdc = bitmap->hdc();
diff --git a/Source/WebCore/platform/graphics/win/FontWin.cpp b/Source/WebCore/platform/graphics/win/FontWin.cpp
index 2ed9eb3..cdb2fd2 100644
--- a/Source/WebCore/platform/graphics/win/FontWin.cpp
+++ b/Source/WebCore/platform/graphics/win/FontWin.cpp
@@ -122,8 +122,8 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon
     UniscribeController controller(this, run, fallbackFonts);
     controller.advance(run.length());
     if (glyphOverflow) {
-        glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - ascent());
-        glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - descent());
+        glyphOverflow->top = max<int>(glyphOverflow->top, ceilf(-controller.minGlyphBoundingBoxY()) - fontMetrics().ascent());
+        glyphOverflow->bottom = max<int>(glyphOverflow->bottom, ceilf(controller.maxGlyphBoundingBoxY()) - fontMetrics().descent());
         glyphOverflow->left = max<int>(0, ceilf(-controller.minGlyphBoundingBoxX()));
         glyphOverflow->right = max<int>(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.runWidthSoFar()));
     }
diff --git a/Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp b/Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
index 20d42ff..21f2533 100644
--- a/Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
+++ b/Source/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
@@ -64,11 +64,11 @@ void SimpleFontData::platformInit()
     int iAscent = CGFontGetAscent(font);
     int iDescent = CGFontGetDescent(font);
     int iLineGap = CGFontGetLeading(font);
-    m_unitsPerEm = CGFontGetUnitsPerEm(font);
+    unsigned unitsPerEm = CGFontGetUnitsPerEm(font);
     float pointSize = m_platformData.size();
-    float fAscent = scaleEmToUnits(iAscent, m_unitsPerEm) * pointSize;
-    float fDescent = -scaleEmToUnits(iDescent, m_unitsPerEm) * pointSize;
-    float fLineGap = scaleEmToUnits(iLineGap, m_unitsPerEm) * pointSize;
+    float fAscent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize;
+    float fDescent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize;
+    float fLineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize;
 
     if (!isCustomFont()) {
         HDC dc = GetDC(0);
@@ -93,10 +93,9 @@ void SimpleFontData::platformInit()
         }
     }
 
-    m_ascent = lroundf(fAscent);
-    m_descent = lroundf(fDescent);
-    m_lineGap = lroundf(fLineGap);
-    m_lineSpacing = m_ascent + m_descent + m_lineGap;
+    m_fontMetrics.setAscent(fAscent);
+    m_fontMetrics.setDescent(fDescent);
+    m_fontMetrics.setLineGap(fLineGap);
 
     // 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.
@@ -109,11 +108,13 @@ void SimpleFontData::platformInit()
         // 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.
-        m_xHeight = scaleEmToUnits(max(CGRectGetMaxX(xBox), CGRectGetMaxY(xBox)), m_unitsPerEm) * pointSize;
+        m_fontMetrics.setXHeight(scaleEmToUnits(max(CGRectGetMaxX(xBox), CGRectGetMaxY(xBox)), unitsPerEm) * pointSize);
     } else {
         int iXHeight = CGFontGetXHeight(font);
-        m_xHeight = scaleEmToUnits(iXHeight, m_unitsPerEm) * pointSize;
+        m_fontMetrics.setXHeight(scaleEmToUnits(iXHeight, unitsPerEm) * pointSize);
     }
+
+    m_fontMetrics.setUnitsPerEm(unitsPerEm);
 }
 
 void SimpleFontData::platformCharWidthInit()
@@ -133,7 +134,7 @@ FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
     CGRect box;
     CGFontGetGlyphBBoxes(m_platformData.cgFont(), &glyph, 1, &box);
     float pointSize = m_platformData.size();
-    CGFloat scale = pointSize / unitsPerEm();
+    CGFloat scale = pointSize / fontMetrics().unitsPerEm();
     FloatRect boundingBox = CGRectApplyAffineTransform(box, CGAffineTransformMakeScale(scale, -scale));
     if (m_syntheticBoldOffset)
         boundingBox.setWidth(boundingBox.width() + m_syntheticBoldOffset);
diff --git a/Source/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp b/Source/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
index 62ea060..452f819 100644
--- a/Source/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
+++ b/Source/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
@@ -63,13 +63,15 @@ void SimpleFontData::platformInit()
 
     TEXTMETRIC textMetrics;
     GetTextMetrics(hdc, &textMetrics);
-    m_ascent = lroundf(textMetrics.tmAscent * metricsMultiplier);
-    m_descent = lroundf(textMetrics.tmDescent * metricsMultiplier);
-    m_xHeight = m_ascent * 0.56f; // Best guess for xHeight for non-Truetype fonts.
-    m_lineGap = lroundf(textMetrics.tmExternalLeading * metricsMultiplier);
-    m_lineSpacing = m_ascent + m_descent + m_lineGap;
-    m_avgCharWidth = lroundf(textMetrics.tmAveCharWidth * metricsMultiplier);
-    m_maxCharWidth = lroundf(textMetrics.tmMaxCharWidth * metricsMultiplier);
+    float ascent = textMetrics.tmAscent * metricsMultiplier;
+    float descent = textMetrics.tmDescent * metricsMultiplier;
+    float xHeight = ascent * 0.56f; // Best guess for xHeight for non-Truetype fonts.
+    float lineGap = textMetrics.tmExternalLeading * metricsMultiplier;
+    m_fontMetrics.setAscent(ascent);
+    m_fontMetrics.setDescent(descent);
+    m_fontMetrics.setLineGap(lineGap);
+    m_avgCharWidth = textMetrics.tmAveCharWidth * metricsMultiplier;
+    m_maxCharWidth = textMetrics.tmMaxCharWidth * metricsMultiplier;
 
     OUTLINETEXTMETRIC metrics;
     if (GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics) > 0) {
@@ -78,9 +80,10 @@ void SimpleFontData::platformInit()
         MAT2 mat = { 1, 0, 0, 1 };
         DWORD len = GetGlyphOutline(hdc, 'x', GGO_METRICS, &gm, 0, 0, &mat);
         if (len != GDI_ERROR && gm.gmptGlyphOrigin.y > 0)
-            m_xHeight = gm.gmptGlyphOrigin.y * metricsMultiplier;
+            xHeight = gm.gmptGlyphOrigin.y * metricsMultiplier;
     }
 
+    m_fontMetrics.setXHeight(xHeight);
     cairo_win32_scaled_font_done_font(scaledFont);
 
     m_isSystemFont = false;
diff --git a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
index 60afe6a..d31e040 100644
--- a/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
+++ b/Source/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
@@ -66,14 +66,9 @@ bool SimpleFontData::shouldApplyMacAscentHack()
 void SimpleFontData::initGDIFont()
 {
     if (!m_platformData.size()) {
-        m_ascent = 0;
-        m_descent = 0;
-        m_lineGap = 0;
-        m_lineSpacing = 0;
+        m_fontMetrics.reset();
         m_avgCharWidth = 0;
         m_maxCharWidth = 0;
-        m_xHeight = 0;
-        m_unitsPerEm = 0;
         return;
     }
 
@@ -82,21 +77,24 @@ void SimpleFontData::initGDIFont()
      OUTLINETEXTMETRIC metrics;
      GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics);
      TEXTMETRIC& textMetrics = metrics.otmTextMetrics;
-     m_ascent = textMetrics.tmAscent;
-     m_descent = textMetrics.tmDescent;
-     m_lineGap = textMetrics.tmExternalLeading;
-     m_lineSpacing = m_ascent + m_descent + m_lineGap;
+     float ascent = textMetrics.tmAscent;
+     float descent = textMetrics.tmDescent;
+     float lineGap = textMetrics.tmExternalLeading;
+     m_fontMetrics.setAscent(ascent);
+     m_fontMetrics.setDescent(descent);
+     m_fontMetrics.setLineGap(lineGap);
      m_avgCharWidth = textMetrics.tmAveCharWidth;
      m_maxCharWidth = textMetrics.tmMaxCharWidth;
-     m_xHeight = m_ascent * 0.56f; // Best guess for xHeight if no x glyph is present.
+     float xHeight = ascent * 0.56f; // Best guess for xHeight if no x glyph is present.
 
      GLYPHMETRICS gm;
      MAT2 mat = { 1, 0, 0, 1 };
      DWORD len = GetGlyphOutline(hdc, 'x', GGO_METRICS, &gm, 0, 0, &mat);
      if (len != GDI_ERROR && gm.gmptGlyphOrigin.y > 0)
-         m_xHeight = gm.gmptGlyphOrigin.y;
+         xHeight = gm.gmptGlyphOrigin.y;
 
-     m_unitsPerEm = metrics.otmEMSquare;
+     m_fontMetrics.setXHeight(xHeight);
+     m_fontMetrics.setUnitsPerEm(metrics.otmEMSquare);
 
      SelectObject(hdc, oldFont);
      ReleaseDC(0, hdc);
diff --git a/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp b/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
index 9b672d2..779633f 100644
--- a/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
+++ b/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp
@@ -1537,7 +1537,7 @@ void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPo
     m_data->m_opacity *= fillColor().alpha() / 255.0;
 
     FloatRect textRect = font.selectionRectForText(run, point, font.height(), from, to);
-    textRect.setY(textRect.y() - font.ascent());
+    textRect.setY(textRect.y() - font.fontMetrics().ascent());
     IntRect trRect = enclosingIntRect(m_data->mapRect(textRect));
     RECT bmpRect;
     AlphaPaintType alphaPaintType = mustSupportAlpha ? AlphaPaintOther : AlphaPaintNone;
@@ -1546,7 +1546,7 @@ void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPo
             GraphicsContext gc(0);
             gc.setBitmap(bmp);
             gc.scale(FloatSize(m_data->m_transform.a(), m_data->m_transform.d()));
-            font.drawText(&gc, run, IntPoint(0, font.ascent()), from, to);
+            font.drawText(&gc, run, IntPoint(0, font.fontMetrics().ascent()), from, to);
         }
         unsigned key1;
         HDC memDC = bmp->getDC(&key1);
@@ -1591,7 +1591,7 @@ void GraphicsContext::drawText(const SimpleFontData* fontData, const GlyphBuffer
         ? fontData->platformData().getScaledFontHandle(height, scaleX == scaleY ? 0 : width)
         : 0;
 
-    FloatPoint startPoint(point.x(), point.y() - fontData->ascent());
+    FloatPoint startPoint(point.x(), point.y() - fontData->fontMetrics().ascent());
     FloatPoint trPoint = m_data->mapPoint(startPoint);
     int y = stableRound(trPoint.y());
 
diff --git a/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp b/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
index 27a021e..0c1be21 100644
--- a/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
+++ b/Source/WebCore/platform/graphics/wince/SimpleFontDataWinCE.cpp
@@ -51,11 +51,13 @@ void SimpleFontData::platformInit()
     const TEXTMETRIC& tm = m_platformData.metrics();
     m_isSystemFont = m_platformData.isSystemFont();
 
-    m_ascent = (tm.tmAscent * m_platformData.size() + 36) / 72;
-    m_descent = (tm.tmDescent * m_platformData.size() + 36) / 72;
-    m_lineGap = (tm.tmExternalLeading * m_platformData.size() + 36) / 72;
-    m_lineSpacing = m_ascent + m_descent + m_lineGap;
-    m_xHeight = m_ascent * 0.56f;
+    float ascent = (tm.tmAscent * m_platformData.size() + 36) / 72.0f;
+    float descent = (tm.tmDescent * m_platformData.size() + 36) / 72.0f;
+    float lineGap = (tm.tmExternalLeading * m_platformData.size() + 36) / 72.0f;
+    m_fontMetrics.setAscent(ascent);
+    m_fontMetrics.setDescent(descent);
+    m_fontMetrics.setLineGap(lineGap);
+    m_fontMetrics.setXHeight(ascent * 0.56f);
 }
 
 void SimpleFontData::platformDestroy()
diff --git a/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp b/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
index 0e24bfc..cbabc29 100644
--- a/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
+++ b/Source/WebCore/platform/graphics/wx/SimpleFontDataWx.cpp
@@ -53,12 +53,11 @@ void SimpleFontData::platformInit()
     wxFont *font = m_platformData.font();
     if (font && font->IsOk()) {
         wxFontProperties props = wxFontProperties(font);
-        m_ascent = props.GetAscent();
-        m_descent = props.GetDescent();
-        m_lineSpacing = props.GetLineSpacing();
-        m_xHeight = props.GetXHeight();
-        m_unitsPerEm = 1; // FIXME!
-        m_lineGap = props.GetLineGap();
+        m_fontMetrics.setAscent(props.GetAscent());
+        m_fontMetrics.setDescent(props.GetDescent());
+        m_fontMetrics.setXHeight(props.GetXHeight());
+        m_fontMetrics.setUnitsPerEm(1); // FIXME!
+        m_fontMetrics.setLineGap(props.GetLineGap());
     }
 
     m_syntheticBoldOffset = 0.0f;
diff --git a/Source/WebCore/platform/win/PopupMenuWin.cpp b/Source/WebCore/platform/win/PopupMenuWin.cpp
index 15871e6..3d96658 100644
--- a/Source/WebCore/platform/win/PopupMenuWin.cpp
+++ b/Source/WebCore/platform/win/PopupMenuWin.cpp
@@ -306,7 +306,7 @@ void PopupMenuWin::calculatePositionAndSize(const IntRect& r, FrameView* v)
 
     // First, determine the popup's height
     int itemCount = client()->listSize();
-    m_itemHeight = client()->menuStyle().font().height() + optionSpacingMiddle;
+    m_itemHeight = client()->menuStyle().font().fontMetrics().height() + optionSpacingMiddle;
     int naturalHeight = m_itemHeight * itemCount;
     int popupHeight = min(maxPopupHeight, naturalHeight);
     // The popup should show an integral number of items (i.e. no partial items should be visible)
@@ -649,7 +649,7 @@ void PopupMenuWin::paint(const IntRect& damageRect, HDC hdc)
             int textX = max(0, client()->clientPaddingLeft() - client()->clientInsetLeft());
             if (RenderTheme::defaultTheme()->popupOptionSupportsTextIndent() && itemStyle.textDirection() == LTR)
                 textX += itemStyle.textIndent().calcMinValue(itemRect.width());
-            int textY = itemRect.y() + itemFont.ascent() + (itemRect.height() - itemFont.height()) / 2;
+            int textY = itemRect.y() + itemFont.fontMetrics().ascent() + (itemRect.height() - itemFont.fontMetrics().height()) / 2;
             context.drawBidiText(itemFont, textRun, IntPoint(textX, textY));
         }
     }
diff --git a/Source/WebCore/rendering/EllipsisBox.cpp b/Source/WebCore/rendering/EllipsisBox.cpp
index d367c07..958569c 100644
--- a/Source/WebCore/rendering/EllipsisBox.cpp
+++ b/Source/WebCore/rendering/EllipsisBox.cpp
@@ -53,7 +53,7 @@ void EllipsisBox::paint(PaintInfo& paintInfo, int tx, int ty)
     }
 
     const String& str = m_str;
-    context->drawText(style->font(), TextRun(str.characters(), str.length(), false, 0, 0, false, style->visuallyOrdered()), IntPoint(m_x + tx, m_y + ty + style->font().ascent()));
+    context->drawText(style->font(), TextRun(str.characters(), str.length(), false, 0, 0, false, style->visuallyOrdered()), IntPoint(m_x + tx, m_y + ty + style->fontMetrics().ascent()));
 
     // Restore the regular fill color.
     if (textColor != context->fillColor())
@@ -65,7 +65,7 @@ void EllipsisBox::paint(PaintInfo& paintInfo, int tx, int ty)
     if (m_markupBox) {
         // Paint the markup box
         tx += m_x + m_logicalWidth - m_markupBox->x();
-        ty += m_y + style->font().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->font().ascent());
+        ty += m_y + style->fontMetrics().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->fontMetrics().ascent());
         m_markupBox->paint(paintInfo, tx, ty);
     }
 }
@@ -108,7 +108,7 @@ bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
     if (m_markupBox) {
         RenderStyle* style = m_renderer->style(m_firstLine);
         int mtx = tx + m_logicalWidth - m_markupBox->x();
-        int mty = ty + style->font().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->font().ascent());
+        int mty = ty + style->fontMetrics().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->fontMetrics().ascent());
         if (m_markupBox->nodeAtPoint(request, result, x, y, mtx, mty)) {
             renderer()->updateHitTestResult(result, IntPoint(x - mtx, y - mty));
             return true;
diff --git a/Source/WebCore/rendering/InlineBox.cpp b/Source/WebCore/rendering/InlineBox.cpp
index bbf5a74..4fcbe2d 100644
--- a/Source/WebCore/rendering/InlineBox.cpp
+++ b/Source/WebCore/rendering/InlineBox.cpp
@@ -94,14 +94,14 @@ int InlineBox::logicalHeight() const
 #endif
     
     if (renderer()->isText())
-        return m_isText ? renderer()->style(m_firstLine)->font().height() : 0;
+        return m_isText ? renderer()->style(m_firstLine)->fontMetrics().height() : 0;
     if (renderer()->isBox() && parent())
         return isHorizontal() ? toRenderBox(m_renderer)->height() : toRenderBox(m_renderer)->width();
 
     ASSERT(isInlineFlowBox());
     RenderBoxModelObject* flowObject = boxModelObject();
-    const Font& font = renderer()->style(m_firstLine)->font();
-    int result = font.height();
+    const FontMetrics& fontMetrics = renderer()->style(m_firstLine)->fontMetrics();
+    int result = fontMetrics.height();
     if (parent())
         result += flowObject->borderAndPaddingLogicalHeight();
     return result;
diff --git a/Source/WebCore/rendering/InlineFlowBox.cpp b/Source/WebCore/rendering/InlineFlowBox.cpp
index 75b23c5..5e141cc 100644
--- a/Source/WebCore/rendering/InlineFlowBox.cpp
+++ b/Source/WebCore/rendering/InlineFlowBox.cpp
@@ -408,6 +408,7 @@ static int verticalPositionForBox(InlineBox* box, FontBaseline baselineType, boo
         
         if (verticalAlign != BASELINE) {
             const Font& font = parent->style(firstLine)->font();
+            const FontMetrics& fontMetrics = font.fontMetrics();
             int fontSize = font.pixelSize();
 
             LineDirectionMode lineDirection = parent->style()->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
@@ -417,11 +418,11 @@ static int verticalPositionForBox(InlineBox* box, FontBaseline baselineType, boo
             else if (verticalAlign == SUPER)
                 verticalPosition -= fontSize / 3 + 1;
             else if (verticalAlign == TEXT_TOP)
-                verticalPosition += renderer->baselinePosition(baselineType, firstLine, lineDirection) - font.ascent(baselineType);
+                verticalPosition += renderer->baselinePosition(baselineType, firstLine, lineDirection) - fontMetrics.ascent(baselineType);
             else if (verticalAlign == MIDDLE)
-                verticalPosition += -static_cast<int>(font.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
+                verticalPosition += -static_cast<int>(fontMetrics.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
             else if (verticalAlign == TEXT_BOTTOM) {
-                verticalPosition += font.descent(baselineType);
+                verticalPosition += fontMetrics.descent(baselineType);
                 // lineHeight - baselinePosition is always 0 for replaced elements (except inline blocks), so don't bother wasting time in that case.
                 if (!renderer->isReplaced() || renderer->isInlineBlockOrInlineTable())
                     verticalPosition -= (renderer->lineHeight(firstLine, lineDirection) - renderer->baselinePosition(baselineType, firstLine, lineDirection));
@@ -503,9 +504,10 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
             baseline = 0;
             int baselineToBottom = 0;
             for (size_t i = 0; i < usedFonts->size(); ++i) {
-                int halfLeading = (usedFonts->at(i)->lineSpacing() - usedFonts->at(i)->height()) / 2;
-                int usedFontBaseline = halfLeading + usedFonts->at(i)->ascent(baselineType);
-                int usedFontBaselineToBottom = usedFonts->at(i)->lineSpacing() - usedFontBaseline;
+                const FontMetrics& fontMetrics = usedFonts->at(i)->fontMetrics();
+                int halfLeading = (fontMetrics.lineSpacing() - fontMetrics.height()) / 2;
+                int usedFontBaseline = halfLeading + fontMetrics.ascent(baselineType);
+                int usedFontBaselineToBottom = fontMetrics.lineSpacing() - usedFontBaseline;
                 if (!baselineSet) {
                     baselineSet = true;
                     baseline = usedFontBaseline;
@@ -515,9 +517,9 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
                     baselineToBottom = max(baselineToBottom, usedFontBaselineToBottom);
                 }
                 if (!affectsAscent)
-                    affectsAscent = usedFonts->at(i)->ascent() - curr->logicalTop() > 0;
+                    affectsAscent = fontMetrics.ascent() - curr->logicalTop() > 0;
                 if (!affectsDescent)
-                    affectsDescent = usedFonts->at(i)->descent() + curr->logicalTop() > 0;
+                    affectsDescent = fontMetrics.descent() + curr->logicalTop() > 0;
             }
             lineHeight = baseline + baselineToBottom;
         } else {
@@ -527,11 +529,12 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
                 // Examine the font box for inline flows and text boxes to see if any part of it is above the baseline.
                 // If the top of our font box relative to the root box baseline is above the root box baseline, then
                 // we are contributing to the maxAscent value.
-                affectsAscent = curr->renderer()->style(m_firstLine)->font().ascent(baselineType) - curr->logicalTop() > 0;
+                const FontMetrics& fontMetrics = curr->renderer()->style(m_firstLine)->fontMetrics();
+                affectsAscent = fontMetrics.ascent(baselineType) - curr->logicalTop() > 0;
                 
                 // Descent is similar.  If any part of our font box is below the root box's baseline, then
                 // we contribute to the maxDescent value.
-                affectsDescent = curr->renderer()->style(m_firstLine)->font().descent(baselineType) + curr->logicalTop() > 0;
+                affectsDescent = fontMetrics.descent(baselineType) + curr->logicalTop() > 0;
             } else {
                 // Replaced elements always affect both the ascent and descent.
                 affectsAscent = true;
@@ -606,8 +609,8 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
         int boxHeightIncludingMargins = boxHeight;
             
         if (curr->isText() || curr->isInlineFlowBox()) {
-            const Font& font = curr->renderer()->style(m_firstLine)->font();
-            newLogicalTop += curr->baselinePosition(baselineType) - font.ascent(baselineType);
+            const FontMetrics& fontMetrics = curr->renderer()->style(m_firstLine)->fontMetrics();
+            newLogicalTop += curr->baselinePosition(baselineType) - fontMetrics.ascent(baselineType);
             if (curr->isInlineFlowBox()) {
                 RenderBoxModelObject* boxObject = toRenderBoxModelObject(curr->renderer());
                 newLogicalTop -= boxObject->style(m_firstLine)->isHorizontalWritingMode() ? boxObject->borderTop() + boxObject->paddingTop() : 
@@ -668,8 +671,8 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
     }
 
     if (isRootInlineBox()) {
-        const Font& font = renderer()->style(m_firstLine)->font();
-        setLogicalTop(logicalTop() + baselinePosition(baselineType) - font.ascent(baselineType));
+        const FontMetrics& fontMetrics = renderer()->style(m_firstLine)->fontMetrics();
+        setLogicalTop(logicalTop() + baselinePosition(baselineType) - fontMetrics.ascent(baselineType));
         
         if (hasTextChildren() || strictMode) {
             if (!setLineTop) {
diff --git a/Source/WebCore/rendering/InlineTextBox.cpp b/Source/WebCore/rendering/InlineTextBox.cpp
index 71a3758..8a92450 100644
--- a/Source/WebCore/rendering/InlineTextBox.cpp
+++ b/Source/WebCore/rendering/InlineTextBox.cpp
@@ -485,7 +485,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
     IntPoint boxOrigin = locationIncludingFlipping();
     boxOrigin.move(tx, ty);    
     IntRect boxRect(boxOrigin, IntSize(logicalWidth(), logicalHeight()));
-    IntPoint textOrigin = IntPoint(boxOrigin.x(), boxOrigin.y() + styleToUse->font().ascent());
+    IntPoint textOrigin = IntPoint(boxOrigin.x(), boxOrigin.y() + styleToUse->fontMetrics().ascent());
 
     if (!isHorizontal()) {
         context->save();
@@ -626,7 +626,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
     bool hasTextEmphasis = getEmphasisMarkPosition(styleToUse, emphasisMarkPosition);
     const AtomicString& emphasisMark = hasTextEmphasis ? styleToUse->textEmphasisMarkString() : nullAtom;
     if (!emphasisMark.isEmpty())
-        emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ? -font.ascent() - font.emphasisMarkDescent(emphasisMark) : font.descent() + font.emphasisMarkAscent(emphasisMark);
+        emphasisMarkOffset = emphasisMarkPosition == TextEmphasisPositionOver ? -font.fontMetrics().ascent() - font.emphasisMarkDescent(emphasisMark) : font.fontMetrics().descent() + font.emphasisMarkAscent(emphasisMark);
 
     if (!paintSelectedTextOnly) {
         // For stroked painting, we have to change the text drawing mode.  It's probably dangerous to leave that mutated as a side
@@ -837,7 +837,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& bo
     bool linesAreOpaque = !isPrinting && (!(deco & UNDERLINE) || underline.alpha() == 255) && (!(deco & OVERLINE) || overline.alpha() == 255) && (!(deco & LINE_THROUGH) || linethrough.alpha() == 255);
 
     RenderStyle* styleToUse = renderer()->style(m_firstLine);
-    int baseline = styleToUse->font().ascent();
+    int baseline = styleToUse->fontMetrics().ascent();
 
     bool setClip = false;
     int extraOffset = 0;
@@ -970,7 +970,7 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntP
     // So, we generally place the underline at the bottom of the text, but in larger fonts that's not so good so
     // we pin to two pixels under the baseline.
     int lineThickness = cMisspellingLineThickness;
-    int baseline = renderer()->style(m_firstLine)->font().ascent();
+    int baseline = renderer()->style(m_firstLine)->fontMetrics().ascent();
     int descent = logicalHeight() - baseline;
     int underlineOffset;
     if (descent <= (2 + lineThickness)) {
@@ -1127,7 +1127,7 @@ void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const IntPoi
     // All other marked text underlines are 1px thick.
     // If there's not enough space the underline will touch or overlap characters.
     int lineThickness = 1;
-    int baseline = renderer()->style(m_firstLine)->font().ascent();
+    int baseline = renderer()->style(m_firstLine)->fontMetrics().ascent();
     if (underline.thick && logicalHeight() - baseline >= 2)
         lineThickness = 2;
 
diff --git a/Source/WebCore/rendering/RenderBlock.cpp b/Source/WebCore/rendering/RenderBlock.cpp
index bf10532..9535403 100644
--- a/Source/WebCore/rendering/RenderBlock.cpp
+++ b/Source/WebCore/rendering/RenderBlock.cpp
@@ -4958,8 +4958,8 @@ int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, Lin
         return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
     }
 
-    const Font& f = style(firstLine)->font();
-    return f.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
+    const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
+    return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
 }
 
 int RenderBlock::firstLineBoxBaseline() const
@@ -4969,7 +4969,7 @@ int RenderBlock::firstLineBoxBaseline() const
 
     if (childrenInline()) {
         if (firstLineBox())
-            return firstLineBox()->logicalTop() + style(true)->font().ascent(firstRootBox()->baselineType());
+            return firstLineBox()->logicalTop() + style(true)->fontMetrics().ascent(firstRootBox()->baselineType());
         else
             return -1;
     }
@@ -4995,11 +4995,13 @@ int RenderBlock::lastLineBoxBaseline() const
 
     if (childrenInline()) {
         if (!firstLineBox() && hasLineIfEmpty()) {
-            const Font& f = firstLineStyle()->font();
-            return f.ascent() + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f.height()) / 2 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
+            const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
+            return fontMetrics.ascent()
+                 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
+                 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
         }
         if (lastLineBox())
-            return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->font().ascent(lastRootBox()->baselineType());
+            return lastLineBox()->logicalTop() + style(lastLineBox() == firstLineBox())->fontMetrics().ascent(lastRootBox()->baselineType());
         return -1;
     } else {
         bool haveNormalFlowChild = false;
@@ -5012,8 +5014,10 @@ int RenderBlock::lastLineBoxBaseline() const
             }
         }
         if (!haveNormalFlowChild && hasLineIfEmpty()) {
-            const Font& f = firstLineStyle()->font();
-            return f.ascent() + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - f.height()) / 2 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
+            const FontMetrics& fontMetrics = firstLineStyle()->fontMetrics();
+            return fontMetrics.ascent()
+                 + (lineHeight(true, lineDirection, PositionOfInteriorLineBoxes) - fontMetrics.height()) / 2
+                 + (lineDirection == HorizontalLine ? borderTop() + paddingTop() : borderRight() + paddingRight());
         }
     }
 
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index 36c24b7..86ba374 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -2976,7 +2976,7 @@ IntRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, int* extraWid
     // <rdar://problem/3777804> Deleting all content in a document can result in giant tall-as-window insertion point
     //
     // FIXME: ignoring :first-line, missing good reason to take care of
-    int fontHeight = style()->font().height();
+    int fontHeight = style()->fontMetrics().height();
     if (fontHeight > rect.height() || (!isReplaced() && !isTable()))
         rect.setHeight(fontHeight);
 
diff --git a/Source/WebCore/rendering/RenderEmbeddedObject.cpp b/Source/WebCore/rendering/RenderEmbeddedObject.cpp
index 5486d51..cdd6c55 100644
--- a/Source/WebCore/rendering/RenderEmbeddedObject.cpp
+++ b/Source/WebCore/rendering/RenderEmbeddedObject.cpp
@@ -172,8 +172,9 @@ void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
     context->setFillColor(m_missingPluginIndicatorIsPressed ? replacementTextRoundedRectPressedColor() : Color::white, style()->colorSpace());
     context->fillPath(path);
 
+    const FontMetrics& fontMetrics = font.fontMetrics();
     float labelX = roundf(replacementTextRect.location().x() + (replacementTextRect.size().width() - textWidth) / 2);
-    float labelY = roundf(replacementTextRect.location().y() + (replacementTextRect.size().height() - font.height()) / 2 + font.ascent());
+    float labelY = roundf(replacementTextRect.location().y() + (replacementTextRect.size().height() - fontMetrics.height()) / 2 + fontMetrics.ascent());
     context->setAlpha(m_missingPluginIndicatorIsPressed ? replacementTextPressedTextOpacity : replacementTextTextOpacity);
     context->setFillColor(Color::black, style()->colorSpace());
     context->drawBidiText(font, run, FloatPoint(labelX, labelY));
diff --git a/Source/WebCore/rendering/RenderImage.cpp b/Source/WebCore/rendering/RenderImage.cpp
index 16a273b..ccc86a9 100644
--- a/Source/WebCore/rendering/RenderImage.cpp
+++ b/Source/WebCore/rendering/RenderImage.cpp
@@ -112,7 +112,7 @@ bool RenderImage::setImageSizeForAltText(CachedImage* newImage /* = 0 */)
     // we have an alt and the user meant it (its not a text we invented)
     if (!m_altText.isEmpty()) {
         const Font& font = style()->font();
-        IntSize textSize(min(font.width(TextRun(m_altText.characters(), m_altText.length())), maxAltTextWidth), min(font.height(), maxAltTextHeight));
+        IntSize textSize(min(font.width(TextRun(m_altText.characters(), m_altText.length())), maxAltTextWidth), min(font.fontMetrics().height(), maxAltTextHeight));
         imageSize = imageSize.expandedTo(textSize);
     }
 
@@ -289,17 +289,18 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
                 int ax = tx + leftBorder + leftPad;
                 int ay = ty + topBorder + topPad;
                 const Font& font = style()->font();
-                int ascent = font.ascent();
+                const FontMetrics& fontMetrics = font.fontMetrics();
+                int ascent = fontMetrics.ascent();
 
                 // Only draw the alt text if it'll fit within the content box,
                 // and only if it fits above the error image.
                 TextRun textRun(text.characters(), text.length());
                 int textWidth = font.width(textRun);
                 if (errorPictureDrawn) {
-                    if (usableWidth >= textWidth && font.height() <= imageY)
-                        context->drawText(style()->font(), textRun, IntPoint(ax, ay + ascent));
-                } else if (usableWidth >= textWidth && cHeight >= font.height())
-                    context->drawText(style()->font(), textRun, IntPoint(ax, ay + ascent));
+                    if (usableWidth >= textWidth && fontMetrics.height() <= imageY)
+                        context->drawText(font, textRun, IntPoint(ax, ay + ascent));
+                } else if (usableWidth >= textWidth && cHeight >= fontMetrics.height())
+                    context->drawText(font, textRun, IntPoint(ax, ay + ascent));
             }
         }
     } else if (m_imageResource->hasImage() && cWidth > 0 && cHeight > 0) {
diff --git a/Source/WebCore/rendering/RenderInline.cpp b/Source/WebCore/rendering/RenderInline.cpp
index 7466ace..b5ca8a4 100644
--- a/Source/WebCore/rendering/RenderInline.cpp
+++ b/Source/WebCore/rendering/RenderInline.cpp
@@ -905,8 +905,8 @@ int RenderInline::lineHeight(bool firstLine, LineDirectionMode /*direction*/, Li
 
 int RenderInline::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
 {
-    const Font& f = style(firstLine)->font();
-    return f.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - f.height()) / 2;
+    const FontMetrics& fontMetrics = style(firstLine)->fontMetrics();
+    return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
 }
 
 IntSize RenderInline::relativePositionedInlineOffset(const RenderBox* child) const
diff --git a/Source/WebCore/rendering/RenderListBox.cpp b/Source/WebCore/rendering/RenderListBox.cpp
index 90f13da..fcd78bf 100644
--- a/Source/WebCore/rendering/RenderListBox.cpp
+++ b/Source/WebCore/rendering/RenderListBox.cpp
@@ -303,7 +303,7 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, int tx, int ty, in
 
     // Determine where the item text should be placed
     IntRect r = itemBoundingBoxRect(tx, ty, listIndex);
-    r.move(optionsSpacingHorizontal, style()->font().ascent());
+    r.move(optionsSpacingHorizontal, style()->fontMetrics().ascent());
 
     RenderStyle* itemStyle = element->renderStyle();
     if (!itemStyle)
@@ -550,7 +550,7 @@ void RenderListBox::scrollTo(int newOffset)
 
 int RenderListBox::itemHeight() const
 {
-    return style()->font().height() + rowSpacing;
+    return style()->fontMetrics().height() + rowSpacing;
 }
 
 int RenderListBox::verticalScrollbarWidth() const
diff --git a/Source/WebCore/rendering/RenderListMarker.cpp b/Source/WebCore/rendering/RenderListMarker.cpp
index cd41c75..c096100 100644
--- a/Source/WebCore/rendering/RenderListMarker.cpp
+++ b/Source/WebCore/rendering/RenderListMarker.cpp
@@ -1265,7 +1265,7 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
         context->translate(-marker.x(), -marker.bottom());
     }
 
-    IntPoint textOrigin = IntPoint(marker.x(), marker.y() + style()->font().ascent());
+    IntPoint textOrigin = IntPoint(marker.x(), marker.y() + style()->fontMetrics().ascent());
 
     if (type == Asterisks || type == Footnotes)
         context->drawText(style()->font(), textRun, textOrigin);
@@ -1311,7 +1311,7 @@ void RenderListMarker::layout()
         setHeight(m_image->imageSize(this, style()->effectiveZoom()).height());
     } else {
         setLogicalWidth(minPreferredLogicalWidth());
-        setLogicalHeight(style()->font().height());
+        setLogicalHeight(style()->fontMetrics().height());
     }
 
     setMarginStart(0);
@@ -1346,11 +1346,12 @@ void RenderListMarker::computePreferredLogicalWidths()
     m_text = "";
 
     const Font& font = style()->font();
+    const FontMetrics& fontMetrics = font.fontMetrics();
 
     if (isImage()) {
         // FIXME: This is a somewhat arbitrary width.  Generated images for markers really won't become particularly useful
         // until we support the CSS3 marker pseudoclass to allow control over the width and height of the marker box.
-        int bulletWidth = font.ascent() / 2;
+        int bulletWidth = fontMetrics.ascent() / 2;
         m_image->setImageContainerSize(IntSize(bulletWidth, bulletWidth));
         IntSize imageSize = m_image->imageSize(this, style()->effectiveZoom());
         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = style()->isHorizontalWritingMode() ? imageSize.width() : imageSize.height();
@@ -1373,7 +1374,7 @@ void RenderListMarker::computePreferredLogicalWidths()
         case Disc:
         case Square:
             m_text = listMarkerText(type, 0); // value is ignored for these types
-            logicalWidth = (font.ascent() * 2 / 3 + 1) / 2 + 2;
+            logicalWidth = (fontMetrics.ascent() * 2 / 3 + 1) / 2 + 2;
             break;
         case Afar:
         case Amharic:
@@ -1472,7 +1473,7 @@ void RenderListMarker::computePreferredLogicalWidths()
 
 void RenderListMarker::updateMargins()
 {
-    const Font& font = style()->font();
+    const FontMetrics& fontMetrics = style()->fontMetrics();
 
     int marginStart = 0;
     int marginEnd = 0;
@@ -1485,7 +1486,7 @@ void RenderListMarker::updateMargins()
             case Circle:
             case Square:
                 marginStart = -1;
-                marginEnd = font.ascent() - minPreferredLogicalWidth() + 1;
+                marginEnd = fontMetrics.ascent() - minPreferredLogicalWidth() + 1;
                 break;
             default:
                 break;
@@ -1495,7 +1496,7 @@ void RenderListMarker::updateMargins()
             if (isImage())
                 marginStart = -minPreferredLogicalWidth() - cMarkerPadding;
             else {
-                int offset = font.ascent() * 2 / 3;
+                int offset = fontMetrics.ascent() * 2 / 3;
                 switch (style()->listStyleType()) {
                     case Disc:
                     case Circle:
@@ -1513,7 +1514,7 @@ void RenderListMarker::updateMargins()
             if (isImage())
                 marginEnd = cMarkerPadding;
             else {
-                int offset = font.ascent() * 2 / 3;
+                int offset = fontMetrics.ascent() * 2 / 3;
                 switch (style()->listStyleType()) {
                     case Disc:
                     case Circle:
@@ -1584,15 +1585,15 @@ IntRect RenderListMarker::getRelativeMarkerRect()
         case Asterisks:
         case Footnotes: {
             const Font& font = style()->font();
-            relativeRect = IntRect(0, 0, font.width(m_text), font.height());
+            relativeRect = IntRect(0, 0, font.width(m_text), font.fontMetrics().height());
             break;
         }
         case Disc:
         case Circle:
         case Square: {
             // FIXME: Are these particular rounding rules necessary?
-            const Font& font = style()->font();
-            int ascent = font.ascent();
+            const FontMetrics& fontMetrics = style()->fontMetrics();
+            int ascent = fontMetrics.ascent();
             int bulletWidth = (ascent * 2 / 3 + 1) / 2;
             relativeRect = IntRect(1, 3 * (ascent - ascent * 2 / 3) / 2, bulletWidth, bulletWidth);
             break;
@@ -1680,7 +1681,7 @@ IntRect RenderListMarker::getRelativeMarkerRect()
             int itemWidth = font.width(m_text);
             UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' };
             int suffixSpaceWidth = font.width(TextRun(suffixSpace, 2));
-            relativeRect = IntRect(0, 0, itemWidth + suffixSpaceWidth, font.height());
+            relativeRect = IntRect(0, 0, itemWidth + suffixSpaceWidth, font.fontMetrics().height());
     }
 
     if (!style()->isHorizontalWritingMode()) {
diff --git a/Source/WebCore/rendering/RenderTextControl.cpp b/Source/WebCore/rendering/RenderTextControl.cpp
index cac8113..91ed262 100644
--- a/Source/WebCore/rendering/RenderTextControl.cpp
+++ b/Source/WebCore/rendering/RenderTextControl.cpp
@@ -644,7 +644,7 @@ void RenderTextControl::paintPlaceholder(PaintInfo& paintInfo, int tx, int ty)
     RenderBox* textRenderer = innerTextElement() ? innerTextElement()->renderBox() : 0;
     if (textRenderer) {
         IntPoint textPoint;
-        textPoint.setY(ty + textBlockInsetTop() + placeholderStyle->font().ascent());
+        textPoint.setY(ty + textBlockInsetTop() + placeholderStyle->fontMetrics().ascent());
         if (placeholderStyle->isLeftToRightDirection())
             textPoint.setX(tx + textBlockInsetLeft());
         else
diff --git a/Source/WebCore/rendering/RenderTextControlSingleLine.cpp b/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
index 306e8ba..603e74b 100644
--- a/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -708,7 +708,7 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const
     textBlockStyle->setOverflowY(OHIDDEN);
 
     // Do not allow line-height to be smaller than our default.
-    if (textBlockStyle->font().lineSpacing() > lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes))
+    if (textBlockStyle->fontMetrics().lineSpacing() > lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes))
         textBlockStyle->setLineHeight(Length(-100.0f, Percent));
 
     WebCore::EDisplay display = (m_innerBlock || inputElement()->hasSpinButton() ? INLINE_BLOCK : BLOCK);
diff --git a/Source/WebCore/rendering/RenderThemeWin.cpp b/Source/WebCore/rendering/RenderThemeWin.cpp
index f0f8268..d0daaa8 100644
--- a/Source/WebCore/rendering/RenderThemeWin.cpp
+++ b/Source/WebCore/rendering/RenderThemeWin.cpp
@@ -769,7 +769,7 @@ void RenderThemeWin::adjustMenuListButtonStyle(CSSStyleSelector* selector, Rende
     style->setHeight(Length(Auto));
 
     // Calculate our min-height
-    int minHeight = style->font().height();
+    int minHeight = style->fontMetrics().height();
     minHeight = max(minHeight, dropDownBoxMinHeight);
 
     style->setMinHeight(Length(minHeight, Fixed));
diff --git a/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp b/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
index 9d80fbe..48d3f39 100644
--- a/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
+++ b/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp
@@ -176,7 +176,7 @@ int RenderMathMLFraction::baselinePosition(FontBaseline, bool firstLine, LineDir
             refStyle = previousSibling()->style();
         else if (nextSibling())
             refStyle = nextSibling()->style();
-        int shift = int(ceil((refStyle->font().xHeight() + 1) / 2));
+        int shift = int(ceil((refStyle->fontMetrics().xHeight() + 1) / 2));
         return numerator->offsetHeight() + shift;
     }
     return RenderBlock::baselinePosition(AlphabeticBaseline, firstLine, lineDirection, linePositionMode);
diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h
index 75ba048..7a81b35 100644
--- a/Source/WebCore/rendering/style/RenderStyle.h
+++ b/Source/WebCore/rendering/style/RenderStyle.h
@@ -463,6 +463,7 @@ public:
     ETableLayout tableLayout() const { return static_cast<ETableLayout>(noninherited_flags._table_layout); }
 
     const Font& font() const { return inherited->font; }
+    const FontMetrics& fontMetrics() const { return inherited->font.fontMetrics(); }
     const FontDescription& fontDescription() const { return inherited->font.fontDescription(); }
     int fontSize() const { return inherited->font.pixelSize(); }
 
@@ -487,7 +488,7 @@ public:
 
         // Negative value means the line height is not set.  Use the font's built-in spacing.
         if (lh.isNegative())
-            return font().lineSpacing();
+            return fontMetrics().lineSpacing();
 
         if (lh.isPercent())
             return lh.calcMinValue(fontSize());
diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
index 91ffb5c..ce2609d 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
@@ -161,7 +161,7 @@ VisiblePosition RenderSVGInlineText::positionForPoint(const IntPoint& point)
 
     RenderStyle* style = this->style();
     ASSERT(style);
-    int baseline = style->font().ascent();
+    int baseline = style->fontMetrics().ascent();
 
     RenderBlock* containingBlock = this->containingBlock();
     ASSERT(containingBlock);
diff --git a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
index 2879f20..257a8c5 100644
--- a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
+++ b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
@@ -84,7 +84,7 @@ FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment&
     ASSERT(startPosition < endPosition);
 
     const Font& font = style->font();
-    FloatPoint textOrigin(fragment.x, fragment.y - font.ascent());
+    FloatPoint textOrigin(fragment.x, fragment.y - font.fontMetrics().ascent());
     return font.selectionRectForText(constructTextRun(style, fragment), textOrigin, fragment.height, startPosition, endPosition);
 }
 
@@ -409,16 +409,16 @@ bool SVGInlineTextBox::mapStartEndPositionsIntoFragmentCoordinates(const SVGText
     return true;
 }
 
-static inline float positionOffsetForDecoration(ETextDecoration decoration, const Font& font, float thickness)
+static inline float positionOffsetForDecoration(ETextDecoration decoration, const FontMetrics& fontMetrics, float thickness)
 {
     // FIXME: For SVG Fonts we need to use the attributes defined in the <font-face> if specified.
     // Compatible with Batik/Opera.
     if (decoration == UNDERLINE)
-        return font.ascent() + thickness * 1.5f;
+        return fontMetrics.ascent() + thickness * 1.5f;
     if (decoration == OVERLINE)
         return thickness;
     if (decoration == LINE_THROUGH)
-        return font.ascent() * 5.0f / 8.0f;
+        return fontMetrics.ascent() * 5.0f / 8.0f;
 
     ASSERT_NOT_REACHED();
     return 0.0f;
@@ -487,6 +487,7 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, ETextD
     ASSERT(decorationStyle);
 
     const Font& font = decorationStyle->font();
+    const FontMetrics& fontMetrics = font.fontMetrics();
 
     // The initial y value refers to overline position.
     float thickness = thicknessForDecoration(decoration, font);
@@ -494,7 +495,7 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, ETextD
     if (fragment.width <= 0 && thickness <= 0)
         return;
 
-    float y = fragment.y - font.ascent() + positionOffsetForDecoration(decoration, font, thickness);
+    float y = fragment.y - fontMetrics.ascent() + positionOffsetForDecoration(decoration, fontMetrics, thickness);
 
     Path path;
     path.addRect(FloatRect(fragment.x, y, fragment.width, thickness));
@@ -513,7 +514,7 @@ void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyl
     const ShadowData* shadow = style->textShadow();
 
     FloatPoint textOrigin(fragment.x, fragment.y);
-    FloatRect shadowRect(FloatPoint(textOrigin.x(), textOrigin.y() - font.ascent()), FloatSize(fragment.width, fragment.height));
+    FloatRect shadowRect(FloatPoint(textOrigin.x(), textOrigin.y() - font.fontMetrics().ascent()), FloatSize(fragment.width, fragment.height));
 
     do {
         if (!prepareGraphicsContextForTextPainting(context, textRun, style))
@@ -587,7 +588,7 @@ IntRect SVGInlineTextBox::calculateBoundaries() const
     ASSERT(style);
 
     int baseline = baselinePosition(AlphabeticBaseline);
-    int heightDifference = baseline - style->font().ascent();
+    int heightDifference = baseline - style->fontMetrics().ascent();
 
     unsigned textFragmentsSize = m_textFragments.size();
     for (unsigned i = 0; i < textFragmentsSize; ++i) {
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp
index 3863322..e30e9c5 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp
@@ -49,9 +49,9 @@ float SVGTextLayoutEngineBaseline::calculateBaselineShift(const SVGRenderStyle*
     case BS_BASELINE:
         return 0;
     case BS_SUB:
-        return -m_font.height() / 2;
+        return -m_font.fontMetrics().height() / 2;
     case BS_SUPER:
-        return m_font.height() / 2;
+        return m_font.fontMetrics().height() / 2;
     default:
         ASSERT_NOT_REACHED();
         return 0;
@@ -122,27 +122,29 @@ float SVGTextLayoutEngineBaseline::calculateAlignmentBaselineShift(bool isVertic
         ASSERT(baseline != AB_AUTO);
     }
 
+    const FontMetrics& fontMetrics = m_font.fontMetrics();
+
     // Note: http://wiki.apache.org/xmlgraphics-fop/LineLayout/AlignmentHandling
     switch (baseline) {
     case AB_BASELINE:
         return dominantBaselineToAlignmentBaseline(isVerticalText, textRendererParent);
     case AB_BEFORE_EDGE:
     case AB_TEXT_BEFORE_EDGE:
-        return m_font.ascent();
+        return fontMetrics.ascent();
     case AB_MIDDLE:
-        return m_font.xHeight() / 2;
+        return fontMetrics.xHeight() / 2;
     case AB_CENTRAL:
-        return (m_font.ascent() - m_font.descent()) / 2;
+        return (fontMetrics.ascent() - fontMetrics.descent()) / 2;
     case AB_AFTER_EDGE:
     case AB_TEXT_AFTER_EDGE:
     case AB_IDEOGRAPHIC:
-        return m_font.descent();
+        return fontMetrics.descent();
     case AB_ALPHABETIC:
         return 0;
     case AB_HANGING:
-        return m_font.ascent() * 8 / 10.f;
+        return fontMetrics.ascent() * 8 / 10.f;
     case AB_MATHEMATICAL:
-        return m_font.ascent() / 2;
+        return fontMetrics.ascent() / 2;
     default:
         ASSERT_NOT_REACHED();
         return 0;
@@ -192,12 +194,14 @@ float SVGTextLayoutEngineBaseline::calculateGlyphAdvanceAndOrientation(bool isVe
     // Spec: If if the 'glyph-orientation-vertical' results in an orientation angle that is not a multiple of
     // 180 degrees, then the current text position is incremented according to the horizontal metrics of the glyph.
 
+    const FontMetrics& fontMetrics = m_font.fontMetrics();
+
     // Vertical orientation handling.
     if (isVerticalText) {
-        float ascentMinusDescent = m_font.ascent() - m_font.descent();
+        float ascentMinusDescent = fontMetrics.ascent() - fontMetrics.descent();
         if (!angle) {
             xOrientationShift = (ascentMinusDescent - metrics.width()) / 2;
-            yOrientationShift = m_font.ascent();
+            yOrientationShift = fontMetrics.ascent();
         } else if (angle == 180)
             xOrientationShift = (ascentMinusDescent + metrics.width()) / 2;
         else if (angle == 270) {
@@ -217,7 +221,7 @@ float SVGTextLayoutEngineBaseline::calculateGlyphAdvanceAndOrientation(bool isVe
         yOrientationShift = -metrics.width();
     else if (angle == 180) {
         xOrientationShift = metrics.width();
-        yOrientationShift = -m_font.ascent();
+        yOrientationShift = -fontMetrics.ascent();
     } else if (angle == 270)
         xOrientationShift = metrics.width();
 
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
index 6c54b67..e9aa127 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
@@ -58,7 +58,7 @@ float SVGTextLayoutEngineSpacing::calculateSVGKerning(bool isVerticalText, const
 
     m_lastGlyph = currentGlyph;
     m_lastGlyph.isValid = true;
-    kerning *= m_font.size() / m_font.primaryFont()->unitsPerEm();
+    kerning *= m_font.size() / m_font.fontMetrics().unitsPerEm();
     return kerning;
 #else
     UNUSED_PARAM(isVerticalText);
diff --git a/Source/WebCore/rendering/svg/SVGTextMetrics.cpp b/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
index ec8c2c6..0367318 100644
--- a/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
@@ -43,7 +43,7 @@ SVGTextMetrics::SVGTextMetrics(const Font& font, const TextRun& run, unsigned po
     int length = 0;
 
     m_width = font.floatWidth(run, extraCharsAvailable, length, m_glyph.name);
-    m_height = font.height();
+    m_height = font.fontMetrics().height();
     m_glyph.unicodeString = String(run.characters(), length);
     m_glyph.isValid = true;
 
diff --git a/Source/WebCore/rendering/svg/SVGTextQuery.cpp b/Source/WebCore/rendering/svg/SVGTextQuery.cpp
index 42d511b..2c11c85 100644
--- a/Source/WebCore/rendering/svg/SVGTextQuery.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextQuery.cpp
@@ -472,7 +472,7 @@ struct ExtentOfCharacterData : SVGTextQuery::Data {
 
 static inline void calculateGlyphBoundaries(SVGTextQuery::Data* queryData, const SVGTextFragment& fragment, int startPosition, FloatRect& extent)
 {
-    extent.setLocation(FloatPoint(fragment.x, fragment.y - queryData->textRenderer->style()->font().ascent()));
+    extent.setLocation(FloatPoint(fragment.x, fragment.y - queryData->textRenderer->style()->fontMetrics().ascent()));
 
     if (startPosition) {
         SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.positionListOffset, startPosition);
diff --git a/Source/WebCore/svg/SVGFontFaceElement.cpp b/Source/WebCore/svg/SVGFontFaceElement.cpp
index ef7f5bd..7af22be 100644
--- a/Source/WebCore/svg/SVGFontFaceElement.cpp
+++ b/Source/WebCore/svg/SVGFontFaceElement.cpp
@@ -125,7 +125,7 @@ unsigned SVGFontFaceElement::unitsPerEm() const
 {
     const AtomicString& value = getAttribute(units_per_emAttr);
     if (value.isEmpty())
-        return defaultUnitsPerEm;
+        return gDefaultUnitsPerEm;
 
     return static_cast<unsigned>(ceilf(value.toFloat()));
 }
diff --git a/Source/WebCore/svg/SVGLength.cpp b/Source/WebCore/svg/SVGLength.cpp
index 6d75f8b..281ee14 100644
--- a/Source/WebCore/svg/SVGLength.cpp
+++ b/Source/WebCore/svg/SVGLength.cpp
@@ -438,7 +438,7 @@ float SVGLength::convertValueFromUserUnitsToEXS(float value, const SVGElement* c
 
     // Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg
     // if this causes problems in real world cases maybe it would be best to remove this
-    float xHeight = ceilf(style->font().xHeight());
+    float xHeight = ceilf(style->fontMetrics().xHeight());
     if (!xHeight) {
         ec = NOT_SUPPORTED_ERR;
         return 0;
@@ -457,7 +457,7 @@ float SVGLength::convertValueFromEXSToUserUnits(float value, const SVGElement* c
     RenderStyle* style = context->renderer()->style();
     // Use of ceil allows a pixel match to the W3Cs expected output of coords-units-03-b.svg
     // if this causes problems in real world cases maybe it would be best to remove this
-    return value * ceilf(style->font().xHeight());
+    return value * ceilf(style->fontMetrics().xHeight());
 }
 
 SVGLength SVGLength::fromCSSPrimitiveValue(CSSPrimitiveValue* value)
diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog
index ef4b2fb..740f798 100644
--- a/Source/WebKit/chromium/ChangeLog
+++ b/Source/WebKit/chromium/ChangeLog
@@ -1,3 +1,19 @@
+2011-01-21  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        Introduce FontMetrics abstraction
+        https://bugs.webkit.org/show_bug.cgi?id=51456
+
+        * src/ExternalPopupMenu.cpp: Use FontMetrics instead of Font to access the metrics.
+        (WebKit::ExternalPopupMenu::getPopupMenuInfo):
+        * src/WebFontImpl.cpp: Ditto.
+        (WebKit::WebFontImpl::ascent):
+        (WebKit::WebFontImpl::descent):
+        (WebKit::WebFontImpl::height):
+        (WebKit::WebFontImpl::lineSpacing):
+        (WebKit::WebFontImpl::xHeight):
+
 2011-01-21  Chris Rogers  <crogers at google.com>
 
         Unreviewed
diff --git a/Source/WebKit/chromium/src/ExternalPopupMenu.cpp b/Source/WebKit/chromium/src/ExternalPopupMenu.cpp
index f7f9862..84dda40 100644
--- a/Source/WebKit/chromium/src/ExternalPopupMenu.cpp
+++ b/Source/WebKit/chromium/src/ExternalPopupMenu.cpp
@@ -142,7 +142,7 @@ void ExternalPopupMenu::getPopupMenuInfo(WebPopupMenuInfo* info)
         popupItem.enabled = m_popupMenuClient->itemIsEnabled(i);
     }
 
-    info->itemHeight = m_popupMenuClient->menuStyle().font().height();
+    info->itemHeight = m_popupMenuClient->menuStyle().font().fontMetrics().height();
     info->itemFontSize =
         static_cast<int>(m_popupMenuClient->menuStyle().font().size());
     info->selectedIndex = m_popupMenuClient->selectedIndex();
diff --git a/Source/WebKit/chromium/src/WebFontImpl.cpp b/Source/WebKit/chromium/src/WebFontImpl.cpp
index e1fa0e7..cb37896 100644
--- a/Source/WebKit/chromium/src/WebFontImpl.cpp
+++ b/Source/WebKit/chromium/src/WebFontImpl.cpp
@@ -64,27 +64,27 @@ WebFontDescription WebFontImpl::fontDescription() const
 
 int WebFontImpl::ascent() const
 {
-    return m_font.ascent();
+    return m_font.fontMetrics().ascent();
 }
 
 int WebFontImpl::descent() const
 {
-    return m_font.descent();
+    return m_font.fontMetrics().descent();
 }
 
 int WebFontImpl::height() const
 {
-    return m_font.height();
+    return m_font.fontMetrics().height();
 }
 
 int WebFontImpl::lineSpacing() const
 {
-    return m_font.lineSpacing();
+    return m_font.fontMetrics().lineSpacing();
 }
 
 float WebFontImpl::xHeight() const
 {
-    return m_font.xHeight();
+    return m_font.fontMetrics().xHeight();
 }
 
 void WebFontImpl::drawText(WebCanvas* canvas, const WebTextRun& run, const WebFloatPoint& leftBaseline,
diff --git a/Source/WebKit/win/ChangeLog b/Source/WebKit/win/ChangeLog
index 6a3b53c..e60e1d9 100644
--- a/Source/WebKit/win/ChangeLog
+++ b/Source/WebKit/win/ChangeLog
@@ -1,3 +1,17 @@
+2011-01-21  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        Introduce FontMetrics abstraction
+        https://bugs.webkit.org/show_bug.cgi?id=51456
+
+        * FullscreenVideoController.cpp: Use FontMetrics instead of Font to access the metrics.
+        (FullscreenVideoController::draw):
+        * WebCoreSupport/WebDragClient.cpp: Ditto.
+        (WebDragClient::createDragImageForLink):
+        * WebKitGraphics.cpp: Ditto.
+        (FontMetrics):
+
 2011-01-21  Chris Rogers  <crogers at google.com>
 
         Reviewed by Darin Fisher.
diff --git a/Source/WebKit/win/FullscreenVideoController.cpp b/Source/WebKit/win/FullscreenVideoController.cpp
index ab954f8..6adbcaa 100644
--- a/Source/WebKit/win/FullscreenVideoController.cpp
+++ b/Source/WebKit/win/FullscreenVideoController.cpp
@@ -532,15 +532,16 @@ void FullscreenVideoController::draw()
     // the text at the center of the slider.
     // Left string
     s = timeToString(currentTime());
+    int fontHeight = font.fontMetrics().height();
     TextRun leftText(s);
     context.setFillColor(Color(textColor), ColorSpaceDeviceRGB);
-    context.drawText(font, leftText, IntPoint(windowWidth / 2 - timeSliderWidth / 2 - margin - font.width(leftText), windowHeight - margin - sliderHeight / 2 + font.height() / 4));
+    context.drawText(font, leftText, IntPoint(windowWidth / 2 - timeSliderWidth / 2 - margin - font.width(leftText), windowHeight - margin - sliderHeight / 2 + fontHeight / 4));
 
     // Right string
     s = timeToString(currentTime() - duration());
     TextRun rightText(s);
     context.setFillColor(Color(textColor), ColorSpaceDeviceRGB);
-    context.drawText(font, rightText, IntPoint(windowWidth / 2 + timeSliderWidth / 2 + margin, windowHeight - margin - sliderHeight / 2 + font.height() / 4));
+    context.drawText(font, rightText, IntPoint(windowWidth / 2 + timeSliderWidth / 2 + margin, windowHeight - margin - sliderHeight / 2 + fontHeight / 4));
 
     // Copy to the window
     BLENDFUNCTION blendFunction = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
diff --git a/Source/WebKit/win/WebCoreSupport/WebDragClient.cpp b/Source/WebKit/win/WebCoreSupport/WebDragClient.cpp
index 184df95..3ec19c4 100644
--- a/Source/WebKit/win/WebCoreSupport/WebDragClient.cpp
+++ b/Source/WebKit/win/WebCoreSupport/WebDragClient.cpp
@@ -248,7 +248,7 @@ DragImageRef WebDragClient::createDragImageForLink(KURL& url, const String& inLa
     //First step in drawing the link drag image width
     TextRun labelRun(label.impl());
     TextRun urlRun(urlString.impl());
-    IntSize labelSize(labelFont->width(labelRun), labelFont->ascent() + labelFont->descent());
+    IntSize labelSize(labelFont->width(labelRun), labelFont->fontMetrics().ascent() + labelFont->fontMetrics().descent());
 
     if (labelSize.width() > MAX_DRAG_LABEL_STRING_WIDTH){
         labelSize.setWidth(MAX_DRAG_LABEL_STRING_WIDTH);
@@ -261,7 +261,7 @@ DragImageRef WebDragClient::createDragImageForLink(KURL& url, const String& inLa
 
     if (drawURLString) {
         urlStringSize.setWidth(urlFont->width(urlRun));
-        urlStringSize.setHeight(urlFont->ascent() + urlFont->descent()); 
+        urlStringSize.setHeight(urlFont->fontMetrics().ascent() + urlFont->fontMetrics().descent()); 
         imageSize.setHeight(imageSize.height() + urlStringSize.height());
         if (urlStringSize.width() > MAX_DRAG_LABEL_STRING_WIDTH) {
             imageSize.setWidth(MAX_DRAG_LABEL_WIDTH);
@@ -304,7 +304,7 @@ DragImageRef WebDragClient::createDragImageForLink(KURL& url, const String& inLa
     if (drawURLString) {
         if (clipURLString)
             urlString = StringTruncator::rightTruncate(urlString, imageSize.width() - (DRAG_LABEL_BORDER_X * 2.0f), *urlFont, false);
-        IntPoint textPos(DRAG_LABEL_BORDER_X, imageSize.height() - (DRAG_LABEL_BORDER_Y_OFFSET + urlFont->descent()));
+        IntPoint textPos(DRAG_LABEL_BORDER_X, imageSize.height() - (DRAG_LABEL_BORDER_Y_OFFSET + urlFont->fontMetrics().descent()));
         WebCoreDrawDoubledTextAtPoint(context, urlString, textPos, *urlFont, topColor, bottomColor);
     }
     
diff --git a/Source/WebKit/win/WebKitGraphics.cpp b/Source/WebKit/win/WebKitGraphics.cpp
index 5343608..16a3950 100644
--- a/Source/WebKit/win/WebKitGraphics.cpp
+++ b/Source/WebKit/win/WebKitGraphics.cpp
@@ -133,15 +133,16 @@ void FontMetrics(const WebFontDescription& description, int* ascent, int* descen
         return;
 
     Font font(makeFont(description));
+    const WebCore::FontMetrics& fontMetrics(font.fontMetrics());
 
     if (ascent)
-        *ascent = font.ascent();
+        *ascent = fontMetrics.ascent();
 
     if (descent)
-        *descent = font.descent();
+        *descent = fontMetrics.descent();
 
     if (lineSpacing)
-        *lineSpacing = font.lineSpacing();
+        *lineSpacing = fontMetrics.lineSpacing();
 }
 
 unsigned CenterTruncateStringToWidth(LPCTSTR text, int length, const WebFontDescription& description, float width, WCHAR* buffer)
diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog
index e11a18e..be31bbb 100644
--- a/Source/WebKit2/ChangeLog
+++ b/Source/WebKit2/ChangeLog
@@ -1,3 +1,13 @@
+2011-01-21  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Dirk Schulze.
+
+        Introduce FontMetrics abstraction
+        https://bugs.webkit.org/show_bug.cgi?id=51456
+
+        * WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp: Use FontMetrics instead of Font to access the metrics.
+        (WebKit::WebPopupMenu::setUpPlatformData):
+
 2011-01-22  Alexey Proskuryakov  <ap at apple.com>
 
         Reviewed by Dan Bernstein.
diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp
index 9c23133..9fdfe2f 100644
--- a/Source/WebKit2/WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp
+++ b/Source/WebKit2/WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp
@@ -49,7 +49,7 @@ void WebPopupMenu::setUpPlatformData(const WebCore::IntRect& pageCoordinates, Pl
     data.m_clientPaddingRight = m_popupClient->clientPaddingRight();
     data.m_clientInsetLeft = m_popupClient->clientInsetLeft();
     data.m_clientInsetRight = m_popupClient->clientInsetRight();
-    data.m_itemHeight = m_popupClient->menuStyle().font().height() + 1;
+    data.m_itemHeight = m_popupClient->menuStyle().font().fontMetrics().height() + 1;
 
     int popupWidth = 0;
     for (size_t i = 0; i < itemCount; ++i) {
@@ -133,7 +133,7 @@ void WebPopupMenu::setUpPlatformData(const WebCore::IntRect& pageCoordinates, Pl
             int textX = std::max(0, data.m_clientPaddingLeft - data.m_clientInsetLeft);
             if (RenderTheme::defaultTheme()->popupOptionSupportsTextIndent() && itemStyle.textDirection() == LTR)
                 textX += itemStyle.textIndent().calcMinValue(itemRect.width());
-            int textY = itemRect.y() + itemFont.ascent() + (itemRect.height() - itemFont.height()) / 2;
+            int textY = itemRect.y() + itemFont.fontMetrics().ascent() + (itemRect.height() - itemFont.fontMetrics().height()) / 2;
 
             notSelectedBackingStoreContext->drawBidiText(itemFont, textRun, IntPoint(textX, textY));
             selectedBackingStoreContext->drawBidiText(itemFont, textRun, IntPoint(textX, textY));

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list