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 f453126c0020688cf3f48f0faeba250ffcf13763..ea2a555585c163e397b59a77c20413bcdb5b105b 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 7ca96651278b8635d984fecee104f4e11cac8d93..e846d71f1238c401f311fc89a6de822d923de821 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 f75805ea1e0d61b21c1d00ddee9dfe0b0d959d41..c75796cf16fb3bc7aa9e53b57478367162e421c1 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 d065de9f6bd3d7240c6a470f29aac1fbe3904e00..0c3f9159fadd97325a1553854346c4dbfe2ace9b 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 d16e562a2f68d24081fc28a4f78f3e30bbb3b907..814d1a579fc6b44dffde1e1f3d09fcdecabaa108 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 0685dbf2e2a7b3c019e429053ae1a59a66c69557..4ba34f67708a35e0480e6dfd6dc5d58483301835 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 99e7b10f06738327327c03960f60709e57af7627..247cb21641f17dc9286a4554e66402f8886cfa96 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 b0f7365d63eb9292c0923e90f3d56ef9e25e9a88..62ff56f5067bf54bdf22235579b32019f28bdab3 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 d2ce8539b868829bb9f10b57e3af1c2883f49d12..e1d6dccb817c05f790840a491989a81dd04569b5 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 cb5af7ceebc1037725bd31a47a9b2be4c4fad47c..a4d2438cc4d9f5de2215bc3666072f626f36b0c4 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 f772e4a8eb147995db0b8dd3b3016cc2fc3d731e..a8218d937f23a0ac892fb57c0259d4b4369413fa 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 8b2bed39fadd2fb269c5f0f0e9f5d09d0b6901d1..52e3a5150cea4ddabf1321ee077f7b56a83853c4 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 737adf65988bcfe7f7e4cb9e3e1d9006cef18262..50ca448ba028ff22fd73c0f0013c9ff3c906fdb6 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 6feb1dd792623f212c02c57dcfa70a02cca39a40..3ca6ae0fdf2aa292665f6ed07f6e7f3f8f578c69 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 dedf667691c4dbe91a728a0b383d1de2e344b017..62af077e594239fd803682d601cb4939db0e96e3 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 c8a9cc0fb58afe704c63f28ef3af0dd4ea5339f3..e11e5dfceb0b79a33e6a09894c2d1781c28eb284 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 4a87f3b28f96b10a3db184964511a96dac5a257f..b086d0d26716a40d9356d6fde0e58f4987cd1881 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 cc04a61ca511956c3224bca09be1459262497dbb..4b7d4ad27b06ef4314b2cdb98a0991f90940011c 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 39479b2020eb49f402bf6cb2cd47a4f324fc0480..1d48665eecbaf6b6f33ab2eec6f507b3215fb2a1 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 37ca1eddb2e84ee3d6b0386a1c77ccb8b10c44fb..c79886a9d7533d32384cd6a88b3b9ce7460f035a 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 c6a4ecc9f3a7de85e2294090797fe6c0f4dc9c5c..47d76bd2432ff2a5956fd39fcad8a242e06ffbd1 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 f31f78d1ad705d9789a191d859b2e0c4f64bfac4..00b17dac179e8bcc286d5f12b3c0c97d23c0be46 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 3f9ae671a5d1d12da432360a6faf36dfd3e46961..d34069e3e44dbf39d211e74cdb4adb31394528cc 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 b779bf64a1a0ba7485b6bfc6f9f23176d57e6a8d..f03fd548af5ea4c1d3fb60cc92cf89e245002788 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 4d3b660b191735b7fb25b6940e7e57cf33387f49..73406f156be080e4b7335ab1d2a1bc3158cd0c5b 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 7f1be55f0038abff989f887090603357ba7517b8..099d0f0c398cbb12cd83bf2053f258acffe14d31 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 8937681758452dd037c4f3b6534f5e5ee2955fea..58d045001acac89abf474de9a4d10c356d85eb2b 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 9f3d8a504ec8c0eb43974661e80273788c013e1b..9ea3be5ba984e609a1c22abb68a8e564dc90d0fa 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 4d36c824846089a68caa73254a994426c627aa2e..2d8ea92b4a91af3610bb6aaad363919f6377edb0 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 e9aa127550510ba9f5a102ce7693c85afa0acdf9..bb8ef12b826d10bab918cdfdbcc476aca5512ca9 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 d9d86f61a181c0bc3ecf54df6f82c2e68bc36629..035458485d0a9de20d9037b97702d443f66c0d06 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 06095fed82d4b087c44b2b66a575e2b3cbe75295..dff687adccabc182b7153de9638ff84fd8e81755 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 2e0b0f7821dcd95d6818e97b3f881af39961f6e7..fca3d0cc60f90ce86d8f154fbe5dadb5ee17df3b 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 63433ee19db2396dc926a7c6e35b7cda6b741503..55b8d3dc5a8eae0139bd9dab7e4820e19b0b0013 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 f202d26150d75a914dd76ef2646db0882f28d57c..d84a0ca11e5bd4add2aa3d7fb00ee4d992fd4109 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 7a06fe17965fc422f51b19ba78bf5787535a8606..b45de5eb4beab26e2708536e9b5913a5c5124de5 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 444871c94bdb04f5a97523fe30de0679e1b5c58e..9fd4dff78ca1c8aa0974718dd228301567033b48 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 7680d0c6c35c60069fc7ba60333214e16a363988..cc2a851d779fe05552600bcbcf8ece3429f00481 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 77ea2fe799b7411c8a0f7c24a8ddb06a9c26fcee..01f06701c81dc77988a12185f3e04918fde52d0b 100644 (file)
@@ -30,8 +30,6 @@
 
 namespace WebCore {
 
-class SVGFontData;
-
 class SVGVKernElement : public SVGElement {
 public:
     static PassRefPtr<SVGVKernElement> create(const QualifiedName&, Document*);