2011-05-24 Nikolas Zimmermann <nzimmermann@rim.com>
authorzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 May 2011 15:27:36 +0000 (15:27 +0000)
committerzimmermann@webkit.org <zimmermann@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 May 2011 15:27:36 +0000 (15:27 +0000)
        Reviewed by Antti Koivisto.

        Remove platform layering violation: TextRun stores RenderObjects for SVG Fonts support
        https://bugs.webkit.org/show_bug.cgi?id=60254

        First part:
        Remove a long-standing layering violation in TextRun: it stores RenderObject/RenderSVGResource pointers for SVG Fonts support.
        Replace the two Render* pointers with a single RefPtr<AbstractRenderingContext>. AbstractRenderingContext is a helper class,
        that can be derived from in order to associate additional data with a TextRun. This effectively reduces the memory consumption of TextRun.

        Introduce rendering/TextRunRenderingContext.h, which inherits from TextRun::AbstractRenderingContext and holds additional data.
        If the primary font in use is a SVG Font then allocate a TextRunRenderingContext object and store it in the RefPtr<AbstractRenderingContext>
        in TextRun. If the primary font is not a SVG Font, don't even allocate the TextRunRenderingContext structure, as we won't need the context data.
        SVG Fonts glyph matching only works within a context, so we need access to the RenderObject that's drawing the text.

        This is the main preparation patch for the SVG Fonts rewrite, that will allow us to share the simple text code path for SVG Fonts as well,
        making all CSS text properties work for HTML text using SVG Fonts, and allows proper integration within the GlyphPage concept. Soon
        we can intermix WOFF/SVG & native fonts, within segment font declarations.

        Second part:
        Remove a long-standing layering violation in SimpleFontData: it stores SVGFontData objects, that are living in svg/.
        Use the same concept as above, introduce SimpleFontData::AbstractFontData, and let SVGFontData inherit from AbstractFontData and extent it.
        If SVG Fonts are used, CSSFontFaceSource will create a SVGFontData object and pass it as PassOwnPtr<AbstractFontData> to SimpleFontData.

        All layering violations are gone now, SVG Fonts are cleanly integrated now.
        Doesn't affect any tests yet, refactoring only.

        * CMakeLists.txt:
        * GNUmakefile.list.am:
        * WebCore.gypi:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * css/CSSFontFaceSource.cpp:
        (WebCore::CSSFontFaceSource::getFontData):
        * platform/graphics/Font.cpp:
        (WebCore::Font::drawText):
        (WebCore::Font::width):
        (WebCore::Font::selectionRectForText):
        (WebCore::Font::offsetForPosition):
        * platform/graphics/Font.h:
        * platform/graphics/SimpleFontData.cpp:
        (WebCore::SimpleFontData::SimpleFontData):
        (WebCore::SimpleFontData::~SimpleFontData):
        * platform/graphics/SimpleFontData.h:
        (WebCore::SimpleFontData::FontData::~FontData):
        (WebCore::SimpleFontData::fontMetrics):
        (WebCore::SimpleFontData::setMaxCharWidth):
        (WebCore::SimpleFontData::setAvgCharWidth):
        (WebCore::SimpleFontData::setSpaceWidth):
        (WebCore::SimpleFontData::setSpaceGlyph):
        (WebCore::SimpleFontData::setZeroWidthSpaceGlyph):
        (WebCore::SimpleFontData::fontData):
        (WebCore::SimpleFontData::isSVGFont):
        (WebCore::SimpleFontData::setMissingGlyphData):
        * platform/graphics/TextRun.h:
        (WebCore::TextRun::TextRun):
        (WebCore::TextRun::setAllowTabs):
        (WebCore::TextRun::setXPos):
        (WebCore::TextRun::RenderingContext::~RenderingContext):
        (WebCore::TextRun::renderingContext):
        (WebCore::TextRun::setRenderingContext):
        * rendering/EllipsisBox.cpp:
        (WebCore::EllipsisBox::paint):
        (WebCore::EllipsisBox::selectionRect):
        (WebCore::EllipsisBox::paintSelection):
        * rendering/InlineTextBox.cpp:
        (WebCore::InlineTextBox::selectionRect):
        (WebCore::InlineTextBox::paint):
        (WebCore::InlineTextBox::paintSelection):
        (WebCore::InlineTextBox::paintCompositionBackground):
        (WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
        (WebCore::InlineTextBox::paintTextMatchMarker):
        (WebCore::InlineTextBox::computeRectForReplacementMarker):
        (WebCore::InlineTextBox::offsetForPosition):
        (WebCore::InlineTextBox::positionForOffset):
        (WebCore::InlineTextBox::constructTextRun):
        * rendering/InlineTextBox.h:
        * rendering/RenderBlock.cpp:
        (WebCore::stripTrailingSpace):
        (WebCore::RenderBlock::constructTextRun):
        * rendering/RenderBlock.h:
        * rendering/RenderBlockLineLayout.cpp:
        (WebCore::setLogicalWidthForTextRun):
        (WebCore::textWidth):
        (WebCore::tryHyphenating):
        (WebCore::RenderBlock::LineBreaker::nextLineBreak):
        (WebCore::RenderBlock::checkLinesForTextOverflow):
        * rendering/RenderCombineText.cpp:
        (WebCore::RenderCombineText::combineText):
        * rendering/RenderFileUploadControl.cpp:
        (WebCore::RenderFileUploadControl::paintObject):
        (WebCore::RenderFileUploadControl::computePreferredLogicalWidths):
        * rendering/RenderFlexibleBox.cpp:
        (WebCore::RenderFlexibleBox::applyLineClamp):
        * rendering/RenderImage.cpp:
        (WebCore::RenderImage::setImageSizeForAltText):
        (WebCore::RenderImage::paintReplaced):
        * rendering/RenderListBox.cpp:
        (WebCore::RenderListBox::updateFromElement):
        * rendering/RenderListMarker.cpp:
        (WebCore::RenderListMarker::paint):
        (WebCore::RenderListMarker::computePreferredLogicalWidths):
        (WebCore::RenderListMarker::getRelativeMarkerRect):
        * rendering/RenderText.cpp:
        (WebCore::RenderText::widthFromCache):
        (WebCore::RenderText::trimmedPrefWidths):
        (WebCore::RenderText::computePreferredLogicalWidths):
        (WebCore::RenderText::width):
        * rendering/RenderTextControl.cpp:
        (WebCore::RenderTextControl::getAvgCharWidth):
        * rendering/svg/RenderSVGAllInOne.cpp:
        * rendering/svg/SVGInlineTextBox.cpp:
        (WebCore::SVGInlineTextBox::offsetForPositionInFragment):
        (WebCore::SVGInlineTextBox::prepareGraphicsContextForTextPainting):
        (WebCore::SVGInlineTextBox::restoreGraphicsContextAfterTextPainting):
        (WebCore::SVGInlineTextBox::constructTextRun):
        (WebCore::SVGInlineTextBox::paintText):
        * rendering/svg/SVGTextLayoutEngineSpacing.cpp:
        (WebCore::SVGTextLayoutEngineSpacing::calculateSVGKerning):
        * rendering/svg/SVGTextMetrics.cpp:
        (WebCore::constructTextRun):
        (WebCore::SVGTextMetrics::measureCharacterRange):
        * rendering/svg/SVGTextRunRenderingContext.cpp: Copied from svg/SVGFont.cpp.
        (WebCore::svgFontAndFontFaceElementForFontData):
        (WebCore::firstParentRendererForNonTextNode):
        (WebCore::referencingRenderObjectFromRun):
        (WebCore::activePaintingResourceFromRun):
        (WebCore::SVGTextRunWalker::walk):
        (WebCore::floatWidthMissingGlyphCallback):
        (WebCore::floatWidthOfSubStringUsingSVGFont):
        (WebCore::SVGTextRunRenderingContext::floatWidthUsingSVGFont):
        (WebCore::SVGTextRunRenderingContext::drawTextUsingSVGFont):
        (WebCore::SVGTextRunRenderingContext::selectionRectForTextUsingSVGFont):
        (WebCore::SVGTextRunRenderingContext::offsetForPositionForTextUsingSVGFont):
        * rendering/svg/SVGTextRunRenderingContext.h: Added.
        (WebCore::SVGTextRunRenderingContext::create):
        (WebCore::SVGTextRunRenderingContext::context):
        (WebCore::SVGTextRunRenderingContext::activePaintingResource):
        (WebCore::SVGTextRunRenderingContext::setActivePaintingResource):
        (WebCore::SVGTextRunRenderingContext::SVGTextRunRenderingContext):
        (WebCore::textRunNeedsRenderingContext):
        * svg/SVGAllInOne.cpp:
        * svg/SVGFont.cpp: Removed.
        * svg/SVGFontData.cpp:
        (WebCore::SVGFontData::initializeFontData):
        * svg/SVGFontData.h:
        (WebCore::SVGFontData::create):
        (WebCore::SVGFontData::isSVGFontData):
        * svg/SVGGlyphElement.cpp:
        (WebCore::SVGGlyphElement::SVGGlyphElement):
        (WebCore::SVGGlyphElement::buildGenericGlyphIdentifier):
        (WebCore::SVGGlyphElement::buildGlyphIdentifier):
        * svg/SVGHKernElement.cpp:
        (WebCore::SVGHKernElement::SVGHKernElement):
        (WebCore::SVGHKernElement::buildHorizontalKerningPair):
        * svg/SVGVKernElement.cpp:
        (WebCore::SVGVKernElement::SVGVKernElement):
        (WebCore::SVGVKernElement::buildVerticalKerningPair):
        * svg/SVGVKernElement.h:

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

40 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.pro
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/css/CSSFontFaceSource.cpp
Source/WebCore/platform/graphics/Font.cpp
Source/WebCore/platform/graphics/Font.h
Source/WebCore/platform/graphics/SimpleFontData.cpp
Source/WebCore/platform/graphics/SimpleFontData.h
Source/WebCore/platform/graphics/TextRun.h
Source/WebCore/rendering/EllipsisBox.cpp
Source/WebCore/rendering/InlineTextBox.cpp
Source/WebCore/rendering/InlineTextBox.h
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlock.h
Source/WebCore/rendering/RenderBlockLineLayout.cpp
Source/WebCore/rendering/RenderCombineText.cpp
Source/WebCore/rendering/RenderFileUploadControl.cpp
Source/WebCore/rendering/RenderFlexibleBox.cpp
Source/WebCore/rendering/RenderImage.cpp
Source/WebCore/rendering/RenderListBox.cpp
Source/WebCore/rendering/RenderListMarker.cpp
Source/WebCore/rendering/RenderText.cpp
Source/WebCore/rendering/RenderTextControl.cpp
Source/WebCore/rendering/svg/RenderSVGAllInOne.cpp
Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
Source/WebCore/rendering/svg/SVGTextMetrics.cpp
Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp [moved from Source/WebCore/svg/SVGFont.cpp with 73% similarity]
Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h [new file with mode: 0644]
Source/WebCore/svg/SVGAllInOne.cpp
Source/WebCore/svg/SVGFontData.cpp
Source/WebCore/svg/SVGFontData.h
Source/WebCore/svg/SVGGlyphElement.cpp
Source/WebCore/svg/SVGHKernElement.cpp
Source/WebCore/svg/SVGVKernElement.cpp
Source/WebCore/svg/SVGVKernElement.h

index f453126..ea2a555 100644 (file)
@@ -1617,6 +1617,7 @@ IF (ENABLE_SVG)
         rendering/svg/SVGTextLayoutEngine.cpp
         rendering/svg/SVGTextLayoutEngineBaseline.cpp
         rendering/svg/SVGTextLayoutEngineSpacing.cpp
+        rendering/svg/SVGTextRunRenderingContext.cpp
         rendering/svg/SVGTextMetrics.cpp
         rendering/svg/SVGTextQuery.cpp
         svg/ColorDistance.cpp
@@ -1671,7 +1672,6 @@ IF (ENABLE_SVG)
         svg/SVGFilterElement.cpp
         svg/SVGFilterPrimitiveStandardAttributes.cpp
         svg/SVGFitToViewBox.cpp
-        svg/SVGFont.cpp
         svg/SVGFontData.cpp
         svg/SVGFontElement.cpp
         svg/SVGFontFaceElement.cpp
index 7ca9665..e846d71 100644 (file)
@@ -1,3 +1,166 @@
+2011-05-24  Nikolas Zimmermann  <nzimmermann@rim.com>
+
+        Reviewed by Antti Koivisto.
+
+        Remove platform layering violation: TextRun stores RenderObjects for SVG Fonts support
+        https://bugs.webkit.org/show_bug.cgi?id=60254
+
+        First part:
+        Remove a long-standing layering violation in TextRun: it stores RenderObject/RenderSVGResource pointers for SVG Fonts support.
+        Replace the two Render* pointers with a single RefPtr<AbstractRenderingContext>. AbstractRenderingContext is a helper class,
+        that can be derived from in order to associate additional data with a TextRun. This effectively reduces the memory consumption of TextRun.
+
+        Introduce rendering/TextRunRenderingContext.h, which inherits from TextRun::AbstractRenderingContext and holds additional data.
+        If the primary font in use is a SVG Font then allocate a TextRunRenderingContext object and store it in the RefPtr<AbstractRenderingContext>
+        in TextRun. If the primary font is not a SVG Font, don't even allocate the TextRunRenderingContext structure, as we won't need the context data.
+        SVG Fonts glyph matching only works within a context, so we need access to the RenderObject that's drawing the text.
+
+        This is the main preparation patch for the SVG Fonts rewrite, that will allow us to share the simple text code path for SVG Fonts as well,
+        making all CSS text properties work for HTML text using SVG Fonts, and allows proper integration within the GlyphPage concept. Soon
+        we can intermix WOFF/SVG & native fonts, within segment font declarations.
+
+        Second part:
+        Remove a long-standing layering violation in SimpleFontData: it stores SVGFontData objects, that are living in svg/.
+        Use the same concept as above, introduce SimpleFontData::AbstractFontData, and let SVGFontData inherit from AbstractFontData and extent it.
+        If SVG Fonts are used, CSSFontFaceSource will create a SVGFontData object and pass it as PassOwnPtr<AbstractFontData> to SimpleFontData.
+
+        All layering violations are gone now, SVG Fonts are cleanly integrated now.
+        Doesn't affect any tests yet, refactoring only.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/CSSFontFaceSource.cpp:
+        (WebCore::CSSFontFaceSource::getFontData):
+        * platform/graphics/Font.cpp:
+        (WebCore::Font::drawText):
+        (WebCore::Font::width):
+        (WebCore::Font::selectionRectForText):
+        (WebCore::Font::offsetForPosition):
+        * platform/graphics/Font.h:
+        * platform/graphics/SimpleFontData.cpp:
+        (WebCore::SimpleFontData::SimpleFontData):
+        (WebCore::SimpleFontData::~SimpleFontData):
+        * platform/graphics/SimpleFontData.h:
+        (WebCore::SimpleFontData::FontData::~FontData):
+        (WebCore::SimpleFontData::fontMetrics):
+        (WebCore::SimpleFontData::setMaxCharWidth):
+        (WebCore::SimpleFontData::setAvgCharWidth):
+        (WebCore::SimpleFontData::setSpaceWidth):
+        (WebCore::SimpleFontData::setSpaceGlyph):
+        (WebCore::SimpleFontData::setZeroWidthSpaceGlyph):
+        (WebCore::SimpleFontData::fontData):
+        (WebCore::SimpleFontData::isSVGFont):
+        (WebCore::SimpleFontData::setMissingGlyphData):
+        * platform/graphics/TextRun.h:
+        (WebCore::TextRun::TextRun):
+        (WebCore::TextRun::setAllowTabs):
+        (WebCore::TextRun::setXPos):
+        (WebCore::TextRun::RenderingContext::~RenderingContext):
+        (WebCore::TextRun::renderingContext):
+        (WebCore::TextRun::setRenderingContext):
+        * rendering/EllipsisBox.cpp:
+        (WebCore::EllipsisBox::paint):
+        (WebCore::EllipsisBox::selectionRect):
+        (WebCore::EllipsisBox::paintSelection):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::selectionRect):
+        (WebCore::InlineTextBox::paint):
+        (WebCore::InlineTextBox::paintSelection):
+        (WebCore::InlineTextBox::paintCompositionBackground):
+        (WebCore::InlineTextBox::paintSpellingOrGrammarMarker):
+        (WebCore::InlineTextBox::paintTextMatchMarker):
+        (WebCore::InlineTextBox::computeRectForReplacementMarker):
+        (WebCore::InlineTextBox::offsetForPosition):
+        (WebCore::InlineTextBox::positionForOffset):
+        (WebCore::InlineTextBox::constructTextRun):
+        * rendering/InlineTextBox.h:
+        * rendering/RenderBlock.cpp:
+        (WebCore::stripTrailingSpace):
+        (WebCore::RenderBlock::constructTextRun):
+        * rendering/RenderBlock.h:
+        * rendering/RenderBlockLineLayout.cpp:
+        (WebCore::setLogicalWidthForTextRun):
+        (WebCore::textWidth):
+        (WebCore::tryHyphenating):
+        (WebCore::RenderBlock::LineBreaker::nextLineBreak):
+        (WebCore::RenderBlock::checkLinesForTextOverflow):
+        * rendering/RenderCombineText.cpp:
+        (WebCore::RenderCombineText::combineText):
+        * rendering/RenderFileUploadControl.cpp:
+        (WebCore::RenderFileUploadControl::paintObject):
+        (WebCore::RenderFileUploadControl::computePreferredLogicalWidths):
+        * rendering/RenderFlexibleBox.cpp:
+        (WebCore::RenderFlexibleBox::applyLineClamp):
+        * rendering/RenderImage.cpp:
+        (WebCore::RenderImage::setImageSizeForAltText):
+        (WebCore::RenderImage::paintReplaced):
+        * rendering/RenderListBox.cpp:
+        (WebCore::RenderListBox::updateFromElement):
+        * rendering/RenderListMarker.cpp:
+        (WebCore::RenderListMarker::paint):
+        (WebCore::RenderListMarker::computePreferredLogicalWidths):
+        (WebCore::RenderListMarker::getRelativeMarkerRect):
+        * rendering/RenderText.cpp:
+        (WebCore::RenderText::widthFromCache):
+        (WebCore::RenderText::trimmedPrefWidths):
+        (WebCore::RenderText::computePreferredLogicalWidths):
+        (WebCore::RenderText::width):
+        * rendering/RenderTextControl.cpp:
+        (WebCore::RenderTextControl::getAvgCharWidth):
+        * rendering/svg/RenderSVGAllInOne.cpp:
+        * rendering/svg/SVGInlineTextBox.cpp:
+        (WebCore::SVGInlineTextBox::offsetForPositionInFragment):
+        (WebCore::SVGInlineTextBox::prepareGraphicsContextForTextPainting):
+        (WebCore::SVGInlineTextBox::restoreGraphicsContextAfterTextPainting):
+        (WebCore::SVGInlineTextBox::constructTextRun):
+        (WebCore::SVGInlineTextBox::paintText):
+        * rendering/svg/SVGTextLayoutEngineSpacing.cpp:
+        (WebCore::SVGTextLayoutEngineSpacing::calculateSVGKerning):
+        * rendering/svg/SVGTextMetrics.cpp:
+        (WebCore::constructTextRun):
+        (WebCore::SVGTextMetrics::measureCharacterRange):
+        * rendering/svg/SVGTextRunRenderingContext.cpp: Copied from svg/SVGFont.cpp.
+        (WebCore::svgFontAndFontFaceElementForFontData):
+        (WebCore::firstParentRendererForNonTextNode):
+        (WebCore::referencingRenderObjectFromRun):
+        (WebCore::activePaintingResourceFromRun):
+        (WebCore::SVGTextRunWalker::walk):
+        (WebCore::floatWidthMissingGlyphCallback):
+        (WebCore::floatWidthOfSubStringUsingSVGFont):
+        (WebCore::SVGTextRunRenderingContext::floatWidthUsingSVGFont):
+        (WebCore::SVGTextRunRenderingContext::drawTextUsingSVGFont):
+        (WebCore::SVGTextRunRenderingContext::selectionRectForTextUsingSVGFont):
+        (WebCore::SVGTextRunRenderingContext::offsetForPositionForTextUsingSVGFont):
+        * rendering/svg/SVGTextRunRenderingContext.h: Added.
+        (WebCore::SVGTextRunRenderingContext::create):
+        (WebCore::SVGTextRunRenderingContext::context):
+        (WebCore::SVGTextRunRenderingContext::activePaintingResource):
+        (WebCore::SVGTextRunRenderingContext::setActivePaintingResource):
+        (WebCore::SVGTextRunRenderingContext::SVGTextRunRenderingContext):
+        (WebCore::textRunNeedsRenderingContext):
+        * svg/SVGAllInOne.cpp:
+        * svg/SVGFont.cpp: Removed.
+        * svg/SVGFontData.cpp:
+        (WebCore::SVGFontData::initializeFontData):
+        * svg/SVGFontData.h:
+        (WebCore::SVGFontData::create):
+        (WebCore::SVGFontData::isSVGFontData):
+        * svg/SVGGlyphElement.cpp:
+        (WebCore::SVGGlyphElement::SVGGlyphElement):
+        (WebCore::SVGGlyphElement::buildGenericGlyphIdentifier):
+        (WebCore::SVGGlyphElement::buildGlyphIdentifier):
+        * svg/SVGHKernElement.cpp:
+        (WebCore::SVGHKernElement::SVGHKernElement):
+        (WebCore::SVGHKernElement::buildHorizontalKerningPair):
+        * svg/SVGVKernElement.cpp:
+        (WebCore::SVGVKernElement::SVGVKernElement):
+        (WebCore::SVGVKernElement::buildVerticalKerningPair):
+        * svg/SVGVKernElement.h:
+
 2011-05-24  Ryuan Choi  <ryuan.choi@samsung.com>
 
         Reviewed by Andreas Kling.
