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 <rtl/logfile.hxx>
29 : #include <vcl/embeddedfontshelper.hxx>
30 :
31 : #include <xmloff/nmspmap.hxx>
32 : #include "xmloff/xmlnmspe.hxx"
33 : #include <xmloff/xmltoken.hxx>
34 : #include "fonthdl.hxx"
35 : #include <xmloff/xmlimp.hxx>
36 : #include <xmloff/maptype.hxx>
37 :
38 :
39 : using namespace ::com::sun::star;
40 : using namespace ::com::sun::star::uno;
41 : using namespace ::com::sun::star::xml::sax;
42 : using namespace ::com::sun::star::container;
43 : using namespace ::com::sun::star::beans;
44 : using namespace ::com::sun::star::lang;
45 : using namespace ::com::sun::star::awt;
46 : using namespace ::xmloff::token;
47 :
48 :
49 : #define XML_STYLE_FAMILY_FONT 1
50 :
51 : enum XMLFontStyleAttrTokens
52 : {
53 : XML_TOK_FONT_STYLE_ATTR_FAMILY,
54 : XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC,
55 : XML_TOK_FONT_STYLE_ATTR_STYLENAME,
56 : XML_TOK_FONT_STYLE_ATTR_PITCH,
57 : XML_TOK_FONT_STYLE_ATTR_CHARSET,
58 :
59 : XML_TOK_FONT_STYLE_ATTR_END=XML_TOK_UNKNOWN
60 : };
61 :
62 263 : static const SvXMLTokenMapEntry* lcl_getFontStyleAttrTokenMap()
63 : {
64 : static SvXMLTokenMapEntry aFontStyleAttrTokenMap[] =
65 : {
66 : { XML_NAMESPACE_SVG, XML_FONT_FAMILY,
67 : XML_TOK_FONT_STYLE_ATTR_FAMILY },
68 : { XML_NAMESPACE_STYLE, XML_FONT_FAMILY_GENERIC,
69 : XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC },
70 : { XML_NAMESPACE_STYLE, XML_FONT_ADORNMENTS,
71 : XML_TOK_FONT_STYLE_ATTR_STYLENAME },
72 : { XML_NAMESPACE_STYLE, XML_FONT_PITCH,
73 : XML_TOK_FONT_STYLE_ATTR_PITCH },
74 : { XML_NAMESPACE_STYLE, XML_FONT_CHARSET,
75 : XML_TOK_FONT_STYLE_ATTR_CHARSET },
76 :
77 : XML_TOKEN_MAP_END
78 : };
79 263 : return aFontStyleAttrTokenMap;
80 : }
81 :
82 4108 : TYPEINIT1( XMLFontStyleContextFontFace, SvXMLStyleContext );
83 :
84 1251 : XMLFontStyleContextFontFace::XMLFontStyleContextFontFace( SvXMLImport& rImport,
85 : sal_uInt16 nPrfx, const OUString& rLName,
86 : const Reference< XAttributeList > & xAttrList,
87 : XMLFontStylesContext& rStyles ) :
88 : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, XML_STYLE_FAMILY_FONT ),
89 1251 : xStyles( &rStyles )
90 : {
91 1251 : OUString sEmpty;
92 1251 : aFamilyName <<= sEmpty;
93 1251 : aStyleName <<= sEmpty;
94 1251 : aFamily <<= (sal_Int16)awt::FontFamily::DONTKNOW;
95 1251 : aPitch <<= (sal_Int16)awt::FontPitch::DONTKNOW;
96 1251 : aEnc <<= (sal_Int16)rStyles.GetDfltCharset();
97 1251 : }
98 :
99 4754 : void XMLFontStyleContextFontFace::SetAttribute( sal_uInt16 nPrefixKey,
100 : const OUString& rLocalName,
101 : const OUString& rValue )
102 : {
103 4754 : SvXMLUnitConverter& rUnitConv = GetImport().GetMM100UnitConverter();
104 4754 : const SvXMLTokenMap& rTokenMap = GetStyles()->GetFontStyleAttrTokenMap();
105 4754 : Any aAny;
106 :
107 4754 : switch( rTokenMap.Get( nPrefixKey, rLocalName ) )
108 : {
109 : case XML_TOK_FONT_STYLE_ATTR_FAMILY:
110 2502 : if( GetStyles()->GetFamilyNameHdl().importXML( rValue, aAny,
111 1251 : rUnitConv ) )
112 1249 : aFamilyName = aAny;
113 1251 : break;
114 : case XML_TOK_FONT_STYLE_ATTR_STYLENAME:
115 6 : aStyleName <<= rValue;
116 6 : break;
117 : case XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC:
118 2274 : if( GetStyles()->GetFamilyHdl().importXML( rValue, aAny,
119 1137 : rUnitConv ) )
120 1137 : aFamily = aAny;
121 1137 : break;
122 : case XML_TOK_FONT_STYLE_ATTR_PITCH:
123 2214 : if( GetStyles()->GetPitchHdl().importXML( rValue, aAny,
124 1107 : rUnitConv ) )
125 1107 : aPitch = aAny;
126 1107 : break;
127 : case XML_TOK_FONT_STYLE_ATTR_CHARSET:
128 4 : if( GetStyles()->GetEncodingHdl().importXML( rValue, aAny,
129 2 : rUnitConv ) )
130 2 : aEnc = aAny;
131 2 : break;
132 : default:
133 1251 : SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
134 1251 : break;
135 4754 : }
136 4754 : }
137 :
138 2502 : XMLFontStyleContextFontFace::~XMLFontStyleContextFontFace()
139 : {
140 2502 : }
141 :
142 1027 : void XMLFontStyleContextFontFace::FillProperties(
143 : ::std::vector< XMLPropertyState > &rProps,
144 : sal_Int32 nFamilyNameIdx,
145 : sal_Int32 nStyleNameIdx,
146 : sal_Int32 nFamilyIdx,
147 : sal_Int32 nPitchIdx,
148 : sal_Int32 nCharsetIdx ) const
149 : {
150 1027 : if( nFamilyNameIdx != -1 )
151 : {
152 1027 : XMLPropertyState aPropState( nFamilyNameIdx, aFamilyName );
153 1027 : rProps.push_back( aPropState );
154 : }
155 1027 : if( nStyleNameIdx != -1 )
156 : {
157 1027 : XMLPropertyState aPropState( nStyleNameIdx, aStyleName );
158 1027 : rProps.push_back( aPropState );
159 : }
160 1027 : if( nFamilyIdx != -1 )
161 : {
162 1027 : XMLPropertyState aPropState( nFamilyIdx, aFamily );
163 1027 : rProps.push_back( aPropState );
164 : }
165 1027 : if( nPitchIdx != -1 )
166 : {
167 1027 : XMLPropertyState aPropState( nPitchIdx, aPitch );
168 1027 : rProps.push_back( aPropState );
169 : }
170 1027 : if( nCharsetIdx != -1 )
171 : {
172 1027 : XMLPropertyState aPropState( nCharsetIdx, aEnc );
173 1027 : rProps.push_back( aPropState );
174 : }
175 1027 : }
176 :
177 0 : SvXMLImportContext * XMLFontStyleContextFontFace::CreateChildContext(
178 : sal_uInt16 nPrefix,
179 : const OUString& rLocalName,
180 : const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList )
181 : {
182 0 : if( nPrefix == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_FONT_FACE_SRC ))
183 0 : return new XMLFontStyleContextFontFaceSrc( GetImport(), nPrefix, rLocalName, *this );
184 0 : return SvXMLStyleContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
185 : }
186 :
187 0 : OUString XMLFontStyleContextFontFace::familyName() const
188 : {
189 0 : OUString ret;
190 0 : aFamilyName >>= ret;
191 0 : return ret;
192 : }
193 :
194 :
195 0 : TYPEINIT1( XMLFontStyleContextFontFaceSrc, SvXMLImportContext );
196 :
197 0 : XMLFontStyleContextFontFaceSrc::XMLFontStyleContextFontFaceSrc( SvXMLImport& rImport,
198 : sal_uInt16 nPrfx, const OUString& rLName,
199 : const XMLFontStyleContextFontFace& _font )
200 : : SvXMLImportContext( rImport, nPrfx, rLName )
201 0 : , font( _font )
202 : {
203 0 : }
204 :
205 0 : SvXMLImportContext * XMLFontStyleContextFontFaceSrc::CreateChildContext(
206 : sal_uInt16 nPrefix,
207 : const OUString& rLocalName,
208 : const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList )
209 : {
210 0 : if( nPrefix == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_FONT_FACE_URI ))
211 0 : return new XMLFontStyleContextFontFaceUri( GetImport(), nPrefix, rLocalName, xAttrList, font );
212 0 : return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
213 : }
214 :
215 :
216 0 : TYPEINIT1( XMLFontStyleContextFontFaceUri, SvXMLImportContext );
217 :
218 0 : XMLFontStyleContextFontFaceUri::XMLFontStyleContextFontFaceUri( SvXMLImport& rImport,
219 : sal_uInt16 nPrfx, const OUString& rLName,
220 : const ::com::sun::star::uno::Reference<
221 : ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
222 : const XMLFontStyleContextFontFace& _font )
223 : : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList )
224 0 : , font( _font )
225 : {
226 0 : }
227 :
228 0 : void XMLFontStyleContextFontFaceUri::SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
229 : const OUString& rValue )
230 : {
231 0 : if( nPrefixKey == XML_NAMESPACE_XLINK && IsXMLToken( rLocalName, XML_HREF ))
232 0 : handleEmbeddedFont( rValue );
233 : else
234 0 : SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
235 0 : }
236 :
237 0 : void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const OUString& url )
238 : {
239 0 : if( GetImport().embeddedFontAlreadyProcessed( url ))
240 : {
241 0 : GetImport().NotifyEmbeddedFontRead();
242 0 : return;
243 : }
244 0 : OUString fontName = font.familyName();
245 : // If there's any giveMeStreamForThisURL(), then it's well-hidden for me to find it.
246 0 : if( GetImport().IsPackageURL( url ))
247 : {
248 0 : uno::Reference< embed::XStorage > storage;
249 0 : storage.set( GetImport().GetSourceStorage(), UNO_QUERY_THROW );
250 0 : if( url.indexOf( '/' ) > -1 ) // TODO what if more levels?
251 0 : storage.set( storage->openStorageElement( url.copy( 0, url.indexOf( '/' )),
252 0 : ::embed::ElementModes::READ ), uno::UNO_QUERY_THROW );
253 0 : uno::Reference< io::XInputStream > inputStream;
254 0 : inputStream.set( storage->openStreamElement( url.copy( url.indexOf( '/' ) + 1 ), ::embed::ElementModes::READ ),
255 0 : UNO_QUERY_THROW );
256 0 : if( EmbeddedFontsHelper::addEmbeddedFont( inputStream, fontName, "?" ))
257 0 : GetImport().NotifyEmbeddedFontRead();
258 0 : inputStream->closeInput();
259 : }
260 : else
261 0 : SAL_WARN( "xmloff", "External URL for font file not handled." );
262 : }
263 :
264 1251 : SvXMLStyleContext *XMLFontStylesContext::CreateStyleChildContext(
265 : sal_uInt16 nPrefix,
266 : const OUString& rLocalName,
267 : const ::com::sun::star::uno::Reference<
268 : ::com::sun::star::xml::sax::XAttributeList > & xAttrList )
269 : {
270 : SvXMLStyleContext *pStyle;
271 2502 : if( XML_NAMESPACE_STYLE == nPrefix &&
272 1251 : IsXMLToken( rLocalName, XML_FONT_FACE ) )
273 : {
274 1251 : pStyle = new XMLFontStyleContextFontFace( GetImport(), nPrefix,
275 1251 : rLocalName, xAttrList, *this );
276 : }
277 : else
278 : {
279 : pStyle = SvXMLStylesContext::CreateStyleChildContext( nPrefix,
280 0 : rLocalName, xAttrList );
281 : }
282 :
283 1251 : return pStyle;
284 : }
285 :
286 0 : TYPEINIT1( XMLFontStylesContext, SvXMLStylesContext );
287 :
288 263 : XMLFontStylesContext::XMLFontStylesContext( SvXMLImport& rImport,
289 : sal_uInt16 nPrfx, const OUString& rLName,
290 : const Reference< XAttributeList > & xAttrList,
291 : rtl_TextEncoding eDfltEnc ) :
292 : SvXMLStylesContext( rImport, nPrfx, rLName, xAttrList ),
293 263 : pFamilyNameHdl( new XMLFontFamilyNamePropHdl ),
294 263 : pFamilyHdl( new XMLFontFamilyPropHdl ),
295 263 : pPitchHdl( new XMLFontPitchPropHdl ),
296 263 : pEncHdl( new XMLFontEncodingPropHdl ),
297 263 : pFontStyleAttrTokenMap( new SvXMLTokenMap(lcl_getFontStyleAttrTokenMap()) ),
298 1578 : eDfltEncoding( eDfltEnc )
299 : {
300 263 : }
301 :
302 789 : XMLFontStylesContext::~XMLFontStylesContext()
303 : {
304 263 : delete pFamilyNameHdl;
305 263 : delete pFamilyHdl;
306 263 : delete pPitchHdl;
307 263 : delete pEncHdl;
308 263 : delete pFontStyleAttrTokenMap;
309 526 : }
310 :
311 1035 : sal_Bool XMLFontStylesContext::FillProperties( const OUString& rName,
312 : ::std::vector< XMLPropertyState > &rProps,
313 : sal_Int32 nFamilyNameIdx,
314 : sal_Int32 nStyleNameIdx,
315 : sal_Int32 nFamilyIdx,
316 : sal_Int32 nPitchIdx,
317 : sal_Int32 nCharsetIdx ) const
318 : {
319 1035 : const SvXMLStyleContext* pStyle = FindStyleChildContext( XML_STYLE_FAMILY_FONT, rName, sal_True );
320 1035 : const XMLFontStyleContextFontFace *pFontStyle = PTR_CAST( XMLFontStyleContextFontFace,pStyle);// use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
321 1035 : if( pFontStyle )
322 : pFontStyle->FillProperties( rProps, nFamilyNameIdx, nStyleNameIdx,
323 1027 : nFamilyIdx, nPitchIdx, nCharsetIdx );
324 1035 : return 0 != pFontStyle;
325 : }
326 :
327 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|