SVG export: fix missing custom bullets
It seems this was broken since b76628acb1
(text export support for bullets and hyperlinks, 2012-08-11), the
problem is that SVGFilter::implEmbedBulletGlyphs() has a fixed list of
characters that are typically used as bullets, but e.g. "-" is missing
from that list.
Fix this by improving SVGTextWriter::implWriteBulletChars() to continue
working from those shared glyph paths when the glyph is in the fixed
list, but otherwise call GetTextOutline() to look up the path for the
custom bullet.
Change-Id: I3de8fab8dc6c78e273629d13566d1f9f289eb752
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128495
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
This commit is contained in:
parent
586a0f149f
commit
bbc4360b5b
6 changed files with 100 additions and 5 deletions
36
filter/qa/unit/data/custom-bullet.fodp
Normal file
36
filter/qa/unit/data/custom-bullet.fodp
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<office:document xmlns:presentation="urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.presentation">
|
||||
<office:automatic-styles>
|
||||
<style:page-layout style:name="PM1">
|
||||
<style:page-layout-properties fo:margin-top="0cm" fo:margin-bottom="0cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:page-width="28cm" fo:page-height="15.75cm" style:print-orientation="landscape"/>
|
||||
</style:page-layout>
|
||||
<style:style style:name="gr1" style:family="graphic" style:parent-style-name="standard">
|
||||
<style:graphic-properties draw:stroke="none" svg:stroke-color="#000000" draw:fill="none" draw:fill-color="#ffffff" draw:auto-grow-height="true" draw:auto-grow-width="false" fo:max-height="0cm" fo:min-height="0cm"/>
|
||||
</style:style>
|
||||
<text:list-style style:name="L1">
|
||||
<text:list-level-style-bullet text:level="1" text:bullet-char="-">
|
||||
<style:list-level-properties text:min-label-width="0.6cm"/>
|
||||
<style:text-properties fo:font-family="OpenSymbol" style:font-style-name="Regular" style:font-charset="x-symbol" style:use-window-font-color="true" fo:font-size="45%"/>
|
||||
</text:list-level-style-bullet>
|
||||
</text:list-style>
|
||||
</office:automatic-styles>
|
||||
<office:master-styles>
|
||||
<style:master-page style:name="Default" style:page-layout-name="PM1">
|
||||
</style:master-page>
|
||||
</office:master-styles>
|
||||
<office:body>
|
||||
<office:presentation>
|
||||
<draw:page draw:name="page1" draw:master-page-name="Default">
|
||||
<draw:frame draw:style-name="gr1" draw:text-style-name="P8" draw:layer="layout" svg:width="9.525cm" svg:height="0.962cm" svg:x="3.175cm" svg:y="2.54cm">
|
||||
<draw:text-box>
|
||||
<text:list text:style-name="L1">
|
||||
<text:list-item>
|
||||
<text:p>hello</text:p>
|
||||
</text:list-item>
|
||||
</text:list>
|
||||
</draw:text-box>
|
||||
</draw:frame>
|
||||
</draw:page>
|
||||
</office:presentation>
|
||||
</office:body>
|
||||
</office:document>
|
|
@ -182,6 +182,33 @@ CPPUNIT_TEST_FIXTURE(SvgFilterTest, testShapeNographic)
|
|||
xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList());
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(SvgFilterTest, testCustomBullet)
|
||||
{
|
||||
// Given a presentation with a custom bullet:
|
||||
load(u"custom-bullet.fodp");
|
||||
|
||||
// When exporting that to SVG:
|
||||
uno::Reference<frame::XStorable> xStorable(getComponent(), uno::UNO_QUERY_THROW);
|
||||
SvMemoryStream aStream;
|
||||
uno::Reference<io::XOutputStream> xOut = new utl::OOutputStreamWrapper(aStream);
|
||||
utl::MediaDescriptor aMediaDescriptor;
|
||||
aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export");
|
||||
aMediaDescriptor["OutputStream"] <<= xOut;
|
||||
xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList());
|
||||
|
||||
// Then make sure the bullet glyph is not lost:
|
||||
aStream.Seek(STREAM_SEEK_TO_BEGIN);
|
||||
xmlDocUniquePtr pXmlDoc = parseXmlStream(&aStream);
|
||||
// Without the accompanying fix in place, this test would have failed with:
|
||||
// - Expected: 1
|
||||
// - Actual : 0
|
||||
// - XPath '//svg:g[@class='BulletChars']//svg:path' number of nodes is incorrect
|
||||
// i.e. the custom bullet used '<use transform="scale(285,285)"
|
||||
// xlink:href="#bullet-char-template-45"/>', but nobody produced a bullet-char-template-45,
|
||||
// instead we need the path of the glyph inline.
|
||||
CPPUNIT_ASSERT(!getXPath(pXmlDoc, "//svg:g[@class='BulletChars']//svg:path", "d").isEmpty());
|
||||
}
|
||||
|
||||
CPPUNIT_PLUGIN_IMPLEMENT();
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
|
@ -1524,6 +1524,7 @@ void SVGFilter::implEmbedBulletGlyph( sal_Unicode cBullet, const OUString & sPat
|
|||
mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "d", sPathData );
|
||||
SvXMLElementExport aPathElem( *mpSVGExport, XML_NAMESPACE_NONE, "path", true, true );
|
||||
|
||||
mpSVGExport->SetEmbeddedBulletGlyph(cBullet);
|
||||
}
|
||||
|
||||
void SVGFilter::implExportBackgroundBitmaps()
|
||||
|
@ -2858,4 +2859,15 @@ void SVGExport::writeMtf( const GDIMetaFile& rMtf )
|
|||
}
|
||||
}
|
||||
|
||||
void SVGExport::SetEmbeddedBulletGlyph(sal_Unicode cBullet)
|
||||
{
|
||||
maEmbeddedBulletGlyphs.insert(cBullet);
|
||||
}
|
||||
|
||||
bool SVGExport::IsEmbeddedBulletGlyph(sal_Unicode cBullet) const
|
||||
{
|
||||
auto it = maEmbeddedBulletGlyphs.find(cBullet);
|
||||
return it != maEmbeddedBulletGlyphs.end();
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
|
|
@ -66,6 +66,7 @@ class SVGExport : public SvXMLExport
|
|||
bool mbIsUseOpacity;
|
||||
bool mbIsUseNativeTextDecoration;
|
||||
bool mbIsUsePositionedCharacters;
|
||||
std::set<sal_Unicode> maEmbeddedBulletGlyphs;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -84,6 +85,9 @@ public:
|
|||
|
||||
void writeMtf( const GDIMetaFile& rMtf );
|
||||
|
||||
void SetEmbeddedBulletGlyph(sal_Unicode cBullet);
|
||||
bool IsEmbeddedBulletGlyph(sal_Unicode cBullet) const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void ExportStyles_( bool /* bUsed */ ) override {}
|
||||
|
|
|
@ -1416,11 +1416,12 @@ void SVGTextWriter::implWriteBulletChars()
|
|||
|
||||
SvXMLElementExport aPositioningElem( mrExport, XML_NAMESPACE_NONE, aXMLElemG, true, true );
|
||||
|
||||
// <use transform="scale(font-size)" xlink:ref="/" >
|
||||
if (mrExport.IsEmbeddedBulletGlyph(rInfo.cBulletChar))
|
||||
{
|
||||
// <use transform="scale(font-size)" xlink:ref="/" >
|
||||
// Add size attribute through a scaling
|
||||
sScaling = "scale(" + OUString::number( rInfo.nFontSize ) +
|
||||
"," + OUString::number( rInfo.nFontSize )+ ")";
|
||||
sScaling = "scale(" + OUString::number( rInfo.aFont.GetFontHeight() ) +
|
||||
"," + OUString::number( rInfo.aFont.GetFontHeight() )+ ")";
|
||||
mrExport.AddAttribute( XML_NAMESPACE_NONE, "transform", sScaling );
|
||||
|
||||
// Add ref attribute
|
||||
|
@ -1430,6 +1431,21 @@ void SVGTextWriter::implWriteBulletChars()
|
|||
|
||||
SvXMLElementExport aRefElem( mrExport, XML_NAMESPACE_NONE, "use", true, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
// <path d="...">
|
||||
tools::PolyPolygon aPolyPolygon;
|
||||
OUString aStr(rInfo.cBulletChar);
|
||||
mpVDev->Push(vcl::PushFlags::FONT);
|
||||
mpVDev->SetFont(rInfo.aFont);
|
||||
if (mpVDev->GetTextOutline(aPolyPolygon, aStr))
|
||||
{
|
||||
OUString aPathString(SVGActionWriter::GetPathString(aPolyPolygon, false));
|
||||
mrExport.AddAttribute(XML_NAMESPACE_NONE, "d", aPathString);
|
||||
SvXMLElementExport aPath(mrExport, XML_NAMESPACE_NONE, "path", true, true);
|
||||
}
|
||||
mpVDev->Pop();
|
||||
}
|
||||
} // close aPositioningElem
|
||||
}
|
||||
|
||||
|
@ -1684,7 +1700,7 @@ void SVGTextWriter::implWriteTextPortion( const Point& rPos,
|
|||
{
|
||||
sId += ".bp";
|
||||
BulletListItemInfo& aBulletListItemInfo = maBulletListItemMap[ sId ];
|
||||
aBulletListItemInfo.nFontSize = rFont.GetFontHeight();
|
||||
aBulletListItemInfo.aFont = rFont;
|
||||
aBulletListItemInfo.aColor = aTextColor;
|
||||
aBulletListItemInfo.aPos = maTextPos;
|
||||
aBulletListItemInfo.cBulletChar = mcBulletChar;
|
||||
|
|
|
@ -188,7 +188,7 @@ class GDIMetaFile;
|
|||
|
||||
struct BulletListItemInfo
|
||||
{
|
||||
tools::Long nFontSize;
|
||||
vcl::Font aFont;
|
||||
Color aColor;
|
||||
Point aPos;
|
||||
sal_Unicode cBulletChar;
|
||||
|
|
Loading…
Reference in a new issue