https://bugs.webkit.org/show_bug.cgi?id=54244
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Feb 2011 19:19:07 +0000 (19:19 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 17 Feb 2011 19:19:07 +0000 (19:19 +0000)
Reviewed by Dan Bernstein.

Convert the line box tree to floating point and eliminate font rounding hacks.  This patch removes all of the rounding
hacks from the Font code and makes sure all Font APIs involving width measurement and width offsets use floats.

The line box tree's x, y and logicalWidth members have all been converted to floats and all of the line box APIs have
been changed as well.

In terms of pixel adjustments, overflow is using an enclosing model (so it will be enclosingIntRect of a line box's x/y/width/height).

Background and border painting is using a rounding model, so borders and backgrounds will round to the nearest pixel when painting.

Replaced elements still snap to integer positions on lines, and they use a rounding model as well, although their underlying line boxes
still have a precise floating point position.

Justification will now allow subpixel positioning to occur as well.  Platforms that don't support subpixel positioning should already
be rounding justification spacing in their font code.

Many layout test results change on Mac, since rounding hacks were used there and are now gone.

../WebCore:

* WebCore.exp.in:
* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::drawTextInternal):
* platform/chromium/FileChooserChromium.cpp:
(WebCore::FileChooser::basenameForWidth):
* platform/graphics/Font.cpp:
(WebCore::Font::width):
* platform/graphics/Font.h:
(WebCore::Font::spaceWidth):
(WebCore::Font::tabWidth):
* platform/graphics/FontFastPath.cpp:
(WebCore::Font::getGlyphsAndAdvancesForSimpleText):
* platform/graphics/GraphicsContext.cpp:
(WebCore::GraphicsContext::drawText):
(WebCore::GraphicsContext::drawEmphasisMarks):
(WebCore::GraphicsContext::drawBidiText):
(WebCore::GraphicsContext::drawHighlightForText):
* platform/graphics/GraphicsContext.h:
* platform/graphics/SimpleFontData.cpp:
(WebCore::SimpleFontData::SimpleFontData):
(WebCore::SimpleFontData::platformGlyphInit):
* platform/graphics/SimpleFontData.h:
(WebCore::SimpleFontData::spaceWidth):
* platform/graphics/StringTruncator.cpp:
(WebCore::stringWidth):
(WebCore::truncateString):
(WebCore::StringTruncator::centerTruncate):
(WebCore::StringTruncator::rightTruncate):
(WebCore::StringTruncator::width):
* platform/graphics/StringTruncator.h:
* platform/graphics/TextRun.h:
(WebCore::TextRun::TextRun):
(WebCore::TextRun::xPos):
(WebCore::TextRun::expansion):
(WebCore::TextRun::directionalOverride):
(WebCore::TextRun::disableSpacing):
* platform/graphics/WidthIterator.cpp:
(WebCore::WidthIterator::WidthIterator):
(WebCore::WidthIterator::advance):
* platform/graphics/WidthIterator.h:
* platform/graphics/cairo/GraphicsContextCairo.cpp:
(WebCore::GraphicsContext::drawLineForText):
(WebCore::GraphicsContext::drawLineForTextChecking):
* platform/graphics/cg/GraphicsContextCG.cpp:
(WebCore::GraphicsContext::drawLineForText):
* platform/graphics/mac/ComplexTextController.cpp:
(WebCore::ComplexTextController::ComplexTextController):
(WebCore::ComplexTextController::advance):
(WebCore::ComplexTextController::adjustGlyphsAndAdvances):
* platform/graphics/mac/ComplexTextController.h:
* platform/graphics/mac/FontComplexTextMac.cpp:
(WebCore::Font::getGlyphsAndAdvancesForComplexText):
* platform/graphics/mac/GraphicsContextMac.mm:
(WebCore::GraphicsContext::drawLineForTextChecking):
* platform/graphics/qt/GraphicsContextQt.cpp:
(WebCore::GraphicsContext::drawLineForText):
(WebCore::GraphicsContext::drawLineForTextChecking):
* platform/graphics/qt/SimpleFontDataQt.cpp:
(WebCore::SimpleFontData::platformGlyphInit):
* platform/graphics/skia/GraphicsContextSkia.cpp:
(WebCore::GraphicsContext::drawLineForTextChecking):
(WebCore::GraphicsContext::drawLineForText):
* platform/graphics/win/GraphicsContextCGWin.cpp:
(WebCore::GraphicsContext::drawLineForTextChecking):
* platform/graphics/win/UniscribeController.cpp:
(WebCore::UniscribeController::shapeAndPlaceItem):
* platform/gtk/FileChooserGtk.cpp:
(WebCore::FileChooser::basenameForWidth):
* platform/mac/DragImageMac.mm:
(WebCore::widthWithFont):
(WebCore::drawAtPoint):
* platform/mac/FileChooserMac.mm:
(WebCore::FileChooser::basenameForWidth):
* platform/win/DragImageWin.cpp:
(WebCore::createDragImageForLink):
* platform/win/FileChooserWin.cpp:
(WebCore::FileChooser::basenameForWidth):
* platform/win/PopupMenuWin.cpp:
(WebCore::PopupMenuWin::calculatePositionAndSize):
* platform/win/WebCoreTextRenderer.cpp:
(WebCore::WebCoreTextFloatWidth):
* rendering/HitTestResult.cpp:
(WebCore::HitTestResult::addNodeToRectBasedTestResult):
* rendering/HitTestResult.h:
* rendering/InlineBox.cpp:
(WebCore::InlineBox::adjustPosition):
(WebCore::InlineBox::placeEllipsisBox):
(WebCore::InlineBox::locationIncludingFlipping):
(WebCore::InlineBox::flipForWritingMode):
* rendering/InlineBox.h:
(WebCore::InlineBox::InlineBox):
(WebCore::InlineBox::adjustLineDirectionPosition):
(WebCore::InlineBox::adjustBlockDirectionPosition):
(WebCore::InlineBox::setX):
(WebCore::InlineBox::x):
(WebCore::InlineBox::setY):
(WebCore::InlineBox::y):
(WebCore::InlineBox::width):
(WebCore::InlineBox::height):
(WebCore::InlineBox::logicalLeft):
(WebCore::InlineBox::logicalRight):
(WebCore::InlineBox::setLogicalLeft):
(WebCore::InlineBox::pixelSnappedLogicalLeft):
(WebCore::InlineBox::pixelSnappedLogicalRight):
(WebCore::InlineBox::setLogicalWidth):
(WebCore::InlineBox::logicalWidth):
(WebCore::InlineBox::verticalAlign):
* rendering/InlineFlowBox.cpp:
(WebCore::InlineFlowBox::roundedFrameRect):
(WebCore::InlineFlowBox::adjustPosition):
(WebCore::InlineFlowBox::placeBoxesInInlineDirection):
(WebCore::InlineFlowBox::adjustMaxAscentAndDescent):
(WebCore::verticalPositionForBox):
(WebCore::InlineFlowBox::computeLogicalBoxHeights):
(WebCore::InlineFlowBox::placeBoxesInBlockDirection):
(WebCore::InlineFlowBox::addBoxShadowVisualOverflow):
(WebCore::InlineFlowBox::addTextBoxVisualOverflow):
(WebCore::InlineFlowBox::computeOverflow):
(WebCore::InlineFlowBox::setLayoutOverflow):
(WebCore::InlineFlowBox::setVisualOverflow):
(WebCore::InlineFlowBox::nodeAtPoint):
(WebCore::InlineFlowBox::paintBoxDecorations):
(WebCore::InlineFlowBox::paintMask):
(WebCore::InlineFlowBox::placeEllipsisBox):
* rendering/InlineFlowBox.h:
(WebCore::InlineFlowBox::maxYLayoutOverflow):
(WebCore::InlineFlowBox::maxXLayoutOverflow):
(WebCore::InlineFlowBox::layoutOverflowRect):
(WebCore::InlineFlowBox::maxYVisualOverflow):
(WebCore::InlineFlowBox::maxXVisualOverflow):
(WebCore::InlineFlowBox::visualOverflowRect):
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::placeEllipsisBox):
(WebCore::InlineTextBox::nodeAtPoint):
(WebCore::paintTextWithShadows):
(WebCore::InlineTextBox::paint):
(WebCore::InlineTextBox::paintSelection):
(WebCore::InlineTextBox::paintCompositionBackground):
(WebCore::InlineTextBox::paintDecoration):
(WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
(WebCore::InlineTextBox::paintTextMatchMarker):
(WebCore::InlineTextBox::paintDocumentMarkers):
(WebCore::InlineTextBox::paintCompositionUnderline):
(WebCore::InlineTextBox::textPos):
(WebCore::InlineTextBox::offsetForPosition):
(WebCore::InlineTextBox::positionForOffset):
* rendering/InlineTextBox.h:
(WebCore::InlineTextBox::setExpansion):
* rendering/RenderBR.h:
(WebCore::RenderBR::width):
* rendering/RenderBlock.cpp:
(WebCore::stripTrailingSpace):
(WebCore::updatePreferredWidth):
(WebCore::RenderBlock::computeInlinePreferredLogicalWidths):
(WebCore::RenderBlock::adjustForBorderFit):
(WebCore::RenderBlock::addFocusRingRects):
* rendering/RenderBlock.h:
* rendering/RenderBlockLineLayout.cpp:
(WebCore::RenderBlock::computeInlineDirectionPositionsForLine):
(WebCore::RenderBlock::fitBelowFloats):
(WebCore::textWidth):
(WebCore::tryHyphenating):
(WebCore::RenderBlock::findNextLineBreak):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::positionLineBox):
(WebCore::RenderBox::flipForWritingMode):
* rendering/RenderBox.h:
* rendering/RenderCombineText.cpp:
(WebCore::RenderCombineText::width):
(WebCore::RenderCombineText::adjustTextOrigin):
(WebCore::RenderCombineText::combineText):
* rendering/RenderCombineText.h:
(WebCore::RenderCombineText::combinedTextWidth):
* rendering/RenderCounter.cpp:
(WebCore::RenderCounter::computePreferredLogicalWidths):
* rendering/RenderCounter.h:
* rendering/RenderEmbeddedObject.cpp:
(WebCore::RenderEmbeddedObject::getReplacementTextGeometry):
* rendering/RenderFileUploadControl.cpp:
(WebCore::RenderFileUploadControl::computePreferredLogicalWidths):
* rendering/RenderImage.cpp:
* rendering/RenderInline.cpp:
(WebCore::RenderInline::linesBoundingBox):
(WebCore::RenderInline::linesVisualOverflowBoundingBox):
(WebCore::RenderInline::addFocusRingRects):
(WebCore::RenderInline::paintOutline):
* rendering/RenderListBox.cpp:
(WebCore::RenderListBox::updateFromElement):
(WebCore::RenderListBox::paintItemForeground):
* rendering/RenderMenuList.cpp:
(WebCore::RenderMenuList::updateOptionsWidth):
* rendering/RenderText.cpp:
(WebCore::RenderText::localCaretRect):
(WebCore::RenderText::widthFromCache):
(WebCore::RenderText::trimmedPrefWidths):
(WebCore::RenderText::minLogicalWidth):
(WebCore::RenderText::maxLogicalWidth):
(WebCore::RenderText::computePreferredLogicalWidths):
(WebCore::RenderText::firstRunOrigin):
(WebCore::RenderText::firstRunX):
(WebCore::RenderText::firstRunY):
(WebCore::RenderText::width):
(WebCore::RenderText::linesBoundingBox):
* rendering/RenderText.h:
* rendering/RenderTextControl.cpp:
(WebCore::RenderTextControl::getAvgCharWidth):
(WebCore::RenderTextControl::paintPlaceholder):
* rendering/RenderTreeAsText.cpp:
(WebCore::writeTextRun):
* rendering/RootInlineBox.cpp:
(WebCore::RootInlineBox::placeEllipsis):
(WebCore::RootInlineBox::placeEllipsisBox):
(WebCore::RootInlineBox::adjustPosition):
(WebCore::RootInlineBox::beforeAnnotationsAdjustment):
(WebCore::RootInlineBox::paddedLayoutOverflowRect):
* rendering/RootInlineBox.h:
* rendering/VerticalPositionCache.h:
* rendering/svg/SVGInlineTextBox.cpp:
(WebCore::SVGInlineTextBox::offsetForPosition):
(WebCore::SVGInlineTextBox::positionForOffset):
(WebCore::SVGInlineTextBox::constructTextRun):
* rendering/svg/SVGInlineTextBox.h:
* rendering/svg/SVGRenderTreeAsText.cpp:
(WebCore::writeRenderSVGTextBox):
* rendering/svg/SVGTextMetrics.cpp:
(WebCore::SVGTextMetrics::SVGTextMetrics):
(WebCore::constructTextRun):
* svg/SVGFont.cpp:
(WebCore::floatWidthMissingGlyphCallback):
(WebCore::Font::drawTextUsingSVGFont):

../WebKit/mac:

* Misc/WebKitNSStringExtras.mm:
(-[NSString _web_drawAtPoint:font:textColor:allowingFontSmoothing:]):
(-[NSString _web_widthWithFont:]):

../WebKit/win:

* WebKitGraphics.cpp:
(CenterTruncateStringToWidth):
(RightTruncateStringToWidth):

../WebKit2:

* WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp:
(WebKit::WebPopupMenu::setUpPlatformData):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@78846 268f45cc-cd09-0410-ab3c-d52691b4dbfc

76 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
Source/WebCore/platform/chromium/FileChooserChromium.cpp
Source/WebCore/platform/graphics/Font.cpp
Source/WebCore/platform/graphics/Font.h
Source/WebCore/platform/graphics/FontFastPath.cpp
Source/WebCore/platform/graphics/GraphicsContext.cpp
Source/WebCore/platform/graphics/GraphicsContext.h
Source/WebCore/platform/graphics/SimpleFontData.cpp
Source/WebCore/platform/graphics/SimpleFontData.h
Source/WebCore/platform/graphics/StringTruncator.cpp
Source/WebCore/platform/graphics/StringTruncator.h
Source/WebCore/platform/graphics/TextRun.h
Source/WebCore/platform/graphics/WidthIterator.cpp
Source/WebCore/platform/graphics/WidthIterator.h
Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
Source/WebCore/platform/graphics/mac/ComplexTextController.cpp
Source/WebCore/platform/graphics/mac/ComplexTextController.h
Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp
Source/WebCore/platform/graphics/mac/GraphicsContextMac.mm
Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp
Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
Source/WebCore/platform/graphics/win/UniscribeController.cpp
Source/WebCore/platform/gtk/FileChooserGtk.cpp
Source/WebCore/platform/mac/DragImageMac.mm
Source/WebCore/platform/mac/FileChooserMac.mm
Source/WebCore/platform/win/DragImageWin.cpp
Source/WebCore/platform/win/FileChooserWin.cpp
Source/WebCore/platform/win/PopupMenuWin.cpp
Source/WebCore/platform/win/WebCoreTextRenderer.cpp
Source/WebCore/rendering/HitTestResult.cpp
Source/WebCore/rendering/HitTestResult.h
Source/WebCore/rendering/InlineBox.cpp
Source/WebCore/rendering/InlineBox.h
Source/WebCore/rendering/InlineFlowBox.cpp
Source/WebCore/rendering/InlineFlowBox.h
Source/WebCore/rendering/InlineTextBox.cpp
Source/WebCore/rendering/InlineTextBox.h
Source/WebCore/rendering/RenderBR.h
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/rendering/RenderBlockLineLayout.cpp
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBox.h
Source/WebCore/rendering/RenderCombineText.cpp
Source/WebCore/rendering/RenderCombineText.h
Source/WebCore/rendering/RenderCounter.cpp
Source/WebCore/rendering/RenderCounter.h
Source/WebCore/rendering/RenderEmbeddedObject.cpp
Source/WebCore/rendering/RenderFileUploadControl.cpp
Source/WebCore/rendering/RenderImage.cpp
Source/WebCore/rendering/RenderInline.cpp
Source/WebCore/rendering/RenderListBox.cpp
Source/WebCore/rendering/RenderMenuList.cpp
Source/WebCore/rendering/RenderText.cpp
Source/WebCore/rendering/RenderText.h
Source/WebCore/rendering/RenderTextControl.cpp
Source/WebCore/rendering/RenderTreeAsText.cpp
Source/WebCore/rendering/RootInlineBox.cpp
Source/WebCore/rendering/RootInlineBox.h
Source/WebCore/rendering/VerticalPositionCache.h
Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
Source/WebCore/rendering/svg/SVGInlineTextBox.h
Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
Source/WebCore/rendering/svg/SVGTextMetrics.cpp
Source/WebCore/svg/SVGFont.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/Misc/WebKitNSStringExtras.mm
Source/WebKit/win/ChangeLog
Source/WebKit/win/WebKitGraphics.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp

index 260509a..a00e915 100644 (file)
@@ -1,3 +1,258 @@
+2011-02-16  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        https://bugs.webkit.org/show_bug.cgi?id=54244
+        
+        Convert the line box tree to floating point and eliminate font rounding hacks.  This patch removes all of the rounding
+        hacks from the Font code and makes sure all Font APIs involving width measurement and width offsets use floats.
+        
+        The line box tree's x, y and logicalWidth members have all been converted to floats and all of the line box APIs have
+        been changed as well.
+        
+        In terms of pixel adjustments, overflow is using an enclosing model (so it will be enclosingIntRect of a line box's x/y/width/height).
+        
+        Background and border painting is using a rounding model, so borders and backgrounds will round to the nearest pixel when painting.
+        
+        Replaced elements still snap to integer positions on lines, and they use a rounding model as well, although their underlying line boxes
+        still have a precise floating point position.
+
+        Justification will now allow subpixel positioning to occur as well.  Platforms that don't support subpixel positioning should already
+        be rounding justification spacing in their font code.
+
+        Many layout test results change on Mac, since rounding hacks were used there and are now gone.
+
+        * WebCore.exp.in:
+        * html/canvas/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::drawTextInternal):
+        * platform/chromium/FileChooserChromium.cpp:
+        (WebCore::FileChooser::basenameForWidth):
+        * platform/graphics/Font.cpp:
+        (WebCore::Font::width):
+        * platform/graphics/Font.h:
+        (WebCore::Font::spaceWidth):
+        (WebCore::Font::tabWidth):
+        * platform/graphics/FontFastPath.cpp:
+        (WebCore::Font::getGlyphsAndAdvancesForSimpleText):
+        * platform/graphics/GraphicsContext.cpp:
+        (WebCore::GraphicsContext::drawText):
+        (WebCore::GraphicsContext::drawEmphasisMarks):
+        (WebCore::GraphicsContext::drawBidiText):
+        (WebCore::GraphicsContext::drawHighlightForText):
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/SimpleFontData.cpp:
+        (WebCore::SimpleFontData::SimpleFontData):
+        (WebCore::SimpleFontData::platformGlyphInit):
+        * platform/graphics/SimpleFontData.h:
+        (WebCore::SimpleFontData::spaceWidth):
+        * platform/graphics/StringTruncator.cpp:
+        (WebCore::stringWidth):
+        (WebCore::truncateString):
+        (WebCore::StringTruncator::centerTruncate):
+        (WebCore::StringTruncator::rightTruncate):
+        (WebCore::StringTruncator::width):
+        * platform/graphics/StringTruncator.h:
+        * platform/graphics/TextRun.h:
+        (WebCore::TextRun::TextRun):
+        (WebCore::TextRun::xPos):
+        (WebCore::TextRun::expansion):
+        (WebCore::TextRun::directionalOverride):
+        (WebCore::TextRun::disableSpacing):
+        * platform/graphics/WidthIterator.cpp:
+        (WebCore::WidthIterator::WidthIterator):
+        (WebCore::WidthIterator::advance):
+        * platform/graphics/WidthIterator.h:
+        * platform/graphics/cairo/GraphicsContextCairo.cpp:
+        (WebCore::GraphicsContext::drawLineForText):
+        (WebCore::GraphicsContext::drawLineForTextChecking):
+        * platform/graphics/cg/GraphicsContextCG.cpp:
+        (WebCore::GraphicsContext::drawLineForText):
+        * platform/graphics/mac/ComplexTextController.cpp:
+        (WebCore::ComplexTextController::ComplexTextController):
+        (WebCore::ComplexTextController::advance):
+        (WebCore::ComplexTextController::adjustGlyphsAndAdvances):
+        * platform/graphics/mac/ComplexTextController.h:
+        * platform/graphics/mac/FontComplexTextMac.cpp:
+        (WebCore::Font::getGlyphsAndAdvancesForComplexText):
+        * platform/graphics/mac/GraphicsContextMac.mm:
+        (WebCore::GraphicsContext::drawLineForTextChecking):
+        * platform/graphics/qt/GraphicsContextQt.cpp:
+        (WebCore::GraphicsContext::drawLineForText):
+        (WebCore::GraphicsContext::drawLineForTextChecking):
+        * platform/graphics/qt/SimpleFontDataQt.cpp:
+        (WebCore::SimpleFontData::platformGlyphInit):
+        * platform/graphics/skia/GraphicsContextSkia.cpp:
+        (WebCore::GraphicsContext::drawLineForTextChecking):
+        (WebCore::GraphicsContext::drawLineForText):
+        * platform/graphics/win/GraphicsContextCGWin.cpp:
+        (WebCore::GraphicsContext::drawLineForTextChecking):
+        * platform/graphics/win/UniscribeController.cpp:
+        (WebCore::UniscribeController::shapeAndPlaceItem):
+        * platform/gtk/FileChooserGtk.cpp:
+        (WebCore::FileChooser::basenameForWidth):
+        * platform/mac/DragImageMac.mm:
+        (WebCore::widthWithFont):
+        (WebCore::drawAtPoint):
+        * platform/mac/FileChooserMac.mm:
+        (WebCore::FileChooser::basenameForWidth):
+        * platform/win/DragImageWin.cpp:
+        (WebCore::createDragImageForLink):
+        * platform/win/FileChooserWin.cpp:
+        (WebCore::FileChooser::basenameForWidth):
+        * platform/win/PopupMenuWin.cpp:
+        (WebCore::PopupMenuWin::calculatePositionAndSize):
+        * platform/win/WebCoreTextRenderer.cpp:
+        (WebCore::WebCoreTextFloatWidth):
+        * rendering/HitTestResult.cpp:
+        (WebCore::HitTestResult::addNodeToRectBasedTestResult):
+        * rendering/HitTestResult.h:
+        * rendering/InlineBox.cpp:
+        (WebCore::InlineBox::adjustPosition):
+        (WebCore::InlineBox::placeEllipsisBox):
+        (WebCore::InlineBox::locationIncludingFlipping):
+        (WebCore::InlineBox::flipForWritingMode):
+        * rendering/InlineBox.h:
+        (WebCore::InlineBox::InlineBox):
+        (WebCore::InlineBox::adjustLineDirectionPosition):
+        (WebCore::InlineBox::adjustBlockDirectionPosition):
+        (WebCore::InlineBox::setX):
+        (WebCore::InlineBox::x):
+        (WebCore::InlineBox::setY):
+        (WebCore::InlineBox::y):
+        (WebCore::InlineBox::width):
+        (WebCore::InlineBox::height):
+        (WebCore::InlineBox::logicalLeft):
+        (WebCore::InlineBox::logicalRight):
+        (WebCore::InlineBox::setLogicalLeft):
+        (WebCore::InlineBox::pixelSnappedLogicalLeft):
+        (WebCore::InlineBox::pixelSnappedLogicalRight):
+        (WebCore::InlineBox::setLogicalWidth):
+        (WebCore::InlineBox::logicalWidth):
+        (WebCore::InlineBox::verticalAlign):
+        * rendering/InlineFlowBox.cpp:
+        (WebCore::InlineFlowBox::roundedFrameRect):
+        (WebCore::InlineFlowBox::adjustPosition):
+        (WebCore::InlineFlowBox::placeBoxesInInlineDirection):
+        (WebCore::InlineFlowBox::adjustMaxAscentAndDescent):
+        (WebCore::verticalPositionForBox):
+        (WebCore::InlineFlowBox::computeLogicalBoxHeights):
+        (WebCore::InlineFlowBox::placeBoxesInBlockDirection):
+        (WebCore::InlineFlowBox::addBoxShadowVisualOverflow):
+        (WebCore::InlineFlowBox::addTextBoxVisualOverflow):
+        (WebCore::InlineFlowBox::computeOverflow):
+        (WebCore::InlineFlowBox::setLayoutOverflow):
+        (WebCore::InlineFlowBox::setVisualOverflow):
+        (WebCore::InlineFlowBox::nodeAtPoint):
+        (WebCore::InlineFlowBox::paintBoxDecorations):
+        (WebCore::InlineFlowBox::paintMask):
+        (WebCore::InlineFlowBox::placeEllipsisBox):
+        * rendering/InlineFlowBox.h:
+        (WebCore::InlineFlowBox::maxYLayoutOverflow):
+        (WebCore::InlineFlowBox::maxXLayoutOverflow):
+        (WebCore::InlineFlowBox::layoutOverflowRect):
+        (WebCore::InlineFlowBox::maxYVisualOverflow):
+        (WebCore::InlineFlowBox::maxXVisualOverflow):
+        (WebCore::InlineFlowBox::visualOverflowRect):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::placeEllipsisBox):
+        (WebCore::InlineTextBox::nodeAtPoint):
+        (WebCore::paintTextWithShadows):
+        (WebCore::InlineTextBox::paint):
+        (WebCore::InlineTextBox::paintSelection):
+        (WebCore::InlineTextBox::paintCompositionBackground):
+        (WebCore::InlineTextBox::paintDecoration):
+        (WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
+        (WebCore::InlineTextBox::paintTextMatchMarker):
+        (WebCore::InlineTextBox::paintDocumentMarkers):
+        (WebCore::InlineTextBox::paintCompositionUnderline):
+        (WebCore::InlineTextBox::textPos):
+        (WebCore::InlineTextBox::offsetForPosition):
+        (WebCore::InlineTextBox::positionForOffset):
+        * rendering/InlineTextBox.h:
+        (WebCore::InlineTextBox::setExpansion):
+        * rendering/RenderBR.h:
+        (WebCore::RenderBR::width):
+        * rendering/RenderBlock.cpp:
+        (WebCore::stripTrailingSpace):
+        (WebCore::updatePreferredWidth):
+        (WebCore::RenderBlock::computeInlinePreferredLogicalWidths):
+        (WebCore::RenderBlock::adjustForBorderFit):
+        (WebCore::RenderBlock::addFocusRingRects):
+        * rendering/RenderBlock.h:
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::RenderBlock::computeInlineDirectionPositionsForLine):
+        (WebCore::RenderBlock::fitBelowFloats):
+        (WebCore::textWidth):
+        (WebCore::tryHyphenating):
+        (WebCore::RenderBlock::findNextLineBreak):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::positionLineBox):
+        (WebCore::RenderBox::flipForWritingMode):
+        * rendering/RenderBox.h:
+        * rendering/RenderCombineText.cpp:
+        (WebCore::RenderCombineText::width):
+        (WebCore::RenderCombineText::adjustTextOrigin):
+        (WebCore::RenderCombineText::combineText):
+        * rendering/RenderCombineText.h:
+        (WebCore::RenderCombineText::combinedTextWidth):
+        * rendering/RenderCounter.cpp:
+        (WebCore::RenderCounter::computePreferredLogicalWidths):
+        * rendering/RenderCounter.h:
+        * rendering/RenderEmbeddedObject.cpp:
+        (WebCore::RenderEmbeddedObject::getReplacementTextGeometry):
+        * rendering/RenderFileUploadControl.cpp:
+        (WebCore::RenderFileUploadControl::computePreferredLogicalWidths):
+        * rendering/RenderImage.cpp:
+        * rendering/RenderInline.cpp:
+        (WebCore::RenderInline::linesBoundingBox):
+        (WebCore::RenderInline::linesVisualOverflowBoundingBox):
+        (WebCore::RenderInline::addFocusRingRects):
+        (WebCore::RenderInline::paintOutline):
+        * rendering/RenderListBox.cpp:
+        (WebCore::RenderListBox::updateFromElement):
+        (WebCore::RenderListBox::paintItemForeground):
+        * rendering/RenderMenuList.cpp:
+        (WebCore::RenderMenuList::updateOptionsWidth):
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::localCaretRect):
+        (WebCore::RenderText::widthFromCache):
+        (WebCore::RenderText::trimmedPrefWidths):
+        (WebCore::RenderText::minLogicalWidth):
+        (WebCore::RenderText::maxLogicalWidth):
+        (WebCore::RenderText::computePreferredLogicalWidths):
+        (WebCore::RenderText::firstRunOrigin):
+        (WebCore::RenderText::firstRunX):
+        (WebCore::RenderText::firstRunY):
+        (WebCore::RenderText::width):
+        (WebCore::RenderText::linesBoundingBox):
+        * rendering/RenderText.h:
+        * rendering/RenderTextControl.cpp:
+        (WebCore::RenderTextControl::getAvgCharWidth):
+        (WebCore::RenderTextControl::paintPlaceholder):
+        * rendering/RenderTreeAsText.cpp:
+        (WebCore::writeTextRun):
+        * rendering/RootInlineBox.cpp:
+        (WebCore::RootInlineBox::placeEllipsis):
+        (WebCore::RootInlineBox::placeEllipsisBox):
+        (WebCore::RootInlineBox::adjustPosition):
+        (WebCore::RootInlineBox::beforeAnnotationsAdjustment):
+        (WebCore::RootInlineBox::paddedLayoutOverflowRect):
+        * rendering/RootInlineBox.h:
+        * rendering/VerticalPositionCache.h:
+        * rendering/svg/SVGInlineTextBox.cpp:
+        (WebCore::SVGInlineTextBox::offsetForPosition):
+        (WebCore::SVGInlineTextBox::positionForOffset):
+        (WebCore::SVGInlineTextBox::constructTextRun):
+        * rendering/svg/SVGInlineTextBox.h:
+        * rendering/svg/SVGRenderTreeAsText.cpp:
+        (WebCore::writeRenderSVGTextBox):
+        * rendering/svg/SVGTextMetrics.cpp:
+        (WebCore::SVGTextMetrics::SVGTextMetrics):
+        (WebCore::constructTextRun):
+        * svg/SVGFont.cpp:
+        (WebCore::floatWidthMissingGlyphCallback):
+        (WebCore::Font::drawTextUsingSVGFont):
+
 2011-02-17  Nikolas Zimmermann  <nzimmermann@rim.com>
 
         Reviewed by Dirk Schulze.
