bug 527276 - part 4 - extend OTS to allow OpenType Layout tables to be preserved. r=jdaggett a=blocking2.0
--- a/gfx/ots/include/opentype-sanitiser.h
+++ b/gfx/ots/include/opentype-sanitiser.h
@@ -166,18 +166,21 @@ class OTSStream {
// -----------------------------------------------------------------------------
// Process a given OpenType file and write out a sanitised version
// output: a pointer to an object implementing the OTSStream interface. The
// sanitisied output will be written to this. In the even of a failure,
// partial output may have been written.
// input: the OpenType file
// length: the size, in bytes, of |input|
+// preserve_otl_tables: whether to preserve OpenType Layout tables
+// (GDEF/GPOS/GSUB) without verification
// -----------------------------------------------------------------------------
-bool Process(OTSStream *output, const uint8_t *input, size_t length);
+bool Process(OTSStream *output, const uint8_t *input, size_t length,
+ bool preserve_otl_tables = false);
// Force to disable debug output even when the library is compiled with
// -DOTS_DEBUG.
void DisableDebugOutput();
} // namespace ots
#endif // OPENTYPE_SANITISER_H_
--- a/gfx/ots/src/Makefile.in
+++ b/gfx/ots/src/Makefile.in
@@ -61,16 +61,19 @@ CPPSRCS = \
maxp.cc \
name.cc \
os2.cc \
ots.cc \
post.cc \
prep.cc \
vdmx.cc \
vorg.cc \
+ gdef.cc \
+ gpos.cc \
+ gsub.cc \
$(NULL)
EXPORTS = \
../include/opentype-sanitiser.h \
../include/ots-memory-stream.h \
$(NULL)
LOCAL_INCLUDES += -I$(srcdir)
new file mode 100644
--- /dev/null
+++ b/gfx/ots/src/gdef.cc
@@ -0,0 +1,45 @@
+// 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 "gdef.h"
+
+// GDEF - Glyph Definition Table
+// http://www.microsoft.com/typography/otspec/gdef.htm
+
+namespace ots {
+
+bool ots_gdef_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
+ Buffer table(data, length);
+
+ OpenTypeGDEF *gdef = new OpenTypeGDEF;
+ file->gdef = gdef;
+
+ if (!table.Skip(length)) {
+ return OTS_FAILURE();
+ }
+
+ gdef->data = data;
+ gdef->length = length;
+ return true;
+}
+
+bool ots_gdef_should_serialise(OpenTypeFile *file) {
+ return file->preserve_otl && file->gdef;
+}
+
+bool ots_gdef_serialise(OTSStream *out, OpenTypeFile *file) {
+ const OpenTypeGDEF *gdef = file->gdef;
+
+ if (!out->Write(gdef->data, gdef->length)) {
+ return OTS_FAILURE();
+ }
+
+ return true;
+}
+
+void ots_gdef_free(OpenTypeFile *file) {
+ delete file->gdef;
+}
+
+} // namespace ots
new file mode 100644
--- /dev/null
+++ b/gfx/ots/src/gdef.h
@@ -0,0 +1,19 @@
+// 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_GDEF_H_
+#define OTS_GDEF_H_
+
+#include "ots.h"
+
+namespace ots {
+
+struct OpenTypeGDEF {
+ const uint8_t *data;
+ uint32_t length;
+};
+
+} // namespace ots
+
+#endif // OTS_GDEF_H_
new file mode 100644
--- /dev/null
+++ b/gfx/ots/src/gpos.cc
@@ -0,0 +1,45 @@
+// 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 "gpos.h"
+
+// GPOS - Glyph Positioning Table
+// http://www.microsoft.com/typography/otspec/gpos.htm
+
+namespace ots {
+
+bool ots_gpos_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
+ Buffer table(data, length);
+
+ OpenTypeGPOS *gpos = new OpenTypeGPOS;
+ file->gpos = gpos;
+
+ if (!table.Skip(length)) {
+ return OTS_FAILURE();
+ }
+
+ gpos->data = data;
+ gpos->length = length;
+ return true;
+}
+
+bool ots_gpos_should_serialise(OpenTypeFile *file) {
+ return file->preserve_otl && file->gpos;
+}
+
+bool ots_gpos_serialise(OTSStream *out, OpenTypeFile *file) {
+ const OpenTypeGPOS *gpos = file->gpos;
+
+ if (!out->Write(gpos->data, gpos->length)) {
+ return OTS_FAILURE();
+ }
+
+ return true;
+}
+
+void ots_gpos_free(OpenTypeFile *file) {
+ delete file->gpos;
+}
+
+} // namespace ots
new file mode 100644
--- /dev/null
+++ b/gfx/ots/src/gpos.h
@@ -0,0 +1,19 @@
+// 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_GPOS_H_
+#define OTS_GPOS_H_
+
+#include "ots.h"
+
+namespace ots {
+
+struct OpenTypeGPOS {
+ const uint8_t *data;
+ uint32_t length;
+};
+
+} // namespace ots
+
+#endif // OTS_GPOS_H_
new file mode 100644
--- /dev/null
+++ b/gfx/ots/src/gsub.cc
@@ -0,0 +1,45 @@
+// 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 "gsub.h"
+
+// GSUB - Glyph Substitution Table
+// http://www.microsoft.com/typography/otspec/gsub.htm
+
+namespace ots {
+
+bool ots_gsub_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
+ Buffer table(data, length);
+
+ OpenTypeGSUB *gsub = new OpenTypeGSUB;
+ file->gsub = gsub;
+
+ if (!table.Skip(length)) {
+ return OTS_FAILURE();
+ }
+
+ gsub->data = data;
+ gsub->length = length;
+ return true;
+}
+
+bool ots_gsub_should_serialise(OpenTypeFile *file) {
+ return file->preserve_otl && file->gsub;
+}
+
+bool ots_gsub_serialise(OTSStream *out, OpenTypeFile *file) {
+ const OpenTypeGSUB *gsub = file->gsub;
+
+ if (!out->Write(gsub->data, gsub->length)) {
+ return OTS_FAILURE();
+ }
+
+ return true;
+}
+
+void ots_gsub_free(OpenTypeFile *file) {
+ delete file->gsub;
+}
+
+} // namespace ots
new file mode 100644
--- /dev/null
+++ b/gfx/ots/src/gsub.h
@@ -0,0 +1,19 @@
+// 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_GSUB_H_
+#define OTS_GSUB_H_
+
+#include "ots.h"
+
+namespace ots {
+
+struct OpenTypeGSUB {
+ const uint8_t *data;
+ uint32_t length;
+};
+
+} // namespace ots
+
+#endif // OTS_GSUB_H_
--- a/gfx/ots/src/ots.cc
+++ b/gfx/ots/src/ots.cc
@@ -137,18 +137,24 @@ const struct {
{ Tag("prep"), ots::ots_prep_parse, ots::ots_prep_serialise,
ots::ots_prep_should_serialise, ots::ots_prep_free, false },
{ Tag("LTSH"), ots::ots_ltsh_parse, ots::ots_ltsh_serialise,
ots::ots_ltsh_should_serialise, ots::ots_ltsh_free, false },
{ Tag("VORG"), ots::ots_vorg_parse, ots::ots_vorg_serialise,
ots::ots_vorg_should_serialise, ots::ots_vorg_free, false },
{ Tag("kern"), ots::ots_kern_parse, ots::ots_kern_serialise,
ots::ots_kern_should_serialise, ots::ots_kern_free, false },
+ { Tag("GDEF"), ots::ots_gdef_parse, ots::ots_gdef_serialise,
+ ots::ots_gdef_should_serialise, ots::ots_gdef_free, false },
+ { Tag("GPOS"), ots::ots_gpos_parse, ots::ots_gpos_serialise,
+ ots::ots_gpos_should_serialise, ots::ots_gpos_free, false },
+ { Tag("GSUB"), ots::ots_gsub_parse, ots::ots_gsub_serialise,
+ ots::ots_gsub_should_serialise, ots::ots_gsub_free, false },
// TODO(yusukes): Support GDEF, GPOS, GSUB, mort, base, and jstf tables.
- { 0, NULL, NULL, NULL, NULL, false },
+ { 0, NULL, NULL, NULL, NULL, false }
};
bool IsValidVersionTag(uint32_t tag) {
return tag == Tag("\x00\x01\x00\x00") ||
// OpenType fonts with CFF data have 'OTTO' tag.
tag == Tag("OTTO") ||
// Older Mac fonts might have 'true' or 'typ1' tag.
tag == Tag("true") ||
@@ -576,22 +582,24 @@ bool ProcessGeneric(ots::OpenTypeFile *h
} // namespace
namespace ots {
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 preserveOTL) {
OpenTypeFile header;
if (length < 4) {
return OTS_FAILURE();
}
+ header.preserve_otl = preserveOTL;
+
bool result;
if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F') {
result = ProcessWOFF(&header, output, data, length);
} else {
result = ProcessTTF(&header, output, data, length);
}
for (unsigned i = 0; ; ++i) {
--- a/gfx/ots/src/ots.h
+++ b/gfx/ots/src/ots.h
@@ -172,17 +172,20 @@ class Buffer {
F(loca, LOCA) \
F(ltsh, LTSH) \
F(maxp, MAXP) \
F(name, NAME) \
F(os2, OS2) \
F(post, POST) \
F(prep, PREP) \
F(vdmx, VDMX) \
- F(vorg, VORG)
+ F(vorg, VORG) \
+ F(gdef, GDEF) \
+ F(gpos, GPOS) \
+ F(gsub, GSUB)
#define F(name, capname) struct OpenType##capname;
FOR_EACH_TABLE_TYPE
#undef F
struct OpenTypeFile {
OpenTypeFile() {
#define F(name, capname) name = NULL;
@@ -191,16 +194,20 @@ struct OpenTypeFile {
}
uint32_t version;
uint16_t num_tables;
uint16_t search_range;
uint16_t entry_selector;
uint16_t range_shift;
+ // This is used to tell the GDEF/GPOS/GSUB parsers whether to preserve the
+ // OpenType Layout tables (**without** any checking).
+ bool preserve_otl;
+
#define F(name, capname) OpenType##capname *name;
FOR_EACH_TABLE_TYPE
#undef F
};
} // namespace ots
#endif // OTS_H_