Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <xmloff/XMLFontStylesContext.hxx>
21 : #include "XMLFontStylesContext_impl.hxx"
22 :
23 : #include <com/sun/star/awt/FontFamily.hpp>
24 : #include <com/sun/star/awt/FontPitch.hpp>
25 : #include <com/sun/star/embed/ElementModes.hpp>
26 :
27 : #include <osl/file.hxx>
28 : #include <vcl/embeddedfontshelper.hxx>
29 :
30 : #include <xmloff/nmspmap.hxx>
31 : #include <xmloff/xmlnmspe.hxx>
32 : #include <xmloff/xmltoken.hxx>
33 : #include "fonthdl.hxx"
34 : #include <xmloff/xmlimp.hxx>
35 : #include <xmloff/maptype.hxx>
36 :
37 :
38 : using namespace ::com::sun::star;
39 : using namespace ::com::sun::star::uno;
40 : using namespace ::com::sun::star::xml::sax;
41 : using namespace ::com::sun::star::container;
42 : using namespace ::com::sun::star::beans;
43 : using namespace ::com::sun::star::lang;
44 : using namespace ::com::sun::star::awt;
45 : using namespace ::xmloff::token;
46 :
47 :
48 : #define XML_STYLE_FAMILY_FONT 1
49 :
50 : enum XMLFontStyleAttrTokens
51 : {
52 : XML_TOK_FONT_STYLE_ATTR_FAMILY,
53 : XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC,
54 : XML_TOK_FONT_STYLE_ATTR_STYLENAME,
55 : XML_TOK_FONT_STYLE_ATTR_PITCH,
56 : XML_TOK_FONT_STYLE_ATTR_CHARSET,
57 :
58 : XML_TOK_FONT_STYLE_ATTR_END=XML_TOK_UNKNOWN
59 : };
60 :
61 0 : static const SvXMLTokenMapEntry* lcl_getFontStyleAttrTokenMap()
62 : {
63 : static const SvXMLTokenMapEntry aFontStyleAttrTokenMap[] =
64 : {
65 : { XML_NAMESPACE_SVG, XML_FONT_FAMILY,
66 : XML_TOK_FONT_STYLE_ATTR_FAMILY },
67 : { XML_NAMESPACE_STYLE, XML_FONT_FAMILY_GENERIC,
68 : XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC },
69 : { XML_NAMESPACE_STYLE, XML_FONT_ADORNMENTS,
70 : XML_TOK_FONT_STYLE_ATTR_STYLENAME },
71 : { XML_NAMESPACE_STYLE, XML_FONT_PITCH,
72 : XML_TOK_FONT_STYLE_ATTR_PITCH },
73 : { XML_NAMESPACE_STYLE, XML_FONT_CHARSET,
74 : XML_TOK_FONT_STYLE_ATTR_CHARSET },
75 :
76 : XML_TOKEN_MAP_END
77 : };
78 0 : return aFontStyleAttrTokenMap;
79 : }
80 :
81 0 : TYPEINIT1( XMLFontStyleContextFontFace, SvXMLStyleContext );
82 :
83 0 : XMLFontStyleContextFontFace::XMLFontStyleContextFontFace( SvXMLImport& rImport,
84 : sal_uInt16 nPrfx, const OUString& rLName,
85 : const Reference< XAttributeList > & xAttrList,
86 : XMLFontStylesContext& rStyles ) :
87 : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, XML_STYLE_FAMILY_FONT ),
88 0 : xStyles( &rStyles )
89 : {
90 0 : OUString sEmpty;
91 0 : aFamilyName <<= sEmpty;
92 0 : aStyleName <<= sEmpty;
93 0 : aFamily <<= (sal_Int16)awt::FontFamily::DONTKNOW;
94 0 : aPitch <<= (sal_Int16)awt::FontPitch::DONTKNOW;
95 0 : aEnc <<= (sal_Int16)rStyles.GetDfltCharset();
96 0 : }
97 :
98 0 : void XMLFontStyleContextFontFace::SetAttribute( sal_uInt16 nPrefixKey,
99 : const OUString& rLocalName,
100 : const OUString& rValue )
101 : {
102 0 : SvXMLUnitConverter& rUnitConv = GetImport().GetMM100UnitConverter();
103 0 : const SvXMLTokenMap& rTokenMap = GetStyles()->GetFontStyleAttrTokenMap();
104 0 : Any aAny;
105 :
106 0 : switch( rTokenMap.Get( nPrefixKey, rLocalName ) )
107 : {
108 : case XML_TOK_FONT_STYLE_ATTR_FAMILY:
109 0 : if( GetStyles()->GetFamilyNameHdl().importXML( rValue, aAny,
110 0 : rUnitConv ) )
111 0 : aFamilyName = aAny;
112 0 : break;
113 : case XML_TOK_FONT_STYLE_ATTR_STYLENAME:
114 0 : aStyleName <<= rValue;
115 0 : break;
116 : case XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC:
117 0 : if( GetStyles()->GetFamilyHdl().importXML( rValue, aAny,
118 0 : rUnitConv ) )
119 0 : aFamily = aAny;
120 0 : break;
121 : case XML_TOK_FONT_STYLE_ATTR_PITCH:
122 0 : if( GetStyles()->GetPitchHdl().importXML( rValue, aAny,
123 0 : rUnitConv ) )
124 0 : aPitch = aAny;
125 0 : break;
126 : case XML_TOK_FONT_STYLE_ATTR_CHARSET:
127 0 : if( GetStyles()->GetEncodingHdl().importXML( rValue, aAny,
128 0 : rUnitConv ) )
129 0 : aEnc = aAny;
130 0 : break;
131 : default:
132 0 : SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
133 0 : break;
134 0 : }
135 0 : }
136 :
137 0 : XMLFontStyleContextFontFace::~XMLFontStyleContextFontFace()
138 : {
139 0 : }
140 :
141 0 : void XMLFontStyleContextFontFace::FillProperties(
142 : ::std::vector< XMLPropertyState > &rProps,
143 : sal_Int32 nFamilyNameIdx,
144 : sal_Int32 nStyleNameIdx,
145 : sal_Int32 nFamilyIdx,
146 : sal_Int32 nPitchIdx,
147 : sal_Int32 nCharsetIdx ) const
148 : {
149 0 : if( nFamilyNameIdx != -1 )
150 : {
151 0 : XMLPropertyState aPropState( nFamilyNameIdx, aFamilyName );
152 0 : rProps.push_back( aPropState );
153 : }
154 0 : if( nStyleNameIdx != -1 )
155 : {
156 0 : XMLPropertyState aPropState( nStyleNameIdx, aStyleName );
157 0 : rProps.push_back( aPropState );
158 : }
159 0 : if( nFamilyIdx != -1 )
160 : {
161 0 : XMLPropertyState aPropState( nFamilyIdx, aFamily );
162 0 : rProps.push_back( aPropState );
163 : }
164 0 : if( nPitchIdx != -1 )
165 : {
166 0 : XMLPropertyState aPropState( nPitchIdx, aPitch );
167 0 : rProps.push_back( aPropState );
168 : }
169 0 : if( nCharsetIdx != -1 )
170 : {
171 0 : XMLPropertyState aPropState( nCharsetIdx, aEnc );
172 0 : rProps.push_back( aPropState );
173 : }
174 0 : }
175 :
176 0 : SvXMLImportContext * XMLFontStyleContextFontFace::CreateChildContext(
177 : sal_uInt16 nPrefix,
178 : const OUString& rLocalName,
179 : const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList )
180 : {
181 0 : if( nPrefix == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_FONT_FACE_SRC ))
182 0 : return new XMLFontStyleContextFontFaceSrc( GetImport(), nPrefix, rLocalName, *this );
183 0 : return SvXMLStyleContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
184 : }
185 :
186 0 : OUString XMLFontStyleContextFontFace::familyName() const
187 : {
188 0 : OUString ret;
189 0 : aFamilyName >>= ret;
190 0 : return ret;
191 : }
192 :
193 0 : TYPEINIT1( XMLFontStyleContextFontFaceFormat, SvXMLStyleContext );
194 :
195 0 : XMLFontStyleContextFontFaceFormat::XMLFontStyleContextFontFaceFormat( SvXMLImport& rImport,
196 : sal_uInt16 nPrfx, const OUString& rLName,
197 : const ::com::sun::star::uno::Reference<
198 : ::com::sun::star::xml::sax::XAttributeList > &xAttrList,
199 : XMLFontStyleContextFontFaceUri& _uri )
200 : : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList)
201 0 : , uri(_uri)
202 : {
203 0 : }
204 :
205 0 : void XMLFontStyleContextFontFaceFormat::SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
206 : const OUString& rValue )
207 : {
208 0 : if( nPrefixKey == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_STRING ))
209 0 : uri.SetFormat(rValue);
210 : else
211 0 : SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
212 0 : }
213 :
214 0 : TYPEINIT1( XMLFontStyleContextFontFaceSrc, SvXMLImportContext );
215 :
216 0 : XMLFontStyleContextFontFaceSrc::XMLFontStyleContextFontFaceSrc( SvXMLImport& rImport,
217 : sal_uInt16 nPrfx, const OUString& rLName,
218 : const XMLFontStyleContextFontFace& _font )
219 : : SvXMLImportContext( rImport, nPrfx, rLName )
220 0 : , font( _font )
221 : {
222 0 : }
223 :
224 0 : SvXMLImportContext * XMLFontStyleContextFontFaceSrc::CreateChildContext(
225 : sal_uInt16 nPrefix,
226 : const OUString& rLocalName,
227 : const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList )
228 : {
229 0 : if( nPrefix == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_FONT_FACE_URI ))
230 0 : return new XMLFontStyleContextFontFaceUri( GetImport(), nPrefix, rLocalName, xAttrList, font );
231 0 : return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
232 : }
233 :
234 :
235 0 : TYPEINIT1( XMLFontStyleContextFontFaceUri, SvXMLImportContext );
236 :
237 0 : XMLFontStyleContextFontFaceUri::XMLFontStyleContextFontFaceUri( SvXMLImport& rImport,
238 : sal_uInt16 nPrfx, const OUString& rLName,
239 : const ::com::sun::star::uno::Reference<
240 : ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
241 : const XMLFontStyleContextFontFace& _font )
242 : : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList )
243 0 : , font( _font )
244 : {
245 0 : }
246 :
247 0 : SvXMLImportContext * XMLFontStyleContextFontFaceUri::CreateChildContext(
248 : sal_uInt16 nPrefix,
249 : const OUString& rLocalName,
250 : const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList )
251 : {
252 0 : if( nPrefix == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_FONT_FACE_FORMAT ))
253 0 : return new XMLFontStyleContextFontFaceFormat( GetImport(), nPrefix, rLocalName, xAttrList, *this );
254 0 : return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
255 : }
256 :
257 0 : void XMLFontStyleContextFontFaceUri::SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
258 : const OUString& rValue )
259 : {
260 0 : if( nPrefixKey == XML_NAMESPACE_XLINK && IsXMLToken( rLocalName, XML_HREF ))
261 0 : linkPath = rValue;
262 : else
263 0 : SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
264 0 : }
265 :
266 0 : void XMLFontStyleContextFontFaceUri::SetFormat( const OUString& rFormat )
267 : {
268 0 : format = rFormat;
269 0 : }
270 :
271 : // the CSS2 standard ( http://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#referencing )
272 : // defines these format strings.
273 : const char* OPENTYPE_FORMAT = "opentype";
274 : const char* TRUETYPE_FORMAT = "truetype";
275 : const char* EOT_FORMAT = "embedded-opentype";
276 :
277 0 : void XMLFontStyleContextFontFaceUri::EndElement()
278 : {
279 0 : if( linkPath.getLength() == 0 )
280 : {
281 : SAL_WARN( "xmloff", "svg:font-face-uri tag with no link; ignoring." );
282 0 : return;
283 : }
284 : bool eot;
285 : // Assume by default that the font is not compressed.
286 0 : if( format.getLength() == 0
287 0 : || format.equalsAscii( OPENTYPE_FORMAT )
288 0 : || format.equalsAscii( TRUETYPE_FORMAT ))
289 : {
290 0 : eot = false;
291 : }
292 0 : else if( format.equalsAscii( EOT_FORMAT ))
293 : {
294 0 : eot = true;
295 : }
296 : else
297 : {
298 : SAL_WARN( "xmloff", "Unknown format of embedded font; assuming TTF." );
299 0 : eot = false;
300 : }
301 0 : handleEmbeddedFont( linkPath, eot );
302 : }
303 :
304 0 : void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const OUString& url, bool eot )
305 : {
306 0 : if( GetImport().embeddedFontAlreadyProcessed( url ))
307 : {
308 0 : GetImport().NotifyEmbeddedFontRead();
309 0 : return;
310 : }
311 0 : OUString fontName = font.familyName();
312 : // If there's any giveMeStreamForThisURL(), then it's well-hidden for me to find it.
313 0 : if( GetImport().IsPackageURL( url ))
314 : {
315 0 : uno::Reference< embed::XStorage > storage;
316 0 : storage.set( GetImport().GetSourceStorage(), UNO_QUERY_THROW );
317 0 : if( url.indexOf( '/' ) > -1 ) // TODO what if more levels?
318 0 : storage.set( storage->openStorageElement( url.copy( 0, url.indexOf( '/' )),
319 0 : ::embed::ElementModes::READ ), uno::UNO_QUERY_THROW );
320 0 : uno::Reference< io::XInputStream > inputStream;
321 0 : inputStream.set( storage->openStreamElement( url.copy( url.indexOf( '/' ) + 1 ), ::embed::ElementModes::READ ),
322 0 : UNO_QUERY_THROW );
323 0 : if( EmbeddedFontsHelper::addEmbeddedFont( inputStream, fontName, "?", std::vector< unsigned char >(), eot ))
324 0 : GetImport().NotifyEmbeddedFontRead();
325 0 : inputStream->closeInput();
326 : }
327 : else
328 0 : SAL_WARN( "xmloff", "External URL for font file not handled." );
329 : }
330 :
331 0 : SvXMLStyleContext *XMLFontStylesContext::CreateStyleChildContext(
332 : sal_uInt16 nPrefix,
333 : const OUString& rLocalName,
334 : const ::com::sun::star::uno::Reference<
335 : ::com::sun::star::xml::sax::XAttributeList > & xAttrList )
336 : {
337 : SvXMLStyleContext *pStyle;
338 0 : if( XML_NAMESPACE_STYLE == nPrefix &&
339 0 : IsXMLToken( rLocalName, XML_FONT_FACE ) )
340 : {
341 0 : pStyle = new XMLFontStyleContextFontFace( GetImport(), nPrefix,
342 0 : rLocalName, xAttrList, *this );
343 : }
344 : else
345 : {
346 : pStyle = SvXMLStylesContext::CreateStyleChildContext( nPrefix,
347 0 : rLocalName, xAttrList );
348 : }
349 :
350 0 : return pStyle;
351 : }
352 :
353 0 : TYPEINIT1( XMLFontStylesContext, SvXMLStylesContext );
354 :
355 0 : XMLFontStylesContext::XMLFontStylesContext( SvXMLImport& rImport,
356 : sal_uInt16 nPrfx, const OUString& rLName,
357 : const Reference< XAttributeList > & xAttrList,
358 : rtl_TextEncoding eDfltEnc ) :
359 : SvXMLStylesContext( rImport, nPrfx, rLName, xAttrList ),
360 0 : pFamilyNameHdl( new XMLFontFamilyNamePropHdl ),
361 0 : pFamilyHdl( new XMLFontFamilyPropHdl ),
362 0 : pPitchHdl( new XMLFontPitchPropHdl ),
363 0 : pEncHdl( new XMLFontEncodingPropHdl ),
364 0 : pFontStyleAttrTokenMap( new SvXMLTokenMap(lcl_getFontStyleAttrTokenMap()) ),
365 0 : eDfltEncoding( eDfltEnc )
366 : {
367 0 : }
368 :
369 0 : XMLFontStylesContext::~XMLFontStylesContext()
370 : {
371 0 : delete pFamilyNameHdl;
372 0 : delete pFamilyHdl;
373 0 : delete pPitchHdl;
374 0 : delete pEncHdl;
375 0 : delete pFontStyleAttrTokenMap;
376 0 : }
377 :
378 0 : bool XMLFontStylesContext::FillProperties( const OUString& rName,
379 : ::std::vector< XMLPropertyState > &rProps,
380 : sal_Int32 nFamilyNameIdx,
381 : sal_Int32 nStyleNameIdx,
382 : sal_Int32 nFamilyIdx,
383 : sal_Int32 nPitchIdx,
384 : sal_Int32 nCharsetIdx ) const
385 : {
386 0 : const SvXMLStyleContext* pStyle = FindStyleChildContext( XML_STYLE_FAMILY_FONT, rName, true );
387 0 : const XMLFontStyleContextFontFace *pFontStyle = PTR_CAST( XMLFontStyleContextFontFace,pStyle);// use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
388 0 : if( pFontStyle )
389 : pFontStyle->FillProperties( rProps, nFamilyNameIdx, nStyleNameIdx,
390 0 : nFamilyIdx, nPitchIdx, nCharsetIdx );
391 0 : return 0 != pFontStyle;
392 : }
393 :
394 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|