index fc98056..9fa935a 100644 (file)
@@ -400,9 +400,9 @@ __ZN7WebCore15ProtectionSpaceC1ERKN3WTF6StringEiNS_25ProtectionSpaceServerTypeES
 __ZN7WebCore15ProtectionSpaceC1Ev
 __ZN7WebCore15ScrollAlignment17alignCenterAlwaysE
 __ZN7WebCore15ScrollAlignment19alignToEdgeIfNeededE
-__ZN7WebCore15StringTruncator13rightTruncateERKN3WTF6StringEfRKNS_4FontEb
-__ZN7WebCore15StringTruncator14centerTruncateERKN3WTF6StringEfRKNS_4FontEb
-__ZN7WebCore15StringTruncator5widthERKN3WTF6StringERKNS_4FontEb
+__ZN7WebCore15StringTruncator14centerTruncateERKN3WTF6StringEfRKNS_4FontE
+__ZN7WebCore15StringTruncator13rightTruncateERKN3WTF6StringEfRKNS_4FontE
+__ZN7WebCore15StringTruncator5widthERKN3WTF6StringERKNS_4FontE
 __ZN7WebCore15VisiblePositionC1EPNS_4NodeEiNS_9EAffinityE
 __ZN7WebCore15VisiblePositionC1ERKNS_8PositionENS_9EAffinityE
 __ZN7WebCore15defaultLanguageEv
@@ -1127,7 +1127,7 @@ __ZNK7WebCore27AuthenticationChallengeBase18proposedCredentialEv
 __ZNK7WebCore27AuthenticationChallengeBase20previousFailureCountEv
 __ZNK7WebCore27AuthenticationChallengeBase5errorEv
 __ZNK7WebCore27AuthenticationChallengeBase6isNullEv
-__ZNK7WebCore4Font10floatWidthERKNS_7TextRunEPN3WTF7HashSetIPKNS_14SimpleFontDataENS4_7PtrHashIS8_EENS4_10HashTraitsIS8_EEEEPNS_13GlyphOverflowE
+__ZNK7WebCore4Font5widthERKNS_7TextRunEPN3WTF7HashSetIPKNS_14SimpleFontDataENS4_7PtrHashIS8_EENS4_10HashTraitsIS8_EEEEPNS_13GlyphOverflowE
 __ZNK7WebCore4Font8drawTextEPNS_15GraphicsContextERKNS_7TextRunERKNS_10FloatPointEii
 __ZNK7WebCore4KURL11createCFURLEv
 __ZNK7WebCore4KURL11isLocalFileEv
index 574bb9d..7eb3dfc 100644 (file)
@@ -1773,7 +1773,7 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
 
     unsigned length = text.length();
     const UChar* string = text.characters();
-    TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, rtl, override, false, false);
+    TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, rtl, override);
 
     // Draw the item text at the correct point.
     FloatPoint location(x, y);
index 3d75b42..dcc7eb0 100644 (file)
@@ -44,9 +44,9 @@ String FileChooser::basenameForWidth(const Font& font, int width) const
     else if (m_filenames.size() == 1)
         string = pathGetDisplayFileName(m_filenames[0]);
     else
-        return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font, false);
+        return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font);
 
-    return StringTruncator::centerTruncate(string, static_cast<float>(width), font, false);
+    return StringTruncator::centerTruncate(string, static_cast<float>(width), font);
 }
 
 } // namespace WebCore
