[Libreoffice-commits] core.git: include/vcl include/xmloff vcl/Library_vcl.mk vcl/source xmloff/source
Brennan Vincent
brennanv at email.arizona.edu
Wed Nov 13 06:38:16 PST 2013
include/vcl/embeddedfontshelper.hxx | 5 -
include/xmloff/xmltoken.hxx | 1
vcl/Library_vcl.mk | 1
vcl/source/gdi/embeddedfontshelper.cxx | 63 ++++++++++++++++++--
vcl/source/gdi/pdfwriter_impl.cxx | 6 +
xmloff/source/core/xmltoken.cxx | 1
xmloff/source/style/XMLFontStylesContext.cxx | 67 +++++++++++++++++++++-
xmloff/source/style/XMLFontStylesContext_impl.hxx | 33 ++++++++++
8 files changed, 165 insertions(+), 12 deletions(-)
New commits:
commit 5ce50b8d171c9d86d2175dd35b1e7ef23255e895
Author: Brennan Vincent <brennanv at email.arizona.edu>
Date: Sat Oct 5 16:50:24 2013 -0700
Respect svg:font-face-format element.
Call libeot to parse font if value "embedded-opentype" is found.
Change-Id: I03a072fd4db47d151a3934e959ad17c1e24fcf09
Reviewed-on: https://gerrit.libreoffice.org/6144
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
diff --git a/include/vcl/embeddedfontshelper.hxx b/include/vcl/embeddedfontshelper.hxx
index 2250aa3..b02431e 100644
--- a/include/vcl/embeddedfontshelper.hxx
+++ b/include/vcl/embeddedfontshelper.hxx
@@ -44,10 +44,11 @@ public:
@param fontName name of the font (e.g. 'Times New Roman')
@param extra additional text to use for name (e.g. to distinguish regular from bold, italic,...), "?" for unique
@param key key to xor the data with, from the start until the key's length (not repeated)
+ @param eot whether the data is compressed in Embedded OpenType format
*/
static bool addEmbeddedFont( com::sun::star::uno::Reference< com::sun::star::io::XInputStream > stream,
const OUString& fontName, const char* extra,
- std::vector< unsigned char > key = std::vector< unsigned char >());
+ std::vector< unsigned char > key = std::vector< unsigned char >(), bool eot = false);
/**
Returns an URL for a file where to store contents of a given temporary font.
@@ -75,7 +76,7 @@ public:
@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 );
+ static bool sufficientTTFRights( const void* data, long size, FontRights rights );
/**
Removes all temporary fonts in the path used by fileUrlForTemporaryFont().
diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 33f2bee..bb585c6 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -2482,6 +2482,7 @@ namespace xmloff { namespace token {
XML_FONT_FACE,
XML_FONT_FACE_SRC,
XML_FONT_FACE_URI,
+ XML_FONT_FACE_FORMAT,
XML_FONT_ADORNMENTS,
XML_INCH,
XML_SPACE_AFTER,
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index fd24589..38cf55a 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -58,6 +58,7 @@ $(eval $(call gb_Library_use_custom_headers,vcl,\
$(eval $(call gb_Library_use_externals,vcl,\
jpeg \
nss3 \
+ libeot \
))
$(eval $(call gb_Library_use_libraries,vcl,\
diff --git a/vcl/source/gdi/embeddedfontshelper.cxx b/vcl/source/gdi/embeddedfontshelper.cxx
index 3460f78..c3101df 100644
--- a/vcl/source/gdi/embeddedfontshelper.cxx
+++ b/vcl/source/gdi/embeddedfontshelper.cxx
@@ -18,16 +18,29 @@
#include <vcl/svapp.hxx>
#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
#include <fontsubset.hxx>
#include <outdev.h>
#include <outfont.hxx>
#include <salgdi.hxx>
+#include <config_eot.h>
+
+#if ENABLE_EOT
+extern "C"
+{
+namespace libeot
+{
+#include <libeot.h>
+} // namespace libeot
+} // extern "C"
+#endif
+
using namespace com::sun::star;
using namespace vcl;
static void clearDir( const OUString& path )
- {
+{
osl::Directory dir( path );
if( dir.reset() == osl::Directory::E_None )
{
@@ -53,7 +66,7 @@ void EmbeddedFontsHelper::clearTemporaryFontFiles()
}
bool EmbeddedFontsHelper::addEmbeddedFont( uno::Reference< io::XInputStream > stream, const OUString& fontName,
- const char* extra, std::vector< unsigned char > key )
+ const char* extra, std::vector< unsigned char > key, bool eot )
{
OUString fileUrl = EmbeddedFontsHelper::fileUrlForTemporaryFont( fontName, extra );
osl::File file( fileUrl );
@@ -78,7 +91,8 @@ bool EmbeddedFontsHelper::addEmbeddedFont( uno::Reference< io::XInputStream > st
pos < read && keyPos < key.size();
++pos )
buffer[ pos ] ^= key[ keyPos++ ];
- if( read > 0 )
+ // if eot, don't write the file out yet, since we need to unpack it first.
+ if( !eot && read > 0 )
{
sal_uInt64 writtenTotal = 0;
while( writtenTotal < read )
@@ -92,13 +106,50 @@ bool EmbeddedFontsHelper::addEmbeddedFont( uno::Reference< io::XInputStream > st
if( read <= 0 )
break;
}
+ bool sufficientFontRights;
+#if ENABLE_EOT
+ if( eot )
+ {
+ unsigned uncompressedFontSize = 0;
+ unsigned char *nakedPointerToUncompressedFont = NULL;
+ libeot::EOTMetadata eotMetadata;
+ libeot::EOTError uncompressError =
+ libeot::eot2ttf_buffer( (const unsigned char *)&fontData[0], fontData.size(), &eotMetadata, &nakedPointerToUncompressedFont, &uncompressedFontSize ):
+ boost::shared_ptr<unsigned char> uncompressedFont( nakedPointerToUncompressedFont, libeot::freeEOTBuffer );
+ if( uncompressError != libeot::EOT_SUCCESS )
+ {
+ SAL_WARN( "vcl.fonts", "Failed to uncompress font" );
+ osl::File::remove( fileUrl );
+ return false;
+ }
+ sal_uInt64 writtenTotal = 0;
+ while( writtenTotal < uncompressedFontSize )
+ {
+ sal_uInt64 written;
+ if( file.write( uncompressedFont.get() + writtenTotal, uncompressedFontSize - writtenTotal, written ) != osl::File::E_None )
+ {
+ SAL_WARN( "vcl.fonts", "Error writing temporary font file" );
+ osl::File::remove( fileUrl );
+ return false;
+ }
+ writtenTotal += written;
+ }
+ sufficientFontRights = libeot::canLegallyEdit( eotMetadata );
+ libeot::EOTfreeMetadata( &eotMetadata );
+ }
+#endif
+
if( file.close() != osl::File::E_None )
{
SAL_WARN( "vcl.fonts", "Writing temporary font file failed" );
osl::File::remove( fileUrl );
return false;
}
- if( !sufficientFontRights( &fontData.front(), fontData.size(), EditingAllowed ))
+ if( !eot )
+ {
+ sufficientFontRights = sufficientTTFRights( &fontData.front(), fontData.size(), EditingAllowed );
+ }
+ if( sufficientFontRights )
{
// 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
@@ -139,7 +190,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.
-bool EmbeddedFontsHelper::sufficientFontRights( const void* data, long size, FontRights rights )
+bool EmbeddedFontsHelper::sufficientTTFRights( const void* data, long size, FontRights rights )
{
TrueTypeFont* font;
if( OpenTTFontBuffer( data, size, 0 /*TODO*/, &font ) == SF_OK )
@@ -225,7 +276,7 @@ OUString EmbeddedFontsHelper::fontFileUrl( const OUString& familyName, FontFamil
long size;
if( const void* data = graphics->GetEmbedFontData( selected, unicodes, widths, info, &size ))
{
- if( sufficientFontRights( data, size, rights ))
+ if( sufficientTTFRights( 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/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index f6e823a..b6001cb 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -85,6 +85,12 @@
#include "cmst.h"
#endif
+#include <config_eot.h>
+
+#if ENABLE_EOT
+#include "libeot.h"
+#endif
+
using namespace vcl;
#if (OSL_DEBUG_LEVEL < 3)
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index 4051104..dedb2b4 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -2486,6 +2486,7 @@ namespace xmloff { namespace token {
TOKEN( "font-face", XML_FONT_FACE ),
TOKEN( "font-face-src", XML_FONT_FACE_SRC ),
TOKEN( "font-face-uri", XML_FONT_FACE_URI ),
+ TOKEN( "font-face-format", XML_FONT_FACE_FORMAT ),
TOKEN( "font-adornments", XML_FONT_ADORNMENTS ),
TOKEN( "inch", XML_INCH ),
TOKEN( "space-after", XML_SPACE_AFTER ),
diff --git a/xmloff/source/style/XMLFontStylesContext.cxx b/xmloff/source/style/XMLFontStylesContext.cxx
index 33f998a..29f4808 100644
--- a/xmloff/source/style/XMLFontStylesContext.cxx
+++ b/xmloff/source/style/XMLFontStylesContext.cxx
@@ -190,6 +190,26 @@ OUString XMLFontStyleContextFontFace::familyName() const
return ret;
}
+TYPEINIT1( XMLFontStyleContextFontFaceFormat, SvXMLStyleContext );
+
+XMLFontStyleContextFontFaceFormat::XMLFontStyleContextFontFaceFormat( SvXMLImport& rImport,
+ sal_uInt16 nPrfx, const OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > &xAttrList,
+ XMLFontStyleContextFontFaceUri& _uri )
+ : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList)
+ , uri(_uri)
+{
+}
+
+void XMLFontStyleContextFontFaceFormat::SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
+ const OUString& rValue )
+{
+ if( nPrefixKey == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_STRING ))
+ uri.SetFormat(rValue);
+ else
+ SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
+}
TYPEINIT1( XMLFontStyleContextFontFaceSrc, SvXMLImportContext );
@@ -224,16 +244,57 @@ XMLFontStyleContextFontFaceUri::XMLFontStyleContextFontFaceUri( SvXMLImport& rIm
{
}
+SvXMLImportContext * XMLFontStyleContextFontFaceUri::CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList )
+{
+ if( nPrefix == XML_NAMESPACE_SVG && IsXMLToken( rLocalName, XML_FONT_FACE_FORMAT ))
+ return new XMLFontStyleContextFontFaceFormat( GetImport(), nPrefix, rLocalName, xAttrList, *this );
+ return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList );
+}
+
void XMLFontStyleContextFontFaceUri::SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
const OUString& rValue )
{
if( nPrefixKey == XML_NAMESPACE_XLINK && IsXMLToken( rLocalName, XML_HREF ))
- handleEmbeddedFont( rValue );
+ linkPath = rValue;
else
SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
}
-void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const OUString& url )
+void XMLFontStyleContextFontFaceUri::SetFormat( const OUString& rFormat )
+{
+ format = rFormat;
+}
+void XMLFontStyleContextFontFaceUri::EndElement()
+{
+ if( linkPath.getLength() == 0 )
+ {
+ SAL_WARN( "xmloff", "svg:font-face-uri tag with no link; ignoring." );
+ return;
+ }
+ bool eot;
+ // Assume by default that the font is not compressed.
+ if( format.getLength() == 0
+ || format.equalsAscii( OPENTYPE_FORMAT )
+ || format.equalsAscii( TRUETYPE_FORMAT ))
+ {
+ eot = false;
+ }
+ else if( format.equalsAscii( EOT_FORMAT ))
+ {
+ eot = true;
+ }
+ else
+ {
+ SAL_WARN( "xmloff", "Unknown format of embedded font; assuming TTF." );
+ eot = false;
+ }
+ handleEmbeddedFont( linkPath, eot );
+}
+
+void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const OUString& url, bool eot )
{
if( GetImport().embeddedFontAlreadyProcessed( url ))
{
@@ -252,7 +313,7 @@ void XMLFontStyleContextFontFaceUri::handleEmbeddedFont( const OUString& url )
uno::Reference< io::XInputStream > inputStream;
inputStream.set( storage->openStreamElement( url.copy( url.indexOf( '/' ) + 1 ), ::embed::ElementModes::READ ),
UNO_QUERY_THROW );
- if( EmbeddedFontsHelper::addEmbeddedFont( inputStream, fontName, "?" ))
+ if( EmbeddedFontsHelper::addEmbeddedFont( inputStream, fontName, "?", std::vector< unsigned char >(), eot ))
GetImport().NotifyEmbeddedFontRead();
inputStream->closeInput();
}
diff --git a/xmloff/source/style/XMLFontStylesContext_impl.hxx b/xmloff/source/style/XMLFontStylesContext_impl.hxx
index 81e1b7a..6ad621f 100644
--- a/xmloff/source/style/XMLFontStylesContext_impl.hxx
+++ b/xmloff/source/style/XMLFontStylesContext_impl.hxx
@@ -88,8 +88,16 @@ public:
/// Handles <style:font-face-uri>
class XMLFontStyleContextFontFaceUri : public SvXMLStyleContext
{
+ // the CSS2 standard ( http://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#referencing )
+ // defines these format strings.
+ const char* OPENTYPE_FORMAT = "opentype";
+ const char* TRUETYPE_FORMAT = "truetype";
+ const char* EOT_FORMAT = "embedded-opentype";
+
const XMLFontStyleContextFontFace& font;
- void handleEmbeddedFont( const OUString& url );
+ OUString format;
+ OUString linkPath;
+ void handleEmbeddedFont( const OUString& url, bool eot );
public:
TYPEINFO();
@@ -102,6 +110,29 @@ public:
virtual void SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
const OUString& rValue );
+ void SetFormat( const OUString& rFormat );
+ void EndElement();
+ SvXMLImportContext * CreateChildContext(
+ sal_uInt16 nPrefix,
+ const OUString& rLocalName,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList > & xAttrList );
+};
+
+/// Handles <svg:font-face-format>
+class XMLFontStyleContextFontFaceFormat : public SvXMLStyleContext
+{
+ XMLFontStyleContextFontFaceUri& uri;
+public:
+ TYPEINFO();
+
+ XMLFontStyleContextFontFaceFormat( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ XMLFontStyleContextFontFaceUri& uri );
+
+ void SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
+ const OUString& rValue );
};
#endif
More information about the Libreoffice-commits
mailing list