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.0
bugs527276
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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_