'<(skia_src_path)/core/SkFontHost.cpp',
'<(skia_src_path)/core/SkFontDescriptor.cpp',
'<(skia_src_path)/core/SkFontDescriptor.h',
+ '<(skia_src_path)/core/SkFontStream.cpp',
+ '<(skia_src_path)/core/SkFontStream.h',
'<(skia_src_path)/core/SkGeometry.cpp',
'<(skia_src_path)/core/SkGlyphCache.cpp',
'<(skia_src_path)/core/SkGlyphCache.h',
--- /dev/null
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkEndian.h"
+#include "SkFontStream.h"
+#include "SkStream.h"
+
+struct SkSFNTHeader {
+ uint32_t fVersion;
+ uint16_t fNumTables;
+ uint16_t fSearchRange;
+ uint16_t fEntrySelector;
+ uint16_t fRangeShift;
+};
+
+struct SkTTCFHeader {
+ uint32_t fTag;
+ uint32_t fVersion;
+ uint32_t fNumOffsets;
+ uint32_t fOffset0; // the first of N (fNumOffsets)
+};
+
+union SkSharedTTHeader {
+ SkSFNTHeader fSingle;
+ SkTTCFHeader fCollection;
+};
+
+struct SkSFNTDirEntry {
+ uint32_t fTag;
+ uint32_t fChecksum;
+ uint32_t fOffset;
+ uint32_t fLength;
+};
+
+/** Return the number of tables, or if this is a TTC (collection), return the
+ number of tables in the first element of the collection. In either case,
+ if offsetToDir is not-null, set it to the offset to the beginning of the
+ table headers (SkSFNTDirEntry), relative to the start of the stream.
+
+ On an error, return 0 for number of tables, and ignore offsetToDir
+ */
+static int count_tables(SkStream* stream, size_t* offsetToDir = NULL) {
+ SkSharedTTHeader shared;
+ if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
+ return 0;
+ }
+
+ // by default, SkSFNTHeader is at the start of the stream
+ size_t offset = 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) {
+ if (shared.fCollection.fNumOffsets == 0) {
+ return 0;
+ }
+ // this is the offset to the first local SkSFNTHeader
+ offset = SkEndian_SwapBE32(shared.fCollection.fOffset0);
+ stream->rewind();
+ if (stream->skip(offset) != offset) {
+ return 0;
+ }
+ if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
+ return 0;
+ }
+ }
+
+ if (offsetToDir) {
+ // add the size of the header, so we will point to the DirEntries
+ *offsetToDir = offset + sizeof(SkSFNTHeader);
+ }
+ return SkEndian_SwapBE16(shared.fSingle.fNumTables);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+struct SfntHeader {
+ SfntHeader() : fCount(0), fDir(NULL) {}
+ ~SfntHeader() { sk_free(fDir); }
+
+ /** If it returns true, then fCount and fDir are properly initialized.
+ Note: fDir will point to the raw array of SkSFNTDirEntry values,
+ meaning they will still be in the file's native endianness (BE).
+
+ fDir will be automatically freed when this object is destroyed
+ */
+ bool init(SkStream* stream) {
+ size_t offsetToDir;
+ fCount = count_tables(stream, &offsetToDir);
+ if (0 == fCount) {
+ return false;
+ }
+
+ stream->rewind();
+ if (stream->skip(offsetToDir) != offsetToDir) {
+ return false;
+ }
+
+ size_t size = fCount * sizeof(SkSFNTDirEntry);
+ fDir = reinterpret_cast<SkSFNTDirEntry*>(sk_malloc_throw(size));
+ return stream->read(fDir, size) == size;
+ }
+
+ int fCount;
+ SkSFNTDirEntry* fDir;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+int SkFontStream::GetTableTags(SkStream* stream, SkFontTableTag tags[]) {
+ SfntHeader header;
+ if (!header.init(stream)) {
+ return 0;
+ }
+
+ if (tags) {
+ for (int i = 0; i < header.fCount; i++) {
+ tags[i] = SkEndian_SwapBE32(header.fDir[i].fTag);
+ }
+ }
+ return header.fCount;
+}
+
+size_t SkFontStream::GetTableData(SkStream* stream, SkFontTableTag tag,
+ size_t offset, size_t length, void* data) {
+ SfntHeader header;
+ if (!header.init(stream)) {
+ return 0;
+ }
+
+ for (int i = 0; i < header.fCount; i++) {
+ if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) {
+ size_t realOffset = SkEndian_SwapBE32(header.fDir[i].fOffset);
+ size_t realLength = SkEndian_SwapBE32(header.fDir[i].fLength);
+ // now sanity check the caller's offset/length
+ if (offset >= realLength) {
+ return 0;
+ }
+ // if the caller is trusting the length from the file, then a
+ // hostile file might choose a value which would overflow offset +
+ // length.
+ if (offset + length < offset) {
+ return 0;
+ }
+ if (length > realLength - offset) {
+ length = realLength - offset;
+ }
+ if (data) {
+ // skip the stream to the part of the table we want to copy from
+ stream->rewind();
+ size_t bytesToSkip = realOffset + offset;
+ if (stream->skip(bytesToSkip) != bytesToSkip) {
+ return 0;
+ }
+ if (stream->read(data, length) != length) {
+ return 0;
+ }
+ }
+ return length;
+ }
+ }
+ return 0;
+}
+
+
--- /dev/null
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkFontStream_DEFINED
+#define SkFontStream_DEFINED
+
+class SkStream;
+
+#include "SkTypeface.h"
+
+class SkFontStream {
+public:
+ static int GetTableTags(SkStream*, SkFontTableTag tags[]);
+ static size_t GetTableData(SkStream*, SkFontTableTag tag,
+ size_t offset, size_t length, void* data);
+};
+
+#endif
+
+
-
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
+
#include "SkEndian.h"
#include "SkFontHost.h"
+#include "SkFontStream.h"
#include "SkStream.h"
-struct SkSFNTHeader {
- uint32_t fVersion;
- uint16_t fNumTables;
- uint16_t fSearchRange;
- uint16_t fEntrySelector;
- uint16_t fRangeShift;
-};
-
-struct SkTTCFHeader {
- uint32_t fTag;
- uint32_t fVersion;
- uint32_t fNumOffsets;
- uint32_t fOffset0; // the first of N (fNumOffsets)
-};
-
-union SkSharedTTHeader {
- SkSFNTHeader fSingle;
- SkTTCFHeader fCollection;
-};
-
-struct SkSFNTDirEntry {
- uint32_t fTag;
- uint32_t fChecksum;
- uint32_t fOffset;
- uint32_t fLength;
-};
-
-/** Return the number of tables, or if this is a TTC (collection), return the
- number of tables in the first element of the collection. In either case,
- if offsetToDir is not-null, set it to the offset to the beginning of the
- table headers (SkSFNTDirEntry), relative to the start of the stream.
-
- On an error, return 0 for number of tables, and ignore offsetToDir
- */
-static int count_tables(SkStream* stream, size_t* offsetToDir = NULL) {
- SkSharedTTHeader shared;
- if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
- return 0;
- }
-
- // by default, SkSFNTHeader is at the start of the stream
- size_t offset = 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) {
- if (shared.fCollection.fNumOffsets == 0) {
- return 0;
- }
- // this is the offset to the first local SkSFNTHeader
- offset = SkEndian_SwapBE32(shared.fCollection.fOffset0);
- stream->rewind();
- if (stream->skip(offset) != offset) {
- return 0;
- }
- if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
- return 0;
- }
- }
-
- if (offsetToDir) {
- // add the size of the header, so we will point to the DirEntries
- *offsetToDir = offset + sizeof(SkSFNTHeader);
- }
- return SkEndian_SwapBE16(shared.fSingle.fNumTables);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-struct SfntHeader {
- SfntHeader() : fCount(0), fDir(NULL) {}
- ~SfntHeader() { sk_free(fDir); }
-
- /** If it returns true, then fCount and fDir are properly initialized.
- Note: fDir will point to the raw array of SkSFNTDirEntry values,
- meaning they will still be in the file's native endianness (BE).
-
- fDir will be automatically freed when this object is destroyed
- */
- bool init(SkStream* stream) {
- size_t offsetToDir;
- fCount = count_tables(stream, &offsetToDir);
- if (0 == fCount) {
- return false;
- }
-
- stream->rewind();
- if (stream->skip(offsetToDir) != offsetToDir) {
- return false;
- }
-
- size_t size = fCount * sizeof(SkSFNTDirEntry);
- fDir = reinterpret_cast<SkSFNTDirEntry*>(sk_malloc_throw(size));
- return stream->read(fDir, size) == size;
- }
-
- int fCount;
- SkSFNTDirEntry* fDir;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
int SkFontHost::CountTables(SkFontID fontID) {
SkStream* stream = SkFontHost::OpenStream(fontID);
if (NULL == stream) {
}
SkAutoUnref au(stream);
- return count_tables(stream);
+ return SkFontStream::GetTableTags(stream, NULL);
}
int SkFontHost::GetTableTags(SkFontID fontID, SkFontTableTag tags[]) {
}
SkAutoUnref au(stream);
- SfntHeader header;
- if (!header.init(stream)) {
- return 0;
- }
-
- for (int i = 0; i < header.fCount; i++) {
- tags[i] = SkEndian_SwapBE32(header.fDir[i].fTag);
- }
- return header.fCount;
+ return SkFontStream::GetTableTags(stream, tags);
}
size_t SkFontHost::GetTableSize(SkFontID fontID, SkFontTableTag tag) {
}
SkAutoUnref au(stream);
- SfntHeader header;
- if (!header.init(stream)) {
- return 0;
- }
-
- for (int i = 0; i < header.fCount; i++) {
- if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) {
- return SkEndian_SwapBE32(header.fDir[i].fLength);
- }
- }
- return 0;
+ return SkFontStream::GetTableData(stream, tag, 0, ~0U, NULL);
}
size_t SkFontHost::GetTableData(SkFontID fontID, SkFontTableTag tag,
}
SkAutoUnref au(stream);
- SfntHeader header;
- if (!header.init(stream)) {
- return 0;
- }
-
- for (int i = 0; i < header.fCount; i++) {
- if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) {
- size_t realOffset = SkEndian_SwapBE32(header.fDir[i].fOffset);
- size_t realLength = SkEndian_SwapBE32(header.fDir[i].fLength);
- // now sanity check the caller's offset/length
- if (offset >= realLength) {
- return 0;
- }
- // if the caller is trusting the length from the file, then a
- // hostile file might choose a value which would overflow offset +
- // length.
- if (offset + length < offset) {
- return 0;
- }
- if (offset + length > realLength) {
- length = realLength - offset;
- }
- // skip the stream to the part of the table we want to copy from
- stream->rewind();
- size_t bytesToSkip = realOffset + offset;
- if (stream->skip(bytesToSkip) != bytesToSkip) {
- return 0;
- }
- if (stream->read(data, length) != length) {
- return 0;
- }
- return length;
- }
- }
- return 0;
+ return SkFontStream::GetTableData(stream, tag, offset, length, data);
}
+
+