Update to 10-17-11 snapshot

git-svn-id: http://sfntly.googlecode.com/svn/trunk/cpp/src@103 672e30a5-4c29-85ac-ac6d-611c735e0a51
diff --git a/sfntly/data/readable_font_data.cc b/sfntly/data/readable_font_data.cc
index bb58c26..06d783f 100644
--- a/sfntly/data/readable_font_data.cc
+++ b/sfntly/data/readable_font_data.cc
@@ -257,21 +257,25 @@
 CALLER_ATTACH FontData* ReadableFontData::Slice(int32_t offset,
                                                 int32_t length) {
   if (offset < 0 || offset + length > Size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundsException(
+        "Attempt to bind data outside of its limits");
+#endif
     return NULL;
   }
   FontDataPtr slice = new ReadableFontData(this, offset, length);
-  // Note: exception not ported because the condition is always false in C++.
-  // if (slice == null) { throw new IndexOutOfBoundsException( ...
   return slice.Detach();
 }
 
 CALLER_ATTACH FontData* ReadableFontData::Slice(int32_t offset) {
   if (offset < 0 || offset > Size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundsException(
+        "Attempt to bind data outside of its limits");
+#endif
     return NULL;
   }
   FontDataPtr slice = new ReadableFontData(this, offset);
-  // Note: exception not ported because the condition is always false in C++.
-  // if (slice == null) { throw new IndexOutOfBoundsException( ...
   return slice.Detach();
 }
 
diff --git a/sfntly/data/writable_font_data.cc b/sfntly/data/writable_font_data.cc
index ace387c..7f6f72f 100644
--- a/sfntly/data/writable_font_data.cc
+++ b/sfntly/data/writable_font_data.cc
@@ -166,21 +166,25 @@
 CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset,
                                                 int32_t length) {
   if (offset < 0 || offset + length > Size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundsException(
+        "Attempt to bind data outside of its limits");
+#endif
     return NULL;
   }
   FontDataPtr slice = new WritableFontData(this, offset, length);
-  // Note: exception not ported because the condition is always false in C++.
-  // if (slice == null) { throw new IndexOutOfBoundsException( ...
   return slice.Detach();
 }
 
 CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset) {
   if (offset > Size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+    throw IndexOutOfBoundsException(
+        "Attempt to bind data outside of its limits");
+#endif
     return NULL;
   }
   FontDataPtr slice = new WritableFontData(this, offset);
-  // Note: exception not ported because the condition is always false in C++.
-  // if (slice == null) { throw new IndexOutOfBoundsException( ...
   return slice.Detach();
 }
 
diff --git a/sfntly/table/bitmap/bitmap_size_table.cc b/sfntly/table/bitmap/bitmap_size_table.cc
index 5e0c237..bde903a 100644
--- a/sfntly/table/bitmap/bitmap_size_table.cc
+++ b/sfntly/table/bitmap/bitmap_size_table.cc
@@ -316,6 +316,15 @@
   return sub_table_list->at(index);
 }
 
+CALLER_ATTACH BitmapGlyphInfo* BitmapSizeTable::Builder::GlyphInfo(
+    int32_t glyph_id) {
+  IndexSubTable::Builder* sub_table = SearchIndexSubTables(glyph_id);
+  if (sub_table == NULL) {
+    return NULL;
+  }
+  return sub_table->GlyphInfo(glyph_id);
+}
+
 int32_t BitmapSizeTable::Builder::GlyphOffset(int32_t glyph_id) {
   IndexSubTable::Builder* subtable = SearchIndexSubTables(glyph_id);
   if (subtable == NULL) {
@@ -384,6 +393,31 @@
 
 IndexSubTable::Builder* BitmapSizeTable::Builder::SearchIndexSubTables(
     int32_t glyph_id) {
+  // would be faster to binary search but too many size tables don't have
+  // sorted subtables
+#if (SFNTLY_BITMAPSIZE_USE_BINARY_SEARCH)
+  return BinarySearchIndexSubTables(glyph_id);
+#else
+  return LinearSearchIndexSubTables(glyph_id);
+#endif
+}
+
+IndexSubTable::Builder* BitmapSizeTable::Builder::LinearSearchIndexSubTables(
+    int32_t glyph_id) {
+  IndexSubTableBuilderList* subtable_list = GetIndexSubTableBuilders();
+  for (IndexSubTableBuilderList::iterator b = subtable_list->begin(),
+                                          e = subtable_list->end();
+                                          b != e; b++) {
+    if ((*b)->first_glyph_index() <= glyph_id &&
+        (*b)->last_glyph_index() >= glyph_id) {
+      return *b;
+    }
+  }
+  return NULL;
+}
+
+IndexSubTable::Builder* BitmapSizeTable::Builder::BinarySearchIndexSubTables(
+    int32_t glyph_id) {
   IndexSubTableBuilderList* subtable_list = GetIndexSubTableBuilders();
   int32_t index = 0;
   int32_t bottom = 0;
diff --git a/sfntly/table/bitmap/bitmap_size_table.h b/sfntly/table/bitmap/bitmap_size_table.h
index 2bc91da..4f4a961 100644
--- a/sfntly/table/bitmap/bitmap_size_table.h
+++ b/sfntly/table/bitmap/bitmap_size_table.h
@@ -98,6 +98,7 @@
 
     // Note: renamed from indexSubTable()
     IndexSubTable::Builder* GetIndexSubTable(int32_t index);
+    CALLER_ATTACH BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
     int32_t GlyphOffset(int32_t glyph_id);
     int32_t GlyphLength(int32_t glyph_id);
     int32_t GlyphFormat(int32_t glyph_id);
@@ -115,6 +116,8 @@
 
     void SetNumberOfIndexSubTables(int32_t count);
     IndexSubTable::Builder* SearchIndexSubTables(int32_t glyph_id);
+    IndexSubTable::Builder* LinearSearchIndexSubTables(int32_t glyph_id);
+    IndexSubTable::Builder* BinarySearchIndexSubTables(int32_t glyph_id);
     IndexSubTableBuilderList* GetIndexSubTableBuilders();
     void Initialize(ReadableFontData* data);
     CALLER_ATTACH IndexSubTable::Builder* CreateIndexSubTableBuilder(
diff --git a/sfntly/table/bitmap/ebdt_table.cc b/sfntly/table/bitmap/ebdt_table.cc
index 19e5e55..eeb1fa0 100644
--- a/sfntly/table/bitmap/ebdt_table.cc
+++ b/sfntly/table/bitmap/ebdt_table.cc
@@ -222,7 +222,7 @@
         BitmapGlyphInfoPtr info = entry->second;
         ReadableFontDataPtr slice;
         slice.Attach(down_cast<ReadableFontData*>(data->Slice(
-            info->start_offset(), info->length())));
+            info->offset(), info->length())));
         BitmapGlyphBuilderPtr glyph_builder;
         glyph_builder.Attach(BitmapGlyph::Builder::CreateGlyphBuilder(
             slice, info->format()));
diff --git a/sfntly/table/bitmap/index_sub_table.cc b/sfntly/table/bitmap/index_sub_table.cc
index 66d2d83..80c0ffe 100644
--- a/sfntly/table/bitmap/index_sub_table.cc
+++ b/sfntly/table/bitmap/index_sub_table.cc
@@ -104,6 +104,17 @@
   Initialize(InternalReadData());
 }
 
