bump product version to 5.0.4.1
[LibreOffice.git] / xmloff / source / style / XMLFontStylesContext.cxx
blob373e116bf9a89bd5c1605902f3b43a271d05dd62
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <xmloff/XMLFontStylesContext.hxx>
21 #include "XMLFontStylesContext_impl.hxx"
23 #include <com/sun/star/awt/FontFamily.hpp>
24 #include <com/sun/star/awt/FontPitch.hpp>
25 #include <com/sun/star/embed/ElementModes.hpp>
27 #include <comphelper/seqstream.hxx>
29 #include <osl/file.hxx>
30 #include <vcl/embeddedfontshelper.hxx>
32 #include <xmloff/nmspmap.hxx>
33 #include <xmloff/xmlnmspe.hxx>
34 #include <xmloff/xmltoken.hxx>
35 #include "fonthdl.hxx"
36 #include <xmloff/xmlimp.hxx>
37 #include <xmloff/maptype.hxx>
38 #include <xmloff/XMLBase64ImportContext.hxx>
41 using namespace ::com::sun::star;
42 using namespace ::com::sun::star::uno;
43 using namespace ::com::sun::star::xml::sax;
44 using namespace ::com::sun::star::container;
45 using namespace ::com::sun::star::beans;
46 using namespace ::com::sun::star::lang;
47 using namespace ::com::sun::star::awt;
48 using namespace ::xmloff::token;
51 #define XML_STYLE_FAMILY_FONT 1
53 enum XMLFontStyleAttrTokens
55 XML_TOK_FONT_STYLE_ATTR_FAMILY,
56 XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC,
57 XML_TOK_FONT_STYLE_ATTR_STYLENAME,
58 XML_TOK_FONT_STYLE_ATTR_PITCH,
59 XML_TOK_FONT_STYLE_ATTR_CHARSET,
61 XML_TOK_FONT_STYLE_ATTR_END=XML_TOK_UNKNOWN
64 static const SvXMLTokenMapEntry* lcl_getFontStyleAttrTokenMap()
66 static const SvXMLTokenMapEntry aFontStyleAttrTokenMap[] =
68 { XML_NAMESPACE_SVG, XML_FONT_FAMILY,
69 XML_TOK_FONT_STYLE_ATTR_FAMILY },
70 { XML_NAMESPACE_STYLE, XML_FONT_FAMILY_GENERIC,
71 XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC },
72 { XML_NAMESPACE_STYLE, XML_FONT_ADORNMENTS,
73 XML_TOK_FONT_STYLE_ATTR_STYLENAME },
74 { XML_NAMESPACE_STYLE, XML_FONT_PITCH,
75 XML_TOK_FONT_STYLE_ATTR_PITCH },
76 { XML_NAMESPACE_STYLE, XML_FONT_CHARSET,
77 XML_TOK_FONT_STYLE_ATTR_CHARSET },
79 XML_TOKEN_MAP_END
81 return aFontStyleAttrTokenMap;
84 TYPEINIT1( XMLFontStyleContextFontFace, SvXMLStyleContext );
86 XMLFontStyleContextFontFace::XMLFontStyleContextFontFace( SvXMLImport& rImport,
87 sal_uInt16 nPrfx, const OUString& rLName,
88 const Reference< XAttributeList > & xAttrList,
89 XMLFontStylesContext& rStyles ) :
90 SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, XML_STYLE_FAMILY_FONT ),
91 xStyles( &rStyles )
93 OUString sEmpty;
94 aFamilyName <<= sEmpty;
95 aStyleName <<= sEmpty;
96 aFamily <<= (sal_Int16)awt::FontFamily::DONTKNOW;
97 aPitch <<= (sal_Int16)awt::FontPitch::DONTKNOW;
98 aEnc <<= (sal_Int16)rStyles.GetDfltCharset();
101 void XMLFontStyleContextFontFace::SetAttribute( sal_uInt16 nPrefixKey,
102 const OUString& rLocalName,
103 const OUString& rValue )
105 SvXMLUnitConverter& rUnitConv = GetImport().GetMM100UnitConverter();
106 const SvXMLTokenMap& rTokenMap = GetStyles()->GetFontStyleAttrTokenMap();
107 Any aAny;
109 switch( rTokenMap.Get( nPrefixKey, rLocalName ) )
111 case XML_TOK_FONT_STYLE_ATTR_FAMILY:
112 if( GetStyles()->GetFamilyNameHdl().importXML( rValue, aAny,
113 rUnitConv ) )
114 aFamilyName = aAny;
115 break;
116 case XML_TOK_FONT_STYLE_ATTR_STYLENAME:
117 aStyleName <<= rValue;
118 break;
119 case XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC:
120 if( GetStyles()->GetFamilyHdl().importXML( rValue, aAny,
121 rUnitConv ) )
122 aFamily = aAny;
123 break;
124 case XML_TOK_FONT_STYLE_ATTR_PITCH:
125 if( GetStyles()->GetPitchHdl().importXML( rValue, aAny,
126 rUnitConv ) )
127 aPitch = aAny;
128 break;
129 case XML_TOK_FONT_STYLE_ATTR_CHARSET:
130 if( GetStyles()->GetEncodingHdl().importXML( rValue, aAny,
131 rUnitConv ) )
132 aEnc = aAny;
133 break;
134 default:
135 SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
136 break;
140 XMLFontStyleContextFontFace::~XMLFontStyleContextFontFace()
144 void XMLFontStyleContextFontFace::FillProperties(
145 ::std::vector< XMLPropertyState > &rProps,
146 sal_Int32 nFamilyNameIdx,
147 sal_Int32 nStyleNameIdx,
148 sal_Int32 nFamilyIdx,
149 sal_Int32 nPitchIdx,
150 sal_Int32 nCharsetIdx ) const
152 if( nFamilyNameIdx != -1 )
154 XMLPropertyState aPropState( nFamilyNameIdx, aFamilyName );
155 rProps.push_back( aPropState );
157 if( nStyleNameIdx != -1 )
159 XMLPropertyState aPropState( nStyleNameIdx, aStyleName );
160 rProps.push_back( aPropState );
162 if( nFamilyIdx != -1 )
164 XMLPropertyState aPropState( nFamilyIdx, aFamily );
165 rProps.push_back( aPropState );
167 if( nPitchIdx != -1 )
169 XMLPropertyState aPropState( nPitchIdx, aPitch );
170 rProps.push_back( aPropState );
172 if( nCharsetIdx != -1 )
174 XMLPropertyState aPropState( nCharsetIdx, aEnc );
175 rProps.push_back( aPropState );
179 SvXMLImportContext * XMLFontStyleContextFontFace::CreateChildContext(
180 sal_uInt16 nPrefix,
181 const OUString& rLocalName,
182 const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList )
184 if( nPrefix == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_FONT_FACE_SRC ))
185 return new XMLFontStyleContextFontFaceSrc( GetImport(), nPrefix, rLocalName, *this );
186 return SvXMLStyleContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
189 OUString XMLFontStyleContextFontFace::familyName() const
191 OUString ret;
192 aFamilyName >>= ret;
193 return ret;
196 TYPEINIT1( XMLFontStyleContextFontFaceFormat, SvXMLStyleContext );
198 XMLFontStyleContextFontFaceFormat::XMLFontStyleContextFontFaceFormat( SvXMLImport& rImport,
199 sal_uInt16 nPrfx, const OUString& rLName,
200 const ::com::sun::star::uno::Reference<
201 ::com::sun::star::xml::sax::XAttributeList > &xAttrList,
202 XMLFontStyleContextFontFaceUri& _uri )
203 : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList)
204 , uri(_uri)
208 void XMLFontStyleContextFontFaceFormat::SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
209 const OUString& rValue )
211 if( nPrefixKey == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_STRING ))
212 uri.SetFormat(rValue);
213 else
214 SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
217 TYPEINIT1( XMLFontStyleContextFontFaceSrc, SvXMLImportContext );
219 XMLFontStyleContextFontFaceSrc::XMLFontStyleContextFontFaceSrc( SvXMLImport& rImport,
220 sal_uInt16 nPrfx, const OUString& rLName,
221 const XMLFontStyleContextFontFace& _font )
222 : SvXMLImportContext( rImport, nPrfx, rLName )
223 , font( _font )
227 SvXMLImportContext * XMLFontStyleContextFontFaceSrc::CreateChildContext(
228 sal_uInt16 nPrefix,
229 const OUString& rLocalName,
230 const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList )
232 if( nPrefix == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_FONT_FACE_URI ))
233 return new XMLFontStyleContextFontFaceUri( GetImport(), nPrefix, rLocalName, xAttrList, font );
234 return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
238 TYPEINIT1( XMLFontStyleContextFontFaceUri, SvXMLImportContext );
240 XMLFontStyleContextFontFaceUri::XMLFontStyleContextFontFaceUri( SvXMLImport& rImport,
241 sal_uInt16 nPrfx, const OUString& rLName,
242 const ::com::sun::star::uno::Reference<
243 ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
244 const XMLFontStyleContextFontFace& _font )
245 : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList )
246 , font( _font )
250 SvXMLImportContext * XMLFontStyleContextFontFaceUri::CreateChildContext(
251 sal_uInt16 nPrefix,
252 const OUString& rLocalName,
253 const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList )
255 if( nPrefix == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_FONT_FACE_FORMAT ))
256 return new XMLFontStyleContextFontFaceFormat( GetImport(), nPrefix, rLocalName, xAttrList, *this );
257 if( linkPath.isEmpty() && ( nPrefix == XML_NAMESPACE_OFFICE ) && IsXMLToken( rLocalName, XML_BINARY_DATA ) )
259 mxBase64Stream.set( new comphelper::OSequenceOutputStream( maFontData ) );
260 if( mxBase64Stream.is() )
261 return new XMLBase64ImportContext( GetImport(), nPrefix, rLocalName, xAttrList, mxBase64Stream );
263 return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
266 void XMLFontStyleContextFontFaceUri::SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
267 const OUString& rValue )
269 if( nPrefixKey == XML_NAMESPACE_XLINK && IsXMLToken( rLocalName, XML_HREF ))
270 linkPath = rValue;
271 else
272 SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
275 void XMLFontStyleContextFontFaceUri::SetFormat( const OUString& rFormat )
277 format = rFormat;
280 // the CSS2 standard ( http://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#referencing )
281 // defines these format strings.
282 const char* OPENTYPE_FORMAT = "opentype";
283 const char* TRUETYPE_FORMAT = "truetype";
284 const char* EOT_FORMAT = "embedded-opentype";
286 void XMLFontStyleContextFontFaceUri::EndElement()
288 if( ( linkPath.getLength() == 0 ) && ( maFontData.getLength() == 0 ) )
290 SAL_WARN( "xmloff", "svg:font-face-uri tag with no link or base64 data; ignoring." );
291 return;
293 bool eot;
294 // Assume by default that the font is not compressed.
295 if( format.getLength() == 0
296 || format.equalsAscii( OPENTYPE_FORMAT )
297 || format.equalsAscii( TRUETYPE_FORMAT ))
299 eot = false;
301 else if( format.equalsAscii( EOT_FORMAT ))
303 eot = true;
305 else
307 SAL_WARN( "xmloff", "Unknown format of embedded font; assuming TTF." );
308 eot = false;
310 if ( maFontData.getLength() == 0 )
311 handleEmbeddedFont( linkPath, eot );
312 else
313 handleEmbeddedFont( maFontData, eot );
316 void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const OUString& url, bool eot )
318 if( GetImport().embeddedFontAlreadyProcessed( url ))
320 GetImport().NotifyEmbeddedFontRead();
321 return;
323 OUString fontName = font.familyName();
324 // If there's any giveMeStreamForThisURL(), then it's well-hidden for me to find it.
325 if( GetImport().IsPackageURL( url ))
327 uno::Reference< embed::XStorage > storage;
328 storage.set( GetImport().GetSourceStorage(), UNO_QUERY_THROW );
329 if( url.indexOf( '/' ) > -1 ) // TODO what if more levels?
330 storage.set( storage->openStorageElement( url.copy( 0, url.indexOf( '/' )),
331 ::embed::ElementModes::READ ), uno::UNO_QUERY_THROW );
332 uno::Reference< io::XInputStream > inputStream;
333 inputStream.set( storage->openStreamElement( url.copy( url.indexOf( '/' ) + 1 ), ::embed::ElementModes::READ ),
334 UNO_QUERY_THROW );
335 if( EmbeddedFontsHelper::addEmbeddedFont( inputStream, fontName, "?", std::vector< unsigned char >(), eot ))
336 GetImport().NotifyEmbeddedFontRead();
337 inputStream->closeInput();
339 else
340 SAL_WARN( "xmloff", "External URL for font file not handled." );
343 void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const ::css::uno::Sequence< sal_Int8 >& rData, const bool eot )
345 const uno::Reference< io::XInputStream > xInput( new comphelper::SequenceInputStream( rData ) );
346 const OUString fontName = font.familyName();
347 if( EmbeddedFontsHelper::addEmbeddedFont( xInput, fontName, "?", std::vector< unsigned char >(), eot ) )
348 GetImport().NotifyEmbeddedFontRead();
349 xInput->closeInput();
352 SvXMLStyleContext *XMLFontStylesContext::CreateStyleChildContext(
353 sal_uInt16 nPrefix,
354 const OUString& rLocalName,
355 const ::com::sun::star::uno::Reference<
356 ::com::sun::star::xml::sax::XAttributeList > & xAttrList )
358 SvXMLStyleContext *pStyle;
359 if( XML_NAMESPACE_STYLE == nPrefix &&
360 IsXMLToken( rLocalName, XML_FONT_FACE ) )
362 pStyle = new XMLFontStyleContextFontFace( GetImport(), nPrefix,
363 rLocalName, xAttrList, *this );
365 else
367 pStyle = SvXMLStylesContext::CreateStyleChildContext( nPrefix,
368 rLocalName, xAttrList );
371 return pStyle;
374 TYPEINIT1( XMLFontStylesContext, SvXMLStylesContext );
376 XMLFontStylesContext::XMLFontStylesContext( SvXMLImport& rImport,
377 sal_uInt16 nPrfx, const OUString& rLName,
378 const Reference< XAttributeList > & xAttrList,
379 rtl_TextEncoding eDfltEnc ) :
380 SvXMLStylesContext( rImport, nPrfx, rLName, xAttrList ),
381 pFamilyNameHdl( new XMLFontFamilyNamePropHdl ),
382 pFamilyHdl( new XMLFontFamilyPropHdl ),
383 pPitchHdl( new XMLFontPitchPropHdl ),
384 pEncHdl( new XMLFontEncodingPropHdl ),
385 pFontStyleAttrTokenMap( new SvXMLTokenMap(lcl_getFontStyleAttrTokenMap()) ),
386 eDfltEncoding( eDfltEnc )
390 XMLFontStylesContext::~XMLFontStylesContext()
392 delete pFamilyNameHdl;
393 delete pFamilyHdl;
394 delete pPitchHdl;
395 delete pEncHdl;
396 delete pFontStyleAttrTokenMap;
399 bool XMLFontStylesContext::FillProperties( const OUString& rName,
400 ::std::vector< XMLPropertyState > &rProps,
401 sal_Int32 nFamilyNameIdx,
402 sal_Int32 nStyleNameIdx,
403 sal_Int32 nFamilyIdx,
404 sal_Int32 nPitchIdx,
405 sal_Int32 nCharsetIdx ) const
407 const SvXMLStyleContext* pStyle = FindStyleChildContext( XML_STYLE_FAMILY_FONT, rName, true );
408 const XMLFontStyleContextFontFace *pFontStyle = PTR_CAST( XMLFontStyleContextFontFace,pStyle);// use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
409 if( pFontStyle )
410 pFontStyle->FillProperties( rProps, nFamilyNameIdx, nStyleNameIdx,
411 nFamilyIdx, nPitchIdx, nCharsetIdx );
412 return 0 != pFontStyle;
415 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */