summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@suse.cz>2013-03-07 19:45:49 +0100
committerLuboš Luňák <l.lunak@suse.cz>2013-03-08 13:35:27 +0100
commite2cd75f005dd5bf57336f39abd8820ecac0b048e (patch)
tree429e024b52781adc38817f4039c833b12d340cf4
parent8fcc60bee755b812489ef652ab2fa779babddeac (diff)
embed also view-only fonts, but do not use them
MSO embeds even fonts which allow only embedding for viewing the document but not editing it. So embed such fonts too, but do not actually use them from the document. What MSO does when such a font is not present locally when opening the document is switching to read-only mode, warning about this and providing a button for switching to editing mode by dumping the font(s). That should be done for LO too, but right now dropping view-only fonts is better than using them for editing. Change-Id: I19c28fadb091e6b21beaf4cbf8b47e3078256d1c
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx5
-rw-r--r--vcl/inc/vcl/embeddedfontshelper.hxx18
-rw-r--r--vcl/source/gdi/embeddedfontshelper.cxx28
-rw-r--r--xmloff/source/style/XMLFontAutoStylePool.cxx5
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 ))