+CALLER_ATTACH BitmapGlyphInfo* IndexSubTable::Builder::GlyphInfo(
+    int32_t glyph_id) {
+  BitmapGlyphInfoPtr glyph_info =
+      new BitmapGlyphInfo(glyph_id,
+                          image_data_offset(),
+                          GlyphStartOffset(glyph_id),
+                          GlyphLength(glyph_id),
+                          image_format());
+  return glyph_info.Detach();
+}
+
 int32_t IndexSubTable::Builder::GlyphOffset(int32_t glyph_id) {
   return image_data_offset() + GlyphStartOffset(glyph_id);
 }
diff --git a/sfntly/table/bitmap/index_sub_table.h b/sfntly/table/bitmap/index_sub_table.h
index c2be7d1..0993e76 100644
--- a/sfntly/table/bitmap/index_sub_table.h
+++ b/sfntly/table/bitmap/index_sub_table.h
@@ -45,6 +45,11 @@
 
     virtual int32_t NumGlyphs() = 0;
 
+    // Gets the glyph info for the specified glyph id.
+    // @param glyphId the glyph id to look up
+    // @return the glyph info
+    CALLER_ATTACH virtual BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
+
     // Gets the full offset of the glyph within the EBDT table.
     // @param glyphId the glyph id
     // @return the glyph offset
diff --git a/test/subsetter_impl.cc b/test/subsetter_impl.cc
index 7934085..292e83f 100644
--- a/test/subsetter_impl.cc
+++ b/test/subsetter_impl.cc
@@ -315,15 +315,9 @@
       for (IntegerSet::const_iterator gid = glyph_ids.begin(),
                                       gid_end = glyph_ids.end();
                                       gid != gid_end; gid++) {
-        if ((*index_builders)[j]->first_glyph_index() <= *gid &&
-            (*index_builders)[j]->last_glyph_index() >= *gid &&
-            (*index_builders)[j]->GlyphStartOffset(*gid) != -1) {
-          BitmapGlyphInfoPtr info =
-              new BitmapGlyphInfo(*gid,
-                                  (*index_builders)[j]->image_data_offset() +
-                                  (*index_builders)[j]->GlyphStartOffset(*gid),
-                                  (*index_builders)[j]->GlyphLength(*gid),
-                                  (*index_builders)[j]->image_format());
+        BitmapGlyphInfoPtr info;
+        info.Attach((*index_builders)[j]->GlyphInfo(*gid));
+        if (info) {
           info_map[*gid] = info;
         }
       }
@@ -356,6 +350,12 @@
   return true;
 }
 
+/******************************************************************************
+ * EXPERIMENTAL CODE STARTS
+ *
+ * The following code is used for experiment.  Will obsolete once we have
+ * support to create format 4 and 5 index sub tables from scratch.
+ *****************************************************************************/
 void GenerateOffsetArray(int32_t first_gid, int32_t last_gid,
                          const BitmapGlyphInfoMap& loca,
                          IntegerList* new_offsets) {
@@ -378,12 +378,6 @@
   }
 }
 
-/******************************************************************************
- * EXPERIMENTAL CODE STARTS
- *
- * The following code is used for experiment.  Will obsolete once we have
- * support to create format 4 and 5 index sub tables from scratch.
- *****************************************************************************/
 void SubsetIndexSubTableFormat1(IndexSubTable::Builder* b,
                                 const BitmapGlyphInfoMap& loca) {
   IndexSubTableFormat1BuilderPtr builder =