Bug 719286 - Add OTS support for OpenType SVG table r=jfkthame
authorEdwin Flores <eflores@mozilla.com>
Thu, 06 Sep 2012 16:57:02 +1200
changeset 104399 a27c021626dc993f02f026aa09aeab47fbb463c8
parent 104398 95e68df32601918874660f0652b9919a1e08464d
child 104400 286c5d489588368b801d151c4e6a630a078258ea
push id14492
push usereflores@mozilla.com
push dateThu, 06 Sep 2012 05:26:13 +0000
treeherdermozilla-inbound@d5e3428f33fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs719286
milestone18.0a1
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 719286 - Add OTS support for OpenType SVG table r=jfkthame
gfx/ots/src/Makefile.in
gfx/ots/src/ots.cc
gfx/ots/src/ots.h
gfx/ots/src/svg.cc
gfx/ots/src/svg.h
--- a/gfx/ots/src/Makefile.in
+++ b/gfx/ots/src/Makefile.in
@@ -71,16 +71,17 @@ CPPSRCS	= \
   vdmx.cc \
   vhea.cc \
   vmtx.cc \
   vorg.cc \
   gdef.cc \
   gpos.cc \
   gsub.cc \
   graphite.cc \
+  svg.cc \
   $(NULL)
 
 EXPORTS = \
   ../include/opentype-sanitiser.h \
   ../include/ots-memory-stream.h  \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/gfx/ots/src/ots.cc
+++ b/gfx/ots/src/ots.cc
@@ -167,16 +167,19 @@ const struct {
   { "Sill", ots::ots_sill_parse, ots::ots_sill_serialise,
     ots::ots_sill_should_serialise, ots::ots_sill_free, false },
   { "Gloc", ots::ots_gloc_parse, ots::ots_gloc_serialise,
     ots::ots_gloc_should_serialise, ots::ots_gloc_free, false },
   { "Glat", ots::ots_glat_parse, ots::ots_glat_serialise,
     ots::ots_glat_should_serialise, ots::ots_glat_free, false },
   { "Feat", ots::ots_feat_parse, ots::ots_feat_serialise,
     ots::ots_feat_should_serialise, ots::ots_feat_free, false },
+  // SVG glyph table
+  { "SVG ", ots::ots_svg_parse, ots::ots_svg_serialise,
+    ots::ots_svg_should_serialise, ots::ots_svg_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") ||
          // OpenType fonts with CFF data have 'OTTO' tag.
          tag == Tag("OTTO") ||
--- a/gfx/ots/src/ots.h
+++ b/gfx/ots/src/ots.h
@@ -217,17 +217,18 @@ class Buffer {
   F(vdmx, VDMX) \
   F(vorg, VORG) \
   F(vhea, VHEA) \
   F(vmtx, VMTX) \
   F(silf, SILF) \
   F(sill, SILL) \
   F(glat, GLAT) \
   F(gloc, GLOC) \
-  F(feat, FEAT)
+  F(feat, FEAT) \
+  F(svg, SVG)
 
 #define F(name, capname) struct OpenType##capname;
 FOR_EACH_TABLE_TYPE
 #undef F
 
 struct OpenTypeFile {
   OpenTypeFile() {
 #define F(name, capname) name = NULL;
new file mode 100644
--- /dev/null
+++ b/gfx/ots/src/svg.cc
@@ -0,0 +1,125 @@
+// Copyright (c) 2012 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 "ots.h"
+
+#include "svg.h"
+
+#define NONFATAL_FAILURE(msg) \
+  do { \
+    OTS_WARNING(msg); \
+    delete file->svg; file->svg = 0; \
+    return true; \
+  } while (0)
+
+namespace ots {
+
+bool ots_svg_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
+  Buffer table(data, length);
+
+  OpenTypeSVG *svg = new OpenTypeSVG;
+  file->svg = svg;
+
+  std::map<uint32_t, uint32_t> doc_locations;
+  typedef std::map<uint32_t, uint32_t>::iterator lociter_t;
+
+  uint16_t version;
+  uint16_t index_length;
+  if (!table.ReadU16(&version) ||
+      !table.ReadU16(&index_length)) {
+    NONFATAL_FAILURE("Couldn't read SVG table header");
+  }
+
+  if (version != 1) {
+    NONFATAL_FAILURE("Unknown SVG table version");
+  }
+
+  uint32_t max_address = 0;
+  uint32_t total_docs_length = 0;
+
+  uint16_t start_glyph;
+  uint16_t end_glyph;
+  uint32_t doc_offset;
+  uint32_t doc_length;
+  uint16_t last_end_glyph = 0;
+
+  for (uint16_t i = 0; i < index_length; i++) {
+    if (!table.ReadU16(&start_glyph) ||
+        !table.ReadU16(&end_glyph) ||
+        !table.ReadU32(&doc_offset) ||
+        !table.ReadU32(&doc_length)) {
+      NONFATAL_FAILURE("Couldn't read SVG table index");
+    }
+
+    if (end_glyph < start_glyph) {
+      NONFATAL_FAILURE("Bad SVG table index range");
+    }
+
+    if (last_end_glyph && start_glyph < last_end_glyph) {
+      NONFATAL_FAILURE("SVG table index range is not sorted");
+    }
+
+    if (doc_locations.find(doc_offset) != doc_locations.end()) {
+      if (doc_locations[doc_offset] != doc_length) {
+        NONFATAL_FAILURE("SVG table contains overlapping document range");
+      }
+    } else {
+      doc_locations[doc_offset] = doc_length;
+      total_docs_length += doc_length;
+      if (doc_offset + doc_length > max_address) {
+        max_address = doc_offset + doc_length;
+      }
+    }
+
+    if (doc_offset > 1024 * 1024 * 1024 ||
+        doc_length > 1024 * 1024 * 1024 ||
+        total_docs_length > 1024 * 1024 * 1024) {
+      NONFATAL_FAILURE("Bad SVG document length");
+    }
+
+    last_end_glyph = end_glyph;
+  }
+
+  uint32_t last_end = 4 + 12 * index_length;
+  for (lociter_t iter = doc_locations.begin();
+       iter != doc_locations.end(); ++iter) {
+    if (iter->first != last_end) {
+      NONFATAL_FAILURE("SVG table contains overlapping document range");
+    }
+    last_end = iter->first + iter->second;
+  }
+
+  if (max_address != length) {
+    NONFATAL_FAILURE("Bad SVG document length");
+  }
+
+  if (!table.Skip(total_docs_length)) {
+    NONFATAL_FAILURE("SVG table is too short");
+  }
+
+  svg->data = data;
+  svg->length = length;
+
+  return true;
+}
+
+bool ots_svg_serialise(OTSStream *out, OpenTypeFile *file) {
+  OpenTypeSVG *svg = file->svg;
+
+  if (!out->Write(svg->data, svg->length)) {
+    return OTS_FAILURE();
+  }
+
+  return true;
+}
+
+bool ots_svg_should_serialise(OpenTypeFile *file) {
+  return file->svg;
+}
+
+void ots_svg_free(OpenTypeFile *file) {
+  delete file->svg;
+}
+
+}
new file mode 100644
--- /dev/null
+++ b/gfx/ots/src/svg.h
@@ -0,0 +1,21 @@
+// Copyright (c) 2012 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_SVG_H
+#define OTS_SVG_H
+
+#include <map>
+
+#include "ots.h"
+
+namespace ots {
+
+struct OpenTypeSVG {
+  const uint8_t *data;
+  size_t length;
+};
+
+}
+
+#endif