Bug 1020927 - Part 2: Update OTS to bf4afceb8b441f3a219dd7cfea5613c18183836c so that we fix the compile warnings. r=jfkthame
authorFrédéric Wang <fred.wang@free.fr>
Thu, 05 Jun 2014 11:09:00 -0400
changeset 187808 fc4e74df29438cf96611fff1a86da8c182f36d4a
parent 187807 192b91676f1d2caadc40262907c43ce9f9ee9b5b
child 187809 86f5521e907f82df1fef53f72f8cfb90063d8932
push idunknown
push userunknown
push dateunknown
reviewersjfkthame
bugs1020927
milestone32.0a1
Bug 1020927 - Part 2: Update OTS to bf4afceb8b441f3a219dd7cfea5613c18183836c so that we fix the compile warnings. r=jfkthame
gfx/ots/README.mozilla
gfx/ots/include/opentype-sanitiser.h
gfx/ots/ots-visibility.patch
gfx/ots/src/cff.cc
gfx/ots/src/cmap.cc
gfx/ots/src/cvt.cc
gfx/ots/src/fpgm.cc
gfx/ots/src/gasp.cc
gfx/ots/src/gdef.cc
gfx/ots/src/glyf.cc
gfx/ots/src/gpos.cc
gfx/ots/src/gsub.cc
gfx/ots/src/hdmx.cc
gfx/ots/src/head.cc
gfx/ots/src/hhea.cc
gfx/ots/src/hmtx.cc
gfx/ots/src/kern.cc
gfx/ots/src/layout.cc
gfx/ots/src/loca.cc
gfx/ots/src/ltsh.cc
gfx/ots/src/math.cc
gfx/ots/src/maxp.cc
gfx/ots/src/metrics.cc
gfx/ots/src/name.cc
gfx/ots/src/os2.cc
gfx/ots/src/ots.cc
gfx/ots/src/ots.h
gfx/ots/src/post.cc
gfx/ots/src/prep.cc
gfx/ots/src/vdmx.cc
gfx/ots/src/vhea.cc
gfx/ots/src/vmtx.cc
gfx/ots/src/vorg.cc
gfx/thebes/gfxUserFontSet.cpp
--- a/gfx/ots/README.mozilla
+++ b/gfx/ots/README.mozilla
@@ -1,11 +1,11 @@
 This is the Sanitiser for OpenType project, from http://code.google.com/p/ots/.
 
 Our reference repository is https://github.com/khaledhosny/ots/.
 
-Current revision: 06372729b075619ec94aa2e075afcabc894b6069
+Current revision: bf4afceb8b441f3a219dd7cfea5613c18183836c
 
 Upstream files included: LICENSE, src/, include/
 
 Additional files: README.mozilla, src/moz.build
 
 Additional patch: ots-visibility.patch (bug 711079).
--- a/gfx/ots/include/opentype-sanitiser.h
+++ b/gfx/ots/include/opentype-sanitiser.h
@@ -194,55 +194,78 @@ class OTSStream {
   }
 
  protected:
   uint32_t chksum_;
   uint8_t chksum_buffer_[4];
   unsigned chksum_buffer_offset_;
 };
 
-// -----------------------------------------------------------------------------
-// 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|
-// -----------------------------------------------------------------------------
-bool OTS_API Process(OTSStream *output, const uint8_t *input, size_t length);
-
 // Signature of the function to be provided by the client in order to report errors.
 // The return type is a boolean so that it can be used within an expression,
 // but the actual value is ignored. (Suggested convention is to always return 'false'.)
 #ifdef __GCC__
 #define MSGFUNC_FMT_ATTR __attribute__((format(printf, 2, 3)))
 #else
 #define MSGFUNC_FMT_ATTR
 #endif
 typedef bool (*MessageFunc)(void *user_data, const char *format, ...)  MSGFUNC_FMT_ATTR;
 