index f75805e..c75796c 100644 (file)
@@ -3091,6 +3091,8 @@ webcore_sources += \
        Source/WebCore/rendering/svg/SVGTextMetrics.h \
        Source/WebCore/rendering/svg/SVGTextQuery.cpp \
        Source/WebCore/rendering/svg/SVGTextQuery.h \
+       Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp \
+       Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h \
        Source/WebCore/rendering/TableLayout.h \
        Source/WebCore/rendering/TrailingFloatsRootInlineBox.h \
        Source/WebCore/rendering/TransformState.cpp \
@@ -3388,7 +3390,6 @@ webcore_sources += \
        Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h \
        Source/WebCore/svg/SVGFitToViewBox.cpp \
        Source/WebCore/svg/SVGFitToViewBox.h \
-       Source/WebCore/svg/SVGFont.cpp \
        Source/WebCore/svg/SVGFontData.cpp \
        Source/WebCore/svg/SVGFontData.h \
        Source/WebCore/svg/SVGFontElement.cpp \
index d065de9..0c3f915 100644 (file)
             'rendering/svg/SVGTextMetrics.h',
             'rendering/svg/SVGTextQuery.cpp',
             'rendering/svg/SVGTextQuery.h',
+            'rendering/svg/SVGTextRunRenderingContext.cpp',
+            'rendering/svg/SVGTextRunRenderingContext.h',
             'storage/AbstractDatabase.cpp',
             'storage/ChangeVersionWrapper.cpp',
             'storage/ChangeVersionWrapper.h',
             'svg/SVGFilterPrimitiveStandardAttributes.h',
             'svg/SVGFitToViewBox.cpp',
             'svg/SVGFitToViewBox.h',
-            'svg/SVGFont.cpp',
             'svg/SVGFontData.cpp',
             'svg/SVGFontData.h',
             'svg/SVGFontElement.cpp',
index d16e562..814d1a5 100644 (file)
@@ -2252,6 +2252,7 @@ HEADERS += \
     rendering/svg/SVGTextLayoutEngineSpacing.h \
     rendering/svg/SVGTextMetrics.h \
     rendering/svg/SVGTextQuery.h \
+    rendering/svg/SVGTextRunRenderingContext.h \
     rendering/TransformState.h \
     svg/animation/SMILTimeContainer.h \
     svg/animation/SMILTime.h \
@@ -3208,6 +3209,7 @@ contains(DEFINES, ENABLE_SVG=1) {
               rendering/svg/SVGTextLayoutEngineSpacing.cpp \
               rendering/svg/SVGTextMetrics.cpp \
               rendering/svg/SVGTextQuery.cpp \
+              rendering/svg/SVGTextRunRenderingContext.cpp \
               svg/SVGDocumentExtensions.cpp \
               svg/SVGImageLoader.cpp \
               svg/ColorDistance.cpp \
@@ -3261,7 +3263,6 @@ contains(DEFINES, ENABLE_SVG=1) {
               svg/SVGFilterElement.cpp \
               svg/SVGFilterPrimitiveStandardAttributes.cpp \
               svg/SVGFitToViewBox.cpp \
-              svg/SVGFont.cpp \
               svg/SVGFontData.cpp \
               svg/SVGFontElement.cpp \
               svg/SVGFontFaceElement.cpp \
index 0685dbf..4ba34f6 100755 (executable)
                                        RelativePath="..\rendering\svg\SVGTextQuery.h"
                                        >
                                </File>
+                               <File
+                                       RelativePath="..\rendering\svg\SVGTextRunRenderingContext.cpp"
+                                       >
+                                       <FileConfiguration
+                                               Name="Debug|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Release|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Debug_Cairo_CFLite|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Release_Cairo_CFLite|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Debug_All|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                                       <FileConfiguration
+                                               Name="Production|Win32"
+                                               ExcludedFromBuild="true"
+                                               >
+                                               <Tool
+                                                       Name="VCCLCompilerTool"
+                                               />
+                                       </FileConfiguration>
+                               </File>
+                               <File
+                                       RelativePath="..\rendering\svg\SVGTextRunRenderingContext.h"
+                                       >
+                               </File>
                        </Filter>
                </Filter>
                <Filter
index 99e7b10..247cb21 100644 (file)
@@ -98,6 +98,7 @@
                085A15931289A8DD002710E3 /* SVGAnimatedTransformListPropertyTearOff.h in Headers */ = {isa = PBXBuildFile; fileRef = 085A15921289A8DD002710E3 /* SVGAnimatedTransformListPropertyTearOff.h */; settings = {ATTRIBUTES = (Private, ); }; };
                085B92BA0EFDE73D00E6123C /* FormDataBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 085B92B80EFDE73D00E6123C /* FormDataBuilder.cpp */; };
                085B92BB0EFDE73D00E6123C /* FormDataBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 085B92B90EFDE73D00E6123C /* FormDataBuilder.h */; settings = {ATTRIBUTES = (); }; };
+               085CD275138BB8E000907F2D /* SVGTextRunRenderingContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 085CD274138BB8E000907F2D /* SVGTextRunRenderingContext.h */; };
                08641D4712142F7D008DE9F6 /* RenderImageResourceStyleImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08641D4512142F7D008DE9F6 /* RenderImageResourceStyleImage.cpp */; };
                08641D4812142F7D008DE9F6 /* RenderImageResourceStyleImage.h in Headers */ = {isa = PBXBuildFile; fileRef = 08641D4612142F7D008DE9F6 /* RenderImageResourceStyleImage.h */; settings = {ATTRIBUTES = (Private, ); }; };
                086BBD0F136039C2008B15D8 /* Glyph.h in Headers */ = {isa = PBXBuildFile; fileRef = 086BBD0E136039C2008B15D8 /* Glyph.h */; settings = {ATTRIBUTES = (Private, ); }; };
                B25599A30D00D8BA00BB825C /* SVGImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B255990B0D00D8B900BB825C /* SVGImage.cpp */; };
                B25599A40D00D8BA00BB825C /* SVGImage.h in Headers */ = {isa = PBXBuildFile; fileRef = B255990C0D00D8B900BB825C /* SVGImage.h */; };
                B25599A50D00D8BA00BB825C /* EmptyClients.h in Headers */ = {isa = PBXBuildFile; fileRef = B255990D0D00D8B900BB825C /* EmptyClients.h */; };
-               B262B8040D1F32D000158F09 /* SVGFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B262B8030D1F32D000158F09 /* SVGFont.cpp */; };
                B266CD4D0C3AEC6500EB08D2 /* JSSVGException.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B266CD4B0C3AEC6500EB08D2 /* JSSVGException.cpp */; };
                B266CD4E0C3AEC6500EB08D2 /* JSSVGException.h in Headers */ = {isa = PBXBuildFile; fileRef = B266CD4C0C3AEC6500EB08D2 /* JSSVGException.h */; };
                B27535580B053814002CE64F /* TransformationMatrixCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B275352A0B053814002CE64F /* TransformationMatrixCG.cpp */; };
                085A15921289A8DD002710E3 /* SVGAnimatedTransformListPropertyTearOff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedTransformListPropertyTearOff.h; sourceTree = "<group>"; };
                085B92B80EFDE73D00E6123C /* FormDataBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormDataBuilder.cpp; sourceTree = "<group>"; };
                085B92B90EFDE73D00E6123C /* FormDataBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormDataBuilder.h; sourceTree = "<group>"; };
+               085CD274138BB8E000907F2D /* SVGTextRunRenderingContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGTextRunRenderingContext.h; sourceTree = "<group>"; };
                08641D4512142F7D008DE9F6 /* RenderImageResourceStyleImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderImageResourceStyleImage.cpp; sourceTree = "<group>"; };
                08641D4612142F7D008DE9F6 /* RenderImageResourceStyleImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderImageResourceStyleImage.h; sourceTree = "<group>"; };
                086BBD0E136039C2008B15D8 /* Glyph.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Glyph.h; sourceTree = "<group>"; };
                08C925170FCC7C4A00480DEC /* FilterEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FilterEffect.cpp; path = filters/FilterEffect.cpp; sourceTree = "<group>"; };
                08C925180FCC7C4A00480DEC /* FilterEffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FilterEffect.h; path = filters/FilterEffect.h; sourceTree = "<group>"; };
                08CA3D4312894A3800FFF260 /* SVGStaticPropertyWithParentTearOff.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGStaticPropertyWithParentTearOff.h; sourceTree = "<group>"; };
+               08D29440138669E40097C89B /* SVGTextRunRenderingContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGTextRunRenderingContext.cpp; sourceTree = "<group>"; };
                08D46CE2127AD5FC0089694B /* SVGAnimatedEnumeration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGAnimatedEnumeration.h; sourceTree = "<group>"; };
                08E4FE450E2BD41400F4CAE0 /* JSSVGLengthCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSVGLengthCustom.cpp; sourceTree = "<group>"; };
                08EDE19E12A50B8E00B95797 /* SVGRect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGRect.h; sourceTree = "<group>"; };
                B255990B0D00D8B900BB825C /* SVGImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SVGImage.cpp; sourceTree = "<group>"; };
                B255990C0D00D8B900BB825C /* SVGImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SVGImage.h; sourceTree = "<group>"; };
                B255990D0D00D8B900BB825C /* EmptyClients.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = EmptyClients.h; sourceTree = "<group>"; };
-               B262B8030D1F32D000158F09 /* SVGFont.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SVGFont.cpp; sourceTree = "<group>"; };
                B266CD4B0C3AEC6500EB08D2 /* JSSVGException.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSSVGException.cpp; sourceTree = "<group>"; };
                B266CD4C0C3AEC6500EB08D2 /* JSSVGException.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSSVGException.h; sourceTree = "<group>"; };
                B275352A0B053814002CE64F /* TransformationMatrixCG.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TransformationMatrixCG.cpp; sourceTree = "<group>"; };
                                08F0BFC11255C53C00075185 /* SVGTextMetrics.h */,
                                0854B0121255E4E600B9CDD0 /* SVGTextQuery.cpp */,
                                0854B0131255E4E600B9CDD0 /* SVGTextQuery.h */,
+                               08D29440138669E40097C89B /* SVGTextRunRenderingContext.cpp */,
+                               085CD274138BB8E000907F2D /* SVGTextRunRenderingContext.h */,
                        );
                        path = svg;
                        sourceTree = "<group>";
                                B222787B0D00BF200071B782 /* SVGFitToViewBox.cpp */,
                                B222787C0D00BF200071B782 /* SVGFitToViewBox.h */,
                                B222787D0D00BF200071B782 /* SVGFitToViewBox.idl */,