index 6bdddfc..ee85e45 100644 (file)
@@ -39,17 +39,6 @@ using namespace Unicode;
 
 namespace WebCore {
 
-const uint8_t Font::gRoundingHackCharacterTable[256] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*\t*/, 1 /*\n*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    1 /*space*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*-*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*?*/,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    1 /*no-break space*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
 Font::CodePath Font::s_codePath = Auto;
 
 // ============================================================================================
@@ -176,7 +165,7 @@ void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const
         drawEmphasisMarksForComplexText(context, run, mark, point, from, to);
 }
 
-float Font::floatWidth(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
 {
 #if ENABLE(SVG_FONTS)
     if (primaryFont()->isSVGFont())
@@ -194,7 +183,7 @@ float Font::floatWidth(const TextRun& run, HashSet<const SimpleFontData*>* fallb
     return floatWidthForComplexText(run, fallbackFonts, glyphOverflow);
 }
 
-float Font::floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const
+float Font::width(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const
 {
 #if !ENABLE(SVG_FONTS)
     UNUSED_PARAM(extraCharsAvailable);
index 258240b..9aae3e2 100644 (file)
@@ -94,9 +94,8 @@ public:
     void drawText(GraphicsContext*, const TextRun&, const FloatPoint&, int from = 0, int to = -1) const;
     void drawEmphasisMarks(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1) const;
 
-    int width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* glyphOverflow = 0) const { return lroundf(floatWidth(run, fallbackFonts, glyphOverflow)); }
-    float floatWidth(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* glyphOverflow = 0) const;
-    float floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const;
+    float width(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
+    float width(const TextRun&, int extraCharsAvailable, int& charsConsumed, String& glyphName) const;
 
     int offsetForPosition(const TextRun&, float position, bool includePartialGlyphs) const;
     FloatRect selectionRectForText(const TextRun&, const FloatPoint&, int h, int from = 0, int to = -1) const;
@@ -129,8 +128,8 @@ public:
 
     // Metrics that we query the FontFallbackList for.
     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 spaceWidth() const { return primaryFont()->spaceWidth() + m_letterSpacing; }
+    float tabWidth(const SimpleFontData& fontData) const { return 8 * fontData.spaceWidth() + letterSpacing(); }
     int emphasisMarkAscent(const AtomicString&) const;
     int emphasisMarkDescent(const AtomicString&) const;
     int emphasisMarkHeight(const AtomicString&) const;
@@ -201,12 +200,6 @@ public:
     static CodePath codePath();
     static CodePath s_codePath;
 
-    static const uint8_t gRoundingHackCharacterTable[256];
-    static bool isRoundingHackCharacter(UChar32 c)
-    {
-        return (((c & ~0xFF) == 0 && gRoundingHackCharacterTable[c]));
-    }
-
     FontSelector* fontSelector() const;
     static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == noBreakSpace; }
     static bool treatAsZeroWidthSpace(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || c == softHyphen || (c >= 0x200c && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == objectReplacementCharacter; }
index 034ac22..e62df61 100644 (file)
@@ -297,9 +297,8 @@ float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int
     float afterWidth = it.m_runWidthSoFar;
 
     if (run.rtl()) {
-        float finalRoundingWidth = it.m_finalRoundingWidth;
         it.advance(run.length());
-        initialAdvance = finalRoundingWidth + it.m_runWidthSoFar - afterWidth;
+        initialAdvance = it.m_runWidthSoFar - afterWidth;
     } else
         initialAdvance = beforeWidth;
 
index 2d0bd1e..8026891 100644 (file)
@@ -375,7 +375,7 @@ void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const
 }
 
 #if !OS(WINCE) || PLATFORM(QT)
-void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPoint& point, int from, int to)
+void GraphicsContext::drawText(const Font& font, const TextRun& run, const FloatPoint& point, int from, int to)
 {
     if (paintingDisabled())
         return;
@@ -384,7 +384,7 @@ void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPo
 }
 #endif
 
-void GraphicsContext::drawEmphasisMarks(const Font& font, const TextRun& run, const AtomicString& mark, const IntPoint& point, int from, int to)
+void GraphicsContext::drawEmphasisMarks(const Font& font, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to)
 {
     if (paintingDisabled())
         return;
@@ -422,13 +422,13 @@ void GraphicsContext::drawBidiText(const Font& font, const TextRun& run, const F
         bidiRun = bidiRun->next();
         // FIXME: Have Font::drawText return the width of what it drew so that we don't have to re-measure here.
         if (bidiRun)
-            currPoint.move(font.floatWidth(subrun), 0.f);
+            currPoint.move(font.width(subrun), 0);
     }
 
     bidiResolver.deleteRuns();
 }
 
-void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run, const IntPoint& point, int h, const Color& backgroundColor, ColorSpace colorSpace, int from, int to)
+void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run, const FloatPoint& point, int h, const Color& backgroundColor, ColorSpace colorSpace, int from, int to)
 {
     if (paintingDisabled())
         return;
index fddf775..3657387 100644 (file)
@@ -339,20 +339,20 @@ namespace WebCore {
         TextDrawingModeFlags textDrawingMode() const;
         void setTextDrawingMode(TextDrawingModeFlags);
 
-        void drawText(const Font&, const TextRun&, const IntPoint&, int from = 0, int to = -1);
-        void drawEmphasisMarks(const Font&, const TextRun& , const AtomicString& mark, const IntPoint&, int from = 0, int to = -1);
+        void drawText(const Font&, const TextRun&, const FloatPoint&, int from = 0, int to = -1);
+        void drawEmphasisMarks(const Font&, const TextRun& , const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1);
         void drawBidiText(const Font&, const TextRun&, const FloatPoint&);
-        void drawHighlightForText(const Font&, const TextRun&, const IntPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1);
+        void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1);
 
         FloatRect roundToDevicePixels(const FloatRect&);
 
-        void drawLineForText(const IntPoint&, int width, bool printing);
+        void drawLineForText(const FloatPoint&, float width, bool printing);
         enum TextCheckingLineStyle {
             TextCheckingSpellingLineStyle,
             TextCheckingGrammarLineStyle,
             TextCheckingReplacementLineStyle
         };
-        void drawLineForTextChecking(const IntPoint&, int width, TextCheckingLineStyle);
+        void drawLineForTextChecking(const FloatPoint&, float width, TextCheckingLineStyle);
 
         bool paintingDisabled() const;
         void setPaintingDisabled(bool);
index 4b1e8f5..aaab666 100644 (file)
@@ -115,7 +115,6 @@ SimpleFontData::SimpleFontData(PassOwnPtr<SVGFontData> svgFontData, int size, bo
     m_spaceGlyph = 0;
     m_zeroWidthSpaceGlyph = 0;
     determinePitch();
-    m_adjustedSpaceWidth = roundf(m_spaceWidth);
     m_missingGlyphData.fontData = this;
     m_missingGlyphData.glyph = 0;
 }
@@ -150,7 +149,6 @@ void SimpleFontData::platformGlyphInit()
         LOG_ERROR("Failed to get glyph page zero.");
         m_spaceGlyph = 0;
         m_spaceWidth = 0;
-        m_adjustedSpaceWidth = 0;
         determinePitch();
         m_zeroWidthSpaceGlyph = 0;
         m_missingGlyphData.fontData = this;
@@ -167,7 +165,6 @@ void SimpleFontData::platformGlyphInit()
     float width = widthForGlyph(m_spaceGlyph);
     m_spaceWidth = width;
     determinePitch();
-    m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width);
 
     // Force the glyph for ZERO WIDTH SPACE to have zero width, unless it is shared with SPACE.
     // Helvetica is an example of a non-zero width ZERO WIDTH SPACE glyph.
index 07c2bd1..93d33bb 100644 (file)
@@ -112,7 +112,6 @@ public:
     float platformWidthForGlyph(Glyph) const;
 
     float spaceWidth() const { return m_spaceWidth; }
-    float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; }
 
 #if PLATFORM(CG) || PLATFORM(CAIRO) || PLATFORM(WX)
     float syntheticBoldOffset() const { return m_syntheticBoldOffset; }
@@ -230,7 +229,6 @@ private:
 
     Glyph m_spaceGlyph;
     float m_spaceWidth;
-    float m_adjustedSpaceWidth;
 
     Glyph m_zeroWidthSpaceGlyph;
 
index 8468188..fa8f211 100644 (file)
@@ -92,22 +92,20 @@ static unsigned rightTruncateToBuffer(const String& string, unsigned length, uns
     return truncatedLength;
 }
 
-static float stringWidth(const Font& renderer, const UChar* characters, unsigned length, bool disableRoundingHacks)
+static float stringWidth(const Font& renderer, const UChar* characters, unsigned length)
 {
     TextRun run(characters, length);
-    if (disableRoundingHacks)
-        run.disableRoundingHacks();
-    return renderer.floatWidth(run);
+    return renderer.width(run);
 }
 
-static String truncateString(const String& string, float maxWidth, const Font& font, TruncationFunction truncateToBuffer, bool disableRoundingHacks)
+static String truncateString(const String& string, float maxWidth, const Font& font, TruncationFunction truncateToBuffer)
 {
     if (string.isEmpty())
         return string;
     
     ASSERT(maxWidth >= 0);
     
-    float currentEllipsisWidth = stringWidth(font, &horizontalEllipsis, 1, disableRoundingHacks);
+    float currentEllipsisWidth = stringWidth(font, &horizontalEllipsis, 1);
     
     UChar stringBuffer[STRING_BUFFER_SIZE];
     unsigned truncatedLength;
@@ -123,7 +121,7 @@ static String truncateString(const String& string, float maxWidth, const Font& f
         truncatedLength = length;
     }
 
-    float width = stringWidth(font, stringBuffer, truncatedLength, disableRoundingHacks);
+    float width = stringWidth(font, stringBuffer, truncatedLength);
     if (width <= maxWidth)
         return string;
 
@@ -159,7 +157,7 @@ static String truncateString(const String& string, float maxWidth, const Font& f
         
         truncatedLength = truncateToBuffer(string, length, keepCount, stringBuffer);
 
-        width = stringWidth(font, stringBuffer, truncatedLength, disableRoundingHacks);
+        width = stringWidth(font, stringBuffer, truncatedLength);
         if (width <= maxWidth) {
             keepCountForLargestKnownToFit = keepCount;
             widthForLargestKnownToFit = width;
@@ -181,19 +179,19 @@ static String truncateString(const String& string, float maxWidth, const Font& f
     return String(stringBuffer, truncatedLength);
 }
 
-String StringTruncator::centerTruncate(const String& string, float maxWidth, const Font& font, bool disableRoundingHacks)
+String StringTruncator::centerTruncate(const String& string, float maxWidth, const Font& font)
 {
-    return truncateString(string, maxWidth, font, centerTruncateToBuffer, disableRoundingHacks);
+    return truncateString(string, maxWidth, font, centerTruncateToBuffer);
 }
 
-String StringTruncator::rightTruncate(const String& string, float maxWidth, const Font& font, bool disableRoundingHacks)
+String StringTruncator::rightTruncate(const String& string, float maxWidth, const Font& font)
 {
-    return truncateString(string, maxWidth, font, rightTruncateToBuffer, disableRoundingHacks);
+    return truncateString(string, maxWidth, font, rightTruncateToBuffer);
 }
 
-float StringTruncator::width(const String& string, const Font& font, bool disableRoundingHacks)
+float StringTruncator::width(const String& string, const Font& font)
 {
-    return stringWidth(font, string.characters(), string.length(), disableRoundingHacks);
+    return stringWidth(font, string.characters(), string.length());
 }
 
 } // namespace WebCore
index 6791d38..89dc9ef 100644 (file)
@@ -37,9 +37,9 @@ namespace WebCore {
     
     class StringTruncator {
     public:
-        static String centerTruncate(const String&, float maxWidth, const Font&, bool disableRoundingHacks = true);
-        static String rightTruncate(const String&, float maxWidth, const Font&, bool disableRoundingHacks = true);
-        static float width(const String&, const Font&, bool disableRoundingHacks = true);
+        static String centerTruncate(const String&, float maxWidth, const Font&);
+        static String rightTruncate(const String&, float maxWidth, const Font&);
+        static float width(const String&, const Font&);
     };
     
 } // namespace WebCore
index ef434bd..4e0980b 100644 (file)
@@ -38,8 +38,7 @@ public:
         ForbidTrailingExpansion
     };
 
-    TextRun(const UChar* c, int len, bool allowTabs = false, int xpos = 0, int expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false,
-              bool applyRunRounding = true, bool applyWordRounding = true)
+    TextRun(const UChar* c, int len, bool allowTabs = false, float xpos = 0, float expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false)
         : m_characters(c)
         , m_len(len)
         , m_xpos(xpos)
@@ -51,8 +50,6 @@ public:
         , m_allowTabs(allowTabs)
         , m_rtl(rtl)
         , m_directionalOverride(directionalOverride)
-        , m_applyRunRounding(applyRunRounding)
-        , m_applyWordRounding(applyWordRounding)
         , m_disableSpacing(false)
 #if ENABLE(SVG_FONTS)
         , m_referencingRenderObject(0)
@@ -61,8 +58,7 @@ public:
     {
     }
 
-    TextRun(const String& s, bool allowTabs = false, int xpos = 0, int expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false,
-              bool applyRunRounding = true, bool applyWordRounding = true)
+    TextRun(const String& s, bool allowTabs = false, float xpos = 0, float expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false)
         : m_characters(s.characters())
         , m_len(s.length())
         , m_xpos(xpos)
@@ -74,8 +70,6 @@ public:
         , m_allowTabs(allowTabs)
         , m_rtl(rtl)
         , m_directionalOverride(directionalOverride)
-        , m_applyRunRounding(applyRunRounding)
-        , m_applyWordRounding(applyWordRounding)
         , m_disableSpacing(false)
 #if ENABLE(SVG_FONTS)
         , m_referencingRenderObject(0)
@@ -98,18 +92,15 @@ public:
 #endif
 
     bool allowTabs() const { return m_allowTabs; }
-    int xPos() const { return m_xpos; }
-    int expansion() const { return m_expansion; }
+    float xPos() const { return m_xpos; }
+    float expansion() const { return m_expansion; }
     bool allowsTrailingExpansion() const { return m_trailingExpansionBehavior == AllowTrailingExpansion; }
     bool rtl() const { return m_rtl; }
     bool ltr() const { return !m_rtl; }
     bool directionalOverride() const { return m_directionalOverride; }
-    bool applyRunRounding() const { return m_applyRunRounding; }
-    bool applyWordRounding() const { return m_applyWordRounding; }
     bool spacingDisabled() const { return m_disableSpacing; }
 
     void disableSpacing() { m_disableSpacing = true; }
-    void disableRoundingHacks() { m_applyRunRounding = m_applyWordRounding = false; }
     void setRTL(bool b) { m_rtl = b; }
     void setDirectionalOverride(bool override) { m_directionalOverride = override; }
 
@@ -128,8 +119,8 @@ private:
     // m_xpos is the x position relative to the left start of the text line, not relative to the left
     // start of the containing block. In the case of right alignment or center alignment, left start of
     // the text line is not the same as left start of the containing block.
-    int m_xpos;  
-    int m_expansion;
+    float m_xpos;  
+    float m_expansion;
     TrailingExpansionBehavior m_trailingExpansionBehavior;
 #if ENABLE(SVG)
     float m_horizontalGlyphStretch;
@@ -137,8 +128,6 @@ private:
     bool m_allowTabs;
     bool m_rtl;
     bool m_directionalOverride;
-    bool m_applyRunRounding;
-    bool m_applyWordRounding;
     bool m_disableSpacing;
 
 #if ENABLE(SVG_FONTS)
index a1a88da..27b0627 100644 (file)
@@ -48,7 +48,6 @@ WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const
     , m_currentCharacter(0)
     , m_runWidthSoFar(0)
     , m_isAfterExpansion(true)
-    , m_finalRoundingWidth(0)
     , m_fallbackFonts(fallbackFonts)
     , m_accountForGlyphBounds(accountForGlyphBounds)
     , m_maxGlyphBoundingBoxY(numeric_limits<float>::min())
@@ -86,11 +85,6 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
     bool rtl = m_run.rtl();
     bool hasExtraSpacing = (m_font->letterSpacing() || m_font->wordSpacing() || m_expansion) && !m_run.spacingDisabled();
 
-    float widthSinceLastRounding = m_runWidthSoFar;
-    m_runWidthSoFar = floorf(m_runWidthSoFar);
-    widthSinceLastRounding -= m_runWidthSoFar;
-
-    float lastRoundingWidth = m_finalRoundingWidth;
     FloatRect bounds;
 
     const SimpleFontData* primaryFont = m_font->primaryFont();
@@ -136,7 +130,7 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
         float width;
         if (c == '\t' && m_run.allowTabs()) {
             float tabWidth = m_font->tabWidth(*fontData);
-            width = tabWidth - fmodf(m_run.xPos() + m_runWidthSoFar + widthSinceLastRounding, tabWidth);
+            width = tabWidth - fmodf(m_run.xPos() + m_runWidthSoFar, tabWidth);
         } else {
             width = fontData->widthForGlyph(glyph);
 
@@ -144,13 +138,6 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
             // SVG uses horizontalGlyphStretch(), when textLength is used to stretch/squeeze text.
             width *= m_run.horizontalGlyphStretch();
 #endif
-
-            // We special case spaces in two ways when applying word rounding.
-            // First, we round spaces to an adjusted width in all fonts.
-            // Second, in fixed-pitch fonts we ensure that all characters that
-            // match the width of the space character have the same width as the space character.
-            if (width == fontData->spaceWidth() && (fontData->pitch() == FixedPitch || glyph == fontData->spaceGlyph()) && m_run.applyWordRounding())
-                width = fontData->adjustedSpaceWidth();
         }
 
         if (fontData != lastFontData && width) {
@@ -179,18 +166,15 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
                 // Distribute the run's total expansion evenly over all expansion opportunities in the run.
                 if (m_expansion && (m_run.allowsTrailingExpansion() || (m_run.ltr() && currentCharacter + clusterLength < static_cast<size_t>(m_run.length()))
                     || (m_run.rtl() && currentCharacter))) {
-                    float previousExpansion = m_expansion;
                     if (!treatAsSpace && !m_isAfterExpansion) {
                         // Take the expansion opportunity before this ideograph.
                         m_expansion -= m_expansionPerOpportunity;
-                        int expansion = roundf(previousExpansion) - roundf(m_expansion);
-                        m_runWidthSoFar += expansion;
+                        m_runWidthSoFar += m_expansionPerOpportunity;
                         if (glyphBuffer)
-                            glyphBuffer->expandLastAdvance(expansion);
-                        previousExpansion = m_expansion;
+                            glyphBuffer->expandLastAdvance(m_expansionPerOpportunity);
                     }
                     m_expansion -= m_expansionPerOpportunity;
-                    width += roundf(previousExpansion) - roundf(m_expansion);
+                    width += m_expansionPerOpportunity;
                     m_isAfterExpansion = true;
                 } else
                     m_isAfterExpansion = false;
@@ -216,43 +200,10 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
         cp += clusterLength;
         currentCharacter += clusterLength;
 
-        // Account for float/integer impedance mismatch between CG and KHTML. "Words" (characters 
-        // followed by a character defined by isRoundingHackCharacter()) are always an integer width.
-        // We adjust the width of the last character of a "word" to ensure an integer width.
-        // If we move KHTML to floats we can remove this (and related) hacks.
-
-        float oldWidth = width;
-
-        // Force characters that are used to determine word boundaries for the rounding hack
-        // to be integer width, so following words will start on an integer boundary.
-        if (m_run.applyWordRounding() && Font::isRoundingHackCharacter(c)) {
-            width = ceilf(width);
-
-            // Since widthSinceLastRounding can lose precision if we include measurements for
-            // preceding whitespace, we bypass it here.
-            m_runWidthSoFar += width;
-
-            // Since this is a rounding hack character, we should have reset this sum on the previous
-            // iteration.
-            ASSERT(!widthSinceLastRounding);
-        } else {
-            // Check to see if the next character is a "rounding hack character", if so, adjust
-            // width so that the total run width will be on an integer boundary.
-            if ((m_run.applyWordRounding() && currentCharacter < m_run.length() && Font::isRoundingHackCharacter(*cp))
-                    || (m_run.applyRunRounding() && currentCharacter >= m_end)) {
-                float totalWidth = widthSinceLastRounding + width;
-                widthSinceLastRounding = ceilf(totalWidth);
-                width += widthSinceLastRounding - totalWidth;
-                m_runWidthSoFar += widthSinceLastRounding;
-                widthSinceLastRounding = 0;
-            } else
-                widthSinceLastRounding += width;
-        }
+        m_runWidthSoFar += width;
 
         if (glyphBuffer)
-            glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width));
-
-        lastRoundingWidth = width - oldWidth;
+            glyphBuffer->add(glyph, fontData, width);
 
         if (m_accountForGlyphBounds) {
             m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, bounds.maxY());
@@ -262,8 +213,6 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
     }
 
     m_currentCharacter = currentCharacter;
-    m_runWidthSoFar += widthSinceLastRounding;
-    m_finalRoundingWidth = lastRoundingWidth;
 }
 
 bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer* glyphBuffer)
index 2b4f051..8cb89cf 100644 (file)
@@ -53,7 +53,6 @@ struct WidthIterator {
     float m_expansion;
     float m_expansionPerOpportunity;
     bool m_isAfterExpansion;
-    float m_finalRoundingWidth;
 
 private:
     UChar32 normalizeVoicingMarks(int currentCharacter);
index 3164566..b4d197d 100644 (file)
@@ -701,20 +701,22 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int
     cairo_restore(cr);
 }
 
-void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
+void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool printing)
 {
     if (paintingDisabled())
         return;
 
-    IntPoint endPoint = origin + IntSize(width, 0);
-    drawLine(origin, endPoint);
+    FloatPoint endPoint = origin + FloatSize(width, 0);
+    
+    // FIXME: Loss of precision here. Might consider rounding.
+    drawLine(IntPoint(origin.x(), origin.y()), IntPoint(endPoint.x(), endPoint.y()));
 }
 
 #if !PLATFORM(GTK)
 #include "DrawErrorUnderline.h"
 #endif
 
-void GraphicsContext::drawLineForTextChecking(const IntPoint& origin, int width, TextCheckingLineStyle style)
+void GraphicsContext::drawLineForTextChecking(const FloatPoint& origin, float width, TextCheckingLineStyle style)
 {
     if (paintingDisabled())
         return;
index 2f1a725..7e6b759 100644 (file)
@@ -1144,7 +1144,7 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
     return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin);
 }
 
-void GraphicsContext::drawLineForText(const IntPoint& point, int width, bool printing)
+void GraphicsContext::drawLineForText(const FloatPoint& point, float width, bool printing)
 {
     if (paintingDisabled())
         return;
index 1fe3d28..1a56664 100644 (file)
@@ -49,13 +49,6 @@ static inline CGFloat roundCGFloat(CGFloat f)
     return static_cast<CGFloat>(round(f));
 }
 
-static inline CGFloat ceilCGFloat(CGFloat f)
-{
-    if (sizeof(CGFloat) == sizeof(float))
-        return ceilf(static_cast<float>(f));
-    return static_cast<CGFloat>(ceil(f));
-}
-
 ComplexTextController::ComplexTextController(const Font* font, const TextRun& run, bool mayUseNaturalWritingDirection, HashSet<const SimpleFontData*>* fallbackFonts, bool forTextEmphasis)
     : m_font(*font)
     , m_run(run)
@@ -69,7 +62,6 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru
     , m_currentRun(0)
     , m_glyphInCurrentRun(0)
     , m_characterInCurrentGlyph(0)
-    , m_finalRoundingWidth(0)
     , m_expansion(run.expansion())
     , m_afterExpansion(true)
     , m_fallbackFonts(fallbackFonts)
@@ -77,7 +69,6 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru
     , m_maxGlyphBoundingBoxX(numeric_limits<float>::min())
     , m_minGlyphBoundingBoxY(numeric_limits<float>::max())
     , m_maxGlyphBoundingBoxY(numeric_limits<float>::min())
-    , m_lastRoundingGlyph(0)
 {
     if (!m_expansion)
         m_expansionPerOpportunity = 0;
@@ -413,13 +404,11 @@ void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer)
         m_currentRun++;
         m_glyphInCurrentRun = 0;
     }
-    if (!ltr && m_numGlyphsSoFar == m_adjustedAdvances.size())
-        m_runWidthSoFar += m_finalRoundingWidth;
 }
 
 void ComplexTextController::adjustGlyphsAndAdvances()
 {
-    CGFloat widthSinceLastRounding = 0;
+    CGFloat widthSinceLastCommit = 0;
     size_t runCount = m_complexTextRuns.size();
     bool hasExtraSpacing = (m_font.letterSpacing() || m_font.wordSpacing() || m_expansion) && !m_run.spacingDisabled();
     for (size_t r = 0; r < runCount; ++r) {
@@ -431,9 +420,8 @@ void ComplexTextController::adjustGlyphsAndAdvances()
         const CGSize* advances = complexTextRun.advances();
 
         bool lastRun = r + 1 == runCount;
-        const UChar* cp = complexTextRun.characters();
-        CGFloat roundedSpaceWidth = roundCGFloat(fontData->spaceWidth());
         bool roundsAdvances = !m_font.isPrinterFont() && fontData->platformData().roundsGlyphAdvances();
+        const UChar* cp = complexTextRun.characters();
         CGPoint glyphOrigin = CGPointZero;
         CFIndex lastCharacterIndex = m_run.ltr() ? numeric_limits<CFIndex>::min() : numeric_limits<CFIndex>::max();
         bool isMonotonic = true;
@@ -463,7 +451,7 @@ void ComplexTextController::adjustGlyphsAndAdvances()
 
             if (ch == '\t' && m_run.allowTabs()) {
                 float tabWidth = m_font.tabWidth(*fontData);
-                advance.width = tabWidth - fmodf(m_run.xPos() + m_totalWidth + widthSinceLastRounding, tabWidth);
+                advance.width = tabWidth - fmodf(m_run.xPos() + m_totalWidth + widthSinceLastCommit, tabWidth);
             } else if (ch == zeroWidthSpace || (Font::treatAsZeroWidthSpace(ch) && !treatAsSpace)) {
                 advance.width = 0;
                 glyph = fontData->spaceGlyph();
@@ -475,13 +463,6 @@ void ComplexTextController::adjustGlyphsAndAdvances()
 
             advance.width += fontData->syntheticBoldOffset();
 
-            // We special case spaces in two ways when applying word rounding.
-            // First, we round spaces to an adjusted width in all fonts.
-            // Second, in fixed-pitch fonts we ensure that all glyphs that
-            // match the width of the space glyph have the same width as the space glyph.
-            if (roundedAdvanceWidth == roundedSpaceWidth && (fontData->pitch() == FixedPitch || glyph == fontData->spaceGlyph()) && m_run.applyWordRounding())
-                advance.width = fontData->adjustedSpaceWidth();
-
             if (hasExtraSpacing) {
                 // If we're a glyph with an advance, go ahead and add in letter-spacing.
                 // That way we weed out zero width lurkers.  This behavior matches the fast text code path.
@@ -492,17 +473,14 @@ void ComplexTextController::adjustGlyphsAndAdvances()
                 if (treatAsSpace || Font::isCJKIdeographOrSymbol(ch)) {
                     // Distribute the run's total expansion evenly over all expansion opportunities in the run.
                     if (m_expansion && (!lastGlyph || m_run.allowsTrailingExpansion())) {
-                        float previousExpansion = m_expansion;
                         if (!treatAsSpace && !m_afterExpansion) {
                             // Take the expansion opportunity before this ideograph.
                             m_expansion -= m_expansionPerOpportunity;
-                            int expansion = roundf(previousExpansion) - roundf(m_expansion);
-                            m_totalWidth += expansion;
-                            m_adjustedAdvances.last().width += expansion;
-                            previousExpansion = m_expansion;
+                            m_totalWidth += m_expansionPerOpportunity;
+                            m_adjustedAdvances.last().width += m_expansionPerOpportunity;
                         }
                         m_expansion -= m_expansionPerOpportunity;
-                        advance.width += roundf(previousExpansion) - roundf(m_expansion);
+                        advance.width += m_expansionPerOpportunity;
                         m_afterExpansion = true;
                     } else
                         m_afterExpansion = false;
@@ -514,33 +492,7 @@ void ComplexTextController::adjustGlyphsAndAdvances()
                     m_afterExpansion = false;
             }
 
-            // Deal with the float/integer impedance mismatch between CG and WebCore. "Words" (characters 
-            // followed by a character defined by isRoundingHackCharacter()) are always an integer width.
-            // We adjust the width of the last character of a "word" to ensure an integer width.
-            // Force characters that are used to determine word boundaries for the rounding hack
-            // to be integer width, so the following words will start on an integer boundary.
-            if (m_run.applyWordRounding() && Font::isRoundingHackCharacter(ch))
-                advance.width = ceilCGFloat(advance.width);
-
-            // Check to see if the next character is a "rounding hack character", if so, adjust the
-            // width so that the total run width will be on an integer boundary.
-            if ((m_run.applyWordRounding() && !lastGlyph && Font::isRoundingHackCharacter(nextCh)) || (m_run.applyRunRounding() && lastGlyph)) {
-                CGFloat totalWidth = widthSinceLastRounding + advance.width;
-                widthSinceLastRounding = ceilCGFloat(totalWidth);
-                CGFloat extraWidth = widthSinceLastRounding - totalWidth;
-                if (m_run.ltr())
-                    advance.width += extraWidth;
-                else {
-                    if (m_lastRoundingGlyph)
-                        m_adjustedAdvances[m_lastRoundingGlyph - 1].width += extraWidth;
-                    else
-                        m_finalRoundingWidth = extraWidth;
-                    m_lastRoundingGlyph = m_adjustedAdvances.size() + 1;
-                }
-                m_totalWidth += widthSinceLastRounding;
-                widthSinceLastRounding = 0;
-            } else
-                widthSinceLastRounding += advance.width;
+            widthSinceLastCommit += advance.width;
 
             // FIXME: Combining marks should receive a text emphasis mark if they are combine with a space.
             if (m_forTextEmphasis && (!Font::canReceiveTextEmphasis(ch) || (U_GET_GC_MASK(ch) & U_GC_M_MASK)))
@@ -564,7 +516,7 @@ void ComplexTextController::adjustGlyphsAndAdvances()
         if (!isMonotonic)
             complexTextRun.setIsNonMonotonic();
     }
-    m_totalWidth += widthSinceLastRounding;
+    m_totalWidth += widthSinceLastCommit;
 }
 
 } // namespace WebCore
index 63f93a2..7373bfe 100644 (file)
@@ -60,9 +60,6 @@ public:
 
     float totalWidth() const { return m_totalWidth; }
 
-    // Extra width to the left of the leftmost glyph.
-    float finalRoundingWidth() const { return m_finalRoundingWidth; }
-
     float minGlyphBoundingBoxX() const { return m_minGlyphBoundingBoxX; }
     float maxGlyphBoundingBoxX() const { return m_maxGlyphBoundingBoxX; }
     float minGlyphBoundingBoxY() const { return m_minGlyphBoundingBoxY; }
@@ -176,7 +173,6 @@ private:
     size_t m_currentRun;
     unsigned m_glyphInCurrentRun;
     unsigned m_characterInCurrentGlyph;
-    float m_finalRoundingWidth;
     float m_expansion;
     float m_expansionPerOpportunity;
     bool m_afterExpansion;
@@ -187,8 +183,6 @@ private:
     float m_maxGlyphBoundingBoxX;
     float m_minGlyphBoundingBoxY;
     float m_maxGlyphBoundingBoxY;
-    
-    unsigned m_lastRoundingGlyph;
 };
 
 } // namespace WebCore
index 865051d..eed49a5 100644 (file)
@@ -71,7 +71,7 @@ float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int
     float afterWidth = controller.runWidthSoFar();
 
     if (run.rtl()) {
-        initialAdvance = controller.totalWidth() + controller.finalRoundingWidth() - afterWidth;
+        initialAdvance = controller.totalWidth() - afterWidth;
         for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end)
             glyphBuffer.swap(i, end);
     } else
index 6a4fa03..2383006 100644 (file)
@@ -112,14 +112,14 @@ static NSColor* createPatternColor(NSString* name, NSColor* defaultColor, bool&
 }
 
 // WebKit on Mac is a standard platform component, so it must use the standard platform artwork for underline.
-void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width, TextCheckingLineStyle style)
+void GraphicsContext::drawLineForTextChecking(const FloatPoint& point, float width, TextCheckingLineStyle style)
 {
     if (paintingDisabled())
         return;
         
     // These are the same for misspelling or bad grammar.
     int patternHeight = cMisspellingLineThickness;
-    int patternWidth = cMisspellingLinePatternWidth;
+    float patternWidth = cMisspellingLinePatternWidth;
 
     bool usingDot;
     NSColor *patternColor;
@@ -165,7 +165,7 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width,
     // space between adjacent misspelled words was underlined.
     if (usingDot) {
         // allow slightly more considering that the pattern ends with a transparent pixel
-        int widthMod = width % patternWidth;
+        float widthMod = fmodf(width, patternWidth);
         if (patternWidth - widthMod > cMisspellingLinePatternGapWidth)
             width -= widthMod;
     }
index d552aa0..36c41d9 100644 (file)
@@ -854,13 +854,13 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int
     drawFocusRingForPath(m_data->p(), path, color, m_data->antiAliasingForRectsAndLines);
 }
 
-void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool)
+void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool)
 {
     if (paintingDisabled())
         return;
 
-    IntPoint startPoint = origin;
-    IntPoint endPoint = origin + IntSize(width, 0);
+    FloatPoint startPoint = origin;
+    FloatPoint endPoint = origin + FloatSize(width, 0);
 
     // If paintengine type is X11 to avoid artifacts
     // like bug https://bugs.webkit.org/show_bug.cgi?id=42248
@@ -880,10 +880,11 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool)
     }
 #endif // defined(Q_WS_X11)
 
-    drawLine(startPoint, endPoint);
+    // FIXME: Loss of precision here. Might consider rounding.
+    drawLine(IntPoint(startPoint.x(), startPoint.y()), IntPoint(endPoint.x(), endPoint.y()));
 }
 
-void GraphicsContext::drawLineForTextChecking(const IntPoint&, int, TextCheckingLineStyle)
+void GraphicsContext::drawLineForTextChecking(const FloatPoint&, float, TextCheckingLineStyle)
 {
     if (paintingDisabled())
         return;
index 9e43558..5d0b302 100644 (file)
@@ -61,7 +61,6 @@ void SimpleFontData::platformGlyphInit()
     if (!m_platformData.size())
         return;
     m_spaceGlyph = 0;
-    m_adjustedSpaceWidth = m_spaceWidth;
     determinePitch();
     m_missingGlyphData.fontData = this;
     m_missingGlyphData.glyph = 0;
index 3a6efeb..f8803ee 100644 (file)
@@ -606,7 +606,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
     platformContext()->canvas()->drawPoints(SkCanvas::kLines_PointMode, 2, pts, paint);
 }
 
-void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, TextCheckingLineStyle style)
+void GraphicsContext::drawLineForTextChecking(const FloatPoint& pt, float width, TextCheckingLineStyle style)
 {
     if (paintingDisabled())
         return;
@@ -655,8 +655,8 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, Tex
     }
 
     // Offset it vertically by 1 so that there's some space under the text.
-    SkScalar originX = SkIntToScalar(pt.x());
-    SkScalar originY = SkIntToScalar(pt.y()) + 1;
+    SkScalar originX = WebCoreFloatToSkScalar(pt.x());
+    SkScalar originY = WebCoreFloatToSkScalar(pt.y()) + 1;
 
     // Make a shader for the bitmap with an origin of the box we'll draw. This
     // shader is refcounted and will have an initial refcount of 1.
@@ -678,13 +678,13 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, Tex
     SkRect rect;
     rect.set(originX,
              originY,
-             originX + SkIntToScalar(width),
+             originX + WebCoreFloatToSkScalar(width),
              originY + SkIntToScalar(misspellBitmap->height()));
     platformContext()->canvas()->drawRect(rect, paint);
 }
 
-void GraphicsContext::drawLineForText(const IntPoint& pt,
-                                      int width,
+void GraphicsContext::drawLineForText(const FloatPoint& pt,
+                                      float width,
                                       bool printing)
 {
     if (paintingDisabled())
@@ -697,9 +697,9 @@ void GraphicsContext::drawLineForText(const IntPoint& pt,
 
     int thickness = SkMax32(static_cast<int>(strokeThickness()), 1);
     SkRect r;
-    r.fLeft = SkIntToScalar(pt.x());
-    r.fTop = SkIntToScalar(pt.y());
-    r.fRight = r.fLeft + SkIntToScalar(width);
+    r.fLeft = WebCoreFloatToSkScalar(pt.x());
+    r.fTop = WebCoreFloatToSkScalar(pt.y());
+    r.fRight = r.fLeft + WebCoreFloatToSkScalar(width);
     r.fBottom = r.fTop + SkIntToScalar(thickness);
 
     SkPaint paint;
index d3c6b58..d0bd4e9 100644 (file)
@@ -184,7 +184,7 @@ static const Color& grammarPatternColor() {
     return grammarColor;
 }
 
-void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width, TextCheckingLineStyle style)
+void GraphicsContext::drawLineForTextChecking(const FloatPoint& point, float width, TextCheckingLineStyle style)
 {
     if (paintingDisabled())
         return;
@@ -204,7 +204,7 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width,
     // bounds (e.g. when at the edge of a view) and could make it appear that the
     // space between adjacent misspelled words was underlined.
     // allow slightly more considering that the pattern ends with a transparent pixel
-    int widthMod = width % patternWidth;
+    float widthMod = fmodf(width, patternWidth);
     if (patternWidth - widthMod > cMisspellingLinePatternGapWidth)
         width -= widthMod;
       
index ebbed51..a850882 100644 (file)
@@ -261,18 +261,13 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S
         return true;
 
     // Convert all chars that should be treated as spaces to use the space glyph.
-    // We also create a map that allows us to quickly go from space glyphs or rounding
-    // hack glyphs back to their corresponding characters.
+    // We also create a map that allows us to quickly go from space glyphs back to their corresponding characters.
     Vector<int> spaceCharacters(glyphs.size());
     spaceCharacters.fill(-1);
-    Vector<int> roundingHackCharacters(glyphs.size());
-    roundingHackCharacters.fill(-1);
-    Vector<int> roundingHackWordBoundaries(glyphs.size());
-    roundingHackWordBoundaries.fill(-1);
 
     const float cLogicalScale = fontData->platformData().useGDI() ? 1.0f : 32.0f;
     unsigned logicalSpaceWidth = fontData->spaceWidth() * cLogicalScale;
-    float roundedSpaceWidth = roundf(fontData->spaceWidth());
+    float spaceWidth = fontData->spaceWidth();
 
     for (int k = 0; k < len; k++) {
         UChar ch = *(str + k);
@@ -286,21 +281,6 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S
             if (treatAsSpace)
                 spaceCharacters[clusters[k]] = m_currentCharacter + k + item.iCharPos;
         }
-
-        if (Font::isRoundingHackCharacter(ch))
-            roundingHackCharacters[clusters[k]] = m_currentCharacter + k + item.iCharPos;
-
-        int boundary = k + m_currentCharacter + item.iCharPos;
-        if (boundary < m_run.length()) {
-            // When at the last character in the str, don't look one past the end for a rounding hack character.
-            // Instead look ahead to the first character of next item, if there is a next one. 
-            if (k + 1 == len) {
-                if (i + 2 < m_items.size() // Check for at least 2 items remaining. The last item is a terminating item containing no characters.
-                    && Font::isRoundingHackCharacter(*(cp + m_items[i + 1].iCharPos)))
-                    roundingHackWordBoundaries[clusters[k]] = boundary;
-            } else if (Font::isRoundingHackCharacter(*(str + k + 1)))
-                roundingHackWordBoundaries[clusters[k]] = boundary;
-        }
     }
 
     // Populate our glyph buffer with this information.
@@ -324,14 +304,6 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S
 
         advance += fontData->syntheticBoldOffset();
 
-        // We special case spaces in two ways when applying word rounding.
-        // First, we round spaces to an adjusted width in all fonts.
-        // Second, in fixed-pitch fonts we ensure that all glyphs that
-        // match the width of the space glyph have the same width as the space glyph.
-        if (roundedAdvance == roundedSpaceWidth && (fontData->pitch() == FixedPitch || glyph == fontData->spaceGlyph()) &&
-            m_run.applyWordRounding())
-            advance = fontData->adjustedSpaceWidth();
-
         if (hasExtraSpacing) {
             // If we're a glyph with an advance, go ahead and add in letter-spacing.
             // That way we weed out zero width lurkers.  This behavior matches the fast text code path.
@@ -350,9 +322,8 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S
                         advance += m_padding;
                         m_padding = 0;
                     } else {
-                        float previousPadding = m_padding;
                         m_padding -= m_padPerSpace;
-                        advance += roundf(previousPadding) - roundf(m_padding);
+                        advance += m_padPerSpace;
                     }
                 }
 
@@ -362,25 +333,6 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S
             }
         }
 
-        // Deal with the float/integer impedance mismatch between CG and WebCore. "Words" (characters 
-        // followed by a character defined by isRoundingHackCharacter()) are always an integer width.
-        // We adjust the width of the last character of a "word" to ensure an integer width.
-        // Force characters that are used to determine word boundaries for the rounding hack
-        // to be integer width, so the following words will start on an integer boundary.
-        int roundingHackIndex = roundingHackCharacters[k];
-        if (m_run.applyWordRounding() && roundingHackIndex != -1)
-            advance = ceilf(advance);
-
-        // Check to see if the next character is a "rounding hack character", if so, adjust the
-        // width so that the total run width will be on an integer boundary.
-        int position = m_currentCharacter + len;
-        bool lastGlyph = (k == glyphs.size() - 1) && (m_run.rtl() ? i == 0 : i == m_items.size() - 2) && (position >= m_end);
-        if ((m_run.applyWordRounding() && roundingHackWordBoundaries[k] != -1) ||
-            (m_run.applyRunRounding() && lastGlyph)) { 
-            float totalWidth = m_runWidthSoFar + advance;
-            advance += ceilf(totalWidth) - totalWidth;
-        }
-
         m_runWidthSoFar += advance;
 
         // FIXME: We need to take the GOFFSETS for combining glyphs and store them in the glyph buffer
index 54763d4..b4bdf3f 100644 (file)
@@ -60,8 +60,8 @@ String FileChooser::basenameForWidth(const Font& font, int width) const
         gchar* systemBasename = g_path_get_basename(systemFilename.data());
         stringByAdoptingFileSystemRepresentation(systemBasename, string);
     } else if (m_filenames.size() > 1)
-        return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font, false);
+        return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font);
 
-    return StringTruncator::centerTruncate(string, width, font, false);
+    return StringTruncator::centerTruncate(string, width, font);
 }
 }
index fc58173..8f60fd4 100644 (file)
@@ -158,8 +158,7 @@ static float widthWithFont(NSString *string, NSFont *font)
     if (canUseFastRenderer(buffer.data(), length)) {
         Font webCoreFont(FontPlatformData(font, [font pointSize]), ![[NSGraphicsContext currentContext] isDrawingToScreen]);
         TextRun run(buffer.data(), length);
-        run.disableRoundingHacks();
-        return webCoreFont.floatWidth(run);
+        return webCoreFont.width(run);
     }
     
     return [string sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]].width;
@@ -197,8 +196,7 @@ static void drawAtPoint(NSString *string, NSPoint point, NSFont *font, NSColor *
             
         Font webCoreFont(FontPlatformData(font, [font pointSize]), ![nsContext isDrawingToScreen], Antialiased);
         TextRun run(buffer.data(), length);
-        run.disableRoundingHacks();
-        
+
         CGFloat red;
         CGFloat green;
         CGFloat blue;
index 03532ff..d9c2426 100644 (file)
@@ -47,9 +47,9 @@ String FileChooser::basenameForWidth(const Font& font, int width) const
     else if (m_filenames.size() == 1)
         strToTruncate = [[NSFileManager defaultManager] displayNameAtPath:(m_filenames[0])];
     else
-        return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font, false);
+        return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font);
 
-    return StringTruncator::centerTruncate(strToTruncate, width, font, false);
+    return StringTruncator::centerTruncate(strToTruncate, width, font);
 }
 
 }
index 4e5d168..0d67002 100644 (file)
@@ -210,13 +210,13 @@ DragImageRef createDragImageForLink(KURL& url, const String& inLabel, Frame* fra
     static const Color bottomColor(255, 255, 255, 127); // original alpha = 0.5
     if (drawURLString) {
         if (clipURLString)
-            urlString = StringTruncator::rightTruncate(urlString, imageSize.width() - (DragLabelBorderX * 2.0f), *urlFont, false);
+            urlString = StringTruncator::rightTruncate(urlString, imageSize.width() - (DragLabelBorderX * 2.0f), *urlFont);
         IntPoint textPos(DragLabelBorderX, imageSize.height() - (LabelBorderYOffset + urlFont->fontMetrics().descent()));
         WebCoreDrawDoubledTextAtPoint(context, urlString, textPos, *urlFont, topColor, bottomColor);
     }
     
     if (clipLabelString)
-        label = StringTruncator::rightTruncate(label, imageSize.width() - (DragLabelBorderX * 2.0f), *labelFont, false);
+        label = StringTruncator::rightTruncate(label, imageSize.width() - (DragLabelBorderX * 2.0f), *labelFont);
 
     IntPoint textPos(DragLabelBorderX, DragLabelBorderY + labelFont->pixelSize());
     WebCoreDrawDoubledTextAtPoint(context, label, textPos, *labelFont, topColor, bottomColor);
index 195b8eb..39ea0af 100644 (file)
@@ -46,9 +46,9 @@ String FileChooser::basenameForWidth(const Font& font, int width) const
         LPWSTR basename = PathFindFileNameW(tmpFilename.charactersWithNullTermination());
         string = String(basename);
     } else
-        return StringTruncator::rightTruncate(String::number(m_filenames.size()) + " files", width, font, false);
+        return StringTruncator::rightTruncate(String::number(m_filenames.size()) + " files", width, font);
 
-    return StringTruncator::centerTruncate(string, width, font, false);
+    return StringTruncator::centerTruncate(string, width, font);
 }
 
 } // namespace WebCore
index 3f3afa2..c75e219 100644 (file)
@@ -326,7 +326,7 @@ void PopupMenuWin::calculatePositionAndSize(const IntRect& r, FrameView* v)
             itemFont.update(m_popupClient->fontSelector());
         }
 
-        popupWidth = max(popupWidth, itemFont.width(TextRun(text.characters(), text.length())));
+        popupWidth = max(popupWidth, static_cast<int>(ceilf(itemFont.width(TextRun(text.characters(), text.length())))));
     }
 
     if (naturalHeight > maxPopupHeight)
index e96ba31..717e31d 100644 (file)
@@ -101,7 +101,7 @@ void WebCoreDrawDoubledTextAtPoint(GraphicsContext& context, const String& text,
 
 float WebCoreTextFloatWidth(const String& text, const Font& font)
 {
-    return StringTruncator::width(text, font, false);
+    return StringTruncator::width(text, font);
 }
 
 void WebCoreSetShouldUseFontSmoothing(bool smooth)
index 5d9b3df..ba98eff 100644 (file)
@@ -545,6 +545,23 @@ bool HitTestResult::addNodeToRectBasedTestResult(Node* node, int x, int y, const
     return !rect.contains(rectForPoint(x, y));
 }
 
+bool HitTestResult::addNodeToRectBasedTestResult(Node* node, int x, int y, const FloatRect& rect)
+{
+    // If it is not a rect-based hit test, this method has to be no-op.
+    // Return false, so the hit test stops.
+    if (!isRectBasedTest())
+        return false;
+
+    // If node is null, return true so the hit test can continue.
+    if (!node)
+        return true;
+
+    node = node->shadowAncestorNode();
+    m_rectBasedTestResult.add(node);
+
+    return !rect.contains(rectForPoint(x, y));
+}
+
 void HitTestResult::append(const HitTestResult& other)
 {
     ASSERT(isRectBasedTest() && other.isRectBasedTest());
index 1545da9..3aa17e3 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef HitTestResult_h
 #define HitTestResult_h
 
+#include "FloatRect.h"
 #include "IntPoint.h"
 #include "IntRect.h"
 #include "IntSize.h"
@@ -109,7 +110,8 @@ public:
 
     // Returns true if it is rect-based hit test and needs to continue until the rect is fully
     // enclosed by the boundaries of a node.
-    bool addNodeToRectBasedTestResult(Node*, int x, int y, const IntRect& rect = IntRect());
+    bool addNodeToRectBasedTestResult(Node*, int x, int y, const IntRect& = IntRect());
+    bool addNodeToRectBasedTestResult(Node*, int x, int y, const FloatRect&);
     const ListHashSet<RefPtr<Node> >& rectBasedTestResult() const { return m_rectBasedTestResult; }
     void append(const HitTestResult&);
 
index 4fcbe2d..1f4e244 100644 (file)
@@ -150,14 +150,12 @@ void InlineBox::attachLine()
         toRenderBox(m_renderer)->setInlineBoxWrapper(this);
 }
 
-void InlineBox::adjustPosition(int dx, int dy)
+void InlineBox::adjustPosition(float dx, float dy)
 {
     m_x += dx;
     m_y += dy;
-    if (m_renderer->isReplaced()) {
-        RenderBox* box = toRenderBox(m_renderer);
-        box->move(dx, dy);
-    }
+    if (m_renderer->isReplaced())
+        toRenderBox(m_renderer)->positionLineBox(this);
 }
 
 void InlineBox::paint(PaintInfo& paintInfo, int tx, int ty)
@@ -278,21 +276,35 @@ bool InlineBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidt
     return !(boxRect.intersects(ellipsisRect));
 }
 
-int InlineBox::placeEllipsisBox(bool, int, int, int, bool&)
+float InlineBox::placeEllipsisBox(bool, float, float, float, bool&)
 {
     // Use -1 to mean "we didn't set the position."
     return -1;
 }
 
-IntPoint InlineBox::locationIncludingFlipping()
+FloatPoint InlineBox::locationIncludingFlipping()
 {
     if (!renderer()->style()->isFlippedBlocksWritingMode())
-        return IntPoint(x(), y());
+        return FloatPoint(x(), y());
     RenderBlock* block = root()->block();
     if (block->style()->isHorizontalWritingMode())
-        return IntPoint(x(), block->height() - height() - y());
+        return FloatPoint(x(), block->height() - height() - y());
     else
-        return IntPoint(block->width() - width() - x(), y());
+        return FloatPoint(block->width() - width() - x(), y());
+}
+
+void InlineBox::flipForWritingMode(FloatRect& rect)
+{
+    if (!renderer()->style()->isFlippedBlocksWritingMode())
+        return;
+    root()->block()->flipForWritingMode(rect);
+}
+
+FloatPoint InlineBox::flipForWritingMode(const FloatPoint& point)
+{
+    if (!renderer()->style()->isFlippedBlocksWritingMode())
+        return point;
+    return root()->block()->flipForWritingMode(point);
 }
 
 void InlineBox::flipForWritingMode(IntRect& rect)
index d486ec0..de7b224 100644 (file)
@@ -68,7 +68,7 @@ public:
     {
     }
 
-    InlineBox(RenderObject* obj, int x, int y, int logicalWidth, bool firstLine, bool constructed,
+    InlineBox(RenderObject* obj, float x, float y, float logicalWidth, bool firstLine, bool constructed,
               bool dirty, bool extracted, bool isHorizontal, InlineBox* next, InlineBox* prev, InlineFlowBox* parent)
         : m_next(next)
         , m_prev(prev)
@@ -112,15 +112,15 @@ public:
 
     virtual bool isLineBreak() const { return false; }
 
-    virtual void adjustPosition(int dx, int dy);
-    void adjustLineDirectionPosition(int delta)
+    virtual void adjustPosition(float dx, float dy);
+    void adjustLineDirectionPosition(float delta)
     {
         if (isHorizontal())
             adjustPosition(delta, 0);
         else
             adjustPosition(0, delta);
     }
-    void adjustBlockDirectionPosition(int delta)
+    void adjustBlockDirectionPosition(float delta)
     {
         if (isHorizontal())
             adjustPosition(0, delta);
@@ -220,28 +220,28 @@ public:
     RootInlineBox* root();
 
     // x() is the left side of the box in the containing block's coordinate system.
-    void setX(int x) { m_x = x; }
-    int x() const { return m_x; }
+    void setX(float x) { m_x = x; }
+    float x() const { return m_x; }
 
     // y() is the top side of the box in the containing block's coordinate system.
-    void setY(int y) { m_y = y; }
-    int y() const { return m_y; }
+    void setY(float y) { m_y = y; }
+    float y() const { return m_y; }
 
-    int width() const { return isHorizontal() ? logicalWidth() : logicalHeight(); }
-    int height() const { return isHorizontal() ? logicalHeight() : logicalWidth(); }
-
-    IntRect frameRect() const { return IntRect(x(), y(), width(), height()); }
+    float width() const { return isHorizontal() ? logicalWidth() : logicalHeight(); }
+    float height() const { return isHorizontal() ? logicalHeight() : logicalWidth(); }
 
     // The logicalLeft position is the left edge of the line box in a horizontal line and the top edge in a vertical line.
-    int logicalLeft() const { return isHorizontal() ? m_x : m_y; }
-    int logicalRight() const { return logicalLeft() + logicalWidth(); }
-    void setLogicalLeft(int left)
+    float logicalLeft() const { return isHorizontal() ? m_x : m_y; }
+    float logicalRight() const { return logicalLeft() + logicalWidth(); }
+    void setLogicalLeft(float left)
     {
         if (isHorizontal())
             m_x = left;
         else
             m_y = left;
     }
+    int pixelSnappedLogicalLeft() const { return logicalLeft(); }
+    int pixelSnappedLogicalRight() const { return ceilf(logicalRight()); }
 
     // The logicalTop[ position is the top edge of the line box in a horizontal line and the left edge in a vertical line.
     int logicalTop() const { return isHorizontal() ? m_y : m_x; }
@@ -255,8 +255,8 @@ public:
     }
 
     // The logical width is our extent in the line's overall inline direction, i.e., width for horizontal text and height for vertical text.
-    void setLogicalWidth(int w) { m_logicalWidth = w; }
-    int logicalWidth() const { return m_logicalWidth; }
+    void setLogicalWidth(float w) { m_logicalWidth = w; }
+    float logicalWidth() const { return m_logicalWidth; }
 
     // The logical height is our extent in the block flow direction, i.e., height for horizontal text and width for vertical text.
     int logicalHeight() const;
@@ -286,7 +286,7 @@ public:
 
     virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth);
     // visibleLeftEdge, visibleRightEdge are in the parent's coordinate system.
-    virtual int placeEllipsisBox(bool ltr, int visibleLeftEdge, int visibleRightEdge, int ellipsisWidth, bool&);
+    virtual float placeEllipsisBox(bool ltr, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, bool&);
 
     void setHasBadParent();
 
@@ -294,6 +294,8 @@ public:
     
     bool visibleToHitTesting() const { return renderer()->style()->visibility() == VISIBLE && renderer()->style()->pointerEvents() != PE_NONE; }
     
+    EVerticalAlign verticalAlign() const { return renderer()->style(m_firstLine)->verticalAlign(); }
+
     // Use with caution! The type is not checked!
     RenderBoxModelObject* boxModelObject() const
     { 
@@ -302,7 +304,9 @@ public:
         return 0;
     }
 
-    IntPoint locationIncludingFlipping();
+    FloatPoint locationIncludingFlipping();
+    void flipForWritingMode(FloatRect&);
+    FloatPoint flipForWritingMode(const FloatPoint&);
     void flipForWritingMode(IntRect&);
     IntPoint flipForWritingMode(const IntPoint&);
 
@@ -315,9 +319,9 @@ private:
 public:
     RenderObject* m_renderer;
 
-    int m_x;
-    int m_y;
-    int m_logicalWidth;
+    float m_x;
+    float m_y;
+    float m_logicalWidth;
     
     // Some of these bits are actually for subclasses and moved here to compact the structures.
 
index aa9fcb5..30bbb66 100644 (file)
@@ -67,6 +67,18 @@ int InlineFlowBox::getFlowSpacingLogicalWidth()
     return totWidth;
 }
 
+IntRect InlineFlowBox::roundedFrameRect() const
+{
+    // Begin by snapping the x and y coordinates to the nearest pixel.
+    int snappedX = lroundf(x());
+    int snappedY = lroundf(y());
+    
+    int snappedMaxX = lroundf(x() + width());
+    int snappedMaxY = lroundf(y() + height());
+    
+    return IntRect(snappedX, snappedY, snappedMaxX - snappedX, snappedMaxY - snappedY);
+}
+
 void InlineFlowBox::addToLine(InlineBox* child) 
 {
     ASSERT(!child->parent());
@@ -167,13 +179,13 @@ void InlineFlowBox::attachLineBoxToRenderObject()
     toRenderInline(renderer())->lineBoxes()->attachLineBox(this);
 }
 
-void InlineFlowBox::adjustPosition(int dx, int dy)
+void InlineFlowBox::adjustPosition(float dx, float dy)
 {
     InlineBox::adjustPosition(dx, dy);
     for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
         child->adjustPosition(dx, dy);
     if (m_overflow)
-        m_overflow->move(dx, dy);
+        m_overflow->move(dx, dy); // FIXME: Rounding error here since overflow was pixel snapped, but nobody other than list markers passes non-integral values here.
 }
 
 RenderLineBoxList* InlineFlowBox::rendererLineBoxes() const
@@ -255,12 +267,12 @@ void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, RenderObject* en
     }
 }
 
-int InlineFlowBox::placeBoxesInInlineDirection(int logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
+float InlineFlowBox::placeBoxesInInlineDirection(float logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
 {
     // Set our x position.
     setLogicalLeft(logicalLeft);
   
-    int startLogicalLeft = logicalLeft;
+    float startLogicalLeft = logicalLeft;
     logicalLeft += borderLogicalLeft() + paddingLogicalLeft();
     
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
@@ -345,17 +357,16 @@ bool InlineFlowBox::requiresIdeographicBaseline(const GlyphOverflowAndFallbackFo
     return false;
 }
 
-void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent,
-                                              int maxPositionTop, int maxPositionBottom)
+void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent, int maxPositionTop, int maxPositionBottom)
 {
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
         // The computed lineheight needs to be extended for the
         // positioned elements
         if (curr->renderer()->isPositioned())
             continue; // Positioned placeholders don't affect calculations.
-        if (curr->logicalTop() == PositionTop || curr->logicalTop() == PositionBottom) {
+        if (curr->verticalAlign() == TOP || curr->verticalAlign() == BOTTOM) {
             int lineHeight = curr->lineHeight();
-            if (curr->logicalTop() == PositionTop) {
+            if (curr->verticalAlign() == TOP) {
                 if (maxAscent + maxDescent < lineHeight)
                     maxDescent = lineHeight - maxAscent;
             }
@@ -397,40 +408,37 @@ static int verticalPositionForBox(InlineBox* box, FontBaseline baselineType, boo
 
     int verticalPosition = 0;
     EVerticalAlign verticalAlign = renderer->style()->verticalAlign();
-    if (verticalAlign == TOP)
-        verticalPosition = PositionTop;
-    else if (verticalAlign == BOTTOM)
-        verticalPosition = PositionBottom;
-    else {
-        RenderObject* parent = renderer->parent();
-        if (parent->isRenderInline() && parent->style()->verticalAlign() != TOP && parent->style()->verticalAlign() != BOTTOM)
-            verticalPosition = box->parent()->logicalTop();
-        
-        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;
-
-            if (verticalAlign == SUB)
-                verticalPosition += fontSize / 5 + 1;
-            else if (verticalAlign == SUPER)
-                verticalPosition -= fontSize / 3 + 1;
-            else if (verticalAlign == TEXT_TOP)
-                verticalPosition += renderer->baselinePosition(baselineType, firstLine, lineDirection) - fontMetrics.ascent(baselineType);
-            else if (verticalAlign == MIDDLE)
-                verticalPosition += -static_cast<int>(fontMetrics.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
-            else if (verticalAlign == TEXT_BOTTOM) {
-                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));
-            } else if (verticalAlign == BASELINE_MIDDLE)
-                verticalPosition += -renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
-            else if (verticalAlign == LENGTH)
-                verticalPosition -= renderer->style()->verticalAlignLength().calcValue(renderer->lineHeight(firstLine, lineDirection));
-        }
+    if (verticalAlign == TOP || verticalAlign == BOTTOM)
+        return 0;
+   
+    RenderObject* parent = renderer->parent();
+    if (parent->isRenderInline() && parent->style()->verticalAlign() != TOP && parent->style()->verticalAlign() != BOTTOM)
+        verticalPosition = box->parent()->logicalTop();
+    
+    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;
+
+        if (verticalAlign == SUB)
+            verticalPosition += fontSize / 5 + 1;
+        else if (verticalAlign == SUPER)
+            verticalPosition -= fontSize / 3 + 1;
+        else if (verticalAlign == TEXT_TOP)
+            verticalPosition += renderer->baselinePosition(baselineType, firstLine, lineDirection) - fontMetrics.ascent(baselineType);
+        else if (verticalAlign == MIDDLE)
+            verticalPosition += -static_cast<int>(fontMetrics.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
+        else if (verticalAlign == TEXT_BOTTOM) {
+            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));
+        } else if (verticalAlign == BASELINE_MIDDLE)
+            verticalPosition += -renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType, firstLine, lineDirection);
+        else if (verticalAlign == LENGTH)
+            verticalPosition -= renderer->style()->verticalAlignLength().calcValue(renderer->lineHeight(firstLine, lineDirection));
     }
 
     // Store the cached value.
@@ -542,10 +550,10 @@ void InlineFlowBox::computeLogicalBoxHeights(int& maxPositionTop, int& maxPositi
             }
         }
 
-        if (curr->logicalTop() == PositionTop) {
+        if (curr->verticalAlign() == TOP) {
             if (maxPositionTop < lineHeight)
                 maxPositionTop = lineHeight;
-        } else if (curr->logicalTop() == PositionBottom) {
+        } else if (curr->verticalAlign() == BOTTOM) {
             if (maxPositionBottom < lineHeight)
                 maxPositionBottom = lineHeight;
         } else if ((!isInlineFlow || static_cast<InlineFlowBox*>(curr)->hasTextChildren()) || curr->boxModelObject()->hasInlineDirectionBordersOrPadding() || strictMode) {
@@ -592,9 +600,9 @@ void InlineFlowBox::placeBoxesInBlockDirection(int top, int maxHeight, int maxAs
                                                                           lineTopIncludingMargins, lineBottomIncludingMargins, hasAnnotationsBefore, hasAnnotationsAfter, baselineType);
 
         bool childAffectsTopBottomPos = true;
-        if (curr->logicalTop() == PositionTop)
+        if (curr->verticalAlign() == TOP)
             curr->setLogicalTop(top);
-        else if (curr->logicalTop() == PositionBottom)
+        else if (curr->verticalAlign() == BOTTOM)
             curr->setLogicalTop(top + maxHeight - curr->lineHeight());
         else {
             if ((isInlineFlow && !static_cast<InlineFlowBox*>(curr)->hasTextChildren()) && !curr->boxModelObject()->hasInlineDirectionBordersOrPadding() && !strictMode)
@@ -724,8 +732,8 @@ void InlineFlowBox::addBoxShadowVisualOverflow(IntRect& logicalVisualOverflow)
     int boxShadowLogicalRight;
     renderer()->style(m_firstLine)->getBoxShadowInlineDirectionExtent(boxShadowLogicalLeft, boxShadowLogicalRight);
 
-    int logicalLeftVisualOverflow = min(logicalLeft() + boxShadowLogicalLeft, logicalVisualOverflow.x());
-    int logicalRightVisualOverflow = max(logicalRight() + boxShadowLogicalRight, logicalVisualOverflow.maxX());
+    int logicalLeftVisualOverflow = min(pixelSnappedLogicalLeft() + boxShadowLogicalLeft, logicalVisualOverflow.x());
+    int logicalRightVisualOverflow = max(pixelSnappedLogicalRight() + boxShadowLogicalRight, logicalVisualOverflow.maxX());
     
     logicalVisualOverflow = IntRect(logicalLeftVisualOverflow, logicalTopVisualOverflow,
                                     logicalRightVisualOverflow - logicalLeftVisualOverflow, logicalBottomVisualOverflow - logicalTopVisualOverflow);
@@ -781,8 +789,8 @@ void InlineFlowBox::addTextBoxVisualOverflow(const InlineTextBox* textBox, Glyph
 
     int logicalTopVisualOverflow = min(textBox->logicalTop() + childOverflowLogicalTop, logicalVisualOverflow.y());
     int logicalBottomVisualOverflow = max(textBox->logicalBottom() + childOverflowLogicalBottom, logicalVisualOverflow.maxY());
-    int logicalLeftVisualOverflow = min(textBox->logicalLeft() + childOverflowLogicalLeft, logicalVisualOverflow.x());
-    int logicalRightVisualOverflow = max(textBox->logicalRight() + childOverflowLogicalRight, logicalVisualOverflow.maxX());
+    int logicalLeftVisualOverflow = min(textBox->pixelSnappedLogicalLeft() + childOverflowLogicalLeft, logicalVisualOverflow.x());
+    int logicalRightVisualOverflow = max(textBox->pixelSnappedLogicalRight() + childOverflowLogicalRight, logicalVisualOverflow.maxX());
     
     logicalVisualOverflow = IntRect(logicalLeftVisualOverflow, logicalTopVisualOverflow,
                                     logicalRightVisualOverflow - logicalLeftVisualOverflow, logicalBottomVisualOverflow - logicalTopVisualOverflow);
@@ -819,7 +827,7 @@ void InlineFlowBox::computeOverflow(int lineTop, int lineBottom, bool strictMode
     // Visual overflow just includes overflow for stuff we need to repaint ourselves.  Self-painting layers are ignored.
     // Layout overflow is used to determine scrolling extent, so it still includes child layers and also factors in
     // transforms, relative positioning, etc.
-    IntRect logicalLayoutOverflow(logicalLeft(), topOverflow, logicalWidth(), bottomOverflow - topOverflow);
+    IntRect logicalLayoutOverflow(enclosingIntRect(FloatRect(logicalLeft(), topOverflow, logicalWidth(), bottomOverflow - topOverflow)));
     IntRect logicalVisualOverflow(logicalLayoutOverflow);
   
     // box-shadow on root line boxes is applying to the block and not to the lines.
@@ -864,7 +872,7 @@ void InlineFlowBox::computeOverflow(int lineTop, int lineBottom, bool strictMode
 // all functions that query overflow.   
 void InlineFlowBox::setLayoutOverflow(const IntRect& rect)
 {
-    IntRect frameBox = frameRect();
+    IntRect frameBox = enclosingIntRect(FloatRect(x(), y(), width(), height()));
     if (frameBox == rect || rect.isEmpty())
         return;
         
@@ -876,7 +884,7 @@ void InlineFlowBox::setLayoutOverflow(const IntRect& rect)
 
 void InlineFlowBox::setVisualOverflow(const IntRect& rect)
 {
-    IntRect frameBox = frameRect();
+    IntRect frameBox = enclosingIntRect(FloatRect(x(), y(), width(), height()));
     if (frameBox == rect || rect.isEmpty())
         return;
         
@@ -912,9 +920,9 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
     }
 
     // Now check ourselves.
-    IntPoint boxOrigin = locationIncludingFlipping();
+    FloatPoint boxOrigin = locationIncludingFlipping();
     boxOrigin.move(tx, ty);
-    IntRect rect(boxOrigin, IntSize(width(), height()));
+    FloatRect rect(boxOrigin, IntSize(width(), height()));
     if (visibleToHitTesting() && rect.intersects(result.rectForPoint(x, y))) {
         renderer()->updateHitTestResult(result, flipForWritingMode(IntPoint(x - tx, y - ty))); // Don't add in m_x or m_y here, we want coords in the containing block's space.
         if (!result.addNodeToRectBasedTestResult(renderer()->node(), x, y, rect))
@@ -1050,10 +1058,12 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, int tx, int ty)
     if (!paintInfo.shouldPaintWithinRoot(renderer()) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
         return;
 
-    int x = m_x;
-    int y = m_y;
-    int w = width();
-    int h = height();
+    // Pixel snap background/border painting.
+    IntRect frameRect = roundedFrameRect();
+    int x = frameRect.x();
+    int y = frameRect.y();
+    int w = frameRect.width();
+    int h = frameRect.height();
 
     // Constrain our background/border painting to the line top and bottom if necessary.
     bool noQuirksMode = renderer()->document()->inNoQuirksMode();
@@ -1133,10 +1143,12 @@ void InlineFlowBox::paintMask(PaintInfo& paintInfo, int tx, int ty)
     if (!paintInfo.shouldPaintWithinRoot(renderer()) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
         return;
 
-    int x = m_x;
-    int y = m_y;
-    int w = width();
-    int h = height();
+    // Pixel snap mask painting.
+    IntRect frameRect = roundedFrameRect();
+    int x = frameRect.x();
+    int y = frameRect.y();
+    int w = frameRect.width();
+    int h = frameRect.height();
 
     // Constrain our background/border painting to the line top and bottom if necessary.
     bool noQuirksMode = renderer()->document()->inNoQuirksMode();
@@ -1237,14 +1249,14 @@ bool InlineFlowBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsis
     return true;
 }
 
-int InlineFlowBox::placeEllipsisBox(bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth, bool& foundBox)
+float InlineFlowBox::placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, bool& foundBox)
 {
-    int result = -1;
+    float result = -1;
     // We iterate over all children, the foundBox variable tells us when we've found the
     // box containing the ellipsis.  All boxes after that one in the flow are hidden.
     // If our flow is ltr then iterate over the boxes from left to right, otherwise iterate
     // from right to left. Varying the order allows us to correctly hide the boxes following the ellipsis.
-    InlineBox *box = ltr ? firstChild() : lastChild();
+    InlineBoxbox = ltr ? firstChild() : lastChild();
 
     // NOTE: these will cross after foundBox = true.
     int visibleLeftEdge = blockLeftEdge;
index d47111f..918cf5d 100644 (file)
@@ -85,7 +85,7 @@ public:
     virtual void deleteLine(RenderArena*);
     virtual void extractLine();
     virtual void attachLine();
-    virtual void adjustPosition(int dx, int dy);
+    virtual void adjustPosition(float dx, float dy);
 
     virtual void extractLineBoxFromRenderObject();
     virtual void attachLineBoxToRenderObject();
@@ -93,6 +93,8 @@ public:
 
     virtual void clearTruncation();
 
+    IntRect roundedFrameRect() const;
+    
     virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
     virtual void paintMask(PaintInfo&, int tx, int ty);
     void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, int tx, int ty, int w, int h, CompositeOperator = CompositeSourceOver);
@@ -155,7 +157,7 @@ public:
     void determineSpacingForFlowBoxes(bool lastLine, RenderObject* endObject);
     int getFlowSpacingLogicalWidth();
     bool onEndChain(RenderObject* endObject);
-    int placeBoxesInInlineDirection(int logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&);
+    float placeBoxesInInlineDirection(float logicalLeft, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap&);
     void computeLogicalBoxHeights(int& maxPositionTop, int& maxPositionBottom,
                                   int& maxAscent, int& maxDescent, bool& setMaxAscent, bool& setMaxDescent,
                                   bool strictMode, GlyphOverflowAndFallbackFontsMap&, FontBaseline, VerticalPositionCache&);
@@ -176,7 +178,7 @@ public:
     virtual RenderObject::SelectionState selectionState();
 
     virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth);
-    virtual int placeEllipsisBox(bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth, bool&);
+    virtual float placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, bool&);
 
     bool hasTextChildren() const { return m_hasTextChildren; }
 
@@ -187,10 +189,10 @@ public:
     // For horizontal-tb and vertical-lr they will match physical directions, but for horizontal-bt and vertical-rl, the top/bottom and left/right
     // respectively are flipped when compared to their physical counterparts.  For example minX is on the left in vertical-lr, but it is on the right in vertical-rl.
     int minYLayoutOverflow() const { return m_overflow ? m_overflow->minYLayoutOverflow() : m_y; }
-    int maxYLayoutOverflow() const { return m_overflow ? m_overflow->maxYLayoutOverflow() : m_y + height(); }
+    int maxYLayoutOverflow() const { return m_overflow ? m_overflow->maxYLayoutOverflow() : ceilf(m_y + height()); }
     int minXLayoutOverflow() const { return m_overflow ? m_overflow->minXLayoutOverflow() : m_x; }
-    int maxXLayoutOverflow() const { return m_overflow ? m_overflow->maxXLayoutOverflow() : m_x + width(); }
-    IntRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : IntRect(m_x, m_y, width(), height()); }
+    int maxXLayoutOverflow() const { return m_overflow ? m_overflow->maxXLayoutOverflow() : ceilf(m_x + width()); }
+    IntRect layoutOverflowRect() const { return m_overflow ? m_overflow->layoutOverflowRect() : enclosingIntRect(FloatRect(m_x, m_y, width(), height())); }
     int logicalLeftLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? minXLayoutOverflow() : minYLayoutOverflow(); }
     int logicalRightLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? maxXLayoutOverflow() : maxYLayoutOverflow(); }
     int logicalTopLayoutOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? minYVisualOverflow() : minXVisualOverflow(); }
@@ -204,10 +206,10 @@ public:
     }
 
     int minYVisualOverflow() const { return m_overflow ? m_overflow->minYVisualOverflow() : m_y; }
-    int maxYVisualOverflow() const { return m_overflow ? m_overflow->maxYVisualOverflow() : m_y + height(); }
+    int maxYVisualOverflow() const { return m_overflow ? m_overflow->maxYVisualOverflow() : ceilf(m_y + height()); }
     int minXVisualOverflow() const { return m_overflow ? m_overflow->minXVisualOverflow() : m_x; }
-    int maxXVisualOverflow() const { return m_overflow ? m_overflow->maxXVisualOverflow() : m_x + width(); }
-    IntRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : IntRect(m_x, m_y, width(), height()); }
+    int maxXVisualOverflow() const { return m_overflow ? m_overflow->maxXVisualOverflow() : ceilf(m_x + width()); }
+    IntRect visualOverflowRect() const { return m_overflow ? m_overflow->visualOverflowRect() : enclosingIntRect(FloatRect(m_x, m_y, width(), height())); }
     int logicalLeftVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? minXVisualOverflow() : minYVisualOverflow(); }
     int logicalRightVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? maxXVisualOverflow() : maxYVisualOverflow(); }
     int logicalTopVisualOverflow() const { return renderer()->style()->isHorizontalWritingMode() ? minYVisualOverflow() : minXVisualOverflow(); }
index 9fe92df..fb5f2be 100644 (file)
@@ -201,7 +201,7 @@ void InlineTextBox::attachLine()
     toRenderText(renderer())->attachTextBox(this);
 }
 
-int InlineTextBox::placeEllipsisBox(bool flowIsLTR, int visibleLeftEdge, int visibleRightEdge, int ellipsisWidth, bool& foundBox)
+float InlineTextBox::placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, bool& foundBox)
 {
     if (foundBox) {
         m_truncation = cFullTruncation;
@@ -209,7 +209,7 @@ int InlineTextBox::placeEllipsisBox(bool flowIsLTR, int visibleLeftEdge, int vis
     }
 
     // For LTR this is the left edge of the box, for RTL, the right edge in parent coordinates.
-    int ellipsisX = flowIsLTR ? visibleRightEdge - ellipsisWidth : visibleLeftEdge + ellipsisWidth;
+    float ellipsisX = flowIsLTR ? visibleRightEdge - ellipsisWidth : visibleLeftEdge + ellipsisWidth;
     
     // Criteria for full truncation:
     // LTR: the left edge of the ellipsis is to the left of our text run.
@@ -251,7 +251,7 @@ int InlineTextBox::placeEllipsisBox(bool flowIsLTR, int visibleLeftEdge, int vis
 
         // If we got here that means that we were only partially truncated and we need to return the pixel offset at which
         // to place the ellipsis.
-        int widthOfVisibleText = toRenderText(renderer())->width(m_start, offset, textPos(), m_firstLine);
+        float widthOfVisibleText = toRenderText(renderer())->width(m_start, offset, textPos(), m_firstLine);
 
         // The ellipsis needs to be placed just after the last visible character.
         // Where "after" is defined by the flow directionality, not the inline
@@ -319,9 +319,9 @@ bool InlineTextBox::nodeAtPoint(const HitTestRequest&, HitTestResult& result, in
     if (isLineBreak())
         return false;
 
-    IntPoint boxOrigin = locationIncludingFlipping();
+    FloatPoint boxOrigin = locationIncludingFlipping();
     boxOrigin.move(tx, ty);
-    IntRect rect(boxOrigin, IntSize(width(), height()));
+    FloatRect rect(boxOrigin, IntSize(width(), height()));
     if (m_truncation != cFullTruncation && visibleToHitTesting() && rect.intersects(result.rectForPoint(x, y))) {
         renderer()->updateHitTestResult(result, flipForWritingMode(IntPoint(x - tx, y - ty)));
         if (!result.addNodeToRectBasedTestResult(renderer()->node(), x, y, rect))
@@ -357,8 +357,8 @@ FloatSize InlineTextBox::applyShadowToGraphicsContext(GraphicsContext* context,
     return extraOffset;
 }
 
-static void paintTextWithShadows(GraphicsContext* context, const Font& font, const TextRun& textRun, const AtomicString& emphasisMark, int emphasisMarkOffset, int startOffset, int endOffset, int truncationPoint, const IntPoint& textOrigin,
-                                 const IntRect& boxRect, const ShadowData* shadow, bool stroked, bool horizontal)
+static void paintTextWithShadows(GraphicsContext* context, const Font& font, const TextRun& textRun, const AtomicString& emphasisMark, int emphasisMarkOffset, int startOffset, int endOffset, int truncationPoint, const FloatPoint& textOrigin,
+                                 const FloatRect& boxRect, const ShadowData* shadow, bool stroked, bool horizontal)
 {
     Color fillColor = context->fillColor();
     ColorSpace fillColorSpace = context->fillColorSpace();
@@ -482,10 +482,10 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty)
     
     ty -= styleToUse->isHorizontalWritingMode() ? 0 : logicalHeight();
 
-    IntPoint boxOrigin = locationIncludingFlipping();
+    FloatPoint boxOrigin = locationIncludingFlipping();
     boxOrigin.move(tx, ty);    
-    IntRect boxRect(boxOrigin, IntSize(logicalWidth(), logicalHeight()));
-    IntPoint textOrigin = IntPoint(boxOrigin.x(), boxOrigin.y() + styleToUse->fontMetrics().ascent());
+    FloatRect boxRect(boxOrigin, IntSize(logicalWidth(), logicalHeight()));
+    FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + styleToUse->fontMetrics().ascent());
 
     RenderCombineText* combinedText = styleToUse->hasTextCombine() ? toRenderCombineText(textRenderer()) : 0;
     bool shouldRotate = !isHorizontal() && (!combinedText || !combinedText->isCombined());
@@ -736,7 +736,7 @@ void InlineTextBox::selectionStartEnd(int& sPos, int& ePos)
     ePos = min(endPos - m_start, (int)m_len);
 }
 
-void InlineTextBox::paintSelection(GraphicsContext* context, const IntPoint& boxOrigin, RenderStyle* style, const Font& font)
+void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font)
 {
     // See if we have a selection to paint at all.
     int sPos, ePos;
@@ -770,15 +770,15 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const IntPoint& box
 
     int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
     int selHeight = selectionHeight();
-    IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
-    context->clip(IntRect(localOrigin, IntSize(m_logicalWidth, selHeight)));
+    FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
+    context->clip(FloatRect(localOrigin, FloatSize(m_logicalWidth, selHeight)));
     context->drawHighlightForText(font, TextRun(characters, length, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), 
                                   !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
                                   localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
     context->restore();
 }
 
-void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const IntPoint& boxOrigin, RenderStyle* style, const Font& font, int startPos, int endPos)
+void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font, int startPos, int endPos)
 {
     int offset = m_start;
     int sPos = max(startPos - offset, 0);
@@ -795,7 +795,7 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const I
 
     int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
     int selHeight = selectionHeight();
-    IntPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
+    FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
     context->drawHighlightForText(font, TextRun(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(),
                                   !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered()),
                                   localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
@@ -822,14 +822,14 @@ void InlineTextBox::paintCustomHighlight(int tx, int ty, const AtomicString& typ
 
 #endif
 
-void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& boxOrigin, int deco, const ShadowData* shadow)
+void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, int deco, const ShadowData* shadow)
 {
     if (m_truncation == cFullTruncation)
         return;
 
-    IntPoint localOrigin = boxOrigin;
+    FloatPoint localOrigin = boxOrigin;
 
-    int width = m_logicalWidth;
+    float width = m_logicalWidth;
     if (m_truncation != cNoTruncation) {
         width = toRenderText(renderer())->width(m_start, m_truncation, textPos(), m_firstLine);
         if (!isLeftToRightDirection())
@@ -853,9 +853,9 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& bo
     int extraOffset = 0;
     if (!linesAreOpaque && shadow && shadow->next()) {
         context->save();
-        IntRect clipRect(localOrigin, IntSize(width, baseline + 2));
+        FloatRect clipRect(localOrigin, FloatSize(width, baseline + 2));
         for (const ShadowData* s = shadow; s; s = s->next()) {
-            IntRect shadowRect(localOrigin, IntSize(width, baseline + 2));
+            FloatRect shadowRect(localOrigin, FloatSize(width, baseline + 2));
             shadowRect.inflate(s->blur());
             int shadowX = isHorizontal() ? s->x() : s->y();
             int shadowY = isHorizontal() ? s->y() : -s->x();
@@ -882,7 +882,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& bo
             }
             int shadowX = isHorizontal() ? shadow->x() : shadow->y();
             int shadowY = isHorizontal() ? shadow->y() : -shadow->x();
-            context->setShadow(IntSize(shadowX, shadowY - extraOffset), shadow->blur(), shadow->color(), colorSpace);
+            context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow->blur(), shadow->color(), colorSpace);
             setShadow = true;
             shadow = shadow->next();
         }
@@ -891,7 +891,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& bo
             context->setStrokeColor(underline, colorSpace);
             context->setStrokeStyle(SolidStroke);
             // Leave one pixel of white between the baseline and the underline.
-            context->drawLineForText(IntPoint(localOrigin.x(), localOrigin.y() + baseline + 1), width, isPrinting);
+            context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + baseline + 1), width, isPrinting);
         }
         if (deco & OVERLINE) {
             context->setStrokeColor(overline, colorSpace);
@@ -901,7 +901,7 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const IntPoint& bo
         if (deco & LINE_THROUGH) {
             context->setStrokeColor(linethrough, colorSpace);
             context->setStrokeStyle(SolidStroke);
-            context->drawLineForText(IntPoint(localOrigin.x(), localOrigin.y() + 2 * baseline / 3), width, isPrinting);
+            context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + 2 * baseline / 3), width, isPrinting);
         }
     } while (shadow);
 
@@ -926,7 +926,7 @@ static GraphicsContext::TextCheckingLineStyle textCheckingLineStyleForMarkerType
     }
 }
 
-void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntPoint& boxOrigin, const DocumentMarker& marker, RenderStyle* style, const Font& font, bool grammar)
+void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const FloatPoint& boxOrigin, const DocumentMarker& marker, RenderStyle* style, const Font& font, bool grammar)
 {
     // Never print spelling/grammar markers (5327887)
     if (textRenderer()->document()->printing())
@@ -935,8 +935,8 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntP
     if (m_truncation == cFullTruncation)
         return;
 
-    int start = 0;                  // start of line to draw, relative to tx
-    int width = m_logicalWidth;            // how much line to draw
+    float start = 0; // start of line to draw, relative to tx
+    float width = m_logicalWidth; // how much line to draw
 
     // Determine whether we need to measure text
     bool markerSpansWholeBox = true;
@@ -957,9 +957,10 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntP
         // Calculate start & width
         int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
         int selHeight = selectionHeight();
-        IntPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
+        FloatPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
         TextRun run(textRenderer()->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride || style->visuallyOrdered());
-         
+        
+        // FIXME: Convert the document markers to float rects.
         IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, selHeight, startPosition, endPosition));
         start = markerRect.x() - startPoint.x();
         width = markerRect.width();
@@ -990,10 +991,10 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const IntP
         // In larger fonts, though, place the underline up near the baseline to prevent a big gap.
         underlineOffset = baseline + 2;
     }
-    pt->drawLineForTextChecking(IntPoint(boxOrigin.x() + start, boxOrigin.y() + underlineOffset), width, textCheckingLineStyleForMarkerType(marker.type));
+    pt->drawLineForTextChecking(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + underlineOffset), width, textCheckingLineStyleForMarkerType(marker.type));
 }
 
-void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const IntPoint& boxOrigin, const DocumentMarker& marker, RenderStyle* style, const Font& font)
+void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint& boxOrigin, const DocumentMarker& marker, RenderStyle* style, const Font& font)
 {
     // Use same y positioning and height as for selection, so that when the selection and this highlight are on
     // the same word there are no pieces sticking out.
@@ -1016,8 +1017,8 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const IntPoint& bo
             renderer()->theme()->platformInactiveTextSearchHighlightColor();
         pt->save();
         updateGraphicsContext(pt, color, color, 0, style->colorSpace());  // Don't draw text at all!
-        pt->clip(IntRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_logicalWidth, selHeight));
-        pt->drawHighlightForText(font, run, IntPoint(boxOrigin.x(), boxOrigin.y() - deltaY), selHeight, color, style->colorSpace(), sPos, ePos);
+        pt->clip(FloatRect(boxOrigin.x(), boxOrigin.y() - deltaY, m_logicalWidth, selHeight));
+        pt->drawHighlightForText(font, run, FloatPoint(boxOrigin.x(), boxOrigin.y() - deltaY), selHeight, color, style->colorSpace(), sPos, ePos);
         pt->restore();
     }
 }
@@ -1039,7 +1040,7 @@ void InlineTextBox::computeRectForReplacementMarker(const DocumentMarker& marker
     renderer()->document()->markers()->setRenderedRectForMarker(renderer()->node(), marker, markerRect);
 }
     
-void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const IntPoint& boxOrigin, RenderStyle* style, const Font& font, bool background)
+void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font, bool background)
 {
     if (!renderer()->node())
         return;
@@ -1099,14 +1100,13 @@ void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const IntPoint& bo
     }
 }
 
-
-void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const IntPoint& boxOrigin, const CompositionUnderline& underline)
+void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const FloatPoint& boxOrigin, const CompositionUnderline& underline)
 {
     if (m_truncation == cFullTruncation)
         return;
     
-    int start = 0;                 // start of line to draw, relative to tx
-    int width = m_logicalWidth;           // how much line to draw
+    float start = 0; // start of line to draw, relative to tx
+    float width = m_logicalWidth; // how much line to draw
     bool useWholeWidth = true;
     unsigned paintStart = m_start;
     unsigned paintEnd = end() + 1; // end points at the last char, not past it
@@ -1142,7 +1142,7 @@ void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const IntPoi
 
     ctx->setStrokeColor(underline.color, renderer()->style()->colorSpace());
     ctx->setStrokeThickness(lineThickness);
-    ctx->drawLineForText(IntPoint(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness), width, textRenderer()->document()->printing());
+    ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness), width, textRenderer()->document()->printing());
 }
 
 int InlineTextBox::caretMinOffset() const
@@ -1160,7 +1160,7 @@ unsigned InlineTextBox::caretMaxRenderedOffset() const
     return m_start + m_len;
 }
 
-int InlineTextBox::textPos() const
+float InlineTextBox::textPos() const
 {
     // When computing the width of a text run, RenderBlock::computeInlineDirectionPositionsForLine() doesn't include the actual offset
     // from the containing block edge in its measurement. textPos() should be consistent so the text are rendered in the same width.
@@ -1169,7 +1169,7 @@ int InlineTextBox::textPos() const
     return logicalLeft() - root()->logicalLeft();
 }
 
-int InlineTextBox::offsetForPosition(int lineOffset, bool includePartialGlyphs) const
+int InlineTextBox::offsetForPosition(float lineOffset, bool includePartialGlyphs) const
 {
     if (isLineBreak())
         return 0;
@@ -1196,7 +1196,7 @@ int InlineTextBox::offsetForPosition(int lineOffset, bool includePartialGlyphs)
     return offset;
 }
 
-int InlineTextBox::positionForOffset(int offset) const
+float InlineTextBox::positionForOffset(int offset) const
 {
     ASSERT(offset >= m_start);
     ASSERT(offset <= m_start + m_len);
@@ -1209,8 +1209,8 @@ int InlineTextBox::positionForOffset(int offset) const
     int from = !isLeftToRightDirection() ? offset - m_start : 0;
     int to = !isLeftToRightDirection() ? m_len : offset - m_start;
     // FIXME: Do we need to add rightBearing here?
-    return enclosingIntRect(f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride),
-                                                   IntPoint(logicalLeft(), 0), 0, from, to)).maxX();
+    return f.selectionRectForText(TextRun(text->text()->characters() + m_start, m_len, textRenderer()->allowTabs(), textPos(), m_expansion, trailingExpansionBehavior(), !isLeftToRightDirection(), m_dirOverride),
+                                  IntPoint(logicalLeft(), 0), 0, from, to).maxX();
 }
 
 bool InlineTextBox::containsCaretOffset(int offset) const
index 724ef82..d894b85 100644 (file)
@@ -105,12 +105,12 @@ public:
 
 private:
     virtual void clearTruncation() { m_truncation = cNoTruncation; }
-    virtual int placeEllipsisBox(bool flowIsLTR, int visibleLeftEdge, int visibleRightEdge, int ellipsisWidth, bool& foundBox);
+    virtual float placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, bool& foundBox);
 
 public:
     virtual bool isLineBreak() const;
 
-    void setExpansion(int expansion) { m_logicalWidth -= m_expansion; m_expansion = expansion; m_logicalWidth += m_expansion; }
+    void setExpansion(float expansion) { m_logicalWidth -= m_expansion; m_expansion = expansion; m_logicalWidth += m_expansion; }
 
 private:
     virtual bool isInlineTextBox() const { return true; }    
@@ -122,11 +122,11 @@ public:
 private:
     virtual unsigned caretMaxRenderedOffset() const;
 
-    int textPos() const; // returns the x position relative to the left start of the text line.
+    float textPos() const; // returns the x position relative to the left start of the text line.
 
 public:
-    virtual int offsetForPosition(int x, bool includePartialGlyphs = true) const;
-    virtual int positionForOffset(int offset) const;
+    virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const;
+    virtual float positionForOffset(int offset) const;
 
     bool containsCaretOffset(int offset) const; // false for offset after line break
 
@@ -144,18 +144,18 @@ private:
                       // denote no truncation (the whole run paints) and full truncation (nothing paints at all).
 
 protected:
-    void paintCompositionBackground(GraphicsContext*, const IntPoint& boxOrigin, RenderStyle*, const Font&, int startPos, int endPos);
-    void paintDocumentMarkers(GraphicsContext*, const IntPoint& boxOrigin, RenderStyle*, const Font&, bool background);
-    void paintCompositionUnderline(GraphicsContext*, const IntPoint& boxOrigin, const CompositionUnderline&);
+    void paintCompositionBackground(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, int startPos, int endPos);
+    void paintDocumentMarkers(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, bool background);
+    void paintCompositionUnderline(GraphicsContext*, const FloatPoint& boxOrigin, const CompositionUnderline&);
 #if PLATFORM(MAC)
     void paintCustomHighlight(int tx, int ty, const AtomicString& type);
 #endif
 
 private:
-    void paintDecoration(GraphicsContext*, const IntPoint& boxOrigin, int decoration, const ShadowData*);
-    void paintSelection(GraphicsContext*, const IntPoint& boxOrigin, RenderStyle*, const Font&);
-    void paintSpellingOrGrammarMarker(GraphicsContext*, const IntPoint& boxOrigin, const DocumentMarker&, RenderStyle*, const Font&, bool grammar);
-    void paintTextMatchMarker(GraphicsContext*, const IntPoint& boxOrigin, const DocumentMarker&, RenderStyle*, const Font&);
+    void paintDecoration(GraphicsContext*, const FloatPoint& boxOrigin, int decoration, const ShadowData*);
+    void paintSelection(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&);
+    void paintSpellingOrGrammarMarker(GraphicsContext*, const FloatPoint& boxOrigin, const DocumentMarker&, RenderStyle*, const Font&, bool grammar);
+    void paintTextMatchMarker(GraphicsContext*, const FloatPoint& boxOrigin, const DocumentMarker&, RenderStyle*, const Font&);
     void computeRectForReplacementMarker(const DocumentMarker&, RenderStyle*, const Font&);
 
     TextRun::TrailingExpansionBehavior trailingExpansionBehavior() const { return m_expansion && nextLeafChild() ? TextRun::AllowTrailingExpansion : TextRun::ForbidTrailingExpansion; }
index 72a4514..25717b1 100644 (file)
@@ -40,8 +40,8 @@ public:
  
     virtual IntRect selectionRectForRepaint(RenderBoxModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/) { return IntRect(); }
 
-    virtual unsigned width(unsigned /*from*/, unsigned /*len*/, const Font&, int /*xPos*/, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/ , GlyphOverflow* = 0) const { return 0; }
-    virtual unsigned width(unsigned /*from*/, unsigned /*len*/, int /*xpos*/, bool = false /*firstLine*/, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/, GlyphOverflow* = 0) const { return 0; }
+    virtual float width(unsigned /*from*/, unsigned /*len*/, const Font&, float /*xPos*/, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/ , GlyphOverflow* = 0) const { return 0; }
+    virtual float width(unsigned /*from*/, unsigned /*len*/, float /*xpos*/, bool = false /*firstLine*/, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/, GlyphOverflow* = 0) const { return 0; }
 
     int lineHeight(bool firstLine) const;
 
