merge the formfield patch from ooo-build
[ooovba.git] / filter / source / svg / svgfontexport.cxx
blob6961ea2224dd9c0291bf4d6c0d6a3dbfb81cc42b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svgfontexport.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_filter.hxx"
35 #include "svgfontexport.hxx"
37 static const sal_Int32 nFontEM = 2048;
39 // -----------------
40 // - SVGFontExport -
41 // -----------------
43 SVGFontExport::SVGFontExport( SvXMLExport& rExport, const ::std::vector< ObjectRepresentation >& rObjects ) :
44 mrExport( rExport ),
45 maObjects( rObjects ),
46 mnCurFontId( 0 )
50 // -----------------------------------------------------------------------------
52 SVGFontExport::~SVGFontExport()
56 // -----------------------------------------------------------------------------
58 void SVGFontExport::implCollectGlyphs()
60 VirtualDevice aVDev;
61 ObjectVector::const_iterator aIter( maObjects.begin() );
63 aVDev.EnableOutput( sal_False );
65 while( aIter != maObjects.end() )
67 if( (*aIter).HasRepresentation() )
69 const GDIMetaFile& rMtf = (*aIter).GetRepresentation();
71 aVDev.Push();
73 for( sal_uInt32 i = 0, nCount = rMtf.GetActionCount(); i < nCount; ++i )
75 ::rtl::OUString aText;
76 MetaAction* pAction = rMtf.GetAction( i );
77 const USHORT nType = pAction->GetType();
79 switch( nType )
81 case( META_TEXT_ACTION ):
83 const MetaTextAction* pA = (const MetaTextAction*) pAction;
84 aText = String( pA->GetText(), pA->GetIndex(), pA->GetLen() );
86 break;
88 case( META_TEXTRECT_ACTION ):
90 const MetaTextRectAction* pA = (const MetaTextRectAction*) pAction;
91 aText = pA->GetText();
93 break;
95 case( META_TEXTARRAY_ACTION ):
97 const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pAction;
98 aText = String( pA->GetText(), pA->GetIndex(), pA->GetLen() );
100 break;
102 case( META_STRETCHTEXT_ACTION ):
104 const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pAction;
105 aText = String( pA->GetText(), pA->GetIndex(), pA->GetLen() );
107 break;
109 default:
110 pAction->Execute( &aVDev );
111 break;
114 if( aText.getLength() )
116 const String& rFontName = aVDev.GetFont().GetName();
117 const sal_Unicode* pStr = aText.getStr();
119 for( sal_uInt32 j = 0, nLen = aText.getLength(); j < nLen; ++j )
120 maGlyphs[ rFontName ].insert( pStr[ j ] );
124 aVDev.Pop();
127 ++aIter;
131 // -----------------------------------------------------------------------------
133 void SVGFontExport::implEmbedFont( const ::rtl::OUString& rFontName, const ::std::set< sal_Unicode >& rGlyphs )
135 #ifdef _SVG_EMBED_FONTS
136 ::std::set< sal_Unicode >::const_iterator aIter( rGlyphs.begin() );
137 const ::rtl::OUString aEmbeddedFontStr( B2UCONST( "EmbeddedFont_" ) );
140 SvXMLElementExport aExp( mrExport, XML_NAMESPACE_NONE, "defs", TRUE, TRUE );
141 ::rtl::OUString aCurIdStr( aEmbeddedFontStr );
142 ::rtl::OUString aUnitsPerEM( SVGActionWriter::GetValueString( nFontEM ) );
143 VirtualDevice aVDev;
144 Font aFont( rFontName, Size( 0, nFontEM ) );
146 aVDev.SetMapMode( MAP_100TH_MM );
147 aFont.SetAlign( ALIGN_BASELINE );
148 aVDev.SetFont( aFont );
150 mrExport.AddAttribute( XML_NAMESPACE_NONE, "id", aCurIdStr += SVGActionWriter::GetValueString( ++mnCurFontId ) );
151 mrExport.AddAttribute( XML_NAMESPACE_NONE, "horiz-adv-x", aUnitsPerEM );
154 SvXMLElementExport aExp2( mrExport, XML_NAMESPACE_NONE, "font", TRUE, TRUE );
155 Point aPos;
156 Size aSize( nFontEM, nFontEM );
157 PolyPolygon aMissingGlyphPolyPoly( Rectangle( aPos, aSize ) );
159 aMissingGlyphPolyPoly.Move( 0, -nFontEM );
160 aMissingGlyphPolyPoly.Scale( 1.0, -1.0 );
162 mrExport.AddAttribute( XML_NAMESPACE_NONE, "font-family", GetMappedFontName( rFontName ) );
163 mrExport.AddAttribute( XML_NAMESPACE_NONE, "units-per-em", aUnitsPerEM );
164 mrExport.AddAttribute( XML_NAMESPACE_NONE, "ascent", SVGActionWriter::GetValueString( aVDev.GetFontMetric().GetAscent() ) );
165 mrExport.AddAttribute( XML_NAMESPACE_NONE, "descent", SVGActionWriter::GetValueString( aVDev.GetFontMetric().GetDescent() ) );
168 SvXMLElementExport aExp3( mrExport, XML_NAMESPACE_NONE, "font-face", TRUE, TRUE );
171 mrExport.AddAttribute( XML_NAMESPACE_NONE, "horiz-adv-x", SVGActionWriter::GetValueString( aSize.Width() ) );
174 SvXMLElementExport aExp3( mrExport, XML_NAMESPACE_NONE, "missing-glyph", TRUE, TRUE );
176 mrExport.AddAttribute( XML_NAMESPACE_NONE, "style", B2UCONST( "fill:none;stroke:black;stroke-width:33" ) );
177 mrExport.AddAttribute( XML_NAMESPACE_NONE, "d", SVGActionWriter::GetPathString( aMissingGlyphPolyPoly, sal_False ) );
180 SvXMLElementExport aExp4( mrExport, XML_NAMESPACE_NONE, "path", TRUE, TRUE );
184 while( aIter != rGlyphs.end() )
186 implEmbedGlyph( aVDev, ::rtl::OUString( *aIter ) );
187 ++aIter;
191 #endif
194 // -----------------------------------------------------------------------------
196 void SVGFontExport::implEmbedGlyph( OutputDevice& rOut, const ::rtl::OUString& rGlyphs )
198 PolyPolygon aPolyPoly;
199 ::rtl::OUString aStr( rGlyphs );
200 const sal_Unicode nSpace = ' ';
202 if( rOut.GetTextOutline( aPolyPoly, aStr ) )
204 Rectangle aBoundRect;
206 aPolyPoly.Scale( 1.0, -1.0 );
208 if( !rOut.GetTextBoundRect( aBoundRect, aStr ) )
209 aBoundRect = Rectangle( Point( 0, 0 ), Size( rOut.GetTextWidth( aStr ), 0 ) );
211 mrExport.AddAttribute( XML_NAMESPACE_NONE, "unicode", aStr );
213 if( rGlyphs[ 0 ] == nSpace )
214 aBoundRect = Rectangle( Point( 0, 0 ), Size( rOut.GetTextWidth( sal_Unicode( 'x' ) ), 0 ) );
216 mrExport.AddAttribute( XML_NAMESPACE_NONE, "horiz-adv-x", SVGActionWriter::GetValueString( aBoundRect.GetWidth() ) );
219 SvXMLElementExport aExp( mrExport, XML_NAMESPACE_NONE, "glyph", TRUE, TRUE );
220 const ::rtl::OUString aPathString( SVGActionWriter::GetPathString( aPolyPoly, sal_False ) );
222 if( aPathString.getLength() )
224 mrExport.AddAttribute( XML_NAMESPACE_NONE, "d", aPathString );
227 SvXMLElementExport aElem( mrExport, XML_NAMESPACE_NONE, B2UCONST( "path" ), TRUE, TRUE );
234 // -----------------------------------------------------------------------------
236 void SVGFontExport::EmbedFonts()
238 implCollectGlyphs();
240 GlyphMap::const_iterator aIter( maGlyphs.begin() );
242 while( aIter != maGlyphs.end() )
244 implEmbedFont( (*aIter).first, (*aIter).second );
245 ++aIter;
249 // -----------------------------------------------------------------------------
251 ::rtl::OUString SVGFontExport::GetMappedFontName( const ::rtl::OUString& rFontName ) const
253 ::rtl::OUString aRet( String( rFontName ).GetToken( 0, ';' ) );
255 #ifdef _SVG_EMBED_FONTS
256 if( mnCurFontId )
257 aRet += B2UCONST( " embedded" );
258 #endif
260 return aRet;