-                               B262B8030D1F32D000158F09 /* SVGFont.cpp */,
                                B237C8A50D344D110013F707 /* SVGFontData.cpp */,
                                B237C8A60D344D110013F707 /* SVGFontData.h */,
                                B2A1F2A10CEF0ABF00442F6A /* SVGFontElement.cpp */,
                                858C381C0AA8E29600B187A4 /* DOMCSSValue.h in Headers */,
                                85B498F30ADB336A00925CBB /* DOMCSSValueInternal.h in Headers */,
                                858C383C0AA8ED8200B187A4 /* DOMCSSValueList.h in Headers */,
-                               C0F2A44113869AAB0066C534 /* preprocessor.pm in Headers */,
                                85909D2B0ACC7D5500DF01F1 /* DOMCSSValueListInternal.h in Headers */,
                                E10B9CCC0B747A44003ED890 /* DOMCustomXPathNSResolver.h in Headers */,
                                85ACABB00A9CAF8000671E90 /* DOMDocument.h in Headers */,
                                FE80D7CF0E9C1F25000D6F75 /* PositionErrorCallback.h in Headers */,
                                37919C240B7D188600A56998 /* PositionIterator.h in Headers */,
                                FE80D7D10E9C1F25000D6F75 /* PositionOptions.h in Headers */,
+                               C0F2A44113869AAB0066C534 /* preprocessor.pm in Headers */,
                                B71FE6DF11091CB300DAEF77 /* PrintContext.h in Headers */,
                                A8EA7EBC0A1945D000A8EF5F /* ProcessingInstruction.h in Headers */,
                                E44613EC0CD681B500FADA75 /* ProgressEvent.h in Headers */,
                                B2227ACE0D00BF220071B782 /* SVGTextPathElement.h in Headers */,
                                B2227AD10D00BF220071B782 /* SVGTextPositioningElement.h in Headers */,
                                0854B0251255E4E600B9CDD0 /* SVGTextQuery.h in Headers */,
+                               085CD275138BB8E000907F2D /* SVGTextRunRenderingContext.h in Headers */,
                                B2227AD40D00BF220071B782 /* SVGTitleElement.h in Headers */,
                                B2227AD70D00BF220071B782 /* SVGTransform.h in Headers */,
                                B2227ADA0D00BF220071B782 /* SVGTransformable.h in Headers */,
                                B2227A0B0D00BF220071B782 /* SVGFilterElement.cpp in Sources */,
                                B2227A0E0D00BF220071B782 /* SVGFilterPrimitiveStandardAttributes.cpp in Sources */,
                                B2227A110D00BF220071B782 /* SVGFitToViewBox.cpp in Sources */,
-                               B262B8040D1F32D000158F09 /* SVGFont.cpp in Sources */,
                                B237C8A70D344D110013F707 /* SVGFontData.cpp in Sources */,
                                B2A1F2AA0CEF0ABF00442F6A /* SVGFontElement.cpp in Sources */,
                                B2227A140D00BF220071B782 /* SVGFontFaceElement.cpp in Sources */,
index b0f7365..62ff56f 100644 (file)
@@ -154,7 +154,7 @@ SimpleFontData* CSSFontFaceSource::getFontData(const FontDescription& fontDescri
                         m_svgFontFaceElement = fontFaceElement;
                     }
 
-                    fontData = adoptPtr(new SimpleFontData(adoptPtr(new SVGFontData(fontFaceElement)), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic));
+                    fontData = adoptPtr(new SimpleFontData(SVGFontData::create(fontFaceElement), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic));
                 }
             } else
 #endif
@@ -170,7 +170,7 @@ SimpleFontData* CSSFontFaceSource::getFontData(const FontDescription& fontDescri
 #if ENABLE(SVG_FONTS)
             // In-Document SVG Fonts
             if (m_svgFontFaceElement)
-                fontData = adoptPtr(new SimpleFontData(adoptPtr(new SVGFontData(m_svgFontFaceElement.get())), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic));
+                fontData = adoptPtr(new SimpleFontData(SVGFontData::create(m_svgFontFaceElement.get()), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic));
 #endif
         }
     } else {
index d2ce853..e1d6dcc 100644 (file)
@@ -136,8 +136,8 @@ void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoi
     to = (to == -1 ? run.length() : to);
 
 #if ENABLE(SVG_FONTS)
-    if (primaryFont()->isSVGFont()) {
-        drawTextUsingSVGFont(context, run, point, from, to);
+    if (TextRun::RenderingContext* renderingContext = run.renderingContext()) {
+        renderingContext->drawTextUsingSVGFont(*this, context, run, point, from, to);
         return;
     }
 #endif
@@ -178,8 +178,8 @@ void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const
 float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
 {
 #if ENABLE(SVG_FONTS)
-    if (primaryFont()->isSVGFont())
-        return floatWidthUsingSVGFont(run);
+    if (TextRun::RenderingContext* renderingContext = run.renderingContext())
+        return renderingContext->floatWidthUsingSVGFont(*this, run);
 #endif
 
     CodePath codePathToUse = codePath(run);
@@ -195,11 +195,11 @@ float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFo
 
 float Font::width(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const
 {
-#if !ENABLE(SVG_FONTS)
-    UNUSED_PARAM(extraCharsAvailable);
+#if ENABLE(SVG_FONTS)
+    if (TextRun::RenderingContext* renderingContext = run.renderingContext())
+        return renderingContext->floatWidthUsingSVGFont(*this, run, extraCharsAvailable, charsConsumed, glyphName);
 #else
-    if (primaryFont()->isSVGFont())
-        return floatWidthUsingSVGFont(run, extraCharsAvailable, charsConsumed, glyphName);
+    UNUSED_PARAM(extraCharsAvailable);
 #endif
 
     charsConsumed = run.length();
@@ -214,10 +214,10 @@ float Font::width(const TextRun& run, int extraCharsAvailable, int& charsConsume
 FloatRect Font::selectionRectForText(const TextRun& run, const FloatPoint& point, int h, int from, int to) const
 {
 #if ENABLE(SVG_FONTS)
-    if (primaryFont()->isSVGFont())
-        return selectionRectForTextUsingSVGFont(run, point, h, from, to);
+    if (TextRun::RenderingContext* renderingContext = run.renderingContext())
+        return renderingContext->selectionRectForTextUsingSVGFont(*this, run, point, h, from, to);
 #endif
-
     to = (to == -1 ? run.length() : to);
 
     if (codePath(run) != Complex)
@@ -229,8 +229,8 @@ FloatRect Font::selectionRectForText(const TextRun& run, const FloatPoint& point
 int Font::offsetForPosition(const TextRun& run, float x, bool includePartialGlyphs) const
 {
 #if ENABLE(SVG_FONTS)
-    if (primaryFont()->isSVGFont())
-        return offsetForPositionForTextUsingSVGFont(run, x, includePartialGlyphs);
+    if (TextRun::RenderingContext* renderingContext = run.renderingContext())
+        return renderingContext->offsetForPositionForTextUsingSVGFont(*this, run, x, includePartialGlyphs);
 #endif
 
     if (codePath(run) != Complex)
@@ -239,13 +239,6 @@ int Font::offsetForPosition(const TextRun& run, float x, bool includePartialGlyp
     return offsetForPositionForComplexText(run, x, includePartialGlyphs);
 }
 
-#if ENABLE(SVG_FONTS)
-bool Font::isSVGFont() const
-{ 
-    return primaryFont()->isSVGFont(); 
-}
-#endif
-
 String Font::normalizeSpaces(const UChar* characters, unsigned length)
 {
     UChar* buffer;
index cb5af7c..a4d2438 100644 (file)
@@ -50,7 +50,6 @@ class FontSelector;
 class GlyphBuffer;
 class GlyphPageTreeNode;
 class GraphicsContext;
-class SVGFontElement;
 class TextRun;
 
 struct GlyphData;
@@ -157,14 +156,6 @@ public:
     enum CodePath { Auto, Simple, Complex, SimpleWithGlyphOverflow };
 
 private:
-#if ENABLE(SVG_FONTS)
-    void drawTextUsingSVGFont(GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
-    float floatWidthUsingSVGFont(const TextRun&) const;
-    float floatWidthUsingSVGFont(const TextRun&, int extraCharsAvailable, int& charsConsumed, String& glyphName) const;
-    FloatRect selectionRectForTextUsingSVGFont(const TextRun&, const FloatPoint&, int h, int from, int to) const;
-    int offsetForPositionForTextUsingSVGFont(const TextRun&, float position, bool includePartialGlyphs) const;
-#endif
-
     enum ForTextEmphasisOrNot { NotForTextEmphasis, ForTextEmphasis };
 
     // Returns the initial in-stream advance.
@@ -220,11 +211,6 @@ public:
 
     static String normalizeSpaces(const UChar*, unsigned length);
 
-#if ENABLE(SVG_FONTS)
-    bool isSVGFont() const;
-    SVGFontElement* svgFont() const;
-#endif
-
     bool needsTranscoding() const { return m_needsTranscoding; }
 
 private:
index f772e4a..a8218d9 100644 (file)
 #include "Font.h"
 #include "FontCache.h"
 
-#if ENABLE(SVG_FONTS)
-#include "SVGFontData.h"
-#include "SVGFontElement.h"
-#include "SVGFontFaceElement.h"
-#include "SVGGlyphElement.h"
-#endif
-
 #include <wtf/MathExtras.h>
 #include <wtf/UnusedParam.h>
 
@@ -63,64 +56,18 @@ SimpleFontData::SimpleFontData(const FontPlatformData& platformData, bool isCust
     platformCharWidthInit();
 }
 
-#if ENABLE(SVG_FONTS)
-SimpleFontData::SimpleFontData(PassOwnPtr<SVGFontData> svgFontData, int size, bool syntheticBold, bool syntheticItalic)
+SimpleFontData::SimpleFontData(PassOwnPtr<SimpleFontData::FontData> fontData, int size, bool syntheticBold, bool syntheticItalic)
     : m_platformData(FontPlatformData(size, syntheticBold, syntheticItalic))
+    , m_fontData(fontData)
     , m_treatAsFixedPitch(false)
-    , m_svgFontData(svgFontData)
     , m_isCustomFont(true)
     , m_isLoading(false)
     , m_isTextOrientationFallback(false)
     , m_isBrokenIdeographFallback(false)
     , m_hasVerticalGlyphs(false)
 {
-    SVGFontFaceElement* svgFontFaceElement = m_svgFontData->svgFontFaceElement();
-    unsigned unitsPerEm = svgFontFaceElement->unitsPerEm();
-
-    float scale = size;
-    if (unitsPerEm)
-        scale /= unitsPerEm;
-
-    float xHeight = svgFontFaceElement->xHeight() * scale;
-    float ascent = svgFontFaceElement->ascent() * scale;
-    float descent = svgFontFaceElement->descent() * scale;
-    float lineGap = 0.1f * size;
-
-    SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement();
-    if (!xHeight) {    
-        // Fallback if x_heightAttr is not specified for the font element.
-        Vector<SVGGlyph> letterXGlyphs;
-        associatedFontElement->getGlyphIdentifiersForString(String("x", 1), letterXGlyphs);
-        xHeight = letterXGlyphs.isEmpty() ? 2 * ascent / 3 : letterXGlyphs.first().horizontalAdvanceX * scale;
-    }
-
-    m_fontMetrics.setUnitsPerEm(unitsPerEm);
-    m_fontMetrics.setAscent(ascent);
-    m_fontMetrics.setDescent(descent);
-    m_fontMetrics.setLineGap(lineGap);
-    m_fontMetrics.setLineSpacing(roundf(ascent) + roundf(descent) + roundf(lineGap));
-    m_fontMetrics.setXHeight(xHeight);
-
-    Vector<SVGGlyph> spaceGlyphs;
-    associatedFontElement->getGlyphIdentifiersForString(String(" ", 1), spaceGlyphs);
-    m_spaceWidth = spaceGlyphs.isEmpty() ? xHeight : spaceGlyphs.first().horizontalAdvanceX * scale;
-
-    Vector<SVGGlyph> numeralZeroGlyphs;
-    associatedFontElement->getGlyphIdentifiersForString(String("0", 1), numeralZeroGlyphs);
-    m_avgCharWidth = numeralZeroGlyphs.isEmpty() ? m_spaceWidth : numeralZeroGlyphs.first().horizontalAdvanceX * scale;
-
-    Vector<SVGGlyph> letterWGlyphs;
-    associatedFontElement->getGlyphIdentifiersForString(String("W", 1), letterWGlyphs);
-    m_maxCharWidth = letterWGlyphs.isEmpty() ? ascent : letterWGlyphs.first().horizontalAdvanceX * scale;
-
-    // FIXME: is there a way we can get the space glyph from the SVGGlyph above?
-    m_spaceGlyph = 0;
-    m_zeroWidthSpaceGlyph = 0;
-    determinePitch();
-    m_missingGlyphData.fontData = this;
-    m_missingGlyphData.glyph = 0;
+    m_fontData->initializeFontData(this, size);
 }
-#endif
 
 #if !(PLATFORM(QT) && !HAVE(QRAWFONT))
 // Estimates of avgCharWidth and maxCharWidth for platforms that don't support accessing these values from the font.
@@ -186,7 +133,7 @@ void SimpleFontData::platformGlyphInit()
 SimpleFontData::~SimpleFontData()
 {
 #if ENABLE(SVG_FONTS)
-    if (!m_svgFontData || !m_svgFontData->svgFontFaceElement())
+    if (!m_fontData)
 #endif
         platformDestroy();
 
index 8b2bed3..52e3a51 100644 (file)
@@ -64,17 +64,26 @@ namespace WebCore {
 
 class FontDescription;
 class SharedBuffer;
-class SVGFontData;
 
 enum FontDataVariant { AutoVariant, NormalVariant, SmallCapsVariant, EmphasisMarkVariant };
 enum Pitch { UnknownPitch, FixedPitch, VariablePitch };
 
 class SimpleFontData : public FontData {
 public:
+    class FontData {
+        WTF_MAKE_FAST_ALLOCATED;
+    public:
+        virtual ~FontData() { }
+    
+        virtual void initializeFontData(SimpleFontData*, int) = 0;
+    };
+
+    // Used to create platform fonts.
     SimpleFontData(const FontPlatformData&, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false);
-#if ENABLE(SVG_FONTS)
-    SimpleFontData(PassOwnPtr<SVGFontData>, int size, bool syntheticBold, bool syntheticItalic);
-#endif
+
+    // Used to create SVG Fonts.
+    SimpleFontData(PassOwnPtr<SimpleFontData::FontData>, int size, bool syntheticBold, bool syntheticItalic);
+
     virtual ~SimpleFontData();
 
     const FontPlatformData& platformData() const { return m_platformData; }
@@ -104,9 +113,14 @@ public:
     bool hasVerticalGlyphs() const { return m_hasVerticalGlyphs; }
     bool isTextOrientationFallback() const { return m_isTextOrientationFallback; }
 
+    FontMetrics& fontMetrics() { return m_fontMetrics; }
     const FontMetrics& fontMetrics() const { return m_fontMetrics; }
+    
     float maxCharWidth() const { return m_maxCharWidth; }
+    void setMaxCharWidth(float maxCharWidth) { m_maxCharWidth = maxCharWidth; }
+
     float avgCharWidth() const { return m_avgCharWidth; }
+    void setAvgCharWidth(float avgCharWidth) { m_avgCharWidth = avgCharWidth; }
 
     FloatRect boundsForGlyph(Glyph) const;
     float widthForGlyph(Glyph glyph) const;
@@ -114,12 +128,15 @@ public:
     float platformWidthForGlyph(Glyph) const;
 
     float spaceWidth() const { return m_spaceWidth; }
+    void setSpaceWidth(float spaceWidth) { m_spaceWidth = spaceWidth; }
 
 #if USE(CG) || USE(CAIRO) || PLATFORM(WX) || USE(SKIA_ON_MAC_CHROME)
     float syntheticBoldOffset() const { return m_syntheticBoldOffset; }
 #endif
 
     Glyph spaceGlyph() const { return m_spaceGlyph; }
+    void setSpaceGlyph(Glyph spaceGlyph) { m_spaceGlyph = spaceGlyph; }
+    void setZeroWidthSpaceGlyph(Glyph spaceGlyph) { m_zeroWidthSpaceGlyph = spaceGlyph; }
     bool isZeroWidthSpaceGlyph(Glyph glyph) const { return glyph == m_zeroWidthSpaceGlyph && glyph; }
 
     virtual const SimpleFontData* fontDataForCharacter(UChar32) const;
@@ -128,18 +145,15 @@ public:
     void determinePitch();
     Pitch pitch() const { return m_treatAsFixedPitch ? FixedPitch : VariablePitch; }
 
-#if ENABLE(SVG_FONTS)
-    SVGFontData* svgFontData() const { return m_svgFontData.get(); }
-    bool isSVGFont() const { return m_svgFontData; }
-#else
-    bool isSVGFont() const { return false; }
-#endif
+    SimpleFontData::FontData* fontData() const { return m_fontData.get(); }
+    bool isSVGFont() const { return m_fontData; }
 
     virtual bool isCustomFont() const { return m_isCustomFont; }
     virtual bool isLoading() const { return m_isLoading; }
     virtual bool isSegmented() const;
 
     const GlyphData& missingGlyphData() const { return m_missingGlyphData; }
+    void setMissingGlyphData(const GlyphData& glyphData) { m_missingGlyphData = glyphData; }
 
 #ifndef NDEBUG
     virtual String description() const;
@@ -208,16 +222,12 @@ private:
     float m_avgCharWidth;
     
     FontPlatformData m_platformData;
+    OwnPtr<SimpleFontData::FontData> m_fontData;
 
     mutable OwnPtr<GlyphMetricsMap<FloatRect> > m_glyphToBoundsMap;
     mutable GlyphMetricsMap<float> m_glyphToWidthMap;
 
     bool m_treatAsFixedPitch;
-
-#if ENABLE(SVG_FONTS)
-    OwnPtr<SVGFontData> m_svgFontData;
-#endif
-
     bool m_isCustomFont;  // Whether or not we are custom font loaded via @font-face
     bool m_isLoading; // Whether or not this custom font is still in the act of loading.
     
index 737adf6..50ca448 100644 (file)
 #ifndef TextRun_h
 #define TextRun_h
 
-#include "PlatformString.h"
 #include "TextDirection.h"
+#include <wtf/RefCounted.h>
+#include <wtf/text/WTFString.h>
 
 namespace WebCore {
 
-class RenderObject;
-class RenderSVGResource;
+class FloatPoint;
+class FloatRect;
+class Font;
+class GraphicsContext;
 
 class TextRun {
 public:
@@ -56,10 +59,6 @@ public:
         , m_direction(direction)
         , m_directionalOverride(directionalOverride)
         , m_disableSpacing(false)
-#if ENABLE(SVG_FONTS)
-        , m_referencingRenderObject(0)
-        , m_activePaintingResource(0)
-#endif
     {
     }
 
@@ -76,10 +75,6 @@ public:
         , m_direction(direction)
         , m_directionalOverride(directionalOverride)
         , m_disableSpacing(false)
-#if ENABLE(SVG_FONTS)
-        , m_referencingRenderObject(0)
-        , m_activePaintingResource(0)
-#endif
     {
     }
 
@@ -97,7 +92,9 @@ public:
 #endif
 
     bool allowTabs() const { return m_allowTabs; }
+    void setAllowTabs(bool allowTabs) { m_allowTabs = allowTabs; }
     float xPos() const { return m_xpos; }
+    void setXPos(float xPos) { m_xpos = xPos; }
     float expansion() const { return m_expansion; }
     bool allowsLeadingExpansion() const { return m_expansionBehavior & AllowLeadingExpansion; }
     bool allowsTrailingExpansion() const { return m_expansionBehavior & AllowTrailingExpansion; }
@@ -111,13 +108,22 @@ public:
     void setDirection(TextDirection direction) { m_direction = direction; }
     void setDirectionalOverride(bool override) { m_directionalOverride = override; }
 
-#if ENABLE(SVG_FONTS)
-    RenderObject* referencingRenderObject() const { return m_referencingRenderObject; }
-    void setReferencingRenderObject(RenderObject* object) { m_referencingRenderObject = object; }
+    class RenderingContext : public RefCounted<RenderingContext> {
+    public:
+        virtual ~RenderingContext() { }
 
-    RenderSVGResource* activePaintingResource() const { return m_activePaintingResource; }
-    void setActivePaintingResource(RenderSVGResource* object) { m_activePaintingResource = object; }
+#if ENABLE(SVG_FONTS)
+        // FIXME: Note that the SVG Font integration APIs will be more abstract and simpler once the SVG Fonts rewrite patch lands (59085).
+        virtual void drawTextUsingSVGFont(const Font&, GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const = 0;
+        virtual float floatWidthUsingSVGFont(const Font&, const TextRun&) const = 0;
+        virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int extraCharsAvailable, int& charsConsumed, String& glyphName) const = 0;
+        virtual FloatRect selectionRectForTextUsingSVGFont(const Font&, const TextRun&, const FloatPoint&, int h, int from, int to) const = 0;
+        virtual int offsetForPositionForTextUsingSVGFont(const Font&, const TextRun&, float position, bool includePartialGlyphs) const = 0;
 #endif
+    };
+
+    RenderingContext* renderingContext() const { return m_renderingContext.get(); }
+    void setRenderingContext(PassRefPtr<RenderingContext> context) { m_renderingContext = context; }
 
 private:
     const UChar* m_characters;
@@ -136,11 +142,7 @@ private:
     TextDirection m_direction;
     bool m_directionalOverride; // Was this direction set by an override character.
     bool m_disableSpacing;
-
-#if ENABLE(SVG_FONTS)
-    RenderObject* m_referencingRenderObject;
-    RenderSVGResource* m_activePaintingResource;
-#endif
+    RefPtr<RenderingContext> m_renderingContext;
 };
 
 }
index 6feb1dd..3ca6ae0 100644 (file)
@@ -44,8 +44,9 @@ void EllipsisBox::paint(PaintInfo& paintInfo, int tx, int ty, int lineTop, int l
         setShadow = true;
     }
 
+    const Font& font = style->font();
     if (selectionState() != RenderObject::SelectionNone) {
-        paintSelection(context, tx, ty, style, style->font());
+        paintSelection(context, tx, ty, style, font);
 
         // Select the correct color for painting the text.
         Color foreground = paintInfo.forceBlackText ? Color::black : renderer()->selectionForegroundColor();
@@ -54,7 +55,7 @@ void EllipsisBox::paint(PaintInfo& paintInfo, int tx, int ty, int lineTop, int l
     }
 
     // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
-    context->drawText(style->font(), RenderBlock::constructTextRunAllowTrailingExpansion(m_str, style), IntPoint(m_x + tx, m_y + ty + style->fontMetrics().ascent()));
+    context->drawText(font, RenderBlock::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), IntPoint(m_x + tx, m_y + ty + style->fontMetrics().ascent()));
 
     // Restore the regular fill color.
     if (textColor != context->fillColor())
@@ -74,9 +75,9 @@ void EllipsisBox::paint(PaintInfo& paintInfo, int tx, int ty, int lineTop, int l
 IntRect EllipsisBox::selectionRect(int tx, int ty)
 {
     RenderStyle* style = m_renderer->style(m_firstLine);
-    const Font& f = style->font();
+    const Font& font = style->font();
     // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
-    return enclosingIntRect(f.selectionRectForText(RenderBlock::constructTextRunAllowTrailingExpansion(m_str, style), IntPoint(m_x + tx, m_y + ty + root()->selectionTop()), root()->selectionHeight()));
+    return enclosingIntRect(font.selectionRectForText(RenderBlock::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), IntPoint(m_x + tx, m_y + ty + root()->selectionTop()), root()->selectionHeight()));
 }
 
 void EllipsisBox::paintSelection(GraphicsContext* context, int tx, int ty, RenderStyle* style, const Font& font)
@@ -96,7 +97,7 @@ void EllipsisBox::paintSelection(GraphicsContext* context, int tx, int ty, Rende
     int h = root()->selectionHeight();
     context->clip(IntRect(m_x + tx, y + ty, m_logicalWidth, h));
     // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
-    context->drawHighlightForText(font, RenderBlock::constructTextRunAllowTrailingExpansion(m_str, style), IntPoint(m_x + tx, m_y + ty + y), h, c, style->colorSpace());
+    context->drawHighlightForText(font, RenderBlock::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), IntPoint(m_x + tx, m_y + ty + y), h, c, style->colorSpace());
 }
 
 bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const IntPoint& pointInContainer, int tx, int ty, int lineTop, int lineBottom)
index dedf667..62af077 100644 (file)
@@ -41,8 +41,8 @@
 #include "RenderRubyRun.h"
 #include "RenderRubyText.h"
 #include "RenderTheme.h"
+#include "SVGTextRunRenderingContext.h"
 #include "Text.h"
-#include "TextRun.h"
 #include "break_lines.h"
 #include <wtf/AlwaysInline.h>
 
@@ -182,15 +182,15 @@ IntRect InlineTextBox::selectionRect(int tx, int ty, int startPos, int endPos)
     int selTop = selectionTop();
     int selHeight = selectionHeight();
     RenderStyle* styleToUse = textObj->style(m_firstLine);
-    const Font& f = styleToUse->font();
+    const Font& font = styleToUse->font();
 
     BufferForAppendingHyphen charactersWithHyphen;
     bool respectHyphen = ePos == m_len && hasHyphen();
-    TextRun textRun = constructTextRun(styleToUse, respectHyphen ? &charactersWithHyphen : 0);
+    TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charactersWithHyphen : 0);
     if (respectHyphen)
         endPos = textRun.length();
 
-    IntRect r = enclosingIntRect(f.selectionRectForText(textRun, FloatPoint(logicalLeft(), selTop), selHeight, sPos, ePos));
+    IntRect r = enclosingIntRect(font.selectionRectForText(textRun, FloatPoint(logicalLeft(), selTop), selHeight, sPos, ePos));
 
     int logicalWidth = r.width();
     if (r.x() > logicalRight())
@@ -643,7 +643,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty, int /*lineTop*/,
         combinedText->charactersToRender(m_start, characters, length);
 
     BufferForAppendingHyphen charactersWithHyphen;
-    TextRun textRun = constructTextRun(styleToUse, characters, length, hasHyphen() ? &charactersWithHyphen : 0);
+    TextRun textRun = constructTextRun(styleToUse, font, characters, length, hasHyphen() ? &charactersWithHyphen : 0);
     if (hasHyphen())
         length = textRun.length();
 
@@ -680,7 +680,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty, int /*lineTop*/,
         if (!emphasisMark.isEmpty()) {
             updateGraphicsContext(context, emphasisMarkColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace());
 
-            static TextRun objectReplacementCharacterTextRun(&objectReplacementCharacter, 1);
+            DEFINE_STATIC_LOCAL(TextRun, objectReplacementCharacterTextRun, (&objectReplacementCharacter, 1));
             TextRun& emphasisMarkTextRun = combinedText ? objectReplacementCharacterTextRun : textRun;
             FloatPoint emphasisMarkTextOrigin = combinedText ? FloatPoint(boxOrigin.x() + boxRect.width() / 2, boxOrigin.y() + font.fontMetrics().ascent()) : textOrigin;
             if (combinedText)
@@ -706,7 +706,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, int tx, int ty, int /*lineTop*/,
         if (!emphasisMark.isEmpty()) {
             updateGraphicsContext(context, selectionEmphasisMarkColor, textStrokeColor, textStrokeWidth, styleToUse->colorSpace());
 
-            static TextRun objectReplacementCharacterTextRun(&objectReplacementCharacter, 1);
+            DEFINE_STATIC_LOCAL(TextRun, objectReplacementCharacterTextRun, (&objectReplacementCharacter, 1));
             TextRun& emphasisMarkTextRun = combinedText ? objectReplacementCharacterTextRun : textRun;
             FloatPoint emphasisMarkTextOrigin = combinedText ? FloatPoint(boxOrigin.x() + boxRect.width() / 2, boxOrigin.y() + font.fontMetrics().ascent()) : textOrigin;
             if (combinedText)
@@ -808,7 +808,7 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& b
 
     BufferForAppendingHyphen charactersWithHyphen;
     bool respectHyphen = ePos == length && hasHyphen();
-    TextRun textRun = constructTextRun(style, characters, length, respectHyphen ? &charactersWithHyphen : 0);
+    TextRun textRun = constructTextRun(style, font, characters, length, respectHyphen ? &charactersWithHyphen : 0);
     if (respectHyphen)
         ePos = textRun.length();
 
@@ -843,7 +843,7 @@ void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const F
     int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
     int selHeight = selectionHeight();
     FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
-    context->drawHighlightForText(font, constructTextRun(style), localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
+    context->drawHighlightForText(font, constructTextRun(style, font), localOrigin, selHeight, c, style->colorSpace(), sPos, ePos);
 }
 
 #if PLATFORM(MAC)
@@ -1001,7 +1001,7 @@ void InlineTextBox::paintSpellingOrGrammarMarker(GraphicsContext* pt, const Floa
         int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
         int selHeight = selectionHeight();
         FloatPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
-        TextRun run = constructTextRun(style);
+        TextRun run = constructTextRun(style, font);
 
         // FIXME: Convert the document markers to float rects.
         IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, startPoint, selHeight, startPosition, endPosition));
@@ -1046,7 +1046,7 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint&
 
     int sPos = max(marker.startOffset() - m_start, (unsigned)0);
     int ePos = min(marker.endOffset() - m_start, (unsigned)m_len);
-    TextRun run = constructTextRun(style);
+    TextRun run = constructTextRun(style, font);
     // Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
     IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(m_x, selectionTop()), selHeight, sPos, ePos));
     markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
@@ -1073,7 +1073,7 @@ void InlineTextBox::computeRectForReplacementMarker(const DocumentMarker& marker
 
     int sPos = max(marker.startOffset() - m_start, (unsigned)0);
     int ePos = min(marker.endOffset() - m_start, (unsigned)m_len);
-    TextRun run = constructTextRun(style);
+    TextRun run = constructTextRun(style, font);
     IntPoint startPoint = IntPoint(m_x, y);
     
     // Compute and store the rect associated with this marker.
@@ -1232,8 +1232,8 @@ int InlineTextBox::offsetForPosition(float lineOffset, bool includePartialGlyphs
 
     RenderText* text = toRenderText(renderer());
     RenderStyle* style = text->style(m_firstLine);
-    const Font* f = &style->font();
-    int offset = f->offsetForPosition(constructTextRun(style), lineOffset - logicalLeft(), includePartialGlyphs);
+    const Font& font = style->font();
+    int offset = font.offsetForPosition(constructTextRun(style, font), lineOffset - logicalLeft(), includePartialGlyphs);
     if (blockIsInOppositeDirection && (!offset || offset == m_len))
         return !offset ? m_len : 0;
     return offset;
@@ -1250,11 +1250,11 @@ float InlineTextBox::positionForOffset(int offset) const
     RenderText* text = toRenderText(renderer());
     RenderStyle* styleToUse = text->style(m_firstLine);
     ASSERT(styleToUse);
-    const Font& f = styleToUse->font();
+    const Font& font = styleToUse->font();
     int from = !isLeftToRightDirection() ? offset - m_start : 0;
     int to = !isLeftToRightDirection() ? m_len : offset - m_start;
     // FIXME: Do we need to add rightBearing here?
-    return f.selectionRectForText(constructTextRun(styleToUse), IntPoint(logicalLeft(), 0), 0, from, to).maxX();
+    return font.selectionRectForText(constructTextRun(styleToUse, font), IntPoint(logicalLeft(), 0), 0, from, to).maxX();
 }
 
 bool InlineTextBox::containsCaretOffset(int offset) const
@@ -1281,7 +1281,7 @@ bool InlineTextBox::containsCaretOffset(int offset) const
     return true;
 }
 
-TextRun InlineTextBox::constructTextRun(RenderStyle* style, BufferForAppendingHyphen* charactersWithHyphen) const
+TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, BufferForAppendingHyphen* charactersWithHyphen) const
 {
     ASSERT(style);
 
@@ -1289,10 +1289,10 @@ TextRun InlineTextBox::constructTextRun(RenderStyle* style, BufferForAppendingHy
     ASSERT(textRenderer);
     ASSERT(textRenderer->characters());
 
-    return constructTextRun(style, textRenderer->characters() + start(), len(), charactersWithHyphen);
+    return constructTextRun(style, font, textRenderer->characters() + start(), len(), charactersWithHyphen);
 }
 
-TextRun InlineTextBox::constructTextRun(RenderStyle* style, const UChar* characters, int length, BufferForAppendingHyphen* charactersWithHyphen) const
+TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, const UChar* characters, int length, BufferForAppendingHyphen* charactersWithHyphen) const
 {
     ASSERT(style);
 
@@ -1302,8 +1302,11 @@ TextRun InlineTextBox::constructTextRun(RenderStyle* style, const UChar* charact
     if (charactersWithHyphen)
         adjustCharactersAndLengthForHyphen(*charactersWithHyphen, style, characters, length);
 
-    // FIXME: Remove TextRuns all-in-one-constructor and use explicit setters here.
-    return TextRun(characters, length, textRenderer->allowTabs(), textPos(), expansion(), expansionBehavior(), direction(), m_dirOverride || style->visuallyOrdered());
+    TextRun run(characters, length, textRenderer->allowTabs(), textPos(), expansion(), expansionBehavior(), direction(), m_dirOverride || style->visuallyOrdered());
+    if (textRunNeedsRenderingContext(font))
+        run.setRenderingContext(SVGTextRunRenderingContext::create(textRenderer));
+
+    return run;
 }
 
 #ifndef NDEBUG
index c8a9cc0..e11e5df 100644 (file)
@@ -99,8 +99,8 @@ private:
     int selectionBottom();
     int selectionHeight();
 
-    TextRun constructTextRun(RenderStyle*, BufferForAppendingHyphen* = 0) const;
-    TextRun constructTextRun(RenderStyle*, const UChar*, int length, BufferForAppendingHyphen* = 0) const;
+    TextRun constructTextRun(RenderStyle*, const Font&, BufferForAppendingHyphen* = 0) const;
+    TextRun constructTextRun(RenderStyle*, const Font&, const UChar*, int length, BufferForAppendingHyphen* = 0) const;
 
 public:
     virtual IntRect calculateBoundaries() const { return IntRect(x(), y(), width(), height()); }
index 4a87f3b..b086d0d 100644 (file)
@@ -51,7 +51,7 @@
 #include "RenderTheme.h"
 #include "RenderView.h"
 #include "Settings.h"
-#include "TextRun.h"
+#include "SVGTextRunRenderingContext.h"
 #include "TransformState.h"
 #include <wtf/StdLibExtras.h>
 
@@ -4707,7 +4707,7 @@ static inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
         RenderText* t = toRenderText(trailingSpaceChild);
         const UChar space = ' ';
         const Font& font = t->style()->font(); // FIXME: This ignores first-line.
-        float spaceWidth = font.width(TextRun(&space, 1));
+        float spaceWidth = font.width(RenderBlock::constructTextRun(t, font, &space, 1, t->style()));
         inlineMax -= spaceWidth + font.wordSpacing();
         if (inlineMin > inlineMax)
             inlineMin = inlineMax;
@@ -6316,7 +6316,7 @@ inline void RenderBlock::FloatingObjects::decreaseObjectsCount(FloatingObject::T
         m_rightObjectsCount--;
 }
 
-TextRun RenderBlock::constructTextRunAllowTrailingExpansion(const UChar* characters, int length, RenderStyle* style, TextRunFlags flags)
+TextRun RenderBlock::constructTextRun(RenderObject* context, const Font& font, const UChar* characters, int length, RenderStyle* style, TextRun::ExpansionBehavior expansion, TextRunFlags flags)
 {
     ASSERT(style);
 
@@ -6329,13 +6329,16 @@ TextRun RenderBlock::constructTextRunAllowTrailingExpansion(const UChar* charact
             directionalOverride |= style->unicodeBidi() == Override;
     }
 
-    // FIXME: Remove TextRuns all-in-one-constructor and use explicit setters here.
-    return TextRun(characters, length, false, 0, 0, TextRun::AllowTrailingExpansion, textDirection, directionalOverride);
+    TextRun run(characters, length, false, 0, 0, expansion, textDirection, directionalOverride);
+    if (textRunNeedsRenderingContext(font))
+        run.setRenderingContext(SVGTextRunRenderingContext::create(context));
+
+    return run;
 }
 
-TextRun RenderBlock::constructTextRunAllowTrailingExpansion(const String& string, RenderStyle* style, TextRunFlags flags)
+TextRun RenderBlock::constructTextRun(RenderObject* context, const Font& font, const String& string, RenderStyle* style, TextRun::ExpansionBehavior expansion, TextRunFlags flags)
 {
-    return constructTextRunAllowTrailingExpansion(string.characters(), string.length(), style, flags);
+    return constructTextRun(context, font, string.characters(), string.length(), style, expansion, flags);
 }
 
 #ifndef NDEBUG
index cc04a61..4b7d4ad 100644 (file)
@@ -27,6 +27,7 @@
 #include "RenderBox.h"
 #include "RenderLineBoxList.h"
 #include "RootInlineBox.h"
+#include "TextRun.h"
 #include <wtf/OwnPtr.h>
 #include <wtf/ListHashSet.h>
 
@@ -169,8 +170,11 @@ public:
     
     static void appendRunsForObject(BidiRunList<BidiRun>&, int start, int end, RenderObject*, InlineBidiResolver&);
 
-    static TextRun constructTextRunAllowTrailingExpansion(const String&, RenderStyle*, TextRunFlags = DefaultTextRunFlags);
-    static TextRun constructTextRunAllowTrailingExpansion(const UChar*, int length, RenderStyle*, TextRunFlags = DefaultTextRunFlags);
+    static TextRun constructTextRun(RenderObject* context, const Font&, const String&, RenderStyle*,
+                                    TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags);
+
+    static TextRun constructTextRun(RenderObject* context, const Font&, const UChar*, int length, RenderStyle*,
+                                    TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags);
 
     ColumnInfo* columnInfo() const;
     int columnGap() const;
index 39479b2..1d48665 100644 (file)
@@ -36,7 +36,6 @@
 #include "RenderView.h"
 #include "Settings.h"
 #include "TextBreakIterator.h"
-#include "TextRun.h"
 #include "TrailingFloatsRootInlineBox.h"
 #include "VerticalPositionCache.h"
 #include "break_lines.h"
@@ -482,7 +481,8 @@ static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* ru
     int hyphenWidth = 0;
     if (static_cast<InlineTextBox*>(run->m_box)->hasHyphen()) {
         const AtomicString& hyphenString = renderer->style()->hyphenString();
-        hyphenWidth = renderer->style(lineInfo.isFirstLine())->font().width(TextRun(hyphenString.characters(), hyphenString.length()));
+        const Font& font = renderer->style(lineInfo.isFirstLine())->font();
+        hyphenWidth = font.width(RenderBlock::constructTextRun(renderer, font, hyphenString.string(), renderer->style()));
     }
     run->m_box->setLogicalWidth(renderer->width(run->m_start, run->m_stop - run->m_start, xPos, lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow) + hyphenWidth);
     if (!fallbackFonts.isEmpty()) {
@@ -1576,7 +1576,10 @@ static inline float textWidth(RenderText* text, unsigned from, unsigned len, con
 {
     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));
+    TextRun run = RenderBlock::constructTextRun(text, font, text->characters() + from, len, text->style());
+    run.setAllowTabs(!collapseWhiteSpace);
+    run.setXPos(xPos);
+    return font.width(run);
 }
 
 static void tryHyphenating(RenderText* text, const Font& font, const AtomicString& localeIdentifier, int minimumPrefixLength, int minimumSuffixLength, int lastSpace, int pos, float xPos, int availableWidth, bool isFixedPitch, bool collapseWhiteSpace, int lastSpaceWordSpacing, InlineIterator& lineBreak, int nextBreakable, bool& hyphenated)
@@ -1592,7 +1595,7 @@ static void tryHyphenating(RenderText* text, const Font& font, const AtomicStrin
         return;
 
     const AtomicString& hyphenString = text->style()->hyphenString();
-    int hyphenWidth = font.width(TextRun(hyphenString.characters(), hyphenString.length()));
+    int hyphenWidth = font.width(RenderBlock::constructTextRun(text, font, hyphenString.string(), text->style()));
 
     float maxPrefixWidth = availableWidth - xPos - hyphenWidth - lastSpaceWordSpacing;
     // If the maximum width available for the prefix before the hyphen is small, then it is very unlikely
@@ -1600,7 +1603,11 @@ static void tryHyphenating(RenderText* text, const Font& font, const AtomicStrin
     if (maxPrefixWidth <= font.pixelSize() * 5 / 4)
         return;
 
-    unsigned prefixLength = font.offsetForPosition(TextRun(text->characters() + lastSpace, pos - lastSpace, !collapseWhiteSpace, xPos + lastSpaceWordSpacing), maxPrefixWidth, false);
+    TextRun run = RenderBlock::constructTextRun(text, font, text->characters() + lastSpace, pos - lastSpace, text->style());
+    run.setAllowTabs(!collapseWhiteSpace);
+    run.setXPos(xPos + lastSpaceWordSpacing);
+
+    unsigned prefixLength = font.offsetForPosition(run, maxPrefixWidth, false);
     if (prefixLength < static_cast<unsigned>(minimumPrefixLength))
         return;
 
@@ -2043,7 +2050,7 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol
 
             // Non-zero only when kerning is enabled, in which case we measure words with their trailing
             // space, then subtract its width.
-            float wordTrailingSpaceWidth = f.typesettingFeatures() & Kerning ? f.width(TextRun(&space, 1)) + wordSpacing : 0;
+            float wordTrailingSpaceWidth = f.typesettingFeatures() & Kerning ? f.width(constructTextRun(t, f, &space, 1, style)) + wordSpacing : 0;
 
             float wrapW = width.uncommittedWidth() + inlineLogicalWidth(current.m_obj, !appliedStartWidth, true);
             float charWidth = 0;
@@ -2072,7 +2079,7 @@ InlineIterator RenderBlock::LineBreaker::nextLineBreak(InlineBidiResolver& resol
 
                 if (c == softHyphen && autoWrap && !hyphenWidth && style->hyphens() != HyphensNone) {
                     const AtomicString& hyphenString = style->hyphenString();
-                    hyphenWidth = f.width(TextRun(hyphenString.characters(), hyphenString.length()));
+                    hyphenWidth = f.width(constructTextRun(t, f, hyphenString.string(), current.m_obj->style()));
                     width.addUncommittedWidth(hyphenWidth);
                 }
 
@@ -2403,12 +2410,11 @@ void RenderBlock::checkLinesForTextOverflow()
 {
     // Determine the width of the ellipsis using the current font.
     // FIXME: CSS3 says this is configurable, also need to use 0x002E (FULL STOP) if horizontal ellipsis is "not renderable"
-    TextRun ellipsisRun(&horizontalEllipsis, 1);
+    const Font& font = style()->font();
     DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1));
     const Font& firstLineFont = firstLineStyle()->font();
-    const Font& font = style()->font();
-    int firstLineEllipsisWidth = firstLineFont.width(ellipsisRun);
-    int ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : font.width(ellipsisRun);
+    int firstLineEllipsisWidth = firstLineFont.width(constructTextRun(this, firstLineFont, &horizontalEllipsis, 1, firstLineStyle()));
+    int ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : font.width(constructTextRun(this, font, &horizontalEllipsis, 1, style()));
 
     // For LTR text truncation, we want to get the right edge of our padding box, and then we want to see
     // if the right edge of a line box exceeds that.  For RTL, we use the left edge of the padding box and
index 37ca1ed..c79886a 100644 (file)
@@ -21,7 +21,7 @@
 #include "config.h"
 #include "RenderCombineText.h"
 
-#include "TextRun.h"
+#include "RenderBlock.h"
 
 namespace WebCore {
 
@@ -93,7 +93,7 @@ void RenderCombineText::combineText()
     if (style()->isHorizontalWritingMode())
         return;
 
-    TextRun run = TextRun(String(text()));
+    TextRun run = RenderBlock::constructTextRun(this, originalFont(), String(text()), style());
     FontDescription description = originalFont().fontDescription();
     float emWidth = description.computedSize() * textCombineMargin;
     bool shouldUpdateFont = false;
index c6a4ecc..47d76bd 100644 (file)
@@ -221,7 +221,8 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
 
     if (paintInfo.phase == PaintPhaseForeground) {
         const String& displayedFilename = fileTextValue();
-        TextRun textRun = constructTextRunAllowTrailingExpansion(displayedFilename, style(), RespectDirection | RespectDirectionOverride);
+        const Font& font = style()->font();
+        TextRun textRun = constructTextRun(this, font, displayedFilename, style(), TextRun::AllowTrailingExpansion, RespectDirection | RespectDirectionOverride);
 
         // Determine where the filename should be placed
         int contentLeft = tx + borderLeft() + paddingLeft();
@@ -231,7 +232,7 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
         if (style()->isLeftToRightDirection())
             textX = contentLeft + buttonAndIconWidth;
         else
-            textX = contentLeft + contentWidth() - buttonAndIconWidth - style()->font().width(textRun);
+            textX = contentLeft + contentWidth() - buttonAndIconWidth - font.width(textRun);
         // We want to match the button's baseline
         RenderButton* buttonRenderer = toRenderButton(m_button->renderer());
         int textY = buttonRenderer->absoluteBoundingBoxRect().y()
@@ -241,7 +242,7 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, int tx, int ty)
         paintInfo.context->setFillColor(style()->visitedDependentColor(CSSPropertyColor), style()->colorSpace());
         
         // Draw the filename
-        paintInfo.context->drawBidiText(style()->font(), textRun, IntPoint(textX, textY));
+        paintInfo.context->drawBidiText(font, textRun, IntPoint(textX, textY));
         
         if (m_fileChooser->icon()) {
             // Determine where the icon should be placed
@@ -271,13 +272,14 @@ void RenderFileUploadControl::computePreferredLogicalWidths()
     RenderStyle* style = this->style();
     ASSERT(style);
 
+    const Font& font = style->font();
     if (style->width().isFixed() && style->width().value() > 0)
         m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeContentBoxLogicalWidth(style->width().value());
     else {
         // 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().width(constructTextRunAllowTrailingExpansion(String(&ch, 1), style));
+        float charWidth = font.width(constructTextRun(this, font, String(&ch, 1), style, TextRun::AllowTrailingExpansion));
         m_maxPreferredLogicalWidth = (int)ceilf(charWidth * defaultWidthNumChars);
     }
 
index f31f78d..00b17da 100644 (file)
@@ -27,7 +27,6 @@
 
 #include "RenderLayer.h"
 #include "RenderView.h"
-#include "TextRun.h"
 #include <wtf/StdLibExtras.h>
 #include <wtf/unicode/CharacterNames.h>
 
@@ -902,10 +901,10 @@ void RenderFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool relayoutC
         int totalWidth;
         InlineBox* anchorBox = lastLine->lastChild();
         if (anchorBox && anchorBox->renderer()->style()->isLink())
-            totalWidth = anchorBox->logicalWidth() + font.width(TextRun(ellipsisAndSpace, 2));
+            totalWidth = anchorBox->logicalWidth() + font.width(constructTextRun(this, font, ellipsisAndSpace, 2, style()));
         else {
             anchorBox = 0;
-            totalWidth = font.width(TextRun(&horizontalEllipsis, 1));
+            totalWidth = font.width(constructTextRun(this, font, &horizontalEllipsis, 1, style()));
         }
 
         // See if this width can be accommodated on the last visible line
index 3f9ae67..d34069e 100644 (file)
@@ -39,7 +39,6 @@
 #include "Page.h"
 #include "RenderLayer.h"
 #include "RenderView.h"
-#include "TextRun.h"
 #include <wtf/UnusedParam.h>
 
 using namespace std;
@@ -104,7 +103,7 @@ bool RenderImage::setImageSizeForAltText(CachedImage* newImage /* = 0 */)
     // we have an alt and the user meant it (its not a text we invented)
     if (!m_altText.isEmpty()) {
         const Font& font = style()->font();
-        IntSize textSize(min(font.width(TextRun(m_altText)), maxAltTextWidth), min(font.fontMetrics().height(), maxAltTextHeight));
+        IntSize textSize(min(font.width(RenderBlock::constructTextRun(this, font, m_altText, style())), maxAltTextWidth), min(font.fontMetrics().height(), maxAltTextHeight));
         imageSize = imageSize.expandedTo(textSize);
     }
 
@@ -286,7 +285,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
 
                 // Only draw the alt text if it'll fit within the content box,
                 // and only if it fits above the error image.
-                TextRun textRun(text);
+                TextRun textRun = RenderBlock::constructTextRun(this, font, text, style());
                 int textWidth = font.width(textRun);
                 if (errorPictureDrawn) {
                     if (usableWidth >= textWidth && fontMetrics.height() <= imageY)
index b779bf6..f03fd54 100644 (file)
@@ -56,7 +56,6 @@
 #include "ScrollbarTheme.h"
 #include "SelectElement.h"
 #include "SpatialNavigation.h"
-#include "TextRun.h"
 #include <math.h>
 
 using namespace std;
@@ -120,7 +119,7 @@ void RenderListBox::updateFromElement()
 
             if (!text.isEmpty()) {
                 // FIXME: Why is this always LTR? Can't text direction affect the width?
-                float textWidth = itemFont.width(constructTextRunAllowTrailingExpansion(text, style()));
+                float textWidth = itemFont.width(constructTextRun(this, itemFont, text, style(), TextRun::AllowTrailingExpansion));
                 width = max(width, textWidth);
             }
         }
index 4d3b660..73406f1 100644 (file)
@@ -31,7 +31,6 @@
 #include "RenderLayer.h"
 #include "RenderListItem.h"
 #include "RenderView.h"
-#include "TextRun.h"
 #include <wtf/unicode/CharacterNames.h>
 
 using namespace std;
@@ -1253,7 +1252,8 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
     if (m_text.isEmpty())
         return;
 
-    TextRun textRun(m_text);
+    const Font& font = style()->font();
+    TextRun textRun = RenderBlock::constructTextRun(this, font, m_text, style());
 
     GraphicsContextStateSaver stateSaver(*context, false);
     if (!style()->isHorizontalWritingMode()) {
@@ -1269,7 +1269,7 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
     IntPoint textOrigin = IntPoint(marker.x(), marker.y() + style()->fontMetrics().ascent());
 
     if (type == Asterisks || type == Footnotes)
-        context->drawText(style()->font(), textRun, textOrigin);
+        context->drawText(font, textRun, textOrigin);
     else {
         // Text is not arbitrary. We can judge whether it's RTL from the first character,
         // and we only need to handle the direction RightToLeft for now.
@@ -1280,22 +1280,21 @@ void RenderListMarker::paint(PaintInfo& paintInfo, int tx, int ty)
             reversedText.grow(length);
             for (int i = 0; i < length; ++i)
                 reversedText[length - i - 1] = m_text[i];
-            textRun = TextRun(reversedText.data(), length);
+            textRun.setText(reversedText.data(), length);
         }
 
-        const Font& font = style()->font();
         const UChar suffix = listMarkerSuffix(type, m_listItem->value());
         if (style()->isLeftToRightDirection()) {
             int width = font.width(textRun);
-            context->drawText(style()->font(), textRun, textOrigin);
+            context->drawText(font, textRun, textOrigin);
             UChar suffixSpace[2] = { suffix, ' ' };
-            context->drawText(style()->font(), TextRun(suffixSpace, 2), textOrigin + IntSize(width, 0));
+            context->drawText(font, RenderBlock::constructTextRun(this, font, suffixSpace, 2, style()), textOrigin + IntSize(width, 0));
         } else {
             UChar spaceSuffix[2] = { ' ', suffix };
-            TextRun spaceSuffixRun(spaceSuffix, 2);
+            TextRun spaceSuffixRun = RenderBlock::constructTextRun(this, font, spaceSuffix, 2, style());
             int width = font.width(spaceSuffixRun);
-            context->drawText(style()->font(), spaceSuffixRun, textOrigin);
-            context->drawText(style()->font(), textRun, textOrigin + IntSize(width, 0));
+            context->drawText(font, spaceSuffixRun, textOrigin);
+            context->drawText(font, textRun, textOrigin + IntSize(width, 0));
         }
     }
 }
@@ -1455,7 +1454,7 @@ void RenderListMarker::computePreferredLogicalWidths()
             else {
                 int itemWidth = font.width(m_text);
                 UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' };
-                int suffixSpaceWidth = font.width(TextRun(suffixSpace, 2));
+                int suffixSpaceWidth = font.width(RenderBlock::constructTextRun(this, font, suffixSpace, 2, style()));
                 logicalWidth = itemWidth + suffixSpaceWidth;
             }
             break;
@@ -1678,7 +1677,7 @@ IntRect RenderListMarker::getRelativeMarkerRect()
             const Font& font = style()->font();
             int itemWidth = font.width(m_text);
             UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' };
-            int suffixSpaceWidth = font.width(TextRun(suffixSpace, 2));
+            int suffixSpaceWidth = font.width(RenderBlock::constructTextRun(this, font, suffixSpace, 2, style()));
             relativeRect = IntRect(0, 0, itemWidth + suffixSpaceWidth, font.fontMetrics().height());
     }
 
index 7f1be55..099d0f0 100644 (file)
@@ -40,7 +40,6 @@
 #include "Text.h"
 #include "TextBreakIterator.h"
 #include "TextResourceDecoder.h"
-#include "TextRun.h"
 #include "VisiblePosition.h"
 #include "break_lines.h"
 #include <wtf/AlwaysInline.h>
@@ -631,7 +630,10 @@ ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len
         return w;
     }
 
-    return f.width(TextRun(text()->characters() + start, len, allowTabs(), xPos), fallbackFonts, glyphOverflow);
+    TextRun run = RenderBlock::constructTextRun(const_cast<RenderText*>(this), f, text()->characters() + start, len, style());
+    run.setAllowTabs(allowTabs());
+    run.setXPos(xPos);
+    return f.width(run, fallbackFonts, glyphOverflow);
 }
 
 void RenderText::trimmedPrefWidths(float leadWidth,
@@ -676,13 +678,13 @@ void RenderText::trimmedPrefWidths(float leadWidth,
     ASSERT(m_text);
     StringImpl& text = *m_text.impl();
     if (text[0] == ' ' || (text[0] == '\n' && !style()->preserveNewline()) || text[0] == '\t') {
-        const Font& f = style()->font(); // FIXME: This ignores first-line.
+        const Font& font = style()->font(); // FIXME: This ignores first-line.
         if (stripFrontSpaces) {
             const UChar space = ' ';
-            float spaceWidth = f.width(TextRun(&space, 1));
+            float spaceWidth = font.width(RenderBlock::constructTextRun(this, font, &space, 1, style()));
             maxW -= spaceWidth;
         } else
-            maxW += f.wordSpacing();
+            maxW += font.wordSpacing();
     }
 
     stripFrontSpaces = collapseWhiteSpace && m_hasEndWS;
@@ -915,7 +917,11 @@ void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
                     m_maxWidth = currMaxWidth;
                 currMaxWidth = 0;
             } else {
-                currMaxWidth += f.width(TextRun(txt + i, 1, allowTabs(), leadWidth + currMaxWidth));
+                TextRun run = RenderBlock::constructTextRun(this, f, txt + i, 1, style());
+                run.setAllowTabs(allowTabs());
+                run.setXPos(leadWidth + currMaxWidth);
+
+                currMaxWidth += f.width(run);
                 glyphOverflow.right = 0;
                 needsWordSpacing = isSpace && !previousCharacterIsSpace && i == len - 1;
             }
@@ -1289,8 +1295,12 @@ float RenderText::width(unsigned from, unsigned len, const Font& f, float xPos,
                 w = maxLogicalWidth();
         } else
             w = widthFromCache(f, from, len, xPos, fallbackFonts, glyphOverflow);
-    } else
-        w = f.width(TextRun(text()->characters() + from, len, allowTabs(), xPos), fallbackFonts, glyphOverflow);
+    } else {
+        TextRun run = RenderBlock::constructTextRun(const_cast<RenderText*>(this), f, text()->characters() + from, len, style());
+        run.setAllowTabs(allowTabs());
+        run.setXPos(xPos);
+        w = f.width(run, fallbackFonts, glyphOverflow);
+    }
 
     return w;
 }
index 8937681..58d0450 100644 (file)
@@ -40,7 +40,6 @@
 #include "Text.h"
 #include "TextControlInnerElements.h"
 #include "TextIterator.h"
-#include "TextRun.h"
 #include <wtf/unicode/CharacterNames.h>
 
 using namespace std;
@@ -534,7 +533,8 @@ float RenderTextControl::getAvgCharWidth(AtomicString family)
         return roundf(style()->font().primaryFont()->avgCharWidth());
 
     const UChar ch = '0';
-    return style()->font().width(constructTextRunAllowTrailingExpansion(String(&ch, 1), style()));
+    const Font& font = style()->font();
+    return font.width(constructTextRun(this, font, String(&ch, 1), style(), TextRun::AllowTrailingExpansion));
 }
 
 float RenderTextControl::scaleEmToUnits(int x) const
index 9f3d8a5..9ea3be5 100644 (file)
@@ -72,5 +72,6 @@
 #include "SVGTextLayoutEngine.cpp"
 #include "SVGTextLayoutEngineBaseline.cpp"
 #include "SVGTextLayoutEngineSpacing.cpp"
+#include "SVGTextRunRenderingContext.cpp"
 #include "SVGTextMetrics.cpp"
 #include "SVGTextQuery.cpp"
index 4d36c82..2d8ea92 100644 (file)
@@ -32,7 +32,7 @@
 #include "RenderSVGResourceSolidColor.h"
 #include "SVGImageBufferTools.h"
 #include "SVGRootInlineBox.h"
-#include "TextRun.h"
+#include "SVGTextRunRenderingContext.h"
 
 using namespace std;
 
@@ -66,7 +66,7 @@ int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragmen
     RenderStyle* style = textRenderer->style();
     ASSERT(style);
 
-    TextRun textRun(constructTextRun(style, fragment));
+    TextRun textRun = constructTextRun(style, fragment);
 
     // Eventually handle lengthAdjust="spacingAndGlyphs".
     // FIXME: Handle vertical text.
@@ -379,14 +379,17 @@ void SVGInlineTextBox::releasePaintingResource(GraphicsContext*& context, const
 bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& context, float scalingFactor, TextRun& textRun, RenderStyle* style)
 {
     bool acquiredResource = acquirePaintingResource(context, scalingFactor, parent()->renderer(), style);
+    if (!acquiredResource)
+        return false;
 
 #if ENABLE(SVG_FONTS)
     // SVG Fonts need access to the painting resource used to draw the current text chunk.
-    if (acquiredResource)
-        textRun.setActivePaintingResource(m_paintingResource);
+    TextRun::RenderingContext* renderingContext = textRun.renderingContext();
+    if (renderingContext)
+        static_cast<SVGTextRunRenderingContext*>(renderingContext)->setActivePaintingResource(m_paintingResource);
 #endif
 
-    return acquiredResource;
+    return true;
 }
 
 void SVGInlineTextBox::restoreGraphicsContextAfterTextPainting(GraphicsContext*& context, TextRun& textRun)
@@ -394,7 +397,11 @@ void SVGInlineTextBox::restoreGraphicsContextAfterTextPainting(GraphicsContext*&
     releasePaintingResource(context, /* path */0);
 
 #if ENABLE(SVG_FONTS)
-    textRun.setActivePaintingResource(0);
+    TextRun::RenderingContext* renderingContext = textRun.renderingContext();
+    if (renderingContext)
+        static_cast<SVGTextRunRenderingContext*>(renderingContext)->setActivePaintingResource(0);
+#else
+    UNUSED_PARAM(textRun);
 #endif
 }
 
@@ -415,9 +422,8 @@ TextRun SVGInlineTextBox::constructTextRun(RenderStyle* style, const SVGTextFrag
                 , direction()
                 , m_dirOverride || style->visuallyOrdered() /* directionalOverride */);
 
-#if ENABLE(SVG_FONTS)
-    run.setReferencingRenderObject(text);
-#endif
+    if (textRunNeedsRenderingContext(style->font()))
+        run.setRenderingContext(SVGTextRunRenderingContext::create(text));
 
     // We handle letter & word spacing ourselves.
     run.disableSpacing();
@@ -659,7 +665,7 @@ void SVGInlineTextBox::paintText(GraphicsContext* context, RenderStyle* style, R
     }
 
     // Fast path if there is no selection, just draw the whole chunk part using the regular style
-    TextRun textRun(constructTextRun(style, fragment));
+    TextRun textRun = constructTextRun(style, fragment);
     if (!hasSelection || startPosition >= endPosition) {
         paintTextWithShadows(context, style, textRun, fragment, 0, fragment.length);
         return;
@@ -673,7 +679,7 @@ void SVGInlineTextBox::paintText(GraphicsContext* context, RenderStyle* style, R
     if (style != selectionStyle)
         SVGResourcesCache::clientStyleChanged(parent()->renderer(), StyleDifferenceRepaint, selectionStyle);
 
-    TextRun selectionTextRun(constructTextRun(selectionStyle, fragment));
+    TextRun selectionTextRun = constructTextRun(selectionStyle, fragment);
     paintTextWithShadows(context, selectionStyle, textRun, fragment, startPosition, endPosition);
 
     if (style != selectionStyle)
index e9aa127..bb8ef12 100644 (file)
@@ -26,7 +26,9 @@
 #include "SVGRenderStyle.h"
 
 #if ENABLE(SVG_FONTS)
+#include "SVGFontData.h"
 #include "SVGFontElement.h"
+#include "SVGFontFaceElement.h"
 #endif
 
 namespace WebCore {
@@ -40,13 +42,24 @@ SVGTextLayoutEngineSpacing::SVGTextLayoutEngineSpacing(const Font& font)
 float SVGTextLayoutEngineSpacing::calculateSVGKerning(bool isVerticalText, const SVGTextMetrics::Glyph& currentGlyph)
 {
 #if ENABLE(SVG_FONTS)
-    if (!m_font.isSVGFont()) {
+    const SimpleFontData* fontData = m_font.primaryFont();
+    if (!fontData->isSVGFont()) {
         m_lastGlyph.isValid = false;
         return 0;
     }
 
-    SVGFontElement* svgFont = m_font.svgFont();
-    ASSERT(svgFont);
+    ASSERT(fontData->isCustomFont());
+    ASSERT(fontData->isSVGFont());
+
+    const SVGFontData* svgFontData = static_cast<const SVGFontData*>(fontData->fontData());
+    SVGFontFaceElement* svgFontFace = svgFontData->svgFontFaceElement();
+    ASSERT(svgFontFace);
+
+    SVGFontElement* svgFont = svgFontFace->associatedFontElement();
+    if (!svgFont) {
+        m_lastGlyph.isValid = false;
+        return 0;
+    }
 
     float kerning = 0;
     if (m_lastGlyph.isValid) {
index d9d86f6..0354584 100644 (file)
@@ -23,7 +23,7 @@
 #include "SVGTextMetrics.h"
 
 #include "RenderSVGInlineText.h"
-#include "TextRun.h"
+#include "SVGTextRunRenderingContext.h"
 
 namespace WebCore {
 
@@ -86,9 +86,8 @@ static TextRun constructTextRun(RenderSVGInlineText* text, const UChar* characte
                 , style->direction()
                 , style->unicodeBidi() == Override /* directionalOverride */);
 
-#if ENABLE(SVG_FONTS)
-    run.setReferencingRenderObject(text);
-#endif
+    if (textRunNeedsRenderingContext(style->font()))
+        run.setRenderingContext(SVGTextRunRenderingContext::create(text));
 
     // We handle letter & word spacing ourselves.
     run.disableSpacing();
@@ -98,8 +97,7 @@ static TextRun constructTextRun(RenderSVGInlineText* text, const UChar* characte
 SVGTextMetrics SVGTextMetrics::measureCharacterRange(RenderSVGInlineText* text, unsigned position, unsigned length)
 {
     ASSERT(text);
-    TextRun run(constructTextRun(text, text->characters(), position, length));
-    return SVGTextMetrics(text, run, position, text->textLength());
+    return SVGTextMetrics(text, constructTextRun(text, text->characters(), position, length), position, text->textLength());
 }
 
 }
similarity index 73%
rename from Source/WebCore/svg/SVGFont.cpp
rename to Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
index 06095fe..dff687a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -36,8 +36,8 @@
 #include "SVGGlyphMap.h"
 #include "SVGMissingGlyphElement.h"
 #include "SVGNames.h"
+#include "SVGTextRunRenderingContext.h"
 #include "SimpleFontData.h"
-#include "TextRun.h"
 #include "XMLNames.h"
 
 using namespace WTF::Unicode;
@@ -59,10 +59,11 @@ static inline bool isVerticalWritingMode(const SVGRenderStyle* style)
 
 static inline const SVGFontData* svgFontAndFontFaceElementForFontData(const SimpleFontData* fontData, SVGFontFaceElement*& fontFace, SVGFontElement*& font)
 {
+    ASSERT(fontData);
     ASSERT(fontData->isCustomFont());
     ASSERT(fontData->isSVGFont());
 
-    const SVGFontData* svgFontData = static_cast<const SVGFontData*>(fontData->svgFontData());
+    const SVGFontData* svgFontData = static_cast<const SVGFontData*>(fontData->fontData());
 
     fontFace = svgFontData->svgFontFaceElement();
     ASSERT(fontFace);
@@ -71,6 +72,29 @@ static inline const SVGFontData* svgFontAndFontFaceElementForFontData(const Simp
     return svgFontData;
 }
 
+static inline RenderObject* firstParentRendererForNonTextNode(RenderObject* renderer)
+{
+    ASSERT(renderer);
+    RenderObject* newRenderer = renderer->isText() ? renderer->parent() : renderer;
+    ASSERT(newRenderer->node());
+    ASSERT(newRenderer->node()->isElementNode());
+    return newRenderer;
+}
+
+static inline RenderObject* referencingRenderObjectFromRun(const TextRun& run)
+{
+    if (TextRun::RenderingContext* renderingContext = run.renderingContext())
+        return static_cast<SVGTextRunRenderingContext*>(renderingContext)->renderer();
+    return 0;
+}
+
+static inline RenderSVGResource* activePaintingResourceFromRun(const TextRun& run)
+{
+    if (TextRun::RenderingContext* renderingContext = run.renderingContext())
+        return static_cast<SVGTextRunRenderingContext*>(renderingContext)->activePaintingResource();
+    return 0;
+}
+
 // Helper class to walk a text run. Lookup a SVGGlyph for each character
 // - also respecting possibly defined ligatures - and invoke a callback for each found glyph.
 template<typename SVGTextRunData>
@@ -100,19 +124,18 @@ struct SVGTextRunWalker {
         int characterLookupRange;
         int endOfScanRange = to + m_walkerData.extraCharsAvailable;
 
+        RenderObject* renderObject = referencingRenderObjectFromRun(run);
+        RenderObject* parentRenderObject = firstParentRendererForNonTextNode(renderObject);
+
         bool haveAltGlyph = false;
         SVGGlyph altGlyphIdentifier;
-        if (RenderObject* renderObject = run.referencingRenderObject()) {
-            RenderObject* parentRenderer = renderObject->parent();
-            ASSERT(parentRenderer);
-            if (parentRenderer->node() && parentRenderer->node()->hasTagName(SVGNames::altGlyphTag)) {
-                SVGGlyphElement* glyphElement = static_cast<SVGAltGlyphElement*>(parentRenderer->node())->glyphElement();
-                if (glyphElement) {
-                    haveAltGlyph = true;
-                    altGlyphIdentifier = glyphElement->buildGlyphIdentifier();
-                    altGlyphIdentifier.isValid = true;
-                    altGlyphIdentifier.unicodeStringLength = to - from;
-                }
+        Node* node = parentRenderObject->node();
+        if (node->hasTagName(SVGNames::altGlyphTag)) {
+            if (SVGGlyphElement* glyphElement = static_cast<SVGAltGlyphElement*>(node)->glyphElement()) {
+                haveAltGlyph = true;
+                altGlyphIdentifier = glyphElement->buildGlyphIdentifier();
+                altGlyphIdentifier.isValid = true;
+                altGlyphIdentifier.unicodeStringLength = to - from;
             }
         }
 
@@ -157,6 +180,7 @@ struct SVGTextRunWalker {
                 } else {
                     // Fallback to system font fallback
                     TextRun subRun(run);
+                    subRun.setRenderingContext(0);
                     subRun.setText(subRun.data(i), 1);
 
                     (*m_walkerMissingGlyphCallback)(subRun, m_walkerData);
@@ -210,24 +234,12 @@ 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.width(run);
+    TextRun fallbackRun(run);
+    fallbackRun.setRenderingContext(0);
+    data.length += font.width(fallbackRun);
 }
 
-
-SVGFontElement* Font::svgFont() const
-{ 
-    if (!isSVGFont())
-        return 0;
-
-    SVGFontElement* fontElement = 0;
-    SVGFontFaceElement* fontFaceElement = 0;
-    if (svgFontAndFontFaceElementForFontData(primaryFont(), fontFaceElement, fontElement))
-        return fontElement;
-    
-    return 0;
-}
-
-static float floatWidthOfSubStringUsingSVGFont(const Font* font, const TextRun& run, int extraCharsAvailable, int from, int to, int& charsConsumed, String& glyphName)
+static float floatWidthOfSubStringUsingSVGFont(const Font& font, const TextRun& run, int extraCharsAvailable, int from, int to, int& charsConsumed, String& glyphName)
 {
     int newFrom = to > from ? from : to;
     int newTo = to > from ? to : from;
@@ -238,33 +250,26 @@ static float floatWidthOfSubStringUsingSVGFont(const Font* font, const TextRun&
     SVGFontElement* fontElement = 0;
     SVGFontFaceElement* fontFaceElement = 0;
 
-    if (const SVGFontData* fontData = svgFontAndFontFaceElementForFontData(font->primaryFont(), fontFaceElement, fontElement)) {
+    if (const SVGFontData* fontData = svgFontAndFontFaceElementForFontData(font.primaryFont(), fontFaceElement, fontElement)) {
         if (!fontElement)
             return 0.0f;
 
         SVGTextRunWalkerMeasuredLengthData data;
 
-        data.font = font;
+        data.font = &font;
         data.at = from;
         data.from = from;
         data.to = to;
         data.extraCharsAvailable = extraCharsAvailable;
         data.charsConsumed = 0;
-        data.scale = convertEmUnitToPixel(font->size(), fontFaceElement->unitsPerEm(), 1.0f);
+        data.scale = convertEmUnitToPixel(font.size(), fontFaceElement->unitsPerEm(), 1.0f);
         data.length = 0.0f;
 
-        String language;
-        bool isVerticalText = false; // Holds true for HTML text
+        RenderObject* renderObject = referencingRenderObjectFromRun(run);
+        RenderObject* parentRenderObject = firstParentRendererForNonTextNode(renderObject); 
 
-        // TODO: language matching & svg glyphs should be possible for HTML text, too.
-        if (RenderObject* renderObject = run.referencingRenderObject()) {
-            RenderObject* parentRenderer = renderObject->parent();
-            ASSERT(parentRenderer);
-            isVerticalText = isVerticalWritingMode(parentRenderer->style()->svgStyle());
-
-            if (SVGElement* element = static_cast<SVGElement*>(parentRenderer->node()))
-                language = element->getAttribute(XMLNames::langAttr);
-        }
+        String language = toElement(parentRenderObject->node())->getAttribute(XMLNames::langAttr);
+        bool isVerticalText = isVerticalWritingMode(parentRenderObject->style()->svgStyle());
 
         SVGTextRunWalker<SVGTextRunWalkerMeasuredLengthData> runWalker(fontData, fontElement, data, floatWidthUsingSVGFontCallback, floatWidthMissingGlyphCallback);
         runWalker.walk(run, isVerticalText, language, from, to);
@@ -276,16 +281,16 @@ static float floatWidthOfSubStringUsingSVGFont(const Font* font, const TextRun&
     return 0.0f;
 }
 
-float Font::floatWidthUsingSVGFont(const TextRun& run) const
+float SVGTextRunRenderingContext::floatWidthUsingSVGFont(const Font& font, const TextRun& run) const
 {
     int charsConsumed;
     String glyphName;
-    return floatWidthOfSubStringUsingSVGFont(this, run, 0, 0, run.length(), charsConsumed, glyphName);
+    return floatWidthOfSubStringUsingSVGFont(font, run, 0, 0, run.length(), charsConsumed, glyphName);
 }
 
-float Font::floatWidthUsingSVGFont(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const
+float SVGTextRunRenderingContext::floatWidthUsingSVGFont(const Font& font, const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const
 {
-    return floatWidthOfSubStringUsingSVGFont(this, run, extraCharsAvailable, 0, run.length(), charsConsumed, glyphName);
+    return floatWidthOfSubStringUsingSVGFont(font, run, extraCharsAvailable, 0, run.length(), charsConsumed, glyphName);
 }
 
 // Callback & data structures to draw text using SVG Fonts
@@ -310,26 +315,26 @@ static void drawTextMissingGlyphCallback(const TextRun& run, SVGTextRunWalkerDra
     data.fallbackCharacters.append(run[0]);
 }
 
-void Font::drawTextUsingSVGFont(GraphicsContext* context, const TextRun& run, 
-                                const FloatPoint& point, int from, int to) const
+void SVGTextRunRenderingContext::drawTextUsingSVGFont(const Font& font, GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
 {
     SVGFontElement* fontElement = 0;
     SVGFontFaceElement* fontFaceElement = 0;
 
-    if (const SVGFontData* fontData = svgFontAndFontFaceElementForFontData(primaryFont(), fontFaceElement, fontElement)) {
+    if (const SVGFontData* fontData = svgFontAndFontFaceElementForFontData(font.primaryFont(), fontFaceElement, fontElement)) {
         if (!fontElement)
             return;
 
         SVGTextRunWalkerDrawTextData data;
         FloatPoint currentPoint = point;
-        float scale = convertEmUnitToPixel(size(), fontFaceElement->unitsPerEm(), 1.0f);
-
-        RenderSVGResource* activePaintingResource = run.activePaintingResource();
+        float scale = convertEmUnitToPixel(font.size(), fontFaceElement->unitsPerEm(), 1.0f);
 
-        // If renderObject is not set, we're dealing for HTML text rendered using SVG Fonts.
-        if (!run.referencingRenderObject()) {
-            ASSERT(!activePaintingResource);
+        // We can only paint SVGFonts if a context is available.
+        RenderObject* renderObject = referencingRenderObjectFromRun(run);
+        RenderObject* parentRenderObject = firstParentRendererForNonTextNode(renderObject);
 
+        // If activePaintingResource is not set, we're dealing for HTML text rendered using SVG Fonts.
+        RenderSVGResource* activePaintingResource = activePaintingResourceFromRun(run);
+        if (!activePaintingResource) {
             // TODO: We're only supporting simple filled HTML text so far.
             RenderSVGResourceSolidColor* solidPaintingResource = RenderSVGResource::sharedSolidPaintingResource();
             solidPaintingResource->setColor(context->fillColor());
@@ -337,29 +342,16 @@ void Font::drawTextUsingSVGFont(GraphicsContext* context, const TextRun& run,
             activePaintingResource = solidPaintingResource;
         }
 
-        ASSERT(activePaintingResource);
-
         int charsConsumed;
         String glyphName;
-        bool isVerticalText = false;
-        float xStartOffset = floatWidthOfSubStringUsingSVGFont(this, run, 0, run.rtl() ? to : 0, run.rtl() ? run.length() : from, charsConsumed, glyphName);
+        float xStartOffset = floatWidthOfSubStringUsingSVGFont(font, run, 0, run.rtl() ? to : 0, run.rtl() ? run.length() : from, charsConsumed, glyphName);
         FloatPoint glyphOrigin;
 
-        String language;
-
-        // TODO: language matching & svg glyphs should be possible for HTML text, too.
-        RenderObject* referencingRenderObject = run.referencingRenderObject();
-        RenderObject* referencingRenderObjectParent = referencingRenderObject ? referencingRenderObject->parent() : 0;
-        RenderStyle* referencingRenderObjectParentStyle = 0;
-        if (referencingRenderObject) {
-            ASSERT(referencingRenderObjectParent);
-            referencingRenderObjectParentStyle = referencingRenderObjectParent->style();
-
-            isVerticalText = isVerticalWritingMode(referencingRenderObjectParentStyle->svgStyle());    
-            if (SVGElement* element = static_cast<SVGElement*>(referencingRenderObjectParent->node()))
-                language = element->getAttribute(XMLNames::langAttr);
-        }
+        Node* node = parentRenderObject->node();
+        String language = toElement(node)->getAttribute(XMLNames::langAttr);
 
+        RenderStyle* parentRenderObjectStyle = parentRenderObject->style();
+        bool isVerticalText = isVerticalWritingMode(parentRenderObjectStyle->svgStyle());
         if (!isVerticalText) {
             glyphOrigin.setX(fontData->horizontalOriginX() * scale);
             glyphOrigin.setY(fontData->horizontalOriginY() * scale);
@@ -394,12 +386,12 @@ void Font::drawTextUsingSVGFont(GraphicsContext* context, const TextRun& run,
                     Path glyphPath = identifier.pathData;
                     glyphPath.transform(glyphPathTransform);
 
-                    if (activePaintingResource->applyResource(referencingRenderObjectParent, referencingRenderObjectParentStyle, context, resourceMode)) {
-                        if (referencingRenderObject) {
-                            RenderSVGInlineText* textRenderer = toRenderSVGInlineText(referencingRenderObject);
+                    if (activePaintingResource->applyResource(parentRenderObject, parentRenderObjectStyle, context, resourceMode)) {
+                        if (renderObject && renderObject->isSVGInlineText()) {
+                            const RenderSVGInlineText* textRenderer = toRenderSVGInlineText(renderObject);
                             context->setStrokeThickness(context->strokeThickness() * textRenderer->scalingFactor());
                         }
-                        activePaintingResource->postApplyResource(referencingRenderObjectParent, context, resourceMode, &glyphPath);
+                        activePaintingResource->postApplyResource(parentRenderObject, context, resourceMode, &glyphPath);
                     }
                 }
 
@@ -409,12 +401,13 @@ void Font::drawTextUsingSVGFont(GraphicsContext* context, const TextRun& run,
                     currentPoint.move(identifier.horizontalAdvanceX * scale, 0.0f);
             } else {
                 // Handle system font fallback
-                FontDescription fontDescription(m_fontDescription);
+                FontDescription fontDescription(font.fontDescription());
                 fontDescription.setFamily(FontFamily());
                 Font font(fontDescription, 0, 0); // spacing handled by SVG text code.
-                font.update(fontSelector());
+                font.update(font.fontSelector());
 
                 TextRun fallbackCharacterRun(run);
+                fallbackCharacterRun.setRenderingContext(0);
                 fallbackCharacterRun.setText(&data.fallbackCharacters[run.rtl() ? data.fallbackCharacters.size() - fallbackCharacterIndex - 1 : fallbackCharacterIndex], 1);
                 font.drawText(context, fallbackCharacterRun, currentPoint);
 
@@ -429,16 +422,16 @@ void Font::drawTextUsingSVGFont(GraphicsContext* context, const TextRun& run,
     }
 }
 
-FloatRect Font::selectionRectForTextUsingSVGFont(const TextRun& run, const FloatPoint& point, int height, int from, int to) const
+FloatRect SVGTextRunRenderingContext::selectionRectForTextUsingSVGFont(const Font& font, const TextRun& run, const FloatPoint& point, int height, int from, int to) const
 {
     int charsConsumed;
     String glyphName;
 
-    return FloatRect(point.x() + floatWidthOfSubStringUsingSVGFont(this, run, 0, run.rtl() ? to : 0, run.rtl() ? run.length() : from, charsConsumed, glyphName),
-                     point.y(), floatWidthOfSubStringUsingSVGFont(this, run, 0, from, to, charsConsumed, glyphName), height);
+    return FloatRect(point.x() + floatWidthOfSubStringUsingSVGFont(font, run, 0, run.rtl() ? to : 0, run.rtl() ? run.length() : from, charsConsumed, glyphName),
+                     point.y(), floatWidthOfSubStringUsingSVGFont(font, run, 0, from, to, charsConsumed, glyphName), height);
 }
 
-int Font::offsetForPositionForTextUsingSVGFont(const TextRun&, float, bool) const
+int SVGTextRunRenderingContext::offsetForPositionForTextUsingSVGFont(const Font&, const TextRun&, float, bool) const
 {
     // TODO: Fix text selection when HTML text is drawn using a SVG Font
     // We need to integrate the SVG text selection code in the offsetForPosition() framework.
diff --git a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h
new file mode 100644 (file)
index 0000000..831fdf7
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SVGTextRunRenderingContext_h
+#define SVGTextRunRenderingContext_h
+
+#include "TextRun.h"
+
+namespace WebCore {
+
+class RenderObject;
+class RenderSVGResource;
+
+class SVGTextRunRenderingContext : public TextRun::RenderingContext {
+public:
+    static PassRefPtr<SVGTextRunRenderingContext> create(RenderObject* renderer)
+    {
+        return adoptRef(new SVGTextRunRenderingContext(renderer));
+    }
+
+    RenderObject* renderer() const { return m_renderer; }
+
+#if ENABLE(SVG_FONTS)
+    RenderSVGResource* activePaintingResource() const { return m_activePaintingResource; }
+    void setActivePaintingResource(RenderSVGResource* object) { m_activePaintingResource = object; }
+
+    virtual void drawTextUsingSVGFont(const Font&, GraphicsContext*, const TextRun&, const FloatPoint&, int from, int to) const;
+    virtual float floatWidthUsingSVGFont(const Font&, const TextRun&) const;
+    virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int extraCharsAvailable, int& charsConsumed, String& glyphName) const;
+    virtual FloatRect selectionRectForTextUsingSVGFont(const Font&, const TextRun&, const FloatPoint&, int h, int from, int to) const;
+    virtual int offsetForPositionForTextUsingSVGFont(const Font&, const TextRun&, float position, bool includePartialGlyphs) const;
+#endif
+
+private:
+    SVGTextRunRenderingContext(RenderObject* renderer)
+        : m_renderer(renderer)
+#if ENABLE(SVG_FONTS)
+        , m_activePaintingResource(0)
+#endif
+    {
+    }
+
+    RenderObject* m_renderer;
+
+#if ENABLE(SVG_FONTS)
+    RenderSVGResource* m_activePaintingResource;
+#endif
+};
+
+inline bool textRunNeedsRenderingContext(const Font& font)
+{
+    // Only save the extra data if SVG Fonts are used, which depend on them.
+    // FIXME: SVG Fonts won't work as segmented fonts at the moment, if that's fixed, we need to check for them as well below.
+    ASSERT(font.primaryFont());
+    return font.primaryFont()->isSVGFont();
+}
+
+} // namespace WebCore
+
+#endif // SVGTextRunRenderingContext_h
index 2e0b0f7..fca3d0c 100644 (file)
@@ -77,7 +77,6 @@
 #include "SVGFilterElement.cpp"
 #include "SVGFilterPrimitiveStandardAttributes.cpp"
 #include "SVGFitToViewBox.cpp"
-#include "SVGFont.cpp"
 #include "SVGFontData.cpp"
 #include "SVGFontElement.cpp"
 #include "SVGFontFaceElement.cpp"
index 63433ee..55b8d3d 100644 (file)
@@ -22,6 +22,9 @@
 #if ENABLE(SVG_FONTS)
 #include "SVGFontData.h"
 
+#include "SVGFontElement.h"
+#include "SVGGlyph.h"
+
 namespace WebCore {
 
 SVGFontData::SVGFontData(SVGFontFaceElement* fontFaceElement)
@@ -36,6 +39,61 @@ SVGFontData::SVGFontData(SVGFontFaceElement* fontFaceElement)
     ASSERT_ARG(fontFaceElement, fontFaceElement);
 }
 
+void SVGFontData::initializeFontData(SimpleFontData* fontData, int size)
+{
+    ASSERT(fontData);
+
+    SVGFontFaceElement* svgFontFaceElement = this->svgFontFaceElement();
+    unsigned unitsPerEm = svgFontFaceElement->unitsPerEm();
+
+    float scale = size;
+    if (unitsPerEm)
+        scale /= unitsPerEm;
+
+    float xHeight = svgFontFaceElement->xHeight() * scale;
+    float ascent = svgFontFaceElement->ascent() * scale;
+    float descent = svgFontFaceElement->descent() * scale;
+    float lineGap = 0.1f * size;
+
+    SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement();
+    if (!xHeight) {
+        // Fallback if x_heightAttr is not specified for the font element.
+        Vector<SVGGlyph> letterXGlyphs;
+        associatedFontElement->getGlyphIdentifiersForString(String("x", 1), letterXGlyphs);
+        xHeight = letterXGlyphs.isEmpty() ? 2 * ascent / 3 : letterXGlyphs.first().horizontalAdvanceX * scale;
+    }
+
+    FontMetrics& fontMetrics = fontData->fontMetrics();
+    fontMetrics.setUnitsPerEm(unitsPerEm);
+    fontMetrics.setAscent(ascent);
+    fontMetrics.setDescent(descent);
+    fontMetrics.setLineGap(lineGap);
+    fontMetrics.setLineSpacing(roundf(ascent) + roundf(descent) + roundf(lineGap));
+    fontMetrics.setXHeight(xHeight);
+
+    Vector<SVGGlyph> spaceGlyphs;
+    associatedFontElement->getGlyphIdentifiersForString(String(" ", 1), spaceGlyphs);
+    fontData->setSpaceWidth(spaceGlyphs.isEmpty() ? xHeight : spaceGlyphs.first().horizontalAdvanceX * scale);
+
+    Vector<SVGGlyph> numeralZeroGlyphs;
+    associatedFontElement->getGlyphIdentifiersForString(String("0", 1), numeralZeroGlyphs);
+    fontData->setAvgCharWidth(numeralZeroGlyphs.isEmpty() ? fontData->spaceWidth() : numeralZeroGlyphs.first().horizontalAdvanceX * scale);
+
+    Vector<SVGGlyph> letterWGlyphs;
+    associatedFontElement->getGlyphIdentifiersForString(String("W", 1), letterWGlyphs);
+    fontData->setMaxCharWidth(letterWGlyphs.isEmpty() ? ascent : letterWGlyphs.first().horizontalAdvanceX * scale);
+
+    // FIXME: is there a way we can get the space glyph from the SVGGlyph above?
+    fontData->setSpaceGlyph(0);
+    fontData->setZeroWidthSpaceGlyph(0);
+    fontData->determinePitch();
+
+    GlyphData missingGlyphData;
+    missingGlyphData.fontData = fontData;
+    missingGlyphData.glyph = 0;
+    fontData->setMissingGlyphData(missingGlyphData);
+}
+
 } // namespace WebCore
 
 #endif
index f202d26..d84a0ca 100644 (file)
 #define SVGFontData_h
 
 #if ENABLE(SVG_FONTS)
+#include "SimpleFontData.h"
 #include "SVGFontFaceElement.h"
 
 namespace WebCore {
 
-class SVGFontData {
-    WTF_MAKE_NONCOPYABLE(SVGFontData); WTF_MAKE_FAST_ALLOCATED;
+class SVGFontData : public SimpleFontData::FontData {
 public:
-    SVGFontData(SVGFontFaceElement*);
+    static PassOwnPtr<SVGFontData> create(SVGFontFaceElement* element)
+    {
+        return adoptPtr(new SVGFontData(element));
+    }
+
     virtual ~SVGFontData() { }
 
+    virtual bool isSVGFontData() const { return true; }
+    virtual void initializeFontData(SimpleFontData*, int size);
+
     SVGFontFaceElement* svgFontFaceElement() const { return m_svgFontFaceElement; }
 
     float horizontalOriginX() const { return m_horizontalOriginX; }
@@ -42,6 +49,8 @@ public:
     float verticalAdvanceY() const { return m_verticalAdvanceY; }
 
 private:
+    SVGFontData(SVGFontFaceElement*);
+
     // Ths SVGFontFaceElement is kept alive --
     // 1) in the external font case: by the CSSFontFaceSource, which holds a reference to the external SVG document
     //    containing the element;
index 7a06fe1..b45de5e 100644 (file)
 #include "SVGFontFaceElement.h"
 #include "SVGNames.h"
 #include "SVGPathParserFactory.h"
-#include "SimpleFontData.h"
-#include "XMLNames.h"
 
 namespace WebCore {
 
-using namespace SVGNames;
-
 inline SVGGlyphElement::SVGGlyphElement(const QualifiedName& tagName, Document* document)
     : SVGStyledElement(tagName, document)
 {
-    ASSERT(hasTagName(glyphTag));
+    ASSERT(hasTagName(SVGNames::glyphTag));
 }
 
 PassRefPtr<SVGGlyphElement> SVGGlyphElement::create(const QualifiedName& tagName, Document* document)
@@ -150,28 +146,28 @@ void SVGGlyphElement::fillAttributeToPropertyTypeMap()
 SVGGlyph SVGGlyphElement::buildGenericGlyphIdentifier(const SVGElement* element)
 {
     SVGGlyph identifier;
-    identifier.pathData = parsePathData(element->getAttribute(dAttr));
+    identifier.pathData = parsePathData(element->getAttribute(SVGNames::dAttr));
  
     // Spec: The horizontal advance after rendering the glyph in horizontal orientation.
     // If the attribute is not specified, the effect is as if the attribute were set to the
     // value of the font's horiz-adv-x attribute. Glyph widths are required to be non-negative,
     // even if the glyph is typically rendered right-to-left, as in Hebrew and Arabic scripts.
-    identifier.horizontalAdvanceX = parseSVGGlyphAttribute(element, horiz_adv_xAttr);
+    identifier.horizontalAdvanceX = parseSVGGlyphAttribute(element, SVGNames::horiz_adv_xAttr);
 
     // Spec: The X-coordinate in the font coordinate system of the origin of the glyph to be
     // used when drawing vertically oriented text. If the attribute is not specified, the effect
     // is as if the attribute were set to the value of the font's vert-origin-x attribute.
-    identifier.verticalOriginX = parseSVGGlyphAttribute(element, vert_origin_xAttr);
+    identifier.verticalOriginX = parseSVGGlyphAttribute(element, SVGNames::vert_origin_xAttr);
 
     // Spec: The Y-coordinate in the font coordinate system of the origin of a glyph to be
     // used when drawing vertically oriented text. If the attribute is not specified, the effect
     // is as if the attribute were set to the value of the font's vert-origin-y attribute.
-    identifier.verticalOriginY = parseSVGGlyphAttribute(element, vert_origin_yAttr);
+    identifier.verticalOriginY = parseSVGGlyphAttribute(element, SVGNames::vert_origin_yAttr);
 
     // Spec: The vertical advance after rendering a glyph in vertical orientation.
     // If the attribute is not specified, the effect is as if the attribute were set to the
     // value of the font's vert-adv-y attribute.
-    identifier.verticalAdvanceY = parseSVGGlyphAttribute(element, vert_adv_yAttr);
+    identifier.verticalAdvanceY = parseSVGGlyphAttribute(element, SVGNames::vert_adv_yAttr);
 
     return identifier;
 }
@@ -179,9 +175,9 @@ SVGGlyph SVGGlyphElement::buildGenericGlyphIdentifier(const SVGElement* element)
 SVGGlyph SVGGlyphElement::buildGlyphIdentifier() const
 {
     SVGGlyph identifier(buildGenericGlyphIdentifier(this));
-    identifier.glyphName = getAttribute(glyph_nameAttr);
-    identifier.orientation = parseOrientation(getAttribute(orientationAttr));
-    identifier.arabicForm = parseArabicForm(getAttribute(arabic_formAttr));
+    identifier.glyphName = getAttribute(SVGNames::glyph_nameAttr);
+    identifier.orientation = parseOrientation(getAttribute(SVGNames::orientationAttr));
+    identifier.arabicForm = parseArabicForm(getAttribute(SVGNames::arabic_formAttr));
 
     String language = getAttribute(SVGNames::langAttr);
     if (!language.isEmpty())
index 444871c..9fd4dff 100644 (file)
 #if ENABLE(SVG_FONTS)
 #include "SVGHKernElement.h"
 
-#include "SVGFontData.h"
 #include "SVGFontElement.h"
 #include "SVGFontFaceElement.h"
 #include "SVGNames.h"
-#include "SimpleFontData.h"
-#include "XMLNames.h"
 
 namespace WebCore {
 
-using namespace SVGNames;
-
 inline SVGHKernElement::SVGHKernElement(const QualifiedName& tagName, Document* document)
     : SVGElement(tagName, document)
 {
-    ASSERT(hasTagName(hkernTag));
+    ASSERT(hasTagName(SVGNames::hkernTag));
 }
 
 PassRefPtr<SVGHKernElement> SVGHKernElement::create(const QualifiedName& tagName, Document* document)
@@ -68,10 +63,10 @@ void SVGHKernElement::removedFromDocument()
 
 void SVGHKernElement::buildHorizontalKerningPair(KerningPairVector& kerningPairs)
 {
-    String u1 = getAttribute(u1Attr);
-    String g1 = getAttribute(g1Attr);
-    String u2 = getAttribute(u2Attr);
-    String g2 = getAttribute(g2Attr);
+    String u1 = getAttribute(SVGNames::u1Attr);
+    String g1 = getAttribute(SVGNames::g1Attr);
+    String u2 = getAttribute(SVGNames::u2Attr);
+    String g2 = getAttribute(SVGNames::g2Attr);
     if ((u1.isEmpty() && g1.isEmpty()) || (u2.isEmpty() && g2.isEmpty()))
         return;
 
@@ -80,7 +75,7 @@ void SVGHKernElement::buildHorizontalKerningPair(KerningPairVector& kerningPairs
         && parseGlyphName(g2, kerningPair.glyphName2)
         && parseKerningUnicodeString(u1, kerningPair.unicodeRange1, kerningPair.unicodeName1)
         && parseKerningUnicodeString(u2, kerningPair.unicodeRange2, kerningPair.unicodeName2)) {
-        kerningPair.kerning = getAttribute(kAttr).string().toFloat();
+        kerningPair.kerning = getAttribute(SVGNames::kAttr).string().toFloat();
         kerningPairs.append(kerningPair);
     }
 }
index 7680d0c..cc2a851 100644 (file)
 #if ENABLE(SVG_FONTS)
 #include "SVGVKernElement.h"
 
-#include "SVGFontData.h"
 #include "SVGFontElement.h"
 #include "SVGFontFaceElement.h"
 #include "SVGNames.h"
-#include "SimpleFontData.h"
-#include "XMLNames.h"
 
 namespace WebCore {
 
-using namespace SVGNames;
-
 inline SVGVKernElement::SVGVKernElement(const QualifiedName& tagName, Document* document)
     : SVGElement(tagName, document)
 {
-    ASSERT(hasTagName(vkernTag));
+    ASSERT(hasTagName(SVGNames::vkernTag));
 }
 
 PassRefPtr<SVGVKernElement> SVGVKernElement::create(const QualifiedName& tagName, Document* document)
@@ -66,10 +61,10 @@ void SVGVKernElement::removedFromDocument()
 
 void SVGVKernElement::buildVerticalKerningPair(KerningPairVector& kerningPairs)
 {
-    String u1 = getAttribute(u1Attr);
-    String g1 = getAttribute(g1Attr);
-    String u2 = getAttribute(u2Attr);
-    String g2 = getAttribute(g2Attr);
+    String u1 = getAttribute(SVGNames::u1Attr);
+    String g1 = getAttribute(SVGNames::g1Attr);
+    String u2 = getAttribute(SVGNames::u2Attr);
+    String g2 = getAttribute(SVGNames::g2Attr);
     if ((u1.isEmpty() && g1.isEmpty()) || (u2.isEmpty() && g2.isEmpty()))
         return;
 
@@ -78,7 +73,7 @@ void SVGVKernElement::buildVerticalKerningPair(KerningPairVector& kerningPairs)
         && parseGlyphName(g2, kerningPair.glyphName2)
         && parseKerningUnicodeString(u1, kerningPair.unicodeRange1, kerningPair.unicodeName1)
         && parseKerningUnicodeString(u2, kerningPair.unicodeRange2, kerningPair.unicodeName2)) {
-        kerningPair.kerning = getAttribute(kAttr).string().toFloat();
+        kerningPair.kerning = getAttribute(SVGNames::kAttr).string().toFloat();
         kerningPairs.append(kerningPair);
     }
 }
index 77ea2fe..01f0670 100644 (file)
@@ -30,8 +30,6 @@
 
 namespace WebCore {
 
-class SVGFontData;
-
 class SVGVKernElement : public SVGElement {
 public:
     static PassRefPtr<SVGVKernElement> create(const QualifiedName&, Document*);