index 5b93eca..2197533 100644 (file)
@@ -4616,7 +4616,7 @@ static int getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfI
                child->borderStart();
 }
 
-static inline void stripTrailingSpace(int& inlineMax, int& inlineMin,
+static inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
                                       RenderObject* trailingSpaceChild)
 {
     if (trailingSpaceChild && trailingSpaceChild->isText()) {
@@ -4624,17 +4624,23 @@ static inline void stripTrailingSpace(int& inlineMax, int& inlineMin,
         RenderText* t = toRenderText(trailingSpaceChild);
         const UChar space = ' ';
         const Font& font = t->style()->font(); // FIXME: This ignores first-line.
-        int spaceWidth = font.width(TextRun(&space, 1));
+        float spaceWidth = font.width(TextRun(&space, 1));
         inlineMax -= spaceWidth + font.wordSpacing();
         if (inlineMin > inlineMax)
             inlineMin = inlineMax;
     }
 }
 
+static inline void updatePreferredWidth(int& preferredWidth, float& result)
+{
+    int snappedResult = ceilf(result);
+    preferredWidth = max(snappedResult, preferredWidth);
+}
+
 void RenderBlock::computeInlinePreferredLogicalWidths()
 {
-    int inlineMax = 0;
-    int inlineMin = 0;
+    float inlineMax = 0;
+    float inlineMin = 0;
 
     int cw = containingBlock()->contentLogicalWidth();
 
@@ -4695,15 +4701,15 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
             // the width of the last non-breakable run and use that to start a new line
             // (unless we end in whitespace).
             RenderStyle* cstyle = child->style();
-            int childMin = 0;
-            int childMax = 0;
+            float childMin = 0;
+            float childMax = 0;
 
             if (!child->isText()) {
                 // Case (1) and (2).  Inline replaced and inline flow elements.
                 if (child->isRenderInline()) {
                     // Add in padding/border/margin from the appropriate side of
                     // the element.
-                    int bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
+                    float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
                     childMin += bpm;
                     childMax += bpm;
 
@@ -4713,7 +4719,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
                     child->setPreferredLogicalWidthsDirty(false);
                 } else {
                     // Inline replaced elts add in their margins to their min/max values.
-                    int margins = 0;
+                    float margins = 0;
                     Length startMargin = cstyle->marginStart();
                     Length endMargin = cstyle->marginEnd();
                     if (startMargin.isFixed())
@@ -4743,13 +4749,13 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
 
                 bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
                 if ((canBreakReplacedElement && (autoWrap || oldAutoWrap)) || clearPreviousFloat) {
-                    m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+                    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
                     inlineMin = 0;
                 }
 
                 // If we're supposed to clear the previous float, then terminate maxwidth as well.
                 if (clearPreviousFloat) {
-                    m_maxPreferredLogicalWidth = max(inlineMax, m_maxPreferredLogicalWidth);
+                    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
                     inlineMax = 0;
                 }
 
@@ -4767,12 +4773,12 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
 
                 if (!autoWrap || !canBreakReplacedElement) {
                     if (child->isFloating())
-                        m_minPreferredLogicalWidth = max(childMin, m_minPreferredLogicalWidth);
+                        updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
                     else
                         inlineMin += childMin;
                 } else {
                     // Now check our line.
-                    m_minPreferredLogicalWidth = max(childMin, m_minPreferredLogicalWidth);
+                    updatePreferredWidth(m_minPreferredLogicalWidth, childMin);
 
                     // Now start a new line.
                     inlineMin = 0;
@@ -4789,7 +4795,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
                 RenderText* t = toRenderText(child);
 
                 if (t->isWordBreak()) {
-                    m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+                    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
                     inlineMin = 0;
                     continue;
                 }
@@ -4803,9 +4809,9 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
                 // then they shouldn't be considered in the breakable char
                 // check.
                 bool hasBreakableChar, hasBreak;
-                int beginMin, endMin;
+                float beginMin, endMin;
                 bool beginWS, endWS;
-                int beginMax, endMax;
+                float beginMax, endMax;
                 t->trimmedPrefWidths(inlineMax, beginMin, beginWS, endMin, endWS,
                                      hasBreakableChar, hasBreak, beginMax, endMax,
                                      childMin, childMax, stripFrontSpaces);
@@ -4813,7 +4819,7 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
                 // This text object will not be rendered, but it may still provide a breaking opportunity.
                 if (!hasBreak && childMax == 0) {
                     if (autoWrap && (beginWS || endWS)) {
-                        m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
                         inlineMin = 0;
                     }
                     continue;
@@ -4843,10 +4849,10 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
                     // we start and end with whitespace.
                     if (beginWS)
                         // Go ahead and end the current line.
-                        m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
                     else {
                         inlineMin += beginMin;
-                        m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
                         childMin -= ti;
                     }
 
@@ -4855,18 +4861,18 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
                     if (endWS) {
                         // We end in whitespace, which means we can go ahead
                         // and end our current line.
-                        m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
                         inlineMin = 0;
                     } else {
-                        m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
+                        updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
                         inlineMin = endMin;
                     }
                 }
 
                 if (hasBreak) {
                     inlineMax += beginMax;
-                    m_maxPreferredLogicalWidth = max(inlineMax, m_maxPreferredLogicalWidth);
-                    m_maxPreferredLogicalWidth = max(childMax, m_maxPreferredLogicalWidth);
+                    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
+                    updatePreferredWidth(m_maxPreferredLogicalWidth, childMax);
                     inlineMax = endMax;
                 } else
                     inlineMax += childMax;
@@ -4876,8 +4882,8 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
             if (child->isListMarker())
                 stripFrontSpaces = true;
         } else {
-            m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
-            m_maxPreferredLogicalWidth = max(inlineMax, m_maxPreferredLogicalWidth);
+            updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
+            updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
             inlineMin = inlineMax = 0;
             stripFrontSpaces = true;
             trailingSpaceChild = 0;
@@ -4889,8 +4895,8 @@ void RenderBlock::computeInlinePreferredLogicalWidths()
     if (style()->collapseWhiteSpace())
         stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
 
-    m_minPreferredLogicalWidth = max(inlineMin, m_minPreferredLogicalWidth);
-    m_maxPreferredLogicalWidth = max(inlineMax, m_maxPreferredLogicalWidth);
+    updatePreferredWidth(m_minPreferredLogicalWidth, inlineMin);
+    updatePreferredWidth(m_maxPreferredLogicalWidth, inlineMax);
 }
 
 // Use a very large value (in effect infinite).
@@ -5468,9 +5474,9 @@ void RenderBlock::adjustForBorderFit(int x, int& left, int& right) const
         if (childrenInline()) {
             for (RootInlineBox* box = firstRootBox(); box; box = box->nextRootBox()) {
                 if (box->firstChild())
-                    left = min(left, x + box->firstChild()->x());
+                    left = min(left, x + static_cast<int>(box->firstChild()->x()));
                 if (box->lastChild())
-                    right = max(right, x + box->lastChild()->x() + box->lastChild()->logicalWidth());
+                    right = max(right, x + static_cast<int>(ceilf(box->lastChild()->logicalRight())));
             }
         }
         else {
@@ -5770,8 +5776,8 @@ void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
 
     if (!hasOverflowClip() && !hasControlClip()) {
         for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
-            int top = max(curr->lineTop(), curr->y());
-            int bottom = min(curr->lineBottom(), curr->y() + curr->logicalHeight());
+            int top = max(curr->lineTop(), curr->logicalTop());
+            int bottom = min(curr->lineBottom(), curr->logicalTop() + curr->logicalHeight());
             IntRect rect(tx + curr->x(), ty + top, curr->logicalWidth(), bottom - top);
             if (!rect.isEmpty())
                 rects.append(rect);
index 2c61331..2db3570 100644 (file)
@@ -485,7 +485,7 @@ private:
 
     void skipTrailingWhitespace(InlineIterator&, bool isLineEmpty, bool previousLineBrokeCleanly);
     int skipLeadingWhitespace(InlineBidiResolver&, bool firstLine, bool isLineEmpty, bool previousLineBrokeCleanly, FloatingObject* lastFloatFromPreviousLine);
-    void fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth);
+    void fitBelowFloats(float widthToFit, bool firstLine, float& availableWidth);
     InlineIterator findNextLineBreak(InlineBidiResolver&, bool firstLine, bool& isLineEmpty, bool& previousLineBrokeCleanly, bool& hyphenated, EClear*, FloatingObject* lastFloatFromPreviousLine);
     RootInlineBox* constructLine(unsigned runCount, BidiRun* firstRun, BidiRun* lastRun, bool firstLine, bool lastLine, RenderObject* endObject);
     InlineFlowBox* createLineBoxes(RenderObject*, bool firstLine);
index 945a0d1..45b85dd 100644 (file)
@@ -318,8 +318,8 @@ RootInlineBox* RenderBlock::constructLine(unsigned runCount, BidiRun* firstRun,
 void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox, bool firstLine, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
 {
     // First determine our total logical width.
-    int availableLogicalWidth = availableLogicalWidthForLine(logicalHeight(), firstLine);
-    int totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth();
+    float availableLogicalWidth = availableLogicalWidthForLine(logicalHeight(), firstLine);
+    float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth();
     bool needsWordSpacing = false;
     unsigned expansionOpportunityCount = 0;
     bool isAfterExpansion = true;
@@ -386,7 +386,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
     // we now examine our text-align property in order to determine where to position the
     // objects horizontally.  The total width of the line can be increased if we end up
     // justifying text.
-    int logicalLeft = logicalLeftOffsetForLine(logicalHeight(), firstLine);
+    float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), firstLine);
     switch (textAlign) {
         case LEFT:
         case WEBKIT_LEFT:
@@ -394,7 +394,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
             // particular with RTL blocks, wide lines should still spill out to the left.
             if (style()->isLeftToRightDirection()) {
                 if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
-                    trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
+                    trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
             } else {
                 if (trailingSpaceRun)
                     trailingSpaceRun->m_box->setLogicalWidth(0);
@@ -416,7 +416,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
             // for right to left fall through to right aligned
             if (style()->isLeftToRightDirection()) {
                 if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun)
-                    trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
+                    trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
                 break;
             }
         case RIGHT:
@@ -433,7 +433,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
                     logicalLeft += availableLogicalWidth - totalLogicalWidth;
             } else {
                 if (totalLogicalWidth > availableLogicalWidth && trailingSpaceRun) {
-                    trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
+                    trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceRun->m_box->logicalWidth() - totalLogicalWidth + availableLogicalWidth));
                     totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
                 } else
                     logicalLeft += availableLogicalWidth - totalLogicalWidth;
@@ -441,14 +441,14 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
             break;
         case CENTER:
         case WEBKIT_CENTER:
-            int trailingSpaceWidth = 0;
+            float trailingSpaceWidth = 0;
             if (trailingSpaceRun) {
                 totalLogicalWidth -= trailingSpaceRun->m_box->logicalWidth();
                 trailingSpaceWidth = min(trailingSpaceRun->m_box->logicalWidth(), (availableLogicalWidth - totalLogicalWidth + 1) / 2);
-                trailingSpaceRun->m_box->setLogicalWidth(max(0, trailingSpaceWidth));
+                trailingSpaceRun->m_box->setLogicalWidth(max<float>(0, trailingSpaceWidth));
             }
             if (style()->isLeftToRightDirection())
-                logicalLeft += max((availableLogicalWidth - totalLogicalWidth) / 2, 0);
+                logicalLeft += max<float>((availableLogicalWidth - totalLogicalWidth) / 2, 0);
             else
                 logicalLeft += totalLogicalWidth > availableLogicalWidth ? (availableLogicalWidth - totalLogicalWidth) : (availableLogicalWidth - totalLogicalWidth) / 2 - trailingSpaceWidth;
             break;
@@ -468,7 +468,7 @@ void RenderBlock::computeInlineDirectionPositionsForLine(RootInlineBox* lineBox,
                 // Only justify text if whitespace is collapsed.
                 if (r->m_object->style()->collapseWhiteSpace()) {
                     InlineTextBox* textBox = static_cast<InlineTextBox*>(r->m_box);
-                    int expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
+                    float expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
                     textBox->setExpansion(expansion);
                     totalLogicalWidth += expansion;
                 }
@@ -1369,13 +1369,13 @@ static bool shouldSkipWhitespaceAfterStartObject(RenderBlock* block, RenderObjec
     return false;
 }
 
-void RenderBlock::fitBelowFloats(int widthToFit, bool firstLine, int& availableWidth)
+void RenderBlock::fitBelowFloats(float widthToFit, bool firstLine, float& availableWidth)
 {
     ASSERT(widthToFit > availableWidth);
 
     int floatLogicalBottom;
     int lastFloatLogicalBottom = logicalHeight();
-    int newLineWidth = availableWidth;
+    float newLineWidth = availableWidth;
     while (true) {
         floatLogicalBottom = nextFloatLogicalBottomBelow(lastFloatLogicalBottom);
         if (!floatLogicalBottom)
@@ -1393,19 +1393,19 @@ void RenderBlock::fitBelowFloats(int widthToFit, bool firstLine, int& availableW
     }
 }
 
-static inline unsigned textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, int xPos, bool isFixedPitch, bool collapseWhiteSpace)
+static inline float textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, float xPos, bool isFixedPitch, bool collapseWhiteSpace)
 {
     if (isFixedPitch || (!from && len == text->textLength()) || text->style()->hasTextCombine())
         return text->width(from, len, font, xPos);
     return font.width(TextRun(text->characters() + from, len, !collapseWhiteSpace, xPos));
 }
 
-static void tryHyphenating(RenderText* text, const Font& font, const AtomicString& localeIdentifier, int lastSpace, int pos, int xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator& lineBreak, int nextBreakable, bool& hyphenated)
+static void tryHyphenating(RenderText* text, const Font& font, const AtomicString& localeIdentifier, int lastSpace, int pos, float xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator& lineBreak, int nextBreakable, bool& hyphenated)
 {
     const AtomicString& hyphenString = text->style()->hyphenString();
     int hyphenWidth = font.width(TextRun(hyphenString.characters(), hyphenString.length()));
 
-    int maxPrefixWidth = availableWidth - xPos - hyphenWidth - lastSpaceWordSpacing;
+    float maxPrefixWidth = availableWidth - xPos - hyphenWidth - lastSpaceWordSpacing;
     // If the maximum width available for the prefix before the hyphen is small, then it is very unlikely
     // that an hyphenation opportunity exists, so do not bother to look for it.
     if (maxPrefixWidth <= font.pixelSize() * 5 / 4)
@@ -1420,7 +1420,7 @@ static void tryHyphenating(RenderText* text, const Font& font, const AtomicStrin
         return;
 
 #if !ASSERT_DISABLED
-    int prefixWidth = hyphenWidth + textWidth(text, lastSpace, prefixLength, font, xPos, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
+    float prefixWidth = hyphenWidth + textWidth(text, lastSpace, prefixLength, font, xPos, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
     ASSERT(xPos + prefixWidth <= availableWidth);
 #else
     UNUSED_PARAM(isFixedPitch);
@@ -1440,10 +1440,10 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
     bool appliedStartWidth = resolver.position().pos > 0;
     LineMidpointState& lineMidpointState = resolver.midpointState();
     
-    int width = skipLeadingWhitespace(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, lastFloatFromPreviousLine);
+    float width = skipLeadingWhitespace(resolver, firstLine, isLineEmpty, previousLineBrokeCleanly, lastFloatFromPreviousLine);
 
-    int w = 0;
-    int tmpW = 0;
+    float w = 0;
+    float tmpW = 0;
 
     if (resolver.position().atEnd())
         return resolver.position();
@@ -1462,8 +1462,8 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
 
     InlineIterator lBreak = resolver.position();
 
-    RenderObject *o = resolver.position().obj;
-    RenderObject *last = o;
+    RenderObjecto = resolver.position().obj;
+    RenderObjectlast = o;
     unsigned pos = resolver.position().pos;
     int nextBreakable = resolver.position().nextBreakablePosition;
     bool atStart = true;
@@ -1660,22 +1660,22 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
             bool canHyphenate = style->hyphens() == HyphensAuto && WebCore::canHyphenate(style->hyphenationLocale());
 
             int lastSpace = pos;
-            int wordSpacing = o->style()->wordSpacing();
-            int lastSpaceWordSpacing = 0;
+            float wordSpacing = o->style()->wordSpacing();
+            float lastSpaceWordSpacing = 0;
 
             // Non-zero only when kerning is enabled, in which case we measure words with their trailing
             // space, then subtract its width.
-            int wordTrailingSpaceWidth = f.typesettingFeatures() & Kerning ? f.width(TextRun(&space, 1)) + wordSpacing : 0;
+            float wordTrailingSpaceWidth = f.typesettingFeatures() & Kerning ? f.width(TextRun(&space, 1)) + wordSpacing : 0;
 
-            int wrapW = tmpW + inlineLogicalWidth(o, !appliedStartWidth, true);
-            int charWidth = 0;
+            float wrapW = tmpW + inlineLogicalWidth(o, !appliedStartWidth, true);
+            float charWidth = 0;
             bool breakNBSP = autoWrap && o->style()->nbspMode() == SPACE;
             // Auto-wrapping text should wrap in the middle of a word only if it could not wrap before the word,
             // which is only possible if the word is the first thing on the line, that is, if |w| is zero.
             bool breakWords = o->style()->breakWords() && ((autoWrap && !w) || currWS == PRE);
             bool midWordBreak = false;
             bool breakAll = o->style()->wordBreak() == BreakAllWordBreak && autoWrap;
-            int hyphenWidth = 0;
+            float hyphenWidth = 0;
 
             if (t->isWordBreak()) {
                 w += tmpW;
@@ -1744,7 +1744,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
                         }
                     }
 
-                    int additionalTmpW;
+                    float additionalTmpW;
                     if (wordTrailingSpaceWidth && currentCharacterIsSpace)
                         additionalTmpW = textWidth(t, lastSpace, pos + 1 - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) - wordTrailingSpaceWidth + lastSpaceWordSpacing;
                     else
@@ -1894,7 +1894,7 @@ InlineIterator RenderBlock::findNextLineBreak(InlineBidiResolver& resolver, bool
             }
 
             // IMPORTANT: pos is > length here!
-            int additionalTmpW = ignoringSpaces ? 0 : textWidth(t, lastSpace, pos - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
+            float additionalTmpW = ignoringSpaces ? 0 : textWidth(t, lastSpace, pos - lastSpace, f, w + tmpW, isFixedPitch, collapseWhiteSpace) + lastSpaceWordSpacing;
             tmpW += additionalTmpW;
             tmpW += inlineLogicalWidth(o, !appliedStartWidth, true);
 
index 2c3f70d..55a1189 100644 (file)
@@ -1327,7 +1327,7 @@ void RenderBox::positionLineBox(InlineBox* box)
         box->remove();
         box->destroy(renderArena());
     } else if (isReplaced()) {
-        setLocation(box->x(), box->y());
+        setLocation(lroundf(box->x()), lroundf(box->y()));
         m_inlineBoxWrapper = box;
     }
 }
@@ -3346,6 +3346,24 @@ IntSize RenderBox::flipForWritingMode(const IntSize& offset) const
     return style()->isHorizontalWritingMode() ? IntSize(offset.width(), height() - offset.height()) : IntSize(width() - offset.width(), offset.height());
 }
 
+FloatPoint RenderBox::flipForWritingMode(const FloatPoint& position) const
+{
+    if (!style()->isFlippedBlocksWritingMode())
+        return position;
+    return style()->isHorizontalWritingMode() ? FloatPoint(position.x(), height() - position.y()) : FloatPoint(width() - position.x(), position.y());
+}
+
+void RenderBox::flipForWritingMode(FloatRect& rect) const
+{
+    if (!style()->isFlippedBlocksWritingMode())
+        return;
+
+    if (style()->isHorizontalWritingMode())
+        rect.setY(height() - rect.maxY());
+    else
+        rect.setX(width() - rect.maxX());
+}
+
 IntSize RenderBox::locationOffsetIncludingFlipping() const
 {
     if (!parent() || !parent()->isBox())
index 39bc2a4..04eeecc 100644 (file)
@@ -385,6 +385,8 @@ public:
     IntPoint flipForWritingModeIncludingColumns(const IntPoint&) const;
     IntSize flipForWritingMode(const IntSize&) const;
     void flipForWritingMode(IntRect&) const;
+    FloatPoint flipForWritingMode(const FloatPoint&) const;
+    void flipForWritingMode(FloatRect&) const;
     IntSize locationOffsetIncludingFlipping() const;
 
     IntRect logicalVisualOverflowRectForPropagation(RenderStyle*) const;
index 1b20bd8..250ec9b 100644 (file)
@@ -52,7 +52,7 @@ void RenderCombineText::setTextInternal(PassRefPtr<StringImpl> text)
     m_needsFontUpdate = true;
 }
 
-unsigned RenderCombineText::width(unsigned from, unsigned length, const Font& font, int xPosition, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+float RenderCombineText::width(unsigned from, unsigned length, const Font& font, float xPosition, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
 {
     if (!characters())
         return 0;
@@ -63,7 +63,7 @@ unsigned RenderCombineText::width(unsigned from, unsigned length, const Font& fo
     return RenderText::width(from, length, font, xPosition, fallbackFonts, glyphOverflow);
 }
 
-void RenderCombineText::adjustTextOrigin(IntPoint& textOrigin, const IntRect& boxRect) const
+void RenderCombineText::adjustTextOrigin(FloatPoint& textOrigin, const FloatRect& boxRect) const
 {
     if (m_isCombined)
         textOrigin.move(boxRect.height() / 2 - ceilf(m_combinedTextWidth) / 2, style()->font().pixelSize());
@@ -98,7 +98,7 @@ void RenderCombineText::combineText()
     bool shouldUpdateFont = false;
 
     description.setOrientation(Horizontal); // We are going to draw combined text horizontally.
-    m_combinedTextWidth = style()->font().floatWidth(run);
+    m_combinedTextWidth = style()->font().width(run);
     m_isCombined = m_combinedTextWidth <= emWidth;
 
     if (m_isCombined)
@@ -110,7 +110,7 @@ void RenderCombineText::combineText()
             description.setWidthVariant(widthVariants[i]);
             Font compressedFont = Font(description, style()->font().letterSpacing(), style()->font().wordSpacing());
             compressedFont.update(style()->font().fontSelector());
-            float runWidth = compressedFont.floatWidth(run);
+            float runWidth = compressedFont.width(run);
             if (runWidth <= emWidth) {
                 m_combinedTextWidth = runWidth;
                 m_isCombined = true;
index 582cbd6..3484ab7 100644 (file)
@@ -30,13 +30,13 @@ public:
     RenderCombineText(Node*, PassRefPtr<StringImpl>);
 
     void combineText();
-    void adjustTextOrigin(IntPoint& textOrigin, const IntRect& boxRect) const;
+    void adjustTextOrigin(FloatPoint& textOrigin, const FloatRect& boxRect) const;
     void charactersToRender(int start, const UChar*& characters, int& length) const;
     bool isCombined() const { return m_isCombined; }
-    int combinedTextWidth(const Font& font) const { return font.size(); }
+    float combinedTextWidth(const Font& font) const { return font.size(); }
 
 private:
-    virtual unsigned width(unsigned from, unsigned length, const Font&, int xPosition, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
+    virtual float width(unsigned from, unsigned length, const Font&, float xPosition, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
     virtual const char* renderName() const { return "RenderCombineText"; }
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
     virtual void setTextInternal(PassRefPtr<StringImpl>);
index 211ad86..f4a8736 100644 (file)
@@ -493,7 +493,7 @@ PassRefPtr<StringImpl> RenderCounter::originalText() const
     return text.impl();
 }
 
-void RenderCounter::computePreferredLogicalWidths(int lead)
+void RenderCounter::computePreferredLogicalWidths(float lead)
 {
     setTextInternal(originalText());
     RenderText::computePreferredLogicalWidths(lead);
index de0ee1b..35ffc35 100644 (file)
@@ -50,7 +50,7 @@ private:
     virtual bool isCounter() const;
     virtual PassRefPtr<StringImpl> originalText() const;
     
-    virtual void computePreferredLogicalWidths(int leadWidth);
+    virtual void computePreferredLogicalWidths(float leadWidth);
 
     CounterContent m_counter;
     mutable CounterNode* m_counterNode;
index cdd6c55..3561fe0 100644 (file)
@@ -199,8 +199,7 @@ bool RenderEmbeddedObject::getReplacementTextGeometry(int tx, int ty, FloatRect&
     font.update(0);
     
     run = TextRun(m_replacementText.characters(), m_replacementText.length());
-    run.disableRoundingHacks();
-    textWidth = font.floatWidth(run);
+    textWidth = font.width(run);
     
     replacementTextRect.setSize(FloatSize(textWidth + replacementTextRoundedRectLeftRightTextMargin * 2, replacementTextRoundedRectHeight));
     float x = (contentRect.size().width() / 2 - replacementTextRect.size().width() / 2) + contentRect.location().x();
index f72edad..b50b2ad 100644 (file)
@@ -273,7 +273,7 @@ void RenderFileUploadControl::computePreferredLogicalWidths()
         // Figure out how big the filename space needs to be for a given number of characters
         // (using "0" as the nominal character).
         const UChar ch = '0';
-        float charWidth = style()->font().floatWidth(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false, false, false));
+        float charWidth = style()->font().width(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false));
         m_maxPreferredLogicalWidth = (int)ceilf(charWidth * defaultWidthNumChars);
     }
 
index 7e428c1..4c14845 100644 (file)
@@ -81,7 +81,7 @@ static const unsigned short paddingHeight = 4;
 
 // Alt text is restricted to this maximum size, in pixels.  These are
 // signed integers because they are compared with other signed values.
-static const int maxAltTextWidth = 1024;
+static const float maxAltTextWidth = 1024;
 static const int maxAltTextHeight = 256;
 
 IntSize RenderImage::imageSizeForError(CachedImage* newImage) const
index 3768774..b89c57f 100644 (file)
@@ -559,8 +559,8 @@ IntRect RenderInline::linesBoundingBox() const
     ASSERT(!firstLineBox() == !lastLineBox());  // Either both are null or both exist.
     if (firstLineBox() && lastLineBox()) {
         // Return the width of the minimal left side and the maximal right side.
-        int logicalLeftSide = 0;
-        int logicalRightSide = 0;
+        float logicalLeftSide = 0;
+        float logicalRightSide = 0;
         for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
             if (curr == firstLineBox() || curr->logicalLeft() < logicalLeftSide)
                 logicalLeftSide = curr->logicalLeft();
@@ -570,11 +570,11 @@ IntRect RenderInline::linesBoundingBox() const
         
         bool isHorizontal = style()->isHorizontalWritingMode();
         
-        int x = isHorizontal ? logicalLeftSide : firstLineBox()->x();
-        int y = isHorizontal ? firstLineBox()->y() : logicalLeftSide;
-        int width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->logicalBottom() - x;
-        int height = isHorizontal ? lastLineBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide;
-        result = IntRect(x, y, width, height);
+        float x = isHorizontal ? logicalLeftSide : firstLineBox()->x();
+        float y = isHorizontal ? firstLineBox()->y() : logicalLeftSide;
+        float width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->logicalBottom() - x;
+        float height = isHorizontal ? lastLineBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide;
+        result = enclosingIntRect(FloatRect(x, y, width, height));
     }
 
     return result;
@@ -586,20 +586,20 @@ IntRect RenderInline::linesVisualOverflowBoundingBox() const
         return IntRect();
 
     // Return the width of the minimal left side and the maximal right side.
-    int logicalLeftSide = numeric_limits<int>::max();
-    int logicalRightSide = numeric_limits<int>::min();
+    float logicalLeftSide = numeric_limits<int>::max();
+    float logicalRightSide = numeric_limits<int>::min();
     for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
-        logicalLeftSide = min(logicalLeftSide, curr->logicalLeftVisualOverflow());
-        logicalRightSide = max(logicalRightSide, curr->logicalRightVisualOverflow());
+        logicalLeftSide = min(logicalLeftSide, static_cast<float>(curr->logicalLeftVisualOverflow()));
+        logicalRightSide = max(logicalRightSide, static_cast<float>(curr->logicalRightVisualOverflow()));
     }
 
     bool isHorizontal = style()->isHorizontalWritingMode();
         
-    int x = isHorizontal ? logicalLeftSide : firstLineBox()->minXVisualOverflow();
-    int y = isHorizontal ? firstLineBox()->minYVisualOverflow() : logicalLeftSide;
-    int width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->maxXVisualOverflow() - firstLineBox()->minXVisualOverflow();
-    int height = isHorizontal ? lastLineBox()->maxYVisualOverflow() - firstLineBox()->minYVisualOverflow() : logicalRightSide - logicalLeftSide;
-    return IntRect(x, y, width, height);
+    float x = isHorizontal ? logicalLeftSide : firstLineBox()->minXVisualOverflow();
+    float y = isHorizontal ? firstLineBox()->minYVisualOverflow() : logicalLeftSide;
+    float width = isHorizontal ? logicalRightSide - logicalLeftSide : lastLineBox()->maxXVisualOverflow() - firstLineBox()->minXVisualOverflow();
+    float height = isHorizontal ? lastLineBox()->maxYVisualOverflow() - firstLineBox()->minYVisualOverflow() : logicalRightSide - logicalLeftSide;
+    return enclosingIntRect(FloatRect(x, y, width, height));
 }
 
 IntRect RenderInline::clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer)
@@ -963,8 +963,8 @@ void RenderInline::addFocusRingRects(Vector<IntRect>& rects, int tx, int ty)
 {
     for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
         RootInlineBox* root = curr->root();
-        int top = max(root->lineTop(), curr->y());
-        int bottom = min(root->lineBottom(), curr->y() + curr->logicalHeight());
+        int top = max(root->lineTop(), curr->logicalTop());
+        int bottom = min(root->lineBottom(), curr->logicalBottom());
         IntRect rect(tx + curr->x(), ty + top, curr->logicalWidth(), bottom - top);
         if (!rect.isEmpty())
             rects.append(rect);
@@ -1015,8 +1015,8 @@ void RenderInline::paintOutline(GraphicsContext* graphicsContext, int tx, int ty
     rects.append(IntRect());
     for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
         RootInlineBox* root = curr->root();
-        int top = max(root->lineTop(), curr->y());
-        int bottom = min(root->lineBottom(), curr->y() + curr->logicalHeight());
+        int top = max(root->lineTop(), curr->logicalTop());
+        int bottom = min(root->lineBottom(), curr->logicalBottom());
         rects.append(IntRect(curr->x(), top, curr->logicalWidth(), bottom - top));
     }
     rects.append(IntRect());
index b7796a0..5e6bd90 100644 (file)
@@ -111,7 +111,7 @@ void RenderListBox::updateFromElement()
             }
                 
             if (!text.isEmpty()) {
-                float textWidth = itemFont.floatWidth(TextRun(text.impl(), false, 0, 0, TextRun::AllowTrailingExpansion, false, false, false, false));
+                float textWidth = itemFont.width(TextRun(text.impl(), false, 0, 0, TextRun::AllowTrailingExpansion, false, false));
                 width = max(width, textWidth);
             }
         }
@@ -333,7 +333,7 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, int tx, int ty, in
 
     unsigned length = itemText.length();
     const UChar* string = itemText.characters();
-    TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, !itemStyle->isLeftToRightDirection(), itemStyle->unicodeBidi() == Override, false, false);
+    TextRun textRun(string, length, false, 0, 0, TextRun::AllowTrailingExpansion, !itemStyle->isLeftToRightDirection(), itemStyle->unicodeBidi() == Override);
 
     // Draw the item text
     if (itemStyle->visibility() != HIDDEN)
index 3e9d198..8c11959 100644 (file)
@@ -153,10 +153,10 @@ void RenderMenuList::updateOptionsWidth()
             if (RenderStyle* optionStyle = element->renderStyle())
                 optionWidth += optionStyle->textIndent().calcMinValue(0);
             if (!text.isEmpty())
-                optionWidth += style()->font().floatWidth(text);
+                optionWidth += style()->font().width(text);
             maxOptionWidth = max(maxOptionWidth, optionWidth);
         } else if (!text.isEmpty())
-            maxOptionWidth = max(maxOptionWidth, style()->font().floatWidth(text));
+            maxOptionWidth = max(maxOptionWidth, style()->font().width(text));
     }
 
     int width = static_cast<int>(ceilf(maxOptionWidth));
index 4540cc8..428eb90 100644 (file)
@@ -506,15 +506,19 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e
     int height = box->root()->selectionHeight();
     int top = box->root()->selectionTop();
 
-    int left = box->positionForOffset(caretOffset);
+    // Go ahead and round left to snap it to the nearest pixel.
+    float left = box->positionForOffset(caretOffset);
 
     // Distribute the caret's width to either side of the offset.
     int caretWidthLeftOfOffset = caretWidth / 2;
     left -= caretWidthLeftOfOffset;
     int caretWidthRightOfOffset = caretWidth - caretWidthLeftOfOffset;
 
-    int rootLeft = box->root()->logicalLeft();
-    int rootRight = rootLeft + box->root()->logicalWidth();
+    left = roundf(left);
+
+    float rootLeft = box->root()->logicalLeft();
+    float rootRight = box->root()->logicalRight();
+
     // FIXME: should we use the width of the root inline box or the
     // width of the containing block for this?
     if (extraWidthToEndOfLine)
@@ -522,14 +526,14 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e
 
     RenderBlock* cb = containingBlock();
     RenderStyle* cbStyle = cb->style();
-    int leftEdge;
-    int rightEdge;
+    float leftEdge;
+    float rightEdge;
     if (style()->autoWrap()) {
         leftEdge = cb->logicalLeft();
         rightEdge = cb->logicalRight();
     } else {
-        leftEdge = min(cb->logicalLeft(), rootLeft);
-        rightEdge = max(cb->logicalRight(), rootRight);
+        leftEdge = min(static_cast<float>(cb->logicalLeft()), rootLeft);
+        rightEdge = max(static_cast<float>(cb->logicalRight()), rootRight);
     }
 
     bool rightAligned = false;
@@ -560,7 +564,7 @@ IntRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, int* e
     return style()->isHorizontalWritingMode() ? IntRect(left, top, caretWidth, height) : IntRect(top, left, height, caretWidth);
 }
 
-ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len, int xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
 {
     if (style()->hasTextCombine()) {
         const RenderCombineText* combineText = toRenderCombineText(this);
@@ -569,9 +573,9 @@ ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len,
     }
 
     if (f.isFixedPitch() && !f.isSmallCaps() && m_isAllASCII) {
-        int monospaceCharacterWidth = f.spaceWidth();
-        int tabWidth = allowTabs() ? monospaceCharacterWidth * 8 : 0;
-        int w = 0;
+        float monospaceCharacterWidth = f.spaceWidth();
+        float tabWidth = allowTabs() ? monospaceCharacterWidth * 8 : 0;
+        float w = 0;
         bool isSpace;
         bool previousCharWasSpace = true; // FIXME: Preserves historical behavior, but seems wrong for start > 0.
         ASSERT(m_text);
@@ -583,7 +587,7 @@ ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len,
                     w += monospaceCharacterWidth;
                     isSpace = true;
                 } else if (c == '\t') {
-                    w += tabWidth ? tabWidth - ((xPos + w) % tabWidth) : monospaceCharacterWidth;
+                    w += tabWidth ? tabWidth - fmodf(xPos + w, tabWidth) : monospaceCharacterWidth;
                     isSpace = true;
                 } else
                     isSpace = false;
@@ -601,12 +605,12 @@ ALWAYS_INLINE int RenderText::widthFromCache(const Font& f, int start, int len,
     return f.width(TextRun(text()->characters() + start, len, allowTabs(), xPos), fallbackFonts, glyphOverflow);
 }
 
-void RenderText::trimmedPrefWidths(int leadWidth,
-                                   int& beginMinW, bool& beginWS,
-                                   int& endMinW, bool& endWS,
+void RenderText::trimmedPrefWidths(float leadWidth,
+                                   float& beginMinW, bool& beginWS,
+                                   float& endMinW, bool& endWS,
                                    bool& hasBreakableChar, bool& hasBreak,
-                                   int& beginMaxW, int& endMaxW,
-                                   int& minW, int& maxW, bool& stripFrontSpaces)
+                                   float& beginMaxW, float& endMaxW,
+                                   float& minW, float& maxW, bool& stripFrontSpaces)
 {
     bool collapseWhiteSpace = style()->collapseWhiteSpace();
     if (!collapseWhiteSpace)
@@ -646,7 +650,7 @@ void RenderText::trimmedPrefWidths(int leadWidth,
         const Font& f = style()->font(); // FIXME: This ignores first-line.
         if (stripFrontSpaces) {
             const UChar space = ' ';
-            int spaceWidth = f.width(TextRun(&space, 1));
+            float spaceWidth = f.width(TextRun(&space, 1));
             maxW -= spaceWidth;
         } else
             maxW += f.wordSpacing();
@@ -695,7 +699,7 @@ static inline bool isSpaceAccordingToStyle(UChar c, RenderStyle* style)
     return c == ' ' || (c == noBreakSpace && style->nbspMode() == SPACE);
 }
 
-int RenderText::minPreferredLogicalWidth() const
+float RenderText::minLogicalWidth() const
 {
     if (preferredLogicalWidthsDirty())
         const_cast<RenderText*>(this)->computePreferredLogicalWidths(0);
@@ -703,7 +707,7 @@ int RenderText::minPreferredLogicalWidth() const
     return m_minWidth;
 }
 
-int RenderText::maxPreferredLogicalWidth() const
+float RenderText::maxLogicalWidth() const
 {
     if (preferredLogicalWidthsDirty())
         const_cast<RenderText*>(this)->computePreferredLogicalWidths(0);
@@ -711,7 +715,7 @@ int RenderText::maxPreferredLogicalWidth() const
     return m_maxWidth;
 }
 
-void RenderText::computePreferredLogicalWidths(int leadWidth)
+void RenderText::computePreferredLogicalWidths(float leadWidth)
 {
     HashSet<const SimpleFontData*> fallbackFonts;
     GlyphOverflow glyphOverflow;
@@ -720,7 +724,7 @@ void RenderText::computePreferredLogicalWidths(int leadWidth)
         m_knownToHaveNoOverflowAndNoFallbackFonts = true;
 }
 
-void RenderText::computePreferredLogicalWidths(int leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow& glyphOverflow)
+void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow& glyphOverflow)
 {
     ASSERT(m_hasTab || preferredLogicalWidthsDirty() || !m_knownToHaveNoOverflowAndNoFallbackFonts);
 
@@ -732,8 +736,8 @@ void RenderText::computePreferredLogicalWidths(int leadWidth, HashSet<const Simp
     if (isBR())
         return;
 
-    int currMinWidth = 0;
-    int currMaxWidth = 0;
+    float currMinWidth = 0;
+    float currMaxWidth = 0;
     m_hasBreakableChar = false;
     m_hasBreak = false;
     m_hasTab = false;
@@ -741,7 +745,7 @@ void RenderText::computePreferredLogicalWidths(int leadWidth, HashSet<const Simp
     m_hasEndWS = false;
 
     const Font& f = style()->font(); // FIXME: This ignores first-line.
-    int wordSpacing = style()->wordSpacing();
+    float wordSpacing = style()->wordSpacing();
     int len = textLength();
     const UChar* txt = characters();
     bool needsWordSpacing = false;
@@ -821,7 +825,7 @@ void RenderText::computePreferredLogicalWidths(int leadWidth, HashSet<const Simp
 
         int wordLen = j - i;
         if (wordLen) {
-            int w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
+            float w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
             if (firstGlyphLeftOverflow < 0)
                 firstGlyphLeftOverflow = glyphOverflow.left;
             currMinWidth += w;
@@ -933,17 +937,17 @@ bool RenderText::containsOnlyWhitespace(unsigned from, unsigned len) const
     return currPos >= (from + len);
 }
 
-IntPoint RenderText::firstRunOrigin() const
+FloatPoint RenderText::firstRunOrigin() const
 {
     return IntPoint(firstRunX(), firstRunY());
 }
 
-int RenderText::firstRunX() const
+float RenderText::firstRunX() const
 {
     return m_firstTextBox ? m_firstTextBox->m_x : 0;
 }
 
-int RenderText::firstRunY() const
+float RenderText::firstRunY() const
 {
     return m_firstTextBox ? m_firstTextBox->m_y : 0;
 }
@@ -1223,7 +1227,7 @@ void RenderText::positionLineBox(InlineBox* box)
     m_containsReversedText |= !s->isLeftToRightDirection();
 }
 
-unsigned RenderText::width(unsigned from, unsigned len, int xPos, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+float RenderText::width(unsigned from, unsigned len, float xPos, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
 {
     if (from >= textLength())
         return 0;
@@ -1234,13 +1238,13 @@ unsigned RenderText::width(unsigned from, unsigned len, int xPos, bool firstLine
     return width(from, len, style(firstLine)->font(), xPos, fallbackFonts, glyphOverflow);
 }
 
-unsigned RenderText::width(unsigned from, unsigned len, const Font& f, int xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+float RenderText::width(unsigned from, unsigned len, const Font& f, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
 {
     ASSERT(from + len <= textLength());
     if (!characters())
         return 0;
 
-    int w;
+    float w;
     if (&f == &style()->font()) {
         if (!style()->preserveNewline() && !from && len == textLength()) {
             if (fallbackFonts) {
@@ -1252,7 +1256,7 @@ unsigned RenderText::width(unsigned from, unsigned len, const Font& f, int xPos,
                 }
                 w = m_maxWidth;
             } else
-                w = maxPreferredLogicalWidth();
+                w = maxLogicalWidth();
         } else
             w = widthFromCache(f, from, len, xPos, fallbackFonts, glyphOverflow);
     } else
@@ -1268,8 +1272,8 @@ IntRect RenderText::linesBoundingBox() const
     ASSERT(!firstTextBox() == !lastTextBox());  // Either both are null or both exist.
     if (firstTextBox() && lastTextBox()) {
         // Return the width of the minimal left side and the maximal right side.
-        int logicalLeftSide = 0;
-        int logicalRightSide = 0;
+        float logicalLeftSide = 0;
+        float logicalRightSide = 0;
         for (InlineTextBox* curr = firstTextBox(); curr; curr = curr->nextTextBox()) {
             if (curr == firstTextBox() || curr->logicalLeft() < logicalLeftSide)
                 logicalLeftSide = curr->logicalLeft();
@@ -1279,11 +1283,11 @@ IntRect RenderText::linesBoundingBox() const
         
         bool isHorizontal = style()->isHorizontalWritingMode();
         
-        int x = isHorizontal ? logicalLeftSide : firstTextBox()->x();
-        int y = isHorizontal ? firstTextBox()->y() : logicalLeftSide;
-        int width = isHorizontal ? logicalRightSide - logicalLeftSide : lastTextBox()->logicalBottom() - x;
-        int height = isHorizontal ? lastTextBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide;
-        result = IntRect(x, y, width, height);
+        float x = isHorizontal ? logicalLeftSide : firstTextBox()->x();
+        float y = isHorizontal ? firstTextBox()->y() : logicalLeftSide;
+        float width = isHorizontal ? logicalRightSide - logicalLeftSide : lastTextBox()->logicalBottom() - x;
+        float height = isHorizontal ? lastTextBox()->logicalBottom() - y : logicalRightSide - logicalLeftSide;
+        result = enclosingIntRect(FloatRect(x, y, width, height));
     }
 
     return result;
index 964a1d3..b88590c 100644 (file)
@@ -71,24 +71,24 @@ public:
     unsigned textLength() const { return m_text.length(); } // non virtual implementation of length()
     void positionLineBox(InlineBox*);
 
-    virtual unsigned width(unsigned from, unsigned len, const Font&, int xPos, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
-    virtual unsigned width(unsigned from, unsigned len, int xPos, bool firstLine = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
+    virtual float width(unsigned from, unsigned len, const Font&, float xPos, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
+    virtual float width(unsigned from, unsigned len, float xPos, bool firstLine = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
 
-    virtual int minPreferredLogicalWidth() const;
-    virtual int maxPreferredLogicalWidth() const;
+    float minLogicalWidth() const;
+    float maxLogicalWidth() const;
 
-    void trimmedPrefWidths(int leadWidth,
-                           int& beginMinW, bool& beginWS,
-                           int& endMinW, bool& endWS,
+    void trimmedPrefWidths(float leadWidth,
+                           float& beginMinW, bool& beginWS,
+                           float& endMinW, bool& endWS,
                            bool& hasBreakableChar, bool& hasBreak,
-                           int& beginMaxW, int& endMaxW,
-                           int& minW, int& maxW, bool& stripFrontSpaces);
+                           float& beginMaxW, float& endMaxW,
+                           float& minW, float& maxW, bool& stripFrontSpaces);
 
     virtual IntRect linesBoundingBox() const;
 
-    IntPoint firstRunOrigin() const;
-    int firstRunX() const;
-    int firstRunY() const;
+    FloatPoint firstRunOrigin() const;
+    float firstRunX() const;
+    float firstRunY() const;
 
     void setText(PassRefPtr<StringImpl>, bool force = false);
     void setTextWithOffset(PassRefPtr<StringImpl>, unsigned offset, unsigned len, bool force = false);
@@ -122,7 +122,7 @@ public:
 
     void checkConsistency() const;
 
-    virtual void computePreferredLogicalWidths(int leadWidth);
+    virtual void computePreferredLogicalWidths(float leadWidth);
     bool isAllCollapsibleWhitespace();
     
 protected:
@@ -135,7 +135,7 @@ protected:
     virtual InlineTextBox* createTextBox(); // Subclassed by SVG.
 
 private:
-    void computePreferredLogicalWidths(int leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow&);
+    void computePreferredLogicalWidths(float leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow&);
 
     // Make length() private so that callers that have a RenderText*
     // will use the more efficient textLength() instead, while
@@ -148,22 +148,22 @@ private:
 
     void deleteTextBoxes();
     bool containsOnlyWhitespace(unsigned from, unsigned len) const;
-    int widthFromCache(const Font&, int start, int len, int xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow*) const;
+    float widthFromCache(const Font&, int start, int len, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow*) const;
     bool isAllASCII() const { return m_isAllASCII; }
     void updateNeedsTranscoding();
 
     inline void transformText(String&) const;
 
-    int m_minWidth; // here to minimize padding in 64-bit.
+    float m_minWidth; // here to minimize padding in 64-bit.
 
     String m_text;
 
     InlineTextBox* m_firstTextBox;
     InlineTextBox* m_lastTextBox;
 
-    int m_maxWidth;
-    int m_beginMinWidth;
-    int m_endMinWidth;
+    float m_maxWidth;
+    float m_beginMinWidth;
+    float m_endMinWidth;
 
     bool m_hasBreakableChar : 1; // Whether or not we can be broken into multiple lines.
     bool m_hasBreak : 1; // Whether or not we have a hard break (e.g., <pre> with '\n').
index 72b20ec..c191c29 100644 (file)
@@ -544,7 +544,7 @@ float RenderTextControl::getAvgCharWidth(AtomicString family)
         return roundf(style()->font().primaryFont()->avgCharWidth());
 
     const UChar ch = '0'; 
-    return style()->font().floatWidth(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false, false, false));
+    return style()->font().width(TextRun(&ch, 1, false, 0, 0, TextRun::AllowTrailingExpansion, false));
 }
 
 float RenderTextControl::scaleEmToUnits(int x) const
@@ -639,7 +639,7 @@ void RenderTextControl::paintPlaceholder(PaintInfo& paintInfo, int tx, int ty)
     paintInfo.context->setFillColor(placeholderStyle->visitedDependentColor(CSSPropertyColor), placeholderStyle->colorSpace());
     
     String placeholderText = static_cast<HTMLTextFormControlElement*>(node())->strippedPlaceholder();
-    TextRun textRun(placeholderText.characters(), placeholderText.length(), false, 0, 0, TextRun::AllowTrailingExpansion, !placeholderStyle->isLeftToRightDirection(), placeholderStyle->unicodeBidi() == Override, false, false);
+    TextRun textRun(placeholderText.characters(), placeholderText.length(), false, 0, 0, TextRun::AllowTrailingExpansion, !placeholderStyle->isLeftToRightDirection(), placeholderStyle->unicodeBidi() == Override);
     
     RenderBox* textRenderer = innerTextElement() ? innerTextElement()->renderBox() : 0;
     if (textRenderer) {
index 6d855a0..b54261f 100644 (file)
@@ -470,11 +470,17 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
 
 static void writeTextRun(TextStream& ts, const RenderText& o, const InlineTextBox& run)
 {
-    // FIXME: Table cell adjustment is temporary until results can be updated.
+    // FIXME: For now use an "enclosingIntRect" model for x, y and logicalWidth, although this makes it harder
+    // to detect any changes caused by the conversion to floating point. :(
+    int x = run.m_x;
     int y = run.m_y;
+    int logicalWidth = ceilf(run.m_x + run.m_logicalWidth) - x;
+
+    // FIXME: Table cell adjustment is temporary until results can be updated.
     if (o.containingBlock()->isTableCell())
         y -= toRenderTableCell(o.containingBlock())->intrinsicPaddingBefore();
-    ts << "text run at (" << run.m_x << "," << y << ") width " << run.m_logicalWidth;
+        
+    ts << "text run at (" << x << "," << y << ") width " << logicalWidth;
     if (!run.isLeftToRightDirection() || run.m_dirOverride) {
         ts << (!run.isLeftToRightDirection() ? " RTL" : " LTR");
         if (run.m_dirOverride)
index aa87683..43fc0ff 100644 (file)
@@ -97,7 +97,7 @@ bool RootInlineBox::canAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxE
     return InlineFlowBox::canAccommodateEllipsis(ltr, blockEdge, ellipsisWidth);
 }
 
-void RootInlineBox::placeEllipsis(const AtomicString& ellipsisStr,  bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth,
+void RootInlineBox::placeEllipsis(const AtomicString& ellipsisStr,  bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth,
                                   InlineBox* markupBox)
 {
     // Create an ellipsis box.
@@ -123,9 +123,9 @@ void RootInlineBox::placeEllipsis(const AtomicString& ellipsisStr,  bool ltr, in
     ellipsisBox->m_x = placeEllipsisBox(ltr, blockLeftEdge, blockRightEdge, ellipsisWidth, foundBox);
 }
 
-int RootInlineBox::placeEllipsisBox(bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth, bool& foundBox)
+float RootInlineBox::placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, bool& foundBox)
 {
-    int result = InlineFlowBox::placeEllipsisBox(ltr, blockLeftEdge, blockRightEdge, ellipsisWidth, foundBox);
+    float result = InlineFlowBox::placeEllipsisBox(ltr, blockLeftEdge, blockRightEdge, ellipsisWidth, foundBox);
     if (result == -1)
         result = ltr ? blockRightEdge - ellipsisWidth : blockLeftEdge;
     return result;
@@ -198,10 +198,10 @@ bool RootInlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
     return InlineFlowBox::nodeAtPoint(request, result, x, y, tx, ty);
 }
 
-void RootInlineBox::adjustPosition(int dx, int dy)
+void RootInlineBox::adjustPosition(float dx, float dy)
 {
     InlineFlowBox::adjustPosition(dx, dy);
-    int blockDirectionDelta = isHorizontal() ? dy : dx;
+    int blockDirectionDelta = isHorizontal() ? dy : dx; // The block direction delta will always be integral.
     m_lineTop += blockDirectionDelta;
     m_lineBottom += blockDirectionDelta;
     m_blockLogicalHeight += blockDirectionDelta;
@@ -289,7 +289,7 @@ int RootInlineBox::beforeAnnotationsAdjustment() const
 
         // Annotations over this line may push us further down.
         int highestAllowedPosition = prevRootBox() ? min(prevRootBox()->lineBottom(), lineTop()) + result : block()->borderBefore();
-        result =  computeOverAnnotationAdjustment(highestAllowedPosition);
+        result = computeOverAnnotationAdjustment(highestAllowedPosition);
     } else {
         // Annotations under this line may push us up.
         if (hasAnnotationsBefore())
@@ -544,14 +544,14 @@ IntRect RootInlineBox::paddedLayoutOverflowRect(int endPadding) const
     
     if (isHorizontal()) {
         if (isLeftToRightDirection())
-            lineLayoutOverflow.shiftMaxXEdgeTo(max(lineLayoutOverflow.maxX(), logicalRight() + endPadding));
+            lineLayoutOverflow.shiftMaxXEdgeTo(max(lineLayoutOverflow.maxX(), pixelSnappedLogicalRight() + endPadding));
         else
-            lineLayoutOverflow.shiftXEdgeTo(min(lineLayoutOverflow.x(), logicalLeft() - endPadding));
+            lineLayoutOverflow.shiftXEdgeTo(min(lineLayoutOverflow.x(), pixelSnappedLogicalLeft() - endPadding));
     } else {
         if (isLeftToRightDirection())
-            lineLayoutOverflow.shiftMaxYEdgeTo(max(lineLayoutOverflow.maxY(), logicalRight() + endPadding));
+            lineLayoutOverflow.shiftMaxYEdgeTo(max(lineLayoutOverflow.maxY(), pixelSnappedLogicalRight() + endPadding));
         else
-            lineLayoutOverflow.shiftYEdgeTo(min(lineLayoutOverflow.y(), logicalRight() - endPadding));
+            lineLayoutOverflow.shiftYEdgeTo(min(lineLayoutOverflow.y(), pixelSnappedLogicalLeft() - endPadding));
     }
     
     return lineLayoutOverflow;
index 7c4b15c..55f55a2 100644 (file)
@@ -45,7 +45,7 @@ public:
     RootInlineBox* nextRootBox() const { return static_cast<RootInlineBox*>(m_nextLineBox); }
     RootInlineBox* prevRootBox() const { return static_cast<RootInlineBox*>(m_prevLineBox); }
 
-    virtual void adjustPosition(int dx, int dy);
+    virtual void adjustPosition(float dx, float dy);
 
     int lineTop() const { return m_lineTop; }
     int lineBottom() const { return m_lineBottom; }
@@ -78,8 +78,8 @@ public:
     void childRemoved(InlineBox* box);
 
     bool canAccommodateEllipsis(bool ltr, int blockEdge, int lineBoxEdge, int ellipsisWidth);
-    void placeEllipsis(const AtomicString& ellipsisStr, bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth, InlineBox* markupBox = 0);
-    virtual int placeEllipsisBox(bool ltr, int blockLeftEdge, int blockRightEdge, int ellipsisWidth, bool& foundBox);
+    void placeEllipsis(const AtomicString& ellipsisStr, bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, InlineBox* markupBox = 0);
+    virtual float placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, bool& foundBox);
 
     EllipsisBox* ellipsisBox() const;
 
index b25b2f6..bb39877 100644 (file)
@@ -34,8 +34,6 @@ namespace WebCore {
 class RenderObject;
 
 // Values for vertical alignment.
-const int PositionTop = -0x7fffffff;
-const int PositionBottom = 0x7fffffff;
 const int PositionUndefined = 0x80000000;
 
 class VerticalPositionCache {
index 42c7fd6..05e1357 100644 (file)
@@ -47,7 +47,7 @@ SVGInlineTextBox::SVGInlineTextBox(RenderObject* object)
 {
 }
 
-int SVGInlineTextBox::offsetForPosition(int, bool) const
+int SVGInlineTextBox::offsetForPosition(float, bool) const
 {
     // SVG doesn't use the standard offset <-> position selection system, as it's not suitable for SVGs complex needs.
     // vertical text selection, inline boxes spanning multiple lines (contrary to HTML, etc.)
@@ -76,7 +76,7 @@ int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragmen
     return fragment.positionListOffset - start() + textRenderer->scaledFont().offsetForPosition(textRun, position * scalingFactor, includePartialGlyphs);
 }
 
-int SVGInlineTextBox::positionForOffset(int) const
+float SVGInlineTextBox::positionForOffset(int) const
 {
     // SVG doesn't use the offset <-> position selection system. 
     ASSERT_NOT_REACHED();
@@ -415,9 +415,6 @@ TextRun SVGInlineTextBox::constructTextRun(RenderStyle* style, const SVGTextFrag
     run.setReferencingRenderObject(text);
 #endif
 
-    // Disable any word/character rounding.
-    run.disableRoundingHacks();
-
     // We handle letter & word spacing ourselves.
     run.disableSpacing();
     return run;
index f2ca303..79c836f 100644 (file)
@@ -42,8 +42,8 @@ public:
 
     virtual int selectionTop() { return m_y; }
     virtual int selectionHeight() { return m_logicalHeight; }
-    virtual int offsetForPosition(int x, bool includePartialGlyphs = true) const;
-    virtual int positionForOffset(int offset) const;
+    virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const;
+    virtual float positionForOffset(int offset) const;
 
     void paintSelectionBackground(PaintInfo&);
     virtual void paint(PaintInfo&, int tx, int ty);
index 0922c2d..0f94fdd 100644 (file)
@@ -435,7 +435,10 @@ static void writeRenderSVGTextBox(TextStream& ts, const RenderBlock& text)
     if (!box)
         return;
 
-    ts << " at (" << text.x() << "," << text.y() << ") size " << box->logicalWidth() << "x" << box->logicalHeight();
+    // FIXME: For now use an int for logicalWidth, although this makes it harder
+    // to detect any changes caused by the conversion to floating point. :(
+    int logicalWidth = ceilf(box->x() + box->logicalWidth()) - box->x();
+    ts << " at (" << text.x() << "," << text.y() << ") size " << logicalWidth << "x" << box->logicalHeight();
     
     // FIXME: Remove this hack, once the new text layout engine is completly landed. We want to preserve the old layout test results for now.
     ts << " contains 1 chunk(s)";
index ca20d3d..d75bdb3 100644 (file)
@@ -47,8 +47,9 @@ SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* textRenderer, const TextRun&
     int length = 0;
 
     // Calculate width/height using the scaled font, divide this result by the scalingFactor afterwards.
-    m_width = scaledFont.floatWidth(run, extraCharsAvailable, length, m_glyph.name) / scalingFactor;
+    m_width = scaledFont.width(run, extraCharsAvailable, length, m_glyph.name) / scalingFactor;
     m_height = scaledFont.fontMetrics().floatHeight() / scalingFactor;
+
     m_glyph.unicodeString = String(run.characters(), length);
     m_glyph.isValid = true;
 
@@ -79,9 +80,6 @@ static TextRun constructTextRun(RenderSVGInlineText* text, const UChar* characte
     run.setReferencingRenderObject(text);
 #endif
 
-    // Disable any word/character rounding.
-    run.disableRoundingHacks();
-
     // We handle letter & word spacing ourselves.
     run.disableSpacing();
     return run;
index a92b9b6..e02fced 100644 (file)
@@ -362,7 +362,7 @@ static void floatWidthMissingGlyphCallback(const TextRun& run, SVGTextRunWalkerM
     Font font(fontDescription, 0, 0); // spacing handled by SVG text code.
     font.update(data.font->fontSelector());
 
-    data.length += font.floatWidth(run);
+    data.length += font.width(run);
 }
 
 
@@ -573,9 +573,9 @@ void Font::drawTextUsingSVGFont(GraphicsContext* context, const TextRun& run,
                 font.drawText(context, fallbackCharacterRun, currentPoint);
 
                 if (isVerticalText)
-                    currentPoint.move(0.0f, font.floatWidth(fallbackCharacterRun));
+                    currentPoint.move(0.0f, font.width(fallbackCharacterRun));
                 else
-                    currentPoint.move(font.floatWidth(fallbackCharacterRun), 0.0f);
+                    currentPoint.move(font.width(fallbackCharacterRun), 0.0f);
 
                 fallbackCharacterIndex++;
             }
index f00210e..ebd19c6 100644 (file)
@@ -1,3 +1,31 @@
+2011-02-16  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        https://bugs.webkit.org/show_bug.cgi?id=54244
+        
+        Convert the line box tree to floating point and eliminate font rounding hacks.  This patch removes all of the rounding
+        hacks from the Font code and makes sure all Font APIs involving width measurement and width offsets use floats.
+        
+        The line box tree's x, y and logicalWidth members have all been converted to floats and all of the line box APIs have
+        been changed as well.
+        
+        In terms of pixel adjustments, overflow is using an enclosing model (so it will be enclosingIntRect of a line box's x/y/width/height).
+        
+        Background and border painting is using a rounding model, so borders and backgrounds will round to the nearest pixel when painting.
+        
+        Replaced elements still snap to integer positions on lines, and they use a rounding model as well, although their underlying line boxes
+        still have a precise floating point position.
+
+        Justification will now allow subpixel positioning to occur as well.  Platforms that don't support subpixel positioning should already
+        be rounding justification spacing in their font code.
+
+        Many layout test results change on Mac, since rounding hacks were used there and are now gone.
+
+        * Misc/WebKitNSStringExtras.mm:
+        (-[NSString _web_drawAtPoint:font:textColor:allowingFontSmoothing:]):
+        (-[NSString _web_widthWithFont:]):
+
 2011-02-10  Luiz Agostini  <luiz.agostini@openbossa.org>
 
         Reviewed by Adam Roben.
index a997e30..124a472 100644 (file)
@@ -91,7 +91,6 @@ static BOOL canUseFastRenderer(const UniChar *buffer, unsigned length)
 
         Font webCoreFont(FontPlatformData(font, [font pointSize]), ![nsContext isDrawingToScreen], fontSmoothingIsAllowed ? AutoSmoothing : Antialiased);
         TextRun run(buffer.data(), length);
-        run.disableRoundingHacks();
 
         CGFloat red;
         CGFloat green;
@@ -137,8 +136,7 @@ static BOOL canUseFastRenderer(const UniChar *buffer, unsigned length)
     if (canUseFastRenderer(buffer.data(), length)) {
         Font webCoreFont(FontPlatformData(font, [font pointSize]), ![[NSGraphicsContext currentContext] isDrawingToScreen]);
         TextRun run(buffer.data(), length);
-        run.disableRoundingHacks();
-        return webCoreFont.floatWidth(run);
+        return webCoreFont.width(run);
     }
 
     return [self sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]].width;
index 600a97f..afc5296 100644 (file)
@@ -1,3 +1,31 @@
+2011-02-16  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        https://bugs.webkit.org/show_bug.cgi?id=54244
+        
+        Convert the line box tree to floating point and eliminate font rounding hacks.  This patch removes all of the rounding
+        hacks from the Font code and makes sure all Font APIs involving width measurement and width offsets use floats.
+        
+        The line box tree's x, y and logicalWidth members have all been converted to floats and all of the line box APIs have
+        been changed as well.
+        
+        In terms of pixel adjustments, overflow is using an enclosing model (so it will be enclosingIntRect of a line box's x/y/width/height).
+        
+        Background and border painting is using a rounding model, so borders and backgrounds will round to the nearest pixel when painting.
+        
+        Replaced elements still snap to integer positions on lines, and they use a rounding model as well, although their underlying line boxes
+        still have a precise floating point position.
+
+        Justification will now allow subpixel positioning to occur as well.  Platforms that don't support subpixel positioning should already
+        be rounding justification spacing in their font code.
+
+        Many layout test results change on Mac, since rounding hacks were used there and are now gone.
+
+        * WebKitGraphics.cpp:
+        (CenterTruncateStringToWidth):
+        (RightTruncateStringToWidth):
+
 2011-02-10  Luiz Agostini  <luiz.agostini@openbossa.org>
 
         Reviewed by Adam Roben.
index 1907050..b130002 100644 (file)
@@ -149,7 +149,7 @@ unsigned CenterTruncateStringToWidth(LPCTSTR text, int length, const WebFontDesc
 {
     ASSERT(buffer);
 
-    String result = StringTruncator::centerTruncate(String(text, length), width, makeFont(description), false);
+    String result = StringTruncator::centerTruncate(String(text, length), width, makeFont(description));
     memcpy(buffer, result.characters(), result.length() * sizeof(UChar));
     buffer[result.length()] = '\0';
     return result.length();
@@ -159,7 +159,7 @@ unsigned RightTruncateStringToWidth(LPCTSTR text, int length, const WebFontDescr
 {
     ASSERT(buffer);
 
-    String result = StringTruncator::rightTruncate(String(text, length), width, makeFont(description), false);
+    String result = StringTruncator::rightTruncate(String(text, length), width, makeFont(description));
     memcpy(buffer, result.characters(), result.length() * sizeof(UChar));
     buffer[result.length()] = '\0';
     return result.length();
index b42dfa0..5abb6a4 100644 (file)
@@ -1,3 +1,30 @@
+2011-02-16  David Hyatt  <hyatt@apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        https://bugs.webkit.org/show_bug.cgi?id=54244
+        
+        Convert the line box tree to floating point and eliminate font rounding hacks.  This patch removes all of the rounding
+        hacks from the Font code and makes sure all Font APIs involving width measurement and width offsets use floats.
+        
+        The line box tree's x, y and logicalWidth members have all been converted to floats and all of the line box APIs have
+        been changed as well.
+        
+        In terms of pixel adjustments, overflow is using an enclosing model (so it will be enclosingIntRect of a line box's x/y/width/height).
+        
+        Background and border painting is using a rounding model, so borders and backgrounds will round to the nearest pixel when painting.
+        
+        Replaced elements still snap to integer positions on lines, and they use a rounding model as well, although their underlying line boxes
+        still have a precise floating point position.
+
+        Justification will now allow subpixel positioning to occur as well.  Platforms that don't support subpixel positioning should already
+        be rounding justification spacing in their font code.
+
+        Many layout test results change on Mac, since rounding hacks were used there and are now gone.
+
+        * WebProcess/WebCoreSupport/win/WebPopupMenuWin.cpp:
+        (WebKit::WebPopupMenu::setUpPlatformData):
+
 2011-02-10  Luiz Agostini  <luiz.agostini@openbossa.org>
 
         Reviewed by Adam Roben.
index b80dccd..b4db406 100644 (file)
@@ -66,7 +66,7 @@ void WebPopupMenu::setUpPlatformData(const WebCore::IntRect& pageCoordinates, Pl
             itemFont.update(m_popupClient->fontSelector());
         }
 
-        popupWidth = std::max(popupWidth, itemFont.width(TextRun(text.characters(), text.length())));
+        popupWidth = std::max<float>(popupWidth, ceilf(itemFont.width(TextRun(text.characters(), text.length()))));
     }
 
     // FIXME: popupWidth should probably take into account monitor constraints as is done with WebPopupMenuProxyWin::calculatePositionAndSize.