LibreOffice Module xmloff (master)  1
XMLFontStylesContext.cxx
Go to the documentation of this file.
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 
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 #include <com/sun/star/embed/XStorage.hpp>
27 
28 #include <comphelper/seqstream.hxx>
29 
30 #include <sal/log.hxx>
32 
33 #include <xmloff/xmlnmspe.hxx>
34 #include <xmloff/xmltoken.hxx>
35 #include "fonthdl.hxx"
36 #include <xmloff/xmlimp.hxx>
37 #include <xmloff/maptype.hxx>
39 
40 
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;
49 
50 
51 #define XML_STYLE_FAMILY_FONT XmlStyleFamily::PAGE_MASTER
52 
53 namespace {
54 
56 {
57  XML_TOK_FONT_STYLE_ATTR_FAMILY,
58  XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC,
59  XML_TOK_FONT_STYLE_ATTR_STYLENAME,
60  XML_TOK_FONT_STYLE_ATTR_PITCH,
61  XML_TOK_FONT_STYLE_ATTR_CHARSET,
62 };
63 
64 }
65 
67 {
68  static const SvXMLTokenMapEntry aFontStyleAttrTokenMap[] =
69  {
71  XML_TOK_FONT_STYLE_ATTR_FAMILY },
73  XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC },
75  XML_TOK_FONT_STYLE_ATTR_STYLENAME },
77  XML_TOK_FONT_STYLE_ATTR_PITCH },
79  XML_TOK_FONT_STYLE_ATTR_CHARSET },
80 
82  };
83  return aFontStyleAttrTokenMap;
84 }
85 
86 
88  sal_uInt16 nPrfx, const OUString& rLName,
89  const Reference< XAttributeList > & xAttrList,
90  XMLFontStylesContext& rStyles ) :
91  SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, XML_STYLE_FAMILY_FONT ),
92  xStyles( &rStyles )
93 {
94  aFamilyName <<= OUString();
95  aStyleName <<= OUString();
96  aFamily <<= sal_Int16(awt::FontFamily::DONTKNOW);
97  aPitch <<= sal_Int16(awt::FontPitch::DONTKNOW);
98  aEnc <<= static_cast<sal_Int16>(rStyles.GetDfltCharset());
99 }
100 
101 void XMLFontStyleContextFontFace::SetAttribute( sal_uInt16 nPrefixKey,
102  const OUString& rLocalName,
103  const OUString& rValue )
104 {
106  const SvXMLTokenMap& rTokenMap = GetStyles()->GetFontStyleAttrTokenMap();
107  Any aAny;
108 
109  switch( rTokenMap.Get( nPrefixKey, rLocalName ) )
110  {
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;
137  }
138 }
139 
141 {
142 }
143 
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
151 {
152  if( nFamilyNameIdx != -1 )
153  {
154  XMLPropertyState aPropState( nFamilyNameIdx, aFamilyName );
155  rProps.push_back( aPropState );
156  }
157  if( nStyleNameIdx != -1 )
158  {
159  XMLPropertyState aPropState( nStyleNameIdx, aStyleName );
160  rProps.push_back( aPropState );
161  }
162  if( nFamilyIdx != -1 )
163  {
164  XMLPropertyState aPropState( nFamilyIdx, aFamily );
165  rProps.push_back( aPropState );
166  }
167  if( nPitchIdx != -1 )
168  {
169  XMLPropertyState aPropState( nPitchIdx, aPitch );
170  rProps.push_back( aPropState );
171  }
172  if( nCharsetIdx != -1 )
173  {
174  XMLPropertyState aPropState( nCharsetIdx, aEnc );
175  rProps.push_back( aPropState );
176  }
177 }
178 
180  sal_uInt16 nPrefix,
181  const OUString& rLocalName,
182  const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList )
183 {
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 );
187 }
188 
190 {
191  OUString ret;
192  aFamilyName >>= ret;
193  return ret;
194 }
195 
196 
198  sal_uInt16 nPrfx, const OUString& rLName,
199  const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList,
201  : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList)
202  , uri(_uri)
203 {
204 }
205 
206 void XMLFontStyleContextFontFaceFormat::SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
207  const OUString& rValue )
208 {
209  if( nPrefixKey == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_STRING ))
210  uri.SetFormat(rValue);
211  else
212  SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
213 }
214 
215 
217  sal_uInt16 nPrfx, const OUString& rLName,
218  const XMLFontStyleContextFontFace& _font )
219  : SvXMLImportContext( rImport, nPrfx, rLName )
220  , font( _font )
221 {
222 }
223 
225  sal_uInt16 nPrefix,
226  const OUString& rLocalName,
227  const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList )
228 {
229  if( nPrefix == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_FONT_FACE_URI ))
230  return new XMLFontStyleContextFontFaceUri( GetImport(), nPrefix, rLocalName, xAttrList, font );
231  return nullptr;
232 }
233 
234 
236  sal_uInt16 nPrfx, const OUString& rLName,
237  const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList,
238  const XMLFontStyleContextFontFace& _font )
239  : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList )
240  , font( _font )
241 {
242 }
243 
245  sal_uInt16 nPrefix,
246  const OUString& rLocalName,
247  const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList )
248 {
249  if( nPrefix == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_FONT_FACE_FORMAT ))
250  return new XMLFontStyleContextFontFaceFormat( GetImport(), nPrefix, rLocalName, xAttrList, *this );
251  if( linkPath.isEmpty() && ( nPrefix == XML_NAMESPACE_OFFICE ) && IsXMLToken( rLocalName, XML_BINARY_DATA ) )
252  {
253  mxBase64Stream.set( new comphelper::OSequenceOutputStream( maFontData ) );
254  if( mxBase64Stream.is() )
255  return new XMLBase64ImportContext( GetImport(), nPrefix, rLocalName, xAttrList, mxBase64Stream );
256  }
257  return nullptr;
258 }
259 
260 void XMLFontStyleContextFontFaceUri::SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
261  const OUString& rValue )
262 {
263  if( nPrefixKey == XML_NAMESPACE_XLINK && IsXMLToken( rLocalName, XML_HREF ))
264  linkPath = rValue;
265  else
266  SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
267 }
268 
269 void XMLFontStyleContextFontFaceUri::SetFormat( const OUString& rFormat )
270 {
271  format = rFormat;
272 }
273 
274 // the CSS2 standard ( http://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#referencing )
275 // defines these format strings.
276 const char OPENTYPE_FORMAT[] = "opentype";
277 const char TRUETYPE_FORMAT[] = "truetype";
278 const char EOT_FORMAT[] = "embedded-opentype";
279 
281 {
282  if( ( linkPath.getLength() == 0 ) && ( !maFontData.hasElements() ) )
283  {
284  SAL_WARN( "xmloff", "svg:font-face-uri tag with no link or base64 data; ignoring." );
285  return;
286  }
287  bool eot;
288  // Assume by default that the font is not compressed.
289  if( format.getLength() == 0
290  || format == OPENTYPE_FORMAT
291  || format == TRUETYPE_FORMAT )
292  {
293  eot = false;
294  }
295  else if( format == EOT_FORMAT )
296  {
297  eot = true;
298  }
299  else
300  {
301  SAL_WARN( "xmloff", "Unknown format of embedded font; assuming TTF." );
302  eot = false;
303  }
304  if ( !maFontData.hasElements() )
306  else
308 }
309 
310 void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const OUString& url, bool eot )
311 {
312  if( GetImport().embeddedFontAlreadyProcessed( url ))
313  {
315  return;
316  }
317  OUString fontName = font.familyName();
318  // If there's any giveMeStreamForThisURL(), then it's well-hidden for me to find it.
319  if( GetImport().IsPackageURL( url ))
320  {
321  uno::Reference< embed::XStorage > storage;
322  storage.set( GetImport().GetSourceStorage(), UNO_SET_THROW );
323  if( url.indexOf( '/' ) > -1 ) // TODO what if more levels?
324  storage.set( storage->openStorageElement( url.copy( 0, url.indexOf( '/' )),
325  ::embed::ElementModes::READ ), uno::UNO_SET_THROW );
326  uno::Reference< io::XInputStream > inputStream;
327  inputStream.set( storage->openStreamElement( url.copy( url.indexOf( '/' ) + 1 ), ::embed::ElementModes::READ ),
328  UNO_QUERY_THROW );
329  if( EmbeddedFontsHelper::addEmbeddedFont( inputStream, fontName, "?", std::vector< unsigned char >(), eot ))
331  inputStream->closeInput();
332  }
333  else
334  SAL_WARN( "xmloff", "External URL for font file not handled." );
335 }
336 
337 void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const ::css::uno::Sequence< sal_Int8 >& rData, const bool eot )
338 {
339  const uno::Reference< io::XInputStream > xInput( new comphelper::SequenceInputStream( rData ) );
340  const OUString fontName = font.familyName();
341  if( EmbeddedFontsHelper::addEmbeddedFont( xInput, fontName, "?", std::vector< unsigned char >(), eot ) )
343  xInput->closeInput();
344 }
345 
347  sal_uInt16 nPrefix,
348  const OUString& rLocalName,
349  const css::uno::Reference< css::xml::sax::XAttributeList > & xAttrList )
350 {
351  SvXMLStyleContext *pStyle;
352  if( XML_NAMESPACE_STYLE == nPrefix &&
353  IsXMLToken( rLocalName, XML_FONT_FACE ) )
354  {
355  pStyle = new XMLFontStyleContextFontFace( GetImport(), nPrefix,
356  rLocalName, xAttrList, *this );
357  }
358  else
359  {
361  rLocalName, xAttrList );
362  }
363 
364  return pStyle;
365 }
366 
367 
369  rtl_TextEncoding eDfltEnc ) :
370  SvXMLStylesContext( rImport ),
371  pFamilyNameHdl( new XMLFontFamilyNamePropHdl ),
372  pFamilyHdl( new XMLFontFamilyPropHdl ),
373  pPitchHdl( new XMLFontPitchPropHdl ),
374  pEncHdl( new XMLFontEncodingPropHdl ),
375  pFontStyleAttrTokenMap( new SvXMLTokenMap(lcl_getFontStyleAttrTokenMap()) ),
376  eDfltEncoding( eDfltEnc )
377 {
378 }
379 
381 
382 bool XMLFontStylesContext::FillProperties( const OUString& rName,
383  ::std::vector< XMLPropertyState > &rProps,
384  sal_Int32 nFamilyNameIdx,
385  sal_Int32 nStyleNameIdx,
386  sal_Int32 nFamilyIdx,
387  sal_Int32 nPitchIdx,
388  sal_Int32 nCharsetIdx ) const
389 {
390  const SvXMLStyleContext* pStyle = FindStyleChildContext( XML_STYLE_FAMILY_FONT, rName, true );
391  const XMLFontStyleContextFontFace *pFontStyle = dynamic_cast<const XMLFontStyleContextFontFace*>(pStyle);// use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
392  if( pFontStyle )
393  pFontStyle->FillProperties( rProps, nFamilyNameIdx, nStyleNameIdx,
394  nFamilyIdx, nPitchIdx, nCharsetIdx );
395  return nullptr != pFontStyle;
396 }
397 
398 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static const SvXMLTokenMapEntry * lcl_getFontStyleAttrTokenMap()
bool IsXMLToken(const OUString &rString, enum XMLTokenEnum eToken)
compare eToken to the string
Definition: xmltoken.cxx:3422
constexpr sal_uInt16 XML_NAMESPACE_STYLE
Definition: xmlnmspe.hxx:30
XMLFontPitchPropHdl & GetPitchHdl() const
bool FillProperties(const OUString &rName,::std::vector< XMLPropertyState > &rProps, sal_Int32 nFamilyNameIdx, sal_Int32 nStyleNameIdx, sal_Int32 nFamilyIdx, sal_Int32 nPitchIdx, sal_Int32 nCharsetIdx) const
XMLFontStyleContextFontFaceUri & uri
PropertyHandler for the XML-data-type:
Definition: fonthdl.hxx:64
const char OPENTYPE_FORMAT[]
virtual bool importXML(const OUString &rStrImpValue, css::uno::Any &rValue, const SvXMLUnitConverter &rUnitConverter) const override
Imports the given value according to the XML-data-type corresponding to the derived class...
Definition: fonthdl.cxx:197
the SvXMLTypeConverter converts values of various types from their internal representation to the tex...
Definition: xmluconv.hxx:77
const XMLFontStyleContextFontFace & font
void FillProperties(::std::vector< XMLPropertyState > &rProps, sal_Int32 nFamilyNameIdx, sal_Int32 nStyleNameIdx, sal_Int32 nFamilyIdx, sal_Int32 nPitchIdx, sal_Int32 nCharsetIdx) const
virtual SvXMLImportContextRef CreateChildContext(sal_uInt16 nPrefix, const OUString &rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList) override
Create a children element context.
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:62
void EndElement() override
EndElement is called before a context will be destructed, but after an elements context has been pars...
virtual void NotifyEmbeddedFontRead()
Definition: xmlimp.hxx:587
virtual SvXMLStyleContext * CreateStyleChildContext(sal_uInt16 nPrefix, const OUString &rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList)
Definition: xmlstyle.cxx:357
XMLFontEncodingPropHdl & GetEncodingHdl() const
#define XML_TOKEN_MAP_END
Definition: xmltkmap.hxx:33
virtual bool importXML(const OUString &rStrImpValue, css::uno::Any &rValue, const SvXMLUnitConverter &rUnitConverter) const override
Imports the given value according to the XML-data-type corresponding to the derived class...
Definition: fonthdl.cxx:264
virtual SvXMLStyleContext * CreateStyleChildContext(sal_uInt16 nPrefix, const OUString &rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList) override
css::uno::Any const & rValue
Definition: ImageStyle.hxx:38
#define XML_STYLE_FAMILY_FONT
virtual bool importXML(const OUString &rStrImpValue, css::uno::Any &rValue, const SvXMLUnitConverter &rUnitConverter) const override
Imports the given value according to the XML-data-type corresponding to the derived class...
Definition: fonthdl.cxx:231
XMLFontStyleContextFontFaceUri(SvXMLImport &rImport, sal_uInt16 nPrfx, const OUString &rLName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList, const XMLFontStyleContextFontFace &font)
virtual void SetAttribute(sal_uInt16 nPrefixKey, const OUString &rLocalName, const OUString &rValue) override
PropertyHandler for the XML-data-type:
Definition: fonthdl.hxx:28
virtual ~XMLFontStyleContextFontFace() override
void SetAttribute(sal_uInt16 nPrefixKey, const OUString &rLocalName, const OUString &rValue) override
PropertyHandler for the XML-data-type:
Definition: fonthdl.hxx:52
virtual bool importXML(const OUString &rStrImpValue, css::uno::Any &rValue, const SvXMLUnitConverter &rUnitConverter) const override
Imports the given value according to the XML-data-type corresponding to the derived class...
Definition: fonthdl.cxx:67
const XMLFontStyleContextFontFace & font
sal_uInt16 Get(sal_uInt16 nPrefix, const OUString &rLName) const
Definition: xmltkmap.cxx:93
rtl_TextEncoding GetDfltCharset() const
SvXMLImportContextRef CreateChildContext(sal_uInt16 nPrefix, const OUString &rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList) override
Create a children element context.
XMLFontStyleContextFontFaceFormat(SvXMLImport &rImport, sal_uInt16 nPrfx, const OUString &rLName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList, XMLFontStyleContextFontFaceUri &uri)
XMLFontStyleContextFontFaceSrc(SvXMLImport &rImport, sal_uInt16 nPrfx, const OUString &rLName, const XMLFontStyleContextFontFace &font)
static bool addEmbeddedFont(const css::uno::Reference< css::io::XInputStream > &stream, const OUString &fontName, const char *extra, std::vector< unsigned char > key, bool eot=false)
XMLFontStylesContext(SvXMLImport &rImport, rtl_TextEncoding eDfltEnc)
::css::uno::Sequence< sal_Int8 > maFontData
This class deliberately does not support XWeak, to improve performance when loading large documents...
Definition: xmlictxt.hxx:44
constexpr sal_uInt16 XML_NAMESPACE_XLINK
Definition: xmlnmspe.hxx:35
void SetAttribute(sal_uInt16 nPrefixKey, const OUString &rLocalName, const OUString &rValue) override
XMLFontStyleAttrTokens
SvXMLImportContextRef CreateChildContext(sal_uInt16 nPrefix, const OUString &rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList) override
Create a children element context.
const SvXMLTokenMap & GetFontStyleAttrTokenMap() const
Handling of tokens in XML:
::css::uno::Reference< ::css::io::XOutputStream > mxBase64Stream
void handleEmbeddedFont(const OUString &url, bool eot)
Smart struct to transport an Any with an index to the appropriate property-name.
Definition: maptype.hxx:104
const SvXMLUnitConverter & GetMM100UnitConverter() const
Definition: xmlimp.hxx:399
XMLFontFamilyPropHdl & GetFamilyHdl() const
virtual SvXMLImportContextRef CreateChildContext(sal_uInt16 nPrefix, const OUString &rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList)
Create a children element context.
Definition: xmlictxt.cxx:51
virtual void SetAttribute(sal_uInt16 nPrefixKey, const OUString &rLocalName, const OUString &rValue)
Definition: xmlstyle.cxx:94
const SvXMLStyleContext * FindStyleChildContext(XmlStyleFamily nFamily, const OUString &rName, bool bCreateIndex=false) const
Definition: xmlstyle.cxx:870
const char TRUETYPE_FORMAT[]
#define SAL_WARN(area, stream)
const char EOT_FORMAT[]
PropertyHandler for the XML-data-type:
Definition: fonthdl.hxx:40
constexpr sal_uInt16 XML_NAMESPACE_SVG
Definition: xmlnmspe.hxx:40
XMLFontFamilyNamePropHdl & GetFamilyNameHdl() const
void SetFormat(const OUString &rFormat)
constexpr sal_uInt16 XML_NAMESPACE_OFFICE
Definition: xmlnmspe.hxx:29
XMLFontStyleContextFontFace(SvXMLImport &rImport, sal_uInt16 nPrfx, const OUString &rLName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList, XMLFontStylesContext &rStyles)