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
svg/SVGFilterElement.cpp
svg/SVGFilterPrimitiveStandardAttributes.cpp
svg/SVGFitToViewBox.cpp
- svg/SVGFont.cpp
svg/SVGFontData.cpp
svg/SVGFontElement.cpp
svg/SVGFontFaceElement.cpp
+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.
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 \
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 \
'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',
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 \
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 \
svg/SVGFilterElement.cpp \
svg/SVGFilterPrimitiveStandardAttributes.cpp \
svg/SVGFitToViewBox.cpp \
- svg/SVGFont.cpp \
svg/SVGFontData.cpp \
svg/SVGFontElement.cpp \
svg/SVGFontFaceElement.cpp \
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
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 */,
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
#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 {
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
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);
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();
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)
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)
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;
class GlyphBuffer;
class GlyphPageTreeNode;
class GraphicsContext;
-class SVGFontElement;
class TextRun;
struct GlyphData;
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.
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:
#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>
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.
SimpleFontData::~SimpleFontData()
{
#if ENABLE(SVG_FONTS)
- if (!m_svgFontData || !m_svgFontData->svgFontFaceElement())
+ if (!m_fontData)
#endif
platformDestroy();
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; }
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;
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;
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;
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.
#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:
, m_direction(direction)
, m_directionalOverride(directionalOverride)
, m_disableSpacing(false)
-#if ENABLE(SVG_FONTS)
- , m_referencingRenderObject(0)
- , m_activePaintingResource(0)
-#endif
{
}
, m_direction(direction)
, m_directionalOverride(directionalOverride)
, m_disableSpacing(false)
-#if ENABLE(SVG_FONTS)
- , m_referencingRenderObject(0)
- , m_activePaintingResource(0)
-#endif
{
}
#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; }
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;
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;
};
}
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();
}
// 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())
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)
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)
#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>
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())
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();
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)
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)
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();
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)
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));
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();
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.
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;
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
return true;
}
-TextRun InlineTextBox::constructTextRun(RenderStyle* style, BufferForAppendingHyphen* charactersWithHyphen) const
+TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, BufferForAppendingHyphen* charactersWithHyphen) const
{
ASSERT(style);
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);
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
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()); }
#include "RenderTheme.h"
#include "RenderView.h"
#include "Settings.h"
-#include "TextRun.h"
+#include "SVGTextRunRenderingContext.h"
#include "TransformState.h"
#include <wtf/StdLibExtras.h>
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;
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);
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
#include "RenderBox.h"
#include "RenderLineBoxList.h"
#include "RootInlineBox.h"
+#include "TextRun.h"
#include <wtf/OwnPtr.h>
#include <wtf/ListHashSet.h>
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;
#include "RenderView.h"
#include "Settings.h"
#include "TextBreakIterator.h"
-#include "TextRun.h"
#include "TrailingFloatsRootInlineBox.h"
#include "VerticalPositionCache.h"
#include "break_lines.h"
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()) {
{
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)
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
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;
// 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;
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);
}
{
// 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
#include "config.h"
#include "RenderCombineText.h"
-#include "TextRun.h"
+#include "RenderBlock.h"
namespace WebCore {
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;
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();
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()
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
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);
}
#include "RenderLayer.h"
#include "RenderView.h"
-#include "TextRun.h"
#include <wtf/StdLibExtras.h>
#include <wtf/unicode/CharacterNames.h>
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
#include "Page.h"
#include "RenderLayer.h"
#include "RenderView.h"
-#include "TextRun.h"
#include <wtf/UnusedParam.h>
using namespace std;
// 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);
}
// 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)
#include "ScrollbarTheme.h"
#include "SelectElement.h"
#include "SpatialNavigation.h"
-#include "TextRun.h"
#include <math.h>
using namespace std;
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);
}
}
#include "RenderLayer.h"
#include "RenderListItem.h"
#include "RenderView.h"
-#include "TextRun.h"
#include <wtf/unicode/CharacterNames.h>
using namespace std;
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()) {
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.
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));
}
}
}
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;
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());
}
#include "Text.h"
#include "TextBreakIterator.h"
#include "TextResourceDecoder.h"
-#include "TextRun.h"
#include "VisiblePosition.h"
#include "break_lines.h"
#include <wtf/AlwaysInline.h>
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,
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;
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;
}
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;
}
#include "Text.h"
#include "TextControlInnerElements.h"
#include "TextIterator.h"
-#include "TextRun.h"
#include <wtf/unicode/CharacterNames.h>
using namespace std;
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
#include "SVGTextLayoutEngine.cpp"
#include "SVGTextLayoutEngineBaseline.cpp"
#include "SVGTextLayoutEngineSpacing.cpp"
+#include "SVGTextRunRenderingContext.cpp"
#include "SVGTextMetrics.cpp"
#include "SVGTextQuery.cpp"
#include "RenderSVGResourceSolidColor.h"
#include "SVGImageBufferTools.h"
#include "SVGRootInlineBox.h"
-#include "TextRun.h"
+#include "SVGTextRunRenderingContext.h"
using namespace std;
RenderStyle* style = textRenderer->style();
ASSERT(style);
- TextRun textRun(constructTextRun(style, fragment));
+ TextRun textRun = constructTextRun(style, fragment);
// Eventually handle lengthAdjust="spacingAndGlyphs".
// FIXME: Handle vertical text.
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)
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
}
, 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();
}
// 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;
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)
#include "SVGRenderStyle.h"
#if ENABLE(SVG_FONTS)
+#include "SVGFontData.h"
#include "SVGFontElement.h"
+#include "SVGFontFaceElement.h"
#endif
namespace WebCore {
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) {
#include "SVGTextMetrics.h"
#include "RenderSVGInlineText.h"
-#include "TextRun.h"
+#include "SVGTextRunRenderingContext.h"
namespace WebCore {
, 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();
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());
}
}
/*
* 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
#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;
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);
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>
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;
}
}
} else {
// Fallback to system font fallback
TextRun subRun(run);
+ subRun.setRenderingContext(0);
subRun.setText(subRun.data(i), 1);
(*m_walkerMissingGlyphCallback)(subRun, m_walkerData);
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;
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);
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
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());
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);
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);
}
}
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);
}
}
-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.
--- /dev/null
+/*
+ * 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
#include "SVGFilterElement.cpp"
#include "SVGFilterPrimitiveStandardAttributes.cpp"
#include "SVGFitToViewBox.cpp"
-#include "SVGFont.cpp"
#include "SVGFontData.cpp"
#include "SVGFontElement.cpp"
#include "SVGFontFaceElement.cpp"
#if ENABLE(SVG_FONTS)
#include "SVGFontData.h"
+#include "SVGFontElement.h"
+#include "SVGGlyph.h"
+
namespace WebCore {
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
#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; }
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;
#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)
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;
}
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())
#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)
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;
&& 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);
}
}
#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)
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;
&& 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);
}
}
namespace WebCore {
-class SVGFontData;
-
class SVGVKernElement : public SVGElement {
public:
static PassRefPtr<SVGVKernElement> create(const QualifiedName&, Document*);