From 5861e88308dbec3a7672f653280264a24e821810 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Fri, 9 Dec 2011 22:32:29 +0000 Subject: [PATCH] bug 631479 (part 3) - allow graphite tables to be passed through OTS for downloadable fonts. r=jdaggett --- gfx/ots/include/opentype-sanitiser.h | 4 +- gfx/ots/src/Makefile.in | 1 + gfx/ots/src/graphite.cc | 181 +++++++++++++++++++++++++++ gfx/ots/src/graphite.h | 39 ++++++ gfx/ots/src/ots.cc | 16 ++- gfx/ots/src/ots.h | 11 +- gfx/thebes/gfxUserFontSet.cpp | 7 +- 7 files changed, 255 insertions(+), 4 deletions(-) create mode 100644 gfx/ots/src/graphite.cc create mode 100644 gfx/ots/src/graphite.h diff --git a/gfx/ots/include/opentype-sanitiser.h b/gfx/ots/include/opentype-sanitiser.h index 15108edee9d..ca7abfd7b58 100644 --- a/gfx/ots/include/opentype-sanitiser.h +++ b/gfx/ots/include/opentype-sanitiser.h @@ -181,8 +181,10 @@ class OTSStream { // partial output may have been written. // input: the OpenType file // length: the size, in bytes, of |input| +// preserve_graphite_tables: whether to preserve Graphite Layout tables // ----------------------------------------------------------------------------- -bool Process(OTSStream *output, const uint8_t *input, size_t length); +bool Process(OTSStream *output, const uint8_t *input, size_t length, + bool preserve_graphite_tables = false); // Force to disable debug output even when the library is compiled with // -DOTS_DEBUG. diff --git a/gfx/ots/src/Makefile.in b/gfx/ots/src/Makefile.in index ee40cb6a182..e196d83f255 100644 --- a/gfx/ots/src/Makefile.in +++ b/gfx/ots/src/Makefile.in @@ -69,6 +69,7 @@ CPPSRCS = \ gdef.cc \ gpos.cc \ gsub.cc \ + graphite.cc \ $(NULL) EXPORTS = \ diff --git a/gfx/ots/src/graphite.cc b/gfx/ots/src/graphite.cc new file mode 100644 index 00000000000..59a0aa9137a --- /dev/null +++ b/gfx/ots/src/graphite.cc @@ -0,0 +1,181 @@ +// Copyright (c) 2010 Mozilla Foundation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "graphite.h" + +// Support for preserving (NOT sanitizing) the Graphite tables + +namespace ots { + +// 'Silf' +bool ots_silf_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { + Buffer table(data, length); + + OpenTypeSILF *silf = new OpenTypeSILF; + file->silf = silf; + + if (!table.Skip(length)) { + return OTS_FAILURE(); + } + + silf->data = data; + silf->length = length; + return true; +} + +bool ots_silf_should_serialise(OpenTypeFile *file) { + return file->preserve_graphite && file->silf; +} + +bool ots_silf_serialise(OTSStream *out, OpenTypeFile *file) { + const OpenTypeSILF *silf = file->silf; + + if (!out->Write(silf->data, silf->length)) { + return OTS_FAILURE(); + } + + return true; +} + +void ots_silf_free(OpenTypeFile *file) { + delete file->silf; +} + +// 'Sill' +bool ots_sill_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { + Buffer table(data, length); + + OpenTypeSILL *sill = new OpenTypeSILL; + file->sill = sill; + + if (!table.Skip(length)) { + return OTS_FAILURE(); + } + + sill->data = data; + sill->length = length; + return true; +} + +bool ots_sill_should_serialise(OpenTypeFile *file) { + return file->preserve_graphite && file->sill; +} + +bool ots_sill_serialise(OTSStream *out, OpenTypeFile *file) { + const OpenTypeSILL *sill = file->sill; + + if (!out->Write(sill->data, sill->length)) { + return OTS_FAILURE(); + } + + return true; +} + +void ots_sill_free(OpenTypeFile *file) { + delete file->sill; +} + +// 'Gloc' +bool ots_gloc_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { + Buffer table(data, length); + + OpenTypeGLOC *gloc = new OpenTypeGLOC; + file->gloc = gloc; + + if (!table.Skip(length)) { + return OTS_FAILURE(); + } + + gloc->data = data; + gloc->length = length; + return true; +} + +bool ots_gloc_should_serialise(OpenTypeFile *file) { + return file->preserve_graphite && file->gloc; +} + +bool ots_gloc_serialise(OTSStream *out, OpenTypeFile *file) { + const OpenTypeGLOC *gloc = file->gloc; + + if (!out->Write(gloc->data, gloc->length)) { + return OTS_FAILURE(); + } + + return true; +} + +void ots_gloc_free(OpenTypeFile *file) { + delete file->gloc; +} + +// 'Glat' +bool ots_glat_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { + Buffer table(data, length); + + OpenTypeGLAT *glat = new OpenTypeGLAT; + file->glat = glat; + + if (!table.Skip(length)) { + return OTS_FAILURE(); + } + + glat->data = data; + glat->length = length; + return true; +} + +bool ots_glat_should_serialise(OpenTypeFile *file) { + return file->preserve_graphite && file->glat; +} + +bool ots_glat_serialise(OTSStream *out, OpenTypeFile *file) { + const OpenTypeGLAT *glat = file->glat; + + if (!out->Write(glat->data, glat->length)) { + return OTS_FAILURE(); + } + + return true; +} + +void ots_glat_free(OpenTypeFile *file) { + delete file->glat; +} + +// 'Feat' +bool ots_feat_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { + Buffer table(data, length); + + OpenTypeFEAT *feat = new OpenTypeFEAT; + file->feat = feat; + + if (!table.Skip(length)) { + return OTS_FAILURE(); + } + + feat->data = data; + feat->length = length; + return true; +} + +bool ots_feat_should_serialise(OpenTypeFile *file) { + return file->preserve_graphite && file->feat; +} + +bool ots_feat_serialise(OTSStream *out, OpenTypeFile *file) { + const OpenTypeFEAT *feat = file->feat; + + if (!out->Write(feat->data, feat->length)) { + return OTS_FAILURE(); + } + + return true; +} + +void ots_feat_free(OpenTypeFile *file) { + delete file->feat; +} + +} // namespace ots diff --git a/gfx/ots/src/graphite.h b/gfx/ots/src/graphite.h new file mode 100644 index 00000000000..7400311811d --- /dev/null +++ b/gfx/ots/src/graphite.h @@ -0,0 +1,39 @@ +// Copyright (c) 2010 Mozilla Foundation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef OTS_GRAPHITE_H_ +#define OTS_GRAPHITE_H_ + +#include "ots.h" + +namespace ots { + +struct OpenTypeSILF { + const uint8_t *data; + uint32_t length; +}; + +struct OpenTypeSILL { + const uint8_t *data; + uint32_t length; +}; + +struct OpenTypeGLOC { + const uint8_t *data; + uint32_t length; +}; + +struct OpenTypeGLAT { + const uint8_t *data; + uint32_t length; +}; + +struct OpenTypeFEAT { + const uint8_t *data; + uint32_t length; +}; + +} // namespace ots + +#endif // OTS_GRAPHITE_H_ diff --git a/gfx/ots/src/ots.cc b/gfx/ots/src/ots.cc index af5052a41b9..a934bbc7b60 100644 --- a/gfx/ots/src/ots.cc +++ b/gfx/ots/src/ots.cc @@ -143,6 +143,17 @@ const struct { ots::ots_vhea_should_serialise, ots::ots_vhea_free, false }, { Tag("vmtx"), ots::ots_vmtx_parse, ots::ots_vmtx_serialise, ots::ots_vmtx_should_serialise, ots::ots_vmtx_free, false }, + // SILGraphite layout tables - not actually parsed, just copied + { Tag("Silf"), ots::ots_silf_parse, ots::ots_silf_serialise, + ots::ots_silf_should_serialise, ots::ots_silf_free, false }, + { Tag("Sill"), ots::ots_sill_parse, ots::ots_sill_serialise, + ots::ots_sill_should_serialise, ots::ots_sill_free, false }, + { Tag("Gloc"), ots::ots_gloc_parse, ots::ots_gloc_serialise, + ots::ots_gloc_should_serialise, ots::ots_gloc_free, false }, + { Tag("Glat"), ots::ots_glat_parse, ots::ots_glat_serialise, + ots::ots_glat_should_serialise, ots::ots_glat_free, false }, + { Tag("Feat"), ots::ots_feat_parse, ots::ots_feat_serialise, + ots::ots_feat_should_serialise, ots::ots_feat_free, false }, // TODO(bashi): Support mort, base, and jstf tables. { 0, NULL, NULL, NULL, NULL, false }, }; @@ -586,12 +597,15 @@ void DisableDebugOutput() { g_debug_output = false; } -bool Process(OTSStream *output, const uint8_t *data, size_t length) { +bool Process(OTSStream *output, const uint8_t *data, size_t length, + bool preserveGraphite) { OpenTypeFile header; if (length < 4) { return OTS_FAILURE(); } + header.preserve_graphite = preserveGraphite; + bool result; if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F') { result = ProcessWOFF(&header, output, data, length); diff --git a/gfx/ots/src/ots.h b/gfx/ots/src/ots.h index c1741e2128a..11de9cb9a8d 100644 --- a/gfx/ots/src/ots.h +++ b/gfx/ots/src/ots.h @@ -183,7 +183,12 @@ class Buffer { F(vdmx, VDMX) \ F(vorg, VORG) \ F(vhea, VHEA) \ - F(vmtx, VMTX) + F(vmtx, VMTX) \ + F(silf, SILF) \ + F(sill, SILL) \ + F(glat, GLAT) \ + F(gloc, GLOC) \ + F(feat, FEAT) #define F(name, capname) struct OpenType##capname; FOR_EACH_TABLE_TYPE @@ -202,6 +207,10 @@ struct OpenTypeFile { uint16_t entry_selector; uint16_t range_shift; + // This is used to tell the relevant parsers whether to preserve the + // Graphite layout tables (currently _without_ any checking) + bool preserve_graphite; + #define F(name, capname) OpenType##capname *name; FOR_EACH_TABLE_TYPE #undef F diff --git a/gfx/thebes/gfxUserFontSet.cpp b/gfx/thebes/gfxUserFontSet.cpp index 8a66254b315..ddc70573823 100644 --- a/gfx/thebes/gfxUserFontSet.cpp +++ b/gfx/thebes/gfxUserFontSet.cpp @@ -363,7 +363,12 @@ SanitizeOpenTypeData(const PRUint8* aData, PRUint32 aLength, // limit output/expansion to 256MB ExpandingMemoryStream output(aIsCompressed ? aLength * 2 : aLength, 1024 * 1024 * 256); - if (ots::Process(&output, aData, aLength)) { +#ifdef MOZ_GRAPHITE +#define PRESERVE_GRAPHITE true +#else +#define PRESERVE_GRAPHITE false +#endif + if (ots::Process(&output, aData, aLength, PRESERVE_GRAPHITE)) { aSaneLength = output.Tell(); return static_cast(output.forget()); } else {