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>
31 
32 #include <xmloff/xmlnamespace.hxx>
33 #include <xmloff/xmltoken.hxx>
34 #include "fonthdl.hxx"
35 #include <xmloff/xmlimp.hxx>
36 #include <xmloff/maptype.hxx>
38 
39 
40 using namespace ::com::sun::star;
41 using namespace ::com::sun::star::uno;
42 using namespace ::com::sun::star::xml::sax;
43 using namespace ::com::sun::star::container;
44 using namespace ::com::sun::star::beans;
45 using namespace ::com::sun::star::lang;
46 using namespace ::com::sun::star::awt;
47 using namespace ::xmloff::token;
48 
49 
50 #define XML_STYLE_FAMILY_FONT XmlStyleFamily::PAGE_MASTER
51 
53  XMLFontStylesContext& rStyles ) :
55  xStyles( &rStyles )
56 {
57  aFamilyName <<= OUString();
58  aStyleName <<= OUString();
59  aFamily <<= sal_Int16(awt::FontFamily::DONTKNOW);
60  aPitch <<= sal_Int16(awt::FontPitch::DONTKNOW);
61  aEnc <<= static_cast<sal_Int16>(rStyles.GetDfltCharset());
62 }
63 
65  const OUString& rValue )
66 {
68  Any aAny;
69 
70  switch(nElement)
71  {
73  case XML_ELEMENT(SVG_COMPAT, XML_FONT_FAMILY):
74  if( GetStyles()->GetFamilyNameHdl().importXML( rValue, aAny,
75  rUnitConv ) )
76  aFamilyName = aAny;
77  break;
79  aStyleName <<= rValue;
80  break;
82  if( GetStyles()->GetFamilyHdl().importXML( rValue, aAny,
83  rUnitConv ) )
84  aFamily = aAny;
85  break;
87  if( GetStyles()->GetPitchHdl().importXML( rValue, aAny,
88  rUnitConv ) )
89  aPitch = aAny;
90  break;
92  if( GetStyles()->GetEncodingHdl().importXML( rValue, aAny,
93  rUnitConv ) )
94  aEnc = aAny;
95  break;
96  default:
97  SvXMLStyleContext::SetAttribute( nElement, rValue );
98  break;
99  }
100 }
101 
103 {
104 }
105 
107  ::std::vector< XMLPropertyState > &rProps,
108  sal_Int32 nFamilyNameIdx,
109  sal_Int32 nStyleNameIdx,
110  sal_Int32 nFamilyIdx,
111  sal_Int32 nPitchIdx,
112  sal_Int32 nCharsetIdx ) const
113 {
114  if( nFamilyNameIdx != -1 )
115  {
116  XMLPropertyState aPropState( nFamilyNameIdx, aFamilyName );
117  rProps.push_back( aPropState );
118  }
119  if( nStyleNameIdx != -1 )
120  {
121  XMLPropertyState aPropState( nStyleNameIdx, aStyleName );
122  rProps.push_back( aPropState );
123  }
124  if( nFamilyIdx != -1 )
125  {
126  XMLPropertyState aPropState( nFamilyIdx, aFamily );
127  rProps.push_back( aPropState );
128  }
129  if( nPitchIdx != -1 )
130  {
131  XMLPropertyState aPropState( nPitchIdx, aPitch );
132  rProps.push_back( aPropState );
133  }
134  if( nCharsetIdx != -1 )
135  {
136  XMLPropertyState aPropState( nCharsetIdx, aEnc );
137  rProps.push_back( aPropState );
138  }
139 }
140 
141 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLFontStyleContextFontFace::createFastChildContext(
142  sal_Int32 nElement,
143  const css::uno::Reference< css::xml::sax::XFastAttributeList > & )
144 {
145  if( nElement == XML_ELEMENT(SVG, XML_FONT_FACE_SRC) ||
146  nElement == XML_ELEMENT(SVG_COMPAT, XML_FONT_FACE_SRC) )
147  return new XMLFontStyleContextFontFaceSrc( GetImport(), *this );
148  else
149  XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
150  return nullptr;
151 }
152 
154 {
155  OUString ret;
156  aFamilyName >>= ret;
157  return ret;
158 }
159 
160 
163  : SvXMLStyleContext( rImport )
164  , uri(_uri)
165 {
166 }
167 
169  const OUString& rValue )
170 {
171  if( nElement == XML_ELEMENT(SVG, XML_STRING) || nElement == XML_ELEMENT(SVG_COMPAT, XML_STRING))
172  uri.SetFormat(rValue);
173  else
174  SvXMLStyleContext::SetAttribute( nElement, rValue );
175 }
176 
177 
179  const XMLFontStyleContextFontFace& _font )
180  : SvXMLImportContext( rImport )
181  , font( _font )
182 {
183 }
184 
185 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLFontStyleContextFontFaceSrc::createFastChildContext(
186  sal_Int32 nElement,
187  const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
188 {
189  if( nElement == XML_ELEMENT(SVG, XML_FONT_FACE_URI) ||
190  nElement == XML_ELEMENT(SVG_COMPAT, XML_FONT_FACE_URI) )
192  XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
193  return nullptr;
194 }
195 
196 
198  const XMLFontStyleContextFontFace& _font )
199  : SvXMLStyleContext( rImport )
200  , font( _font )
201 {
202 }
203 
204 css::uno::Reference< css::xml::sax::XFastContextHandler > XMLFontStyleContextFontFaceUri::createFastChildContext(
205  sal_Int32 nElement,
206  const css::uno::Reference< css::xml::sax::XFastAttributeList > & /*xAttrList*/ )
207 {
208  if( nElement == XML_ELEMENT(SVG, XML_FONT_FACE_FORMAT) )
209  return new XMLFontStyleContextFontFaceFormat( GetImport(), *this );
210  else if( nElement == XML_ELEMENT(OFFICE, XML_BINARY_DATA) )
211  {
212  assert(linkPath.isEmpty());
213  if( linkPath.isEmpty() )
214  {
215  mxBase64Stream.set( new comphelper::OSequenceOutputStream( maFontData ) );
216  if( mxBase64Stream.is() )
218  }
219  }
220  else
221  XMLOFF_WARN_UNKNOWN_ELEMENT("xmloff", nElement);
222  return nullptr;
223 }
224 
226  const OUString& rValue )
227 {
228  if( nElement == XML_ELEMENT(XLINK, XML_HREF) )
229  linkPath = rValue;
230  else
231  SvXMLStyleContext::SetAttribute( nElement, rValue );
232 }
233 
234 void XMLFontStyleContextFontFaceUri::SetFormat( const OUString& rFormat )
235 {
236  format = rFormat;
237 }
238 
239 // the CSS2 standard ( http://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#referencing )
240 // defines these format strings.
241 const char OPENTYPE_FORMAT[] = "opentype";
242 const char TRUETYPE_FORMAT[] = "truetype";
243 const char EOT_FORMAT[] = "embedded-opentype";
244 
246 {
247  if( ( linkPath.getLength() == 0 ) && ( !maFontData.hasElements() ) )
248  {
249  SAL_WARN( "xmloff", "svg:font-face-uri tag with no link or base64 data; ignoring." );
250  return;
251  }
252  bool eot;
253  // Assume by default that the font is not compressed.
254  if( format.getLength() == 0
255  || format == OPENTYPE_FORMAT
256  || format == TRUETYPE_FORMAT )
257  {
258  eot = false;
259  }
260  else if( format == EOT_FORMAT )
261  {
262  eot = true;
263  }
264  else
265  {
266  SAL_WARN( "xmloff", "Unknown format of embedded font; assuming TTF." );
267  eot = false;
268  }
269  if ( !maFontData.hasElements() )
271  else
273 }
274 
275 void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const OUString& url, bool eot )
276 {
277  if( GetImport().embeddedFontAlreadyProcessed( url ))
278  {
280  return;
281  }
282  OUString fontName = font.familyName();
283  // If there's any giveMeStreamForThisURL(), then it's well-hidden for me to find it.
284  if( GetImport().IsPackageURL( url ))
285  {
286  uno::Reference< embed::XStorage > storage;
287  storage.set( GetImport().GetSourceStorage(), UNO_SET_THROW );
288  if( url.indexOf( '/' ) > -1 ) // TODO what if more levels?
289  storage.set( storage->openStorageElement( url.copy( 0, url.indexOf( '/' )),
290  ::embed::ElementModes::READ ), uno::UNO_SET_THROW );
291  uno::Reference< io::XInputStream > inputStream;
292  inputStream.set( storage->openStreamElement( url.copy( url.indexOf( '/' ) + 1 ), ::embed::ElementModes::READ ),
293  UNO_QUERY_THROW );
294  if (GetImport().addEmbeddedFont(inputStream, fontName, "?", std::vector< unsigned char >(), eot))
296  inputStream->closeInput();
297  }
298  else
299  SAL_WARN( "xmloff", "External URL for font file not handled." );
300 }
301 
302 void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const ::css::uno::Sequence< sal_Int8 >& rData, const bool eot )
303 {
304  const uno::Reference< io::XInputStream > xInput( new comphelper::SequenceInputStream( rData ) );
305  const OUString fontName = font.familyName();
306  if (GetImport().addEmbeddedFont(xInput, fontName, "?", std::vector< unsigned char >(), eot))
308  xInput->closeInput();
309 }
310 
312  sal_Int32 nElement,
313  const css::uno::Reference< css::xml::sax::XFastAttributeList > & xAttrList )
314 {
315  if( nElement == XML_ELEMENT(STYLE, XML_FONT_FACE) )
316  {
317  return new XMLFontStyleContextFontFace( GetImport(), *this );
318  }
319  return SvXMLStylesContext::CreateStyleChildContext( nElement, xAttrList );
320 }
321 
322 
324  rtl_TextEncoding eDfltEnc ) :
325  SvXMLStylesContext( rImport ),
326  pFamilyNameHdl( new XMLFontFamilyNamePropHdl ),
327  pFamilyHdl( new XMLFontFamilyPropHdl ),
328  pPitchHdl( new XMLFontPitchPropHdl ),
329  pEncHdl( new XMLFontEncodingPropHdl ),
330  eDfltEncoding( eDfltEnc )
331 {
332 }
333 
335 
336 bool XMLFontStylesContext::FillProperties( const OUString& rName,
337  ::std::vector< XMLPropertyState > &rProps,
338  sal_Int32 nFamilyNameIdx,
339  sal_Int32 nStyleNameIdx,
340  sal_Int32 nFamilyIdx,
341  sal_Int32 nPitchIdx,
342  sal_Int32 nCharsetIdx ) const
343 {
344  const SvXMLStyleContext* pStyle = FindStyleChildContext( XML_STYLE_FAMILY_FONT, rName, true );
345  const XMLFontStyleContextFontFace *pFontStyle = dynamic_cast<const XMLFontStyleContextFontFace*>(pStyle);// use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
346  if( pFontStyle )
347  pFontStyle->FillProperties( rProps, nFamilyNameIdx, nStyleNameIdx,
348  nFamilyIdx, nPitchIdx, nCharsetIdx );
349  return nullptr != pFontStyle;
350 }
351 
352 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual SvXMLStyleContext * CreateStyleChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
Definition: xmlstyle.cxx:311
void SAL_CALL endFastElement(sal_Int32 nElement) override
endFastElement is called before a context will be destructed, but after an elements context has been ...
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:63
const char OPENTYPE_FORMAT[]
the SvXMLTypeConverter converts values of various types from their internal representation to the tex...
Definition: xmluconv.hxx:82
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:59
virtual void NotifyContainsEmbeddedFont()
Definition: xmlimp.hxx:592
virtual void SetAttribute(sal_Int32 nElement, const OUString &rValue) override
void SetAttribute(sal_Int32 nElement, const OUString &rValue) override
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
#define XML_STYLE_FAMILY_FONT
PropertyHandler for the XML-data-type:
Definition: fonthdl.hxx:27
virtual ~XMLFontStyleContextFontFace() override
PropertyHandler for the XML-data-type:
Definition: fonthdl.hxx:51
const XMLFontStyleContextFontFace & font
virtual SvXMLStyleContext * CreateStyleChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
virtual void SetAttribute(sal_Int32 nElement, const OUString &rValue)
Definition: xmlstyle.cxx:66
rtl_TextEncoding GetDfltCharset() const
XMLFontStylesContext(SvXMLImport &rImport, rtl_TextEncoding eDfltEnc)
XMLOFF_DLLPUBLIC bool importXML(css::uno::Reference< css::xml::sax::XFastAttributeList > const &xAttrList, css::uno::Any &rValue, OUString &rStrName, SvXMLImport &rImport)
::css::uno::Sequence< sal_Int8 > maFontData
This class deliberately does not support XWeak, to improve performance when loading large documents...
Definition: xmlictxt.hxx:44
XMLFontStyleContextFontFaceUri(SvXMLImport &rImport, const XMLFontStyleContextFontFace &font)
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
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:97
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:400
void SetAttribute(sal_Int32 nElement, const OUString &rValue) override
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
const SvXMLStyleContext * FindStyleChildContext(XmlStyleFamily nFamily, const OUString &rName, bool bCreateIndex=false) const
Definition: xmlstyle.cxx:788
XMLFontStyleContextFontFaceFormat(SvXMLImport &rImport, XMLFontStyleContextFontFaceUri &uri)
const char TRUETYPE_FORMAT[]
#define SAL_WARN(area, stream)
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
Definition: xmlictxt.hxx:119
const char EOT_FORMAT[]
PropertyHandler for the XML-data-type:
Definition: fonthdl.hxx:39
bool addEmbeddedFont(const css::uno::Reference< css::io::XInputStream > &stream, const OUString &fontName, const char *extra, std::vector< unsigned char > const &key, bool eot)
Definition: xmlimp.cxx:459
void SetFormat(const OUString &rFormat)
exports com.sun.star. uri