1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <osl/file.hxx>
28 #include <rtl/logfile.hxx>
29 #include <vcl/embeddedfontshelper.hxx>
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>
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
;
49 #define XML_STYLE_FAMILY_FONT 1
51 enum XMLFontStyleAttrTokens
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
,
59 XML_TOK_FONT_STYLE_ATTR_END
=XML_TOK_UNKNOWN
62 static const SvXMLTokenMapEntry
* lcl_getFontStyleAttrTokenMap()
64 static SvXMLTokenMapEntry aFontStyleAttrTokenMap
[] =
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
},
79 return aFontStyleAttrTokenMap
;
82 TYPEINIT1( XMLFontStyleContextFontFace
, SvXMLStyleContext
);
84 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
),
92 aFamilyName
<<= sEmpty
;
93 aStyleName
<<= sEmpty
;
94 aFamily
<<= (sal_Int16
)awt::FontFamily::DONTKNOW
;
95 aPitch
<<= (sal_Int16
)awt::FontPitch::DONTKNOW
;
96 aEnc
<<= (sal_Int16
)rStyles
.GetDfltCharset();
99 void XMLFontStyleContextFontFace::SetAttribute( sal_uInt16 nPrefixKey
,
100 const OUString
& rLocalName
,
101 const OUString
& rValue
)
103 SvXMLUnitConverter
& rUnitConv
= GetImport().GetMM100UnitConverter();
104 const SvXMLTokenMap
& rTokenMap
= GetStyles()->GetFontStyleAttrTokenMap();
107 switch( rTokenMap
.Get( nPrefixKey
, rLocalName
) )
109 case XML_TOK_FONT_STYLE_ATTR_FAMILY
:
110 if( GetStyles()->GetFamilyNameHdl().importXML( rValue
, aAny
,
114 case XML_TOK_FONT_STYLE_ATTR_STYLENAME
:
115 aStyleName
<<= rValue
;
117 case XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC
:
118 if( GetStyles()->GetFamilyHdl().importXML( rValue
, aAny
,
122 case XML_TOK_FONT_STYLE_ATTR_PITCH
:
123 if( GetStyles()->GetPitchHdl().importXML( rValue
, aAny
,
127 case XML_TOK_FONT_STYLE_ATTR_CHARSET
:
128 if( GetStyles()->GetEncodingHdl().importXML( rValue
, aAny
,
133 SvXMLStyleContext::SetAttribute( nPrefixKey
, rLocalName
, rValue
);
138 XMLFontStyleContextFontFace::~XMLFontStyleContextFontFace()
142 void XMLFontStyleContextFontFace::FillProperties(
143 ::std::vector
< XMLPropertyState
> &rProps
,
144 sal_Int32 nFamilyNameIdx
,
145 sal_Int32 nStyleNameIdx
,
146 sal_Int32 nFamilyIdx
,
148 sal_Int32 nCharsetIdx
) const
150 if( nFamilyNameIdx
!= -1 )
152 XMLPropertyState
aPropState( nFamilyNameIdx
, aFamilyName
);
153 rProps
.push_back( aPropState
);
155 if( nStyleNameIdx
!= -1 )
157 XMLPropertyState
aPropState( nStyleNameIdx
, aStyleName
);
158 rProps
.push_back( aPropState
);
160 if( nFamilyIdx
!= -1 )
162 XMLPropertyState
aPropState( nFamilyIdx
, aFamily
);
163 rProps
.push_back( aPropState
);
165 if( nPitchIdx
!= -1 )
167 XMLPropertyState
aPropState( nPitchIdx
, aPitch
);
168 rProps
.push_back( aPropState
);
170 if( nCharsetIdx
!= -1 )
172 XMLPropertyState
aPropState( nCharsetIdx
, aEnc
);
173 rProps
.push_back( aPropState
);
177 SvXMLImportContext
* XMLFontStyleContextFontFace::CreateChildContext(
179 const OUString
& rLocalName
,
180 const ::com::sun::star::uno::Reference
< ::com::sun::star::xml::sax::XAttributeList
> & xAttrList
)
182 if( nPrefix
== XML_NAMESPACE_SVG
&& IsXMLToken( rLocalName
, XML_FONT_FACE_SRC
))
183 return new XMLFontStyleContextFontFaceSrc( GetImport(), nPrefix
, rLocalName
, *this );
184 return SvXMLStyleContext::CreateChildContext( nPrefix
, rLocalName
, xAttrList
);
187 OUString
XMLFontStyleContextFontFace::familyName() const
195 TYPEINIT1( XMLFontStyleContextFontFaceSrc
, SvXMLImportContext
);
197 XMLFontStyleContextFontFaceSrc::XMLFontStyleContextFontFaceSrc( SvXMLImport
& rImport
,
198 sal_uInt16 nPrfx
, const OUString
& rLName
,
199 const XMLFontStyleContextFontFace
& _font
)
200 : SvXMLImportContext( rImport
, nPrfx
, rLName
)
205 SvXMLImportContext
* XMLFontStyleContextFontFaceSrc::CreateChildContext(
207 const OUString
& rLocalName
,
208 const ::com::sun::star::uno::Reference
< ::com::sun::star::xml::sax::XAttributeList
> & xAttrList
)
210 if( nPrefix
== XML_NAMESPACE_SVG
&& IsXMLToken( rLocalName
, XML_FONT_FACE_URI
))
211 return new XMLFontStyleContextFontFaceUri( GetImport(), nPrefix
, rLocalName
, xAttrList
, font
);
212 return SvXMLImportContext::CreateChildContext( nPrefix
, rLocalName
, xAttrList
);
216 TYPEINIT1( XMLFontStyleContextFontFaceUri
, SvXMLImportContext
);
218 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
)
228 void XMLFontStyleContextFontFaceUri::SetAttribute( sal_uInt16 nPrefixKey
, const OUString
& rLocalName
,
229 const OUString
& rValue
)
231 if( nPrefixKey
== XML_NAMESPACE_XLINK
&& IsXMLToken( rLocalName
, XML_HREF
))
232 handleEmbeddedFont( rValue
);
234 SvXMLStyleContext::SetAttribute( nPrefixKey
, rLocalName
, rValue
);
237 void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const OUString
& url
)
239 if( GetImport().embeddedFontAlreadyProcessed( url
))
241 GetImport().NotifyEmbeddedFontRead();
244 OUString fontName
= font
.familyName();
245 // If there's any giveMeStreamForThisURL(), then it's well-hidden for me to find it.
246 if( GetImport().IsPackageURL( url
))
248 uno::Reference
< embed::XStorage
> storage
;
249 storage
.set( GetImport().GetSourceStorage(), UNO_QUERY_THROW
);
250 if( url
.indexOf( '/' ) > -1 ) // TODO what if more levels?
251 storage
.set( storage
->openStorageElement( url
.copy( 0, url
.indexOf( '/' )),
252 ::embed::ElementModes::READ
), uno::UNO_QUERY_THROW
);
253 uno::Reference
< io::XInputStream
> inputStream
;
254 inputStream
.set( storage
->openStreamElement( url
.copy( url
.indexOf( '/' ) + 1 ), ::embed::ElementModes::READ
),
256 if( EmbeddedFontsHelper::addEmbeddedFont( inputStream
, fontName
, "?" ))
257 GetImport().NotifyEmbeddedFontRead();
258 inputStream
->closeInput();
261 SAL_WARN( "xmloff", "External URL for font file not handled." );
264 SvXMLStyleContext
*XMLFontStylesContext::CreateStyleChildContext(
266 const OUString
& rLocalName
,
267 const ::com::sun::star::uno::Reference
<
268 ::com::sun::star::xml::sax::XAttributeList
> & xAttrList
)
270 SvXMLStyleContext
*pStyle
;
271 if( XML_NAMESPACE_STYLE
== nPrefix
&&
272 IsXMLToken( rLocalName
, XML_FONT_FACE
) )
274 pStyle
= new XMLFontStyleContextFontFace( GetImport(), nPrefix
,
275 rLocalName
, xAttrList
, *this );
279 pStyle
= SvXMLStylesContext::CreateStyleChildContext( nPrefix
,
280 rLocalName
, xAttrList
);
286 TYPEINIT1( XMLFontStylesContext
, SvXMLStylesContext
);
288 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 pFamilyNameHdl( new XMLFontFamilyNamePropHdl
),
294 pFamilyHdl( new XMLFontFamilyPropHdl
),
295 pPitchHdl( new XMLFontPitchPropHdl
),
296 pEncHdl( new XMLFontEncodingPropHdl
),
297 pFontStyleAttrTokenMap( new SvXMLTokenMap(lcl_getFontStyleAttrTokenMap()) ),
298 eDfltEncoding( eDfltEnc
)
302 XMLFontStylesContext::~XMLFontStylesContext()
304 delete pFamilyNameHdl
;
308 delete pFontStyleAttrTokenMap
;
311 sal_Bool
XMLFontStylesContext::FillProperties( const OUString
& rName
,
312 ::std::vector
< XMLPropertyState
> &rProps
,
313 sal_Int32 nFamilyNameIdx
,
314 sal_Int32 nStyleNameIdx
,
315 sal_Int32 nFamilyIdx
,
317 sal_Int32 nCharsetIdx
) const
319 const SvXMLStyleContext
* pStyle
= FindStyleChildContext( XML_STYLE_FAMILY_FONT
, rName
, sal_True
);
320 const XMLFontStyleContextFontFace
*pFontStyle
= PTR_CAST( XMLFontStyleContextFontFace
,pStyle
);// use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
322 pFontStyle
->FillProperties( rProps
, nFamilyNameIdx
, nStyleNameIdx
,
323 nFamilyIdx
, nPitchIdx
, nCharsetIdx
);
324 return 0 != pFontStyle
;
327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */