start to plumb ttcIndex into fonthost. For now just add to SkFontStream and its callers.
Review URL: https://codereview.chromium.org/12485002

git-svn-id: http://skia.googlecode.com/svn/trunk@7998 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkFontStream.cpp b/src/core/SkFontStream.cpp
index b6a5d6b..ccdc1c7 100644
--- a/src/core/SkFontStream.cpp
+++ b/src/core/SkFontStream.cpp
@@ -43,7 +43,9 @@
 
     On an error, return 0 for number of tables, and ignore offsetToDir
  */
-static int count_tables(SkStream* stream, size_t* offsetToDir = NULL) {
+static int count_tables(SkStream* stream, int ttcIndex, size_t* offsetToDir) {
+    SkASSERT(ttcIndex >= 0);
+
     SkSharedTTHeader shared;
     if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
         return 0;
@@ -55,11 +57,20 @@
     // if we're really a collection, the first 4-bytes will be 'ttcf'
     uint32_t tag = SkEndian_SwapBE32(shared.fCollection.fTag);
     if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) {
-        if (shared.fCollection.fNumOffsets == 0) {
+        unsigned count = SkEndian_SwapBE32(shared.fCollection.fNumOffsets);
+        if ((unsigned)ttcIndex >= count) {
             return 0;
         }
-        // this is the offset to the first local SkSFNTHeader
-        offset = SkEndian_SwapBE32(shared.fCollection.fOffset0);
+        
+        if (ttcIndex > 0) { // need to read more of the shared header
+            stream->rewind();
+            size_t amount = sizeof(shared) + ttcIndex * sizeof(uint32_t);
+            if (stream->read(&shared, amount) != amount) {
+                return 0;
+            }
+        }
+        // this is the offset to the local SkSFNTHeader
+        offset = SkEndian_SwapBE32((&shared.fCollection.fOffset0)[ttcIndex]);
         stream->rewind();
         if (stream->skip(offset) != offset) {
             return 0;
@@ -88,11 +99,11 @@
 
         fDir will be automatically freed when this object is destroyed
      */
-    bool init(SkStream* stream) {
+    bool init(SkStream* stream, int ttcIndex) {
         stream->rewind();
 
         size_t offsetToDir;
-        fCount = count_tables(stream, &offsetToDir);
+        fCount = count_tables(stream, ttcIndex, &offsetToDir);
         if (0 == fCount) {
             return false;
         }
@@ -113,9 +124,27 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-int SkFontStream::GetTableTags(SkStream* stream, SkFontTableTag tags[]) {
+int SkFontStream::CountTTCEntries(SkStream* stream) {
+    stream->rewind();
+
+    SkSharedTTHeader shared;
+    if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
+        return 0;
+    }
+
+    // if we're really a collection, the first 4-bytes will be 'ttcf'
+    uint32_t tag = SkEndian_SwapBE32(shared.fCollection.fTag);
+    if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) {
+        return SkEndian_SwapBE32(shared.fCollection.fNumOffsets);
+    } else {
+        return 0;
+    }        
+}
+
+int SkFontStream::GetTableTags(SkStream* stream, int ttcIndex,
+                               SkFontTableTag tags[]) {
     SfntHeader  header;
-    if (!header.init(stream)) {
+    if (!header.init(stream, ttcIndex)) {
         return 0;
     }
 
@@ -127,10 +156,11 @@
     return header.fCount;
 }
 
-size_t SkFontStream::GetTableData(SkStream* stream, SkFontTableTag tag,
+size_t SkFontStream::GetTableData(SkStream* stream, int ttcIndex,
+                                  SkFontTableTag tag,
                                   size_t offset, size_t length, void* data) {
     SfntHeader  header;
-    if (!header.init(stream)) {
+    if (!header.init(stream, ttcIndex)) {
         return 0;
     }
 
diff --git a/src/core/SkFontStream.h b/src/core/SkFontStream.h
index 283aee0..9cd51fc 100644
--- a/src/core/SkFontStream.h
+++ b/src/core/SkFontStream.h
@@ -15,16 +15,29 @@
 class SkFontStream {
 public:
     /**
+     *  Return the number of shared 'fonts' inside a TTC sfnt, or return 0
+     *  if the stream is a normal sfnt (not a TTC).
+     *
      *  Note: the stream is rewound initially, but is returned at an arbitrary
      *  read offset.
      */
-    static int GetTableTags(SkStream*, SkFontTableTag tags[]);
+    static int CountTTCEntries(SkStream*);
 
     /**
+     *  @param ttcIndex 0 for normal sfnts, or the index within a TTC sfnt.
+     *
      *  Note: the stream is rewound initially, but is returned at an arbitrary
      *  read offset.
      */
-    static size_t GetTableData(SkStream*, SkFontTableTag tag,
+    static int GetTableTags(SkStream*, int ttcIndex, SkFontTableTag tags[]);
+
+    /**
+     *  @param ttcIndex 0 for normal sfnts, or the index within a TTC sfnt.
+     *
+     *  Note: the stream is rewound initially, but is returned at an arbitrary
+     *  read offset.
+     */
+    static size_t GetTableData(SkStream*, int ttcIndex, SkFontTableTag tag,
                                size_t offset, size_t length, void* data);
 };
 
diff --git a/src/ports/SkFontHost_fontconfig.cpp b/src/ports/SkFontHost_fontconfig.cpp
index fef1bab..7f6997a 100644
--- a/src/ports/SkFontHost_fontconfig.cpp
+++ b/src/ports/SkFontHost_fontconfig.cpp
@@ -247,16 +247,21 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkStream* open_stream(const FontConfigTypeface* face) {
+static SkStream* open_stream(const FontConfigTypeface* face, int* ttcIndex) {
     SkStream* stream = face->getLocalStream();
+    int index;
     if (stream) {
         stream->ref();
+        // should have been provided by CreateFromStream()
+        *ttcIndex = 0;
     } else {
         SkAutoTUnref<SkFontConfigInterface> fci(RefFCI());
         if (NULL == fci.get()) {
             return NULL;
         }
         stream = fci->openStream(face->getIdentity());
+        // ttcIndex should be returned explicitly by openStream()
+        *ttcIndex = (int)face->getIdentity().fIntPtr;
     }
     return stream;
 }
@@ -266,7 +271,10 @@
     if (NULL == face) {
         return NULL;
     }
-    return open_stream(face);
+    
+    int ttcIndex;
+    // We should return ttcIndex from this call.
+    return open_stream(face, &ttcIndex);
 }
 
 size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
@@ -292,16 +300,21 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 int FontConfigTypeface::onGetTableTags(SkFontTableTag tags[]) const {
-    SkAutoTUnref<SkStream> stream(open_stream(this));
-    return stream.get() ? SkFontStream::GetTableTags(stream, tags) : 0;
+    int ttcIndex;
+    SkAutoTUnref<SkStream> stream(open_stream(this, &ttcIndex));
+    return stream.get()
+                ? SkFontStream::GetTableTags(stream, ttcIndex, tags)
+                : 0;
 }
 
 size_t FontConfigTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
                                   size_t length, void* data) const {
-    SkAutoTUnref<SkStream> stream(open_stream(this));
-    return stream.get() ?
-               SkFontStream::GetTableData(stream, tag, offset, length, data) :
-               0;
+    int ttcIndex;
+    SkAutoTUnref<SkStream> stream(open_stream(this, &ttcIndex));
+    return stream.get()
+                ? SkFontStream::GetTableData(stream, ttcIndex,
+                                             tag, offset, length, data)
+                : 0;
 }
 
 void FontConfigTypeface::onGetFontDescriptor(SkFontDescriptor* desc) const {