[Libreoffice-commits] core.git: 3 commits - sw/source vcl/inc vcl/source xmloff/inc xmloff/source

Luboš Luňák l.lunak at suse.cz
Wed Mar 6 03:00:35 PST 2013


 sw/source/filter/ww8/docxattributeoutput.cxx |  109 ++++++++++++++-------------
 sw/source/filter/ww8/docxattributeoutput.hxx |    6 +
 vcl/inc/sft.hxx                              |    2 
 vcl/inc/vcl/embeddedfontshelper.hxx          |    4 
 vcl/source/fontsubset/sft.cxx                |    2 
 vcl/source/gdi/embeddedfontshelper.cxx       |   82 ++++++++++++++------
 xmloff/inc/xmloff/XMLFontAutoStylePool.hxx   |    2 
 xmloff/inc/xmloff/xmlimp.hxx                 |    7 +
 xmloff/source/core/xmlimp.cxx                |    8 +
 xmloff/source/style/XMLFontAutoStylePool.cxx |   12 +-
 xmloff/source/style/XMLFontStylesContext.cxx |   21 +----
 11 files changed, 153 insertions(+), 102 deletions(-)

New commits:
commit 3fbc15ce456d0112700e1832e860e06f01eb5c03
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Mar 5 19:35:42 2013 +0100

    remove the need to explicitly specify font style for font embedding
    
    The information can be read from the font data itself now, so
    this is a bit pointless. It wasn't entirely reliable anyway,
    as it is also necessary to ensure two font different font files
    don't overwrite each other.
    
    Change-Id: Ie17ab8118e1c08228beb7c749c5c8d6cf3426362

diff --git a/vcl/inc/vcl/embeddedfontshelper.hxx b/vcl/inc/vcl/embeddedfontshelper.hxx
index 96e8226..ac47786 100644
--- a/vcl/inc/vcl/embeddedfontshelper.hxx
+++ b/vcl/inc/vcl/embeddedfontshelper.hxx
@@ -33,9 +33,9 @@ public:
       Use activateTemporaryFont() to actually enable usage of the font.
 
       @param fontName name of the font (e.g. 'Times New Roman')
-      @param fontStyle font style, "" for regular, "bi" for bold italic, etc.
+      @param extra additional text to use for name (e.g. to distinguish regular from bold, italic,...), "?" for unique
     */
-    static OUString fileUrlForTemporaryFont( const OUString& fontName, const char* fontStyle );
+    static OUString fileUrlForTemporaryFont( const OUString& fontName, const char* extra );
 
     /**
       Adds the given font to the list of known fonts. The font is used only until application
diff --git a/vcl/source/gdi/embeddedfontshelper.cxx b/vcl/source/gdi/embeddedfontshelper.cxx
index ac18655..e53ed18 100644
--- a/vcl/source/gdi/embeddedfontshelper.cxx
+++ b/vcl/source/gdi/embeddedfontshelper.cxx
@@ -49,14 +49,18 @@ void EmbeddedFontsHelper::clearTemporaryFontFiles()
     clearDir( path + "fromsystem/" );
 }
 
-OUString EmbeddedFontsHelper::fileUrlForTemporaryFont( const OUString& fontName, const char* fontStyle )
+OUString EmbeddedFontsHelper::fileUrlForTemporaryFont( const OUString& fontName, const char* extra )
 {
     OUString path = "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap") "::UserInstallation}";
     rtl::Bootstrap::expandMacros( path );
     path += "/user/temp/embeddedfonts/fromdocs/";
     osl::Directory::createPath( path );
     OUString filename = fontName;
-    filename += OStringToOUString( fontStyle, RTL_TEXTENCODING_ASCII_US );
+    static int uniqueCounter = 0;
+    if( strcmp( extra, "?" ) == 0 )
+        filename += OUString::number( uniqueCounter++ );
+    else
+        filename += OStringToOUString( extra, RTL_TEXTENCODING_ASCII_US );
     filename += ".ttf"; // TODO is it always ttf?
     return path + filename;
 }
diff --git a/xmloff/inc/xmloff/XMLFontAutoStylePool.hxx b/xmloff/inc/xmloff/XMLFontAutoStylePool.hxx
index 1b16725..ad6a46d 100644
--- a/xmloff/inc/xmloff/XMLFontAutoStylePool.hxx
+++ b/xmloff/inc/xmloff/XMLFontAutoStylePool.hxx
@@ -39,7 +39,7 @@ class XMLOFF_DLLPUBLIC XMLFontAutoStylePool : public UniRefBase
     XMLFontAutoStylePoolNames_Impl m_aNames;
     bool tryToEmbedFonts;
 
-    OUString embedFontFile( const OUString& fontUrl, const char* style );
+    OUString embedFontFile( const OUString& fontUrl );
 
 protected:
 
diff --git a/xmloff/inc/xmloff/xmlimp.hxx b/xmloff/inc/xmloff/xmlimp.hxx
index 24f1f97..750f567 100644
--- a/xmloff/inc/xmloff/xmlimp.hxx
+++ b/xmloff/inc/xmloff/xmlimp.hxx
@@ -138,6 +138,7 @@ class XMLOFF_DLLPUBLIC SvXMLImport : public ::cppu::WeakImplHelper6<
 
     sal_uInt16  mnImportFlags;
     sal_uInt16  mnErrorFlags;
+    std::set< OUString > embeddedFontUrlsKnown;
 
 protected:
 
@@ -449,6 +450,12 @@ public:
      */
     bool isGraphicLoadOnDemandSupported() const;
 
+    /**
+        Returns true if the embedded font document URL has already been processed.
+        Otherwise returns false and consequent calls with the same URL will return true.
+    */
+    bool embeddedFontAlreadyProcessed( const OUString& url );
+
     virtual void NotifyEmbeddedFontRead() {};
 };
 
diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx
index 9962db5..2edbac4 100644
--- a/xmloff/source/core/xmlimp.cxx
+++ b/xmloff/source/core/xmlimp.cxx
@@ -1902,4 +1902,12 @@ SvXMLImport::AddRDFa(uno::Reference<rdf::XMetadatable> i_xObject,
         i_rAbout, i_rProperty, i_rContent, i_rDatatype);
 }
 
+bool SvXMLImport::embeddedFontAlreadyProcessed( const OUString& url )
+{
+    if( embeddedFontUrlsKnown.count( url ) != 0 )
+        return true;
+    embeddedFontUrlsKnown.insert( url );
+    return false;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/style/XMLFontAutoStylePool.cxx b/xmloff/source/style/XMLFontAutoStylePool.cxx
index e8c33aa..561814d 100644
--- a/xmloff/source/style/XMLFontAutoStylePool.cxx
+++ b/xmloff/source/style/XMLFontAutoStylePool.cxx
@@ -275,13 +275,11 @@ void XMLFontAutoStylePool::exportXML()
         if( tryToEmbedFonts )
         {
             std::vector< OUString > fileUrls;
-            static const char* const styles[] = { "", "b", "i", "bi" };
             static const FontWeight weight[] = { WEIGHT_NORMAL, WEIGHT_BOLD, WEIGHT_NORMAL, WEIGHT_BOLD };
             static const FontItalic italic[] = { ITALIC_NONE, ITALIC_NONE, ITALIC_NORMAL, ITALIC_NORMAL };
-            assert( SAL_N_ELEMENTS( styles ) == SAL_N_ELEMENTS( italic ));
-            assert( SAL_N_ELEMENTS( styles ) == SAL_N_ELEMENTS( weight ));
+            assert( SAL_N_ELEMENTS( weight ) == SAL_N_ELEMENTS( italic ));
             for( unsigned int j = 0;
-                 j < SAL_N_ELEMENTS( styles );
+                 j < SAL_N_ELEMENTS( weight );
                  ++j )
             {
                 OUString fileUrl = EmbeddedFontsHelper::fontFileUrl( pEntry->GetFamilyName(), pEntry->GetFamily(),
@@ -290,7 +288,7 @@ void XMLFontAutoStylePool::exportXML()
                     continue;
                 if( !fontFilesMap.count( fileUrl ))
                 {
-                    OUString docUrl = embedFontFile( fileUrl, styles[ j ] );
+                    OUString docUrl = embedFontFile( fileUrl );
                     if( !docUrl.isEmpty())
                         fontFilesMap[ fileUrl ] = docUrl;
                     else
@@ -319,7 +317,7 @@ void XMLFontAutoStylePool::exportXML()
     }
 }
 
-OUString XMLFontAutoStylePool::embedFontFile( const OUString& fileUrl, const char* style )
+OUString XMLFontAutoStylePool::embedFontFile( const OUString& fileUrl )
 {
     try
     {
@@ -333,7 +331,7 @@ OUString XMLFontAutoStylePool::embedFontFile( const OUString& fileUrl, const cha
         OUString name;
         do
         {
-            name = "font" + OUString::number( ++index ) + OUString::createFromAscii( style ) + ".ttf";
+            name = "font" + OUString::number( ++index ) + ".ttf";
         } while( storage->hasByName( name ) );
         uno::Reference< io::XOutputStream > outputStream;
         outputStream.set( storage->openStreamElement( name, ::embed::ElementModes::WRITE ), UNO_QUERY_THROW );
diff --git a/xmloff/source/style/XMLFontStylesContext.cxx b/xmloff/source/style/XMLFontStylesContext.cxx
index f269284..21b9cdb 100644
--- a/xmloff/source/style/XMLFontStylesContext.cxx
+++ b/xmloff/source/style/XMLFontStylesContext.cxx
@@ -238,18 +238,12 @@ void XMLFontStyleContextFontFaceUri::SetAttribute( sal_uInt16 nPrefixKey, const
 
 void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const OUString& url )
 {
+    if( GetImport().embeddedFontAlreadyProcessed( url ))
+    {
+        GetImport().NotifyEmbeddedFontRead();
+        return;
+    }
     OUString fontName = font.familyName();
-    const char* style = "";
-    // OOXML needs to know what kind of style the font is (regular, italic, bold, bold-italic),
-    // and the EmbeddedFontsHelper class is modelled after it. But ODF doesn't (need to) include
-    // this information, so try to guess from the name (LO encodes the style), otherwise
-    // go with regular and hope it works.
-    if( url.endsWithIgnoreAsciiCase( "bi.ttf" ))
-        style = "bi";
-    else if( url.endsWithIgnoreAsciiCase( "b.ttf" ))
-        style = "b";
-    else if( url.endsWithIgnoreAsciiCase( "i.ttf" ))
-        style = "i";
     // If there's any giveMeStreamForThisURL(), then it's well-hidden for me to find it.
     if( GetImport().IsPackageURL( url ))
     {
@@ -258,15 +252,12 @@ void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const OUString& url )
         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 );
-        OUString fileUrl = EmbeddedFontsHelper::fileUrlForTemporaryFont( fontName, style );
+        OUString fileUrl = EmbeddedFontsHelper::fileUrlForTemporaryFont( fontName, "?" );
         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:
-                GetImport().NotifyEmbeddedFontRead();
-                return; // Assume it's already been added correctly.
             default:
                 SAL_WARN( "xmloff", "Cannot open file for temporary font" );
                 return;
commit 595f954424a5b99f0a9d396b77d2d5b89b5ae664
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Mar 5 18:37:14 2013 +0100

    check whether font files allow being embedded in documents
    
    Change-Id: I95842a35a7c795cb0a3c1957f4062a373a9c4797

diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx
index f7cf58c..3cef61b 100644
--- a/vcl/inc/sft.hxx
+++ b/vcl/inc/sft.hxx
@@ -280,7 +280,7 @@ namespace vcl
  * @return value of SFErrCodes enum
  * @ingroup sft
  */
-    int VCL_DLLPUBLIC OpenTTFontBuffer(void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont** ttf); /*FOLD01*/
+    int VCL_DLLPUBLIC OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont** ttf); /*FOLD01*/
 #if !defined(WIN32)
 /**
  * TrueTypeFont constructor.
diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx
index e110c12..558c648 100644
--- a/vcl/source/fontsubset/sft.cxx
+++ b/vcl/source/fontsubset/sft.cxx
@@ -1566,7 +1566,7 @@ cleanup:
 }
 #endif
 
-int OpenTTFontBuffer(void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont** ttf)
+int OpenTTFontBuffer(const void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont** ttf)
 {
     allocTrueTypeFont( ttf );
     if( *ttf == NULL )
diff --git a/vcl/source/gdi/embeddedfontshelper.cxx b/vcl/source/gdi/embeddedfontshelper.cxx
index dfde14a..ac18655 100644
--- a/vcl/source/gdi/embeddedfontshelper.cxx
+++ b/vcl/source/gdi/embeddedfontshelper.cxx
@@ -11,6 +11,7 @@
 
 #include <osl/file.hxx>
 #include <rtl/bootstrap.hxx>
+#include <sft.hxx>
 #include <vcl/outdev.hxx>
 #include <vcl/svapp.hxx>
 
@@ -20,6 +21,8 @@
 #include <outfont.hxx>
 #include <salgdi.hxx>
 
+using namespace vcl;
+
 static void clearDir( const OUString& path )
     {
     osl::Directory dir( path );
@@ -65,6 +68,30 @@ void EmbeddedFontsHelper::activateFont( const OUString& fontName, const OUString
     pDevice->ImplUpdateAllFontData( true );
 }
 
+// Check if it's (legally) allowed to embed the font file into a document
+// (ttf has a flag allowing this). PhysicalFontFace::IsEmbeddable() appears
+// to have a different meaning (guessing from code, IsSubsettable() might
+// possibly mean it's ttf, while IsEmbeddable() might mean it's type1).
+// So just try to open the data as ttf and see.
+static bool isEmbeddingAllowed( const void* data, long size )
+{
+    TrueTypeFont* font;
+    if( OpenTTFontBuffer( data, size, 0 /*TODO*/, &font ) == SF_OK )
+    {
+        TTGlobalFontInfo info;
+        GetTTGlobalFontInfo( font, &info );
+        CloseTTFont( font );
+        // http://www.microsoft.com/typography/tt/ttf_spec/ttch02.doc
+        // font embedding is allowed if either
+        //   no restriction at all (bit 1 clear)
+        //   editting allowed (bit 1 set, bit 3 set)
+        // (preview&print is considered insufficent, as it would force the document to be read-only)
+        int copyright = info.typeFlags & TYPEFLAG_COPYRIGHT_MASK;
+        return ( copyright & 0x02 ) == 0 || ( copyright & 0x08 );
+    }
+    return true; // no known restriction
+}
+
 OUString EmbeddedFontsHelper::fontFileUrl( const OUString& familyName, FontFamily family, FontItalic italic,
     FontWeight weight, FontPitch pitch, rtl_TextEncoding )
 {
@@ -128,33 +155,36 @@ OUString EmbeddedFontsHelper::fontFileUrl( const OUString& familyName, FontFamil
         long size;
         if( const void* data = graphics->GetEmbedFontData( selected, unicodes, widths, info, &size ))
         {
-            osl::File file( url );
-            if( file.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create ) == osl::File::E_None )
+            if( isEmbeddingAllowed( data, size ))
             {
-                sal_uInt64 written = 0;
-                sal_uInt64 totalSize = size;
-                bool error = false;
-                while( written < totalSize && !error)
+                osl::File file( url );
+                if( file.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create ) == osl::File::E_None )
                 {
-                    sal_uInt64 nowWritten;
-                    switch( file.write( static_cast< const char* >( data ) + written, size - written, nowWritten ))
+                    sal_uInt64 written = 0;
+                    sal_uInt64 totalSize = size;
+                    bool error = false;
+                    while( written < totalSize && !error)
                     {
-                        case osl::File::E_None:
-                            written += nowWritten;
-                            break;
-                        case osl::File::E_AGAIN:
-                        case osl::File::E_INTR:
-                            break;
-                        default:
-                            error = true;
-                            break;
+                        sal_uInt64 nowWritten;
+                        switch( file.write( static_cast< const char* >( data ) + written, size - written, nowWritten ))
+                        {
+                            case osl::File::E_None:
+                                written += nowWritten;
+                                break;
+                            case osl::File::E_AGAIN:
+                            case osl::File::E_INTR:
+                                break;
+                            default:
+                                error = true;
+                                break;
+                        }
                     }
+                    file.close();
+                    if( error )
+                        osl::File::remove( url );
+                    else
+                        ok = true;
                 }
-                file.close();
-                if( error )
-                    osl::File::remove( url );
-                else
-                    ok = true;
             }
             graphics->FreeEmbedFontData( data, size );
         }
commit 25a5ee2aebebe9e175ad3b1c770bba9826fe4d48
Author: Luboš Luňák <l.lunak at suse.cz>
Date:   Tue Mar 5 17:04:31 2013 +0100

    do not embed the same font file twice into one .docx
    
    Change-Id: I6d38e83a7fa609d53f2f687ccfe289440d23e960

diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index b40b70d..e5366ee 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -3077,67 +3077,74 @@ void DocxAttributeOutput::EmbedFontStyle( const OUString& name, int tag, FontFam
     if( fontUrl.isEmpty())
         return;
     // TODO IDocumentSettingAccess::EMBED_SYSTEM_FONTS
-    osl::File file( fontUrl );
-    if( file.open( osl_File_OpenFlag_Read ) != osl::File::E_None )
-        return;
-    uno::Reference< com::sun::star::io::XOutputStream > xOutStream = m_rExport.GetFilter().openFragmentStream(
-        OUString( "word/fonts/font" ) + OUString::number(m_nextFontId) + ".odttf",
-        "application/vnd.openxmlformats-officedocument.obfuscatedFont" );
-    // Not much point in trying hard with the obfuscation key, whoever reads the spec can read the font anyway,
-    // so just alter the first and last part of the key.
-    char fontKeyStr[] = "{00014A78-CABC-4EF0-12AC-5CD89AEFDE00}";
-    sal_uInt8 fontKey[ 16 ] = { 0, 0xDE, 0xEF, 0x9A, 0xD8, 0x5C, 0xAC, 0x12, 0xF0, 0x4E,
-        0xBC, 0xCA, 0x78, 0x4A, 0x01, 0 };
-    fontKey[ 0 ] = fontKey[ 15 ] = m_nextFontId % 256;
-    fontKeyStr[ 1 ] = fontKeyStr[ 35 ] = toHexChar(( m_nextFontId % 256 ) / 16 );
-    fontKeyStr[ 2 ] = fontKeyStr[ 36 ] = toHexChar(( m_nextFontId % 256 ) % 16 );
-    char buffer[ 4096 ];
-    sal_uInt64 readSize;
-    file.read( buffer, 32, readSize );
-    if( readSize < 32 )
-    {
-        SAL_WARN( "sw.ww8", "Font file size too small (" << fontUrl << ")" );
-        xOutStream->closeOutput();
-        return;
-    }
-    for( int i = 0;
-         i < 16;
-         ++i )
+    if( !fontFilesMap.count( fontUrl ))
     {
-        buffer[ i ] ^= fontKey[ i ];
-        buffer[ i + 16 ] ^= fontKey[ i ];
-    }
-    xOutStream->writeBytes( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( buffer ), 32 ));
-    for(;;)
-    {
-        sal_Bool eof;
-        if( file.isEndOfFile( &eof ) != osl::File::E_None )
+        osl::File file( fontUrl );
+        if( file.open( osl_File_OpenFlag_Read ) != osl::File::E_None )
+            return;
+        uno::Reference< com::sun::star::io::XOutputStream > xOutStream = m_rExport.GetFilter().openFragmentStream(
+            OUString( "word/fonts/font" ) + OUString::number(m_nextFontId) + ".odttf",
+            "application/vnd.openxmlformats-officedocument.obfuscatedFont" );
+        // Not much point in trying hard with the obfuscation key, whoever reads the spec can read the font anyway,
+        // so just alter the first and last part of the key.
+        char fontKeyStr[] = "{00014A78-CABC-4EF0-12AC-5CD89AEFDE00}";
+        sal_uInt8 fontKey[ 16 ] = { 0, 0xDE, 0xEF, 0x9A, 0xD8, 0x5C, 0xAC, 0x12, 0xF0, 0x4E,
+            0xBC, 0xCA, 0x78, 0x4A, 0x01, 0 };
+        fontKey[ 0 ] = fontKey[ 15 ] = m_nextFontId % 256;
+        fontKeyStr[ 1 ] = fontKeyStr[ 35 ] = toHexChar(( m_nextFontId % 256 ) / 16 );
+        fontKeyStr[ 2 ] = fontKeyStr[ 36 ] = toHexChar(( m_nextFontId % 256 ) % 16 );
+        char buffer[ 4096 ];
+        sal_uInt64 readSize;
+        file.read( buffer, 32, readSize );
+        if( readSize < 32 )
         {
-            SAL_WARN( "sw.ww8", "Error reading font file " << fontUrl );
+            SAL_WARN( "sw.ww8", "Font file size too small (" << fontUrl << ")" );
             xOutStream->closeOutput();
             return;
         }
-        if( eof )
-            break;
-        if( file.read( buffer, 4096, readSize ) != osl::File::E_None )
+        for( int i = 0;
+             i < 16;
+             ++i )
         {
-            SAL_WARN( "sw.ww8", "Error reading font file " << fontUrl );
-            xOutStream->closeOutput();
-            return;
+            buffer[ i ] ^= fontKey[ i ];
+            buffer[ i + 16 ] ^= fontKey[ i ];
         }
-        if( readSize == 0 )
-            break;
-        xOutStream->writeBytes( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( buffer ), readSize ));
+        xOutStream->writeBytes( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( buffer ), 32 ));
+        for(;;)
+        {
+            sal_Bool eof;
+            if( file.isEndOfFile( &eof ) != osl::File::E_None )
+            {
+                SAL_WARN( "sw.ww8", "Error reading font file " << fontUrl );
+                xOutStream->closeOutput();
+                return;
+            }
+            if( eof )
+                break;
+            if( file.read( buffer, 4096, readSize ) != osl::File::E_None )
+            {
+                SAL_WARN( "sw.ww8", "Error reading font file " << fontUrl );
+                xOutStream->closeOutput();
+                return;
+            }
+            if( readSize == 0 )
+                break;
+            xOutStream->writeBytes( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( buffer ), readSize ));
+        }
+        xOutStream->closeOutput();
+        OString relId = OUStringToOString( GetExport().GetFilter().addRelation( m_pSerializer->getOutputStream(),
+            "http://schemas.openxmlformats.org/officeDocument/2006/relationships/font",
+            OUString( "fonts/font" ) + OUString::number( m_nextFontId ) + ".odttf" ), RTL_TEXTENCODING_UTF8 );
+        EmbeddedFontRef ref;
+        ref.relId = relId;
+        ref.fontKey = fontKeyStr;
+        fontFilesMap[ fontUrl ] = ref;
+        ++m_nextFontId;
     }
-    xOutStream->closeOutput();
-    OString relId = OUStringToOString( GetExport().GetFilter().addRelation( m_pSerializer->getOutputStream(),
-        "http://schemas.openxmlformats.org/officeDocument/2006/relationships/font",
-        OUString( "fonts/font" ) + OUString::number(m_nextFontId) + ".odttf" ), RTL_TEXTENCODING_UTF8 );
     m_pSerializer->singleElementNS( XML_w, tag,
-        FSNS( XML_r, XML_id ), relId.getStr(),
-        FSNS( XML_w, XML_fontKey ), fontKeyStr,
+        FSNS( XML_r, XML_id ), fontFilesMap[ fontUrl ].relId,
+        FSNS( XML_w, XML_fontKey ), fontFilesMap[ fontUrl ].fontKey,
         FSEND );
-    ++m_nextFontId;
 }
 
 void DocxAttributeOutput::NumberingDefinition( sal_uInt16 nId, const SwNumRule &rRule )
diff --git a/sw/source/filter/ww8/docxattributeoutput.hxx b/sw/source/filter/ww8/docxattributeoutput.hxx
index 37a6d4e..eb12e56 100644
--- a/sw/source/filter/ww8/docxattributeoutput.hxx
+++ b/sw/source/filter/ww8/docxattributeoutput.hxx
@@ -630,6 +630,12 @@ private:
     unsigned int m_postitFieldsMaxId;
     int m_anchorId;
     int m_nextFontId;
+    struct EmbeddedFontRef
+    {
+        OString relId;
+        OString fontKey;
+    };
+    std::map< OUString, EmbeddedFontRef > fontFilesMap; // font file url to data
 
     // Remember first cell (used for for default borders/margins) of each table
     std::vector<ww8::WW8TableNodeInfoInner::Pointer_t> tableFirstCells;


More information about the Libreoffice-commits mailing list