aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-05 22:12:11 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-03-05 22:12:11 +0000
commit5bfc8396228b7a9e5be679aeb10f30860adf938f (patch)
tree606192f0cba0680fdf78dd9d0633513ed605f23f /src
parent90ee4488e9c6b8ec4cb1137250fed43b5919ce2c (diff)
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
Diffstat (limited to 'src')
-rw-r--r--src/core/SkFontStream.cpp50
-rw-r--r--src/core/SkFontStream.h17
-rw-r--r--src/ports/SkFontHost_fontconfig.cpp29
3 files changed, 76 insertions, 20 deletions
diff --git a/src/core/SkFontStream.cpp b/src/core/SkFontStream.cpp
index b6a5d6b119..ccdc1c7dd1 100644
--- a/src/core/SkFontStream.cpp
+++ b/src/core/SkFontStream.cpp
@@ -43,7 +43,9 @@ struct SkSFNTDirEntry {
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 @@ static int count_tables(SkStream* stream, size_t* offsetToDir = NULL) {
// 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 @@ struct SfntHeader {
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 @@ struct SfntHeader {
///////////////////////////////////////////////////////////////////////////////
-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 @@ int SkFontStream::GetTableTags(SkStream* stream, SkFontTableTag tags[]) {
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 283aee077f..9cd51fc708 100644
--- a/src/core/SkFontStream.h
+++ b/src/core/SkFontStream.h
@@ -15,16 +15,29 @@ class SkStream;
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 fef1bab96c..7f6997a745 100644
--- a/src/ports/SkFontHost_fontconfig.cpp
+++ b/src/ports/SkFontHost_fontconfig.cpp
@@ -247,16 +247,21 @@ SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
///////////////////////////////////////////////////////////////////////////////
-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 @@ SkStream* SkFontHost::OpenStream(uint32_t id) {
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 @@ size_t SkFontHost::GetFileName(SkFontID fontID, char path[], size_t length,
///////////////////////////////////////////////////////////////////////////////
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 {