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/xmlnamespace.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  XMLFontStylesContext& rStyles ) :
90  xStyles( &rStyles )
91 {
92  aFamilyName <<= OUString();
93  aStyleName <<= OUString();
94  aFamily <<= sal_Int16(awt::FontFamily::DONTKNOW);
95  aPitch <<= sal_Int16(awt::FontPitch::DONTKNOW);
96  aEnc <<= static_cast<sal_Int16>(rStyles.GetDfltCharset());
97 }
98 
99 void XMLFontStyleContextFontFace::SetAttribute( sal_uInt16 nPrefixKey,
100  const OUString& rLocalName,
101  const OUString& rValue )
102 {
104  const SvXMLTokenMap& rTokenMap = GetStyles()->GetFontStyleAttrTokenMap();
105  Any aAny;
106 
107  switch( rTokenMap.Get( nPrefixKey, rLocalName ) )
108  {
109  case XML_TOK_FONT_STYLE_ATTR_FAMILY:
110  if( GetStyles()->GetFamilyNameHdl().importXML( rValue, aAny,
111  rUnitConv ) )
112  aFamilyName = aAny;
113  break;
114  case XML_TOK_FONT_STYLE_ATTR_STYLENAME:
115  aStyleName <<= rValue;
116  break;
117  case XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC:
118  if( GetStyles()->GetFamilyHdl().importXML( rValue, aAny,
119  rUnitConv ) )
120  aFamily = aAny;
121  break;
122  case XML_TOK_FONT_STYLE_ATTR_PITCH:
123  if( GetStyles()->GetPitchHdl().importXML( rValue, aAny,
124  rUnitConv ) )
125  aPitch = aAny;
126  break;
127  case XML_TOK_FONT_STYLE_ATTR_CHARSET:
128  if( GetStyles()->GetEncodingHdl().importXML( rValue, aAny,
129  rUnitConv ) )
130  aEnc = aAny;
131  break;
132  default:
133  SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
134  break;
135  }
136 }
137 
139 {
140 }
141 
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  if( nFamilyNameIdx != -1 )
151  {
152  XMLPropertyState aPropState( nFamilyNameIdx, aFamilyName );
153  rProps.push_back( aPropState );
154  }
155  if( nStyleNameIdx != -1 )
156  {
157  XMLPropertyState aPropState( nStyleNameIdx, aStyleName );
158  rProps.push_back( aPropState );
159  }
160  if( nFamilyIdx != -1 )
161  {
162  XMLPropertyState aPropState( nFamilyIdx, aFamily );
163  rProps.push_back( aPropState );
164  }
165  if( nPitchIdx != -1 )
166  {
167  XMLPropertyState aPropState( nPitchIdx, aPitch );
168  rProps.push_back( aPropState );
169  }
170  if( nCharsetIdx != -1 )
171  {
172  XMLPropertyState aPropState( nCharsetIdx, aEnc );
173  rProps.push_back( aPropState );
174  }
175 }
176 
177 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLFontStyleContextFontFace::createFastChildContext(
178  sal_Int32 nElement,
179  const css::uno::Reference< css::xml::sax::XFastAttributeList > & )
180 {
181  if( nElement == XML_ELEMENT(SVG, XML_FONT_FACE_SRC) ||
182  nElement == XML_ELEMENT(SVG_COMPAT, XML_FONT_FACE_SRC) )
183  return new XMLFontStyleContextFontFaceSrc( GetImport(), *this );
184  else
185  SAL_WARN("xmloff", "unknown element " << SvXMLImport::getPrefixAndNameFromToken(nElement));
186  return nullptr;
187 }
188 
190 {
191  OUString ret;
192  aFamilyName >>= ret;
193  return ret;
194 }
195 
196 
199  : SvXMLStyleContext( rImport )
200  , uri(_uri)
201 {
202 }
203 
204 void XMLFontStyleContextFontFaceFormat::SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
205  const OUString& rValue )
206 {
207  if( nPrefixKey == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_STRING ))
208  uri.SetFormat(rValue);
209  else
210  SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
211 }
212 
213 
215  const XMLFontStyleContextFontFace& _font )
216  : SvXMLImportContext( rImport )
217  , font( _font )
218 {
219 }
220 
221 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLFontStyleContextFontFaceSrc::createFastChildContext(
222  sal_Int32 nElement,
223  const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
224 {
225  if( nElement == XML_ELEMENT(SVG, XML_FONT_FACE_URI) ||
226  nElement == XML_ELEMENT(SVG_COMPAT, XML_FONT_FACE_URI) )
228  SAL_WARN("xmloff", "unknown element " << SvXMLImport::getPrefixAndNameFromToken(nElement));
229  return nullptr;
230 }
231 
232 
234  const XMLFontStyleContextFontFace& _font )
235  : SvXMLStyleContext( rImport )
236  , font( _font )
237 {
238 }
239 
240 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLFontStyleContextFontFaceUri::createFastChildContext(
241  sal_Int32 nElement,
242  const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
243 {
244  if( nElement == XML_ELEMENT(SVG, XML_FONT_FACE_FORMAT) )
245  return new XMLFontStyleContextFontFaceFormat( GetImport(), *this );
246  else if( nElement == XML_ELEMENT(OFFICE, XML_BINARY_DATA) )
247  {
248  assert(linkPath.isEmpty());
249  if( linkPath.isEmpty() )
250  {
251  mxBase64Stream.set( new comphelper::OSequenceOutputStream( maFontData ) );
252  if( mxBase64Stream.is() )
254  }
255  }
256  else
257  SAL_WARN("xmloff", "unknown element " << SvXMLImport::getPrefixAndNameFromToken(nElement));
258  return nullptr;
259 }
260 
261 void XMLFontStyleContextFontFaceUri::SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
262  const OUString& rValue )
263 {
264  if( nPrefixKey == XML_NAMESPACE_XLINK && IsXMLToken( rLocalName, XML_HREF ))
265  linkPath = rValue;
266  else
267  SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
268 }
269 
270 void XMLFontStyleContextFontFaceUri::SetFormat( const OUString& rFormat )
271 {
272  format = rFormat;
273 }
274 
275 // the CSS2 standard ( http://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#referencing )
276 // defines these format strings.
277 const char OPENTYPE_FORMAT[] = "opentype";
278 const char TRUETYPE_FORMAT[] = "truetype";
279 const char EOT_FORMAT[] = "embedded-opentype";
280 
282 {
283  if( ( linkPath.getLength() == 0 ) && ( !maFontData.hasElements() ) )
284  {
285  SAL_WARN( "xmloff", "svg:font-face-uri tag with no link or base64 data; ignoring." );
286  return;
287  }
288  bool eot;
289  // Assume by default that the font is not compressed.
290  if( format.getLength() == 0
291  || format == OPENTYPE_FORMAT
292  || format == TRUETYPE_FORMAT )
293  {
294  eot = false;
295  }
296  else if( format == EOT_FORMAT )
297  {
298  eot = true;
299  }
300  else
301  {
302  SAL_WARN( "xmloff", "Unknown format of embedded font; assuming TTF." );
303  eot = false;
304  }
305  if ( !maFontData.hasElements() )
307  else
309 }
310 
311 void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const OUString& url, bool eot )
312 {
313  if( GetImport().embeddedFontAlreadyProcessed( url ))
314  {
316  return;
317  }
318  OUString fontName = font.familyName();
319  // If there's any giveMeStreamForThisURL(), then it's well-hidden for me to find it.
320  if( GetImport().IsPackageURL( url ))
321  {
322  uno::Reference< embed::XStorage > storage;
323  storage.set( GetImport().GetSourceStorage(), UNO_SET_THROW );
324  if( url.indexOf( '/' ) > -1 ) // TODO what if more levels?
325  storage.set( storage->openStorageElement( url.copy( 0, url.indexOf( '/' )),
326  ::embed::ElementModes::READ ), uno::UNO_SET_THROW );
327  uno::Reference< io::XInputStream > inputStream;
328  inputStream.set( storage->openStreamElement( url.copy( url.indexOf( '/' ) + 1 ), ::embed::ElementModes::READ ),
329  UNO_QUERY_THROW );
330  if( EmbeddedFontsHelper::addEmbeddedFont( inputStream, fontName, "?", std::vector< unsigned char >(), eot ))
332  inputStream->closeInput();
333  }
334  else
335  SAL_WARN( "xmloff", "External URL for font file not handled." );
336 }
337 
338 void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const ::css::uno::Sequence< sal_Int8 >& rData, const bool eot )
339 {
340  const uno::Reference< io::XInputStream > xInput( new comphelper::SequenceInputStream( rData ) );
341  const OUString fontName = font.familyName();
342  if( EmbeddedFontsHelper::addEmbeddedFont( xInput, fontName, "?", std::vector< unsigned char >(), eot ) )
344  xInput->closeInput();
345 }
346 
348  sal_Int32 nElement,
349  const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList )
350 {
351  if( nElement == XML_ELEMENT(STYLE, XML_FONT_FACE) )
352  {
353  return new XMLFontStyleContextFontFace( GetImport(), *this );
354  }
355  return SvXMLStylesContext::CreateStyleChildContext( nElement, xAttrList );
356 }
357 
358 
360  rtl_TextEncoding eDfltEnc ) :
361  SvXMLStylesContext( rImport ),
362  pFamilyNameHdl( new XMLFontFamilyNamePropHdl ),
363  pFamilyHdl( new XMLFontFamilyPropHdl ),
364  pPitchHdl( new XMLFontPitchPropHdl ),
365  pEncHdl( new XMLFontEncodingPropHdl ),
366  pFontStyleAttrTokenMap( new SvXMLTokenMap(lcl_getFontStyleAttrTokenMap()) ),
367  eDfltEncoding( eDfltEnc )
368 {
369 }
370 
372 
373 bool XMLFontStylesContext::FillProperties( const OUString& rName,
374  ::std::vector< XMLPropertyState > &rProps,
375  sal_Int32 nFamilyNameIdx,
376  sal_Int32 nStyleNameIdx,
377  sal_Int32 nFamilyIdx,
378  sal_Int32 nPitchIdx,
379  sal_Int32 nCharsetIdx ) const
380 {
381  const SvXMLStyleContext* pStyle = FindStyleChildContext( XML_STYLE_FAMILY_FONT, rName, true );
382  const XMLFontStyleContextFontFace *pFontStyle = dynamic_cast<const XMLFontStyleContextFontFace*>(pStyle);// use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
383  if( pFontStyle )
384  pFontStyle->FillProperties( rProps, nFamilyNameIdx, nStyleNameIdx,
385  nFamilyIdx, nPitchIdx, nCharsetIdx );
386  return nullptr != pFontStyle;
387 }
388 
389 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static const SvXMLTokenMapEntry * lcl_getFontStyleAttrTokenMap()
virtual SvXMLStyleContext * CreateStyleChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
Definition: xmlstyle.cxx:331
bool IsXMLToken(const OUString &rString, enum XMLTokenEnum eToken)
compare eToken to the string
Definition: xmltoken.cxx:3434
void SAL_CALL endFastElement(sal_Int32 nElement) override
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
XMLFontStyleContextFontFaceSrc(SvXMLImport &rImport, const XMLFontStyleContextFontFace &font)
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
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:62
virtual void NotifyEmbeddedFontRead()
Definition: xmlimp.hxx:593
constexpr sal_uInt16 XML_NAMESPACE_XLINK
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:262
css::uno::Any const & rValue
Definition: ImageStyle.hxx:38
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
#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
static OUString getPrefixAndNameFromToken(sal_Int32 nToken)
Definition: xmlimp.cxx:2025
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
constexpr sal_uInt16 XML_NAMESPACE_SVG
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
virtual SvXMLStyleContext * CreateStyleChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
sal_uInt16 Get(sal_uInt16 nPrefix, const OUString &rLName) const
Definition: xmltkmap.cxx:99
rtl_TextEncoding GetDfltCharset() const
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
void SetAttribute(sal_uInt16 nPrefixKey, const OUString &rLocalName, const OUString &rValue) override
XMLFontStyleContextFontFaceUri(SvXMLImport &rImport, const XMLFontStyleContextFontFace &font)
XMLFontStyleAttrTokens
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
const SvXMLTokenMap & GetFontStyleAttrTokenMap() const
Handling of tokens in XML:
::css::uno::Reference< ::css::io::XOutputStream > mxBase64Stream
void handleEmbeddedFont(const OUString &url, bool eot)
#define XML_ELEMENT(prefix, name)
Definition: xmlimp.hxx:94
Smart struct to transport an Any with an index to the appropriate property-name.
Definition: maptype.hxx:122
const SvXMLUnitConverter & GetMM100UnitConverter() const
Definition: xmlimp.hxx:404
XMLFontFamilyPropHdl & GetFamilyHdl() const
XMLFontStyleContextFontFace(SvXMLImport &rImport, XMLFontStylesContext &rStyles)
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
virtual void SetAttribute(sal_uInt16 nPrefixKey, const OUString &rLocalName, const OUString &rValue)
Definition: xmlstyle.cxx:65
const SvXMLStyleContext * FindStyleChildContext(XmlStyleFamily nFamily, const OUString &rName, bool bCreateIndex=false) const
Definition: xmlstyle.cxx:808
XMLFontStyleContextFontFaceFormat(SvXMLImport &rImport, XMLFontStyleContextFontFaceUri &uri)
const char TRUETYPE_FORMAT[]
#define SAL_WARN(area, stream)
const char EOT_FORMAT[]
PropertyHandler for the XML-data-type:
Definition: fonthdl.hxx:40
XMLFontFamilyNamePropHdl & GetFamilyNameHdl() const
constexpr sal_uInt16 XML_NAMESPACE_STYLE
void SetFormat(const OUString &rFormat)
exports com.sun.star. uri