[automerger skipped] Merge SPL-2019-12-05 skipped: 829f089332

Change-Id: Ifb12e3d90750e726e2197c60df6a3c774fa64c10
diff --git a/Android.bp b/Android.bp
index f26585d..7771723 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2,63 +2,14 @@
     name: "libsfntly",
     host_supported: true,
     srcs: [
-        "cpp/src/sfntly/data/byte_array.cc",
-        "cpp/src/sfntly/data/font_data.cc",
-        "cpp/src/sfntly/data/font_input_stream.cc",
-        "cpp/src/sfntly/data/font_output_stream.cc",
-        "cpp/src/sfntly/data/growable_memory_byte_array.cc",
-        "cpp/src/sfntly/data/memory_byte_array.cc",
-        "cpp/src/sfntly/data/readable_font_data.cc",
-        "cpp/src/sfntly/data/writable_font_data.cc",
-        "cpp/src/sfntly/font.cc",
-        "cpp/src/sfntly/font_factory.cc",
-        "cpp/src/sfntly/port/file_input_stream.cc",
-        "cpp/src/sfntly/port/lock.cc",
-        "cpp/src/sfntly/port/memory_input_stream.cc",
-        "cpp/src/sfntly/port/memory_output_stream.cc",
-        "cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc",
-        "cpp/src/sfntly/table/bitmap/bitmap_glyph.cc",
-        "cpp/src/sfntly/table/bitmap/bitmap_glyph_info.cc",
-        "cpp/src/sfntly/table/bitmap/bitmap_size_table.cc",
-        "cpp/src/sfntly/table/bitmap/composite_bitmap_glyph.cc",
-        "cpp/src/sfntly/table/bitmap/ebdt_table.cc",
-        "cpp/src/sfntly/table/bitmap/eblc_table.cc",
-        "cpp/src/sfntly/table/bitmap/ebsc_table.cc",
-        "cpp/src/sfntly/table/bitmap/glyph_metrics.cc",
-        "cpp/src/sfntly/table/bitmap/index_sub_table.cc",
-        "cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc",
-        "cpp/src/sfntly/table/bitmap/index_sub_table_format2.cc",
-        "cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc",
-        "cpp/src/sfntly/table/bitmap/index_sub_table_format4.cc",
-        "cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc",
-        "cpp/src/sfntly/table/bitmap/simple_bitmap_glyph.cc",
-        "cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc",
-        "cpp/src/sfntly/table/byte_array_table_builder.cc",
-        "cpp/src/sfntly/table/core/cmap_table.cc",
-        "cpp/src/sfntly/table/core/font_header_table.cc",
-        "cpp/src/sfntly/table/core/horizontal_device_metrics_table.cc",
-        "cpp/src/sfntly/table/core/horizontal_header_table.cc",
-        "cpp/src/sfntly/table/core/horizontal_metrics_table.cc",
-        "cpp/src/sfntly/table/core/maximum_profile_table.cc",
-        "cpp/src/sfntly/table/core/name_table.cc",
-        "cpp/src/sfntly/table/core/os2_table.cc",
-        "cpp/src/sfntly/table/font_data_table.cc",
-        "cpp/src/sfntly/table/generic_table_builder.cc",
-        "cpp/src/sfntly/table/header.cc",
-        "cpp/src/sfntly/table/subtable.cc",
-        "cpp/src/sfntly/table/table.cc",
-        "cpp/src/sfntly/table/table_based_table_builder.cc",
-        "cpp/src/sfntly/table/truetype/glyph_table.cc",
-        "cpp/src/sfntly/table/truetype/loca_table.cc",
-        "cpp/src/sfntly/tag.cc",
+        "cpp/src/sfntly/*.cc",
+        "cpp/src/sfntly/data/*.cc",
+        "cpp/src/sfntly/port/*.cc",
+        "cpp/src/sfntly/table/**/*.cc",
         "cpp/src/sample/chromium/font_subsetter.cc",
         "cpp/src/sample/chromium/subsetter_impl.cc",
     ],
 
-    shared_libs: [
-        "libandroidicu",
-    ],
-
     cflags: [
         "-fstack-protector",
         "--param=ssp-buffer-size=4",
@@ -139,6 +90,13 @@
     target: {
         android: {
             cflags: ["-fPIC"],
+            shared_libs: ["libandroidicu"],
+        },
+        host: {
+            shared_libs: [
+                "libicui18n",
+                "libicuuc"
+            ],
         },
         not_windows: {
             cflags: ["-fPIC"],
diff --git a/COPYING.android b/COPYING.android
deleted file mode 100644
index 13bcce2..0000000
--- a/COPYING.android
+++ /dev/null
@@ -1,2 +0,0 @@
-See cpp/COPYING for license details.
-
diff --git a/LICENSE b/LICENSE
new file mode 120000
index 0000000..3cb12fe
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+cpp/COPYING.txt
\ No newline at end of file
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..b02a109
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,14 @@
+name: "sfntly"
+description: "The sfntly project contains Java and C++ libraries for reading, editing, and writing sfnt container fonts (OpenType, TrueType, AAT/GX, and Graphite.)"
+third_party {
+  url {
+    type: GIT
+    value: "https://github.com/googlefonts/sfntly.git"
+  }
+  version: "9620b607af5b796badefebcf16d7ce6e6786f205"
+  last_upgrade_date {
+    year: 2019
+    month: 5
+    day: 3
+  }
+}
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index c61423c..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,203 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright 2011 Google Inc. All Rights Reserved.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
diff --git a/NOTICE b/NOTICE
new file mode 120000
index 0000000..7a694c9
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1 @@
+LICENSE
\ No newline at end of file
diff --git a/README.md b/README.md
index 9961600..7419f81 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,6 @@
-# What is sfntly?
+# sfntly
 
-sfntly is pronounced "esfontlee".
+This project is not developed any further. 
+Only Bug fixes will be merged, but new features won't.
 
-sfntly is a Java and C++ library for using, editing, and creating sfnt container based fonts (e.g. OpenType, TrueType). This library was initially created by Google's Font Team and the C++ port was done by the Chrome team. It has been made open source.
-
-The basic features of sfntly are the reading, editing, and writing of an sfnt container font. Fonts that use an sfnt container include OpenType, TrueType, AAT/GX, and Graphite. sfntly isn't itself a tool that is usable by an end user - it is a library that allows software developers to build tools that manipulate fonts in ways that haven't been easily accessible to most developers. The sfntly library is available in Java with a partial C++ port. However, we have included some font tools that are built on top of sfntly: a font subsetter, font dumper, a font linter, some compression utilities.
-
-The uses of sfntly are really anything that you can think of that involves reading and/or editing fonts. Right now, the Java version is the core library used to power Google's Web Fonts project. There it is used for all font manipulation - to read font data, to pull apart fonts, and to then reassemble them before they are streamed out to a user. Portions of the font that are not needed - specific glyph ranges or features - are stripped using sfntly to minimize the size of the streamed font. The C++ port is used somewhat similarly within Chrome to subset fonts for insertion into a PDF for viewing or printing. Though the features stripped in the font are different in Chrome than in Web Fonts because the end use is different.
-
-Using sfntly you can read and extract any of the tables in a font. The tables are the individual data structures within the font for each of the features and functionality: glyph outlines, character maps, kerning, meta data, etc. If you look over the OpenType and TrueType specs, you will see a number of categories of tables. sfntly currently supports all of the required tables, the TrueType outline tables, bitmap glyph tables, and a couple of the other miscellaneous tables. This level of support provides for many of the needs developers have related to the informational reading of font data. It also covers a lot of the editing needs.
-
-To get started with sfntly: clone the repository and follow the quickstart.txt guide in the Java directory
-
-have fun
-
-Stuart Gill - sfntly Architect and Lead Developer
+An actively maintained fork with new features is available at <https://github.com/rillig/sfntly>
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index 85932bc..57bcabc 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -6,13 +6,15 @@
 
 project(sfntly)
 
+set(GCC_OR_CLANG ((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR CMAKE_COMPILER_IS_GNUCXX))
+
 # For gcc, make the default be debug build and valgrind friendly.
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
   if(NOT CMAKE_BUILD_TYPE)
     set(CMAKE_BUILD_TYPE Debug)
     add_definitions("-DDEBUG -D_DEBUG -g -fno-inline -fno-omit-frame-pointer -fno-builtin")
   endif(NOT CMAKE_BUILD_TYPE)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
 
   set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/lib)
   set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/bin)
@@ -21,9 +23,9 @@
 
 # The following simulates Chrome compilation flags
   add_definitions(-DSFNTLY_NO_EXCEPTION)
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
   add_definitions(-D__wur=__attribute__\(\(warn_unused_result\)\) -Wall -Werror -fno-exceptions)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
 
 # Use STL for TinyXML library
   add_definitions(-DTIXML_USE_STL)
@@ -69,9 +71,9 @@
                                      src/sfntly/tools/*.h src/sfntly/tools/*.cc)
   add_executable(subsetter ${SIMPLE_SUBSETTER})
   target_link_libraries(subsetter sfntly icuuc)
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
   target_link_libraries(subsetter pthread)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
   file(GLOB TINYXML src/test/tinyxml/*.cpp)
   add_library(tinyxml
               ${TINYXML})
@@ -86,9 +88,9 @@
     ext/gtest/src/gtest-all.cc
     ext/gtest/src/gtest_main.cc)
   target_link_libraries(unit_test sfntly icuuc tinyxml)
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
   target_link_libraries(unit_test pthread)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
   # subtly targets
   file(GLOB SUBTLY_FILES src/sample/subtly/*.h src/sample/subtly/*.cc)
   file(GLOB SUBTLY_MAINS src/sample/subtly/*main.cc)
@@ -98,26 +100,26 @@
   add_executable(subtly_subsetter
     src/sample/subtly/subsetter_main.cc)
   target_link_libraries(subtly_subsetter subtly sfntly icuuc)
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
   target_link_libraries(subtly_subsetter pthread)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
   add_executable(subtly_merger
     src/sample/subtly/merger_main.cc)
   target_link_libraries(subtly_merger subtly sfntly icuuc)
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
   target_link_libraries(subtly_merger pthread)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
   add_executable(subtly_debug
     src/sample/subtly/debug_main.cc)
   target_link_libraries(subtly_debug subtly sfntly icuuc)
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
   target_link_libraries(subtly_debug pthread)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
    add_executable(chrome_subsetter
      ${CHROME_SUBSETTER_LIB}
      src/sample/chromium/chrome_subsetter.cc
    )
    target_link_libraries(chrome_subsetter sfntly icuuc)
- if(CMAKE_COMPILER_IS_GNUCXX)
+ if(GCC_OR_CLANG)
    target_link_libraries(chrome_subsetter pthread)
- endif(CMAKE_COMPILER_IS_GNUCXX)
+ endif(GCC_OR_CLANG)
diff --git a/cpp/README.txt b/cpp/README.txt
deleted file mode 100644
index ac2b43a..0000000
--- a/cpp/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Please refer to http://code.google.com/p/sfntly/wiki/build_cpp regarding how to build sfntly.
-
-sfntly wiki contains other useful documents: http://code.google.com/p/sfntly/w/list
\ No newline at end of file
diff --git a/cpp/src/sample/chromium/subsetter_impl.cc b/cpp/src/sample/chromium/subsetter_impl.cc
index fc82ef1..d6c3216 100644
--- a/cpp/src/sample/chromium/subsetter_impl.cc
+++ b/cpp/src/sample/chromium/subsetter_impl.cc
@@ -20,11 +20,13 @@
 
 #include <algorithm>
 #include <iterator>
+#include <limits>
 #include <map>
 #include <set>
 #include <string>
 
 #include <unicode/ustring.h>
+#include <unicode/uversion.h>
 
 #include "sfntly/table/bitmap/eblc_table.h"
 #include "sfntly/table/bitmap/ebdt_table.h"
@@ -306,6 +308,10 @@
     for (int32_t j = last_glyph_id + 1; j <= *i; ++j) {
       loca_list[j] = last_offset;
     }
+
+    if (last_offset > std::numeric_limits<int32_t>::max() - length)
+      return false;
+
     last_offset += length;
     loca_list[*i + 1] = last_offset;
     last_glyph_id = *i;
@@ -320,14 +326,15 @@
 
 bool HasOverlap(int32_t range_begin, int32_t range_end,
                 const IntegerSet& glyph_ids) {
-  if (range_begin == range_end) {
+  if (range_begin == range_end)
     return glyph_ids.find(range_begin) != glyph_ids.end();
-  } else if (range_end > range_begin) {
-    IntegerSet::const_iterator left = glyph_ids.lower_bound(range_begin);
-    IntegerSet::const_iterator right = glyph_ids.lower_bound(range_end);
-    return right != left;
-  }
-  return false;
+
+  if (range_begin >= range_end)
+    return false;
+
+  IntegerSet::const_iterator left = glyph_ids.lower_bound(range_begin);
+  IntegerSet::const_iterator right = glyph_ids.lower_bound(range_end);
+  return left != right;
 }
 
 // Initialize builder, returns false if glyph_id subset is not covered.
@@ -415,14 +422,14 @@
 
 void CopyBigGlyphMetrics(BigGlyphMetrics::Builder* source,
                          BigGlyphMetrics::Builder* target) {
-  target->SetHeight(static_cast<byte_t>(source->Height()));
-  target->SetWidth(static_cast<byte_t>(source->Width()));
-  target->SetHoriBearingX(static_cast<byte_t>(source->HoriBearingX()));
-  target->SetHoriBearingY(static_cast<byte_t>(source->HoriBearingY()));
-  target->SetHoriAdvance(static_cast<byte_t>(source->HoriAdvance()));
-  target->SetVertBearingX(static_cast<byte_t>(source->VertBearingX()));
-  target->SetVertBearingY(static_cast<byte_t>(source->VertBearingY()));
-  target->SetVertAdvance(static_cast<byte_t>(source->VertAdvance()));
+  target->SetHeight(static_cast<uint8_t>(source->Height()));
+  target->SetWidth(static_cast<uint8_t>(source->Width()));
+  target->SetHoriBearingX(static_cast<uint8_t>(source->HoriBearingX()));
+  target->SetHoriBearingY(static_cast<uint8_t>(source->HoriBearingY()));
+  target->SetHoriAdvance(static_cast<uint8_t>(source->HoriAdvance()));
+  target->SetVertBearingX(static_cast<uint8_t>(source->VertBearingX()));
+  target->SetVertBearingY(static_cast<uint8_t>(source->VertBearingY()));
+  target->SetVertAdvance(static_cast<uint8_t>(source->VertAdvance()));
 }
 
 CALLER_ATTACH IndexSubTable::Builder*
@@ -685,11 +692,7 @@
   FontArray font_array;
   factory_->LoadFonts(&mis, &font_array);
   font_ = FindFont(font_name, font_array);
-  if (font_ == NULL) {
-    return false;
-  }
-
-  return true;
+  return font_ != NULL;
 }
 
 int SubsetterImpl::SubsetFont(const unsigned int* glyph_ids,
@@ -723,12 +726,14 @@
 
   MemoryOutputStream output_stream;
   factory_->SerializeFont(new_font, &output_stream);
-  int length = static_cast<int>(output_stream.Size());
-  if (length > 0) {
-    *output_buffer = new unsigned char[length];
-    memcpy(*output_buffer, output_stream.Get(), length);
+  size_t length = output_stream.Size();
+  if (length == 0 ||
+      length > static_cast<size_t>(std::numeric_limits<int>::max())) {
+    return 0;
   }
 
+  *output_buffer = new unsigned char[length];
+  memcpy(*output_buffer, output_stream.Get(), length);
   return length;
 }
 
@@ -790,6 +795,8 @@
     Tag::cmap,  // Keep here for future tagged PDF development.
     Tag::name,  // Keep here due to legal concerns: copyright info inside.
   };
+  const size_t kTablesInSubSetSize =
+      sizeof(TABLES_IN_SUBSET) / sizeof(TABLES_IN_SUBSET[0]);
 
   // Setup font builders we need.
   FontBuilderPtr font_builder;
@@ -817,9 +824,8 @@
   }
 
   IntegerSet allowed_tags;
-  for (size_t i = 0; i < sizeof(TABLES_IN_SUBSET) / sizeof(int32_t); ++i) {
+  for (size_t i = 0; i < kTablesInSubSetSize; ++i)
     allowed_tags.insert(TABLES_IN_SUBSET[i]);
-  }
 
   IntegerSet result;
   std::set_difference(allowed_tags.begin(), allowed_tags.end(),
@@ -828,12 +834,12 @@
   allowed_tags = result;
 
   // Setup remaining builders.
-  for (IntegerSet::iterator i = allowed_tags.begin(), e = allowed_tags.end();
-                            i != e; ++i) {
-    Table* table = font_->GetTable(*i);
-    if (table) {
-      font_builder->NewTableBuilder(*i, table->ReadFontData());
-    }
+  for (IntegerSet::const_iterator it = allowed_tags.begin();
+       it != allowed_tags.end(); ++it) {
+    int32_t tag = *it;
+    Table* table = font_->GetTable(tag);
+    if (table)
+      font_builder->NewTableBuilder(tag, table->ReadFontData());
   }
 
   return font_builder->Build();
diff --git a/cpp/src/sfntly/data/byte_array.cc b/cpp/src/sfntly/data/byte_array.cc
index 57f9eed..f510881 100644
--- a/cpp/src/sfntly/data/byte_array.cc
+++ b/cpp/src/sfntly/data/byte_array.cc
@@ -26,9 +26,6 @@
 
 ByteArray::~ByteArray() {}
 
-int32_t ByteArray::Length() { return filled_length_; }
-int32_t ByteArray::Size() { return storage_length_; }
-
 int32_t ByteArray::SetFilledLength(int32_t filled_length) {
   filled_length_ = std::min<int32_t>(filled_length, storage_length_);
   return filled_length_;
@@ -40,24 +37,27 @@
   return InternalGet(index) & 0xff;
 }
 
-int32_t ByteArray::Get(int32_t index, ByteVector* b) {
+int32_t ByteArray::Get(int32_t index, std::vector<uint8_t>* b) {
   assert(b);
   return Get(index, &((*b)[0]), 0, b->size());
 }
 
 int32_t ByteArray::Get(int32_t index,
-                       byte_t* b,
+                       uint8_t* b,
                        int32_t offset,
                        int32_t length) {
   assert(b);
-  if (index < 0 || index >= filled_length_) {
+  if (index < 0 || index >= filled_length_)
     return 0;
-  }
+
+  if (length <= 0)
+    return 0;
+
   int32_t actual_length = std::min<int32_t>(length, filled_length_ - index);
   return InternalGet(index, b, offset, actual_length);
 }
 
-void ByteArray::Put(int32_t index, byte_t b) {
+void ByteArray::Put(int32_t index, uint8_t b) {
   if (index < 0 || index >= Size()) {
 #if defined (SFNTLY_NO_EXCEPTION)
     return;
@@ -70,13 +70,13 @@
   filled_length_ = std::max<int32_t>(filled_length_, index + 1);
 }
 
-int32_t ByteArray::Put(int index, ByteVector* b) {
+int32_t ByteArray::Put(int index, std::vector<uint8_t>* b) {
   assert(b);
   return Put(index, &((*b)[0]), 0, b->size());
 }
 
 int32_t ByteArray::Put(int32_t index,
-                       byte_t* b,
+                       uint8_t* b,
                        int32_t offset,
                        int32_t length) {
   assert(b);
@@ -109,7 +109,7 @@
     return -1;
   }
 
-  ByteVector b(COPY_BUFFER_SIZE);
+  std::vector<uint8_t> b(COPY_BUFFER_SIZE);
   int32_t bytes_read = 0;
   int32_t index = 0;
   int32_t remaining_length = length;
@@ -130,7 +130,7 @@
 }
 
 int32_t ByteArray::CopyTo(OutputStream* os, int32_t offset, int32_t length) {
-  ByteVector b(COPY_BUFFER_SIZE);
+  std::vector<uint8_t> b(COPY_BUFFER_SIZE);
   int32_t bytes_read = 0;
   int32_t index = 0;
   int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
@@ -143,7 +143,7 @@
 }
 
 bool ByteArray::CopyFrom(InputStream* is, int32_t length) {
-  ByteVector b(COPY_BUFFER_SIZE);
+  std::vector<uint8_t> b(COPY_BUFFER_SIZE);
   int32_t bytes_read = 0;
   int32_t index = 0;
   int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
@@ -163,7 +163,7 @@
 }
 
 bool ByteArray::CopyFrom(InputStream* is) {
-  ByteVector b(COPY_BUFFER_SIZE);
+  std::vector<uint8_t> b(COPY_BUFFER_SIZE);
   int32_t bytes_read = 0;
   int32_t index = 0;
   int32_t buffer_length = COPY_BUFFER_SIZE;
diff --git a/cpp/src/sfntly/data/byte_array.h b/cpp/src/sfntly/data/byte_array.h
index 70dc92f..c5e3788 100644
--- a/cpp/src/sfntly/data/byte_array.h
+++ b/cpp/src/sfntly/data/byte_array.h
@@ -32,15 +32,15 @@
   virtual ~ByteArray();
 
   // Gets the current filled and readable length of the array.
-  int32_t Length();
+  int32_t Length() const { return filled_length_; }
 
   // Gets the maximum size of the array. This is the maximum number of bytes that
   // the array can hold and all of it may not be filled with data or even fully
   // allocated yet.
-  int32_t Size();
+  int32_t Size() const { return storage_length_; }
 
   // Determines whether or not this array is growable or of fixed size.
-  bool growable() { return growable_; }
+  bool growable() const { return growable_; }
 
   int32_t SetFilledLength(int32_t filled_length);
 
@@ -55,7 +55,7 @@
   // @param index the index into the byte array
   // @param b the buffer to put the bytes read into
   // @return the number of bytes read from the buffer
-  virtual int32_t Get(int32_t index, ByteVector* b);
+  virtual int32_t Get(int32_t index, std::vector<uint8_t>* b);
 
   // Gets the bytes from the given index and fill the buffer with them starting
   // at the offset given. As many bytes as the specified length are read unless
@@ -66,18 +66,18 @@
   // @param length the number of bytes to put into the buffer
   // @return the number of bytes read from the buffer
   virtual int32_t Get(int32_t index,
-                      byte_t* b,
+                      uint8_t* b,
                       int32_t offset,
                       int32_t length);
 
   // Puts the specified byte into the array at the given index unless that would
   // be beyond the length of the array and it isn't growable.
-  virtual void Put(int32_t index, byte_t b);
+  virtual void Put(int32_t index, uint8_t b);
 
   // Puts the specified bytes into the array at the given index. The entire
   // buffer is put into the array unless that would extend beyond the length and
   // the array isn't growable.
-  virtual int32_t Put(int32_t index, ByteVector* b);
+  virtual int32_t Put(int32_t index, std::vector<uint8_t>* b);
 
   // Puts the specified bytes into the array at the given index. All of the bytes
   // specified are put into the array unless that would extend beyond the length
@@ -89,7 +89,7 @@
   // @param length the number of bytes to copy into the array
   // @return the number of bytes actually written
   virtual int32_t Put(int32_t index,
-                      byte_t* b,
+                      uint8_t* b,
                       int32_t offset,
                       int32_t length);
 
@@ -149,7 +149,7 @@
   // Stores the byte at the index given.
   // @param index the location to store at
   // @param b the byte to store
-  virtual void InternalPut(int32_t index, byte_t b) = 0;
+  virtual void InternalPut(int32_t index, uint8_t b) = 0;
 
   // Stores the array of bytes at the given index.
   // @param index the location to store at
@@ -158,14 +158,14 @@
   // @param length the length of the byte array to store from the offset
   // @return the number of bytes actually stored
   virtual int32_t InternalPut(int32_t index,
-                              byte_t* b,
+                              uint8_t* b,
                               int32_t offset,
                               int32_t length) = 0;
 
   // Gets the byte at the index given.
   // @param index the location to get from
   // @return the byte stored at the index
-  virtual byte_t InternalGet(int32_t index) = 0;
+  virtual uint8_t InternalGet(int32_t index) = 0;
 
   // Gets the bytes at the index given of the given length.
   // @param index the location to start getting from
@@ -174,7 +174,7 @@
   // @param length the length of bytes to read
   // @return the number of bytes actually ready
   virtual int32_t InternalGet(int32_t index,
-                              byte_t* b,
+                              uint8_t* b,
                               int32_t offset,
                               int32_t length) = 0;
 
@@ -182,7 +182,7 @@
   virtual void Close() = 0;
 
   // C++ port only, raw pointer to the first element of storage.
-  virtual byte_t* Begin() = 0;
+  virtual uint8_t* Begin() = 0;
 
   // Java toString() not ported.
 
diff --git a/cpp/src/sfntly/data/font_data.cc b/cpp/src/sfntly/data/font_data.cc
index 95bee3e..8fa8610 100644
--- a/cpp/src/sfntly/data/font_data.cc
+++ b/cpp/src/sfntly/data/font_data.cc
@@ -81,11 +81,11 @@
   bound_length_ = GROWABLE_SIZE;
 }
 
-int32_t FontData::BoundOffset(int32_t offset) {
+int32_t FontData::BoundOffset(int32_t offset) const {
   return offset + bound_offset_;
 }
 
-int32_t FontData::BoundLength(int32_t offset, int32_t length) {
+int32_t FontData::BoundLength(int32_t offset, int32_t length) const {
   return std::min<int32_t>(length, bound_length_ - offset);
 }
 
diff --git a/cpp/src/sfntly/data/font_data.h b/cpp/src/sfntly/data/font_data.h
index e0e7e79..20c7e37 100644
--- a/cpp/src/sfntly/data/font_data.h
+++ b/cpp/src/sfntly/data/font_data.h
@@ -99,14 +99,14 @@
   // the data.
   // @param offset the offset to get the bound compensated offset for
   // @return the bound compensated offset
-  int32_t BoundOffset(int32_t offset);
+  int32_t BoundOffset(int32_t offset) const;
 
   // Gets the length in the underlying data taking into account any bounds on
   // the data.
   // @param offset the offset that the length is being used at
   // @param length the length to get the bound compensated length for
   // @return the bound compensated length
-  int32_t BoundLength(int32_t offset, int32_t length);
+  int32_t BoundLength(int32_t offset, int32_t length) const;
 
   static const int32_t GROWABLE_SIZE = INT_MAX;
 
diff --git a/cpp/src/sfntly/data/font_input_stream.cc b/cpp/src/sfntly/data/font_input_stream.cc
index dcf8be3..87a515b 100644
--- a/cpp/src/sfntly/data/font_input_stream.cc
+++ b/cpp/src/sfntly/data/font_input_stream.cc
@@ -32,10 +32,17 @@
   // Do not close here, underlying InputStream will close themselves.
 }
 
+int32_t FontInputStream::Length() {
+  if (bounded_)
+    return length_;
+  if (stream_)
+    return stream_->Length();
+  return 0;
+}
+
 int32_t FontInputStream::Available() {
-  if (stream_) {
+  if (stream_)
     return stream_->Available();
-  }
   return 0;
 }
 
@@ -75,7 +82,7 @@
   return b;
 }
 
-int32_t FontInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
+int32_t FontInputStream::Read(std::vector<uint8_t>* b, int32_t offset, int32_t length) {
   if (!stream_ || offset < 0 || length < 0 ||
       (bounded_ && position_ >= length_)) {
     return -1;
@@ -88,7 +95,7 @@
   return bytes_read;
 }
 
-int32_t FontInputStream::Read(ByteVector* b) {
+int32_t FontInputStream::Read(std::vector<uint8_t>* b) {
   return Read(b, 0, b->size());
 }
 
diff --git a/cpp/src/sfntly/data/font_input_stream.h b/cpp/src/sfntly/data/font_input_stream.h
index 9992b07..c02848d 100644
--- a/cpp/src/sfntly/data/font_input_stream.h
+++ b/cpp/src/sfntly/data/font_input_stream.h
@@ -59,7 +59,7 @@
 
   virtual ~FontInputStream();
 
-
+  virtual int32_t Length();
   virtual int32_t Available();
   virtual void Close();
   virtual void Mark(int32_t readlimit);
@@ -67,8 +67,8 @@
   virtual void Reset();
 
   virtual int32_t Read();
-  virtual int32_t Read(ByteVector* buffer);
-  virtual int32_t Read(ByteVector* buffer, int32_t offset, int32_t length);
+  virtual int32_t Read(std::vector<uint8_t>* buffer);
+  virtual int32_t Read(std::vector<uint8_t>* buffer, int32_t offset, int32_t length);
 
   // Get the current position in the stream in bytes.
   // @return the current position in bytes
diff --git a/cpp/src/sfntly/data/font_output_stream.cc b/cpp/src/sfntly/data/font_output_stream.cc
index 3422a22..169b02f 100644
--- a/cpp/src/sfntly/data/font_output_stream.cc
+++ b/cpp/src/sfntly/data/font_output_stream.cc
@@ -29,21 +29,21 @@
   // Do not close, underlying stream shall clean up themselves.
 }
 
-void FontOutputStream::Write(byte_t b) {
+void FontOutputStream::Write(uint8_t b) {
   if (stream_) {
     stream_->Write(b);
     position_++;
   }
 }
 
-void FontOutputStream::Write(ByteVector* b) {
+void FontOutputStream::Write(std::vector<uint8_t>* b) {
   if (b) {
     Write(b, 0, b->size());
     position_ += b->size();
   }
 }
 
-void FontOutputStream::Write(ByteVector* b, int32_t off, int32_t len) {
+void FontOutputStream::Write(std::vector<uint8_t>* b, int32_t off, int32_t len) {
   assert(b);
   assert(stream_);
   if (off < 0 || len < 0 || off + len < 0 ||
@@ -59,7 +59,7 @@
   position_ += len;
 }
 
-void FontOutputStream::Write(byte_t* b, int32_t off, int32_t len) {
+void FontOutputStream::Write(uint8_t* b, int32_t off, int32_t len) {
   assert(b);
   assert(stream_);
   if (off < 0 || len < 0 || off + len < 0) {
@@ -74,13 +74,13 @@
   position_ += len;
 }
 
-void FontOutputStream::WriteChar(byte_t c) {
+void FontOutputStream::WriteChar(uint8_t c) {
   Write(c);
 }
 
 void FontOutputStream::WriteUShort(int32_t us) {
-  Write((byte_t)((us >> 8) & 0xff));
-  Write((byte_t)(us & 0xff));
+  Write((uint8_t)((us >> 8) & 0xff));
+  Write((uint8_t)(us & 0xff));
 }
 
 void FontOutputStream::WriteShort(int32_t s) {
@@ -88,16 +88,16 @@
 }
 
 void FontOutputStream::WriteUInt24(int32_t ui) {
-  Write((byte_t)(ui >> 16) & 0xff);
-  Write((byte_t)(ui >> 8) & 0xff);
-  Write((byte_t)ui & 0xff);
+  Write((uint8_t)(ui >> 16) & 0xff);
+  Write((uint8_t)(ui >> 8) & 0xff);
+  Write((uint8_t)ui & 0xff);
 }
 
 void FontOutputStream::WriteULong(int64_t ul) {
-  Write((byte_t)((ul >> 24) & 0xff));
-  Write((byte_t)((ul >> 16) & 0xff));
-  Write((byte_t)((ul >> 8) & 0xff));
-  Write((byte_t)(ul & 0xff));
+  Write((uint8_t)((ul >> 24) & 0xff));
+  Write((uint8_t)((ul >> 16) & 0xff));
+  Write((uint8_t)((ul >> 8) & 0xff));
+  Write((uint8_t)(ul & 0xff));
 }
 
 void FontOutputStream::WriteLong(int64_t l) {
diff --git a/cpp/src/sfntly/data/font_output_stream.h b/cpp/src/sfntly/data/font_output_stream.h
index fcd48e8..fa4d346 100644
--- a/cpp/src/sfntly/data/font_output_stream.h
+++ b/cpp/src/sfntly/data/font_output_stream.h
@@ -48,13 +48,11 @@
   explicit FontOutputStream(OutputStream* os);
   virtual ~FontOutputStream();
 
-  virtual size_t position() { return position_; }
-
-  virtual void Write(byte_t b);
-  virtual void Write(ByteVector* b);
-  virtual void Write(ByteVector* b, int32_t off, int32_t len);
-  virtual void Write(byte_t* b, int32_t off, int32_t len);
-  virtual void WriteChar(byte_t c);
+  virtual void Write(uint8_t b);
+  virtual void Write(std::vector<uint8_t>* b);
+  virtual void Write(std::vector<uint8_t>* b, int32_t off, int32_t len);
+  virtual void Write(uint8_t* b, int32_t off, int32_t len);
+  virtual void WriteChar(uint8_t c);
   virtual void WriteUShort(int32_t us);
   virtual void WriteShort(int32_t s);
   virtual void WriteUInt24(int32_t ui);
diff --git a/cpp/src/sfntly/data/growable_memory_byte_array.cc b/cpp/src/sfntly/data/growable_memory_byte_array.cc
index c335614..b7b10fc 100644
--- a/cpp/src/sfntly/data/growable_memory_byte_array.cc
+++ b/cpp/src/sfntly/data/growable_memory_byte_array.cc
@@ -39,7 +39,7 @@
   return length;
 }
 
-void GrowableMemoryByteArray::InternalPut(int32_t index, byte_t b) {
+void GrowableMemoryByteArray::InternalPut(int32_t index, uint8_t b) {
   if ((size_t)index >= b_.size()) {
     b_.resize((size_t)(index + 1));
   }
@@ -47,7 +47,7 @@
 }
 
 int32_t GrowableMemoryByteArray::InternalPut(int32_t index,
-                                             byte_t* b,
+                                             uint8_t* b,
                                              int32_t offset,
                                              int32_t length) {
   if ((size_t)index + length >= b_.size()) {
@@ -59,12 +59,12 @@
   return length;
 }
 
-byte_t GrowableMemoryByteArray::InternalGet(int32_t index) {
+uint8_t GrowableMemoryByteArray::InternalGet(int32_t index) {
   return b_[index];
 }
 
 int32_t GrowableMemoryByteArray::InternalGet(int32_t index,
-                                             byte_t* b,
+                                             uint8_t* b,
                                              int32_t offset,
                                              int32_t length) {
   memcpy(b + offset, &(b_[0]) + index, length);
@@ -75,7 +75,7 @@
   b_.clear();
 }
 
-byte_t* GrowableMemoryByteArray::Begin() {
+uint8_t* GrowableMemoryByteArray::Begin() {
   return &(b_[0]);
 }
 
diff --git a/cpp/src/sfntly/data/growable_memory_byte_array.h b/cpp/src/sfntly/data/growable_memory_byte_array.h
index 8583a0d..370d2cb 100644
--- a/cpp/src/sfntly/data/growable_memory_byte_array.h
+++ b/cpp/src/sfntly/data/growable_memory_byte_array.h
@@ -44,21 +44,21 @@
   virtual int32_t CopyTo(OutputStream* os) { return ByteArray::CopyTo(os); }
 
  protected:
-  virtual void InternalPut(int32_t index, byte_t b);
+  virtual void InternalPut(int32_t index, uint8_t b);
   virtual int32_t InternalPut(int32_t index,
-                              byte_t* b,
+                              uint8_t* b,
                               int32_t offset,
                               int32_t length);
-  virtual byte_t InternalGet(int32_t index);
+  virtual uint8_t InternalGet(int32_t index);
   virtual int32_t InternalGet(int32_t index,
-                              byte_t* b,
+                              uint8_t* b,
                               int32_t offset,
                               int32_t length);
   virtual void Close();
-  virtual byte_t* Begin();
+  virtual uint8_t* Begin();
 
  private:
-  ByteVector b_;
+  std::vector<uint8_t> b_;
 };
 
 }  // namespace sfntly
diff --git a/cpp/src/sfntly/data/memory_byte_array.cc b/cpp/src/sfntly/data/memory_byte_array.cc
index d6c9c48..9a81cf6 100644
--- a/cpp/src/sfntly/data/memory_byte_array.cc
+++ b/cpp/src/sfntly/data/memory_byte_array.cc
@@ -24,7 +24,7 @@
     : ByteArray(0, length), b_(NULL), allocated_(true) {
 }
 
-MemoryByteArray::MemoryByteArray(byte_t* b, int32_t filled_length)
+MemoryByteArray::MemoryByteArray(uint8_t* b, int32_t filled_length)
     : ByteArray(filled_length, filled_length), b_(b), allocated_(false) {
   assert(b);
 }
@@ -43,18 +43,18 @@
 
 void MemoryByteArray::Init() {
   if (allocated_ && b_ == NULL) {
-    b_ = new byte_t[Size()];
+    b_ = new uint8_t[Size()];
     memset(b_, 0, Size());
   }
 }
 
-void MemoryByteArray::InternalPut(int32_t index, byte_t b) {
+void MemoryByteArray::InternalPut(int32_t index, uint8_t b) {
   Init();
   b_[index] = b;
 }
 
 int32_t MemoryByteArray::InternalPut(int32_t index,
-                                     byte_t* b,
+                                     uint8_t* b,
                                      int32_t offset,
                                      int32_t length) {
   assert(b);
@@ -63,13 +63,13 @@
   return length;
 }
 
-byte_t MemoryByteArray::InternalGet(int32_t index) {
+uint8_t MemoryByteArray::InternalGet(int32_t index) {
   Init();
   return b_[index];
 }
 
 int32_t MemoryByteArray::InternalGet(int32_t index,
-                                     byte_t* b,
+                                     uint8_t* b,
                                      int32_t offset,
                                      int32_t length) {
   assert(b);
@@ -85,7 +85,7 @@
   b_ = NULL;
 }
 
-byte_t* MemoryByteArray::Begin() {
+uint8_t* MemoryByteArray::Begin() {
   Init();
   return b_;
 }
diff --git a/cpp/src/sfntly/data/memory_byte_array.h b/cpp/src/sfntly/data/memory_byte_array.h
index 838fd1a..b84cc5a 100644
--- a/cpp/src/sfntly/data/memory_byte_array.h
+++ b/cpp/src/sfntly/data/memory_byte_array.h
@@ -28,7 +28,7 @@
   explicit MemoryByteArray(int32_t length);
 
   // Note: not implemented due to dangerous operations in constructor.
-  //explicit MemoryByteArray(ByteVector* b);
+  //explicit MemoryByteArray(std::vector<uint8_t>* b);
 
   // Construct a new MemoryByteArray using byte array.
   // @param b the byte array that provides the actual storage
@@ -37,7 +37,7 @@
   //       ownership of b.  Caller is responsible for handling the lifetime
   //       of b.  C++ port also assumes filled_length is buffer_length since
   //       there is not a reliable way to identify the actual size of buffer.
-  MemoryByteArray(byte_t* b, int32_t filled_length);
+  MemoryByteArray(uint8_t* b, int32_t filled_length);
 
   virtual ~MemoryByteArray();
   virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
@@ -56,23 +56,23 @@
   virtual int32_t CopyTo(OutputStream* os) { return ByteArray::CopyTo(os); }
 
  protected:
-  virtual void InternalPut(int32_t index, byte_t b);
+  virtual void InternalPut(int32_t index, uint8_t b);
   virtual int32_t InternalPut(int32_t index,
-                              byte_t* b,
+                              uint8_t* b,
                               int32_t offset,
                               int32_t length);
-  virtual byte_t InternalGet(int32_t index);
+  virtual uint8_t InternalGet(int32_t index);
   virtual int32_t InternalGet(int32_t index,
-                              byte_t* b,
+                              uint8_t* b,
                               int32_t offset,
                               int32_t length);
   virtual void Close();
-  virtual byte_t* Begin();
+  virtual uint8_t* Begin();
 
  private:
   void Init();  // C++ port only, used to allocate memory outside constructor.
 
-  byte_t* b_;
+  uint8_t* b_;
   bool allocated_;
 };
 
diff --git a/cpp/src/sfntly/data/readable_font_data.cc b/cpp/src/sfntly/data/readable_font_data.cc
index 07a0db6..b7c5332 100644
--- a/cpp/src/sfntly/data/readable_font_data.cc
+++ b/cpp/src/sfntly/data/readable_font_data.cc
@@ -38,7 +38,7 @@
 //                  not too useful without copying, but it's not performance
 //                  savvy to do copying.
 CALLER_ATTACH
-ReadableFontData* ReadableFontData::CreateReadableFontData(ByteVector* b) {
+ReadableFontData* ReadableFontData::CreateReadableFontData(std::vector<uint8_t>* b) {
   assert(b);
   ByteArrayPtr ba = new MemoryByteArray(b->size());
   ba->Put(0, b);
@@ -54,7 +54,7 @@
   return checksum_;
 }
 
-void ReadableFontData::SetCheckSumRanges(const IntegerList& ranges) {
+void ReadableFontData::SetCheckSumRanges(const std::vector<int32_t>& ranges) {
   checksum_range_ = ranges;
   checksum_set_ = false;  // UNIMPLEMENTED: atomicity
 }
@@ -84,7 +84,7 @@
 }
 
 int32_t ReadableFontData::ReadBytes(int32_t index,
-                                    byte_t* b,
+                                    uint8_t* b,
                                     int32_t offset,
                                     int32_t length) {
   return array_->Get(BoundOffset(index), b, offset, BoundLength(index, length));
@@ -192,13 +192,13 @@
 }
 
 int64_t ReadableFontData::ReadDateTimeAsLong(int32_t index) {
-  int32_t high = ReadULong(index);
+  int64_t high = ReadULong(index);
   if (high == kInvalidUnsigned)
     return kInvalidLongDateTime;
-  int32_t low = ReadULong(index + 4);
+  int64_t low = ReadULong(index + 4);
   if (low == kInvalidUnsigned)
     return kInvalidLongDateTime;
-  return (int64_t)high << 32 | low;
+  return high << 32 | low;
 }
 
 int32_t ReadableFontData::ReadFWord(int32_t index) {
diff --git a/cpp/src/sfntly/data/readable_font_data.h b/cpp/src/sfntly/data/readable_font_data.h
index 37a0918..db5e70c 100644
--- a/cpp/src/sfntly/data/readable_font_data.h
+++ b/cpp/src/sfntly/data/readable_font_data.h
@@ -57,7 +57,7 @@
   static const int32_t kInvalidUnsigned = -1;
   static const int64_t kInvalidLongDateTime = -1;
 
-  static CALLER_ATTACH ReadableFontData* CreateReadableFontData(ByteVector* b);
+  static CALLER_ATTACH ReadableFontData* CreateReadableFontData(std::vector<uint8_t>* b);
 
   // Gets a computed checksum for the data. This checksum uses the OpenType spec
   // calculation. Every ULong value (32 bit unsigned) in the data is summed and
@@ -72,7 +72,7 @@
   // assumed to extend to the end of the data. The lengths of each range must be
   // a multiple of 4.
   // @param ranges the range bounds to use for the checksum
-  void SetCheckSumRanges(const IntegerList& ranges);
+  void SetCheckSumRanges(const std::vector<int32_t>& ranges);
 
   // Read the UBYTE at the given index.
   // @param index index into the font data
@@ -94,7 +94,7 @@
   // @return the number of bytes actually read; -1 if the index is outside the
   //         bounds of the font data
   virtual int32_t ReadBytes(int32_t index,
-                            byte_t* b,
+                            uint8_t* b,
                             int32_t offset,
                             int32_t length);
 
@@ -306,7 +306,7 @@
   Lock checksum_lock_;
   bool checksum_set_;
   int64_t checksum_;
-  IntegerList checksum_range_;
+  std::vector<int32_t> checksum_range_;
 };
 typedef Ptr<ReadableFontData> ReadableFontDataPtr;
 
diff --git a/cpp/src/sfntly/data/writable_font_data.cc b/cpp/src/sfntly/data/writable_font_data.cc
index 073e9df..40c778e 100644
--- a/cpp/src/sfntly/data/writable_font_data.cc
+++ b/cpp/src/sfntly/data/writable_font_data.cc
@@ -47,20 +47,20 @@
 //                  not too useful without copying, but it's not performance
 //                  savvy to do copying.
 CALLER_ATTACH
-WritableFontData* WritableFontData::CreateWritableFontData(ByteVector* b) {
+WritableFontData* WritableFontData::CreateWritableFontData(std::vector<uint8_t>* b) {
   ByteArrayPtr ba = new GrowableMemoryByteArray();
   ba->Put(0, b);
   WritableFontDataPtr wfd = new WritableFontData(ba);
   return wfd.Detach();
 }
 
-int32_t WritableFontData::WriteByte(int32_t index, byte_t b) {
+int32_t WritableFontData::WriteByte(int32_t index, uint8_t b) {
   array_->Put(BoundOffset(index), b);
   return 1;
 }
 
 int32_t WritableFontData::WriteBytes(int32_t index,
-                                     byte_t* b,
+                                     uint8_t* b,
                                      int32_t offset,
                                      int32_t length) {
   return array_->Put(BoundOffset(index),
@@ -69,16 +69,16 @@
                      BoundLength(index, length));
 }
 
-int32_t WritableFontData::WriteBytes(int32_t index, ByteVector* b) {
+int32_t WritableFontData::WriteBytes(int32_t index, std::vector<uint8_t>* b) {
   assert(b);
   return WriteBytes(index, &((*b)[0]), 0, b->size());
 }
 
 int32_t WritableFontData::WriteBytesPad(int32_t index,
-                                        ByteVector* b,
+                                        std::vector<uint8_t>* b,
                                         int32_t offset,
                                         int32_t length,
-                                        byte_t pad) {
+                                        uint8_t pad) {
   int32_t written =
       array_->Put(BoundOffset(index),
                   &((*b)[0]),
@@ -90,30 +90,30 @@
 }
 
 int32_t WritableFontData::WritePadding(int32_t index, int32_t count) {
-  return WritePadding(index, count, (byte_t)0);
+  return WritePadding(index, count, (uint8_t)0);
 }
 
 int32_t WritableFontData::WritePadding(int32_t index, int32_t count,
-                                       byte_t pad) {
+                                       uint8_t pad) {
   for (int32_t i = 0; i < count; ++i) {
     array_->Put(index + i, pad);
   }
   return count;
 }
 
-int32_t WritableFontData::WriteChar(int32_t index, byte_t c) {
+int32_t WritableFontData::WriteChar(int32_t index, uint8_t c) {
   return WriteByte(index, c);
 }
 
 int32_t WritableFontData::WriteUShort(int32_t index, int32_t us) {
-  WriteByte(index, (byte_t)((us >> 8) & 0xff));
-  WriteByte(index + 1, (byte_t)(us & 0xff));
+  WriteByte(index, (uint8_t)((us >> 8) & 0xff));
+  WriteByte(index + 1, (uint8_t)(us & 0xff));
   return 2;
 }
 
 int32_t WritableFontData::WriteUShortLE(int32_t index, int32_t us) {
-  WriteByte(index, (byte_t)(us & 0xff));
-  WriteByte(index + 1, (byte_t)((us >> 8) & 0xff));
+  WriteByte(index, (uint8_t)(us & 0xff));
+  WriteByte(index + 1, (uint8_t)((us >> 8) & 0xff));
   return 2;
 }
 
@@ -122,25 +122,25 @@
 }
 
 int32_t WritableFontData::WriteUInt24(int32_t index, int32_t ui) {
-  WriteByte(index, (byte_t)((ui >> 16) & 0xff));
-  WriteByte(index + 1, (byte_t)((ui >> 8) & 0xff));
-  WriteByte(index + 2, (byte_t)(ui & 0xff));
+  WriteByte(index, (uint8_t)((ui >> 16) & 0xff));
+  WriteByte(index + 1, (uint8_t)((ui >> 8) & 0xff));
+  WriteByte(index + 2, (uint8_t)(ui & 0xff));
   return 3;
 }
 
 int32_t WritableFontData::WriteULong(int32_t index, int64_t ul) {
-  WriteByte(index, (byte_t)((ul >> 24) & 0xff));
-  WriteByte(index + 1, (byte_t)((ul >> 16) & 0xff));
-  WriteByte(index + 2, (byte_t)((ul >> 8) & 0xff));
-  WriteByte(index + 3, (byte_t)(ul & 0xff));
+  WriteByte(index, (uint8_t)((ul >> 24) & 0xff));
+  WriteByte(index + 1, (uint8_t)((ul >> 16) & 0xff));
+  WriteByte(index + 2, (uint8_t)((ul >> 8) & 0xff));
+  WriteByte(index + 3, (uint8_t)(ul & 0xff));
   return 4;
 }
 
 int32_t WritableFontData::WriteULongLE(int32_t index, int64_t ul) {
-  WriteByte(index, (byte_t)(ul & 0xff));
-  WriteByte(index + 1, (byte_t)((ul >> 8) & 0xff));
-  WriteByte(index + 2, (byte_t)((ul >> 16) & 0xff));
-  WriteByte(index + 3, (byte_t)((ul >> 24) & 0xff));
+  WriteByte(index, (uint8_t)(ul & 0xff));
+  WriteByte(index + 1, (uint8_t)((ul >> 8) & 0xff));
+  WriteByte(index + 2, (uint8_t)((ul >> 16) & 0xff));
+  WriteByte(index + 3, (uint8_t)((ul >> 24) & 0xff));
   return 4;
 }
 
diff --git a/cpp/src/sfntly/data/writable_font_data.h b/cpp/src/sfntly/data/writable_font_data.h
index d2a049e..61fc6a9 100644
--- a/cpp/src/sfntly/data/writable_font_data.h
+++ b/cpp/src/sfntly/data/writable_font_data.h
@@ -42,13 +42,13 @@
   // bytes.
   // @param b the byte vector to wrap
   // @return a new writable font data
-  static CALLER_ATTACH WritableFontData* CreateWritableFontData(ByteVector* b);
+  static CALLER_ATTACH WritableFontData* CreateWritableFontData(std::vector<uint8_t>* b);
 
   // Write a byte at the given index.
   // @param index index into the font data
   // @param b the byte to write
   // @return the number of bytes written
-  virtual int32_t WriteByte(int32_t index, byte_t b);
+  virtual int32_t WriteByte(int32_t index, uint8_t b);
 
   // Write the bytes from the array.
   // @param index index into the font data
@@ -58,7 +58,7 @@
   // @return the number of bytes actually written; -1 if the index is outside
   //         the FontData's range
   virtual int32_t WriteBytes(int32_t index,
-                             byte_t* b,
+                             uint8_t* b,
                              int32_t offset,
                              int32_t length);
 
@@ -67,7 +67,7 @@
   // @param b the source for the bytes to be written
   // @return the number of bytes actually written; -1 if the index is outside
   //         the FontData's range
-  virtual int32_t WriteBytes(int32_t index, ByteVector* b);
+  virtual int32_t WriteBytes(int32_t index, std::vector<uint8_t>* b);
 
   // Write the bytes from the array and pad if necessary.
   // Write to the length given using the byte array provided and if there are
@@ -80,10 +80,10 @@
   // @param pad the padding byte to be used if necessary
   // @return the number of bytes actually written
   virtual int32_t WriteBytesPad(int32_t index,
-                                ByteVector* b,
+                                std::vector<uint8_t>* b,
                                 int32_t offset,
                                 int32_t length,
-                                byte_t pad);
+                                uint8_t pad);
 
   // Writes padding to the FontData. The padding byte written is 0x00.
   // @param index index into the font data
@@ -96,14 +96,14 @@
   // @param count the number of pad bytes to write
   // @param pad the byte value to use as padding
   // @return the number of pad bytes written
-  virtual int32_t WritePadding(int32_t index, int32_t count, byte_t pad);
+  virtual int32_t WritePadding(int32_t index, int32_t count, uint8_t pad);
 
   // Write the CHAR at the given index.
   // @param index index into the font data
   // @param c the CHAR
   // @return the number of bytes actually written
   // @throws IndexOutOfBoundsException if index is outside the FontData's range
-  virtual int32_t WriteChar(int32_t index, byte_t c);
+  virtual int32_t WriteChar(int32_t index, uint8_t c);
 
   // Write the USHORT at the given index.
   // @param index index into the font data
diff --git a/cpp/src/sfntly/font.cc b/cpp/src/sfntly/font.cc
index ca35048..eec7bec 100644
--- a/cpp/src/sfntly/font.cc
+++ b/cpp/src/sfntly/font.cc
@@ -18,12 +18,13 @@
 
 #include <stdio.h>
 
-#include <functional>
 #include <algorithm>
+#include <functional>
+#include <iterator>
+#include <limits>
 #include <map>
 #include <string>
 #include <typeinfo>
-#include <iterator>
 
 #include "sfntly/data/font_input_stream.h"
 #include "sfntly/font_factory.h"
@@ -47,6 +48,12 @@
 
 const int32_t kMaxTableSize = 200 * 1024 * 1024;
 
+bool IsValidHeaderRegion(int32_t data_length, int32_t offset, int32_t length) {
+  return offset >= 0 && length >= 0 &&
+         offset <= std::numeric_limits<int32_t>::max() - length &&
+         offset + length <= data_length;
+}
+
 }  // namespace
 
 /******************************************************************************
@@ -68,9 +75,9 @@
   return &tables_;
 }
 
-void Font::Serialize(OutputStream* os, IntegerList* table_ordering) {
+void Font::Serialize(OutputStream* os, std::vector<int32_t>* table_ordering) {
   assert(table_ordering);
-  IntegerList final_table_ordering;
+  std::vector<int32_t> final_table_ordering;
   GenerateTableOrdering(table_ordering, &final_table_ordering);
   TableHeaderList table_records;
   BuildTableHeadersForSerialization(&final_table_ordering, &table_records);
@@ -80,36 +87,32 @@
   SerializeTables(&fos, &table_records);
 }
 
-Font::Font(int32_t sfnt_version, ByteVector* digest)
+Font::Font(int32_t sfnt_version, std::vector<uint8_t>* digest)
     : sfnt_version_(sfnt_version) {
   // non-trivial assignments that makes debugging hard if placed in
   // initialization list
   digest_ = *digest;
 }
 
-void Font::BuildTableHeadersForSerialization(IntegerList* table_ordering,
+void Font::BuildTableHeadersForSerialization(std::vector<int32_t>* table_ordering,
                                              TableHeaderList* table_headers) {
   assert(table_headers);
   assert(table_ordering);
 
-  IntegerList final_table_ordering;
+  std::vector<int32_t> final_table_ordering;
   GenerateTableOrdering(table_ordering, &final_table_ordering);
   int32_t table_offset = Offset::kTableRecordBegin + num_tables() *
                          Offset::kTableRecordSize;
-  for (IntegerList::iterator tag = final_table_ordering.begin(),
-                             tag_end = final_table_ordering.end();
-                             tag != tag_end; ++tag) {
-    if (tables_.find(*tag) == tables_.end()) {
+  for (size_t i = 0; i < final_table_ordering.size(); ++i) {
+    int32_t tag = final_table_ordering[i];
+    TablePtr table = GetTable(tag);
+    if (table == NULL)
       continue;
-    }
-    TablePtr table = tables_[*tag];
-    if (table != NULL) {
-      HeaderPtr header =
-          new Header(*tag, table->CalculatedChecksum(), table_offset,
-                     table->header()->length());
-      table_headers->push_back(header);
-      table_offset += (table->DataLength() + 3) & ~3;
-    }
+
+    HeaderPtr header = new Header(tag, table->CalculatedChecksum(),
+                                  table_offset, table->header()->length());
+    table_headers->push_back(header);
+    table_offset += (table->DataLength() + 3) & ~3;
   }
 }
 
@@ -142,10 +145,9 @@
                            TableHeaderList* table_headers) {
   assert(fos);
   assert(table_headers);
-  for (TableHeaderList::iterator record = table_headers->begin(),
-                                 end_of_headers = table_headers->end();
-                                 record != end_of_headers; ++record) {
-    TablePtr target_table = GetTable((*record)->tag());
+  for (size_t i = 0; i < table_headers->size(); ++i) {
+    const HeaderPtr& record = (*table_headers)[i];
+    TablePtr target_table = GetTable(record->tag());
     if (target_table == NULL) {
 #if !defined (SFNTLY_NO_EXCEPTION)
       throw IOException("Table out of sync with font header.");
@@ -153,18 +155,17 @@
       return;
     }
     int32_t table_size = target_table->Serialize(fos);
-    if (table_size != (*record)->length()) {
-      assert(false);
-    }
+    assert(table_size == record->length());
+
     int32_t filler_size = ((table_size + 3) & ~3) - table_size;
     for (int32_t i = 0; i < filler_size; ++i) {
-      fos->Write(static_cast<byte_t>(0));
+      fos->Write(static_cast<uint8_t>(0));
     }
   }
 }
 
-void Font::GenerateTableOrdering(IntegerList* default_table_ordering,
-                                 IntegerList* table_ordering) {
+void Font::GenerateTableOrdering(std::vector<int32_t>* default_table_ordering,
+                                 std::vector<int32_t>* table_ordering) {
   assert(default_table_ordering);
   assert(table_ordering);
   table_ordering->clear();
@@ -179,7 +180,7 @@
                           table != table_end; ++table) {
     tables_in_font.insert(Int2BoolEntry(table->first, false));
   }
-  for (IntegerList::iterator tag = default_table_ordering->begin(),
+  for (std::vector<int32_t>::iterator tag = default_table_ordering->begin(),
                              tag_end = default_table_ordering->end();
                              tag != tag_end; ++tag) {
     if (HasTable(*tag)) {
@@ -195,7 +196,7 @@
   }
 }
 
-void Font::DefaultTableOrdering(IntegerList* default_table_ordering) {
+void Font::DefaultTableOrdering(std::vector<int32_t>* default_table_ordering) {
   assert(default_table_ordering);
   default_table_ordering->clear();
   if (HasTable(Tag::CFF)) {
@@ -268,7 +269,7 @@
   return font.Detach();
 }
 
-void Font::Builder::SetDigest(ByteVector* digest) {
+void Font::Builder::SetDigest(std::vector<uint8_t>* digest) {
   digest_.clear();
   digest_ = *digest;
 }
@@ -440,7 +441,7 @@
     loca_table_builder = down_cast<LocaTable::Builder*>(raw_loca_builder);
   }
 
-  Table::Builder* raw_hmtx_builder = GetBuilder(builder_map, Tag::hmtx);
+  Table::Builder* raw_hmtx_builder = GetReadBuilder(builder_map, Tag::hmtx);
   HorizontalMetricsTableBuilderPtr horizontal_metrics_builder;
   if (raw_hmtx_builder != NULL) {
     horizontal_metrics_builder =
@@ -459,18 +460,22 @@
   // set the inter table data required to build certain tables
   if (horizontal_metrics_builder != NULL) {
     if (max_profile_builder != NULL) {
-      horizontal_metrics_builder->SetNumGlyphs(
-          max_profile_builder->NumGlyphs());
+      int32_t num_glyphs = max_profile_builder->NumGlyphs();
+      if (num_glyphs >= 0)
+        horizontal_metrics_builder->SetNumGlyphs(num_glyphs);
     }
     if (horizontal_header_builder != NULL) {
-      horizontal_metrics_builder->SetNumberOfHMetrics(
-          horizontal_header_builder->NumberOfHMetrics());
+      int32_t num_hmetrics = horizontal_header_builder->NumberOfHMetrics();
+      if (num_hmetrics >= 0)
+        horizontal_metrics_builder->SetNumberOfHMetrics(num_hmetrics);
     }
   }
 
   if (loca_table_builder != NULL) {
     if (max_profile_builder != NULL) {
-      loca_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs());
+      int32_t num_glyphs = max_profile_builder->NumGlyphs();
+      if (num_glyphs >= 0)
+        loca_table_builder->SetNumGlyphs(num_glyphs);
     }
     if (header_table_builder != NULL) {
       loca_table_builder->set_format_version(
@@ -502,6 +507,9 @@
     int64_t checksum = is->ReadULong();
     int32_t offset = is->ReadULongAsInt();
     int32_t length = is->ReadULongAsInt();
+    if (!IsValidHeaderRegion(is->Length(), offset, length))
+      continue;
+
     HeaderPtr table = new Header(tag, checksum, offset, length);
     records->insert(table);
   }
@@ -517,6 +525,9 @@
   entry_selector_ = fd->ReadUShort(offset + Offset::kEntrySelector);
   range_shift_ = fd->ReadUShort(offset + Offset::kRangeShift);
 
+  if (num_tables_ > fd->Size() / Offset::kTableRecordSize)
+    return;
+
   int32_t table_offset = offset + Offset::kTableRecordBegin;
   for (int32_t table_number = 0;
        table_number < num_tables_;
@@ -525,6 +536,9 @@
     int64_t checksum = fd->ReadULong(table_offset + Offset::kTableCheckSum);
     int32_t offset = fd->ReadULongAsInt(table_offset + Offset::kTableOffset);
     int32_t length = fd->ReadULongAsInt(table_offset + Offset::kTableLength);
+    if (!IsValidHeaderRegion(fd->Size(), offset, length))
+      continue;
+
     HeaderPtr table = new Header(tag, checksum, offset, length);
     records->insert(table);
   }
diff --git a/cpp/src/sfntly/font.h b/cpp/src/sfntly/font.h
index 2220adb..3187c11 100644
--- a/cpp/src/sfntly/font.h
+++ b/cpp/src/sfntly/font.h
@@ -149,7 +149,7 @@
     CALLER_ATTACH Font* Build();
 
     // Set a unique fingerprint for the font object.
-    void SetDigest(ByteVector* digest);
+    void SetDigest(std::vector<uint8_t>* digest);
 
     // Clear all table builders.
     void ClearTableBuilders();
@@ -226,7 +226,7 @@
     int32_t entry_selector_;
     int32_t range_shift_;
     DataBlockMap data_blocks_;
-    ByteVector digest_;
+    std::vector<uint8_t> digest_;
   };
 
   virtual ~Font();
@@ -236,7 +236,7 @@
 
   // Gets a copy of the fonts digest that was created when the font was read. If
   // no digest was set at creation time then the return result will be null.
-  ByteVector* digest() { return &digest_; }
+  std::vector<uint8_t>* digest() { return &digest_; }
 
   // Get the checksum for this font.
   int64_t checksum() { return checksum_; }
@@ -265,7 +265,7 @@
   // Serialize the font to the output stream.
   // @param os the destination for the font serialization
   // @param tableOrdering the table ordering to apply
-  void Serialize(OutputStream* os, IntegerList* table_ordering);
+  void Serialize(OutputStream* os, std::vector<int32_t>* table_ordering);
 
  private:
   // Offsets to specific elements in the underlying data. These offsets are
@@ -300,7 +300,7 @@
   // @param digest the computed digest for the font; null if digest was not
   //        computed
   // Note: Current C++ port does not support SHA digest validation.
-  Font(int32_t sfnt_version, ByteVector* digest);
+  Font(int32_t sfnt_version, std::vector<uint8_t>* digest);
 
   // Build the table headers to be used for serialization. These headers will be
   // filled out with the data required for serialization. The headers will be
@@ -309,7 +309,7 @@
   // @param tableOrdering the tables to generate headers for and the order to
   //        sort them
   // @return a list of table headers ready for serialization
-  void BuildTableHeadersForSerialization(IntegerList* table_ordering,
+  void BuildTableHeadersForSerialization(std::vector<int32_t>* table_ordering,
                                          TableHeaderList* table_headers);
 
   // Searialize the headers.
@@ -330,15 +330,15 @@
   // @param defaultTableOrdering the partial ordering to be used as a seed for
   //        the full ordering
   // @param (out) table_ordering the full ordering for serialization
-  void GenerateTableOrdering(IntegerList* default_table_ordering,
-                             IntegerList* table_ordering);
+  void GenerateTableOrdering(std::vector<int32_t>* default_table_ordering,
+                             std::vector<int32_t>* table_ordering);
 
   // Get the default table ordering based on the type of the font.
   // @param (out) default_table_ordering the default table ordering
-  void DefaultTableOrdering(IntegerList* default_table_ordering);
+  void DefaultTableOrdering(std::vector<int32_t>* default_table_ordering);
 
   int32_t sfnt_version_;
-  ByteVector digest_;
+  std::vector<uint8_t> digest_;
   int64_t checksum_;
   TableMap tables_;
 };
diff --git a/cpp/src/sfntly/font_factory.cc b/cpp/src/sfntly/font_factory.cc
index c162a77..bb1986f 100644
--- a/cpp/src/sfntly/font_factory.cc
+++ b/cpp/src/sfntly/font_factory.cc
@@ -52,7 +52,7 @@
   }
 }
 
-void FontFactory::LoadFonts(ByteVector* b, FontArray* output) {
+void FontFactory::LoadFonts(std::vector<uint8_t>* b, FontArray* output) {
   WritableFontDataPtr wfd;
   wfd.Attach(WritableFontData::CreateWritableFontData(b));
   if (IsCollection(wfd)) {
@@ -80,7 +80,7 @@
   }
 }
 
-void FontFactory::LoadFontsForBuilding(ByteVector* b,
+void FontFactory::LoadFontsForBuilding(std::vector<uint8_t>* b,
                                        FontBuilderArray* output) {
   WritableFontDataPtr wfd;
   wfd.Attach(WritableFontData::CreateWritableFontData(b));
@@ -96,12 +96,8 @@
 }
 
 void FontFactory::SerializeFont(Font* font, OutputStream* os) {
-  font->Serialize(os, &table_ordering_);
-}
-
-void FontFactory::SetSerializationTableOrdering(
-    const IntegerList& table_ordering) {
-  table_ordering_ = table_ordering;
+  std::vector<int32_t> table_ordering;
+  font->Serialize(os, &table_ordering);
 }
 
 CALLER_ATTACH Font::Builder* FontFactory::NewFontBuilder() {
@@ -180,6 +176,10 @@
   int32_t version = wfd->ReadFixed(Offset::kVersion);
   UNREFERENCED_PARAMETER(version);
   int32_t num_fonts = wfd->ReadULongAsInt(Offset::kNumFonts);
+  if (num_fonts < 0)
+    return;
+  if (num_fonts > wfd->Length() / 4)
+    return;
 
   builders->reserve(num_fonts);
   int32_t offset_table_offset = Offset::kOffsetTable;
@@ -187,6 +187,9 @@
                font_number < num_fonts;
                font_number++, offset_table_offset += DataSize::kULONG) {
     int32_t offset = wfd->ReadULongAsInt(offset_table_offset);
+    if (offset < 0 || offset >= wfd->Length())
+      continue;
+
     FontBuilderPtr builder;
     builder.Attach(LoadSingleOTFForBuilding(wfd, offset));
     builders->push_back(builder);
@@ -194,14 +197,14 @@
 }
 
 bool FontFactory::IsCollection(PushbackInputStream* pbis) {
-  ByteVector tag(4);
+  std::vector<uint8_t> tag(4);
   pbis->Read(&tag);
   pbis->Unread(&tag);
   return Tag::ttcf == GenerateTag(tag[0], tag[1], tag[2], tag[3]);
 }
 
 bool FontFactory::IsCollection(ReadableFontData* rfd) {
-  ByteVector tag(4);
+  std::vector<uint8_t> tag(4);
   rfd->ReadBytes(0, &(tag[0]), 0, tag.size());
   return Tag::ttcf ==
          GenerateTag(tag[0], tag[1], tag[2], tag[3]);
diff --git a/cpp/src/sfntly/font_factory.h b/cpp/src/sfntly/font_factory.h
index 63deff4..12e54a5 100644
--- a/cpp/src/sfntly/font_factory.h
+++ b/cpp/src/sfntly/font_factory.h
@@ -56,7 +56,7 @@
   // than one font and in this case multiple font objects will be returned. If
   // the data in the stream cannot be parsed or is invalid an array of size zero
   // will be returned.
-  void LoadFonts(ByteVector* b, FontArray* output);
+  void LoadFonts(std::vector<uint8_t>* b, FontArray* output);
 
   // Load the font(s) from the input stream into font builders. The current
   // settings on the factory are used during the loading process. One or more
@@ -72,7 +72,7 @@
   // font container formats may have more than one font and in this case
   // multiple font builder objects will be returned. If the data in the stream
   // cannot be parsed or is invalid an array of size zero will be returned.
-  void LoadFontsForBuilding(ByteVector* b, FontBuilderArray* output);
+  void LoadFontsForBuilding(std::vector<uint8_t>* b, FontBuilderArray* output);
 
   // Font serialization
   // Serialize the font to the output stream.
@@ -81,12 +81,6 @@
   //       Byte buffer it is.
   void SerializeFont(Font* font, OutputStream* os);
 
-  // Set the table ordering to be used in serializing a font. The table ordering
-  // is an ordered list of table ids and tables will be serialized in the order
-  // given. Any tables whose id is not listed in the ordering will be placed in
-  // an unspecified order following those listed.
-  void SetSerializationTableOrdering(const IntegerList& table_ordering);
-
   // Get an empty font builder for creating a new font from scratch.
   CALLER_ATTACH Font::Builder* NewFontBuilder();
 
@@ -131,7 +125,6 @@
   static bool IsCollection(ReadableFontData* wfd);
 
   bool fingerprint_;
-  IntegerList table_ordering_;
 };
 typedef Ptr<FontFactory> FontFactoryPtr;
 
diff --git a/cpp/src/sfntly/port/file_input_stream.cc b/cpp/src/sfntly/port/file_input_stream.cc
index 883c1fd..87b7c8c 100644
--- a/cpp/src/sfntly/port/file_input_stream.cc
+++ b/cpp/src/sfntly/port/file_input_stream.cc
@@ -35,6 +35,10 @@
   Close();
 }
 
+int32_t FileInputStream::Length() {
+  return length_;
+}
+
 int32_t FileInputStream::Available() {
   return length_ - position_;
 }
@@ -70,17 +74,17 @@
 #endif
     return 0;
   }
-  byte_t value = 0;
+  uint8_t value = 0;
   size_t length = fread(&value, 1, 1, file_);
   position_ += length;
   return value;
 }
 
-int32_t FileInputStream::Read(ByteVector* b) {
+int32_t FileInputStream::Read(std::vector<uint8_t>* b) {
   return Read(b, 0, b->size());
 }
 
-int32_t FileInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
+int32_t FileInputStream::Read(std::vector<uint8_t>* b, int32_t offset, int32_t length) {
   assert(b);
   if (!file_) {
 #if !defined (SFNTLY_NO_EXCEPTION)
@@ -127,11 +131,11 @@
   return skip_count;
 }
 
-void FileInputStream::Unread(ByteVector* b) {
+void FileInputStream::Unread(std::vector<uint8_t>* b) {
   Unread(b, 0, b->size());
 }
 
-void FileInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) {
+void FileInputStream::Unread(std::vector<uint8_t>* b, int32_t offset, int32_t length) {
   assert(b);
   assert(b->size() >= size_t(offset + length));
   if (!file_) {
diff --git a/cpp/src/sfntly/port/file_input_stream.h b/cpp/src/sfntly/port/file_input_stream.h
index cbca25f..1128444 100644
--- a/cpp/src/sfntly/port/file_input_stream.h
+++ b/cpp/src/sfntly/port/file_input_stream.h
@@ -29,19 +29,20 @@
   virtual ~FileInputStream();
 
   // InputStream methods
+  virtual int32_t Length();
   virtual int32_t Available();
   virtual void Close();
   virtual void Mark(int32_t readlimit);
   virtual bool MarkSupported();
   virtual int32_t Read();
-  virtual int32_t Read(ByteVector* b);
-  virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length);
+  virtual int32_t Read(std::vector<uint8_t>* b);
+  virtual int32_t Read(std::vector<uint8_t>* b, int32_t offset, int32_t length);
   virtual void Reset();
   virtual int64_t Skip(int64_t n);
 
   // PushbackInputStream methods
-  virtual void Unread(ByteVector* b);
-  virtual void Unread(ByteVector* b, int32_t offset, int32_t length);
+  virtual void Unread(std::vector<uint8_t>* b);
+  virtual void Unread(std::vector<uint8_t>* b, int32_t offset, int32_t length);
 
   // Own methods
   virtual bool Open(const char* file_path);
diff --git a/cpp/src/sfntly/port/input_stream.h b/cpp/src/sfntly/port/input_stream.h
index 5d24036..a403c11 100644
--- a/cpp/src/sfntly/port/input_stream.h
+++ b/cpp/src/sfntly/port/input_stream.h
@@ -24,24 +24,25 @@
 // C++ equivalent to Java's OutputStream class
 class InputStream {
  public:
-  // Make gcc -Wnon-virtual-dtor happy.
-  virtual ~InputStream() {}
-
+  virtual int32_t Length() = 0;
   virtual int32_t Available() = 0;
   virtual void Close() = 0;
   virtual void Mark(int32_t readlimit) = 0;
   virtual bool MarkSupported() = 0;
   virtual int32_t Read() = 0;
-  virtual int32_t Read(ByteVector* b) = 0;
-  virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length) = 0;
+  virtual int32_t Read(std::vector<uint8_t>* b) = 0;
+  virtual int32_t Read(std::vector<uint8_t>* b, int32_t offset, int32_t length) = 0;
   virtual void Reset() = 0;
   virtual int64_t Skip(int64_t n) = 0;
+
+ protected:
+  virtual ~InputStream() {}
 };
 
 class PushbackInputStream : public InputStream {
  public:
-  virtual void Unread(ByteVector* b) = 0;
-  virtual void Unread(ByteVector* b, int32_t offset, int32_t length) = 0;
+  virtual void Unread(std::vector<uint8_t>* b) = 0;
+  virtual void Unread(std::vector<uint8_t>* b, int32_t offset, int32_t length) = 0;
 };
 
 }  // namespace sfntly
diff --git a/cpp/src/sfntly/port/memory_input_stream.cc b/cpp/src/sfntly/port/memory_input_stream.cc
index f6f2b9b..73f03f5 100755
--- a/cpp/src/sfntly/port/memory_input_stream.cc
+++ b/cpp/src/sfntly/port/memory_input_stream.cc
@@ -37,6 +37,10 @@
   Close();
 }
 
+int32_t MemoryInputStream::Length() {
+  return length_;
+}
+
 int32_t MemoryInputStream::Available() {
   return length_ - position_;
 }
@@ -66,15 +70,15 @@
 #endif
     return 0;
   }
-  byte_t value = buffer_[position_++];
+  uint8_t value = buffer_[position_++];
   return value;
 }
 
-int32_t MemoryInputStream::Read(ByteVector* b) {
+int32_t MemoryInputStream::Read(std::vector<uint8_t>* b) {
   return Read(b, 0, b->size());
 }
 
-int32_t MemoryInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
+int32_t MemoryInputStream::Read(std::vector<uint8_t>* b, int32_t offset, int32_t length) {
   assert(b);
   if (!buffer_) {
 #if !defined (SFNTLY_NO_EXCEPTION)
@@ -119,11 +123,11 @@
   return skip_count;
 }
 
-void MemoryInputStream::Unread(ByteVector* b) {
+void MemoryInputStream::Unread(std::vector<uint8_t>* b) {
   Unread(b, 0, b->size());
 }
 
-void MemoryInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) {
+void MemoryInputStream::Unread(std::vector<uint8_t>* b, int32_t offset, int32_t length) {
   assert(b);
   assert(b->size() >= size_t(offset + length));
   if (!buffer_) {
@@ -138,7 +142,7 @@
   position_ -= unread_count;
 }
 
-bool MemoryInputStream::Attach(const byte_t* buffer, size_t length) {
+bool MemoryInputStream::Attach(const uint8_t* buffer, size_t length) {
   assert(buffer);
   assert(length);
   buffer_ = buffer;
diff --git a/cpp/src/sfntly/port/memory_input_stream.h b/cpp/src/sfntly/port/memory_input_stream.h
index bc861c3..2478893 100755
--- a/cpp/src/sfntly/port/memory_input_stream.h
+++ b/cpp/src/sfntly/port/memory_input_stream.h
@@ -29,25 +29,26 @@
   virtual ~MemoryInputStream();
 
   // InputStream methods
+  virtual int32_t Length();
   virtual int32_t Available();
   virtual void Close();
   virtual void Mark(int32_t readlimit);
   virtual bool MarkSupported();
   virtual int32_t Read();
-  virtual int32_t Read(ByteVector* b);
-  virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length);
+  virtual int32_t Read(std::vector<uint8_t>* b);
+  virtual int32_t Read(std::vector<uint8_t>* b, int32_t offset, int32_t length);
   virtual void Reset();
   virtual int64_t Skip(int64_t n);
 
   // PushbackInputStream methods
-  virtual void Unread(ByteVector* b);
-  virtual void Unread(ByteVector* b, int32_t offset, int32_t length);
+  virtual void Unread(std::vector<uint8_t>* b);
+  virtual void Unread(std::vector<uint8_t>* b, int32_t offset, int32_t length);
 
   // Own methods
-  virtual bool Attach(const byte_t* buffer, size_t length);
+  virtual bool Attach(const uint8_t* buffer, size_t length);
 
  private:
-  const byte_t* buffer_;
+  const uint8_t* buffer_;
   size_t position_;
   size_t length_;
 };
diff --git a/cpp/src/sfntly/port/memory_output_stream.cc b/cpp/src/sfntly/port/memory_output_stream.cc
index f2ff2e3..f071c97 100644
--- a/cpp/src/sfntly/port/memory_output_stream.cc
+++ b/cpp/src/sfntly/port/memory_output_stream.cc
@@ -24,11 +24,11 @@
 MemoryOutputStream::~MemoryOutputStream() {
 }
 
-void MemoryOutputStream::Write(ByteVector* buffer) {
+void MemoryOutputStream::Write(std::vector<uint8_t>* buffer) {
   store_.insert(store_.end(), buffer->begin(), buffer->end());
 }
 
-void MemoryOutputStream::Write(ByteVector* buffer,
+void MemoryOutputStream::Write(std::vector<uint8_t>* buffer,
                                int32_t offset,
                                int32_t length) {
   assert(buffer);
@@ -43,7 +43,7 @@
   }
 }
 
-void MemoryOutputStream::Write(byte_t* buffer, int32_t offset, int32_t length) {
+void MemoryOutputStream::Write(uint8_t* buffer, int32_t offset, int32_t length) {
   assert(buffer);
   if (offset >= 0 && length > 0) {
     store_.insert(store_.end(), buffer + offset, buffer + offset + length);
@@ -54,11 +54,11 @@
   }
 }
 
-void MemoryOutputStream::Write(byte_t b) {
+void MemoryOutputStream::Write(uint8_t b) {
   store_.push_back(b);
 }
 
-byte_t* MemoryOutputStream::Get() {
+uint8_t* MemoryOutputStream::Get() {
   if (store_.empty()) {
     return NULL;
   }
diff --git a/cpp/src/sfntly/port/memory_output_stream.h b/cpp/src/sfntly/port/memory_output_stream.h
index d1eda7f..586c9d9 100644
--- a/cpp/src/sfntly/port/memory_output_stream.h
+++ b/cpp/src/sfntly/port/memory_output_stream.h
@@ -34,16 +34,16 @@
 
   virtual void Close() {}  // no-op
   virtual void Flush() {}  // no-op
-  virtual void Write(ByteVector* buffer);
-  virtual void Write(ByteVector* buffer, int32_t offset, int32_t length);
-  virtual void Write(byte_t* buffer, int32_t offset, int32_t length);
-  virtual void Write(byte_t b);
+  virtual void Write(std::vector<uint8_t>* buffer);
+  virtual void Write(std::vector<uint8_t>* buffer, int32_t offset, int32_t length);
+  virtual void Write(uint8_t* buffer, int32_t offset, int32_t length);
+  virtual void Write(uint8_t b);
 
-  byte_t* Get();
+  uint8_t* Get();
   size_t Size();
 
  private:
-  std::vector<byte_t> store_;
+  std::vector<uint8_t> store_;
 };
 
 }  // namespace sfntly
diff --git a/cpp/src/sfntly/port/output_stream.h b/cpp/src/sfntly/port/output_stream.h
index 64a6024..8dd2e5c 100644
--- a/cpp/src/sfntly/port/output_stream.h
+++ b/cpp/src/sfntly/port/output_stream.h
@@ -29,16 +29,16 @@
 
   virtual void Close() = 0;
   virtual void Flush() = 0;
-  virtual void Write(ByteVector* buffer) = 0;
-  virtual void Write(byte_t b) = 0;
+  virtual void Write(std::vector<uint8_t>* buffer) = 0;
+  virtual void Write(uint8_t b) = 0;
 
   // Note: C++ port offered both versions of Write() here.  The first one is
   //       better because it does check bounds.  The second one is there for
   //       performance concerns.
-  virtual void Write(ByteVector* buffer, int32_t offset, int32_t length) = 0;
+  virtual void Write(std::vector<uint8_t>* buffer, int32_t offset, int32_t length) = 0;
 
   // Note: Caller is responsible for the boundary of buffer.
-  virtual void Write(byte_t* buffer, int32_t offset, int32_t length) = 0;
+  virtual void Write(uint8_t* buffer, int32_t offset, int32_t length) = 0;
 };
 
 }  // namespace sfntly
diff --git a/cpp/src/sfntly/port/refcount.h b/cpp/src/sfntly/port/refcount.h
index 6353b08..d083c73 100644
--- a/cpp/src/sfntly/port/refcount.h
+++ b/cpp/src/sfntly/port/refcount.h
@@ -97,6 +97,8 @@
   #pragma warning(disable:4250)
 #endif
 
+bool TestSmartPointer();
+
 namespace sfntly {
 
 template <typename T>
@@ -157,6 +159,7 @@
   }
 
   mutable size_t ref_count_;  // reference count of current object
+  friend bool ::TestSmartPointer();
 #if defined (ENABLE_OBJECT_COUNTER)
   static size_t object_counter_;
   static size_t next_id_;
diff --git a/cpp/src/sfntly/port/type.h b/cpp/src/sfntly/port/type.h
index 9f82a5a..cb8c1ea 100644
--- a/cpp/src/sfntly/port/type.h
+++ b/cpp/src/sfntly/port/type.h
@@ -17,42 +17,21 @@
 #ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_TYPE_H_
 #define SFNTLY_CPP_SRC_SFNTLY_PORT_TYPE_H_
 
-#include <assert.h>
+#include <stdint.h>
 
-#if defined (_MSC_VER) && (_MSC_VER < 1600)
-  typedef unsigned char     uint8_t;
-  typedef signed char       int8_t;
-  typedef unsigned __int16  uint16_t;
-  typedef signed __int16    int16_t;
-  typedef unsigned __int32  uint32_t;
-  typedef signed __int32    int32_t;
-  typedef unsigned __int64  uint64_t;
-  typedef signed __int64    int64_t;
-  // Definitions to avoid ICU redefinition issue
-  #define U_HAVE_INT8_T 1
-  #define U_HAVE_UINT8_T 1
-  #define U_HAVE_INT16_T 1
-  #define U_HAVE_UINT16_T 1
-  #define U_HAVE_INT32_T 1
-  #define U_HAVE_UINT32_T 1
-  #define U_HAVE_INT64_T 1
-  #define U_HAVE_UINT64_T 1
-#else
-  #include <stdint.h>
-#endif
-
-#include <stddef.h>
-#include <vector>
+#include <cassert>
+#include <cstddef>
 #include <set>
+#include <vector>
 
 namespace sfntly {
 
+// deprecated
 typedef uint8_t   byte_t;
 typedef uint16_t  word_t;
 typedef uint32_t  dword_t;
 typedef uint64_t  qword_t;
-
-typedef std::vector<byte_t> ByteVector;
+typedef std::vector<uint8_t> ByteVector;
 typedef std::vector<int32_t> IntegerList;
 typedef std::set<int32_t> IntegerSet;
 
diff --git a/cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc b/cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc
index d853212..041366f 100644
--- a/cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc
+++ b/cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc
@@ -77,7 +77,7 @@
   return InternalReadData()->ReadByte(Offset::kHeight);
 }
 
-void BigGlyphMetrics::Builder::SetHeight(byte_t height) {
+void BigGlyphMetrics::Builder::SetHeight(uint8_t height) {
   InternalWriteData()->WriteByte(Offset::kHeight, height);
 }
 
@@ -85,7 +85,7 @@
   return InternalReadData()->ReadByte(Offset::kWidth);
 }
 
-void BigGlyphMetrics::Builder::SetWidth(byte_t width) {
+void BigGlyphMetrics::Builder::SetWidth(uint8_t width) {
   InternalWriteData()->WriteByte(Offset::kWidth, width);
 }
 
@@ -93,7 +93,7 @@
   return InternalReadData()->ReadByte(Offset::kHoriBearingX);
 }
 
-void BigGlyphMetrics::Builder::SetHoriBearingX(byte_t bearing) {
+void BigGlyphMetrics::Builder::SetHoriBearingX(uint8_t bearing) {
   InternalWriteData()->WriteByte(Offset::kHoriBearingX, bearing);
 }
 
@@ -101,7 +101,7 @@
   return InternalReadData()->ReadByte(Offset::kHoriBearingY);
 }
 
-void BigGlyphMetrics::Builder::SetHoriBearingY(byte_t bearing) {
+void BigGlyphMetrics::Builder::SetHoriBearingY(uint8_t bearing) {
   InternalWriteData()->WriteByte(Offset::kHoriBearingY, bearing);
 }
 
@@ -109,7 +109,7 @@
   return InternalReadData()->ReadByte(Offset::kHoriAdvance);
 }
 
-void BigGlyphMetrics::Builder::SetHoriAdvance(byte_t advance) {
+void BigGlyphMetrics::Builder::SetHoriAdvance(uint8_t advance) {
   InternalWriteData()->WriteByte(Offset::kHoriAdvance, advance);
 }
 
@@ -117,7 +117,7 @@
   return InternalReadData()->ReadByte(Offset::kVertBearingX);
 }
 
-void BigGlyphMetrics::Builder::SetVertBearingX(byte_t bearing) {
+void BigGlyphMetrics::Builder::SetVertBearingX(uint8_t bearing) {
   InternalWriteData()->WriteByte(Offset::kVertBearingX, bearing);
 }
 
@@ -125,7 +125,7 @@
   return InternalReadData()->ReadByte(Offset::kVertBearingY);
 }
 
-void BigGlyphMetrics::Builder::SetVertBearingY(byte_t bearing) {
+void BigGlyphMetrics::Builder::SetVertBearingY(uint8_t bearing) {
   InternalWriteData()->WriteByte(Offset::kVertBearingY, bearing);
 }
 
@@ -133,7 +133,7 @@
   return InternalReadData()->ReadByte(Offset::kVertAdvance);
 }
 
-void BigGlyphMetrics::Builder::SetVertAdvance(byte_t advance) {
+void BigGlyphMetrics::Builder::SetVertAdvance(uint8_t advance) {
   InternalWriteData()->WriteByte(Offset::kVertAdvance, advance);
 }
 
diff --git a/cpp/src/sfntly/table/bitmap/big_glyph_metrics.h b/cpp/src/sfntly/table/bitmap/big_glyph_metrics.h
index a91601c..84783c2 100644
--- a/cpp/src/sfntly/table/bitmap/big_glyph_metrics.h
+++ b/cpp/src/sfntly/table/bitmap/big_glyph_metrics.h
@@ -50,21 +50,21 @@
     virtual ~Builder();
 
     int32_t Height();
-    void SetHeight(byte_t height);
+    void SetHeight(uint8_t height);
     int32_t Width();
-    void SetWidth(byte_t width);
+    void SetWidth(uint8_t width);
     int32_t HoriBearingX();
-    void SetHoriBearingX(byte_t bearing);
+    void SetHoriBearingX(uint8_t bearing);
     int32_t HoriBearingY();
-    void SetHoriBearingY(byte_t bearing);
+    void SetHoriBearingY(uint8_t bearing);
     int32_t HoriAdvance();
-    void SetHoriAdvance(byte_t advance);
+    void SetHoriAdvance(uint8_t advance);
     int32_t VertBearingX();
-    void SetVertBearingX(byte_t bearing);
+    void SetVertBearingX(uint8_t bearing);
     int32_t VertBearingY();
-    void SetVertBearingY(byte_t bearing);
+    void SetVertBearingY(uint8_t bearing);
     int32_t VertAdvance();
-    void SetVertAdvance(byte_t advance);
+    void SetVertAdvance(uint8_t advance);
 
     virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
     virtual void SubDataSet();
diff --git a/cpp/src/sfntly/table/bitmap/eblc_table.cc b/cpp/src/sfntly/table/bitmap/eblc_table.cc
index 0ad2764..d0700d9 100644
--- a/cpp/src/sfntly/table/bitmap/eblc_table.cc
+++ b/cpp/src/sfntly/table/bitmap/eblc_table.cc
@@ -294,19 +294,23 @@
 void EblcTable::Builder::Initialize(ReadableFontData* data,
                                     BitmapSizeTableBuilderList* output) {
   assert(output);
-  if (data) {
-    int32_t num_sizes = data->ReadULongAsInt(Offset::kNumSizes);
-    for (int32_t i = 0; i < num_sizes; ++i) {
-      ReadableFontDataPtr new_data;
-      new_data.Attach(down_cast<ReadableFontData*>(
-          data->Slice(Offset::kBitmapSizeTableArrayStart +
-                      i * Offset::kBitmapSizeTableLength,
-                      Offset::kBitmapSizeTableLength)));
-      BitmapSizeTableBuilderPtr size_builder;
-      size_builder.Attach(BitmapSizeTable::Builder::CreateBuilder(
-          new_data, data));
-      output->push_back(size_builder);
-    }
+  if (!data)
+    return;
+
+  int32_t num_sizes = data->ReadULongAsInt(Offset::kNumSizes);
+  if (num_sizes > data->Size() / Offset::kBitmapSizeTableLength)
+    return;
+
+  for (int32_t i = 0; i < num_sizes; ++i) {
+    ReadableFontDataPtr new_data;
+    new_data.Attach(down_cast<ReadableFontData*>(
+        data->Slice(Offset::kBitmapSizeTableArrayStart +
+                    i * Offset::kBitmapSizeTableLength,
+                    Offset::kBitmapSizeTableLength)));
+    BitmapSizeTableBuilderPtr size_builder;
+    size_builder.Attach(BitmapSizeTable::Builder::CreateBuilder(
+        new_data, data));
+    output->push_back(size_builder);
   }
 }
 
diff --git a/cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc b/cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc
index 5199e18..42d21ab 100644
--- a/cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc
+++ b/cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc
@@ -82,7 +82,7 @@
   if (loca == -1) {
     return 0;
   }
-  IntegerList* offset_array = GetOffsetArray();
+  std::vector<int32_t>* offset_array = GetOffsetArray();
   return offset_array->at(loca + 1) - offset_array->at(loca);
 }
 
@@ -193,7 +193,7 @@
         EblcTable::Offset::kIndexSubTable1_offsetArray)));
     size += source->CopyTo(target);
   } else {
-    for (IntegerList::iterator b = GetOffsetArray()->begin(),
+    for (std::vector<int32_t>::iterator b = GetOffsetArray()->begin(),
                                e = GetOffsetArray()->end(); b != e; b++) {
       size += new_data->WriteLong(size, *b);
     }
@@ -201,12 +201,12 @@
   return size;
 }
 
-IntegerList* IndexSubTableFormat1::Builder::OffsetArray() {
+std::vector<int32_t>* IndexSubTableFormat1::Builder::OffsetArray() {
   return GetOffsetArray();
 }
 
 void IndexSubTableFormat1::Builder::SetOffsetArray(
-    const IntegerList& offset_array) {
+    const std::vector<int32_t>& offset_array) {
   offset_array_.clear();
   offset_array_ = offset_array;
   set_model_changed();
@@ -234,7 +234,7 @@
     : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
 }
 
-IntegerList* IndexSubTableFormat1::Builder::GetOffsetArray() {
+std::vector<int32_t>* IndexSubTableFormat1::Builder::GetOffsetArray() {
   if (offset_array_.empty()) {
     Initialize(InternalReadData());
     set_model_changed();
diff --git a/cpp/src/sfntly/table/bitmap/index_sub_table_format1.h b/cpp/src/sfntly/table/bitmap/index_sub_table_format1.h
index 33171c1..58a6ce7 100644
--- a/cpp/src/sfntly/table/bitmap/index_sub_table_format1.h
+++ b/cpp/src/sfntly/table/bitmap/index_sub_table_format1.h
@@ -53,8 +53,8 @@
     virtual bool SubReadyToSerialize();
     virtual int32_t SubSerialize(WritableFontData* new_data);
 
-    IntegerList* OffsetArray();
-    void SetOffsetArray(const IntegerList& offset_array);
+    std::vector<int32_t>* OffsetArray();
+    void SetOffsetArray(const std::vector<int32_t>& offset_array);
     CALLER_ATTACH BitmapGlyphInfoIter* Iterator();
 
     static CALLER_ATTACH Builder* CreateBuilder();
@@ -78,7 +78,7 @@
     Builder(ReadableFontData* data,
             int32_t first_glyph_index,
             int32_t last_glyph_index);
-    IntegerList* GetOffsetArray();
+    std::vector<int32_t>* GetOffsetArray();
     void Initialize(ReadableFontData* data);
 
     static int32_t DataLength(ReadableFontData* data,
@@ -86,7 +86,7 @@
                               int32_t first_glyph_index,
                               int32_t last_glyph_index);
 
-    IntegerList offset_array_;
+    std::vector<int32_t> offset_array_;
   };
 
   virtual ~IndexSubTableFormat1();
diff --git a/cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc b/cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc
index e2679b7..abd5517 100644
--- a/cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc
+++ b/cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc
@@ -91,7 +91,7 @@
   if (loca == -1) {
     return 0;
   }
-  IntegerList* offset_array = GetOffsetArray();
+  std::vector<int32_t>* offset_array = GetOffsetArray();
   return offset_array->at(loca + 1) - offset_array->at(loca);
 }
 
@@ -108,7 +108,7 @@
 }
 
 void IndexSubTableFormat3::Builder::SetOffsetArray(
-    const IntegerList& offset_array) {
+    const std::vector<int32_t>& offset_array) {
   offset_array_.clear();
   offset_array_ = offset_array;
   set_model_changed();
@@ -205,7 +205,7 @@
         EblcTable::Offset::kIndexSubTable3_offsetArray)));
     size += source->CopyTo(target);
   } else {
-    for (IntegerList::iterator b = GetOffsetArray()->begin(),
+    for (std::vector<int32_t>::iterator b = GetOffsetArray()->begin(),
                                e = GetOffsetArray()->end(); b != e; b++) {
       size += new_data->WriteUShort(size, *b);
     }
@@ -230,7 +230,7 @@
     : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
 }
 
-IntegerList* IndexSubTableFormat3::Builder::GetOffsetArray() {
+std::vector<int32_t>* IndexSubTableFormat3::Builder::GetOffsetArray() {
   if (offset_array_.empty()) {
     Initialize(InternalReadData());
     set_model_changed();
diff --git a/cpp/src/sfntly/table/bitmap/index_sub_table_format3.h b/cpp/src/sfntly/table/bitmap/index_sub_table_format3.h
index d71f857..1f2f0aa 100644
--- a/cpp/src/sfntly/table/bitmap/index_sub_table_format3.h
+++ b/cpp/src/sfntly/table/bitmap/index_sub_table_format3.h
@@ -52,7 +52,7 @@
     virtual bool SubReadyToSerialize();
     virtual int32_t SubSerialize(WritableFontData* new_data);
 
-    void SetOffsetArray(const IntegerList& offset_array);
+    void SetOffsetArray(const std::vector<int32_t>& offset_array);
 
     static CALLER_ATTACH Builder* CreateBuilder();
     static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
@@ -75,7 +75,7 @@
     Builder(ReadableFontData* data,
             int32_t first_glyph_index,
             int32_t last_glyph_index);
-    IntegerList* GetOffsetArray();
+    std::vector<int32_t>* GetOffsetArray();
     void Initialize(ReadableFontData* data);
 
     static int32_t DataLength(ReadableFontData* data,
@@ -83,7 +83,7 @@
                               int32_t first_glyph_index,
                               int32_t last_glyph_index);
 
-    IntegerList offset_array_;
+    std::vector<int32_t> offset_array_;
   };
 
   virtual ~IndexSubTableFormat3();
diff --git a/cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc b/cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc
index 0ca21fe..b1f773a 100644
--- a/cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc
+++ b/cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc
@@ -104,8 +104,8 @@
   if (check == -1) {
     return -1;
   }
-  IntegerList* glyph_array = GetGlyphArray();
-  IntegerList::iterator it = std::find(glyph_array->begin(),
+  std::vector<int32_t>* glyph_array = GetGlyphArray();
+  std::vector<int32_t>::iterator it = std::find(glyph_array->begin(),
                                        glyph_array->end(),
                                        glyph_id);
   if (it == glyph_array->end()) {
@@ -215,7 +215,7 @@
     slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
     size += BigMetrics()->SubSerialize(slice);
     size += new_data->WriteULong(size, glyph_array_.size());
-    for (IntegerList::iterator b = glyph_array_.begin(), e = glyph_array_.end();
+    for (std::vector<int32_t>::iterator b = glyph_array_.begin(), e = glyph_array_.end();
                                b != e; b++) {
       size += new_data->WriteUShort(size, *b);
     }
@@ -245,11 +245,11 @@
   return metrics_;
 }
 
-IntegerList* IndexSubTableFormat5::Builder::GlyphArray() {
+std::vector<int32_t>* IndexSubTableFormat5::Builder::GlyphArray() {
   return GetGlyphArray();
 }
 
-void IndexSubTableFormat5::Builder::SetGlyphArray(const IntegerList& v) {
+void IndexSubTableFormat5::Builder::SetGlyphArray(const std::vector<int32_t>& v) {
   glyph_array_.clear();
   glyph_array_ = v;
   set_model_changed();
@@ -277,7 +277,7 @@
     : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
 }
 
-IntegerList* IndexSubTableFormat5::Builder::GetGlyphArray() {
+std::vector<int32_t>* IndexSubTableFormat5::Builder::GetGlyphArray() {
   if (glyph_array_.empty()) {
     Initialize(InternalReadData());
     set_model_changed();
diff --git a/cpp/src/sfntly/table/bitmap/index_sub_table_format5.h b/cpp/src/sfntly/table/bitmap/index_sub_table_format5.h
index a39e88c..b6534e7 100644
--- a/cpp/src/sfntly/table/bitmap/index_sub_table_format5.h
+++ b/cpp/src/sfntly/table/bitmap/index_sub_table_format5.h
@@ -55,8 +55,8 @@
     int32_t ImageSize();
     void SetImageSize(int32_t image_size);
     BigGlyphMetrics::Builder* BigMetrics();
-    IntegerList* GlyphArray();
-    void SetGlyphArray(const IntegerList& v);
+    std::vector<int32_t>* GlyphArray();
+    void SetGlyphArray(const std::vector<int32_t>& v);
 
     static CALLER_ATTACH Builder* CreateBuilder();
     static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
@@ -79,7 +79,7 @@
             int32_t first_glyph_index,
             int32_t last_glyph_index);
 
-    IntegerList* GetGlyphArray();
+    std::vector<int32_t>* GetGlyphArray();
     void Initialize(ReadableFontData* data);
 
     static int32_t DataLength(ReadableFontData* data,
@@ -87,7 +87,7 @@
                               int32_t first_glyph_index,
                               int32_t last_glyph_index);
 
-    IntegerList glyph_array_;
+    std::vector<int32_t> glyph_array_;
     BigGlyphMetricsBuilderPtr metrics_;
   };
   virtual ~IndexSubTableFormat5();
diff --git a/cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc b/cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc
index 0f3c1e9..24ff624 100644
--- a/cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc
+++ b/cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc
@@ -65,7 +65,7 @@
   return InternalReadData()->ReadByte(Offset::kHeight);
 }
 
-void SmallGlyphMetrics::Builder::SetHeight(byte_t height) {
+void SmallGlyphMetrics::Builder::SetHeight(uint8_t height) {
   InternalWriteData()->WriteByte(Offset::kHeight, height);
 }
 
@@ -73,7 +73,7 @@
   return InternalReadData()->ReadByte(Offset::kWidth);
 }
 
-void SmallGlyphMetrics::Builder::SetWidth(byte_t width) {
+void SmallGlyphMetrics::Builder::SetWidth(uint8_t width) {
   InternalWriteData()->WriteByte(Offset::kWidth, width);
 }
 
@@ -81,7 +81,7 @@
   return InternalReadData()->ReadByte(Offset::kBearingX);
 }
 
-void SmallGlyphMetrics::Builder::SetBearingX(byte_t bearing) {
+void SmallGlyphMetrics::Builder::SetBearingX(uint8_t bearing) {
   InternalWriteData()->WriteByte(Offset::kBearingX, bearing);
 }
 
@@ -89,7 +89,7 @@
   return InternalReadData()->ReadByte(Offset::kBearingY);
 }
 
-void SmallGlyphMetrics::Builder::SetBearingY(byte_t bearing) {
+void SmallGlyphMetrics::Builder::SetBearingY(uint8_t bearing) {
   InternalWriteData()->WriteByte(Offset::kBearingY, bearing);
 }
 
@@ -97,7 +97,7 @@
   return InternalReadData()->ReadByte(Offset::kAdvance);
 }
 
-void SmallGlyphMetrics::Builder::SetAdvance(byte_t advance) {
+void SmallGlyphMetrics::Builder::SetAdvance(uint8_t advance) {
   InternalWriteData()->WriteByte(Offset::kAdvance, advance);
 }
 
diff --git a/cpp/src/sfntly/table/bitmap/small_glyph_metrics.h b/cpp/src/sfntly/table/bitmap/small_glyph_metrics.h
index ea13720..57cc06e 100644
--- a/cpp/src/sfntly/table/bitmap/small_glyph_metrics.h
+++ b/cpp/src/sfntly/table/bitmap/small_glyph_metrics.h
@@ -46,15 +46,15 @@
     virtual ~Builder();
 
     int32_t Height();
-    void SetHeight(byte_t height);
+    void SetHeight(uint8_t height);
     int32_t Width();
-    void SetWidth(byte_t width);
+    void SetWidth(uint8_t width);
     int32_t BearingX();
-    void SetBearingX(byte_t bearing);
+    void SetBearingX(uint8_t bearing);
     int32_t BearingY();
-    void SetBearingY(byte_t bearing);
+    void SetBearingY(uint8_t bearing);
     int32_t Advance();
-    void SetAdvance(byte_t advance);
+    void SetAdvance(uint8_t advance);
 
     virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
     virtual void SubDataSet();
diff --git a/cpp/src/sfntly/table/byte_array_table_builder.cc b/cpp/src/sfntly/table/byte_array_table_builder.cc
index 631a05f..2fc982f 100644
--- a/cpp/src/sfntly/table/byte_array_table_builder.cc
+++ b/cpp/src/sfntly/table/byte_array_table_builder.cc
@@ -31,7 +31,7 @@
   return data->ReadByte(index);
 }
 
-void ByteArrayTableBuilder::SetByteValue(int32_t index, byte_t b) {
+void ByteArrayTableBuilder::SetByteValue(int32_t index, uint8_t b) {
   WritableFontDataPtr data = InternalWriteData();
   if (data == NULL) {
 #if !defined (SFNTLY_NO_EXCEPTION)
diff --git a/cpp/src/sfntly/table/byte_array_table_builder.h b/cpp/src/sfntly/table/byte_array_table_builder.h
index 42d27a8..a3df0f8 100644
--- a/cpp/src/sfntly/table/byte_array_table_builder.h
+++ b/cpp/src/sfntly/table/byte_array_table_builder.h
@@ -36,7 +36,7 @@
   // start of the table.
   // @param index index relative to the start of the table
   // @param b byte value to set
-  virtual void SetByteValue(int32_t index, byte_t b);
+  virtual void SetByteValue(int32_t index, uint8_t b);
 
   // Get the number of bytes set for this table. It may include padding bytes at
   // the end.
diff --git a/cpp/src/sfntly/table/core/cmap_table.cc b/cpp/src/sfntly/table/core/cmap_table.cc
index 1c83d2e..1f1668e 100644
--- a/cpp/src/sfntly/table/core/cmap_table.cc
+++ b/cpp/src/sfntly/table/core/cmap_table.cc
@@ -469,8 +469,8 @@
   }
 
   uint32_t c = ToBE32(character);
-  byte_t high_byte = (c >> 8) & 0xff;
-  byte_t low_byte = c & 0xff;
+  uint8_t high_byte = (c >> 8) & 0xff;
+  uint8_t low_byte = c & 0xff;
   int32_t offset = SubHeaderOffset(high_byte);
 
   if (offset == 0) {
@@ -956,7 +956,7 @@
 }
 
 CMapTable::CMapFormat4::Builder::Builder(SegmentList* segments,
-                                         IntegerList* glyph_id_array,
+                                         std::vector<int32_t>* glyph_id_array,
                                          const CMapId& cmap_id)
     : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL),
                     CMapFormat::kFormat4, cmap_id),
@@ -1016,7 +1016,7 @@
   set_model_changed();
 }
 
-IntegerList* CMapTable::CMapFormat4::Builder::glyph_id_array() {
+std::vector<int32_t>* CMapTable::CMapFormat4::Builder::glyph_id_array() {
   if (glyph_id_array_.empty()) {
     Initialize(InternalReadData());
     set_model_changed();
@@ -1025,7 +1025,7 @@
 }
 
 void CMapTable::CMapFormat4::Builder::
-set_glyph_id_array(IntegerList* glyph_id_array) {
+set_glyph_id_array(std::vector<int32_t>* glyph_id_array) {
   glyph_id_array_.assign(glyph_id_array->begin(), glyph_id_array->end());
   set_model_changed();
 }
diff --git a/cpp/src/sfntly/table/core/cmap_table.h b/cpp/src/sfntly/table/core/cmap_table.h
index b264b07..81f0a5d 100644
--- a/cpp/src/sfntly/table/core/cmap_table.h
+++ b/cpp/src/sfntly/table/core/cmap_table.h
@@ -374,13 +374,13 @@
       virtual ~Builder();
       SegmentList* segments();
       void set_segments(SegmentList* segments);
-      IntegerList* glyph_id_array();
-      void set_glyph_id_array(IntegerList* glyph_id_array);
+      std::vector<int32_t>* glyph_id_array();
+      void set_glyph_id_array(std::vector<int32_t>* glyph_id_array);
 
      protected:
       Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id);
       Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id);
-      Builder(SegmentList* segments, IntegerList* glyph_id_array,
+      Builder(SegmentList* segments, std::vector<int32_t>* glyph_id_array,
               const CMapId& cmap_id);
       explicit Builder(const CMapId& cmap_id);
 
@@ -395,7 +395,7 @@
       void Initialize(ReadableFontData* data);
 
       SegmentList segments_;
-      IntegerList glyph_id_array_;
+      std::vector<int32_t> glyph_id_array_;
     };
 
     CMap::CharacterIterator* Iterator();
diff --git a/cpp/src/sfntly/table/core/font_header_table.cc b/cpp/src/sfntly/table/core/font_header_table.cc
index a848afd..e089c7e 100644
--- a/cpp/src/sfntly/table/core/font_header_table.cc
+++ b/cpp/src/sfntly/table/core/font_header_table.cc
@@ -92,7 +92,7 @@
 
 FontHeaderTable::FontHeaderTable(Header* header, ReadableFontData* data)
     : Table(header, data) {
-  IntegerList checksum_ranges;
+  std::vector<int32_t> checksum_ranges;
   checksum_ranges.push_back(0);
   checksum_ranges.push_back(Offset::kCheckSumAdjustment);
   checksum_ranges.push_back(Offset::kMagicNumber);
diff --git a/cpp/src/sfntly/table/core/name_table.cc b/cpp/src/sfntly/table/core/name_table.cc
index 4eb54ad..0e1fff9 100644
--- a/cpp/src/sfntly/table/core/name_table.cc
+++ b/cpp/src/sfntly/table/core/name_table.cc
@@ -78,7 +78,7 @@
 }
 
 NameTable::NameEntry::NameEntry(const NameEntryId& name_entry_id,
-                                const ByteVector& name_bytes) {
+                                const std::vector<uint8_t>& name_bytes) {
   Init(name_entry_id.platform_id(),
        name_entry_id.encoding_id(),
        name_entry_id.language_id(),
@@ -90,13 +90,13 @@
                                 int32_t encoding_id,
                                 int32_t language_id,
                                 int32_t name_id,
-                                const ByteVector& name_bytes) {
+                                const std::vector<uint8_t>& name_bytes) {
   Init(platform_id, encoding_id, language_id, name_id, &name_bytes);
 }
 
 NameTable::NameEntry::~NameEntry() {}
 
-ByteVector* NameTable::NameEntry::NameAsBytes() {
+std::vector<uint8_t>* NameTable::NameEntry::NameAsBytes() {
   return &name_bytes_;
 }
 
@@ -119,7 +119,7 @@
                                 int32_t encoding_id,
                                 int32_t language_id,
                                 int32_t name_id,
-                                const ByteVector* name_bytes) {
+                                const std::vector<uint8_t>* name_bytes) {
   name_entry_id_ = NameEntryId(platform_id, encoding_id, language_id, name_id);
   if (name_bytes) {
     name_bytes_ = *name_bytes;
@@ -136,7 +136,7 @@
 }
 
 NameTable::NameEntryBuilder::NameEntryBuilder(const NameEntryId& name_entry_id,
-                                              const ByteVector& name_bytes) {
+                                              const std::vector<uint8_t>& name_bytes) {
   Init(name_entry_id.platform_id(),
        name_entry_id.encoding_id(),
        name_entry_id.language_id(),
@@ -174,14 +174,14 @@
                                 &name_entry_->name_bytes_);
 }
 
-void NameTable::NameEntryBuilder::SetName(const ByteVector& name_bytes) {
+void NameTable::NameEntryBuilder::SetName(const std::vector<uint8_t>& name_bytes) {
   name_entry_->name_bytes_.clear();
   std::copy(name_bytes.begin(),
             name_bytes.end(),
             name_entry_->name_bytes_.begin());
 }
 
-void NameTable::NameEntryBuilder::SetName(const ByteVector& name_bytes,
+void NameTable::NameEntryBuilder::SetName(const std::vector<uint8_t>& name_bytes,
                                           int32_t offset,
                                           int32_t length) {
   name_entry_->name_bytes_.clear();
@@ -194,7 +194,7 @@
                                        int32_t encoding_id,
                                        int32_t language_id,
                                        int32_t name_id,
-                                       const ByteVector* name_bytes) {
+                                       const std::vector<uint8_t>* name_bytes) {
   name_entry_ = new NameEntry();
   name_entry_->Init(platform_id, encoding_id, language_id, name_id, name_bytes);
 }
@@ -465,7 +465,7 @@
                            OffsetForNameRecord(index));
 }
 
-void NameTable::NameAsBytes(int32_t index, ByteVector* b) {
+void NameTable::NameAsBytes(int32_t index, std::vector<uint8_t>* b) {
   assert(b);
   b->clear();
 
@@ -473,26 +473,30 @@
   if (length <= 0)
     return;
 
+  int32_t offset = NameOffset(index);
+  if (offset < 0)
+    return;
+
   b->resize(length);
-  data_->ReadBytes(NameOffset(index), &((*b)[0]), 0, length);
+  data_->ReadBytes(offset, &((*b)[0]), 0, length);
 }
 
 void NameTable::NameAsBytes(int32_t platform_id,
                             int32_t encoding_id,
                             int32_t language_id,
                             int32_t name_id,
-                            ByteVector* b) {
+                            std::vector<uint8_t>* b) {
   assert(b);
   NameEntryPtr entry;
   entry.Attach(GetNameEntry(platform_id, encoding_id, language_id, name_id));
   if (entry) {
-    ByteVector* name = entry->NameAsBytes();
+    std::vector<uint8_t>* name = entry->NameAsBytes();
     std::copy(name->begin(), name->end(), b->begin());
   }
 }
 
 UChar* NameTable::Name(int32_t index) {
-  ByteVector b;
+  std::vector<uint8_t> b;
   NameAsBytes(index, &b);
   return ConvertFromNameBytes(&b, PlatformId(index), EncodingId(index));
 }
@@ -510,7 +514,7 @@
 }
 
 CALLER_ATTACH NameTable::NameEntry* NameTable::GetNameEntry(int32_t index) {
-  ByteVector b;
+  std::vector<uint8_t> b;
   NameAsBytes(index, &b);
   NameEntryPtr instance = new NameEntry(PlatformId(index),
                                         EncodingId(index),
@@ -646,7 +650,7 @@
 void NameTable::ConvertToNameBytes(const UChar* name,
                                    int32_t platform_id,
                                    int32_t encoding_id,
-                                   ByteVector* b) {
+                                   std::vector<uint8_t>* b) {
   assert(b);
   assert(name);
   b->clear();
@@ -673,7 +677,7 @@
   ucnv_close(cs);
 }
 
-UChar* NameTable::ConvertFromNameBytes(ByteVector* name_bytes,
+UChar* NameTable::ConvertFromNameBytes(std::vector<uint8_t>* name_bytes,
                                        int32_t platform_id,
                                        int32_t encoding_id) {
   if (name_bytes == NULL || name_bytes->size() == 0) {
diff --git a/cpp/src/sfntly/table/core/name_table.h b/cpp/src/sfntly/table/core/name_table.h
index 4eaafbb..ac109df 100644
--- a/cpp/src/sfntly/table/core/name_table.h
+++ b/cpp/src/sfntly/table/core/name_table.h
@@ -446,12 +446,12 @@
   class NameEntry : public RefCounted<NameEntry> {
    public:
     NameEntry();
-    NameEntry(const NameEntryId& name_entry_id, const ByteVector& name_bytes);
+    NameEntry(const NameEntryId& name_entry_id, const std::vector<uint8_t>& name_bytes);
     NameEntry(int32_t platform_id,
               int32_t encoding_id,
               int32_t language_id,
               int32_t name_id,
-              const ByteVector& name_bytes);
+              const std::vector<uint8_t>& name_bytes);
     virtual ~NameEntry();
 
     NameEntryId& name_entry_id() { return name_entry_id_; }
@@ -462,7 +462,7 @@
 
     // Get the bytes for name.  Returned pointer is the address of private
     // member of this class, do not attempt to delete.
-    ByteVector* NameAsBytes();
+    std::vector<uint8_t>* NameAsBytes();
 
     // C++ port only: get the length of NameAsBytes.
     int32_t NameBytesLength();
@@ -477,10 +477,10 @@
 
    private:
     void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id,
-              int32_t name_id, const ByteVector* name_bytes);
+              int32_t name_id, const std::vector<uint8_t>* name_bytes);
 
     NameEntryId name_entry_id_;
-    ByteVector name_bytes_;
+    std::vector<uint8_t> name_bytes_;
 
     friend class NameEntryBuilder;
   };
@@ -492,14 +492,14 @@
    public:
     NameEntryBuilder();
     NameEntryBuilder(const NameEntryId& name_entry_id,
-                     const ByteVector& name_bytes);
+                     const std::vector<uint8_t>& name_bytes);
     explicit NameEntryBuilder(const NameEntryId& name_entry_id);
     explicit NameEntryBuilder(NameEntry* entry);
     virtual ~NameEntryBuilder();
 
     virtual void SetName(const UChar* name);
-    virtual void SetName(const ByteVector& name_bytes);
-    virtual void SetName(const ByteVector& name_bytes,
+    virtual void SetName(const std::vector<uint8_t>& name_bytes);
+    virtual void SetName(const std::vector<uint8_t>& name_bytes,
                          int32_t offset,
                          int32_t length);
 
@@ -510,7 +510,7 @@
 
    private:
     void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id,
-              int32_t name_id, const ByteVector* name_bytes);
+              int32_t name_id, const std::vector<uint8_t>* name_bytes);
 
     Ptr<NameEntry> name_entry_;
   };
@@ -647,10 +647,10 @@
 
   // Get the name as bytes for the specified name. If there is no entry for the
   // requested name, then empty vector is returned.
-  virtual void NameAsBytes(int32_t index, ByteVector* b);
+  virtual void NameAsBytes(int32_t index, std::vector<uint8_t>* b);
   virtual void NameAsBytes(int32_t platform_id, int32_t encoding_id,
                            int32_t language_id, int32_t name_id,
-                           ByteVector* b);
+                           std::vector<uint8_t>* b);
 
   // Get the name as a UChar* for the given name record. If there is no
   // encoding conversion available for the name record then a best attempt
@@ -724,13 +724,13 @@
   // Note: ICU UConverter* convention requires caller to ucnv_close() it.
   static UConverter* GetCharset(int32_t platform_id, int32_t encoding_id);
 
-  // Note: Output will be stored in ByteVector* b.  Original data in b will be
+  // Note: Output will be stored in std::vector<uint8_t>* b.  Original data in b will be
   // erased and replaced with converted name bytes.
   static void ConvertToNameBytes(const UChar* name, int32_t platform_id,
-                                 int32_t encoding_id, ByteVector* b);
+                                 int32_t encoding_id, std::vector<uint8_t>* b);
 
   // Note: ICU UChar* convention requires caller to delete[] it.
-  static UChar* ConvertFromNameBytes(ByteVector* name_bytes,
+  static UChar* ConvertFromNameBytes(std::vector<uint8_t>* name_bytes,
                                      int32_t platform_id, int32_t encoding_id);
 };  // class NameTable
 typedef Ptr<NameTable> NameTablePtr;
diff --git a/cpp/src/sfntly/table/core/os2_table.cc b/cpp/src/sfntly/table/core/os2_table.cc
index 1fef309..0d37db1 100644
--- a/cpp/src/sfntly/table/core/os2_table.cc
+++ b/cpp/src/sfntly/table/core/os2_table.cc
@@ -166,7 +166,7 @@
   return data_->ReadShort(Offset::kSFamilyClass);
 }
 
-void OS2Table::Panose(ByteVector* value) {
+void OS2Table::Panose(std::vector<uint8_t>* value) {
   assert(value);
   value->clear();
   value->resize(10);
@@ -189,7 +189,7 @@
   return data_->ReadULong(Offset::kUlUnicodeRange4);
 }
 
-void OS2Table::AchVendId(ByteVector* b) {
+void OS2Table::AchVendId(std::vector<uint8_t>* b) {
   assert(b);
   b->clear();
   b->resize(4);
@@ -415,7 +415,7 @@
   InternalWriteData()->WriteShort(Offset::kSFamilyClass, family);
 }
 
-void OS2Table::Builder::Panose(ByteVector* value) {
+void OS2Table::Builder::Panose(std::vector<uint8_t>* value) {
   assert(value);
   value->clear();
   value->resize(Offset::kPanoseLength);
@@ -425,7 +425,7 @@
                                 Offset::kPanoseLength);
 }
 
-void OS2Table::Builder::SetPanose(ByteVector* panose) {
+void OS2Table::Builder::SetPanose(std::vector<uint8_t>* panose) {
   assert(panose);
   if (panose->size() != Offset::kPanoseLength) {
 #if !defined (SFNTLY_NO_EXCEPTION)
@@ -468,14 +468,14 @@
   InternalWriteData()->WriteULong(Offset::kUlUnicodeRange4, range);
 }
 
-void OS2Table::Builder::AchVendId(ByteVector* b) {
+void OS2Table::Builder::AchVendId(std::vector<uint8_t>* b) {
   assert(b);
   b->clear();
   b->resize(4);
   InternalReadData()->ReadBytes(Offset::kAchVendId, &((*b)[0]), 0, 4);
 }
 
-void OS2Table::Builder::SetAchVendId(ByteVector* b) {
+void OS2Table::Builder::SetAchVendId(std::vector<uint8_t>* b) {
   assert(b);
   assert(b->size());
   InternalWriteData()->WriteBytesPad(Offset::kAchVendId,
@@ -484,7 +484,7 @@
                                      std::min<size_t>(
                                          (size_t)Offset::kAchVendIdLength,
                                          b->size()),
-                                     static_cast<byte_t>(' '));
+                                     static_cast<uint8_t>(' '));
 }
 
 int32_t OS2Table::Builder::FsSelection() {
diff --git a/cpp/src/sfntly/table/core/os2_table.h b/cpp/src/sfntly/table/core/os2_table.h
index 00d26d2..6057412 100644
--- a/cpp/src/sfntly/table/core/os2_table.h
+++ b/cpp/src/sfntly/table/core/os2_table.h
@@ -357,8 +357,8 @@
     void SetYStrikeoutPosition(int32_t position);
     int32_t SFamilyClass();
     void SetSFamilyClass(int32_t family);
-    void Panose(ByteVector* value);
-    void SetPanose(ByteVector* panose);
+    void Panose(std::vector<uint8_t>* value);
+    void SetPanose(std::vector<uint8_t>* panose);
     int64_t UlUnicodeRange1();
     void SetUlUnicodeRange1(int64_t range);
     int64_t UlUnicodeRange2();
@@ -369,12 +369,12 @@
     void SetUlUnicodeRange4(int64_t range);
     // UNIMPLEMENTED: EnumSet<UnicodeRange> UlUnicodeRange()
     //                setUlUnicodeRange(EnumSet<UnicodeRange> rangeSet)
-    void AchVendId(ByteVector* b);
+    void AchVendId(std::vector<uint8_t>* b);
     // This field is 4 bytes in length and only the first 4 bytes of the byte
     // array will be written. If the byte array is less than 4 bytes it will be
     // padded out with space characters (0x20).
     // @param b ach Vendor Id
-    void SetAchVendId(ByteVector* b);
+    void SetAchVendId(std::vector<uint8_t>* b);
     // UNIMPLEMENTED: public EnumSet<FsSelection> fsSelection()
     int32_t FsSelection();
     void SetFsSelection(int32_t fs_selection);
@@ -429,13 +429,13 @@
   int32_t YStrikeoutSize();
   int32_t YStrikeoutPosition();
   int32_t SFamilyClass();
-  void Panose(ByteVector* value);
+  void Panose(std::vector<uint8_t>* value);
   int64_t UlUnicodeRange1();
   int64_t UlUnicodeRange2();
   int64_t UlUnicodeRange3();
   int64_t UlUnicodeRange4();
   // UNIMPLEMENTED: public EnumSet<UnicodeRange> UlUnicodeRange()
-  void AchVendId(ByteVector* b);
+  void AchVendId(std::vector<uint8_t>* b);
   // UNIMPLEMENTED: public EnumSet<FsSelection> fsSelection()
   int32_t FsSelection();
   int32_t UsFirstCharIndex();
diff --git a/cpp/src/sfntly/table/header.h b/cpp/src/sfntly/table/header.h
index 7744a21..1a4cba1 100644
--- a/cpp/src/sfntly/table/header.h
+++ b/cpp/src/sfntly/table/header.h
@@ -34,51 +34,51 @@
   virtual ~Header();
 
   // Get the table tag.
-  int32_t tag() { return tag_; }
+  int32_t tag() const { return tag_; }
 
   // Get the table offset. The offset is from the start of the font file.  This
   // offset value is what was read from the font file during construction of the
   // font. It may not be meaningful if the font was maninpulated through the
   // builders.
-  int32_t offset() { return offset_; }
+  int32_t offset() const { return offset_; }
 
   // Is the offset in the header valid. The offset will not be valid if the
   // table was constructed during building and has no physical location in a
   // font file.
-  bool offset_valid() { return offset_valid_; }
+  bool offset_valid() const { return offset_valid_; }
 
   // Get the length of the table as recorded in the table record header.  During
   // building the header length will reflect the length that was initially read
   // from the font file. This may not be consistent with the current state of
   // the data.
-  int32_t length() { return length_; }
+  int32_t length() const { return length_; }
 
   // Is the length in the header valid. The length will not be valid if the
   // table was constructed during building and has no physical location in a
   // font file until the table is built from the builder.
-  bool length_valid() { return length_valid_; }
+  bool length_valid() const { return length_valid_; }
 
   // Get the checksum for the table as recorded in the table record header.
-  int64_t checksum() { return checksum_; }
+  int64_t checksum() const { return checksum_; }
 
   // Is the checksum valid. The checksum will not be valid if the table was
   // constructed during building and has no physical location in a font file.
   // Note that this does *NOT* check the validity of the checksum against
   // the calculated checksum for the table data.
-  bool checksum_valid() { return checksum_valid_; }
+  bool checksum_valid() const { return checksum_valid_; }
 
   // UNIMPLEMENTED: boolean equals(Object obj)
   //                int hashCode()
   //                string toString()
 
  private:
-  int32_t tag_;
-  int32_t offset_;
-  bool offset_valid_;
-  int32_t length_;
-  bool length_valid_;
-  int64_t checksum_;
-  bool checksum_valid_;
+  const int32_t tag_;
+  const int32_t offset_;
+  const bool offset_valid_;
+  const int32_t length_;
+  const bool length_valid_;
+  const int64_t checksum_;
+  const bool checksum_valid_;
 
   friend class HeaderComparatorByOffset;
   friend class HeaderComparatorByTag;
diff --git a/cpp/src/sfntly/table/truetype/glyph_table.cc b/cpp/src/sfntly/table/truetype/glyph_table.cc
index 0c1e841..32b76b6 100644
--- a/cpp/src/sfntly/table/truetype/glyph_table.cc
+++ b/cpp/src/sfntly/table/truetype/glyph_table.cc
@@ -69,13 +69,13 @@
 GlyphTable::Builder::~Builder() {
 }
 
-void GlyphTable::Builder::SetLoca(const IntegerList& loca) {
+void GlyphTable::Builder::SetLoca(const std::vector<int32_t>& loca) {
   loca_ = loca;
   set_model_changed(false);
   glyph_builders_.clear();
 }
 
-void GlyphTable::Builder::GenerateLocaList(IntegerList* locas) {
+void GlyphTable::Builder::GenerateLocaList(std::vector<int32_t>* locas) {
   assert(locas);
   GlyphBuilderList* glyph_builders = GetGlyphBuilders();
   locas->push_back(0);
@@ -158,7 +158,7 @@
 }
 
 void GlyphTable::Builder::Initialize(ReadableFontData* data,
-                                     const IntegerList& loca) {
+                                     const std::vector<int32_t>& loca) {
   if (data != NULL) {
     if (loca_.empty()) {
       return;
@@ -181,7 +181,7 @@
 
 GlyphTable::GlyphBuilderList* GlyphTable::Builder::GetGlyphBuilders() {
   if (glyph_builders_.empty()) {
-    if (InternalReadData() && !loca_.empty()) {
+    if (InternalReadData() && loca_.empty()) {
 #if !defined (SFNTLY_NO_EXCEPTION)
       throw IllegalStateException(
           "Loca values not set - unable to parse glyph data.");
@@ -354,29 +354,6 @@
              data_->Slice(instructions_offset_, InstructionSize()));
 }
 
-int32_t GlyphTable::SimpleGlyph::NumberOfPoints(int32_t contour) {
-  Initialize();
-  if (contour >= NumberOfContours()) {
-    return 0;
-  }
-  return contour_index_[contour + 1] - contour_index_[contour];
-}
-
-int32_t GlyphTable::SimpleGlyph::XCoordinate(int32_t contour, int32_t point) {
-  Initialize();
-  return x_coordinates_[contour_index_[contour] + point];
-}
-
-int32_t GlyphTable::SimpleGlyph::YCoordinate(int32_t contour, int32_t point) {
-  Initialize();
-  return y_coordinates_[contour_index_[contour] + point];
-}
-
-bool GlyphTable::SimpleGlyph::OnCurve(int32_t contour, int32_t point) {
-  Initialize();
-  return on_curve_[contour_index_[contour] + point];
-}
-
 void GlyphTable::SimpleGlyph::Initialize() {
   AutoLock lock(initialization_lock_);
   if (initialized_) {
@@ -545,6 +522,8 @@
 }
 
 int32_t GlyphTable::CompositeGlyph::Flags(int32_t contour) {
+  if (contour < 0 || static_cast<size_t>(contour) >= contour_index_.size())
+    return ReadableFontData::kInvalidUnsigned;
   return data_->ReadUShort(contour_index_[contour]);
 }
 
@@ -553,58 +532,11 @@
 }
 
 int32_t GlyphTable::CompositeGlyph::GlyphIndex(int32_t contour) {
+  if (contour < 0 || static_cast<size_t>(contour) >= contour_index_.size())
+    return ReadableFontData::kInvalidUnsigned;
   return data_->ReadUShort(DataSize::kUSHORT + contour_index_[contour]);
 }
 
-int32_t GlyphTable::CompositeGlyph::Argument1(int32_t contour) {
-  int32_t index = 2 * DataSize::kUSHORT + contour_index_[contour];
-  int32_t contour_flags = Flags(contour);
-  if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) ==
-                       kFLAG_ARG_1_AND_2_ARE_WORDS) {
-    return data_->ReadUShort(index);
-  }
-  return data_->ReadByte(index);
-}
-
-int32_t GlyphTable::CompositeGlyph::Argument2(int32_t contour) {
-  int32_t index = 2 * DataSize::kUSHORT + contour_index_[contour];
-  int32_t contour_flags = Flags(contour);
-  if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) ==
-                       kFLAG_ARG_1_AND_2_ARE_WORDS) {
-    return data_->ReadUShort(index + DataSize::kUSHORT);
-  }
-  return data_->ReadByte(index + DataSize::kUSHORT);
-}
-
-int32_t GlyphTable::CompositeGlyph::TransformationSize(int32_t contour) {
-  int32_t contour_flags = Flags(contour);
-  if ((contour_flags & kFLAG_WE_HAVE_A_SCALE) == kFLAG_WE_HAVE_A_SCALE) {
-      return DataSize::kF2DOT14;
-    } else if ((contour_flags & kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) ==
-                                kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) {
-      return 2 * DataSize::kF2DOT14;
-    } else if ((contour_flags & kFLAG_WE_HAVE_A_TWO_BY_TWO) ==
-                                kFLAG_WE_HAVE_A_TWO_BY_TWO) {
-      return 4 * DataSize::kF2DOT14;
-    }
-    return 0;
-}
-
-void GlyphTable::CompositeGlyph::Transformation(int32_t contour,
-                                                ByteVector* transformation) {
-  int32_t contour_flags = Flags(contour);
-  int32_t index = contour_index_[contour] + 2 * DataSize::kUSHORT;
-  if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) ==
-                       kFLAG_ARG_1_AND_2_ARE_WORDS) {
-    index += 2 * DataSize::kSHORT;
-  } else {
-    index += 2 * DataSize::kBYTE;
-  }
-  int32_t tsize = TransformationSize(contour);
-  transformation->resize(tsize);
-  data_->ReadBytes(index, &((*transformation)[0]), 0, tsize);
-}
-
 int32_t GlyphTable::CompositeGlyph::InstructionSize() {
   return instruction_size_;
 }
@@ -626,6 +558,9 @@
   while ((flags & kFLAG_MORE_COMPONENTS) == kFLAG_MORE_COMPONENTS) {
     contour_index_.push_back(index);
     flags = data_->ReadUShort(index);
+    if (flags == ReadableFontData::kInvalidUnsigned)
+      break;
+
     index += 2 * DataSize::kUSHORT;  // flags and glyphIndex
     if ((flags & kFLAG_ARG_1_AND_2_ARE_WORDS) == kFLAG_ARG_1_AND_2_ARE_WORDS) {
       index += 2 * DataSize::kSHORT;
diff --git a/cpp/src/sfntly/table/truetype/glyph_table.h b/cpp/src/sfntly/table/truetype/glyph_table.h
index 4ffddda..e16c8c8 100644
--- a/cpp/src/sfntly/table/truetype/glyph_table.h
+++ b/cpp/src/sfntly/table/truetype/glyph_table.h
@@ -115,8 +115,8 @@
     Builder(Header* header, ReadableFontData* data);
     virtual ~Builder();
 
-    virtual void SetLoca(const IntegerList& loca);
-    virtual void GenerateLocaList(IntegerList* locas);
+    virtual void SetLoca(const std::vector<int32_t>& loca);
+    virtual void GenerateLocaList(std::vector<int32_t>* locas);
 
     static CALLER_ATTACH Builder* CreateBuilder(Header* header,
                                                 WritableFontData* data);
@@ -150,12 +150,12 @@
     virtual int32_t SubSerialize(WritableFontData* new_data);
 
    private:
-    void Initialize(ReadableFontData* data, const IntegerList& loca);
+    void Initialize(ReadableFontData* data, const std::vector<int32_t>& loca);
     GlyphBuilderList* GetGlyphBuilders();
     void Revert();
 
     GlyphBuilderList glyph_builders_;
-    IntegerList loca_;
+    std::vector<int32_t> loca_;
   };
 
   class SimpleGlyph : public Glyph, public RefCounted<SimpleGlyph> {
@@ -199,11 +199,6 @@
     virtual CALLER_ATTACH ReadableFontData* Instructions();
     virtual void Initialize();
 
-    int32_t NumberOfPoints(int32_t contour);
-    int32_t XCoordinate(int32_t contour, int32_t point);
-    int32_t YCoordinate(int32_t contour, int32_t point);
-    bool OnCurve(int32_t contour, int32_t point);
-
    private:
     void ParseData(bool fill_arrays);
     int32_t FlagAsInt(int32_t index);
@@ -224,10 +219,10 @@
     int32_t x_byte_count_;
     int32_t y_byte_count_;
 
-    IntegerList x_coordinates_;
-    IntegerList y_coordinates_;
+    std::vector<int32_t> x_coordinates_;
+    std::vector<int32_t> y_coordinates_;
     std::vector<bool> on_curve_;
-    IntegerList contour_index_;
+    std::vector<int32_t> contour_index_;
   };
 
   class CompositeGlyph : public Glyph, public RefCounted<CompositeGlyph> {
@@ -272,10 +267,6 @@
     int32_t Flags(int32_t contour);
     int32_t NumGlyphs();
     int32_t GlyphIndex(int32_t contour);
-    int32_t Argument1(int32_t contour);
-    int32_t Argument2(int32_t contour);
-    int32_t TransformationSize(int32_t contour);
-    void Transformation(int32_t contour, ByteVector* transformation);
     virtual int32_t InstructionSize();
     virtual CALLER_ATTACH ReadableFontData* Instructions();
 
@@ -283,7 +274,7 @@
     virtual void Initialize();
 
    private:
-    IntegerList contour_index_;
+    std::vector<int32_t> contour_index_;
     int32_t instruction_size_;
     int32_t instructions_offset_;
     bool initialized_;
diff --git a/cpp/src/sfntly/table/truetype/loca_table.cc b/cpp/src/sfntly/table/truetype/loca_table.cc
index c692155..a1e82a4 100644
--- a/cpp/src/sfntly/table/truetype/loca_table.cc
+++ b/cpp/src/sfntly/table/truetype/loca_table.cc
@@ -40,7 +40,11 @@
 #endif
     return 0;
   }
-  return Loca(glyph_id + 1) - Loca(glyph_id);
+  int32_t glyph_val = Loca(glyph_id);
+  int32_t glyph_next_val = Loca(glyph_id + 1);
+  if (glyph_val < 0 || glyph_next_val < 0 || glyph_next_val <= glyph_val)
+    return 0;
+  return glyph_next_val - glyph_val;
 }
 
 int32_t LocaTable::NumLocas() {
@@ -109,11 +113,11 @@
   return builder.Detach();
 }
 
-IntegerList* LocaTable::Builder::LocaList() {
+std::vector<int32_t>* LocaTable::Builder::LocaList() {
   return GetLocaList();
 }
 
-void LocaTable::Builder::SetLocaList(IntegerList* list) {
+void LocaTable::Builder::SetLocaList(std::vector<int32_t>* list) {
   loca_.clear();
   if (list) {
     loca_ = *list;
@@ -136,6 +140,7 @@
 }
 
 void LocaTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
+  assert(num_glyphs >= 0);
   num_glyphs_ = num_glyphs;
 }
 
@@ -183,7 +188,7 @@
 
 int32_t LocaTable::Builder::SubSerialize(WritableFontData* new_data) {
   int32_t size = 0;
-  for (IntegerList::iterator l = loca_.begin(), end = loca_.end();
+  for (std::vector<int32_t>::iterator l = loca_.begin(), end = loca_.end();
                              l != end; ++l) {
     if (format_version_ == IndexToLocFormat::kLongOffset) {
       size += new_data->WriteULong(size, *l);
@@ -228,7 +233,7 @@
   return !loca_.empty() ? loca_.size() - 2 : num_glyphs_ - 1;
 }
 
-IntegerList* LocaTable::Builder::GetLocaList() {
+std::vector<int32_t>* LocaTable::Builder::GetLocaList() {
   if (loca_.empty()) {
     Initialize(InternalReadData());
     set_model_changed();
diff --git a/cpp/src/sfntly/table/truetype/loca_table.h b/cpp/src/sfntly/table/truetype/loca_table.h
index 67c5749..fe1dd4a 100644
--- a/cpp/src/sfntly/table/truetype/loca_table.h
+++ b/cpp/src/sfntly/table/truetype/loca_table.h
@@ -60,12 +60,12 @@
     // SetLocaList(List) method.
     // If there is no current data for the loca table builder or the loca list
     // have not been previously set then this will return an empty List.
-    IntegerList* LocaList();
+    std::vector<int32_t>* LocaList();
 
     // Set the list of locas to be used for building this table. If any existing
     // list was already retrieved with the LocaList() method then the
     // connection of that previous list to this builder will be broken.
-    void SetLocaList(IntegerList* list);
+    void SetLocaList(std::vector<int32_t>* list);
 
     // Return the offset for the given glyph id. Valid glyph ids are from 0 to
     // one less than the number of glyphs. The zero entry is the special entry
@@ -129,13 +129,13 @@
     // Internal method to get the loca list if already generated and if not to
     // initialize the state of the builder.
     // @return the loca list
-    IntegerList* GetLocaList();
+    std::vector<int32_t>* GetLocaList();
 
     void ClearLoca(bool nullify);
 
     int32_t format_version_;  // Note: IndexToLocFormat
     int32_t num_glyphs_;
-    IntegerList loca_;
+    std::vector<int32_t> loca_;
   };
 
   virtual ~LocaTable();
diff --git a/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.cc b/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.cc
index b3d6b07..02cc149 100644
--- a/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.cc
+++ b/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.cc
@@ -39,7 +39,7 @@
   assert(subsetter);
   assert(font_builder);
 
-  IntegerList* permutation_table = subsetter->GlyphPermutationTable();
+  std::vector<int32_t>* permutation_table = subsetter->GlyphPermutationTable();
   if (!permutation_table || permutation_table->empty())
     return false;
 
@@ -66,7 +66,7 @@
   }
   GlyphTable::GlyphBuilderList* glyph_builders =
       glyph_table_builder->GlyphBuilders();
-  for (IntegerList::iterator old_glyph_id = permutation_table->begin(),
+  for (std::vector<int32_t>::iterator old_glyph_id = permutation_table->begin(),
                              old_glyph_id_end = permutation_table->end();
                              old_glyph_id != old_glyph_id_end; ++old_glyph_id) {
     int old_offset = loca_table->GlyphOffset(*old_glyph_id);
@@ -81,7 +81,7 @@
     glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data));
     glyph_builders->push_back(glyph_builder);
   }
-  IntegerList loca_list;
+  std::vector<int32_t> loca_list;
   glyph_table_builder->GenerateLocaList(&loca_list);
   loca_table_builder->SetLocaList(&loca_list);
   return true;
diff --git a/cpp/src/sfntly/tools/subsetter/subsetter.cc b/cpp/src/sfntly/tools/subsetter/subsetter.cc
index 7d98779..3019cad 100644
--- a/cpp/src/sfntly/tools/subsetter/subsetter.cc
+++ b/cpp/src/sfntly/tools/subsetter/subsetter.cc
@@ -37,7 +37,7 @@
   table_subsetters_.clear();
 }
 
-void Subsetter::SetGlyphs(IntegerList* glyphs) {
+void Subsetter::SetGlyphs(std::vector<int32_t>* glyphs) {
   new_to_old_glyphs_ = *glyphs;
 }
 
@@ -47,7 +47,7 @@
   // TODO(arthurhsu): IMPLEMENT
 }
 
-void Subsetter::SetRemoveTables(IntegerSet* remove_tables) {
+void Subsetter::SetRemoveTables(std::set<int32_t>* remove_tables) {
   remove_tables_ = *remove_tables;
 }
 
@@ -55,13 +55,13 @@
   FontBuilderPtr font_builder;
   font_builder.Attach(font_factory_->NewFontBuilder());
 
-  IntegerSet table_tags;
+  std::set<int32_t> table_tags;
   for (TableMap::const_iterator i = font_->GetTableMap()->begin(),
                                 e = font_->GetTableMap()->end(); i != e; ++i) {
     table_tags.insert(i->first);
   }
   if (!remove_tables_.empty()) {
-    IntegerSet result;
+    std::set<int32_t> result;
     std::set_difference(table_tags.begin(), table_tags.end(),
                         remove_tables_.begin(), remove_tables_.end(),
                         std::inserter(result, result.end()));
@@ -73,15 +73,15 @@
            table_subsetter != table_subsetter_end; ++table_subsetter) {
     bool handled = (*table_subsetter)->Subset(this, font_, font_builder);
     if (handled) {
-      IntegerSet* handled_tags = (*table_subsetter)->TagsHandled();
-      IntegerSet result;
+      std::set<int32_t>* handled_tags = (*table_subsetter)->TagsHandled();
+      std::set<int32_t> result;
       std::set_difference(table_tags.begin(), table_tags.end(),
                           handled_tags->begin(), handled_tags->end(),
                           std::inserter(result, result.end()));
       table_tags = result;
     }
   }
-  for (IntegerSet::iterator tag = table_tags.begin(),
+  for (std::set<int32_t>::iterator tag = table_tags.begin(),
                             tag_end = table_tags.end(); tag != tag_end; ++tag) {
     Table* table = font_->GetTable(*tag);
     if (table) {
@@ -91,7 +91,7 @@
   return font_builder.Detach();
 }
 
-IntegerList* Subsetter::GlyphPermutationTable() {
+std::vector<int32_t>* Subsetter::GlyphPermutationTable() {
   return &new_to_old_glyphs_;
 }
 
diff --git a/cpp/src/sfntly/tools/subsetter/subsetter.h b/cpp/src/sfntly/tools/subsetter/subsetter.h
index 85940a7..d0a2607 100644
--- a/cpp/src/sfntly/tools/subsetter/subsetter.h
+++ b/cpp/src/sfntly/tools/subsetter/subsetter.h
@@ -31,7 +31,7 @@
   Subsetter(Font* font, FontFactory* font_factory);
   virtual ~Subsetter();
 
-  virtual void SetGlyphs(IntegerList* glyphs);
+  virtual void SetGlyphs(std::vector<int32_t>* glyphs);
 
   // Set the cmaps to be used in the subsetted font. The cmaps are listed in
   // order of priority and the number parameter gives a count of how many of the
@@ -51,9 +51,9 @@
   // @param number the maximum number of cmaps to place in the subsetted font
   virtual void SetCMaps(CMapIdList* cmap_ids, int32_t number);
 
-  virtual void SetRemoveTables(IntegerSet* remove_tables);
+  virtual void SetRemoveTables(std::set<int32_t>* remove_tables);
   virtual CALLER_ATTACH Font::Builder* Subset();
-  virtual IntegerList* GlyphPermutationTable();
+  virtual std::vector<int32_t>* GlyphPermutationTable();
   virtual CMapIdList* CMapId();
 
  private:
@@ -62,8 +62,8 @@
   TableSubsetterList table_subsetters_;
 
   // Settings from user
-  IntegerSet remove_tables_;
-  IntegerList new_to_old_glyphs_;
+  std::set<int32_t> remove_tables_;
+  std::vector<int32_t> new_to_old_glyphs_;
   CMapIdList cmap_ids_;
 };
 
diff --git a/cpp/src/sfntly/tools/subsetter/table_subsetter.h b/cpp/src/sfntly/tools/subsetter/table_subsetter.h
index 1336615..6a39f73 100644
--- a/cpp/src/sfntly/tools/subsetter/table_subsetter.h
+++ b/cpp/src/sfntly/tools/subsetter/table_subsetter.h
@@ -26,7 +26,7 @@
 class Subsetter;
 class TableSubsetter : virtual public RefCount {
  public:
-  virtual IntegerSet* TagsHandled() = 0;
+  virtual std::set<int32_t>* TagsHandled() = 0;
   virtual bool TagHandled(int32_t tag) = 0;
   virtual bool Subset(Subsetter* subsetter, Font* font,
                       Font::Builder* font_builder) = 0;
diff --git a/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.cc b/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.cc
index f239c78..d2085a1 100644
--- a/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.cc
+++ b/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.cc
@@ -31,7 +31,7 @@
   return tags_.find(tag) != tags_.end();
 }
 
-IntegerSet* TableSubsetterImpl::TagsHandled() {
+std::set<int32_t>* TableSubsetterImpl::TagsHandled() {
   return &tags_;
 }
 
diff --git a/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.h b/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.h
index de0d9a9..14c770a 100644
--- a/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.h
+++ b/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.h
@@ -26,10 +26,10 @@
   TableSubsetterImpl(const int32_t* tags, size_t tags_length);
   virtual ~TableSubsetterImpl();
   virtual bool TagHandled(int32_t tag);
-  virtual IntegerSet* TagsHandled();
+  virtual std::set<int32_t>* TagsHandled();
 
  protected:
-  IntegerSet tags_;
+  std::set<int32_t> tags_;
 };
 
 }  // namespace sfntly
diff --git a/cpp/src/test/bitmap_table_test.cc b/cpp/src/test/bitmap_table_test.cc
index df3ffc0..e9eacc7 100644
--- a/cpp/src/test/bitmap_table_test.cc
+++ b/cpp/src/test/bitmap_table_test.cc
@@ -58,11 +58,18 @@
   EXPECT_FALSE(bitmap_loca == NULL);
   EXPECT_FALSE(bitmap_table == NULL);
 
+  if (!bitmap_loca) {
+    return false;
+  }
+
   EXPECT_EQ(bitmap_loca->NumSizes(), NUM_STRIKES);
 
   // Strike 1
   BitmapSizeTablePtr strike1 = bitmap_loca->GetBitmapSizeTable(0);
   EXPECT_FALSE(strike1 == NULL);
+  if (!strike1) {
+    return false;
+  }
   EXPECT_EQ(strike1->IndexSubTableArrayOffset(), STRIKE1_ARRAY_OFFSET);
   EXPECT_EQ(strike1->NumberOfIndexSubTables(), STRIKE1_NUM_INDEX_TABLES);
   EXPECT_EQ(strike1->ColorRef(), STRIKE1_COLOR_REF);
diff --git a/cpp/src/test/byte_array_test.cc b/cpp/src/test/byte_array_test.cc
index 40a6489..de50089 100644
--- a/cpp/src/test/byte_array_test.cc
+++ b/cpp/src/test/byte_array_test.cc
@@ -28,7 +28,7 @@
 
 void FillTestByteArray(ByteArray* ba, int32_t size) {
   for (int32_t i = 0; i < size; ++i) {
-    ba->Put(i, (byte_t)(i % 256));
+    ba->Put(i, (uint8_t)(i % 256));
   }
 }
 
diff --git a/cpp/src/test/endian_test.cc b/cpp/src/test/endian_test.cc
index 0d9da09..80cce68 100644
--- a/cpp/src/test/endian_test.cc
+++ b/cpp/src/test/endian_test.cc
@@ -25,7 +25,7 @@
 namespace sfntly {
 
 bool TestEndian() {
-  byte_t test_data[] = {
+  uint8_t test_data[] = {
       0x68, 0x65, 0x61, 0x64,  // 0: head
       0xca, 0xca, 0xca, 0xca,  // 4: ubyte, byte, char
       0x00, 0x18, 0x80, 0x18,  // 8: ushort, short
diff --git a/cpp/src/test/font_data_test.cc b/cpp/src/test/font_data_test.cc
index 4b0db64..5ed041c 100644
--- a/cpp/src/test/font_data_test.cc
+++ b/cpp/src/test/font_data_test.cc
@@ -136,14 +136,14 @@
 
 void FillTestByteArray(ByteArray* ba, int32_t size) {
   for (int32_t i = 0; i < size; ++i) {
-    ba->Put(i, (byte_t)(i % 256));
+    ba->Put(i, (uint8_t)(i % 256));
   }
 }
 
 void ReadFontDataWithSingleByte(ReadableFontData* rfd, ByteVector* buffer) {
   buffer->resize(rfd->Length());
   for (int32_t index = 0; index < rfd->Length(); ++index) {
-    (*buffer)[index] = (byte_t)(rfd->ReadByte(index));
+    (*buffer)[index] = (uint8_t)(rfd->ReadByte(index));
   }
 }
 
@@ -178,7 +178,7 @@
 
 void WriteFontDataWithSingleByte(ReadableFontData* rfd, WritableFontData* wfd) {
   for (int32_t index = 0; index < rfd->Length(); ++index) {
-    byte_t b = (byte_t)(rfd->ReadByte(index));
+    uint8_t b = (uint8_t)(rfd->ReadByte(index));
     wfd->WriteByte(index, b);
   }
 }
diff --git a/cpp/src/test/open_type_data_test.cc b/cpp/src/test/open_type_data_test.cc
index 0917aab..5d73e84 100644
--- a/cpp/src/test/open_type_data_test.cc
+++ b/cpp/src/test/open_type_data_test.cc
@@ -20,12 +20,12 @@
 
 namespace sfntly {
 
-const byte_t TEST_OTF_DATA[] =
+const uint8_t TEST_OTF_DATA[] =
     {0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
 
 bool TestOTFRead() {
   ByteVector bytes;
-  for (size_t i = 0; i < sizeof(TEST_OTF_DATA) / sizeof(byte_t); ++i) {
+  for (size_t i = 0; i < sizeof(TEST_OTF_DATA) / sizeof(uint8_t); ++i) {
     bytes.push_back(TEST_OTF_DATA[i]);
   }
   ByteArrayPtr array = new MemoryByteArray(&(bytes[0]), bytes.size());
@@ -45,7 +45,7 @@
 bool TestOTFCopy() {
   ByteVector source_bytes(1024);
   for (size_t i = 0; i < source_bytes.size(); ++i) {
-    source_bytes[i] = (byte_t)(i & 0xff);
+    source_bytes[i] = (uint8_t)(i & 0xff);
   }
   ByteArrayPtr source_array = new MemoryByteArray(&(source_bytes[0]), 1024);
   ReadableFontDataPtr source = new ReadableFontData(source_array);
diff --git a/cpp/src/test/otf_basic_editing_test.cc b/cpp/src/test/otf_basic_editing_test.cc
index 7388fac..04c8778 100644
--- a/cpp/src/test/otf_basic_editing_test.cc
+++ b/cpp/src/test/otf_basic_editing_test.cc
@@ -33,30 +33,41 @@
   factory.Attach(FontFactory::GetInstance());
   FontBuilderArray font_builder_array;
   BuilderForFontFile(SAMPLE_TTF_FILE, factory, &font_builder_array);
+  if (font_builder_array.size() != 1) {
+    EXPECT_TRUE(false);
+    return false;
+  }
   FontBuilderPtr font_builder = font_builder_array[0];
 
   // ensure the builder is not bogus
-  EXPECT_TRUE(font_builder != NULL);
+  if (!font_builder) {
+    EXPECT_TRUE(false);
+    return false;
+  }
   TableBuilderMap* builder_map = font_builder->table_builders();
-  EXPECT_TRUE(builder_map != NULL);
+  if (!builder_map) {
+    EXPECT_TRUE(false);
+    return false;
+  }
   IntegerSet builder_tags;
   for (TableBuilderMap::iterator i = builder_map->begin(),
                                  e = builder_map->end(); i != e; ++i) {
-    EXPECT_TRUE(i->second != NULL);
-    if (i->second == NULL) {
+    if (!i->second) {
+      EXPECT_TRUE(false);
       char tag[5] = {0};
       int32_t value = ToBE32(i->first);
       memcpy(tag, &value, 4);
       fprintf(stderr, "tag %s does not have valid builder\n", tag);
-    } else {
-      builder_tags.insert(i->first);
+      continue;
     }
+    builder_tags.insert(i->first);
   }
 
   FontHeaderTableBuilderPtr header_builder =
       down_cast<FontHeaderTable::Builder*>(
           font_builder->GetTableBuilder(Tag::head));
   int64_t mod_date = header_builder->Modified();
+  EXPECT_EQ(3397043097, mod_date);
   header_builder->SetModified(mod_date + 1);
   FontPtr font;
   font.Attach(font_builder->Build());
@@ -65,10 +76,10 @@
   const TableMap* table_map = font->GetTableMap();
   for (TableMap::const_iterator i = table_map->begin(), e = table_map->end();
                                 i != e; ++i) {
-    TablePtr table = (*i).second;
+    TablePtr table = i->second;
     HeaderPtr header = table->header();
-    EXPECT_TRUE(builder_tags.find(header->tag()) != builder_tags.end());
-    builder_tags.erase(header->tag());
+    size_t erased = builder_tags.erase(header->tag());
+    EXPECT_EQ(1U, erased);
   }
   EXPECT_TRUE(builder_tags.empty());
 
@@ -79,7 +90,7 @@
 
   // Checksum correctness of builder.
   TablePtr post = font->GetTable(Tag::post);
-  EXPECT_EQ(post->CalculatedChecksum(), TTF_CHECKSUM[SAMPLE_TTF_POST]);
+  EXPECT_EQ(TTF_CHECKSUM[SAMPLE_TTF_POST], post->CalculatedChecksum());
   return true;
 }
 
diff --git a/cpp/src/test/test_utils_test.cc b/cpp/src/test/test_utils_test.cc
index 9afc03c..fbd5ed1 100644
--- a/cpp/src/test/test_utils_test.cc
+++ b/cpp/src/test/test_utils_test.cc
@@ -40,7 +40,7 @@
   for (i = 0; i < 7; ++i) {
     int32_t encoded = TestUtils::EncodeOneChar(conv, (int16_t)from[i]);
     for (; encoded; encoded <<= 8) {
-      byte_t b = (encoded & 0xff000000) >> 24;
+      uint8_t b = (encoded & 0xff000000) >> 24;
       if (!b)
         continue;
       EXPECT_EQ(want[j], b);
diff --git a/cpp/src/test/verify_hhea.cc b/cpp/src/test/verify_hhea.cc
index 81ddb58..1e1001c 100644
--- a/cpp/src/test/verify_hhea.cc
+++ b/cpp/src/test/verify_hhea.cc
@@ -24,7 +24,7 @@
 
 const int32_t HHEA_ASCENDER = 2023;
 const int32_t HHEA_DESCENDER = -648;
-const int32_t HHEA_LINE_GAP = 93;
+// const int32_t HHEA_LINE_GAP = 93;
 const int32_t HHEA_ADVANCE_WIDTH_MAX = 2753;
 const int32_t HHEA_MIN_LSB = -968;
 const int32_t HHEA_MIN_RSB = -411;
diff --git a/cpp/src/test/verify_maxp.cc b/cpp/src/test/verify_maxp.cc
index dcd776e..074042a 100644
--- a/cpp/src/test/verify_maxp.cc
+++ b/cpp/src/test/verify_maxp.cc
@@ -31,7 +31,7 @@
 const int32_t MAXP_MAX_TWILIGHT_POINTS = 0;
 const int32_t MAXP_MAX_STORAGE = 1;
 const int32_t MAXP_MAX_FUNCTION_DEFS = 1;
-const int32_t MAXP_MAX_INSTR_DEFS = 0;
+// const int32_t MAXP_MAX_INSTR_DEFS = 0;
 const int32_t MAXP_MAX_STACK_ELEMENTS = 64;
 const int32_t MAXP_MAX_INSTR_SIZE = 46;
 const int32_t MAXP_MAX_COMPONENT_ELEMENTS = 4;
diff --git a/cpp/src/test/verify_os2.cc b/cpp/src/test/verify_os2.cc
index 4897e87..c80c58a 100644
--- a/cpp/src/test/verify_os2.cc
+++ b/cpp/src/test/verify_os2.cc
@@ -37,12 +37,12 @@
 const int32_t OS2_YSTRIKEOUT_SIZE = 12312;
 const int32_t OS2_YSTRIKEOUT_POS = -16224;
 const int32_t OS2_SFAMILY_CLASS = 0;
-const byte_t OS2_PANOSE[] = { 2, 11, 6, 3, 6, 1, 0, 0, 0, 0 };
+const uint8_t OS2_PANOSE[] = { 2, 11, 6, 3, 6, 1, 0, 0, 0, 0 };
 const int64_t OS2_UL_UNICODE_RANGE1 = 0xE00002FFL;
 const int64_t OS2_UL_UNICODE_RANGE2 = 0x520020FBL;
 const int64_t OS2_UL_UNICODE_RANGE3 = 0L;
 const int64_t OS2_UL_UNICODE_RANGE4 = 0L;
-const byte_t OS2_ACH_VEND_ID[] = { 'P', 'f', 'E', 'd' };
+const uint8_t OS2_ACH_VEND_ID[] = { 'P', 'f', 'E', 'd' };
 const int32_t OS2_FS_SELECTION = 0x0040;
 const int32_t OS2_US_FIRST_CHAR_IDX = 0x0020;
 const int32_t OS2_US_LAST_CHAR_IDX = 0xFFFF;
diff --git a/doc/MicroTypeExpress.md b/doc/MicroTypeExpress.md
new file mode 100644
index 0000000..97f55d0
--- /dev/null
+++ b/doc/MicroTypeExpress.md
@@ -0,0 +1,42 @@
+# MicroType Express in sfntly
+
+This page describes sfntly’s implementation of MicroType Express
+compression.
+
+The MicroType Express format is [documented](http://www.w3.org/Submission/MTX/),
+and is recently available under license terms we believe are friendly to
+open source (as well as proprietary) implementation. The most popular
+implementation of a decoder is Internet Explorer, as a compression
+option in its Embedded OpenType (EOT) format. Since MicroType Express
+gives an approximate 15% gain in compression over gzip, a web font
+service striving for maximum performance can benefit from implementing
+EOT compression.
+
+The current codebase in sfntly is for compression only (this is by far
+the most useful for web serving). The easiest way to get started is with
+the command line tool, sfnttool:
+
+```
+sfnttool -e -x source.ttf source.eot
+```
+
+The code has been tested extensively against IE, and is currently in
+production in Google Web Fonts, both for full fonts and for subsetting
+(using the text= parameter). This serving path also uses sfntly to
+compute the subsets, and is essentially the same as the -s parameter to
+sfnttool.
+
+If you’re interested in the code and details of the compression
+algorithm, here’s a bit of a guide:
+
+The top-level MicroType Express compression code is in MtxWriter.java
+(in the tools/conversion/eot directory). This code implements almost all
+of the MicroType Express format, including the hdmx tables, push
+sequences, and jump coding. The main feature missing is the VDMX table
+(vertical device metrics), which is very rarely used in web fonts.
+
+Patches are welcome -- possible areas include: implementing the VDMX
+table, speeding up the LZCOMP entropy coder (the match finding code is a
+straightforward adaptation of the algorithm in the format document),
+implementing a decoder in addition to an encoder, and porting the Java
+implementation to C++.
diff --git a/doc/SfntlyCPlusPlusNotes.md b/doc/SfntlyCPlusPlusNotes.md
new file mode 100644
index 0000000..0a55f85
--- /dev/null
+++ b/doc/SfntlyCPlusPlusNotes.md
@@ -0,0 +1,164 @@
+Introduction
+===============================================================
+
+This document will as the C++ port matures serve as a log to how
+different parts of the library work. As of today, there is some general
+info but mostly CMap specific details.
+
+------------------------------------------------------------------------
+
+Font Data Tables
+===========================================================================
+
+One of the important goals in `sfntly` is thread safety which is why
+tables can only be created with their nested `Builder` class and are
+immutable after creation.
+
+`CMapTable`
+--------------------------------------------------------
+
+*CMap* = character map; it converts *code points* in a *code page* to
+*glyph IDs*.
+
+The CMapTable is a table of CMaps (CMaps are also tables; one for every
+encoding supported by the font). Representing an encoding-dependent
+character map is in one of 14 formats, out of which formats 0 and 4 are
+the most used; sfntly/C++ will initially only support formats 0, 2, 4
+and 12.
+
+### `CMapFormat0` Byte encoding table
+
+Format 0 is a basic table where a character’s glyph ID is looked up in a
+glyphIdArray256. As it only supports 256 characters it can only encode
+ASCII and ISO 8859-x (alphabet-based languages).
+
+### `CMapFormat2` High-byte mapping through table
+
+Chinese, Japanese and Korean (CJK) need special 2 byte encodings for
+each code point like Shift-JIS.
+
+### `CMapFormat4` Segment mapping to delta values
+
+This is the preferred format for Unicode Basic Multilingual Plane (BMP)
+encodings according to the Microsoft spec. Format 4 defines segments
+(contiguous ranges of characters; variable length). Finding a
+character’s glyph id first means finding the segment it is part of using
+a binary search (the segments are sorted). A segment has a
+**`startCode`**, an **`endCode`** (the minimum and maximum code points
+in the segment), an **`idDelta`** (delta for all code points in the
+segment) and an **`idRangeOffset`** (offset into glyphIdArray or 0).
+
+`idDelta` and `idRangeOffset` seem to be the same thing, offsets. In
+fact, `idRangeOffset` uses the glyph array to get the index by relying
+on the fact that the array is immediately after the `idRangeOffset`
+table in the font file. So, the segment’s offset is `idRangeOffset[i]`
+but since the `idRangeOffset` table contains words and not bytes, the
+value is divided by 2.
+
+``` {.prettyprint}
+glyphIndex = *(&idRangeOffset[i] + idRangeOffset[i] / 2 + (c - startCode[i]))
+```
+
+`idDelta[i]` is another kind of segment offset used when
+`idRangeOffset[i] = 0`, in which case it is added directly to the
+character code.
+
+``` {.prettyprint}
+glyphIndex = idDelta[i] + c
+```
+
+### Class Hierarchy
+
+`CMapTable` is the main class and the container for all other CMap
+related classes.
+
+#### Utility classes
+
+-   `CMapTable::CMapId` describes a pair of IDs, platform ID and
+    encoding ID that form the CMaps ID. The ID a CMap has is usually a
+    good indicator as to what kind of format the CMap uses (Unicode
+    CMaps are usually either format 4 or format 12).
+-   `CMapTable::CMapIdComparator`
+-   `CMapTable::CMapIterator` iteration through the CMapTable is
+    supported through a Java-style iterator.
+-   `CMapTable::CMapFilter` Java-style filter; CMapIterator supports
+    filtering CMaps. By default, it accepts everything CMap.
+-   `CMapTable::CMapIdFilter` extends CMapFilter; only accepts one type
+    of CMap. Used in conjunction with CMapIterator, this is how the CMap
+    getters are implemented.
+-   **`CMapTable::Builder`** is the only way to create a CMapTable.
+
+#### CMaps
+
+-   **`CMapTable::CMap`** is the abstract base class that all
+    `CMapFormat*` derive. It defines basic functions and the abstract
+    `CMapTable::CMap::CharacterIterator` class to iterate through the
+    characters in the map. The basic implementation just loops through
+    every character between a start and an end. This is overridden so
+    that format specific iteration is performed.
+-   `CMapFormat0` (mostly done?)
+-   `CMapFormat2` (needs builders)
+-   ... coming soon
+
+`[todo: will add images soon; need to upload to svn]`
+
+------------------------------------------------------------------------
+
+# Table Building Pipeline
+
+Building a data table in sfntly is done by the
+`FontDataTable::Builder::build` method which defines the general
+pipeline and leaves the details to each implementing subclass
+(`CMapTable::Builder` for example). Note: **`sub*`** methods are table
+specific
+
+**`ReadableFontDataPtr data = internalReadData()`**
+> There are 2 private fields in the `FontDataTable::Builder` class:
+> `rData` and `wData` for `ReadableFontData` and `WritableFontData`.
+> This function returns `rData` if there is any or `wData` (it is cast
+> to readable font data) if `rData` is null. *They hold the same data!*
+
+**`if (model_changed_)`**
+> A font is essentially a binary blob when loaded inside a `FontData`
+> object. A *model* is the Java/C++ collection of objects that represent
+> the same data in a manipulable format. If you ask for the model (even
+> if you dont write to it), it will count as changed and the underlying
+> raw data will get updated.
+
+**`if (!subReadyToSerialize())`**
+**`return NULL`**
+`else`
+1.  **`size = subDataToSerialize()`**
+2.  **`WritableDataPtr new_data = container_->getNewData(size)`**
+3.  **`subSerialize(new_data)`**
+4.  **`data = new_data`**
+
+**`FontDataTablePtr table = subBuildTable(data)`**
+> The table is actually built, where `subBuildTable` is overridden by
+> every class of table but a table header is always added.
+
+Subtable Builders
+------------------------------------------------------------------------------
+
+Subtables are lazily built
+
+When creating the object view of the font and dealing with lots of
+tables, it would be wasteful to create builders for every subtable there
+is since most users only do fairly high level manipulation of the font.
+Instead, **only the tables at font level are fully built**.
+
+All other subtables have builders that contain valid FontData but the
+object view is not created by default. For the `CMapTable`, this means
+that if you don’t go through the `getCMapBuilders()` method, the CMap
+builders are not initialized. So, the builder map would seem to be empty
+when calling its `size()` method but there are CMaps in the font when
+calling `numCMaps(internalReadFont())`.
+
+------------------------------------------------------------------------
+
+Character encoders
+---------------------------------------------------------------------------------
+
+Sfntly/Java uses a native ICU-based API for encoding characters.
+Sfntly/C++ uses ICU directly. In unit tests we assume text is encoded in
+UTF16. Public APIs will use ICU classes like `UnicodeString`.
diff --git a/doc/Useful_links.md b/doc/Useful_links.md
new file mode 100644
index 0000000..2caa409
--- /dev/null
+++ b/doc/Useful_links.md
@@ -0,0 +1,25 @@
+Wiki
+
+-   TrueType
+    [http://en.wikipedia.org/wiki/TrueType](http://en.wikipedia.org/wiki/TrueType)
+-   OpenType
+    [http://en.wikipedia.org/wiki/OpenType](http://en.wikipedia.org/wiki/OpenType)
+
+Microsoft Typography
+[http://www.microsoft.com/typography/default.mspx](http://www.microsoft.com/typography/default.mspx)
+
+-   Font specifications
+    [http://www.microsoft.com/typography/SpecificationsOverview.mspx](http://www.microsoft.com/typography/SpecificationsOverview.mspx),
+    including OpenType and TrueType.
+-   Font Tools
+    [http://www.microsoft.com/typography/tools/tools.aspx](http://www.microsoft.com/typography/tools/tools.aspx)
+
+Apple
+
+-   TrueType reference manual
+    [http://developer.apple.com/fonts/TTRefMan](http://developer.apple.com/fonts/TTRefMan)
+
+Adobe
+
+-   OpenType
+    [http://www.adobe.com/type/opentype/](http://www.adobe.com/type/opentype/)
diff --git a/doc/build_cpp.md b/doc/build_cpp.md
new file mode 100644
index 0000000..5e3d344
--- /dev/null
+++ b/doc/build_cpp.md
@@ -0,0 +1,150 @@
+# How to build sfntly C++ port
+
+## Build Environment Requirements
+
+*   cmake 2.6 or above
+*   C++ compiler requirement
+    *   Windows: Visual C++ 2008, Visual C++ 2010
+    *   Linux: g++ 4.3 or above.
+        g++ must support built-in atomic ops and has companion libstd++.
+    *   Mac: Apple XCode 3.2.5 or above.
+
+## External Dependencies
+
+sfntly is dependent on several external packages.
+ 
+*   [Google C++ Testing Framework](https://github.com/google/googletest)
+
+    You can download the package yourself or extract the one from `ext/redist`.
+    The package needs to be extracted to ext and rename/symbolic link to `gtest`.
+
+    sfntly C++ port had been tested with gTest 1.6.0.
+ 
+*   ICU
+
+    For Linux, default ICU headers in system will be used.
+    Linux users please make sure you have dev packages for ICU.
+    For example, you can run `sudo apt-get install libicu-dev` in Ubuntu and see if the required library is installed.
+    
+    For Windows, download from http://site.icu-project.org/download or extract the one from `ext/redist`.
+    You can also provide your own ICU package.
+    However, you need to alter the include path, library path, and provide `icudt.dll`.
+    
+    Tested with ICU 4.6.1 binary release.
+
+    For Mac users, please download ICU source tarball from http://site.icu-project.org/download
+    and install according to ICU documents.
+
+## Getting the Source
+
+Clone the Git repository from https://github.com/googlei18n/sfntly.
+ 
+## Building on Windows
+
+Let's assume your folder for sfntly is `d:\src\sfntly`.
+
+1.  If you don't have cmake installed, extract the cmake-XXX.zip
+    into `d:\src\sfntly\cpp\ext\cmake` removing the "-XXX" part.
+    The extracted binary should be in `d:\src\sfntly\cpp\ext\cmake\bin\cmake.exe`.
+2.  Extract gtest-XXX.zip into `d:\src\sfntly\cpp\ext\gtest`
+    removing the "-XXX" part.
+3.  Extract icu4c-XXX.zip into `d:\src\sfntly\cpp\ext\icu`
+    removing the "-XXX" part.
+4.  Run the following commands to create the Visual Studio solution files:
+
+    ```
+    d:
+    cd d:\src\sfntly\cpp
+    md build
+    cd build
+    ..\ext\cmake\bin\cmake ..
+    ```
+
+You should see `sfntly.sln` in `d:\src\sfntly\cpp\build`.
+ 
+5.  Until the test is modified to access the fonts in the `ext\data` directory:
+    copy the test fonts from `d:\src\sfntly\cpp\data\ext\` to `d:\src\sfntly\cpp\build\bin\Debug`.
+6.  Open sfntly.sln.
+    Since sfntly use STL extensively, please patch your Visual Studio for any STL-related hotfixes/service packs.
+7.  Build the solution (if the icuuc dll is not found,
+    you may need to add `d:\src\sfntly\cpp\ext\icu\bin` to the system path).
+
+### Building on Windows via Command Line
+
+Visual Studio 2008 and 2010 support command line building,
+therefore you dont need the IDE to build the project.
+
+For Visual Studio 2008 (assume its installed at `c:\vs08`)
+
+    cd d:\src\sfntly\cpp\build
+    ..\ext\cmake\bin\cmake .. -G "Visual Studio 9 2008"
+    c:\vs08\common7\tools\vsvars32.bat
+    vcbuild sfntly.sln
+
+We invoke the cmake with `-G` to make sure
+Visual Studio 2008 solution/project files are generated.
+You can also use `devenv sfntly.sln /build`
+to build the solution instead of using `vcbuild`.
+
+There are subtle differences between `devenv` and `vcbuild`.
+Please refer to your Visual Studio manual for more details.
+
+For Visual Studio 2010 (assume its installed at `c:\vs10`)
+
+
+    cd d:\src\sfntly\cpp\build
+    ..\ext\cmake\bin\cmake .. -G "Visual Studio 10"
+    c:\vs10\common7\tools\vsvars32.bat
+    msbuild sfntly.sln
+
+If you install both Visual Studio 2008 and 2010 on your system,
+you cant run the scripts above in the same Command Prompt window.
+`vsvars32.bat` assumes that it is run from a clean Command Prompt.
+
+## Building on Linux/Mac
+
+### Recommended Out-of-Source Building
+
+1.  `cd` *&lt;sfntly dir&gt;*
+2.  `mkdir build`
+3.  `cd build`
+4.  `cmake ..`
+5.  `make`
+
+### Default In-Source Building
+
+> This is not recommended.
+> Please use out-of-source whenever possible.
+
+1.  `cd` *&lt;sfntly dir&gt;*
+2.  `cmake .`
+3.  `make`
+
+### Using clang Instead
+
+Change the `cmake` command line to
+
+    CC=clang CXX=clang++ cmake ..
+
+The generated Makefile will use clang.
+Please note that sfntly uses a lot of advanced C++ semantics that
+might not be understood or compiled correctly by earlier versions
+of clang (2.8 and before).
+   
+sfntly is tested to compile and run correctly on clang 3.0 (trunk 135314).
+clang 2.9 might work but unfortunately we dont have the resource to test it.
+
+### Debug and Release Builds
+
+Currently Debug builds are set as default.
+To build Release builds, you can either modify the `CMakeList.txt`,
+or set environment variable `CMAKE_BUILD_TYPE` to `Release`
+before invoking `cmake`.
+ 
+Windows users can just switch the configuration in Visual Studio.
+ 
+## Running Unit Test
+
+A program named `unit_test` will be generated after a full compilation.
+It expects fonts in `data/ext` to be in the same directory it resides to execute the unit tests.
+Windows users also needs to copy `icudt.dll` and `icuuc.dll` to that directory.
diff --git a/doc/smart_pointer_usage.md b/doc/smart_pointer_usage.md
new file mode 100644
index 0000000..5f77013
--- /dev/null
+++ b/doc/smart_pointer_usage.md
@@ -0,0 +1,145 @@
+Usage of smart pointers in sfntly C++ port
+=========================================================================================================================================================
+
+In sfntly C++ port, an object ref-counting and smart pointer mechanism
+is implemented. The implementation works very much like COM.
+
+Ref-countable object type inherits from RefCounted&lt;&gt;, which have
+addRef() and release() just like IUnknown in COM (but no
+QueryInterface). Ptr&lt;&gt; is a smart pointer class like
+CComPtr&lt;&gt; which is used to hold the ref-countable objects so that
+the object ref count is handled correctly.
+
+Lets take a look at the example:
+
+``` {.prettyprint}
+class Foo : public RefCounted<Foo> {
+ public:
+  static Foo* CreateInstance() {
+    Ptr<Foo> obj = new Foo();  // ref count = 1
+    return obj.detach();  // Giving away the control of this instance.
+  }
+};
+typedef Ptr<Foo> FooPtr;  // Common short-hand notation.
+
+FooPtr obj;
+obj.attach(Foo::CreateInstance());  // ref count = 1
+                                    // Take over control but not bumping
+                                    // ref count.
+{
+  FooPtr obj2 = obj;  // ref count = 2
+                      // Assignment bumps up ref count.
+}  // ref count = 1
+   // obj2 out of scope, decrements ref count
+
+obj.release();  // ref count = 0, object destroyed
+```
+
+Notes on usage
+---------------------------------------------------------------------
+
+-   Virtual inherit from RefCount interface in base class if smart
+    pointers are going to be defined.
+
+<!-- -->
+
+-   All RefCounted objects must be instantiated on the heap. Allocating
+    the object on stack will cause crash.
+
+<!-- -->
+
+-   Be careful when you have complex inheritance. For example,
+
+> In this case the smart pointer is pretty dumb and dont count on it to
+> nicely destroy your objects as designed. Try refactor your code like
+>
+> ``` {.prettyprint}
+> class I;  // the common interface and implementations
+> class A : public I, public RefCounted<A>;  // A specific implementation
+> class B : public I, public RefCounted<B>;  // B specific implementation
+> ```
+
+-   Smart pointers here are very bad candidates for function parameters
+    and return values. Use dumb pointers when passing over the stack.
+
+<!-- -->
+
+-   When down\_cast is performed on a dangling pointer due to bugs in
+    code, VC++ will generate SEH which is not handled well in VC++
+    debugger. One can use WinDBG to run it and get the faulting stack.
+
+<!-- -->
+
+-   Idioms for heap object as return value
+
+> If you are not passing that object back, you are the end of scope.
+
+> Be very careful when using the assignment operator as opposed to
+> attaching. This can easily cause memory leaks. Have a look at [The
+> difference between assignment and attachment with ATL smart
+> pointers](http://blogs.msdn.com/b/oldnewthing/archive/2009/11/20/9925918.aspx).
+> Since were using essentially the same model, it applies in pretty much
+> the same way. The easiest way of knowing when to Attach and when to
+> assign is to check the declaration of the function you are using.
+>
+> ``` {.prettyprint}
+>   // Attach to the pointer returned by GetInstance
+>   static CALLER_ATTACH FontFactory* GetInstance();
+>
+>   // Assign pointer returned by NewCMapBuilder 
+>   CMap::Builder* NewCMapBuilder(const CMapId& cmap_id,
+>                                 ReadableFontData* data);
+> ```
+
+Detecting Memory Leak
+------------------------------------------------------------------------------------------
+
+> The implementation of COM-like ref-counting and smart pointer remedies
+> the lack of garbage collector in C++ to certain extent, however, it
+> also introduces other problems. The most common one is memory leakage.
+> How do we know that our code leak memory or not?
+
+-   For Linux/Mac, valgrind
+    [http://valgrind.org](http://valgrind.org/)
+    is very useful.
+-   For Windows, the easiest is to use Visual C++ built-in CRT debugging
+    [http://msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.80).aspx](http://msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.80).aspx)
+
+Useful Tips for Debugging Ref-Couting Issue
+------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+-   Define `ENABLE_OBJECT_COUNTER` and `REF_COUNT_DEBUGGING`. All
+    ref-count related activity will be ouput to stderr.
+
+<!-- -->
+
+-   The logs will look like (under VC2010)
+
+> Use your favorite editor to transform them into SQL statements, e.g.
+> Regex pattern
+>
+> ``` {.prettyprint}
+> ^([ACDR]) class RefCounted<class sfntly::([A-Za-z0-9:]+)>[ *const]+:oc=([-0-9]+),oid=([0-9]+),rc=([-0-9]+)
+> ```
+
+> Replace to
+>
+> ``` {.prettyprint}
+> insert into log values(\1, \2, \3, \4, \5);
+> ```
+
+-   Add one line to the beginning of log
+
+<!-- -->
+
+-   Run sqlite shell, use .read to input the SQL file.
+
+<!-- -->
+
+-   Run following commands to get the leaking object class and object
+    id:
+
+<!-- -->
+
+-   Once you know which object is leaking, its much easier to setup
+    conditional breakpoints to identify the real culprit.
diff --git a/doc/unit_tests.md b/doc/unit_tests.md
new file mode 100644
index 0000000..0426979
--- /dev/null
+++ b/doc/unit_tests.md
@@ -0,0 +1,32 @@
+[]{#Unit_Test}Unit Test[](#Unit_Test){.section_anchor}
+======================================================
+
+sfntly C++ port uses Google testing framework for unit testing.
+
+All test cases are under src/test.
+
+To run the unit test, you need to compile sfntly first, then copy
+Tuffy.ttf from data/ext to the folder that unit\_test(.exe) is located.
+Run the unit\_test.
+
+If you are only interested in one test case, for example, you are
+working on name table and only wants name editing test, you can use the
+gtest\_filter flag in command line.
+
+``` {.prettyprint}
+unit_test --gtest_filter=NameEditing.*
+```
+
+For more info regarding running a subset of gtest, please see [GTest
+Advanced
+Guide](http://code.google.com/p/googletest/wiki/V1_6_AdvancedGuide).
+
+Its strongly suggested to run unit\_tests with valgrind. The following
+example shows a typical test command
+
+``` {.prettyprint}
+valgrind --leak-check=full -v ./unit_test --gtest_filter=*.*-FontData.*
+```
+
+FontData tests are the longest and you may want to bypass them during
+development. They shall be run in bots, however.