summaryrefslogtreecommitdiff
path: root/writerfilter/source/dmapper/FontTable.cxx
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2012-09-03 18:09:09 +0200
committerLuboš Luňák <l.lunak@suse.cz>2012-09-06 17:35:47 +0200
commit9b14fa8f64d84866777e35acfe369503da188c7a (patch)
tree51084ae71ad804bb5e904424d39cbb0a96beb670 /writerfilter/source/dmapper/FontTable.cxx
parentb7e56788135c1c6179cbc5387e41a66a85a7460b (diff)
basic .docx read support for embedded fonts (w:embedRegular etc.)
Change-Id: I9bbca2e348bd999e05f6d9e53f3bbcd2d6bb911a
Diffstat (limited to 'writerfilter/source/dmapper/FontTable.cxx')
-rw-r--r--writerfilter/source/dmapper/FontTable.cxx127
1 files changed, 127 insertions, 0 deletions
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 <doctok/resourceids.hxx>
#include <ooxml/resourceids.hxx>
#include <vector>
+#include <osl/file.hxx>
#include <stdio.h>
#include <rtl/tencinfo.h>
+#include <vcl/fontmanager.hxx>
#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