/*
|
* 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
|
*
|
* http://www.apache.org/licenses/LICENSE-2.0
|
*
|
* Unless required by applicable law or agreed to in writing, software
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* See the License for the specific language governing permissions and
|
* limitations under the License.
|
*/
|
|
#ifndef SFNTLY_CPP_SRC_SFNTLY_FONT_H_
|
#define SFNTLY_CPP_SRC_SFNTLY_FONT_H_
|
|
#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> {
|
public:
|
// 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> {
|
public:
|
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();
|
}
|
|
private:
|
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);
|
|
private:
|
// 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
|
|
#endif // SFNTLY_CPP_SRC_SFNTLY_FONT_H_
|