From 9b14fa8f64d84866777e35acfe369503da188c7a Mon Sep 17 00:00:00 2001 From: Luboš Luňák Date: Mon, 3 Sep 2012 18:09:09 +0200 Subject: basic .docx read support for embedded fonts (w:embedRegular etc.) Change-Id: I9bbca2e348bd999e05f6d9e53f3bbcd2d6bb911a --- writerfilter/source/dmapper/FontTable.cxx | 127 ++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) (limited to 'writerfilter/source/dmapper/FontTable.cxx') diff --git a/writerfilter/source/dmapper/FontTable.cxx b/writerfilter/source/dmapper/FontTable.cxx index 203283d38038..9bb108b39300 100644 --- a/writerfilter/source/dmapper/FontTable.cxx +++ b/writerfilter/source/dmapper/FontTable.cxx @@ -21,8 +21,10 @@ #include #include #include +#include #include #include +#include #include "dmapperLoggers.hxx" @@ -133,6 +135,23 @@ void FontTable::lcl_sprm(Sprm& rSprm) case NS_ooxml::LN_CT_Font_charset: resolveSprm( rSprm ); break; + case NS_ooxml::LN_CT_Font_embedRegular: + case NS_ooxml::LN_CT_Font_embedBold: + case NS_ooxml::LN_CT_Font_embedItalic: + case NS_ooxml::LN_CT_Font_embedBoldItalic: + { + writerfilter::Reference< Properties >::Pointer_t pProperties = rSprm.getProps(); + if( pProperties.get( )) + { + EmbeddedFontHandler handler( m_pImpl->pCurrentEntry->sFontName, + nSprmId == NS_ooxml::LN_CT_Font_embedRegular ? "" + : nSprmId == NS_ooxml::LN_CT_Font_embedBold ? "b" + : nSprmId == NS_ooxml::LN_CT_Font_embedItalic ? "i" + : nSprmId == NS_ooxml::LN_CT_Font_embedBoldItalic ? "bi" : "?" ); + pProperties->resolve( handler ); + } + break; + } } } @@ -222,6 +241,114 @@ sal_uInt32 FontTable::size() return m_pImpl->aFontEntries.size(); } +EmbeddedFontHandler::EmbeddedFontHandler( const OUString& _fontName, const char* _style ) +: LoggedProperties(dmapper_logger, "EmbeddedFontHandler") +, fontName( _fontName ) +, style( _style ) +{ +} + +EmbeddedFontHandler::~EmbeddedFontHandler() +{ + if( !inputStream.is()) + return; + OUString fileUrl = psp::PrintFontManager::get().fileUrlForTemporaryFont( fontName, style ); + osl::File file( fileUrl ); + switch( file.open( osl_File_OpenFlag_Create | osl_File_OpenFlag_Write )) + { + case osl::File::E_None: + break; // ok + case osl::File::E_EXIST: + return; // Assume it's already been added correctly. + default: + SAL_WARN( "writerfilter", "Cannot open file for temporary font" ); + inputStream->closeInput(); + return; + } + if( !fontKey.isEmpty()) + { // unobfuscate + uno::Sequence< sal_Int8 > buffer; + int read = inputStream->readBytes( buffer, 32 ); + if( read < 32 ) + { + SAL_WARN( "writerfilter", "Embedded font too small" ); + inputStream->closeInput(); + file.close(); + osl::File::remove( fileUrl ); + return; + } + // 1 3 5 7 10 2 5 7 20 2 5 7 9 1 3 5 + // {62E79491-959F-41E9-B76B-6B32631DEA5C} + static const int pos[ 16 ] = { 35, 33, 31, 29, 27, 25, 22, 20, 17, 15, 12, 10, 7, 5, 3, 1 }; + char key[ 16 ]; + for( int i = 0; + i < 16; + ++i ) + { + int v1 = fontKey[ pos[ i ]]; + int v2 = fontKey[ pos[ i ] + 1 ]; + assert(( v1 >= '0' && v1 <= '9' ) || ( v1 >= 'A' && v1 <= 'F' )); + assert(( v2 >= '0' && v2 <= '9' ) || ( v2 >= 'A' && v2 <= 'F' )); + int val = ( v1 - ( v1 <= '9' ? '0' : 'A' - 10 )) * 16 + v2 - ( v2 <= '9' ? '0' : 'A' - 10 ); + key[ i ] = val; + } + for( int i = 0; + i < 16; + ++i ) + { + buffer[ i ] ^= key[ i ]; + buffer[ i + 16 ] ^= key[ i ]; + } + sal_uInt64 dummy; + file.write( buffer.getConstArray(), 32, dummy ); + } + for(;;) + { + uno::Sequence< sal_Int8 > buffer; + int read = inputStream->readBytes( buffer, 1024 ); + sal_uInt64 dummy; + if( read > 0 ) + file.write( buffer.getConstArray(), read, dummy ); + if( read < 1024 ) + break; + } + inputStream->closeInput(); + if( file.close() != osl::File::E_None ) + { + SAL_WARN( "writerfilter", "Writing temporary font file failed" ); + osl::File::remove( fileUrl ); + return; + } + psp::PrintFontManager::get().activateTemporaryFont( fontName, fileUrl ); +} + +void EmbeddedFontHandler::lcl_attribute( Id name, Value& val ) +{ + OUString sValue = val.getString(); + switch( name ) + { + case NS_ooxml::LN_CT_FontRel_fontKey: + fontKey = sValue; + break; + case NS_ooxml::LN_CT_Rel_id: + id = sValue; + break; + case NS_ooxml::LN_CT_FontRel_subsetted: + break; // TODO? Let's just ignore this for now and hope + // it doesn't break anything. + case NS_ooxml::LN_inputstream: // the actual font data as stream + val.getAny() >>= inputStream; + break; + default: + break; + } +} + +void EmbeddedFontHandler::lcl_sprm( Sprm& ) +{ +} + + }//namespace dmapper }//namespace writerfilter -- cgit