Line data Source code
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 :
20 : #include <FontTable.hxx>
21 : #include <doctok/resourceids.hxx>
22 : #include <ooxml/resourceids.hxx>
23 : #include <vector>
24 : #include <osl/file.hxx>
25 : #include <stdio.h>
26 : #include <rtl/tencinfo.h>
27 : #include <vcl/temporaryfonts.hxx>
28 :
29 : #include "dmapperLoggers.hxx"
30 :
31 : namespace writerfilter {
32 : namespace dmapper
33 : {
34 :
35 324 : struct FontTable_Impl
36 : {
37 : std::vector< FontEntry::Pointer_t > aFontEntries;
38 : FontEntry::Pointer_t pCurrentEntry;
39 324 : FontTable_Impl() {}
40 : };
41 :
42 324 : FontTable::FontTable()
43 : : LoggedProperties(dmapper_logger, "FontTable")
44 : , LoggedTable(dmapper_logger, "FontTable")
45 : , LoggedStream(dmapper_logger, "FontTable")
46 324 : , m_pImpl( new FontTable_Impl )
47 : {
48 324 : }
49 :
50 972 : FontTable::~FontTable()
51 : {
52 324 : delete m_pImpl;
53 648 : }
54 :
55 2968 : void FontTable::lcl_attribute(Id Name, Value & val)
56 : {
57 : OSL_ENSURE( m_pImpl->pCurrentEntry, "current entry has to be set here");
58 2968 : if(!m_pImpl->pCurrentEntry)
59 2968 : return ;
60 2968 : int nIntValue = val.getInt();
61 2968 : OUString sValue = val.getString();
62 2968 : switch(Name)
63 : {
64 : case NS_rtf::LN_CBFFNM1:
65 0 : m_pImpl->pCurrentEntry->sFontName1 = sValue;
66 0 : break;
67 : case NS_rtf::LN_PRQ:
68 0 : m_pImpl->pCurrentEntry->nPitchRequest = static_cast<sal_Int16>( nIntValue );
69 0 : break;
70 : case NS_rtf::LN_FTRUETYPE:
71 0 : m_pImpl->pCurrentEntry->bTrueType = nIntValue == 1 ? true : false;
72 0 : break;
73 : case NS_rtf::LN_UNUSED1_3: //unused
74 : case NS_rtf::LN_FF: //unused
75 : case NS_rtf::LN_UNUSED1_7: //unused
76 0 : break;
77 : case NS_rtf::LN_WWEIGHT:
78 0 : m_pImpl->pCurrentEntry->nBaseWeight = nIntValue;
79 0 : break;
80 : case NS_rtf::LN_CHS:
81 0 : m_pImpl->pCurrentEntry->nTextEncoding = nIntValue;
82 0 : break;
83 : case NS_rtf::LN_IXCHSZALT:
84 0 : break;
85 : case NS_rtf::LN_PANOSE:
86 0 : m_pImpl->pCurrentEntry->sPanose += sValue;
87 0 : break;
88 : case NS_rtf::LN_FS:
89 0 : m_pImpl->pCurrentEntry->sFontSignature += sValue;
90 0 : break;
91 : case NS_rtf::LN_F:
92 0 : break;
93 : case NS_rtf::LN_ALTFONTNAME:
94 0 : m_pImpl->pCurrentEntry->sAlternativeFont = sValue;
95 0 : break;
96 : case NS_rtf::LN_XSZFFN:
97 : case NS_ooxml::LN_CT_Font_name:
98 1834 : m_pImpl->pCurrentEntry->sFontName = sValue;
99 1834 : break;
100 : case NS_ooxml::LN_CT_Charset_val:
101 : // w:characterSet has higher priority, set only if that one is not set
102 914 : if( m_pImpl->pCurrentEntry->nTextEncoding == RTL_TEXTENCODING_DONTKNOW )
103 694 : m_pImpl->pCurrentEntry->nTextEncoding = rtl_getTextEncodingFromWindowsCharset( nIntValue );
104 914 : break;
105 : case NS_ooxml::LN_CT_Charset_characterSet:
106 : {
107 220 : OString tmp;
108 220 : sValue.convertToString( &tmp, RTL_TEXTENCODING_ASCII_US, OUSTRING_TO_OSTRING_CVTFLAGS );
109 220 : m_pImpl->pCurrentEntry->nTextEncoding = rtl_getTextEncodingFromMimeCharset( tmp.getStr() );
110 220 : break;
111 : }
112 : default:
113 : {
114 : //----> debug
115 0 : int nVal = val.getInt();
116 0 : ++nVal;
117 : //<---- debug
118 : }
119 2968 : }
120 : }
121 :
122 4904 : void FontTable::lcl_sprm(Sprm& rSprm)
123 : {
124 : OSL_ENSURE( m_pImpl->pCurrentEntry, "current entry has to be set here");
125 4904 : if(!m_pImpl->pCurrentEntry)
126 4904 : return ;
127 4904 : sal_uInt32 nSprmId = rSprm.getId();
128 :
129 4904 : Value::Pointer_t pValue = rSprm.getValue();
130 4904 : sal_Int32 nIntValue = pValue->getInt();
131 : (void)nIntValue;
132 4904 : switch(nSprmId)
133 : {
134 : case NS_ooxml::LN_CT_Font_charset:
135 914 : resolveSprm( rSprm );
136 914 : break;
137 : case NS_ooxml::LN_CT_Font_embedRegular:
138 : case NS_ooxml::LN_CT_Font_embedBold:
139 : case NS_ooxml::LN_CT_Font_embedItalic:
140 : case NS_ooxml::LN_CT_Font_embedBoldItalic:
141 : {
142 0 : writerfilter::Reference< Properties >::Pointer_t pProperties = rSprm.getProps();
143 0 : if( pProperties.get( ))
144 : {
145 0 : EmbeddedFontHandler handler( m_pImpl->pCurrentEntry->sFontName,
146 : nSprmId == NS_ooxml::LN_CT_Font_embedRegular ? ""
147 : : nSprmId == NS_ooxml::LN_CT_Font_embedBold ? "b"
148 : : nSprmId == NS_ooxml::LN_CT_Font_embedItalic ? "i"
149 0 : : nSprmId == NS_ooxml::LN_CT_Font_embedBoldItalic ? "bi" : "?" );
150 0 : pProperties->resolve( handler );
151 : }
152 0 : break;
153 : }
154 4904 : }
155 : }
156 :
157 914 : void FontTable::resolveSprm(Sprm & r_Sprm)
158 : {
159 914 : writerfilter::Reference<Properties>::Pointer_t pProperties = r_Sprm.getProps();
160 914 : if( pProperties.get())
161 914 : pProperties->resolve(*this);
162 914 : }
163 :
164 1834 : void FontTable::lcl_entry(int /*pos*/, writerfilter::Reference<Properties>::Pointer_t ref)
165 : {
166 : //create a new font entry
167 : OSL_ENSURE( !m_pImpl->pCurrentEntry, "current entry has to be NULL here");
168 1834 : m_pImpl->pCurrentEntry.reset(new FontEntry);
169 1834 : ref->resolve(*this);
170 : //append it to the table
171 1834 : m_pImpl->aFontEntries.push_back( m_pImpl->pCurrentEntry );
172 1834 : m_pImpl->pCurrentEntry.reset();
173 1834 : }
174 :
175 0 : void FontTable::lcl_startSectionGroup()
176 : {
177 0 : }
178 :
179 0 : void FontTable::lcl_endSectionGroup()
180 : {
181 0 : }
182 :
183 0 : void FontTable::lcl_startParagraphGroup()
184 : {
185 0 : }
186 :
187 0 : void FontTable::lcl_endParagraphGroup()
188 : {
189 0 : }
190 :
191 0 : void FontTable::lcl_startCharacterGroup()
192 : {
193 0 : }
194 :
195 0 : void FontTable::lcl_endCharacterGroup()
196 : {
197 0 : }
198 :
199 0 : void FontTable::lcl_text(const sal_uInt8*, size_t )
200 : {
201 0 : }
202 :
203 0 : void FontTable::lcl_utext(const sal_uInt8* , size_t)
204 : {
205 0 : }
206 :
207 0 : void FontTable::lcl_props(writerfilter::Reference<Properties>::Pointer_t)
208 : {
209 0 : }
210 :
211 0 : void FontTable::lcl_table(Id, writerfilter::Reference<Table>::Pointer_t)
212 : {
213 0 : }
214 :
215 0 : void FontTable::lcl_substream(Id, ::writerfilter::Reference<Stream>::Pointer_t)
216 : {
217 0 : }
218 :
219 0 : void FontTable::lcl_info(const string& )
220 : {
221 0 : }
222 :
223 0 : void FontTable::lcl_startShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > )
224 : {
225 0 : }
226 :
227 0 : void FontTable::lcl_endShape( )
228 : {
229 0 : }
230 :
231 9316 : const FontEntry::Pointer_t FontTable::getFontEntry(sal_uInt32 nIndex)
232 : {
233 9316 : return (m_pImpl->aFontEntries.size() > nIndex)
234 9316 : ? m_pImpl->aFontEntries[nIndex]
235 18632 : : FontEntry::Pointer_t();
236 : }
237 :
238 9568 : sal_uInt32 FontTable::size()
239 : {
240 9568 : return m_pImpl->aFontEntries.size();
241 : }
242 :
243 0 : EmbeddedFontHandler::EmbeddedFontHandler( const OUString& _fontName, const char* _style )
244 : : LoggedProperties(dmapper_logger, "EmbeddedFontHandler")
245 : , fontName( _fontName )
246 0 : , style( _style )
247 : {
248 0 : }
249 :
250 0 : EmbeddedFontHandler::~EmbeddedFontHandler()
251 : {
252 0 : if( !inputStream.is())
253 : return;
254 0 : OUString fileUrl = TemporaryFonts::fileUrlForFont( fontName, style );
255 0 : osl::File file( fileUrl );
256 0 : switch( file.open( osl_File_OpenFlag_Create | osl_File_OpenFlag_Write ))
257 : {
258 : case osl::File::E_None:
259 0 : break; // ok
260 : case osl::File::E_EXIST:
261 : return; // Assume it's already been added correctly.
262 : default:
263 : SAL_WARN( "writerfilter", "Cannot open file for temporary font" );
264 0 : inputStream->closeInput();
265 : return;
266 : }
267 0 : if( !fontKey.isEmpty())
268 : { // unobfuscate
269 0 : uno::Sequence< sal_Int8 > buffer;
270 0 : int read = inputStream->readBytes( buffer, 32 );
271 0 : if( read < 32 )
272 : {
273 : SAL_WARN( "writerfilter", "Embedded font too small" );
274 0 : inputStream->closeInput();
275 0 : file.close();
276 0 : osl::File::remove( fileUrl );
277 : return;
278 : }
279 : // 1 3 5 7 10 2 5 7 20 2 5 7 9 1 3 5
280 : // {62E79491-959F-41E9-B76B-6B32631DEA5C}
281 : static const int pos[ 16 ] = { 35, 33, 31, 29, 27, 25, 22, 20, 17, 15, 12, 10, 7, 5, 3, 1 };
282 : char key[ 16 ];
283 0 : for( int i = 0;
284 : i < 16;
285 : ++i )
286 : {
287 0 : int v1 = fontKey[ pos[ i ]];
288 0 : int v2 = fontKey[ pos[ i ] + 1 ];
289 : assert(( v1 >= '0' && v1 <= '9' ) || ( v1 >= 'A' && v1 <= 'F' ));
290 : assert(( v2 >= '0' && v2 <= '9' ) || ( v2 >= 'A' && v2 <= 'F' ));
291 0 : int val = ( v1 - ( v1 <= '9' ? '0' : 'A' - 10 )) * 16 + v2 - ( v2 <= '9' ? '0' : 'A' - 10 );
292 0 : key[ i ] = val;
293 : }
294 0 : for( int i = 0;
295 : i < 16;
296 : ++i )
297 : {
298 0 : buffer[ i ] ^= key[ i ];
299 0 : buffer[ i + 16 ] ^= key[ i ];
300 : }
301 : sal_uInt64 dummy;
302 0 : file.write( buffer.getConstArray(), 32, dummy );
303 : }
304 0 : for(;;)
305 : {
306 0 : uno::Sequence< sal_Int8 > buffer;
307 0 : int read = inputStream->readBytes( buffer, 1024 );
308 : sal_uInt64 dummy;
309 0 : if( read > 0 )
310 0 : file.write( buffer.getConstArray(), read, dummy );
311 0 : if( read < 1024 )
312 : break;
313 0 : }
314 0 : inputStream->closeInput();
315 0 : if( file.close() != osl::File::E_None )
316 : {
317 : SAL_WARN( "writerfilter", "Writing temporary font file failed" );
318 0 : osl::File::remove( fileUrl );
319 : return;
320 : }
321 0 : TemporaryFonts::activateFont( fontName, fileUrl );
322 0 : }
323 :
324 0 : void EmbeddedFontHandler::lcl_attribute( Id name, Value& val )
325 : {
326 0 : OUString sValue = val.getString();
327 0 : switch( name )
328 : {
329 : case NS_ooxml::LN_CT_FontRel_fontKey:
330 0 : fontKey = sValue;
331 0 : break;
332 : case NS_ooxml::LN_CT_Rel_id:
333 0 : id = sValue;
334 0 : break;
335 : case NS_ooxml::LN_CT_FontRel_subsetted:
336 0 : break; // TODO? Let's just ignore this for now and hope
337 : // it doesn't break anything.
338 : case NS_ooxml::LN_inputstream: // the actual font data as stream
339 0 : val.getAny() >>= inputStream;
340 0 : break;
341 : default:
342 0 : break;
343 0 : }
344 0 : }
345 :
346 0 : void EmbeddedFontHandler::lcl_sprm( Sprm& )
347 : {
348 0 : }
349 :
350 :
351 : }//namespace dmapper
352 30 : }//namespace writerfilter
353 :
354 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|