blob: 2220adb39d833997726959a9c8c4244befd1bb4a [file] [log] [blame]
* 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
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* See the License for the specific language governing permissions and
* limitations under the License.
#include <vector>
#include "sfntly/port/refcount.h"
#include "sfntly/port/type.h"
#include "sfntly/port/endian.h"
#include "sfntly/data/font_input_stream.h"
#include "sfntly/data/font_output_stream.h"
#include "sfntly/data/writable_font_data.h"
#include "sfntly/table/table.h"
namespace sfntly {
// Note: following constants are embedded in Font class in Java. They are
// extracted out for easier reference from other classes. Offset is the
// one that is kept within class.
// Platform ids. These are used in a number of places within the font whenever
// the platform needs to be specified.
struct PlatformId {
enum {
kUnknown = -1,
kUnicode = 0,
kMacintosh = 1,
kISO = 2,
kWindows = 3,
kCustom = 4
// Unicode encoding ids. These are used in a number of places within the font
// whenever character encodings need to be specified.
struct UnicodeEncodingId {
enum {
kUnknown = -1,
kUnicode1_0 = 0,
kUnicode1_1 = 1,
kISO10646 = 2,
kUnicode2_0_BMP = 3,
kUnicode2_0 = 4,
kUnicodeVariationSequences = 5
// Windows encoding ids. These are used in a number of places within the font
// whenever character encodings need to be specified.
struct WindowsEncodingId {
enum {
kUnknown = 0xffffffff,
kSymbol = 0,
kUnicodeUCS2 = 1,
kShiftJIS = 2,
kPRC = 3,
kBig5 = 4,
kWansung = 5,
kJohab = 6,
kUnicodeUCS4 = 10
// Macintosh encoding ids. These are used in a number of places within the
// font whenever character encodings need to be specified.
struct MacintoshEncodingId {
// Macintosh Platform Encodings
enum {
kUnknown = -1,
kRoman = 0,
kJapanese = 1,
kChineseTraditional = 2,
kKorean = 3,
kArabic = 4,
kHebrew = 5,
kGreek = 6,
kRussian = 7,
kRSymbol = 8,
kDevanagari = 9,
kGurmukhi = 10,
kGujarati = 11,
kOriya = 12,
kBengali = 13,
kTamil = 14,
kTelugu = 15,
kKannada = 16,
kMalayalam = 17,
kSinhalese = 18,
kBurmese = 19,
kKhmer = 20,
kThai = 21,
kLaotian = 22,
kGeorgian = 23,
kArmenian = 24,
kChineseSimplified = 25,
kTibetan = 26,
kMongolian = 27,
kGeez = 28,
kSlavic = 29,
kVietnamese = 30,
kSindhi = 31,
kUninterpreted = 32
class FontFactory;
// An sfnt container font object. This object is immutable and thread safe. To
// construct one use an instance of Font::Builder.
class Font : public RefCounted<Font> {
// A builder for a font object. The builder allows the for the creation of
// immutable Font objects. The builder is a one use non-thread safe object and
// once the Font object has been created it is no longer usable. To create a
// further Font object new builder will be required.
class Builder : public RefCounted<Builder> {
virtual ~Builder();
static CALLER_ATTACH Builder*
GetOTFBuilder(FontFactory* factory, InputStream* is);
static CALLER_ATTACH Builder*
GetOTFBuilder(FontFactory* factory,
WritableFontData* ba,
int32_t offset_to_offset_table);
static CALLER_ATTACH Builder* GetOTFBuilder(FontFactory* factory);
// Get the font factory that created this font builder.
FontFactory* GetFontFactory() { return factory_; }
// Is the font ready to build?
bool ReadyToBuild();
// Build the Font. After this call this builder will no longer be usable.
CALLER_ATTACH Font* Build();
// Set a unique fingerprint for the font object.
void SetDigest(ByteVector* digest);
// Clear all table builders.
void ClearTableBuilders();
// Does this font builder have the specified table builder.
bool HasTableBuilder(int32_t tag);
// Get the table builder for the given tag. If there is no builder for that
// tag then return a null.
Table::Builder* GetTableBuilder(int32_t tag);
// Creates a new table builder for the table type given by the table id tag.
// This new table has been added to the font and will replace any existing
// builder for that table.
// @return new empty table of the type specified by tag; if tag is not known
// then a generic OpenTypeTable is returned
virtual Table::Builder* NewTableBuilder(int32_t tag);
// Creates a new table builder for the table type given by the table id tag.
// It makes a copy of the data provided and uses that copy for the table.
// This new table has been added to the font and will replace any existing
// builder for that table.
virtual Table::Builder* NewTableBuilder(int32_t tag,
ReadableFontData* src_data);
// Get a map of the table builders in this font builder accessed by table
// tag.
virtual TableBuilderMap* table_builders() { return &table_builders_; }
// Remove the specified table builder from the font builder.
// Note: different from Java: we don't return object in removeTableBuilder
virtual void RemoveTableBuilder(int32_t tag);
// Get the number of table builders in the font builder.
virtual int32_t number_of_table_builders() {
return (int32_t)table_builders_.size();
explicit Builder(FontFactory* factory);
virtual void LoadFont(InputStream* is);
virtual void LoadFont(WritableFontData* wfd,
int32_t offset_to_offset_table);
int32_t SfntWrapperSize();
void BuildAllTableBuilders(DataBlockMap* table_data,
TableBuilderMap* builder_map);
CALLER_ATTACH Table::Builder*
GetTableBuilder(Header* header, WritableFontData* data);
void BuildTablesFromBuilders(Font* font,
TableBuilderMap* builder_map,
TableMap* tables);
static void InterRelateBuilders(TableBuilderMap* builder_map);
void ReadHeader(FontInputStream* is,
HeaderOffsetSortedSet* records);
void ReadHeader(ReadableFontData* fd,
int32_t offset,
HeaderOffsetSortedSet* records);
void LoadTableData(HeaderOffsetSortedSet* headers,
FontInputStream* is,
DataBlockMap* table_data);
void LoadTableData(HeaderOffsetSortedSet* headers,
WritableFontData* fd,
DataBlockMap* table_data);
TableBuilderMap table_builders_;
FontFactory* factory_; // dumb pointer, avoid circular refcounting
int32_t sfnt_version_;
int32_t num_tables_;
int32_t search_range_;
int32_t entry_selector_;
int32_t range_shift_;
DataBlockMap data_blocks_;
ByteVector digest_;
virtual ~Font();
// Gets the sfnt version set in the sfnt wrapper of the font.
int32_t sfnt_version() { return sfnt_version_; }
// 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_; }
// Get the checksum for this font.
int64_t checksum() { return checksum_; }
// Get the number of tables in this font.
int32_t num_tables() { return (int32_t)tables_.size(); }
// Whether the font has a particular table.
bool HasTable(int32_t tag) const;
// UNIMPLEMENTED: public Iterator<? extends Table> iterator
// Get the table in this font with the specified id.
// @param tag the identifier of the table
// @return the table specified if it exists; null otherwise
// C++ port: rename table() to GetTable()
Table* GetTable(int32_t tag);
// Get a map of the tables in this font accessed by table tag.
// @return an unmodifiable view of the tables in this font
// Note: renamed tableMap() to GetTableMap()
const TableMap* GetTableMap();
// UNIMPLEMENTED: toString()
// 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);
// Offsets to specific elements in the underlying data. These offsets are
// relative to the start of the table or the start of sub-blocks within the
// table.
struct Offset {
enum {
// Offsets within the main directory
kSfntVersion = 0,
kNumTables = 4,
kSearchRange = 6,
kEntrySelector = 8,
kRangeShift = 10,
kTableRecordBegin = 12,
kSfntHeaderSize = 12,
// Offsets within a specific table record
kTableTag = 0,
kTableCheckSum = 4,
kTableOffset = 8,
kTableLength = 12,
kTableRecordSize = 16
// Note: the two constants are moved to tag.h to avoid VC++ bug.
// static const int32_t CFF_TABLE_ORDERING[];
// static const int32_t TRUE_TYPE_TABLE_ORDERING[];
// Constructor.
// @param sfntVersion the sfnt version
// @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);
// 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
// sorted in the order specified and only those specified will have headers
// generated.
// @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,
TableHeaderList* table_headers);
// Searialize the headers.
// @param fos the destination stream for the headers
// @param tableHeaders the headers to serialize
// @throws IOException
void SerializeHeader(FontOutputStream* fos, TableHeaderList* table_headers);
// Serialize the tables.
// @param fos the destination stream for the headers
// @param tableHeaders the headers for the tables to serialize
// @throws IOException
void SerializeTables(FontOutputStream* fos, TableHeaderList* table_headers);
// Generate the full table ordering to used for serialization. The full
// ordering uses the partial ordering as a seed and then adds all remaining
// tables in the font in an undefined order.
// @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);
// 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);
int32_t sfnt_version_;
ByteVector digest_;
int64_t checksum_;
TableMap tables_;
typedef Ptr<Font> FontPtr;
typedef std::vector<FontPtr> FontArray;
typedef Ptr<Font::Builder> FontBuilderPtr;
typedef std::vector<FontBuilderPtr> FontBuilderArray;
} // namespace sfntly