-// Set a callback function that will be called when OTS is reporting an error.
-void OTS_API SetMessageCallback(MessageFunc func, void *user_data);
-
 enum TableAction {
   TABLE_ACTION_DEFAULT,  // Use OTS's default action for that table
   TABLE_ACTION_SANITIZE, // Sanitize the table, potentially droping it
   TABLE_ACTION_PASSTHRU, // Serialize the table unchanged
   TABLE_ACTION_DROP      // Drop the table
 };
 
 // Signature of the function to be provided by the client to decide what action
 // to do for a given table.
 //   tag: table tag as an integer in big-endian byte order, independent of platform endianness
 //   user_data: user defined data that are passed to SetTableActionCallback()
 typedef TableAction (*TableActionFunc)(uint32_t tag, void *user_data);
 
-// Set a callback function that will be called when OTS needs to decide what to
-// do for a font table.
-void OTS_API SetTableActionCallback(TableActionFunc func, void *user_data);
+class OTS_API OTSContext {
+  public:
+    OTSContext()
+        : message_func(0),
+          message_user_data(0),
+          table_action_func(0),
+          table_action_user_data(0)
+        {}
+
+    ~OTSContext() {}
+
+    // 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|
+    //   context: optional context that holds various OTS settings like user callbacks
+    bool Process(OTSStream *output, const uint8_t *input, size_t length);
+
+    // Set a callback function that will be called when OTS is reporting an error.
+    void SetMessageCallback(MessageFunc func, void *user_data) {
+      message_func = func;
+      message_user_data = user_data;
+    }
+
+    // Set a callback function that will be called when OTS needs to decide what to
+    // do for a font table.
+    void SetTableActionCallback(TableActionFunc func, void *user_data) {
+      table_action_func = func;
+      table_action_user_data = user_data;
+    }
+
+  private:
+    MessageFunc      message_func;
+    void            *message_user_data;
+    TableActionFunc  table_action_func;
+    void            *table_action_user_data;
+};
 
 // Force to disable debug output even when the library is compiled with
 // -DOTS_DEBUG.
 void DisableDebugOutput();
 
 // Enable WOFF2 support(experimental).
 void EnableWOFF2();
 
--- a/gfx/ots/ots-visibility.patch
+++ b/gfx/ots/ots-visibility.patch
@@ -32,57 +32,27 @@ diff --git a/gfx/ots/include/opentype-sa
  #if defined(_WIN32)
  #include <stdlib.h>
  typedef signed char int8_t;
  typedef unsigned char uint8_t;
  typedef short int16_t;
  typedef unsigned short uint16_t;
  typedef int int32_t;
  typedef unsigned int uint32_t;
-@@ -182,45 +202,45 @@ 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|
- // -----------------------------------------------------------------------------
--bool Process(OTSStream *output, const uint8_t *input, size_t length);
-+bool OTS_API Process(OTSStream *output, const uint8_t *input, size_t length);
- 
- // Signature of the function to be provided by the client in order to report errors.
- // The return type is a boolean so that it can be used within an expression,
- // but the actual value is ignored. (Suggested convention is to always return 'false'.)
- #ifdef __GCC__
- #define MSGFUNC_FMT_ATTR __attribute__((format(printf, 2, 3)))
- #else
- #define MSGFUNC_FMT_ATTR
- #endif
- typedef bool (*MessageFunc)(void *user_data, const char *format, ...)  MSGFUNC_FMT_ATTR;
- 
- // Set a callback function that will be called when OTS is reporting an error.
--void SetMessageCallback(MessageFunc func, void *user_data);
-+void OTS_API SetMessageCallback(MessageFunc func, void *user_data);
- 
- enum TableAction {
-   TABLE_ACTION_DEFAULT,  // Use OTS's default action for that table
-   TABLE_ACTION_SANITIZE, // Sanitize the table, potentially droping it
-   TABLE_ACTION_PASSTHRU, // Serialize the table unchanged
-   TABLE_ACTION_DROP      // Drop the table
+@@ -197,17 +217,17 @@ enum TableAction {
  };
  
  // Signature of the function to be provided by the client to decide what action
  // to do for a given table.
+ //   tag: table tag as an integer in big-endian byte order, independent of platform endianness
+ //   user_data: user defined data that are passed to SetTableActionCallback()
  typedef TableAction (*TableActionFunc)(uint32_t tag, void *user_data);
  
- // Set a callback function that will be called when OTS needs to decide what to
- // do for a font table.
--void SetTableActionCallback(TableActionFunc func, void *user_data);
-+void OTS_API SetTableActionCallback(TableActionFunc func, void *user_data);
+-class OTSContext {
++class OTS_API OTSContext {
+   public:
+     OTSContext()
+         : message_func(0),
+           message_user_data(0),
+           table_action_func(0),
+           table_action_user_data(0)
+         {}
  
- // Force to disable debug output even when the library is compiled with
- // -DOTS_DEBUG.
- void DisableDebugOutput();
- 
- // Enable WOFF2 support(experimental).
- void EnableWOFF2();
- 
--- a/gfx/ots/src/cff.cc
+++ b/gfx/ots/src/cff.cc
@@ -1023,8 +1023,10 @@ void ots_cff_free(OpenTypeFile *file) {
       delete (file->cff->local_subrs_per_font)[i];
     }
     delete file->cff->local_subrs;
     delete file->cff;
   }
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
--- a/gfx/ots/src/cmap.cc
+++ b/gfx/ots/src/cmap.cc
@@ -355,18 +355,18 @@ bool Parse31013(ots::OpenTypeFile *file,
   ots::Buffer subtable(data, length);
 
   // Format 13 tables are simple. We parse these and fully serialise them
   // later.
 
   if (!subtable.Skip(8)) {
     return OTS_FAILURE_MSG("Bad cmap subtable length");
   }
-  uint16_t language = 0;
-  if (!subtable.ReadU16(&language)) {
+  uint32_t language = 0;
+  if (!subtable.ReadU32(&language)) {
     return OTS_FAILURE_MSG("Can't read cmap subtable language");
   }
   if (language) {
     return OTS_FAILURE_MSG("Cmap subtable language should be zero but is %d", language);
   }
 
   uint32_t num_groups = 0;
   if (!subtable.ReadU32(&num_groups)) {
@@ -871,17 +871,17 @@ bool ots_cmap_serialise(OTSStream *out, 
                                  static_cast<unsigned>(have_304) +
                                  static_cast<unsigned>(have_314) +
                                  static_cast<unsigned>(have_31012) +
                                  static_cast<unsigned>(have_31013);
   const off_t table_start = out->Tell();
 
   // Some fonts don't have 3-0-4 MS Symbol nor 3-1-4 Unicode BMP tables
   // (e.g., old fonts for Mac). We don't support them.
-  if (!have_304 && !have_314 && !have_034) {
+  if (!have_304 && !have_314 && !have_034 && !have_31012 && !have_31013) {
     return OTS_FAILURE();
   }
 
   if (!out->WriteU16(0) ||
       !out->WriteU16(num_subtables)) {
     return OTS_FAILURE();
   }
 
@@ -1000,17 +1000,17 @@ bool ots_cmap_serialise(OTSStream *out, 
   }
 
   const off_t offset_31013 = out->Tell();
   if (have_31013) {
     std::vector<OpenTypeCMAPSubtableRange> &groups
         = file->cmap->subtable_3_10_13;
     const unsigned num_groups = groups.size();
     if (!out->WriteU16(13) ||
-        !out->WriteU16(0) ||
+        !out->WriteU32(0) ||
         !out->WriteU32(num_groups * 12 + 14) ||
         !out->WriteU32(0) ||
         !out->WriteU32(num_groups)) {
       return OTS_FAILURE();
     }
 
     for (unsigned i = 0; i < num_groups; ++i) {
       if (!out->WriteU32(groups[i].start_range) ||
@@ -1096,8 +1096,10 @@ bool ots_cmap_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_cmap_free(OpenTypeFile *file) {
   delete file->cmap;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
--- a/gfx/ots/src/cvt.cc
+++ b/gfx/ots/src/cvt.cc
@@ -51,8 +51,10 @@ bool ots_cvt_serialise(OTSStream *out, O
   return true;
 }
 
 void ots_cvt_free(OpenTypeFile *file) {
   delete file->cvt;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
--- a/gfx/ots/src/fpgm.cc
+++ b/gfx/ots/src/fpgm.cc
@@ -45,8 +45,10 @@ bool ots_fpgm_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_fpgm_free(OpenTypeFile *file) {
   delete file->fpgm;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
--- a/gfx/ots/src/gasp.cc
+++ b/gfx/ots/src/gasp.cc
@@ -105,8 +105,11 @@ bool ots_gasp_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_gasp_free(OpenTypeFile *file) {
   delete file->gasp;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
+#undef DROP_THIS_TABLE
--- a/gfx/ots/src/gdef.cc
+++ b/gfx/ots/src/gdef.cc
@@ -379,8 +379,10 @@ bool ots_gdef_serialise(OTSStream *out, 
 }
 
 void ots_gdef_free(OpenTypeFile *file) {
   delete file->gdef;
 }
 
 }  // namespace ots
 
+#undef TABLE_NAME
+#undef DROP_THIS_TABLE
--- a/gfx/ots/src/glyf.cc
+++ b/gfx/ots/src/glyf.cc
@@ -302,8 +302,10 @@ bool ots_glyf_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_glyf_free(OpenTypeFile *file) {
   delete file->glyf;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
--- a/gfx/ots/src/gpos.cc
+++ b/gfx/ots/src/gpos.cc
@@ -807,8 +807,10 @@ bool ots_gpos_serialise(OTSStream *out, 
 }
 
 void ots_gpos_free(OpenTypeFile *file) {
   delete file->gpos;
 }
 
 }  // namespace ots
 
+#undef TABLE_NAME
+#undef DROP_THIS_TABLE
--- a/gfx/ots/src/gsub.cc
+++ b/gfx/ots/src/gsub.cc
@@ -664,8 +664,10 @@ bool ots_gsub_serialise(OTSStream *out, 
 }
 
 void ots_gsub_free(OpenTypeFile *file) {
   delete file->gsub;
 }
 
 }  // namespace ots
 
+#undef TABLE_NAME
+#undef DROP_THIS_TABLE
--- a/gfx/ots/src/hdmx.cc
+++ b/gfx/ots/src/hdmx.cc
@@ -133,8 +133,11 @@ bool ots_hdmx_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_hdmx_free(OpenTypeFile *file) {
   delete file->hdmx;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
+#undef DROP_THIS_TABLE
--- a/gfx/ots/src/head.cc
+++ b/gfx/ots/src/head.cc
@@ -144,8 +144,10 @@ bool ots_head_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_head_free(OpenTypeFile *file) {
   delete file->head;
 }
 
 }  // namespace
+
+#undef TABLE_NAME
--- a/gfx/ots/src/hhea.cc
+++ b/gfx/ots/src/hhea.cc
@@ -44,8 +44,10 @@ bool ots_hhea_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_hhea_free(OpenTypeFile *file) {
   delete file->hhea;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
--- a/gfx/ots/src/hmtx.cc
+++ b/gfx/ots/src/hmtx.cc
@@ -42,8 +42,10 @@ bool ots_hmtx_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_hmtx_free(OpenTypeFile *file) {
   delete file->hmtx;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
--- a/gfx/ots/src/kern.cc
+++ b/gfx/ots/src/kern.cc
@@ -195,8 +195,11 @@ bool ots_kern_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_kern_free(OpenTypeFile *file) {
   delete file->kern;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
+#undef DROP_THIS_TABLE
--- a/gfx/ots/src/layout.cc
+++ b/gfx/ots/src/layout.cc
@@ -1505,8 +1505,9 @@ bool ParseExtensionSubtable(const OpenTy
     return OTS_FAILURE_MSG("Failed to parse lookup from extension lookup");
   }
 
   return true;
 }
 
 }  // namespace ots
 
+#undef TABLE_NAME
--- a/gfx/ots/src/loca.cc
+++ b/gfx/ots/src/loca.cc
@@ -93,8 +93,10 @@ bool ots_loca_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_loca_free(OpenTypeFile *file) {
   delete file->loca;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
--- a/gfx/ots/src/ltsh.cc
+++ b/gfx/ots/src/ltsh.cc
@@ -81,8 +81,11 @@ bool ots_ltsh_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_ltsh_free(OpenTypeFile *file) {
   delete file->ltsh;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
+#undef DROP_THIS_TABLE
--- a/gfx/ots/src/math.cc
+++ b/gfx/ots/src/math.cc
@@ -601,8 +601,10 @@ bool ots_math_serialise(OTSStream *out, 
 }
 
 void ots_math_free(OpenTypeFile *file) {
   delete file->math;
 }
 
 }  // namespace ots
 
+#undef TABLE_NAME
+#undef DROP_THIS_TABLE
--- a/gfx/ots/src/maxp.cc
+++ b/gfx/ots/src/maxp.cc
@@ -123,8 +123,10 @@ bool ots_maxp_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_maxp_free(OpenTypeFile *file) {
   delete file->maxp;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
--- a/gfx/ots/src/metrics.cc
+++ b/gfx/ots/src/metrics.cc
@@ -179,8 +179,9 @@ bool SerialiseMetricsTable(const ots::Op
     }
   }
 
   return true;
 }
 
 }  // namespace ots
 
+#undef TABLE_NAME
--- a/gfx/ots/src/name.cc
+++ b/gfx/ots/src/name.cc
@@ -327,8 +327,10 @@ bool ots_name_serialise(OTSStream* out, 
   return true;
 }
 
 void ots_name_free(OpenTypeFile* file) {
   delete file->name;
 }
 
 }  // namespace
+
+#undef TABLE_NAME
--- a/gfx/ots/src/os2.cc
+++ b/gfx/ots/src/os2.cc
@@ -285,8 +285,10 @@ bool ots_os2_serialise(OTSStream *out, O
   return true;
 }
 
 void ots_os2_free(OpenTypeFile *file) {
   delete file->os2;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
--- a/gfx/ots/src/ots.cc
+++ b/gfx/ots/src/ots.cc
@@ -21,22 +21,16 @@
 // The OpenType Font File
 // http://www.microsoft.com/typography/otspec/cmap.htm
 
 namespace {
 
 bool g_debug_output = true;
 bool g_enable_woff2 = false;
 
-ots::MessageFunc  g_message_func = NULL;
-void             *g_message_user_data = NULL;
-
-ots::TableActionFunc  g_table_action_func = NULL;
-void                 *g_table_action_user_data = NULL;
-
 // Generate a message with or without a table tag, when 'header' is the OpenTypeFile pointer
 #define OTS_FAILURE_MSG_TAG(msg_,tag_) OTS_FAILURE_MSG_TAG_(header, msg_, tag_)
 #define OTS_FAILURE_MSG_HDR(msg_)      OTS_FAILURE_MSG_(header, msg_)
 
 
 struct OpenTypeTable {
   uint32_t tag;
   uint32_t chksum;
@@ -418,21 +412,21 @@ bool ProcessWOFF2(ots::OpenTypeFile *hea
   if (!ots::ConvertWOFF2ToTTF(&decompressed_buffer[0], decompressed_size,
                               data, length)) {
     return OTS_FAILURE();
   }
   return ProcessTTF(header, output, &decompressed_buffer[0], decompressed_size);
 }
 #endif
 
-ots::TableAction GetTableAction(uint32_t tag) {
+ots::TableAction GetTableAction(ots::OpenTypeFile *header, uint32_t tag) {
   ots::TableAction action = ots::TABLE_ACTION_DEFAULT;
 
-  if (g_table_action_func != NULL) {
-    action = g_table_action_func(htonl(tag), g_table_action_user_data);
+  if (header->table_action_func != NULL) {
+    action = header->table_action_func(htonl(tag), header->table_action_user_data);
   }
 
   if (action == ots::TABLE_ACTION_DEFAULT) {
     action = ots::TABLE_ACTION_DROP;
 
     for (unsigned i = 0; ; ++i) {
       if (table_parsers[i].parse == NULL) break;
 
@@ -571,20 +565,20 @@ bool ProcessGeneric(ots::OpenTypeFile *h
     }
   }
 
   Arena arena;
 
   for (unsigned i = 0; ; ++i) {
     if (table_parsers[i].parse == NULL) break;
 
-    const std::map<uint32_t, OpenTypeTable>::const_iterator it
-        = table_map.find(Tag(table_parsers[i].tag));
+    uint32_t tag = Tag(table_parsers[i].tag);
+    const std::map<uint32_t, OpenTypeTable>::const_iterator it = table_map.find(tag);
 
-    ots::TableAction action = GetTableAction(Tag(table_parsers[i].tag));
+    ots::TableAction action = GetTableAction(header, tag);
     if (it == table_map.end()) {
       if (table_parsers[i].required && action == ots::TABLE_ACTION_SANITIZE) {
         return OTS_FAILURE_MSG_TAG("missing required table", table_parsers[i].tag);
       }
       continue;
     }
 
     const uint8_t* table_data;
@@ -627,17 +621,17 @@ bool ProcessGeneric(ots::OpenTypeFile *h
 
     if (table_parsers[i].should_serialise(header)) {
       num_output_tables++;
     }
   }
 
   for (std::map<uint32_t, OpenTypeTable>::const_iterator it = table_map.begin();
        it != table_map.end(); ++it) {
-    ots::TableAction action = GetTableAction(it->first);
+    ots::TableAction action = GetTableAction(header, it->first);
     if (action == ots::TABLE_ACTION_PASSTHRU) {
       num_output_tables++;
     }
   }
 
   unsigned max_pow2 = 0;
   while (1u << (max_pow2 + 1) <= num_output_tables) {
     max_pow2++;
@@ -699,17 +693,17 @@ bool ProcessGeneric(ots::OpenTypeFile *h
       return OTS_FAILURE_MSG_HDR("error writing output");
     }
     out.chksum = output->chksum();
     out_tables.push_back(out);
   }
 
   for (std::map<uint32_t, OpenTypeTable>::const_iterator it = table_map.begin();
        it != table_map.end(); ++it) {
-    ots::TableAction action = GetTableAction(it->first);
+    ots::TableAction action = GetTableAction(header, it->first);
     if (action == ots::TABLE_ACTION_PASSTHRU) {
       OutputTable out;
       out.tag = it->second.tag;
       out.offset = output->Tell();
 
       output->ResetChecksum();
       if (it->second.tag == Tag("head")) {
         head_table_offset = out.offset;
@@ -803,31 +797,25 @@ bool IsValidVersionTag(uint32_t tag) {
 void DisableDebugOutput() {
   g_debug_output = false;
 }
 
 void EnableWOFF2() {
   g_enable_woff2 = true;
 }
 
-void SetMessageCallback(MessageFunc func, void *user_data) {
-  g_message_func = func;
-  g_message_user_data = user_data;
-}
-
-void SetTableActionCallback(TableActionFunc func, void *user_data) {
-  g_table_action_func = func;
-  g_table_action_user_data = user_data;
-}
-
-bool Process(OTSStream *output, const uint8_t *data, size_t length) {
+bool OTSContext::Process(OTSStream *output,
+                         const uint8_t *data,
+                         size_t length) {
   OpenTypeFile header;
 
-  header.message_func = g_message_func;
-  header.user_data = g_message_user_data;
+  header.message_func = message_func;
+  header.message_user_data = message_user_data;
+  header.table_action_func = table_action_func;
+  header.table_action_user_data = table_action_user_data;
 
   if (length < 4) {
     return OTS_FAILURE_MSG_(&header, "file less than 4 bytes");
   }
 
   bool result;
   if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F') {
     result = ProcessWOFF(&header, output, data, length);
--- a/gfx/ots/src/ots.h
+++ b/gfx/ots/src/ots.h
@@ -48,23 +48,23 @@ void Warning(const char *f, int l, const
 // message-less OTS_FAILURE(), so that the current parser will return 'false' as
 // its result (indicating a failure).
 // If a message_func pointer has been provided, this will be called before returning
 // the 'false' status.
 
 // Generate a simple message
 #define OTS_FAILURE_MSG_(otf_,...) \
   ((otf_)->message_func && \
-    (*(otf_)->message_func)((otf_)->user_data, __VA_ARGS__) && \
+    (*(otf_)->message_func)((otf_)->message_user_data, __VA_ARGS__) && \
     false)
 
 // Generate a message with an associated table tag
 #define OTS_FAILURE_MSG_TAG_(otf_,msg_,tag_) \
   ((otf_)->message_func && \
-    (*(otf_)->message_func)((otf_)->user_data, "%4.4s: %s", tag_, msg_) && \
+    (*(otf_)->message_func)((otf_)->message_user_data, "%4.4s: %s", tag_, msg_) && \
     false)
 
 // Convenience macro for use in files that only handle a single table tag,
 // defined as TABLE_NAME at the top of the file; the 'file' variable is
 // expected to be the current OpenTypeFile pointer.
 #define OTS_FAILURE_MSG(...) OTS_FAILURE_MSG_(file, TABLE_NAME ": " __VA_ARGS__)
 
 // Define OTS_NO_TRANSCODE_HINTS (i.e., g++ -DOTS_NO_TRANSCODE_HINTS) if you
@@ -245,18 +245,21 @@ struct OpenTypeFile {
   }
 
   uint32_t version;
   uint16_t num_tables;
   uint16_t search_range;
   uint16_t entry_selector;
   uint16_t range_shift;
 
-  MessageFunc message_func;
-  void        *user_data;
+  MessageFunc  message_func;
+  void        *message_user_data;
+
+  TableActionFunc  table_action_func;
+  void            *table_action_user_data;
 
 #define F(name, capname) OpenType##capname *name;
 FOR_EACH_TABLE_TYPE
 #undef F
 };
 
 #define F(name, capname) \
 bool ots_##name##_parse(OpenTypeFile *f, const uint8_t *d, size_t l); \
--- a/gfx/ots/src/post.cc
+++ b/gfx/ots/src/post.cc
@@ -175,8 +175,10 @@ bool ots_post_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_post_free(OpenTypeFile *file) {
   delete file->post;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
--- a/gfx/ots/src/prep.cc
+++ b/gfx/ots/src/prep.cc
@@ -45,8 +45,10 @@ bool ots_prep_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_prep_free(OpenTypeFile *file) {
   delete file->prep;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
--- a/gfx/ots/src/vdmx.cc
+++ b/gfx/ots/src/vdmx.cc
@@ -176,8 +176,11 @@ bool ots_vdmx_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_vdmx_free(OpenTypeFile *file) {
   delete file->vdmx;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
+#undef DROP_THIS_TABLE
--- a/gfx/ots/src/vhea.cc
+++ b/gfx/ots/src/vhea.cc
@@ -51,8 +51,9 @@ bool ots_vhea_serialise(OTSStream *out, 
 }
 
 void ots_vhea_free(OpenTypeFile *file) {
   delete file->vhea;
 }
 
 }  // namespace ots
 
+#undef TABLE_NAME
--- a/gfx/ots/src/vmtx.cc
+++ b/gfx/ots/src/vmtx.cc
@@ -47,8 +47,9 @@ bool ots_vmtx_serialise(OTSStream *out, 
 }
 
 void ots_vmtx_free(OpenTypeFile *file) {
   delete file->vmtx;
 }
 
 }  // namespace ots
 
+#undef TABLE_NAME
--- a/gfx/ots/src/vorg.cc
+++ b/gfx/ots/src/vorg.cc
@@ -96,8 +96,11 @@ bool ots_vorg_serialise(OTSStream *out, 
   return true;
 }
 
 void ots_vorg_free(OpenTypeFile *file) {
   delete file->vorg;
 }
 
 }  // namespace ots
+
+#undef TABLE_NAME
+#undef DROP_THIS_TABLE
--- a/gfx/thebes/gfxUserFontSet.cpp
+++ b/gfx/thebes/gfxUserFontSet.cpp
@@ -383,20 +383,21 @@ gfxUserFontSet::SanitizeOpenTypeData(gfx
     ExpandingMemoryStream output(aIsCompressed ? aLength * 2 : aLength,
                                  1024 * 1024 * 256);
 
     OTSCallbackUserData userData;
     userData.mFontSet = this;
     userData.mFamily = aFamily;
     userData.mProxy = aProxy;
 
-    ots::SetTableActionCallback(&OTSTableAction, nullptr);
-    ots::SetMessageCallback(&gfxUserFontSet::OTSMessage, &userData);
+    ots::OTSContext otsContext;
+    otsContext.SetTableActionCallback(&OTSTableAction, nullptr);
+    otsContext.SetMessageCallback(&gfxUserFontSet::OTSMessage, &userData);
 
-    if (ots::Process(&output, aData, aLength)) {
+    if (otsContext.Process(&output, aData, aLength)) {
         aSaneLength = output.Tell();
         return static_cast<uint8_t*>(output.forget());
     } else {
         aSaneLength = 0;
         return nullptr;
     }
 }