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 "FontTable.hxx"
21 #include <o3tl/deleter.hxx>
22 #include <ooxml/resourceids.hxx>
25 #include <sal/log.hxx>
26 #include <rtl/tencinfo.h>
27 #include <vcl/embeddedfontshelper.hxx>
28 #include <unotools/fontdefs.hxx>
30 using namespace com::sun::star
;
32 namespace writerfilter::dmapper
37 std::unique_ptr
<EmbeddedFontsHelper
, o3tl::default_delete
<EmbeddedFontsHelper
>> xEmbeddedFontHelper
;
38 std::vector
< FontEntry::Pointer_t
> aFontEntries
;
39 FontEntry::Pointer_t pCurrentEntry
;
43 FontTable::FontTable()
44 : LoggedProperties("FontTable")
45 , LoggedTable("FontTable")
46 , LoggedStream("FontTable")
47 , m_pImpl( new FontTable_Impl
)
51 FontTable::~FontTable()
55 void FontTable::lcl_attribute(Id Name
, Value
& val
)
57 SAL_WARN_IF( !m_pImpl
->pCurrentEntry
, "writerfilter.dmapper", "current entry has to be set here" );
58 if(!m_pImpl
->pCurrentEntry
)
60 int nIntValue
= val
.getInt();
61 OUString sValue
= val
.getString();
64 case NS_ooxml::LN_CT_Pitch_val
:
65 if (static_cast<Id
>(nIntValue
) == NS_ooxml::LN_Value_ST_Pitch_fixed
)
67 else if (static_cast<Id
>(nIntValue
) == NS_ooxml::LN_Value_ST_Pitch_variable
)
69 else if (static_cast<Id
>(nIntValue
) == NS_ooxml::LN_Value_ST_Pitch_default
)
72 SAL_WARN("writerfilter.dmapper", "FontTable::lcl_attribute: unhandled NS_ooxml::CT_Pitch_val: " << nIntValue
);
74 case NS_ooxml::LN_CT_Font_name
:
75 m_pImpl
->pCurrentEntry
->sFontName
= sValue
;
77 case NS_ooxml::LN_CT_Charset_val
:
78 // w:characterSet has higher priority, set only if that one is not set
79 if( m_pImpl
->pCurrentEntry
->nTextEncoding
== RTL_TEXTENCODING_DONTKNOW
)
81 m_pImpl
->pCurrentEntry
->nTextEncoding
= rtl_getTextEncodingFromWindowsCharset( nIntValue
);
82 if( IsOpenSymbol( m_pImpl
->pCurrentEntry
->sFontName
))
83 m_pImpl
->pCurrentEntry
->nTextEncoding
= RTL_TEXTENCODING_SYMBOL
;
86 case NS_ooxml::LN_CT_Charset_characterSet
:
89 sValue
.convertToString( &tmp
, RTL_TEXTENCODING_ASCII_US
, OUSTRING_TO_OSTRING_CVTFLAGS
);
90 m_pImpl
->pCurrentEntry
->nTextEncoding
= rtl_getTextEncodingFromMimeCharset( tmp
.getStr() );
91 // Older LO versions used to write incorrect character set for OpenSymbol, fix.
92 if( IsOpenSymbol( m_pImpl
->pCurrentEntry
->sFontName
))
93 m_pImpl
->pCurrentEntry
->nTextEncoding
= RTL_TEXTENCODING_SYMBOL
;
100 void FontTable::lcl_sprm(Sprm
& rSprm
)
102 SAL_WARN_IF( !m_pImpl
->pCurrentEntry
, "writerfilter.dmapper", "current entry has to be set here" );
103 if(!m_pImpl
->pCurrentEntry
)
105 sal_uInt32 nSprmId
= rSprm
.getId();
109 case NS_ooxml::LN_CT_Font_charset
:
110 case NS_ooxml::LN_CT_Font_pitch
:
111 resolveSprm( rSprm
);
113 case NS_ooxml::LN_CT_Font_embedRegular
:
114 case NS_ooxml::LN_CT_Font_embedBold
:
115 case NS_ooxml::LN_CT_Font_embedItalic
:
116 case NS_ooxml::LN_CT_Font_embedBoldItalic
:
118 writerfilter::Reference
< Properties
>::Pointer_t pProperties
= rSprm
.getProps();
121 EmbeddedFontHandler
handler(*this, m_pImpl
->pCurrentEntry
->sFontName
,
122 nSprmId
== NS_ooxml::LN_CT_Font_embedRegular
? u
""
123 : nSprmId
== NS_ooxml::LN_CT_Font_embedBold
? u
"b"
124 : nSprmId
== NS_ooxml::LN_CT_Font_embedItalic
? u
"i"
125 : /*NS_ooxml::LN_CT_Font_embedBoldItalic*/ u
"bi" );
126 pProperties
->resolve( handler
);
130 case NS_ooxml::LN_CT_Font_altName
:
132 case NS_ooxml::LN_CT_Font_panose1
:
134 case NS_ooxml::LN_CT_Font_family
:
136 case NS_ooxml::LN_CT_Font_sig
:
138 case NS_ooxml::LN_CT_Font_notTrueType
:
141 SAL_WARN("writerfilter.dmapper", "FontTable::lcl_sprm: unhandled token: " << nSprmId
);
146 void FontTable::resolveSprm(Sprm
& r_Sprm
)
148 writerfilter::Reference
<Properties
>::Pointer_t pProperties
= r_Sprm
.getProps();
150 pProperties
->resolve(*this);
153 void FontTable::lcl_entry(writerfilter::Reference
<Properties
>::Pointer_t ref
)
155 //create a new font entry
156 SAL_WARN_IF( m_pImpl
->pCurrentEntry
, "writerfilter.dmapper", "current entry has to be NULL here" );
157 m_pImpl
->pCurrentEntry
= new FontEntry
;
159 //append it to the table
160 m_pImpl
->aFontEntries
.push_back( m_pImpl
->pCurrentEntry
);
161 m_pImpl
->pCurrentEntry
.clear();
164 void FontTable::lcl_startSectionGroup()
168 void FontTable::lcl_endSectionGroup()
172 void FontTable::lcl_startParagraphGroup()
176 void FontTable::lcl_endParagraphGroup()
180 void FontTable::lcl_startCharacterGroup()
184 void FontTable::lcl_endCharacterGroup()
188 void FontTable::lcl_text(const sal_uInt8
*, size_t )
192 void FontTable::lcl_utext(const sal_Unicode
*, size_t)
196 void FontTable::lcl_props(writerfilter::Reference
<Properties
>::Pointer_t
)
200 void FontTable::lcl_table(Id
, writerfilter::Reference
<Table
>::Pointer_t
)
204 void FontTable::lcl_substream(Id
, ::writerfilter::Reference
<Stream
>::Pointer_t
)
208 void FontTable::lcl_startShape(uno::Reference
<drawing::XShape
> const&)
212 void FontTable::lcl_endShape( )
216 FontEntry::Pointer_t
FontTable::getFontEntry(sal_uInt32 nIndex
)
218 return (m_pImpl
->aFontEntries
.size() > nIndex
)
219 ? m_pImpl
->aFontEntries
[nIndex
]
220 : FontEntry::Pointer_t();
223 sal_uInt32
FontTable::size()
225 return m_pImpl
->aFontEntries
.size();
228 void FontTable::addEmbeddedFont(const css::uno::Reference
<css::io::XInputStream
>& stream
,
229 const OUString
& fontName
, std::u16string_view extra
,
230 std::vector
<unsigned char> const & key
)
232 if (!m_pImpl
->xEmbeddedFontHelper
)
233 m_pImpl
->xEmbeddedFontHelper
.reset(new EmbeddedFontsHelper
);
234 m_pImpl
->xEmbeddedFontHelper
->addEmbeddedFont(stream
, fontName
, extra
, key
);
237 EmbeddedFontHandler::EmbeddedFontHandler(FontTable
& rFontTable
, OUString _fontName
, std::u16string_view style
)
238 : LoggedProperties("EmbeddedFontHandler")
239 , m_fontTable( rFontTable
)
240 , m_fontName(std::move( _fontName
))
245 EmbeddedFontHandler::~EmbeddedFontHandler()
247 if( !m_inputStream
.is())
249 std::vector
< unsigned char > key( 32 );
250 if( !m_fontKey
.isEmpty())
251 { // key for unobfuscating
252 // 1 3 5 7 10 2 5 7 20 2 5 7 9 1 3 5
253 // {62E79491-959F-41E9-B76B-6B32631DEA5C}
254 static const int pos
[ 16 ] = { 35, 33, 31, 29, 27, 25, 22, 20, 17, 15, 12, 10, 7, 5, 3, 1 };
259 int v1
= m_fontKey
[ pos
[ i
]];
260 int v2
= m_fontKey
[ pos
[ i
] + 1 ];
261 assert(( v1
>= '0' && v1
<= '9' ) || ( v1
>= 'A' && v1
<= 'F' ));
262 assert(( v2
>= '0' && v2
<= '9' ) || ( v2
>= 'A' && v2
<= 'F' ));
263 int val
= ( v1
- ( v1
<= '9' ? '0' : 'A' - 10 )) * 16 + v2
- ( v2
<= '9' ? '0' : 'A' - 10 );
268 m_fontTable
.addEmbeddedFont( m_inputStream
, m_fontName
, m_style
, key
);
269 m_inputStream
->closeInput();
272 void EmbeddedFontHandler::lcl_attribute( Id name
, Value
& val
)
274 OUString sValue
= val
.getString();
277 case NS_ooxml::LN_CT_FontRel_fontKey
:
280 case NS_ooxml::LN_CT_Rel_id
:
282 case NS_ooxml::LN_CT_FontRel_subsetted
:
283 break; // TODO? Let's just ignore this for now and hope
284 // it doesn't break anything.
285 case NS_ooxml::LN_inputstream
: // the actual font data as stream
286 val
.getAny() >>= m_inputStream
;
293 void EmbeddedFontHandler::lcl_sprm( Sprm
& )
298 }//namespace writerfilter::dmapper
300 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */