2010-10-12 15:53:47 +02:00
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2012-11-12 17:21:24 +00:00
/*
* This file is part of the LibreOffice project .
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice :
*
* Licensed to the Apache Software Foundation ( ASF ) under one or more
* contributor license agreements . See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership . The ASF licenses this file to you under the Apache
* License , Version 2.0 ( the " License " ) ; you may not use this file
* except in compliance with the License . You may obtain a copy of
* the License at http : //www.apache.org/licenses/LICENSE-2.0 .
*/
2000-11-14 09:19:45 +00:00
2013-01-23 16:31:31 +01:00
# include <xmloff/XMLFontStylesContext.hxx>
2013-02-01 15:04:29 +01:00
# include "XMLFontStylesContext_impl.hxx"
2006-09-17 09:50:01 +00:00
2000-11-14 09:19:45 +00:00
# include <com/sun/star/awt/FontFamily.hpp>
# include <com/sun/star/awt/FontPitch.hpp>
2013-02-01 14:26:36 +01:00
# include <com/sun/star/embed/ElementModes.hpp>
2010-04-19 17:29:55 +02:00
2015-01-05 16:45:25 +01:00
# include <comphelper/seqstream.hxx>
2013-02-01 14:26:36 +01:00
# include <osl/file.hxx>
2013-02-21 13:43:44 +01:00
# include <vcl/embeddedfontshelper.hxx>
2010-04-19 17:29:55 +02:00
2007-06-27 14:33:03 +00:00
# include <xmloff/nmspmap.hxx>
2013-11-11 22:30:35 -06:00
# include <xmloff/xmlnmspe.hxx>
2007-06-27 14:33:03 +00:00
# include <xmloff/xmltoken.hxx>
2000-11-14 09:19:45 +00:00
# include "fonthdl.hxx"
2007-06-27 14:33:03 +00:00
# include <xmloff/xmlimp.hxx>
# include <xmloff/maptype.hxx>
2015-01-05 16:45:25 +01:00
# include <xmloff/XMLBase64ImportContext.hxx>
2010-04-19 17:29:55 +02:00
2008-03-12 09:47:19 +00:00
2000-11-14 09:19:45 +00:00
using namespace : : com : : sun : : star ;
using namespace : : com : : sun : : star : : uno ;
using namespace : : com : : sun : : star : : xml : : sax ;
using namespace : : com : : sun : : star : : container ;
using namespace : : com : : sun : : star : : beans ;
using namespace : : com : : sun : : star : : lang ;
using namespace : : com : : sun : : star : : awt ;
2001-06-15 16:16:59 +00:00
using namespace : : xmloff : : token ;
2000-11-14 09:19:45 +00:00
2001-06-29 20:07:26 +00:00
2000-11-14 09:19:45 +00:00
# define XML_STYLE_FAMILY_FONT 1
enum XMLFontStyleAttrTokens
{
XML_TOK_FONT_STYLE_ATTR_FAMILY ,
XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC ,
XML_TOK_FONT_STYLE_ATTR_STYLENAME ,
XML_TOK_FONT_STYLE_ATTR_PITCH ,
XML_TOK_FONT_STYLE_ATTR_CHARSET ,
XML_TOK_FONT_STYLE_ATTR_END = XML_TOK_UNKNOWN
} ;
2012-10-11 17:52:52 +02:00
static const SvXMLTokenMapEntry * lcl_getFontStyleAttrTokenMap ( )
2000-11-14 09:19:45 +00:00
{
2013-07-18 22:16:42 +09:00
static const SvXMLTokenMapEntry aFontStyleAttrTokenMap [ ] =
2009-04-23 10:42:05 +00:00
{
{ XML_NAMESPACE_SVG , XML_FONT_FAMILY ,
XML_TOK_FONT_STYLE_ATTR_FAMILY } ,
{ XML_NAMESPACE_STYLE , XML_FONT_FAMILY_GENERIC ,
XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC } ,
{ XML_NAMESPACE_STYLE , XML_FONT_ADORNMENTS ,
XML_TOK_FONT_STYLE_ATTR_STYLENAME } ,
{ XML_NAMESPACE_STYLE , XML_FONT_PITCH ,
XML_TOK_FONT_STYLE_ATTR_PITCH } ,
{ XML_NAMESPACE_STYLE , XML_FONT_CHARSET ,
XML_TOK_FONT_STYLE_ATTR_CHARSET } ,
2000-11-14 09:19:45 +00:00
2009-04-23 10:42:05 +00:00
XML_TOKEN_MAP_END
} ;
return aFontStyleAttrTokenMap ;
}
2000-11-14 09:19:45 +00:00
2013-02-01 14:40:16 +01:00
TYPEINIT1 ( XMLFontStyleContextFontFace , SvXMLStyleContext ) ;
2000-11-14 09:19:45 +00:00
2013-02-01 14:40:16 +01:00
XMLFontStyleContextFontFace : : XMLFontStyleContextFontFace ( SvXMLImport & rImport ,
2000-11-14 09:19:45 +00:00
sal_uInt16 nPrfx , const OUString & rLName ,
const Reference < XAttributeList > & xAttrList ,
XMLFontStylesContext & rStyles ) :
2001-01-16 15:36:55 +00:00
SvXMLStyleContext ( rImport , nPrfx , rLName , xAttrList , XML_STYLE_FAMILY_FONT ) ,
2000-11-14 09:19:45 +00:00
xStyles ( & rStyles )
{
OUString sEmpty ;
aFamilyName < < = sEmpty ;
aStyleName < < = sEmpty ;
2012-07-02 13:58:52 +02:00
aFamily < < = ( sal_Int16 ) awt : : FontFamily : : DONTKNOW ;
aPitch < < = ( sal_Int16 ) awt : : FontPitch : : DONTKNOW ;
2000-11-14 09:19:45 +00:00
aEnc < < = ( sal_Int16 ) rStyles . GetDfltCharset ( ) ;
}
2013-02-01 14:40:16 +01:00
void XMLFontStyleContextFontFace : : SetAttribute ( sal_uInt16 nPrefixKey ,
2000-11-14 09:19:45 +00:00
const OUString & rLocalName ,
const OUString & rValue )
{
SvXMLUnitConverter & rUnitConv = GetImport ( ) . GetMM100UnitConverter ( ) ;
const SvXMLTokenMap & rTokenMap = GetStyles ( ) - > GetFontStyleAttrTokenMap ( ) ;
Any aAny ;
switch ( rTokenMap . Get ( nPrefixKey , rLocalName ) )
{
case XML_TOK_FONT_STYLE_ATTR_FAMILY :
if ( GetStyles ( ) - > GetFamilyNameHdl ( ) . importXML ( rValue , aAny ,
rUnitConv ) )
aFamilyName = aAny ;
break ;
case XML_TOK_FONT_STYLE_ATTR_STYLENAME :
aStyleName < < = rValue ;
break ;
case XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC :
if ( GetStyles ( ) - > GetFamilyHdl ( ) . importXML ( rValue , aAny ,
rUnitConv ) )
aFamily = aAny ;
break ;
case XML_TOK_FONT_STYLE_ATTR_PITCH :
if ( GetStyles ( ) - > GetPitchHdl ( ) . importXML ( rValue , aAny ,
rUnitConv ) )
aPitch = aAny ;
break ;
case XML_TOK_FONT_STYLE_ATTR_CHARSET :
if ( GetStyles ( ) - > GetEncodingHdl ( ) . importXML ( rValue , aAny ,
rUnitConv ) )
aEnc = aAny ;
break ;
default :
SvXMLStyleContext : : SetAttribute ( nPrefixKey , rLocalName , rValue ) ;
break ;
}
}
2013-02-01 14:40:16 +01:00
XMLFontStyleContextFontFace : : ~ XMLFontStyleContextFontFace ( )
2000-11-14 09:19:45 +00:00
{
}
2013-02-01 14:40:16 +01:00
void XMLFontStyleContextFontFace : : FillProperties (
2000-11-14 09:19:45 +00:00
: : std : : vector < XMLPropertyState > & rProps ,
sal_Int32 nFamilyNameIdx ,
sal_Int32 nStyleNameIdx ,
sal_Int32 nFamilyIdx ,
sal_Int32 nPitchIdx ,
sal_Int32 nCharsetIdx ) const
{
if ( nFamilyNameIdx ! = - 1 )
{
XMLPropertyState aPropState ( nFamilyNameIdx , aFamilyName ) ;
rProps . push_back ( aPropState ) ;
}
if ( nStyleNameIdx ! = - 1 )
{
XMLPropertyState aPropState ( nStyleNameIdx , aStyleName ) ;
rProps . push_back ( aPropState ) ;
}
if ( nFamilyIdx ! = - 1 )
{
XMLPropertyState aPropState ( nFamilyIdx , aFamily ) ;
rProps . push_back ( aPropState ) ;
}
if ( nPitchIdx ! = - 1 )
{
XMLPropertyState aPropState ( nPitchIdx , aPitch ) ;
rProps . push_back ( aPropState ) ;
}
if ( nCharsetIdx ! = - 1 )
{
XMLPropertyState aPropState ( nCharsetIdx , aEnc ) ;
rProps . push_back ( aPropState ) ;
}
}
2013-02-01 14:40:16 +01:00
SvXMLImportContext * XMLFontStyleContextFontFace : : CreateChildContext (
2013-02-01 14:26:36 +01:00
sal_uInt16 nPrefix ,
2013-04-07 12:06:47 +02:00
const OUString & rLocalName ,
2013-02-01 14:26:36 +01:00
const : : com : : sun : : star : : uno : : Reference < : : com : : sun : : star : : xml : : sax : : XAttributeList > & xAttrList )
{
if ( nPrefix = = XML_NAMESPACE_SVG & & IsXMLToken ( rLocalName , XML_FONT_FACE_SRC ) )
return new XMLFontStyleContextFontFaceSrc ( GetImport ( ) , nPrefix , rLocalName , * this ) ;
return SvXMLStyleContext : : CreateChildContext ( nPrefix , rLocalName , xAttrList ) ;
}
2013-02-01 14:40:16 +01:00
OUString XMLFontStyleContextFontFace : : familyName ( ) const
2013-02-01 14:26:36 +01:00
{
OUString ret ;
aFamilyName > > = ret ;
return ret ;
}
2013-10-05 16:50:24 -07:00
TYPEINIT1 ( XMLFontStyleContextFontFaceFormat , SvXMLStyleContext ) ;
XMLFontStyleContextFontFaceFormat : : XMLFontStyleContextFontFaceFormat ( SvXMLImport & rImport ,
sal_uInt16 nPrfx , const OUString & rLName ,
const : : com : : sun : : star : : uno : : Reference <
: : com : : sun : : star : : xml : : sax : : XAttributeList > & xAttrList ,
XMLFontStyleContextFontFaceUri & _uri )
: SvXMLStyleContext ( rImport , nPrfx , rLName , xAttrList )
, uri ( _uri )
{
}
void XMLFontStyleContextFontFaceFormat : : SetAttribute ( sal_uInt16 nPrefixKey , const OUString & rLocalName ,
const OUString & rValue )
{
if ( nPrefixKey = = XML_NAMESPACE_SVG & & IsXMLToken ( rLocalName , XML_STRING ) )
uri . SetFormat ( rValue ) ;
else
SvXMLStyleContext : : SetAttribute ( nPrefixKey , rLocalName , rValue ) ;
}
2013-02-01 14:26:36 +01:00
TYPEINIT1 ( XMLFontStyleContextFontFaceSrc , SvXMLImportContext ) ;
XMLFontStyleContextFontFaceSrc : : XMLFontStyleContextFontFaceSrc ( SvXMLImport & rImport ,
sal_uInt16 nPrfx , const OUString & rLName ,
2013-02-01 14:40:16 +01:00
const XMLFontStyleContextFontFace & _font )
2013-02-01 14:26:36 +01:00
: SvXMLImportContext ( rImport , nPrfx , rLName )
, font ( _font )
{
}
SvXMLImportContext * XMLFontStyleContextFontFaceSrc : : CreateChildContext (
sal_uInt16 nPrefix ,
2013-04-07 12:06:47 +02:00
const OUString & rLocalName ,
2013-02-01 14:26:36 +01:00
const : : com : : sun : : star : : uno : : Reference < : : com : : sun : : star : : xml : : sax : : XAttributeList > & xAttrList )
{
if ( nPrefix = = XML_NAMESPACE_SVG & & IsXMLToken ( rLocalName , XML_FONT_FACE_URI ) )
return new XMLFontStyleContextFontFaceUri ( GetImport ( ) , nPrefix , rLocalName , xAttrList , font ) ;
return SvXMLImportContext : : CreateChildContext ( nPrefix , rLocalName , xAttrList ) ;
}
TYPEINIT1 ( XMLFontStyleContextFontFaceUri , SvXMLImportContext ) ;
XMLFontStyleContextFontFaceUri : : XMLFontStyleContextFontFaceUri ( SvXMLImport & rImport ,
sal_uInt16 nPrfx , const OUString & rLName ,
const : : com : : sun : : star : : uno : : Reference <
: : com : : sun : : star : : xml : : sax : : XAttributeList > & xAttrList ,
2013-02-01 14:40:16 +01:00
const XMLFontStyleContextFontFace & _font )
2013-02-01 14:26:36 +01:00
: SvXMLStyleContext ( rImport , nPrfx , rLName , xAttrList )
, font ( _font )
{
}
2013-10-05 16:50:24 -07:00
SvXMLImportContext * XMLFontStyleContextFontFaceUri : : CreateChildContext (
sal_uInt16 nPrefix ,
const OUString & rLocalName ,
const : : com : : sun : : star : : uno : : Reference < : : com : : sun : : star : : xml : : sax : : XAttributeList > & xAttrList )
{
if ( nPrefix = = XML_NAMESPACE_SVG & & IsXMLToken ( rLocalName , XML_FONT_FACE_FORMAT ) )
return new XMLFontStyleContextFontFaceFormat ( GetImport ( ) , nPrefix , rLocalName , xAttrList , * this ) ;
2015-01-05 16:45:25 +01:00
if ( linkPath . isEmpty ( ) & & ( nPrefix = = XML_NAMESPACE_OFFICE ) & & IsXMLToken ( rLocalName , XML_BINARY_DATA ) )
{
mxBase64Stream . set ( new comphelper : : OSequenceOutputStream ( maFontData ) ) ;
if ( mxBase64Stream . is ( ) )
return new XMLBase64ImportContext ( GetImport ( ) , nPrefix , rLocalName , xAttrList , mxBase64Stream ) ;
}
2013-10-05 16:50:24 -07:00
return SvXMLImportContext : : CreateChildContext ( nPrefix , rLocalName , xAttrList ) ;
}
2013-02-01 14:26:36 +01:00
void XMLFontStyleContextFontFaceUri : : SetAttribute ( sal_uInt16 nPrefixKey , const OUString & rLocalName ,
const OUString & rValue )
{
if ( nPrefixKey = = XML_NAMESPACE_XLINK & & IsXMLToken ( rLocalName , XML_HREF ) )
2013-10-05 16:50:24 -07:00
linkPath = rValue ;
2013-02-01 14:26:36 +01:00
else
SvXMLStyleContext : : SetAttribute ( nPrefixKey , rLocalName , rValue ) ;
}
2013-10-05 16:50:24 -07:00
void XMLFontStyleContextFontFaceUri : : SetFormat ( const OUString & rFormat )
{
format = rFormat ;
}
2013-11-13 15:48:04 +00:00
// the CSS2 standard ( http://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#referencing )
// defines these format strings.
const char * OPENTYPE_FORMAT = " opentype " ;
const char * TRUETYPE_FORMAT = " truetype " ;
const char * EOT_FORMAT = " embedded-opentype " ;
2013-10-05 16:50:24 -07:00
void XMLFontStyleContextFontFaceUri : : EndElement ( )
{
2015-01-05 16:45:25 +01:00
if ( ( linkPath . getLength ( ) = = 0 ) & & ( maFontData . getLength ( ) = = 0 ) )
2013-10-05 16:50:24 -07:00
{
2015-01-05 16:45:25 +01:00
SAL_WARN ( " xmloff " , " svg:font-face-uri tag with no link or base64 data; ignoring. " ) ;
2013-10-05 16:50:24 -07:00
return ;
}
bool eot ;
// Assume by default that the font is not compressed.
if ( format . getLength ( ) = = 0
| | format . equalsAscii ( OPENTYPE_FORMAT )
| | format . equalsAscii ( TRUETYPE_FORMAT ) )
{
eot = false ;
}
else if ( format . equalsAscii ( EOT_FORMAT ) )
{
eot = true ;
}
else
{
SAL_WARN ( " xmloff " , " Unknown format of embedded font; assuming TTF. " ) ;
eot = false ;
}
2015-01-05 16:45:25 +01:00
if ( maFontData . getLength ( ) = = 0 )
handleEmbeddedFont ( linkPath , eot ) ;
else
handleEmbeddedFont ( maFontData , eot ) ;
2013-10-05 16:50:24 -07:00
}
void XMLFontStyleContextFontFaceUri : : handleEmbeddedFont ( const OUString & url , bool eot )
2013-02-01 14:26:36 +01:00
{
2013-03-05 19:35:42 +01:00
if ( GetImport ( ) . embeddedFontAlreadyProcessed ( url ) )
{
GetImport ( ) . NotifyEmbeddedFontRead ( ) ;
return ;
}
2013-02-01 14:26:36 +01:00
OUString fontName = font . familyName ( ) ;
// If there's any giveMeStreamForThisURL(), then it's well-hidden for me to find it.
if ( GetImport ( ) . IsPackageURL ( url ) )
{
uno : : Reference < embed : : XStorage > storage ;
storage . set ( GetImport ( ) . GetSourceStorage ( ) , UNO_QUERY_THROW ) ;
if ( url . indexOf ( ' / ' ) > - 1 ) // TODO what if more levels?
storage . set ( storage - > openStorageElement ( url . copy ( 0 , url . indexOf ( ' / ' ) ) ,
: : embed : : ElementModes : : READ ) , uno : : UNO_QUERY_THROW ) ;
uno : : Reference < io : : XInputStream > inputStream ;
inputStream . set ( storage - > openStreamElement ( url . copy ( url . indexOf ( ' / ' ) + 1 ) , : : embed : : ElementModes : : READ ) ,
UNO_QUERY_THROW ) ;
2013-10-05 16:50:24 -07:00
if ( EmbeddedFontsHelper : : addEmbeddedFont ( inputStream , fontName , " ? " , std : : vector < unsigned char > ( ) , eot ) )
2013-03-07 18:37:30 +01:00
GetImport ( ) . NotifyEmbeddedFontRead ( ) ;
2013-02-01 14:26:36 +01:00
inputStream - > closeInput ( ) ;
}
else
SAL_WARN ( " xmloff " , " External URL for font file not handled. " ) ;
}
2015-01-05 16:45:25 +01:00
void XMLFontStyleContextFontFaceUri : : handleEmbeddedFont ( const : : css : : uno : : Sequence < sal_Int8 > & rData , const bool eot )
{
const uno : : Reference < io : : XInputStream > xInput ( new comphelper : : SequenceInputStream ( rData ) ) ;
const OUString fontName = font . familyName ( ) ;
if ( EmbeddedFontsHelper : : addEmbeddedFont ( xInput , fontName , " ? " , std : : vector < unsigned char > ( ) , eot ) )
GetImport ( ) . NotifyEmbeddedFontRead ( ) ;
xInput - > closeInput ( ) ;
}
2000-11-14 09:19:45 +00:00
SvXMLStyleContext * XMLFontStylesContext : : CreateStyleChildContext (
sal_uInt16 nPrefix ,
2013-04-07 12:06:47 +02:00
const OUString & rLocalName ,
2000-11-14 09:19:45 +00:00
const : : com : : sun : : star : : uno : : Reference <
: : com : : sun : : star : : xml : : sax : : XAttributeList > & xAttrList )
{
SvXMLStyleContext * pStyle ;
if ( XML_NAMESPACE_STYLE = = nPrefix & &
2004-07-13 07:22:51 +00:00
IsXMLToken ( rLocalName , XML_FONT_FACE ) )
2000-11-14 09:19:45 +00:00
{
2013-02-01 14:40:16 +01:00
pStyle = new XMLFontStyleContextFontFace ( GetImport ( ) , nPrefix ,
2000-11-14 09:19:45 +00:00
rLocalName , xAttrList , * this ) ;
}
else
{
pStyle = SvXMLStylesContext : : CreateStyleChildContext ( nPrefix ,
rLocalName , xAttrList ) ;
}
return pStyle ;
}
TYPEINIT1 ( XMLFontStylesContext , SvXMLStylesContext ) ;
XMLFontStylesContext : : XMLFontStylesContext ( SvXMLImport & rImport ,
sal_uInt16 nPrfx , const OUString & rLName ,
const Reference < XAttributeList > & xAttrList ,
rtl_TextEncoding eDfltEnc ) :
SvXMLStylesContext ( rImport , nPrfx , rLName , xAttrList ) ,
pFamilyNameHdl ( new XMLFontFamilyNamePropHdl ) ,
pFamilyHdl ( new XMLFontFamilyPropHdl ) ,
pPitchHdl ( new XMLFontPitchPropHdl ) ,
pEncHdl ( new XMLFontEncodingPropHdl ) ,
2009-04-23 10:42:05 +00:00
pFontStyleAttrTokenMap ( new SvXMLTokenMap ( lcl_getFontStyleAttrTokenMap ( ) ) ) ,
2006-06-19 17:29:23 +00:00
eDfltEncoding ( eDfltEnc )
2000-11-14 09:19:45 +00:00
{
}
XMLFontStylesContext : : ~ XMLFontStylesContext ( )
{
delete pFamilyNameHdl ;
delete pFamilyHdl ;
delete pPitchHdl ;
delete pEncHdl ;
delete pFontStyleAttrTokenMap ;
}
2014-03-27 17:24:01 +02:00
bool XMLFontStylesContext : : FillProperties ( const OUString & rName ,
2000-11-14 09:19:45 +00:00
: : std : : vector < XMLPropertyState > & rProps ,
sal_Int32 nFamilyNameIdx ,
sal_Int32 nStyleNameIdx ,
sal_Int32 nFamilyIdx ,
sal_Int32 nPitchIdx ,
sal_Int32 nCharsetIdx ) const
{
2014-03-31 11:47:05 +02:00
const SvXMLStyleContext * pStyle = FindStyleChildContext ( XML_STYLE_FAMILY_FONT , rName , true ) ;
2013-02-01 14:40:16 +01:00
const XMLFontStyleContextFontFace * pFontStyle = PTR_CAST ( XMLFontStyleContextFontFace , pStyle ) ; // use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
2000-11-14 09:19:45 +00:00
if ( pFontStyle )
pFontStyle - > FillProperties ( rProps , nFamilyNameIdx , nStyleNameIdx ,
nFamilyIdx , nPitchIdx , nCharsetIdx ) ;
return 0 ! = pFontStyle ;
}
2010-10-12 15:53:47 +02:00
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */