diff options
-rw-r--r-- | sw/source/filter/ww8/docxattributeoutput.cxx | 5 | ||||
-rw-r--r-- | vcl/inc/vcl/embeddedfontshelper.hxx | 18 | ||||
-rw-r--r-- | vcl/source/gdi/embeddedfontshelper.cxx | 28 | ||||
-rw-r--r-- | xmloff/source/style/XMLFontAutoStylePool.cxx | 5 |
4 files changed, 48 insertions, 8 deletions
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index e5366eeab1f3..1b8da731baad 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -3073,7 +3073,10 @@ static inline char toHexChar( int value ) void DocxAttributeOutput::EmbedFontStyle( const OUString& name, int tag, FontFamily family, FontItalic italic, FontWeight weight, FontPitch pitch, rtl_TextEncoding encoding ) { - OUString fontUrl = EmbeddedFontsHelper::fontFileUrl( name, family, italic, weight, pitch, encoding ); + // Embed font if at least viewing is allowed (in which case the opening app must check + // the font license rights too and open either read-only or not use the font for editing). + OUString fontUrl = EmbeddedFontsHelper::fontFileUrl( name, family, italic, weight, pitch, encoding, + EmbeddedFontsHelper::ViewingAllowed ); if( fontUrl.isEmpty()) return; // TODO IDocumentSettingAccess::EMBED_SYSTEM_FONTS diff --git a/vcl/inc/vcl/embeddedfontshelper.hxx b/vcl/inc/vcl/embeddedfontshelper.hxx index e5aead64c7bd..0b66e8ab157a 100644 --- a/vcl/inc/vcl/embeddedfontshelper.hxx +++ b/vcl/inc/vcl/embeddedfontshelper.hxx @@ -25,11 +25,18 @@ class VCL_DLLPUBLIC EmbeddedFontsHelper { public: + /// Specification of what kind of operation is allowed when embedding a font + enum FontRights + { + ViewingAllowed, ///< Font may be embedded for viewing the document (but not editing) + EditingAllowed ///< Font may be embedded for editing document (implies viewing) + }; + /** Returns URL for a font file for the given font, or empty if it does not exist. */ static OUString fontFileUrl( const OUString& familyName, FontFamily family, FontItalic italic, - FontWeight weight, FontPitch pitch, rtl_TextEncoding encoding ); + FontWeight weight, FontPitch pitch, rtl_TextEncoding encoding, FontRights rights ); /** Reads a font from the input stream, saves it to a temporary font file and activates the font. @@ -62,6 +69,15 @@ public: static void activateFont( const OUString& fontName, const OUString& fileUrl ); /** + Returns if the restrictions specified in the font (if present) allow embedding + the font for a particular purpose. + @param data font data + @param size size of the font data + @param rights type of operation to be allowed for the font + */ + static bool sufficientFontRights( const void* data, long size, FontRights rights ); + + /** Removes all temporary fonts in the path used by fileUrlForTemporaryFont(). @internal */ diff --git a/vcl/source/gdi/embeddedfontshelper.cxx b/vcl/source/gdi/embeddedfontshelper.cxx index 691e434f0cc7..eedab37098aa 100644 --- a/vcl/source/gdi/embeddedfontshelper.cxx +++ b/vcl/source/gdi/embeddedfontshelper.cxx @@ -66,6 +66,8 @@ bool EmbeddedFontsHelper::addEmbeddedFont( uno::Reference< io::XInputStream > st return false; } size_t keyPos = 0; + std::vector< char > fontData; + fontData.reserve( 1000000 ); for(;;) { uno::Sequence< sal_Int8 > buffer; @@ -84,6 +86,7 @@ bool EmbeddedFontsHelper::addEmbeddedFont( uno::Reference< io::XInputStream > st writtenTotal += written; } } + fontData.insert( fontData.end(), buffer.getConstArray(), buffer.getConstArray() + read ); if( read <= 0 ) break; } @@ -93,6 +96,15 @@ bool EmbeddedFontsHelper::addEmbeddedFont( uno::Reference< io::XInputStream > st osl::File::remove( fileUrl ); return false; } + if( !sufficientFontRights( &fontData.front(), fontData.size(), EditingAllowed )) + { + // It would be actually better to open the document in read-only mode in this case, + // warn the user about this, and provide a button to drop the font(s) in order + // to switch to editing. + SAL_INFO( "vcl.fonts", "Ignoring embedded font that is not usable for editing" ); + osl::File::remove( fileUrl ); + return false; + } EmbeddedFontsHelper::activateFont( fontName, fileUrl ); return true; } @@ -125,7 +137,7 @@ void EmbeddedFontsHelper::activateFont( const OUString& fontName, const OUString // 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 ) +bool EmbeddedFontsHelper::sufficientFontRights( const void* data, long size, FontRights rights ) { TrueTypeFont* font; if( OpenTTFontBuffer( data, size, 0 /*TODO*/, &font ) == SF_OK ) @@ -136,16 +148,22 @@ static bool isEmbeddingAllowed( const void* data, long size ) // http://www.microsoft.com/typography/tt/ttf_spec/ttch02.doc // font embedding is allowed if either // no restriction at all (bit 1 clear) + // viewing allowed (bit 1 set, bit 2 set) // 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 ); + switch( rights ) + { + case ViewingAllowed: + return ( copyright & 0x02 ) == 0 || ( copyright & 0x04 ) || ( copyright & 0x08 ); + case EditingAllowed: + 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 ) + FontWeight weight, FontPitch pitch, rtl_TextEncoding, FontRights rights ) { OUString path = "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap") "::UserInstallation}"; rtl::Bootstrap::expandMacros( path ); @@ -207,7 +225,7 @@ OUString EmbeddedFontsHelper::fontFileUrl( const OUString& familyName, FontFamil long size; if( const void* data = graphics->GetEmbedFontData( selected, unicodes, widths, info, &size )) { - if( isEmbeddingAllowed( data, size )) + if( sufficientFontRights( data, size, rights )) { osl::File file( url ); if( file.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create ) == osl::File::E_None ) diff --git a/xmloff/source/style/XMLFontAutoStylePool.cxx b/xmloff/source/style/XMLFontAutoStylePool.cxx index 561814d32c18..8f603ab0419a 100644 --- a/xmloff/source/style/XMLFontAutoStylePool.cxx +++ b/xmloff/source/style/XMLFontAutoStylePool.cxx @@ -282,8 +282,11 @@ void XMLFontAutoStylePool::exportXML() j < SAL_N_ELEMENTS( weight ); ++j ) { + // Embed font if at least viewing is allowed (in which case the opening app must check + // the font license rights too and open either read-only or not use the font for editing). OUString fileUrl = EmbeddedFontsHelper::fontFileUrl( pEntry->GetFamilyName(), pEntry->GetFamily(), - italic[ j ], weight[ j ], pEntry->GetPitch(), pEntry->GetEncoding()); + italic[ j ], weight[ j ], pEntry->GetPitch(), pEntry->GetEncoding(), + EmbeddedFontsHelper::ViewingAllowed ); if( fileUrl.isEmpty()) continue; if( !fontFilesMap.count( fileUrl )) |