Dear LibreOffice community, I wrote patches for SVG export filter. These fix a bug that texts in an exported SVG are invisible. The most of codes come from Flash export filter (filters/filter/source/swfwriter1.cxx).
Regards, -- KUROSAWA, Takeshi <taken....@gmail.com>
From e10fcbcc9d95eb24505126e6b9ea0313cccd7434 Mon Sep 17 00:00:00 2001 From: Takeshi Kurosawa <taken....@gmail.com> Date: Tue, 4 Jan 2011 13:18:55 +0900 Subject: [PATCH 1/4] Add 'px' unit to 'font-size' Firefox and Opera don't accept unitless font-size values. --- filter/source/svg/svgwriter.cxx | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx index 8b18650..af305ac 100644 --- a/filter/source/svg/svgwriter.cxx +++ b/filter/source/svg/svgwriter.cxx @@ -265,6 +265,7 @@ NMSP_RTL::OUString SVGAttributeWriter::GetFontStyle( const Font& rFont ) aStyle += B2UCONST( ";" ); aStyle += B2UCONST( "font-size:" ); aStyle += SVGActionWriter::GetValueString( rFont.GetHeight() ); + aStyle += B2UCONST( "px" ); // font style /* -- 1.7.1
From 8a4d52c041f691003a34c5107c88c0f820bd1178 Mon Sep 17 00:00:00 2001 From: Takeshi Kurosawa <taken....@gmail.com> Date: Tue, 4 Jan 2011 13:22:26 +0900 Subject: [PATCH 2/4] Use simple syntax for glyph definition Opera and Chrome don't support complex syntax for SVG fonts glyph definition (child elements of glyph element). --- filter/source/svg/svgfontexport.cxx | 27 ++++++++++----------------- 1 files changed, 10 insertions(+), 17 deletions(-) diff --git a/filter/source/svg/svgfontexport.cxx b/filter/source/svg/svgfontexport.cxx index 605f878..0c00a06 100644 --- a/filter/source/svg/svgfontexport.cxx +++ b/filter/source/svg/svgfontexport.cxx @@ -168,15 +168,11 @@ void SVGFontExport::implEmbedFont( const ::rtl::OUString& rFontName, const ::std mrExport.AddAttribute( XML_NAMESPACE_NONE, "horiz-adv-x", SVGActionWriter::GetValueString( aSize.Width() ) ); + mrExport.AddAttribute( XML_NAMESPACE_NONE, "style", B2UCONST( "fill:none;stroke:black;stroke-width:33" ) ); + mrExport.AddAttribute( XML_NAMESPACE_NONE, "d", SVGActionWriter::GetPathString( aMissingGlyphPolyPoly, sal_False ) ); + { SvXMLElementExport aExp3( mrExport, XML_NAMESPACE_NONE, "missing-glyph", TRUE, TRUE ); - - mrExport.AddAttribute( XML_NAMESPACE_NONE, "style", B2UCONST( "fill:none;stroke:black;stroke-width:33" ) ); - mrExport.AddAttribute( XML_NAMESPACE_NONE, "d", SVGActionWriter::GetPathString( aMissingGlyphPolyPoly, sal_False ) ); - - { - SvXMLElementExport aExp4( mrExport, XML_NAMESPACE_NONE, "path", TRUE, TRUE ); - } } while( aIter != rGlyphs.end() ) @@ -213,18 +209,15 @@ void SVGFontExport::implEmbedGlyph( OutputDevice& rOut, const ::rtl::OUString& r mrExport.AddAttribute( XML_NAMESPACE_NONE, "horiz-adv-x", SVGActionWriter::GetValueString( aBoundRect.GetWidth() ) ); + const ::rtl::OUString aPathString( SVGActionWriter::GetPathString( aPolyPoly, sal_False ) ); + + if( aPathString.getLength() ) + { + mrExport.AddAttribute( XML_NAMESPACE_NONE, "d", aPathString ); + } + { SvXMLElementExport aExp( mrExport, XML_NAMESPACE_NONE, "glyph", TRUE, TRUE ); - const ::rtl::OUString aPathString( SVGActionWriter::GetPathString( aPolyPoly, sal_False ) ); - - if( aPathString.getLength() ) - { - mrExport.AddAttribute( XML_NAMESPACE_NONE, "d", aPathString ); - - { - SvXMLElementExport aElem( mrExport, XML_NAMESPACE_NONE, B2UCONST( "path" ), TRUE, TRUE ); - } - } } } } -- 1.7.1
From da3b25f75fd1293b5278e056b080703ad531ce29 Mon Sep 17 00:00:00 2001 From: Takeshi Kurosawa <taken....@gmail.com> Date: Tue, 4 Jan 2011 13:25:12 +0900 Subject: [PATCH 3/4] Remove redundant 'g' element pTransform is completely redundant. --- filter/source/svg/svgwriter.cxx | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx index af305ac..608f6b5 100644 --- a/filter/source/svg/svgwriter.cxx +++ b/filter/source/svg/svgwriter.cxx @@ -848,7 +848,6 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, const String& rText, const Font& rFont = mpVDev->GetFont(); const FontMetric aMetric( mpVDev->GetFontMetric() ); Point aBaseLinePos( rPos ); - SvXMLElementExport* pTransform = NULL; // always adjust text position to match baseline alignment switch( rFont.GetAlign() ) @@ -904,7 +903,6 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, const String& rText, aTransform += ')'; mrExport.AddAttribute( XML_NAMESPACE_NONE, aXMLAttrTransform, aTransform ); - pTransform = new SvXMLElementExport( mrExport, XML_NAMESPACE_NONE, aXMLElemG, TRUE, TRUE ); } // add additional style if requested @@ -989,7 +987,6 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, const String& rText, #endif // _SVG_USE_NATIVE_TEXTDECORATION delete[] pOwnArray; - delete pTransform; } } -- 1.7.1
From dc6a73c1057d83afa77f89e8c0686a4da0f397ca Mon Sep 17 00:00:00 2001 From: Takeshi Kurosawa <taken....@gmail.com> Date: Tue, 4 Jan 2011 13:31:47 +0900 Subject: [PATCH 4/4] Export text color The color selection logic is what flash export filter does. --- filter/source/svg/svgwriter.cxx | 97 +++++++++++++++++++++++++++++++++++++-- filter/source/svg/svgwriter.hxx | 1 + 2 files changed, 94 insertions(+), 4 deletions(-) diff --git a/filter/source/svg/svgwriter.cxx b/filter/source/svg/svgwriter.cxx index 608f6b5..7765ea5 100644 --- a/filter/source/svg/svgwriter.cxx +++ b/filter/source/svg/svgwriter.cxx @@ -809,6 +809,97 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, const String& rText, const sal_Int32* pDXArray, long nWidth, const NMSP_RTL::OUString* pStyle ) { + const FontMetric aMetric( mpVDev->GetFontMetric() ); + + bool bTextSpecial = aMetric.IsShadow() || aMetric.IsOutline() || (aMetric.GetRelief() != RELIEF_NONE); + + if( !bTextSpecial ) + { + ImplWriteText( rPos, rText, pDXArray, nWidth, pStyle, mpVDev->GetTextColor() ); + } + else + { + if( aMetric.GetRelief() != RELIEF_NONE ) + { + Color aReliefColor( COL_LIGHTGRAY ); + Color aTextColor( mpVDev->GetTextColor() ); + + if ( aTextColor.GetColor() == COL_BLACK ) + aTextColor = Color( COL_WHITE ); + + if ( aTextColor.GetColor() == COL_WHITE ) + aReliefColor = Color( COL_BLACK ); + + + Point aPos( rPos ); + Point aOffset( 6, 6 ); + + if ( aMetric.GetRelief() == RELIEF_ENGRAVED ) + { + aPos -= aOffset; + } + else + { + aPos += aOffset; + } + + ImplWriteText( aPos, rText, pDXArray, nWidth, pStyle, aReliefColor ); + ImplWriteText( rPos, rText, pDXArray, nWidth, pStyle, aTextColor ); + } + else + { + if( aMetric.IsShadow() ) + { + long nOff = 1 + ((aMetric.GetLineHeight()-24)/24); + if ( aMetric.IsOutline() ) + nOff += 6; + + Color aTextColor( mpVDev->GetTextColor() ); + Color aShadowColor = Color( COL_BLACK ); + + if ( (aTextColor.GetColor() == COL_BLACK) || (aTextColor.GetLuminance() < 8) ) + aShadowColor = Color( COL_LIGHTGRAY ); + + Point aPos( rPos ); + aPos += Point( nOff, nOff ); + ImplWriteText( aPos, rText, pDXArray, nWidth, pStyle, aShadowColor ); + + if( !aMetric.IsOutline() ) + { + ImplWriteText( rPos, rText, pDXArray, nWidth, pStyle, aTextColor ); + } + } + + if( aMetric.IsOutline() ) + { + Point aPos = rPos + Point( -6, -6 ); + ImplWriteText( aPos, rText, pDXArray, nWidth, pStyle, mpVDev->GetTextColor() ); + aPos = rPos + Point( +6, +6); + ImplWriteText( aPos, rText, pDXArray, nWidth, pStyle, mpVDev->GetTextColor() ); + aPos = rPos + Point( -6, +0); + ImplWriteText( aPos, rText, pDXArray, nWidth, pStyle, mpVDev->GetTextColor() ); + aPos = rPos + Point( -6, +6); + ImplWriteText( aPos, rText, pDXArray, nWidth, pStyle, mpVDev->GetTextColor() ); + aPos = rPos + Point( +0, +6); + ImplWriteText( aPos, rText, pDXArray, nWidth, pStyle, mpVDev->GetTextColor() ); + aPos = rPos + Point( +0, -6); + ImplWriteText( aPos, rText, pDXArray, nWidth, pStyle, mpVDev->GetTextColor() ); + aPos = rPos + Point( +6, -1); + ImplWriteText( aPos, rText, pDXArray, nWidth, pStyle, mpVDev->GetTextColor() ); + aPos = rPos + Point( +6, +0); + ImplWriteText( aPos, rText, pDXArray, nWidth, pStyle, mpVDev->GetTextColor() ); + + ImplWriteText( rPos, rText, pDXArray, nWidth, pStyle, Color( COL_WHITE ) ); + } + } + } +} + +void SVGActionWriter::ImplWriteText( const Point& rPos, const String& rText, + const sal_Int32* pDXArray, long nWidth, + const NMSP_RTL::OUString* pStyle, + Color aTextColor ) +{ long nLen = rText.Len(), i; if( nLen ) @@ -864,6 +955,8 @@ void SVGActionWriter::ImplWriteText( const Point& rPos, const String& rText, break; } + mpContext->SetPaintAttr( COL_TRANSPARENT, aTextColor ); + // get mapped text position const Point aPt( ImplMap( aBaseLinePos ) ); @@ -1528,7 +1621,6 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, aFont.SetHeight( ImplMap( Size( 0, aFont.GetHeight() ) ).Height() ); mpContext->SetFontAttr( aFont ); - mpContext->SetPaintAttr( COL_TRANSPARENT, aFont.GetColor() ); ImplWriteText( pA->GetPoint(), String( pA->GetText(), pA->GetIndex(), pA->GetLen() ), NULL, 0, pStyle ); } } @@ -1543,7 +1635,6 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, aFont.SetHeight( ImplMap( Size( 0, aFont.GetHeight() ) ).Height() ); mpContext->SetFontAttr( aFont ); - mpContext->SetPaintAttr( COL_TRANSPARENT, aFont.GetColor() ); ImplWriteText( pA->GetRect().TopLeft(), pA->GetText(), NULL, 0, pStyle ); } } @@ -1559,7 +1650,6 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, aFont.SetHeight( ImplMap( Size( 0, aFont.GetHeight() ) ).Height() ); mpContext->SetFontAttr( aFont ); - mpContext->SetPaintAttr( COL_TRANSPARENT, aFont.GetColor() ); ImplWriteText( pA->GetPoint(), String( pA->GetText(), pA->GetIndex(), pA->GetLen() ), pA->GetDXArray(), 0, pStyle ); } } @@ -1574,7 +1664,6 @@ void SVGActionWriter::ImplWriteActions( const GDIMetaFile& rMtf, aFont.SetHeight( ImplMap( Size( 0, aFont.GetHeight() ) ).Height() ); mpContext->SetFontAttr( aFont ); - mpContext->SetPaintAttr( COL_TRANSPARENT, aFont.GetColor() ); ImplWriteText( pA->GetPoint(), String( pA->GetText(), pA->GetIndex(), pA->GetLen() ), NULL, pA->GetWidth(), pStyle ); } } diff --git a/filter/source/svg/svgwriter.hxx b/filter/source/svg/svgwriter.hxx index 1bd7867..e1467c3 100644 --- a/filter/source/svg/svgwriter.hxx +++ b/filter/source/svg/svgwriter.hxx @@ -187,6 +187,7 @@ private: void ImplWritePolyPolygon( const PolyPolygon& rPolyPoly, sal_Bool bLineOnly, const ::rtl::OUString* pStyle = NULL ); void ImplWriteGradientEx( const PolyPolygon& rPolyPoly, const Gradient& rGradient, const ::rtl::OUString* pStyle, sal_uInt32 nWriteFlags ); void ImplWriteText( const Point& rPos, const String& rText, const sal_Int32* pDXArray, long nWidth, const ::rtl::OUString* pStyle = NULL ); + void ImplWriteText( const Point& rPos, const String& rText, const sal_Int32* pDXArray, long nWidth, const ::rtl::OUString* pStyle, Color aTextColor ); void ImplWriteBmp( const BitmapEx& rBmpEx, const Point& rPt, const Size& rSz, const Point& rSrcPt, const Size& rSrcSz, const ::rtl::OUString* pStyle = NULL ); void ImplCheckFontAttributes(); -- 1.7.1
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice