Bug 712217 - Update OTS to r77 [r=jfkthame]
authorYury <async.processingjs@yahoo.com>
Thu, 22 Dec 2011 11:46:51 +0100
changeset 83246 a63f8ea052b6fb5f95ec621fbe4e21c219ed6e41
parent 83245 b230ea62de175bbb19573bafdcd5cca8fc61d3e0
child 83247 b02402b95e5cbfa6058d5ecae230604f64ed5fe4
push idunknown
push userunknown
push dateunknown
reviewersjfkthame
bugs712217
milestone12.0a1
Bug 712217 - Update OTS to r77 [r=jfkthame]
gfx/ots/README.mozilla
gfx/ots/src/cff.cc
gfx/ots/src/ots.cc
--- a/gfx/ots/README.mozilla
+++ b/gfx/ots/README.mozilla
@@ -1,8 +1,8 @@
 This is the Sanitiser for OpenType project, from http://code.google.com/p/ots/.
 
-Current revision: r74
+Current revision: r77
 
 Applied local patches:
     ots-fix-vc10.patch - workaround for VS10 STL wrappers (bug 602558)
 
     ots-fix-sparc64.patch - fix alignment error on sparc64 (bug 643137)
--- a/gfx/ots/src/cff.cc
+++ b/gfx/ots/src/cff.cc
@@ -52,17 +52,17 @@ bool ParseIndex(ots::Buffer *table, ots:
   index->off_size = 0;
   index->offsets.clear();
 
   if (!table->ReadU16(&(index->count))) {
     return OTS_FAILURE();
   }
   if (index->count == 0) {
     // An empty INDEX.
-    index->offset_to_next = table->offset() + sizeof(index->count);
+    index->offset_to_next = table->offset();
     return true;
   }
 
   if (!table->ReadU8(&(index->off_size))) {
     return OTS_FAILURE();
   }
   if ((index->off_size == 0) ||
       (index->off_size > 4)) {
--- a/gfx/ots/src/ots.cc
+++ b/gfx/ots/src/ots.cc
@@ -29,22 +29,16 @@ struct OpenTypeTable {
 };
 
 // Round a value up to the nearest multiple of 4. Note that this can overflow
 // and return zero.
 template<typename T> T Round4(T value) {
   return (value + 3) & ~3;
 }
 
-uint32_t Tag(const char *tag_str) {
-  uint32_t ret;
-  std::memcpy(&ret, tag_str, 4);
-  return ret;
-}
-
 bool CheckTag(uint32_t tag_value) {
   for (unsigned i = 0; i < 4; ++i) {
     const uint32_t check = tag_value & 0xff;
     if (check < 32 || check > 126) {
       return false;  // non-ASCII character found.
     }
     tag_value >>= 8;
   }
@@ -78,98 +72,102 @@ struct Arena {
     hunks_.push_back(p);
     return p;
   }
 
  private:
   std::vector<uint8_t*> hunks_;
 };
 
+// Use a macro instead of a function because gcc 4.4.3 creates static
+// initializers in that case. Note this macro assumes a little-endian system.
+#define TAG(a, b, c, d) (a | (b << 8) | (c << 16) | (d << 24))
+
 const struct {
   uint32_t tag;
   bool (*parse)(ots::OpenTypeFile *otf, const uint8_t *data, size_t length);
   bool (*serialise)(ots::OTSStream *out, ots::OpenTypeFile *file);
   bool (*should_serialise)(ots::OpenTypeFile *file);
   void (*free)(ots::OpenTypeFile *file);
   bool required;
 } table_parsers[] = {
-  { Tag("maxp"), ots::ots_maxp_parse, ots::ots_maxp_serialise,
+  { TAG('m', 'a', 'x', 'p'), ots::ots_maxp_parse, ots::ots_maxp_serialise,
     ots::ots_maxp_should_serialise, ots::ots_maxp_free, true },
-  { Tag("head"), ots::ots_head_parse, ots::ots_head_serialise,
+  { TAG('h', 'e', 'a', 'd'), ots::ots_head_parse, ots::ots_head_serialise,
     ots::ots_head_should_serialise, ots::ots_head_free, true },
-  { Tag("OS/2"), ots::ots_os2_parse, ots::ots_os2_serialise,
+  { TAG('O', 'S', '/', '2'), ots::ots_os2_parse, ots::ots_os2_serialise,
     ots::ots_os2_should_serialise, ots::ots_os2_free, true },
-  { Tag("cmap"), ots::ots_cmap_parse, ots::ots_cmap_serialise,
+  { TAG('c', 'm', 'a', 'p'), ots::ots_cmap_parse, ots::ots_cmap_serialise,
     ots::ots_cmap_should_serialise, ots::ots_cmap_free, true },
-  { Tag("hhea"), ots::ots_hhea_parse, ots::ots_hhea_serialise,
+  { TAG('h', 'h', 'e', 'a'), ots::ots_hhea_parse, ots::ots_hhea_serialise,
     ots::ots_hhea_should_serialise, ots::ots_hhea_free, true },
-  { Tag("hmtx"), ots::ots_hmtx_parse, ots::ots_hmtx_serialise,
+  { TAG('h', 'm', 't', 'x'), ots::ots_hmtx_parse, ots::ots_hmtx_serialise,
     ots::ots_hmtx_should_serialise, ots::ots_hmtx_free, true },
-  { Tag("name"), ots::ots_name_parse, ots::ots_name_serialise,
+  { TAG('n', 'a', 'm', 'e'), ots::ots_name_parse, ots::ots_name_serialise,
     ots::ots_name_should_serialise, ots::ots_name_free, true },
-  { Tag("post"), ots::ots_post_parse, ots::ots_post_serialise,
+  { TAG('p', 'o', 's', 't'), ots::ots_post_parse, ots::ots_post_serialise,
     ots::ots_post_should_serialise, ots::ots_post_free, true },
-  { Tag("loca"), ots::ots_loca_parse, ots::ots_loca_serialise,
+  { TAG('l', 'o', 'c', 'a'), ots::ots_loca_parse, ots::ots_loca_serialise,
     ots::ots_loca_should_serialise, ots::ots_loca_free, false },
-  { Tag("glyf"), ots::ots_glyf_parse, ots::ots_glyf_serialise,
+  { TAG('g', 'l', 'y', 'f'), ots::ots_glyf_parse, ots::ots_glyf_serialise,
     ots::ots_glyf_should_serialise, ots::ots_glyf_free, false },
-  { Tag("CFF "), ots::ots_cff_parse, ots::ots_cff_serialise,
+  { TAG('C', 'F', 'F', ' '), ots::ots_cff_parse, ots::ots_cff_serialise,
     ots::ots_cff_should_serialise, ots::ots_cff_free, false },
-  { Tag("VDMX"), ots::ots_vdmx_parse, ots::ots_vdmx_serialise,
+  { TAG('V', 'D', 'M', 'X'), ots::ots_vdmx_parse, ots::ots_vdmx_serialise,
     ots::ots_vdmx_should_serialise, ots::ots_vdmx_free, false },
-  { Tag("hdmx"), ots::ots_hdmx_parse, ots::ots_hdmx_serialise,
+  { TAG('h', 'd', 'm', 'x'), ots::ots_hdmx_parse, ots::ots_hdmx_serialise,
     ots::ots_hdmx_should_serialise, ots::ots_hdmx_free, false },
-  { Tag("gasp"), ots::ots_gasp_parse, ots::ots_gasp_serialise,
+  { TAG('g', 'a', 's', 'p'), ots::ots_gasp_parse, ots::ots_gasp_serialise,
     ots::ots_gasp_should_serialise, ots::ots_gasp_free, false },
-  { Tag("cvt "), ots::ots_cvt_parse, ots::ots_cvt_serialise,
+  { TAG('c', 'v', 't', ' '), ots::ots_cvt_parse, ots::ots_cvt_serialise,
     ots::ots_cvt_should_serialise, ots::ots_cvt_free, false },
-  { Tag("fpgm"), ots::ots_fpgm_parse, ots::ots_fpgm_serialise,
+  { TAG('f', 'p', 'g', 'm'), ots::ots_fpgm_parse, ots::ots_fpgm_serialise,
     ots::ots_fpgm_should_serialise, ots::ots_fpgm_free, false },
-  { Tag("prep"), ots::ots_prep_parse, ots::ots_prep_serialise,
+  { TAG('p', 'r', 'e', 'p'), 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,
+  { TAG('L', 'T', 'S', 'H'), 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,
+  { TAG('V', 'O', 'R', 'G'), 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,
+  { TAG('k', 'e', 'r', 'n'), ots::ots_kern_parse, ots::ots_kern_serialise,
     ots::ots_kern_should_serialise, ots::ots_kern_free, false },
   // We need to parse GDEF table in advance of parsing GSUB/GPOS tables
   // because they could refer GDEF table.
-  { Tag("GDEF"), ots::ots_gdef_parse, ots::ots_gdef_serialise,
+  { TAG('G', 'D', 'E', 'F'), 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,
+  { TAG('G', 'P', 'O', 'S'), 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,
+  { TAG('G', 'S', 'U', 'B'), ots::ots_gsub_parse, ots::ots_gsub_serialise,
     ots::ots_gsub_should_serialise, ots::ots_gsub_free, false },
-  { Tag("vhea"), ots::ots_vhea_parse, ots::ots_vhea_serialise,
+  { TAG('v', 'h', 'e', 'a'), ots::ots_vhea_parse, ots::ots_vhea_serialise,
     ots::ots_vhea_should_serialise, ots::ots_vhea_free, false },
-  { Tag("vmtx"), ots::ots_vmtx_parse, ots::ots_vmtx_serialise,
+  { TAG('v', 'm', 't', 'x'), 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,
+  { TAG('S', 'i', 'l', 'f'), 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,
+  { TAG('S', 'i', 'l', 'l'), 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,
+  { TAG('G', 'l', 'o', 'c'), 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,
+  { TAG('G', 'l', 'a', 't'), 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,
+  { TAG('F', 'e', 'a', 't'), 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 },
 };
 
 bool IsValidVersionTag(uint32_t tag) {
-  return tag == Tag("\x00\x01\x00\x00") ||
+  return tag == TAG('\x00', '\x01', '\x00', '\x00') ||
          // OpenType fonts with CFF data have 'OTTO' tag.
-         tag == Tag("OTTO") ||
+         tag == TAG('O', 'T', 'T', 'O') ||
          // Older Mac fonts might have 'true' or 'typ1' tag.
-         tag == Tag("true") ||
-         tag == Tag("typ1");
+         tag == TAG('t', 'r', 'u', 'e') ||
+         tag == TAG('t', 'y', 'p', '1');
 }
 
 bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
                     const uint8_t *data, size_t length,
                     const std::vector<OpenTypeTable>& tables,
                     ots::Buffer& file);
 
 bool ProcessTTF(ots::OpenTypeFile *header,
@@ -257,17 +255,17 @@ bool ProcessWOFF(ots::OpenTypeFile *head
     return OTS_FAILURE();
   }
 
   uint32_t woff_tag;
   if (!file.ReadTag(&woff_tag)) {
     return OTS_FAILURE();
   }
 
-  if (woff_tag != Tag("wOFF")) {
+  if (woff_tag != TAG('w', 'O', 'F', 'F')) {
     return OTS_FAILURE();
   }
 
   if (!file.ReadTag(&header->version)) {
     return OTS_FAILURE();
   }
   if (!IsValidVersionTag(header->version)) {
       return OTS_FAILURE();
@@ -453,17 +451,17 @@ bool ProcessGeneric(ots::OpenTypeFile *h
 
     if (!table_parsers[i].parse(header, table_data, table_length)) {
       return OTS_FAILURE();
     }
   }
 
   if (header->cff) {
     // font with PostScript glyph
-    if (header->version != Tag("OTTO")) {
+    if (header->version != TAG('O', 'T', 'T', 'O')) {
       return OTS_FAILURE();
     }
     if (header->glyf || header->loca) {
       // mixing outline formats is not recommended
       return OTS_FAILURE();
     }
   } else {
     if (!header->glyf || !header->loca) {
@@ -517,17 +515,17 @@ bool ProcessGeneric(ots::OpenTypeFile *h
       continue;
     }
 
     OutputTable out;
     out.tag = table_parsers[i].tag;
     out.offset = output->Tell();
 
     output->ResetChecksum();
-    if (table_parsers[i].tag == Tag("head")) {
+    if (table_parsers[i].tag == TAG('h', 'e', 'a', 'd')) {
       head_table_offset = out.offset;
     }
     if (!table_parsers[i].serialise(output, header)) {
       return OTS_FAILURE();
     }
 
     const size_t end_offset = output->Tell();
     if (end_offset <= out.offset) {