bug 527276 - part 4 - extend OTS to allow OpenType Layout tables to be preserved. r=jdaggett a=blocking2.0
authorJonathan Kew <jfkthame@gmail.com>
Thu, 07 Oct 2010 08:59:19 +0100
changeset 55085 4756e676e0fbf6fff95fd649bc3b3153604d3745
parent 55084 9120bc25cfb72c24c2c8cd2ba1cfeaaba7c413c4
child 55086 2fa4872fffeb9e2d21bf02d8bb7971a3ed2865e5
push idunknown
push userunknown
push dateunknown
reviewersjdaggett, blocking2
bugs527276
milestone2.0b8pre
bug 527276 - part 4 - extend OTS to allow OpenType Layout tables to be preserved. r=jdaggett a=blocking2.0
gfx/ots/include/opentype-sanitiser.h
gfx/ots/src/Makefile.in
gfx/ots/src/gdef.cc
gfx/ots/src/gdef.h
gfx/ots/src/gpos.cc
gfx/ots/src/gpos.h
gfx/ots/src/gsub.cc
gfx/ots/src/gsub.h
gfx/ots/src/ots.cc
gfx/ots/src/ots.h
--- 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_