Get rid of the useless sfntly

This commit is contained in:
Kovid Goyal 2012-11-06 12:35:35 +05:30
commit 491bfc24bb
127 changed files with 0 additions and 21938 deletions

View File

@ -47,12 +47,6 @@ License: Apache 2.0
The full text of the Apache 2.0 license is available at:
http://www.apache.org/licenses/LICENSE-2.0
Files: src/sfntly/*
Copyright: Google Inc.
License: Apache 2.0
The full text of the Apache 2.0 license is available at:
http://www.apache.org/licenses/LICENSE-2.0
Files: resources/viewer/mathjax/*
Copyright: Unknown
License: Apache 2.0

View File

@ -11,7 +11,6 @@ let g:syntastic_cpp_include_dirs = [
\'/usr/include/freetype2',
\'/usr/include/fontconfig',
\'src/qtcurve/common', 'src/qtcurve',
\'src/sfntly/src', 'src/sfntly/src/sample',
\'/usr/include/ImageMagick',
\]
let g:syntastic_c_include_dirs = g:syntastic_cpp_include_dirs

View File

@ -19,7 +19,6 @@ from setup.build_environment import (chmlib_inc_dirs,
magick_libs, chmlib_lib_dirs, sqlite_inc_dirs, icu_inc_dirs,
icu_lib_dirs, win_ddk_lib_dirs, ft_libs, ft_lib_dirs, ft_inc_dirs,
zlib_libs, zlib_lib_dirs, zlib_inc_dirs)
from setup.sfntly import SfntlyBuilderMixin
MT
isunix = islinux or isosx or isbsd
@ -63,26 +62,8 @@ if isosx:
icu_libs = ['icucore']
icu_cflags = ['-DU_DISABLE_RENAMING'] # Needed to use system libicucore.dylib
class SfntlyExtension(Extension, SfntlyBuilderMixin):
def __init__(self, *args, **kwargs):
Extension.__init__(self, *args, **kwargs)
SfntlyBuilderMixin.__init__(self)
def preflight(self, *args, **kwargs):
self(*args, **kwargs)
extensions = [
SfntlyExtension('sfntly',
['calibre/utils/fonts/sfntly.cpp'],
headers= ['calibre/utils/fonts/sfntly.h'],
libraries=icu_libs,
lib_dirs=icu_lib_dirs,
inc_dirs=icu_inc_dirs,
cflags=icu_cflags
),
Extension('speedup',
['calibre/utils/speedup.c'],
),

View File

@ -1,93 +0,0 @@
#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:fdm=marker:ai
from __future__ import (unicode_literals, division, absolute_import,
print_function)
__license__ = 'GPL v3'
__copyright__ = '2012, Kovid Goyal <kovid at kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import shlex, os
from glob import glob
from setup import iswindows
class Group(object):
def __init__(self, name, base, build_base, cflags):
self.name = name
self.cflags = cflags
self.headers = frozenset(glob(os.path.join(base, '*.h')))
self.src_files = glob(os.path.join(base, '*.cc'))
self.bdir = os.path.abspath(os.path.join(build_base, name))
if not os.path.exists(self.bdir):
os.makedirs(self.bdir)
self.objects = [os.path.join(self.bdir,
os.path.basename(x).rpartition('.')[0] + ('.obj' if iswindows else
'.o')) for x in self.src_files]
def __call__(self, compiler, linker, builder, all_headers):
for src, obj in zip(self.src_files, self.objects):
if builder.newer(obj, [src] + list(all_headers)):
sinc = ['/Tp'+src] if iswindows else ['-c', src]
oinc = ['/Fo'+obj] if iswindows else ['-o', obj]
cmd = [compiler] + self.cflags + sinc + oinc
builder.info(' '.join(cmd))
builder.check_call(cmd)
class SfntlyBuilderMixin(object):
def __init__(self):
self.sfntly_cflags = [
'-DSFNTLY_NO_EXCEPTION',
'-DSFNTLY_EXPERIMENTAL',
]
if iswindows:
self.sfntly_cflags += [
'-D_UNICODE', '-DUNICODE',
] + shlex.split('/W4 /WX /Gm- /Gy /GR-')
self.cflags += ['-DWIN32']
else:
# Possibly add -fno-inline (slower, but more robust)
self.sfntly_cflags += [
'-Werror',
'-fno-exceptions',
]
if len(self.libraries) > 1:
self.libraries = ['icuuc']
if not iswindows:
self.libraries += ['pthread']
def __call__(self, obj_dir, compiler, linker, builder, cflags, ldflags):
self.sfntly_build_dir = os.path.join(obj_dir, 'sfntly')
if '/Ox' in cflags:
cflags.remove('/Ox')
if '-O3' in cflags:
cflags.remove('-O3')
if '/W3' in cflags:
cflags.remove('/W3')
if '-ggdb' not in cflags:
cflags.insert(0, '/O2' if iswindows else '-O2')
groups = []
all_headers = set()
all_objects = []
src_dir = self.absolutize([os.path.join('sfntly', 'src')])[0]
inc_dirs = [src_dir]
self.inc_dirs += inc_dirs
inc_flags = builder.inc_dirs_to_cflags(self.inc_dirs)
for loc in ('', 'port', 'data', 'math', 'table', 'table/bitmap',
'table/core', 'table/truetype'):
path = os.path.join(src_dir, 'sfntly', *loc.split('/'))
gr = Group(loc, path, self.sfntly_build_dir, cflags+
inc_flags+self.sfntly_cflags+self.cflags)
groups.append(gr)
all_headers |= gr.headers
all_objects.extend(gr.objects)
for group in groups:
group(compiler, linker, builder, all_headers)
self.extra_objs = all_objects

View File

@ -91,7 +91,6 @@ class Plugins(collections.Mapping):
'speedup',
'freetype',
'woff',
'sfntly',
]
if iswindows:
plugins.extend(['winutil', 'wpd', 'winfonts'])

View File

@ -37,11 +37,6 @@ def test_freetype():
test()
print ('FreeType OK!')
def test_sfntly():
from calibre.utils.fonts.subset import test
test()
print ('sfntly OK!')
def test_winutil():
from calibre.devices.scanner import win_pnp_drives
matches = win_pnp_drives.scanner()
@ -120,7 +115,6 @@ def test():
test_plugins()
test_lxml()
test_freetype()
test_sfntly()
test_sqlite()
test_imaging()
test_unrar()

View File

@ -1,628 +0,0 @@
/*
* sfntly.cpp
* Copyright (C) 2012 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#define _UNICODE
#define UNICODE
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "sfntly.h"
#include <new>
#include <sfntly/port/memory_input_stream.h>
#include <sfntly/port/memory_output_stream.h>
static PyObject *Error = NULL;
static PyObject *NoGlyphs = NULL;
static PyObject *UnsupportedFont = NULL;
// Predicates {{{
CompositePredicate::CompositePredicate(IntegerSet &chars, IntegerList &ranges) :
chars(chars), ranges(ranges) {}
CompositePredicate::~CompositePredicate() {}
bool CompositePredicate::operator()(int32_t character) const {
for (size_t i = 0; i < ranges.size()/2; i++) {
if (ranges[2*i] <= character && character <= ranges[2*i+1]) return true;
}
return chars.count(character) > 0;
}
// }}}
// Font Info {{{
GlyphId::GlyphId(int32_t glyph_id, FontId font_id) : glyph_id_(glyph_id), font_id_(font_id) {}
GlyphId::~GlyphId() {}
bool GlyphId::operator==(const GlyphId& other) const { return glyph_id_ == other.glyph_id(); }
bool GlyphId::operator<(const GlyphId& other) const { return glyph_id_ < other.glyph_id(); }
int32_t GlyphId::glyph_id() const { return glyph_id_; }
void GlyphId::set_glyph_id(const int32_t glyph_id) { glyph_id_ = glyph_id; }
FontId GlyphId::font_id() const { return font_id_; }
void GlyphId::set_font_id(const FontId font_id) { font_id_ = font_id; }
FontInfo::FontInfo() : chars_to_glyph_ids_(new CharacterMap),
resolved_glyph_ids_(new GlyphIdSet), fonts_(new FontIdMap) { }
FontInfo::FontInfo(CharacterMap* chars_to_glyph_ids,
GlyphIdSet* resolved_glyph_ids,
FontIdMap* fonts) {
chars_to_glyph_ids_ = new CharacterMap(chars_to_glyph_ids->begin(),
chars_to_glyph_ids->end());
resolved_glyph_ids_ = new GlyphIdSet(resolved_glyph_ids->begin(),
resolved_glyph_ids->end());
fonts_ = new FontIdMap(fonts->begin(), fonts->end());
}
FontInfo::~FontInfo() {
delete chars_to_glyph_ids_;
delete resolved_glyph_ids_;
delete fonts_;
}
FontDataTable* FontInfo::GetTable(FontId font_id, int32_t tag) {
if (!fonts_)
return NULL;
FontIdMap::iterator it = fonts_->find(font_id);
if (it == fonts_->end())
return NULL;
return it->second->GetTable(tag);
}
const TableMap* FontInfo::GetTableMap(FontId font_id) {
if (!fonts_)
return NULL;
FontIdMap::iterator it = fonts_->find(font_id);
if (it == fonts_->end())
return NULL;
return it->second->GetTableMap();
}
CharacterMap* FontInfo::chars_to_glyph_ids() const { return chars_to_glyph_ids_; }
void FontInfo::set_chars_to_glyph_ids(CharacterMap* chars_to_glyph_ids) { *chars_to_glyph_ids_ = *chars_to_glyph_ids; }
GlyphIdSet* FontInfo::resolved_glyph_ids() const { return resolved_glyph_ids_; }
void FontInfo::set_resolved_glyph_ids(GlyphIdSet* resolved_glyph_ids) { *resolved_glyph_ids_ = *resolved_glyph_ids; }
FontIdMap* FontInfo::fonts() const { return fonts_; }
void FontInfo::set_fonts(FontIdMap* fonts) { *fonts_ = *fonts; }
FontSourcedInfoBuilder::FontSourcedInfoBuilder(Font* font, FontId font_id) : font_(font), font_id_(font_id),
predicate_(NULL) { Initialize(); }
FontSourcedInfoBuilder::FontSourcedInfoBuilder(Font* font,
FontId font_id,
CharacterPredicate* predicate) :
font_(font), font_id_(font_id), predicate_(predicate) { Initialize(); }
FontSourcedInfoBuilder::~FontSourcedInfoBuilder() { }
CALLER_ATTACH FontInfo* FontSourcedInfoBuilder::GetFontInfo() {
if (!cmap_) {
PyErr_SetString(UnsupportedFont, "This font has no format 4 cmap table (usually symbol or asian fonts), subsetting is not supported");
return NULL;
}
CharacterMap* chars_to_glyph_ids = new CharacterMap;
bool success = GetCharacterMap(chars_to_glyph_ids);
if (!success) {
delete chars_to_glyph_ids;
if (!PyErr_Occurred()) PyErr_SetString(Error, "Error creating character map.\n");
return NULL;
}
GlyphIdSet* resolved_glyph_ids = new GlyphIdSet;
success = ResolveCompositeGlyphs(chars_to_glyph_ids, resolved_glyph_ids);
if (!success) {
delete chars_to_glyph_ids;
delete resolved_glyph_ids;
if (!PyErr_Occurred()) PyErr_SetString(Error, "Error resolving composite glyphs.\n");
return NULL;
}
Ptr<FontInfo> font_info = new FontInfo;
font_info->set_chars_to_glyph_ids(chars_to_glyph_ids);
font_info->set_resolved_glyph_ids(resolved_glyph_ids);
FontIdMap* font_id_map = new FontIdMap;
font_id_map->insert(std::make_pair(font_id_, font_));
font_info->set_fonts(font_id_map);
delete chars_to_glyph_ids;
delete resolved_glyph_ids;
delete font_id_map;
return font_info.Detach();
}
bool FontSourcedInfoBuilder::GetCharacterMap(CharacterMap* chars_to_glyph_ids) {
if (!cmap_ || !chars_to_glyph_ids)
return false;
chars_to_glyph_ids->clear();
CMapTable::CMap::CharacterIterator* character_iterator = cmap_->Iterator();
if (!character_iterator)
return false;
while (character_iterator->HasNext()) {
int32_t character = character_iterator->Next();
if (!predicate_ || (*predicate_)(character)) {
chars_to_glyph_ids->insert
(std::make_pair(character,
GlyphId(cmap_->GlyphId(character), font_id_)));
}
}
delete character_iterator;
return true;
}
bool FontSourcedInfoBuilder::ResolveCompositeGlyphs(CharacterMap* chars_to_glyph_ids,
GlyphIdSet* resolved_glyph_ids) {
if (!chars_to_glyph_ids || !resolved_glyph_ids)
return false;
resolved_glyph_ids->clear();
resolved_glyph_ids->insert(GlyphId(0, font_id_));
IntegerSet* unresolved_glyph_ids = new IntegerSet;
// Since composite glyph elements might themselves be composite, we would need
// to recursively resolve the elements too. To avoid the recursion we
// create two sets, |unresolved_glyph_ids| for the unresolved glyphs,
// initially containing all the ids and |resolved_glyph_ids|, initially empty.
// We'll remove glyph ids from |unresolved_glyph_ids| until it is empty and,
// if the glyph is composite, add its elements to the unresolved set.
for (CharacterMap::iterator it = chars_to_glyph_ids->begin(),
e = chars_to_glyph_ids->end(); it != e; ++it) {
unresolved_glyph_ids->insert(it->second.glyph_id());
}
// As long as there are unresolved glyph ids.
while (!unresolved_glyph_ids->empty()) {
// Get the corresponding glyph.
if (!loca_table_) {
PyErr_SetString(UnsupportedFont, "This font does not have a loca table. Subsetting is not supported for fonts without loca tables (usually OTF fonts with PostScript (CFF) outlines).");
return false;
}
int32_t glyph_id = *(unresolved_glyph_ids->begin());
unresolved_glyph_ids->erase(unresolved_glyph_ids->begin());
if (glyph_id < 0 || glyph_id > loca_table_->num_glyphs()) {
continue;
}
int32_t length = loca_table_->GlyphLength(glyph_id);
if (length == 0) {
continue;
}
int32_t offset = loca_table_->GlyphOffset(glyph_id);
GlyphPtr glyph;
if (!glyph_table_) {
PyErr_SetString(UnsupportedFont, "This font does not have a glyf table. Subsetting is not supported for fonts without glyf tables (usually OTF fonts with PostScript (CFF) outlines).");
return false;
}
glyph.Attach(glyph_table_->GetGlyph(offset, length));
if (glyph == NULL) {
continue;
}
// Mark the glyph as resolved.
resolved_glyph_ids->insert(GlyphId(glyph_id, font_id_));
// If it is composite, add all its components to the unresolved glyph set.
if (glyph->GlyphType() == GlyphType::kComposite) {
Ptr<GlyphTable::CompositeGlyph> composite_glyph =
down_cast<GlyphTable::CompositeGlyph*>(glyph.p_);
int32_t num_glyphs = composite_glyph->NumGlyphs();
for (int32_t i = 0; i < num_glyphs; ++i) {
int32_t glyph_id = composite_glyph->GlyphIndex(i);
if (resolved_glyph_ids->find(GlyphId(glyph_id, -1))
== resolved_glyph_ids->end()) {
unresolved_glyph_ids->insert(glyph_id);
}
}
}
}
delete unresolved_glyph_ids;
return true;
}
void FontSourcedInfoBuilder::Initialize() {
Ptr<CMapTable> cmap_table = down_cast<CMapTable*>(font_->GetTable(Tag::cmap));
// We prefer Windows BMP format 4 cmaps.
cmap_.Attach(cmap_table->GetCMap(CMapTable::WINDOWS_BMP));
// But if none is found,
if (!cmap_) {
return;
}
loca_table_ = down_cast<LocaTable*>(font_->GetTable(Tag::loca));
glyph_table_ = down_cast<GlyphTable*>(font_->GetTable(Tag::glyf));
}
// }}}
// Font Assembler {{{
FontAssembler::FontAssembler(FontInfo* font_info, IntegerSet* table_blacklist) :
table_blacklist_(table_blacklist) {
font_info_ = font_info;
Initialize();
}
FontAssembler::FontAssembler(FontInfo* font_info) : table_blacklist_(NULL) {
font_info_ = font_info;
Initialize();
}
FontAssembler::~FontAssembler() { }
// Assemble a new font from the font info object.
CALLER_ATTACH Font* FontAssembler::Assemble() {
// Assemble tables we can subset.
if (!AssembleCMapTable() || !AssembleGlyphAndLocaTables()) {
return NULL;
}
// For all other tables, either include them unmodified or don't at all.
const TableMap* common_table_map =
font_info_->GetTableMap(font_info_->fonts()->begin()->first);
for (TableMap::const_iterator it = common_table_map->begin(),
e = common_table_map->end(); it != e; ++it) {
if (table_blacklist_
&& table_blacklist_->find(it->first) != table_blacklist_->end()) {
continue;
}
font_builder_->NewTableBuilder(it->first, it->second->ReadFontData());
}
return font_builder_->Build();
}
IntegerSet* FontAssembler::table_blacklist() const { return table_blacklist_; }
void FontAssembler::set_table_blacklist(IntegerSet* table_blacklist) {
table_blacklist_ = table_blacklist;
}
bool FontAssembler::AssembleCMapTable() {
// Creating the new CMapTable and the new format 4 CMap
Ptr<CMapTable::Builder> cmap_table_builder =
down_cast<CMapTable::Builder*>
(font_builder_->NewTableBuilder(Tag::cmap));
if (!cmap_table_builder)
return false;
Ptr<CMapTable::CMapFormat4::Builder> cmap_builder =
down_cast<CMapTable::CMapFormat4::Builder*>
(cmap_table_builder->NewCMapBuilder(CMapFormat::kFormat4,
CMapTable::WINDOWS_BMP));
if (!cmap_builder)
return false;
// Creating the segments and the glyph id array
CharacterMap* chars_to_glyph_ids = font_info_->chars_to_glyph_ids();
SegmentList* segment_list = new SegmentList;
IntegerList* glyph_id_array = new IntegerList;
int32_t last_chararacter = -2;
int32_t last_offset = 0;
Ptr<CMapTable::CMapFormat4::Builder::Segment> current_segment;
// For simplicity, we will have one segment per contiguous range.
// To test the algorithm, we've replaced the original CMap with the CMap
// generated by this code without removing any character.
// Tuffy.ttf: CMap went from 3146 to 3972 bytes (1.7% to 2.17% of file)
// AnonymousPro.ttf: CMap went from 1524 to 1900 bytes (0.96% to 1.2%)
for (CharacterMap::iterator it = chars_to_glyph_ids->begin(),
e = chars_to_glyph_ids->end(); it != e; ++it) {
int32_t character = it->first;
int32_t glyph_id = it->second.glyph_id();
if (character != last_chararacter + 1) { // new segment
if (current_segment != NULL) {
current_segment->set_end_count(last_chararacter);
segment_list->push_back(current_segment);
}
// start_code = character
// end_code = -1 (unknown for now)
// id_delta = 0 (we don't use id_delta for this representation)
// id_range_offset = last_offset (offset into the glyph_id_array)
current_segment =
new CMapTable::CMapFormat4::Builder::
Segment(character, -1, 0, last_offset);
}
glyph_id_array->push_back(glyph_id);
last_offset += DataSize::kSHORT;
last_chararacter = character;
}
// The last segment is still open.
if (glyph_id_array->size() < 1) {
PyErr_SetString(NoGlyphs, "No glyphs for the specified characters found");
return false;
}
current_segment->set_end_count(last_chararacter);
segment_list->push_back(current_segment);
// Updating the id_range_offset for every segment.
for (int32_t i = 0, num_segs = segment_list->size(); i < num_segs; ++i) {
Ptr<CMapTable::CMapFormat4::Builder::Segment> segment = segment_list->at(i);
segment->set_id_range_offset(segment->id_range_offset()
+ (num_segs - i + 1) * DataSize::kSHORT);
}
// Adding the final, required segment.
current_segment =
new CMapTable::CMapFormat4::Builder::Segment(0xffff, 0xffff, 1, 0);
segment_list->push_back(current_segment);
// Writing the segments and glyph id array to the CMap
cmap_builder->set_segments(segment_list);
cmap_builder->set_glyph_id_array(glyph_id_array);
delete segment_list;
delete glyph_id_array;
return true;
}
bool FontAssembler::AssembleGlyphAndLocaTables() {
Ptr<LocaTable::Builder> loca_table_builder =
down_cast<LocaTable::Builder*>
(font_builder_->NewTableBuilder(Tag::loca));
Ptr<GlyphTable::Builder> glyph_table_builder =
down_cast<GlyphTable::Builder*>
(font_builder_->NewTableBuilder(Tag::glyf));
GlyphIdSet* resolved_glyph_ids = font_info_->resolved_glyph_ids();
IntegerList loca_list;
// Basic sanity check: all LOCA tables are of the same size
// This is necessary but not sufficient!
int32_t previous_size = -1;
for (FontIdMap::iterator it = font_info_->fonts()->begin();
it != font_info_->fonts()->end(); ++it) {
Ptr<LocaTable> loca_table =
down_cast<LocaTable*>(font_info_->GetTable(it->first, Tag::loca));
int32_t current_size = loca_table->header_length();
if (previous_size != -1 && current_size != previous_size) {
return false;
}
previous_size = current_size;
}
// Assuming all fonts referenced by the FontInfo are the subsets of the same
// font, their loca tables should all have the same sizes.
// We'll just get the size of the first font's LOCA table for simplicty.
Ptr<LocaTable> first_loca_table =
down_cast<LocaTable*>
(font_info_->GetTable(font_info_->fonts()->begin()->first, Tag::loca));
int32_t num_loca_glyphs = first_loca_table->num_glyphs();
loca_list.resize(num_loca_glyphs);
loca_list.push_back(0);
int32_t last_glyph_id = 0;
int32_t last_offset = 0;
GlyphTable::GlyphBuilderList* glyph_builders =
glyph_table_builder->GlyphBuilders();
for (GlyphIdSet::iterator it = resolved_glyph_ids->begin(),
e = resolved_glyph_ids->end(); it != e; ++it) {
// Get the glyph for this resolved_glyph_id.
int32_t resolved_glyph_id = it->glyph_id();
int32_t font_id = it->font_id();
// Get the LOCA table for the current glyph id.
Ptr<LocaTable> loca_table =
down_cast<LocaTable*>
(font_info_->GetTable(font_id, Tag::loca));
int32_t length = loca_table->GlyphLength(resolved_glyph_id);
int32_t offset = loca_table->GlyphOffset(resolved_glyph_id);
// Get the GLYF table for the current glyph id.
Ptr<GlyphTable> glyph_table =
down_cast<GlyphTable*>
(font_info_->GetTable(font_id, Tag::glyf));
GlyphPtr glyph;
glyph.Attach(glyph_table->GetGlyph(offset, length));
// The data reference by the glyph is copied into a new glyph and
// added to the glyph_builders belonging to the glyph_table_builder.
// When Build gets called, all the glyphs will be built.
Ptr<ReadableFontData> data = glyph->ReadFontData();
Ptr<WritableFontData> copy_data;
copy_data.Attach(WritableFontData::CreateWritableFontData(data->Length()));
data->CopyTo(copy_data);
GlyphBuilderPtr glyph_builder;
glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data));
glyph_builders->push_back(glyph_builder);
// If there are missing glyphs between the last glyph_id and the
// current resolved_glyph_id, since the LOCA table needs to have the same
// size, the offset is kept the same.
for (int32_t i = last_glyph_id + 1; i <= resolved_glyph_id; ++i)
loca_list[i] = last_offset;
last_offset += length;
loca_list[resolved_glyph_id + 1] = last_offset;
last_glyph_id = resolved_glyph_id + 1;
}
// If there are missing glyph ids, their loca entries must all point
// to the same offset as the last valid glyph id making them all zero length.
for (int32_t i = last_glyph_id + 1; i <= num_loca_glyphs; ++i)
loca_list[i] = last_offset;
loca_table_builder->SetLocaList(&loca_list);
return true;
}
void FontAssembler::Initialize() {
font_factory_.Attach(FontFactory::GetInstance());
font_builder_.Attach(font_factory_->NewFontBuilder());
}
// }}}
// Subsetters {{{
// Subsets a given font using a character predicate.
PredicateSubsetter::PredicateSubsetter(Font* font, CharacterPredicate* predicate) : font_(font), predicate_(predicate) {}
PredicateSubsetter::~PredicateSubsetter() { }
// Performs subsetting returning the subsetted font.
CALLER_ATTACH Font* PredicateSubsetter::Subset() {
Ptr<FontSourcedInfoBuilder> info_builder =
new FontSourcedInfoBuilder(font_, 0, predicate_);
Ptr<FontInfo> font_info;
font_info.Attach(info_builder->GetFontInfo());
if (!font_info) {
if (!PyErr_Occurred()) PyErr_SetString(Error, "Could not create font info");
return NULL;
}
IntegerSet* table_blacklist = new IntegerSet;
table_blacklist->insert(Tag::DSIG);
Ptr<FontAssembler> font_assembler = new FontAssembler(font_info,
table_blacklist);
Ptr<Font> font_subset;
font_subset.Attach(font_assembler->Assemble());
delete table_blacklist;
if (!font_subset) { if (!PyErr_Occurred()) PyErr_SetString(Error, "Could not subset font"); }
return font_subset.Detach();
}
// }}}
static void get_stats(Font *font, PyObject *dict) {
PyObject *t;
const TableMap* tables = font->GetTableMap();
for (TableMap::const_iterator it = tables->begin(),
e = tables->end(); it != e; ++it) {
t = PyInt_FromLong(it->second->DataLength());
if (t != NULL) {
PyDict_SetItemString(dict, TagToString(it->first), t);
Py_DECREF(t);
}
}
}
static PyObject*
do_subset(const char *data, Py_ssize_t sz, Ptr<CharacterPredicate> &predicate) {
FontPtr font;
Ptr<FontFactory> font_factory;
FontArray fonts;
MemoryInputStream stream;
PyObject *stats, *stats2;
if (!stream.Attach(reinterpret_cast<const byte_t*>(data), sz))
return PyErr_NoMemory();
font_factory.Attach(FontFactory::GetInstance());
font_factory->LoadFonts(&stream, &fonts);
if (fonts.empty() || fonts[0] == NULL) {
PyErr_SetString(Error, "Failed to load font from provided data.");
return NULL;
}
font = fonts[0];
if (font->num_tables() == 0) {
PyErr_SetString(Error, "Loaded font has 0 tables.");
return NULL;
}
Ptr<CMapTable> cmap_table = down_cast<CMapTable*>(font->GetTable(Tag::cmap));
if (!cmap_table) {
PyErr_SetString(Error, "Loaded font has no cmap table.");
return NULL;
}
Ptr<PredicateSubsetter> subsetter = new PredicateSubsetter(font, predicate);
Ptr<Font> new_font;
new_font.Attach(subsetter->Subset());
if (!new_font) return NULL;
Ptr<FontFactory> ff;
ff.Attach(FontFactory::GetInstance());
MemoryOutputStream output_stream;
ff->SerializeFont(new_font, &output_stream);
stats = PyDict_New(); stats2 = PyDict_New();
if (stats == NULL || stats2 == NULL) return PyErr_NoMemory();
get_stats(font, stats);
get_stats(new_font, stats2);
return Py_BuildValue("s#NN", (char*)output_stream.Get(), output_stream.Size(), stats, stats2);
}
static PyObject*
subset(PyObject *self, PyObject *args) {
const char *data;
Py_ssize_t sz;
PyObject *individual_chars, *ranges, *t;
int32_t temp;
if (!PyArg_ParseTuple(args, "s#OO", &data, &sz, &individual_chars, &ranges)) return NULL;
if (!PyTuple_Check(individual_chars) || !PyTuple_Check(ranges)) {
PyErr_SetString(PyExc_TypeError, "individual_chars and ranges must be tuples");
return NULL;
}
if (PyTuple_Size(ranges) < 1 && PyTuple_Size(individual_chars) < 1) {
PyErr_SetString(NoGlyphs, "No characters specified");
return NULL;
}
IntegerSet chars;
for (Py_ssize_t i = 0; i < PyTuple_Size(individual_chars); i++) {
temp = (int32_t)PyInt_AsLong(PyTuple_GET_ITEM(individual_chars, i));
if (temp == -1 && PyErr_Occurred()) return NULL;
chars.insert(temp);
}
IntegerList cranges;
cranges.resize(2*PyTuple_Size(ranges));
for (Py_ssize_t i = 0; i < PyTuple_Size(ranges); i++) {
t = PyTuple_GET_ITEM(ranges, i);
if (!PyTuple_Check(t) || PyTuple_Size(t) != 2) {
PyErr_SetString(PyExc_TypeError, "ranges must contain only 2-tuples");
return NULL;
}
for (Py_ssize_t j = 0; j < 2; j++) {
cranges[2*i+j] = (int32_t)PyInt_AsLong(PyTuple_GET_ITEM(t, j));
if (cranges[2*i+j] == -1 && PyErr_Occurred()) return NULL;
}
}
Ptr<CharacterPredicate> predicate = new (std::nothrow) CompositePredicate(chars, cranges);
if (predicate == NULL) return PyErr_NoMemory();
try {
return do_subset(data, sz, predicate);
} catch (std::exception &e) {
PyErr_SetString(Error, e.what());
return NULL;
} catch (...) {
PyErr_SetString(Error, "An unknown exception occurred while subsetting");
return NULL;
}
}
static
PyMethodDef methods[] = {
{"subset", (PyCFunction)subset, METH_VARARGS,
"subset(bytestring, individual_chars, ranges) -> Subset the sfnt in bytestring, keeping only characters specified by individual_chars and ranges. Returns the subset font as a bytestring and the sizes of all font tables in the old and new fonts."
},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC
initsfntly(void) {
PyObject *m;
m = Py_InitModule3(
"sfntly", methods,
"Wrapper for the Google sfntly library"
);
if (m == NULL) return;
Error = PyErr_NewException((char*)"sfntly.Error", NULL, NULL);
if (Error == NULL) return;
PyModule_AddObject(m, "Error", Error);
NoGlyphs = PyErr_NewException((char*)"sfntly.NoGlyphs", NULL, NULL);
if (NoGlyphs == NULL) return;
PyModule_AddObject(m, "NoGlyphs", NoGlyphs);
UnsupportedFont = PyErr_NewException((char*)"sfntly.UnsupportedFont", NULL, NULL);
if (UnsupportedFont == NULL) return;
PyModule_AddObject(m, "UnsupportedFont", UnsupportedFont);
}

View File

@ -1,196 +0,0 @@
/*
* sfntly.h
* Copyright (C) 2012 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#pragma once
#include <map>
#include <set>
#include <sfntly/tag.h>
#include <sfntly/font.h>
#include <sfntly/font_factory.h>
#include <sfntly/port/exception_type.h>
#include <sfntly/table/truetype/loca_table.h>
#include <sfntly/table/truetype/glyph_table.h>
#include <sfntly/tools/subsetter/subsetter.h>
using namespace sfntly;
typedef int32_t FontId;
typedef std::map<FontId, Ptr<Font> > FontIdMap;
class CharacterPredicate : virtual public RefCount {
public:
CharacterPredicate() {}
virtual ~CharacterPredicate() {}
virtual bool operator()(int32_t character) const = 0;
};
class CompositePredicate : public CharacterPredicate,
public RefCounted<CompositePredicate> {
public:
CompositePredicate(IntegerSet &chars, IntegerList &ranges);
~CompositePredicate();
virtual bool operator()(int32_t character) const;
private:
IntegerSet chars;
IntegerList ranges;
};
// Glyph id pair that contains the loca table glyph id as well as the
// font id that has the glyph table this glyph belongs to.
class GlyphId {
public:
GlyphId(int32_t glyph_id, FontId font_id);
~GlyphId();
bool operator==(const GlyphId& other) const;
bool operator<(const GlyphId& other) const;
int32_t glyph_id() const;
void set_glyph_id(const int32_t glyph_id);
FontId font_id() const;
void set_font_id(const FontId font_id);
private:
int32_t glyph_id_;
FontId font_id_;
};
typedef std::map<int32_t, GlyphId> CharacterMap;
typedef std::set<GlyphId> GlyphIdSet;
// Font information used for FontAssembler in the construction of a new font.
// Will make copies of character map, glyph id set and font id map.
class FontInfo : public RefCounted<FontInfo> {
public:
// Empty FontInfo object.
FontInfo();
// chars_to_glyph_ids maps characters to GlyphIds for CMap construction
// resolved_glyph_ids defines GlyphIds which should be in the final font
// fonts is a map of font ids to fonts to reference any needed table
FontInfo(CharacterMap* chars_to_glyph_ids,
GlyphIdSet* resolved_glyph_ids,
FontIdMap* fonts);
virtual ~FontInfo();
// Gets the table with the specified tag from the font corresponding to
// font_id or NULL if there is no such font/table.
// font_id is the id of the font that contains the table
// tag identifies the table to be obtained
virtual FontDataTable* GetTable(FontId font_id, int32_t tag);
// Gets the table map of the font whose id is font_id
virtual const TableMap* GetTableMap(FontId font_id);
CharacterMap* chars_to_glyph_ids() const;
// Takes ownership of the chars_to_glyph_ids CharacterMap.
void set_chars_to_glyph_ids(CharacterMap* chars_to_glyph_ids);
GlyphIdSet* resolved_glyph_ids() const;
// Takes ownership of the glyph_ids GlyphIdSet.
void set_resolved_glyph_ids(GlyphIdSet* resolved_glyph_ids);
FontIdMap* fonts() const;
// Takes ownership of the fonts FontIdMap.
void set_fonts(FontIdMap* fonts);
private:
CharacterMap* chars_to_glyph_ids_;
GlyphIdSet* resolved_glyph_ids_;
FontIdMap* fonts_;
};
// FontSourcedInfoBuilder is used to create a FontInfo object from a Font
// optionally specifying a CharacterPredicate to filter out some of
// the font's characters.
// It does not take ownership or copy the values its constructor receives.
class FontSourcedInfoBuilder :
public RefCounted<FontSourcedInfoBuilder> {
public:
FontSourcedInfoBuilder(Font* font, FontId font_id);
FontSourcedInfoBuilder(Font* font,
FontId font_id,
CharacterPredicate* predicate);
virtual ~FontSourcedInfoBuilder();
virtual CALLER_ATTACH FontInfo* GetFontInfo();
protected:
bool GetCharacterMap(CharacterMap* chars_to_glyph_ids);
bool ResolveCompositeGlyphs(CharacterMap* chars_to_glyph_ids,
GlyphIdSet* resolved_glyph_ids);
void Initialize();
private:
Ptr<Font> font_;
FontId font_id_;
CharacterPredicate* predicate_;
Ptr<CMapTable::CMap> cmap_;
Ptr<LocaTable> loca_table_;
Ptr<GlyphTable> glyph_table_;
};
// Assembles FontInfo into font builders.
// Does not take ownership of data passed to it.
class FontAssembler : public RefCounted<FontAssembler> {
public:
// font_info is the FontInfo which will be used for the new font
// table_blacklist is used to decide which tables to exclude from the
// final font.
FontAssembler(FontInfo* font_info, IntegerSet* table_blacklist);
explicit FontAssembler(FontInfo* font_info);
~FontAssembler();
// Assemble a new font from the font info object.
virtual CALLER_ATTACH Font* Assemble();
IntegerSet* table_blacklist() const;
void set_table_blacklist(IntegerSet* table_blacklist);
protected:
virtual bool AssembleCMapTable();
virtual bool AssembleGlyphAndLocaTables();
virtual void Initialize();
private:
Ptr<FontInfo> font_info_;
Ptr<FontFactory> font_factory_;
Ptr<Font::Builder> font_builder_;
IntegerSet* table_blacklist_;
};
class PredicateSubsetter : public RefCounted<Subsetter> {
public:
PredicateSubsetter(Font* font, CharacterPredicate* predicate);
virtual ~PredicateSubsetter();
// Performs subsetting returning the subsetted font.
virtual CALLER_ATTACH Font* Subset();
private:
Ptr<Font> font_;
Ptr<CharacterPredicate> predicate_;
};

View File

@ -1,208 +0,0 @@
#!/usr/bin/env python
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:fdm=marker:ai
from __future__ import (unicode_literals, division, absolute_import,
print_function)
__license__ = 'GPL v3'
__copyright__ = '2012, Kovid Goyal <kovid at kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
from future_builtins import map
class NoGlyphs(ValueError):
'Raised when the font has no glyphs for the specified characters'
pass
class UnsupportedFont(ValueError):
'Raised when the font is not supported for subsetting '
'(usually an OTF font with PostScript outlines).'
pass
def load_sfntly():
from calibre.constants import plugins
sfntly, err = plugins['sfntly']
if err:
raise RuntimeError('Failed to load sfntly: %s'%err)
return sfntly
def subset(font_data, individual_chars, ranges=()):
if font_data[:4] not in {b'\x00\x01\x00\x00', b'OTTO', b'true', b'typ1'}:
raise ValueError('Not a supported font file. sfnt_version not recognized: %r'%
font_data[:4])
individual = tuple(sorted(map(ord, individual_chars)))
cranges = []
for s, e in ranges:
sc, ec = map(ord, (s, e))
if ec <= sc:
raise ValueError('The start character %s is after the end'
' character %s'%(s, e))
cranges.append((sc, ec))
sfntly = load_sfntly()
try:
return sfntly.subset(font_data, individual, tuple(cranges))
except sfntly.NoGlyphs:
raise NoGlyphs('No glyphs were found in this font for the'
' specified characters. Subsetting is pointless')
except sfntly.UnsupportedFont as e:
raise UnsupportedFont(type('')(e))
def option_parser():
import textwrap
from calibre.utils.config import OptionParser
parser = OptionParser(usage=textwrap.dedent('''\
%prog [options] input_font_file output_font_file characters_to_keep
Subset the specified font, keeping only the glyphs for the characters in
characters_to_keep. characters_to_keep is a comma separated list of characters of
the form: a,b,c,A-Z,0-9,xyz
You can specify ranges in the list of characters, as shown above.
'''))
parser.add_option('-c', '--codes', default=False, action='store_true',
help='If specified, the list of characters is interpreted as '
'numeric unicode codes instead of characters. So to specify the '
'characters a,b you would use 97,98')
parser.prog = 'subset-font'
return parser
def print_stats(old_stats, new_stats):
from calibre import prints
prints('========= Table comparison (original vs. subset) =========')
prints('Table', ' ', '%10s'%'Size', ' ', 'Percent', ' ', '%10s'%'New Size',
' New Percent')
prints('='*80)
old_total = sum(old_stats.itervalues())
new_total = sum(new_stats.itervalues())
tables = sorted(old_stats.iterkeys(), key=lambda x:old_stats[x],
reverse=True)
for table in tables:
osz = old_stats[table]
op = osz/old_total * 100
nsz = new_stats.get(table, 0)
np = nsz/new_total * 100
suffix = ' | same size'
if nsz != osz:
suffix = ' | reduced to %.1f %%'%(nsz/osz * 100)
prints('%4s'%table, ' ', '%10s'%osz, ' ', '%5.1f %%'%op, ' ',
'%10s'%nsz, ' ', '%5.1f %%'%np, suffix)
prints('='*80)
def test_mem():
load_sfntly()
from calibre.utils.mem import memory
import gc
gc.collect()
start_mem = memory()
raw = P('fonts/liberation/LiberationSerif-Regular.ttf', data=True)
calls = 1000
for i in xrange(calls):
subset(raw, (), (('a', 'z'),))
del raw
for i in xrange(3): gc.collect()
print ('Leaked memory per call:', (memory() - start_mem)/calls*1024, 'KB')
def test():
raw = P('fonts/liberation/LiberationSerif-Regular.ttf', data=True)
sf, old_stats, new_stats = subset(raw, set(('a', 'b', 'c')), ())
if len(sf) > 0.3 * len(raw):
raise Exception('Subsetting failed')
def all():
from calibre.utils.fonts.scanner import font_scanner
failed = []
unsupported = []
total = 0
for family in font_scanner.find_font_families():
for font in font_scanner.fonts_for_family(family):
raw = font_scanner.get_font_data(font)
print ('Subsetting', font['full_name'], end='\t')
total += 1
try:
sf, old_stats, new_stats = subset(raw, set(('a', 'b', 'c')), ())
except NoGlyphs:
print ('No glyphs!')
continue
except UnsupportedFont as e:
unsupported.append((font['full_name'], font['path'], unicode(e)))
print ('Unsupported!')
continue
except Exception as e:
print ('Failed!')
failed.append((font['full_name'], font['path'], unicode(e)))
else:
print ('Reduced to:', '%.1f'%(
sum(new_stats.itervalues())/sum(old_stats.itervalues())
* 100), '%')
if unsupported:
print ('\n\nUnsupported:')
for name, path, err in unsupported:
print (name, path, err)
print()
if failed:
print ('\n\nFailures:')
for name, path, err in failed:
print (name, path, err)
print()
print('Total:', total, 'Unsupported:', len(unsupported), 'Failed:',
len(failed))
def main(args):
import sys, time
from calibre import prints
parser = option_parser()
opts, args = parser.parse_args(args)
if len(args) < 4 or len(args) > 4:
parser.print_help()
raise SystemExit(1)
iff, off, chars = args[1:]
with open(iff, 'rb') as f:
orig = f.read()
chars = [x.strip() for x in chars.split(',')]
individual, ranges = set(), set()
def not_single(c):
if len(c) > 1:
prints(c, 'is not a single character', file=sys.stderr)
raise SystemExit(1)
for c in chars:
if '-' in c:
parts = [x.strip() for x in c.split('-')]
if len(parts) != 2:
prints('Invalid range:', c, file=sys.stderr)
raise SystemExit(1)
if opts.codes:
parts = tuple(map(unichr, map(int, parts)))
map(not_single, parts)
ranges.add(tuple(parts))
else:
if opts.codes:
c = unichr(int(c))
not_single(c)
individual.add(c)
st = time.time()
sf, old_stats, new_stats = subset(orig, individual, ranges)
taken = time.time() - st
reduced = (len(sf)/len(orig)) * 100
def sz(x):
return '%gKB'%(len(x)/1024.)
print_stats(old_stats, new_stats)
prints('Original size:', sz(orig), 'Subset size:', sz(sf), 'Reduced to: %g%%'%(reduced))
prints('Subsetting took %g seconds'%taken)
with open(off, 'wb') as f:
f.write(sf)
prints('Subset font written to:', off)
if __name__ == '__main__':
try:
import init_calibre
init_calibre
except ImportError:
pass
import sys
main(sys.argv)

View File

@ -1,203 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
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.

View File

@ -1,199 +0,0 @@
/*
* 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.
*/
#include "sfntly/data/byte_array.h"
#include <algorithm>
#include "sfntly/port/exception_type.h"
namespace sfntly {
const int32_t ByteArray::COPY_BUFFER_SIZE = 8192;
ByteArray::~ByteArray() {}
int32_t ByteArray::Length() { return filled_length_; }
int32_t ByteArray::Size() { return storage_length_; }
int32_t ByteArray::SetFilledLength(int32_t filled_length) {
filled_length_ = std::min<int32_t>(filled_length, storage_length_);
return filled_length_;
}
int32_t ByteArray::Get(int32_t index) {
return InternalGet(index) & 0xff;
}
int32_t ByteArray::Get(int32_t index, ByteVector* b) {
assert(b);
return Get(index, &((*b)[0]), 0, b->size());
}
int32_t ByteArray::Get(int32_t index,
byte_t* b,
int32_t offset,
int32_t length) {
assert(b);
if (index < 0 || index >= filled_length_) {
return 0;
}
int32_t actual_length = std::min<int32_t>(length, filled_length_ - index);
return InternalGet(index, b, offset, actual_length);
}
void ByteArray::Put(int32_t index, byte_t b) {
if (index < 0 || index >= Size()) {
#if defined (SFNTLY_NO_EXCEPTION)
return;
#else
throw IndexOutOfBoundException(
"Attempt to write outside the bounds of the data");
#endif
}
InternalPut(index, b);
filled_length_ = std::max<int32_t>(filled_length_, index + 1);
}
int32_t ByteArray::Put(int index, ByteVector* b) {
assert(b);
return Put(index, &((*b)[0]), 0, b->size());
}
int32_t ByteArray::Put(int32_t index,
byte_t* b,
int32_t offset,
int32_t length) {
assert(b);
if (index < 0 || index >= Size()) {
#if defined (SFNTLY_NO_EXCEPTION)
return 0;
#else
throw IndexOutOfBoundException(
"Attempt to write outside the bounds of the data");
#endif
}
int32_t actual_length = std::min<int32_t>(length, Size() - index);
int32_t bytes_written = InternalPut(index, b, offset, actual_length);
filled_length_ = std::max<int32_t>(filled_length_, index + bytes_written);
return bytes_written;
}
int32_t ByteArray::CopyTo(ByteArray* array) {
return CopyTo(array, 0, Length());
}
int32_t ByteArray::CopyTo(ByteArray* array, int32_t offset, int32_t length) {
return CopyTo(0, array, offset, length);
}
int32_t ByteArray::CopyTo(int32_t dst_offset, ByteArray* array,
int32_t src_offset, int32_t length) {
assert(array);
if (array->Size() < dst_offset + length) { // insufficient space
return -1;
}
ByteVector b(COPY_BUFFER_SIZE);
int32_t bytes_read = 0;
int32_t index = 0;
int32_t remaining_length = length;
int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
while ((bytes_read =
Get(index + src_offset, &(b[0]), 0, buffer_length)) > 0) {
int bytes_written = array->Put(index + dst_offset, &(b[0]), 0, bytes_read);
UNREFERENCED_PARAMETER(bytes_written);
index += bytes_read;
remaining_length -= bytes_read;
buffer_length = std::min<int32_t>(b.size(), remaining_length);
}
return index;
}
int32_t ByteArray::CopyTo(OutputStream* os) {
return CopyTo(os, 0, Length());
}
int32_t ByteArray::CopyTo(OutputStream* os, int32_t offset, int32_t length) {
ByteVector b(COPY_BUFFER_SIZE);
int32_t bytes_read = 0;
int32_t index = 0;
int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
while ((bytes_read = Get(index + offset, &(b[0]), 0, buffer_length)) > 0) {
os->Write(&b, 0, bytes_read);
index += bytes_read;
buffer_length = std::min<int32_t>(b.size(), length - index);
}
return index;
}
bool ByteArray::CopyFrom(InputStream* is, int32_t length) {
ByteVector b(COPY_BUFFER_SIZE);
int32_t bytes_read = 0;
int32_t index = 0;
int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
if (Put(index, &(b[0]), 0, bytes_read) != bytes_read) {
#if defined (SFNTLY_NO_EXCEPTION)
return 0;
#else
throw IOException("Error writing bytes.");
#endif
}
index += bytes_read;
length -= bytes_read;
buffer_length = std::min<int32_t>(b.size(), length);
}
return true;
}
bool ByteArray::CopyFrom(InputStream* is) {
ByteVector b(COPY_BUFFER_SIZE);
int32_t bytes_read = 0;
int32_t index = 0;
int32_t buffer_length = COPY_BUFFER_SIZE;
while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
if (Put(index, &b[0], 0, bytes_read) != bytes_read) {
#if defined (SFNTLY_NO_EXCEPTION)
return 0;
#else
throw IOException("Error writing bytes.");
#endif
}
index += bytes_read;
}
return true;
}
ByteArray::ByteArray(int32_t filled_length,
int32_t storage_length,
bool growable) {
Init(filled_length, storage_length, growable);
}
ByteArray::ByteArray(int32_t filled_length, int32_t storage_length) {
Init(filled_length, storage_length, false);
}
void ByteArray::Init(int32_t filled_length,
int32_t storage_length,
bool growable) {
storage_length_ = storage_length;
growable_ = growable;
SetFilledLength(filled_length);
}
} // namespace sfntly

View File

@ -1,201 +0,0 @@
/*
* Copyright (C) 2011 The sfntly Open Source Project
*
* 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_DATA_BYTE_ARRAY_H_
#define SFNTLY_CPP_SRC_SFNTLY_DATA_BYTE_ARRAY_H_
#include "sfntly/port/refcount.h"
#include "sfntly/port/type.h"
#include "sfntly/port/input_stream.h"
#include "sfntly/port/output_stream.h"
namespace sfntly {
// An abstraction to a contiguous array of bytes.
// C++ port of this class assumes that the data are stored in a linear region
// like std::vector.
class ByteArray : virtual public RefCount {
public:
virtual ~ByteArray();
// Gets the current filled and readable length of the array.
int32_t Length();
// Gets the maximum size of the array. This is the maximum number of bytes that
// the array can hold and all of it may not be filled with data or even fully
// allocated yet.
int32_t Size();
// Determines whether or not this array is growable or of fixed size.
bool growable() { return growable_; }
int32_t SetFilledLength(int32_t filled_length);
// Gets the byte from the given index.
// @param index the index into the byte array
// @return the byte or -1 if reading beyond the bounds of the data
virtual int32_t Get(int32_t index);
// Gets the bytes from the given index and fill the buffer with them. As many
// bytes as will fit into the buffer are read unless that would go past the
// end of the array.
// @param index the index into the byte array
// @param b the buffer to put the bytes read into
// @return the number of bytes read from the buffer
virtual int32_t Get(int32_t index, ByteVector* b);
// Gets the bytes from the given index and fill the buffer with them starting
// at the offset given. As many bytes as the specified length are read unless
// that would go past the end of the array.
// @param index the index into the byte array
// @param b the buffer to put the bytes read into
// @param offset the location in the buffer to start putting the bytes
// @param length the number of bytes to put into the buffer
// @return the number of bytes read from the buffer
virtual int32_t Get(int32_t index,
byte_t* b,
int32_t offset,
int32_t length);
// Puts the specified byte into the array at the given index unless that would
// be beyond the length of the array and it isn't growable.
virtual void Put(int32_t index, byte_t b);
// Puts the specified bytes into the array at the given index. The entire
// buffer is put into the array unless that would extend beyond the length and
// the array isn't growable.
virtual int32_t Put(int32_t index, ByteVector* b);
// Puts the specified bytes into the array at the given index. All of the bytes
// specified are put into the array unless that would extend beyond the length
// and the array isn't growable. The bytes to be put into the array are those
// in the buffer from the given offset and for the given length.
// @param index the index into the ByteArray
// @param b the bytes to put into the array
// @param offset the offset in the bytes to start copying from
// @param length the number of bytes to copy into the array
// @return the number of bytes actually written
virtual int32_t Put(int32_t index,
byte_t* b,
int32_t offset,
int32_t length);
// Fully copies this ByteArray to another ByteArray to the extent that the
// destination array has storage for the data copied.
virtual int32_t CopyTo(ByteArray* array);
// Copies a segment of this ByteArray to another ByteArray.
// @param array the destination
// @param offset the offset in this ByteArray to start copying from
// @param length the maximum length in bytes to copy
// @return the number of bytes copied
virtual int32_t CopyTo(ByteArray* array, int32_t offset, int32_t length);
// Copies this ByteArray to another ByteArray.
// @param dstOffset the offset in the destination array to start copying to
// @param array the destination
// @param srcOffset the offset in this ByteArray to start copying from
// @param length the maximum length in bytes to copy
// @return the number of bytes copied
virtual int32_t CopyTo(int32_t dst_offset,
ByteArray* array,
int32_t src_offset,
int32_t length);
// Copies this ByteArray to an OutputStream.
// @param os the destination
// @return the number of bytes copied
virtual int32_t CopyTo(OutputStream* os);
// Copies this ByteArray to an OutputStream.
// @param os the destination
// @param offset
// @param length
// @return the number of bytes copied
virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
// Copies from the InputStream into this ByteArray.
// @param is the source
// @param length the number of bytes to copy
virtual bool CopyFrom(InputStream* is, int32_t length);
// Copies everything from the InputStream into this ByteArray.
// @param is the source
virtual bool CopyFrom(InputStream* is);
protected:
// filledLength the length that is "filled" and readable counting from offset.
// storageLength the maximum storage size of the underlying data.
// growable is the storage growable - storageLength is the max growable size.
ByteArray(int32_t filled_length, int32_t storage_length, bool growable);
ByteArray(int32_t filled_length, int32_t storage_length);
void Init(int32_t filled_length, int32_t storage_length, bool growable);
// Internal subclass API
// Stores the byte at the index given.
// @param index the location to store at
// @param b the byte to store
virtual void InternalPut(int32_t index, byte_t b) = 0;
// Stores the array of bytes at the given index.
// @param index the location to store at
// @param b the bytes to store
// @param offset the offset to start from in the byte array
// @param length the length of the byte array to store from the offset
// @return the number of bytes actually stored
virtual int32_t InternalPut(int32_t index,
byte_t* b,
int32_t offset,
int32_t length) = 0;
// Gets the byte at the index given.
// @param index the location to get from
// @return the byte stored at the index
virtual byte_t InternalGet(int32_t index) = 0;
// Gets the bytes at the index given of the given length.
// @param index the location to start getting from
// @param b the array to put the bytes into
// @param offset the offset in the array to put the bytes into
// @param length the length of bytes to read
// @return the number of bytes actually ready
virtual int32_t InternalGet(int32_t index,
byte_t* b,
int32_t offset,
int32_t length) = 0;
// Close this instance of the ByteArray.
virtual void Close() = 0;
// C++ port only, raw pointer to the first element of storage.
virtual byte_t* Begin() = 0;
// Java toString() not ported.
static const int32_t COPY_BUFFER_SIZE;
private:
//bool bound_; // unused, comment out
int32_t filled_length_;
int32_t storage_length_;
bool growable_;
};
typedef Ptr<ByteArray> ByteArrayPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_BYTE_ARRAY_H_

View File

@ -1,82 +0,0 @@
/*
* 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.
*/
#include <limits.h>
#include <algorithm>
#include <functional>
#include "sfntly/data/font_data.h"
namespace sfntly {
int32_t FontData::Size() const {
return std::min<int32_t>(array_->Size() - bound_offset_, bound_length_);
}
bool FontData::Bound(int32_t offset, int32_t length) {
if (offset + length > Size() || offset < 0 || length < 0)
return false;
bound_offset_ += offset;
bound_length_ = length;
return true;
}
bool FontData::Bound(int32_t offset) {
if (offset > Size() || offset < 0)
return false;
bound_offset_ += offset;
return true;
}
int32_t FontData::Length() const {
return std::min<int32_t>(array_->Length() - bound_offset_, bound_length_);
}
FontData::FontData(ByteArray* ba) {
Init(ba);
}
FontData::FontData(FontData* data, int32_t offset, int32_t length) {
Init(data->array_);
Bound(data->bound_offset_ + offset, length);
}
FontData::FontData(FontData* data, int32_t offset) {
Init(data->array_);
Bound(data->bound_offset_ + offset,
(data->bound_length_ == GROWABLE_SIZE)
? GROWABLE_SIZE : data->bound_length_ - offset);
}
FontData::~FontData() {}
void FontData::Init(ByteArray* ba) {
array_ = ba;
bound_offset_ = 0;
bound_length_ = GROWABLE_SIZE;
}
int32_t FontData::BoundOffset(int32_t offset) {
return offset + bound_offset_;
}
int32_t FontData::BoundLength(int32_t offset, int32_t length) {
return std::min<int32_t>(length, bound_length_ - offset);
}
} // namespace sfntly

View File

@ -1,135 +0,0 @@
/*
* 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_DATA_FONT_DATA_H_
#define SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_DATA_H_
#include <limits.h>
#include <vector>
#include "sfntly/port/type.h"
#include "sfntly/data/byte_array.h"
#include "sfntly/port/refcount.h"
namespace sfntly {
struct DataSize {
enum {
kBYTE = 1,
kCHAR = 1,
kUSHORT = 2,
kSHORT = 2,
kUINT24 = 3,
kULONG = 4,
kLONG = 4,
kFixed = 4,
kFUNIT = 4,
kFWORD = 2,
kUFWORD = 2,
kF2DOT14 = 2,
kLONGDATETIME = 8,
kTag = 4,
kGlyphID = 2,
kOffset = 2
};
};
class FontData : virtual public RefCount {
public:
// Gets the maximum size of the FontData. This is the maximum number of bytes
// that the font data can hold and all of it may not be filled with data or
// even fully allocated yet.
// @return the maximum size of this font data
virtual int32_t Size() const;
// Sets limits on the size of the FontData. The FontData is then only
// visible within the bounds set.
// @param offset the start of the new bounds
// @param length the number of bytes in the bounded array
// @return true if the bounding range was successful; false otherwise
virtual bool Bound(int32_t offset, int32_t length);
// Sets limits on the size of the FontData. This is a offset bound only so if
// the FontData is writable and growable then there is no limit to that growth
// from the bounding operation.
// @param offset the start of the new bounds which must be within the current
// size of the FontData
// @return true if the bounding range was successful; false otherwise
virtual bool Bound(int32_t offset);
// Makes a slice of this FontData. The returned slice will share the data with
// the original <code>FontData</code>.
// @param offset the start of the slice
// @param length the number of bytes in the slice
// @return a slice of the original FontData
virtual CALLER_ATTACH FontData* Slice(int32_t offset, int32_t length) = 0;
// Makes a bottom bound only slice of this array. The returned slice will
// share the data with the original <code>FontData</code>.
// @param offset the start of the slice
// @return a slice of the original FontData
virtual CALLER_ATTACH FontData* Slice(int32_t offset) = 0;
// Gets the length of the data.
virtual int32_t Length() const;
protected:
// Constructor.
// @param ba the byte array to use for the backing data
explicit FontData(ByteArray* ba);
// Constructor.
// @param data the data to wrap
// @param offset the offset to start the wrap from
// @param length the length of the data wrapped
FontData(FontData* data, int32_t offset, int32_t length);
// Constructor.
// @param data the data to wrap
// @param offset the offset to start the wrap from
FontData(FontData* data, int32_t offset);
virtual ~FontData();
void Init(ByteArray* ba);
// Gets the offset in the underlying data taking into account any bounds on
// the data.
// @param offset the offset to get the bound compensated offset for
// @return the bound compensated offset
int32_t BoundOffset(int32_t offset);
// Gets the length in the underlying data taking into account any bounds on
// the data.
// @param offset the offset that the length is being used at
// @param length the length to get the bound compensated length for
// @return the bound compensated length
int32_t BoundLength(int32_t offset, int32_t length);
static const int32_t GROWABLE_SIZE = INT_MAX;
// TODO(arthurhsu): style guide violation: refactor this protected member
ByteArrayPtr array_;
private:
int32_t bound_offset_;
int32_t bound_length_;
};
typedef Ptr<FontData> FontDataPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_DATA_H_

View File

@ -1,141 +0,0 @@
/*
* 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.
*/
#include "sfntly/data/font_input_stream.h"
#include <algorithm>
namespace sfntly {
FontInputStream::FontInputStream(InputStream* is)
: stream_(is), position_(0), length_(0), bounded_(false) {
}
FontInputStream::FontInputStream(InputStream* is, size_t length)
: stream_(is), position_(0), length_(length), bounded_(true) {
}
FontInputStream::~FontInputStream() {
// Do not close here, underlying InputStream will close themselves.
}
int32_t FontInputStream::Available() {
if (stream_) {
return stream_->Available();
}
return 0;
}
void FontInputStream::Close() {
if (stream_) {
stream_->Close();
}
}
void FontInputStream::Mark(int32_t readlimit) {
if (stream_) {
stream_->Mark(readlimit);
}
}
bool FontInputStream::MarkSupported() {
if (stream_) {
return stream_->MarkSupported();
}
return false;
}
void FontInputStream::Reset() {
if (stream_) {
stream_->Reset();
}
}
int32_t FontInputStream::Read() {
if (!stream_ || (bounded_ && position_ >= length_)) {
return -1;
}
int32_t b = stream_->Read();
if (b >= 0) {
position_++;
}
return b;
}
int32_t FontInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
if (!stream_ || offset < 0 || length < 0 ||
(bounded_ && position_ >= length_)) {
return -1;
}
int32_t bytes_to_read =
bounded_ ? std::min<int32_t>(length, (int32_t)(length_ - position_)) :
length;
int32_t bytes_read = stream_->Read(b, offset, bytes_to_read);
position_ += bytes_read;
return bytes_read;
}
int32_t FontInputStream::Read(ByteVector* b) {
return Read(b, 0, b->size());
}
int32_t FontInputStream::ReadChar() {
return Read();
}
int32_t FontInputStream::ReadUShort() {
return 0xffff & (Read() << 8 | Read());
}
int32_t FontInputStream::ReadShort() {
return ((Read() << 8 | Read()) << 16) >> 16;
}
int32_t FontInputStream::ReadUInt24() {
return 0xffffff & (Read() << 16 | Read() << 8 | Read());
}
int64_t FontInputStream::ReadULong() {
return 0xffffffffL & ReadLong();
}
int32_t FontInputStream::ReadULongAsInt() {
int64_t ulong = ReadULong();
return ((int32_t)ulong) & ~0x80000000;
}
int32_t FontInputStream::ReadLong() {
return Read() << 24 | Read() << 16 | Read() << 8 | Read();
}
int32_t FontInputStream::ReadFixed() {
return ReadLong();
}
int64_t FontInputStream::ReadDateTimeAsLong() {
return (int64_t)ReadULong() << 32 | ReadULong();
}
int64_t FontInputStream::Skip(int64_t n) {
if (stream_) {
int64_t skipped = stream_->Skip(n);
position_ += skipped;
return skipped;
}
return 0;
}
} // namespace sfntly

View File

@ -1,97 +0,0 @@
/*
* 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_DATA_FONT_INPUT_STREAM_H_
#define SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_INPUT_STREAM_H_
#include "sfntly/port/type.h"
#include "sfntly/port/input_stream.h"
namespace sfntly {
// An input stream for reading font data.
// The data types used are as listed:
// BYTE 8-bit unsigned integer.
// CHAR 8-bit signed integer.
// USHORT 16-bit unsigned integer.
// SHORT 16-bit signed integer.
// UINT24 24-bit unsigned integer.
// ULONG 32-bit unsigned integer.
// LONG 32-bit signed integer.
// Fixed 32-bit signed fixed-point number (16.16)
// FUNIT Smallest measurable distance in the em space.
// FWORD 16-bit signed integer (SHORT) that describes a quantity in FUnits.
// UFWORD 16-bit unsigned integer (USHORT) that describes a quantity in
// FUnits.
// F2DOT14 16-bit signed fixed number with the low 14 bits of fraction (2.14)
// LONGDATETIME Date represented in number of seconds since 12:00 midnight,
// January 1, 1904. The value is represented as a signed 64-bit
// integer.
// Note: Original class inherits from Java's FilterOutputStream, which wraps
// an InputStream within. In C++, we directly do the wrapping without
// defining another layer of abstraction. The wrapped output stream is
// *NOT* reference counted (because it's meaningless to ref-count an I/O
// stream).
class FontInputStream : public InputStream {
public:
// Constructor.
// @param is input stream to wrap
explicit FontInputStream(InputStream* is);
// Constructor for a bounded font input stream.
// @param is input stream to wrap
// @param length the maximum length of bytes to read
FontInputStream(InputStream* is, size_t length);
virtual ~FontInputStream();
virtual int32_t Available();
virtual void Close();
virtual void Mark(int32_t readlimit);
virtual bool MarkSupported();
virtual void Reset();
virtual int32_t Read();
virtual int32_t Read(ByteVector* buffer);
virtual int32_t Read(ByteVector* buffer, int32_t offset, int32_t length);
// Get the current position in the stream in bytes.
// @return the current position in bytes
virtual int64_t position() { return position_; }
virtual int32_t ReadChar();
virtual int32_t ReadUShort();
virtual int32_t ReadShort();
virtual int32_t ReadUInt24();
virtual int64_t ReadULong();
virtual int32_t ReadULongAsInt();
virtual int32_t ReadLong();
virtual int32_t ReadFixed();
virtual int64_t ReadDateTimeAsLong();
virtual int64_t Skip(int64_t n); // n can be negative.
private:
InputStream* stream_;
int64_t position_;
int64_t length_; // Bound on length of data to read.
bool bounded_;
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_INPUT_STREAM_H_

View File

@ -1,130 +0,0 @@
/*
* 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.
*/
#include "sfntly/data/font_output_stream.h"
#include <algorithm>
namespace sfntly {
FontOutputStream::FontOutputStream(OutputStream* os)
: stream_(os),
position_(0) {
}
FontOutputStream::~FontOutputStream() {
// Do not close, underlying stream shall clean up themselves.
}
void FontOutputStream::Write(byte_t b) {
if (stream_) {
stream_->Write(b);
position_++;
}
}
void FontOutputStream::Write(ByteVector* b) {
if (b) {
Write(b, 0, b->size());
position_ += b->size();
}
}
void FontOutputStream::Write(ByteVector* b, int32_t off, int32_t len) {
assert(b);
assert(stream_);
if (off < 0 || len < 0 || off + len < 0 ||
static_cast<size_t>(off + len) > b->size()) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundException();
#else
return;
#endif
}
stream_->Write(b, off, len);
position_ += len;
}
void FontOutputStream::Write(byte_t* b, int32_t off, int32_t len) {
assert(b);
assert(stream_);
if (off < 0 || len < 0 || off + len < 0) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundException();
#else
return;
#endif
}
stream_->Write(b, off, len);
position_ += len;
}
void FontOutputStream::WriteChar(byte_t c) {
Write(c);
}
void FontOutputStream::WriteUShort(int32_t us) {
Write((byte_t)((us >> 8) & 0xff));
Write((byte_t)(us & 0xff));
}
void FontOutputStream::WriteShort(int32_t s) {
WriteUShort(s);
}
void FontOutputStream::WriteUInt24(int32_t ui) {
Write((byte_t)(ui >> 16) & 0xff);
Write((byte_t)(ui >> 8) & 0xff);
Write((byte_t)ui & 0xff);
}
void FontOutputStream::WriteULong(int64_t ul) {
Write((byte_t)((ul >> 24) & 0xff));
Write((byte_t)((ul >> 16) & 0xff));
Write((byte_t)((ul >> 8) & 0xff));
Write((byte_t)(ul & 0xff));
}
void FontOutputStream::WriteLong(int64_t l) {
WriteULong(l);
}
void FontOutputStream::WriteFixed(int32_t f) {
WriteULong(f);
}
void FontOutputStream::WriteDateTime(int64_t date) {
WriteULong((date >> 32) & 0xffffffff);
WriteULong(date & 0xffffffff);
}
void FontOutputStream::Flush() {
if (stream_) {
stream_->Flush();
}
}
void FontOutputStream::Close() {
if (stream_) {
stream_->Flush();
stream_->Close();
position_ = 0;
}
}
} // namespace sfntly

View File

@ -1,79 +0,0 @@
/*
* 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_DATA_FONT_OUTPUT_STREAM_H_
#define SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_OUTPUT_STREAM_H_
#include "sfntly/port/type.h"
#include "sfntly/port/output_stream.h"
namespace sfntly {
// An output stream for writing font data.
// The data types used are as listed:
// BYTE 8-bit unsigned integer.
// CHAR 8-bit signed integer.
// USHORT 16-bit unsigned integer.
// SHORT 16-bit signed integer.
// UINT24 24-bit unsigned integer.
// ULONG 32-bit unsigned integer.
// LONG 32-bit signed integer.
// Fixed 32-bit signed fixed-point number (16.16)
// FUNIT Smallest measurable distance in the em space.
// FWORD 16-bit signed integer (SHORT) that describes a quantity in FUnits.
// UFWORD 16-bit unsigned integer (USHORT) that describes a quantity in
// FUnits.
// F2DOT14 16-bit signed fixed number with the low 14 bits of fraction (2.14)
// LONGDATETIME Date represented in number of seconds since 12:00 midnight,
// January 1, 1904. The value is represented as a signed 64-bit
// integer.
// Note: The wrapped output stream is *NOT* reference counted (because it's
// meaningless to ref-count an I/O stream).
class FontOutputStream : public OutputStream {
public:
explicit FontOutputStream(OutputStream* os);
virtual ~FontOutputStream();
virtual size_t position() { return position_; }
virtual void Write(byte_t b);
virtual void Write(ByteVector* b);
virtual void Write(ByteVector* b, int32_t off, int32_t len);
virtual void Write(byte_t* b, int32_t off, int32_t len);
virtual void WriteChar(byte_t c);
virtual void WriteUShort(int32_t us);
virtual void WriteShort(int32_t s);
virtual void WriteUInt24(int32_t ui);
virtual void WriteULong(int64_t ul);
virtual void WriteLong(int64_t l);
virtual void WriteFixed(int32_t l);
virtual void WriteDateTime(int64_t date);
// Note: C++ port only.
virtual void Flush();
virtual void Close();
private:
// Note: we do not use the variable name out as in Java because it has
// special meaning in VC++ and will be very confusing.
OutputStream* stream_;
size_t position_;
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_OUTPUT_STREAM_H_

View File

@ -1,82 +0,0 @@
/*
* 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.
*/
#include "sfntly/data/growable_memory_byte_array.h"
#include <limits.h>
#include <string.h>
#include <algorithm>
namespace sfntly {
GrowableMemoryByteArray::GrowableMemoryByteArray()
: ByteArray(0, INT_MAX, true) {
// Note: We did not set an initial size of array like Java because STL
// implementation will determine the best strategy.
}
GrowableMemoryByteArray::~GrowableMemoryByteArray() {}
int32_t GrowableMemoryByteArray::CopyTo(OutputStream* os,
int32_t offset,
int32_t length) {
assert(os);
os->Write(&b_, offset, length);
return length;
}
void GrowableMemoryByteArray::InternalPut(int32_t index, byte_t b) {
if ((size_t)index >= b_.size()) {
b_.resize((size_t)(index + 1));
}
b_[index] = b;
}
int32_t GrowableMemoryByteArray::InternalPut(int32_t index,
byte_t* b,
int32_t offset,
int32_t length) {
if ((size_t)index + length >= b_.size()) {
// Note: We grow one byte more than Java version. VC debuggers shows
// data better this way.
b_.resize((size_t)(index + length + 1));
}
std::copy(b + offset, b + offset + length, b_.begin() + index);
return length;
}
byte_t GrowableMemoryByteArray::InternalGet(int32_t index) {
return b_[index];
}
int32_t GrowableMemoryByteArray::InternalGet(int32_t index,
byte_t* b,
int32_t offset,
int32_t length) {
memcpy(b + offset, &(b_[0]) + index, length);
return length;
}
void GrowableMemoryByteArray::Close() {
b_.clear();
}
byte_t* GrowableMemoryByteArray::Begin() {
return &(b_[0]);
}
} // namespace sfntly

View File

@ -1,66 +0,0 @@
/*
* 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_DATA_GROWABLE_MEMORY_BYTE_ARRAY_H_
#define SFNTLY_CPP_SRC_SFNTLY_DATA_GROWABLE_MEMORY_BYTE_ARRAY_H_
#include "sfntly/data/byte_array.h"
namespace sfntly {
// Note: This is not really a port of Java version. Instead, this wraps a
// std::vector inside and let it grow by calling resize().
class GrowableMemoryByteArray : public ByteArray,
public RefCounted<GrowableMemoryByteArray> {
public:
GrowableMemoryByteArray();
virtual ~GrowableMemoryByteArray();
virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
// Make gcc -Woverloaded-virtual happy.
virtual int32_t CopyTo(ByteArray* array) { return ByteArray::CopyTo(array); }
virtual int32_t CopyTo(ByteArray* array, int32_t offset, int32_t length) {
return ByteArray::CopyTo(array, offset, length);
}
virtual int32_t CopyTo(int32_t dst_offset,
ByteArray* array,
int32_t src_offset,
int32_t length) {
return ByteArray::CopyTo(dst_offset, array, src_offset, length);
}
virtual int32_t CopyTo(OutputStream* os) { return ByteArray::CopyTo(os); }
protected:
virtual void InternalPut(int32_t index, byte_t b);
virtual int32_t InternalPut(int32_t index,
byte_t* b,
int32_t offset,
int32_t length);
virtual byte_t InternalGet(int32_t index);
virtual int32_t InternalGet(int32_t index,
byte_t* b,
int32_t offset,
int32_t length);
virtual void Close();
virtual byte_t* Begin();
private:
ByteVector b_;
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_GROWABLE_MEMORY_BYTE_ARRAY_H_

View File

@ -1,93 +0,0 @@
/*
* 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.
*/
#include "sfntly/data/memory_byte_array.h"
#include <string.h>
namespace sfntly {
MemoryByteArray::MemoryByteArray(int32_t length)
: ByteArray(0, length), b_(NULL), allocated_(true) {
}
MemoryByteArray::MemoryByteArray(byte_t* b, int32_t filled_length)
: ByteArray(filled_length, filled_length), b_(b), allocated_(false) {
assert(b);
}
MemoryByteArray::~MemoryByteArray() {
Close();
}
int32_t MemoryByteArray::CopyTo(OutputStream* os,
int32_t offset,
int32_t length) {
assert(os);
os->Write(b_, offset, length);
return length;
}
void MemoryByteArray::Init() {
if (allocated_ && b_ == NULL) {
b_ = new byte_t[Size()];
memset(b_, 0, Size());
}
}
void MemoryByteArray::InternalPut(int32_t index, byte_t b) {
Init();
b_[index] = b;
}
int32_t MemoryByteArray::InternalPut(int32_t index,
byte_t* b,
int32_t offset,
int32_t length) {
assert(b);
Init();
memcpy(b_ + index, b + offset, length);
return length;
}
byte_t MemoryByteArray::InternalGet(int32_t index) {
Init();
return b_[index];
}
int32_t MemoryByteArray::InternalGet(int32_t index,
byte_t* b,
int32_t offset,
int32_t length) {
assert(b);
Init();
memcpy(b + offset, b_ + index, length);
return length;
}
void MemoryByteArray::Close() {
if (allocated_ && b_) {
delete[] b_;
}
b_ = NULL;
}
byte_t* MemoryByteArray::Begin() {
Init();
return b_;
}
} // namespace sfntly

View File

@ -1,81 +0,0 @@
/*
* 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_DATA_MEMORY_BYTE_ARRAY_H_
#define SFNTLY_CPP_SRC_SFNTLY_DATA_MEMORY_BYTE_ARRAY_H_
#include "sfntly/data/byte_array.h"
namespace sfntly {
class MemoryByteArray : public ByteArray, public RefCounted<MemoryByteArray> {
public:
// Construct a new MemoryByteArray with a new array of the size given. It is
// assumed that none of the array is filled and readable.
explicit MemoryByteArray(int32_t length);
// Note: not implemented due to dangerous operations in constructor.
//explicit MemoryByteArray(ByteVector* b);
// Construct a new MemoryByteArray using byte array.
// @param b the byte array that provides the actual storage
// @param filled_length the index of the last byte in the array has data
// Note: This is different from Java version, it does not take over the
// ownership of b. Caller is responsible for handling the lifetime
// of b. C++ port also assumes filled_length is buffer_length since
// there is not a reliable way to identify the actual size of buffer.
MemoryByteArray(byte_t* b, int32_t filled_length);
virtual ~MemoryByteArray();
virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
// Make gcc -Woverloaded-virtual happy.
virtual int32_t CopyTo(ByteArray* array) { return ByteArray::CopyTo(array); }
virtual int32_t CopyTo(ByteArray* array, int32_t offset, int32_t length) {
return ByteArray::CopyTo(array, offset, length);
}
virtual int32_t CopyTo(int32_t dst_offset,
ByteArray* array,
int32_t src_offset,
int32_t length) {
return ByteArray::CopyTo(dst_offset, array, src_offset, length);
}
virtual int32_t CopyTo(OutputStream* os) { return ByteArray::CopyTo(os); }
protected:
virtual void InternalPut(int32_t index, byte_t b);
virtual int32_t InternalPut(int32_t index,
byte_t* b,
int32_t offset,
int32_t length);
virtual byte_t InternalGet(int32_t index);
virtual int32_t InternalGet(int32_t index,
byte_t* b,
int32_t offset,
int32_t length);
virtual void Close();
virtual byte_t* Begin();
private:
void Init(); // C++ port only, used to allocate memory outside constructor.
byte_t* b_;
bool allocated_;
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_MEMORY_BYTE_ARRAY_H_

View File

@ -1,336 +0,0 @@
/*
* 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.
*/
#include "sfntly/data/readable_font_data.h"
#include <stdio.h>
#include "sfntly/data/memory_byte_array.h"
#include "sfntly/data/writable_font_data.h"
#include "sfntly/port/exception_type.h"
namespace sfntly {
ReadableFontData::ReadableFontData(ByteArray* array)
: FontData(array),
checksum_set_(false),
checksum_(0) {
}
ReadableFontData::~ReadableFontData() {}
// TODO(arthurhsu): re-investigate the memory model of this function. It's
// not too useful without copying, but it's not performance
// savvy to do copying.
CALLER_ATTACH
ReadableFontData* ReadableFontData::CreateReadableFontData(ByteVector* b) {
assert(b);
ByteArrayPtr ba = new MemoryByteArray(b->size());
ba->Put(0, b);
ReadableFontDataPtr wfd = new ReadableFontData(ba);
return wfd.Detach();
}
int64_t ReadableFontData::Checksum() {
AutoLock lock(checksum_lock_);
if (!checksum_set_) {
ComputeChecksum();
}
return checksum_;
}
void ReadableFontData::SetCheckSumRanges(const IntegerList& ranges) {
checksum_range_ = ranges;
checksum_set_ = false; // UNIMPLEMENTED: atomicity
}
int32_t ReadableFontData::ReadUByte(int32_t index) {
int32_t b = array_->Get(BoundOffset(index));
#if !defined (SFNTLY_NO_EXCEPTION)
if (b < 0) {
throw IndexOutOfBoundException(
"Index attempted to be read from is out of bounds", index);
}
#endif
return b;
}
int32_t ReadableFontData::ReadByte(int32_t index) {
int32_t b = array_->Get(BoundOffset(index));
#if !defined (SFNTLY_NO_EXCEPTION)
if (b < 0) {
throw IndexOutOfBoundException(
"Index attempted to be read from is out of bounds", index);
}
#endif
return (b << 24) >> 24;
}
int32_t ReadableFontData::ReadBytes(int32_t index,
byte_t* b,
int32_t offset,
int32_t length) {
return array_->Get(BoundOffset(index), b, offset, BoundLength(index, length));
}
int32_t ReadableFontData::ReadChar(int32_t index) {
return ReadUByte(index);
}
int32_t ReadableFontData::ReadUShort(int32_t index) {
return 0xffff & (ReadUByte(index) << 8 | ReadUByte(index + 1));
}
int32_t ReadableFontData::ReadShort(int32_t index) {
return ((ReadByte(index) << 8 | ReadUByte(index + 1)) << 16) >> 16;
}
int32_t ReadableFontData::ReadUInt24(int32_t index) {
return 0xffffff & (ReadUByte(index) << 16 |
ReadUByte(index + 1) << 8 |
ReadUByte(index + 2));
}
int64_t ReadableFontData::ReadULong(int32_t index) {
return 0xffffffffL & (ReadUByte(index) << 24 |
ReadUByte(index + 1) << 16 |
ReadUByte(index + 2) << 8 |
ReadUByte(index + 3));
}
int32_t ReadableFontData::ReadULongAsInt(int32_t index) {
int64_t ulong = ReadULong(index);
#if !defined (SFNTLY_NO_EXCEPTION)
if ((ulong & 0x80000000) == 0x80000000) {
throw ArithmeticException("Long value too large to fit into an integer.");
}
#endif
return static_cast<int32_t>(ulong);
}
int64_t ReadableFontData::ReadULongLE(int32_t index) {
return 0xffffffffL & (ReadUByte(index) |
ReadUByte(index + 1) << 8 |
ReadUByte(index + 2) << 16 |
ReadUByte(index + 3) << 24);
}
int32_t ReadableFontData::ReadLong(int32_t index) {
return ReadByte(index) << 24 |
ReadUByte(index + 1) << 16 |
ReadUByte(index + 2) << 8 |
ReadUByte(index + 3);
}
int32_t ReadableFontData::ReadFixed(int32_t index) {
return ReadLong(index);
}
int64_t ReadableFontData::ReadDateTimeAsLong(int32_t index) {
return (int64_t)ReadULong(index) << 32 | ReadULong(index + 4);
}
int32_t ReadableFontData::ReadFWord(int32_t index) {
return ReadShort(index);
}
int32_t ReadableFontData::ReadFUFWord(int32_t index) {
return ReadUShort(index);
}
int32_t ReadableFontData::CopyTo(OutputStream* os) {
return array_->CopyTo(os, BoundOffset(0), Length());
}
int32_t ReadableFontData::CopyTo(WritableFontData* wfd) {
return array_->CopyTo(wfd->BoundOffset(0),
wfd->array_,
BoundOffset(0),
Length());
}
int32_t ReadableFontData::CopyTo(ByteArray* ba) {
return array_->CopyTo(ba, BoundOffset(0), Length());
}
int32_t ReadableFontData::SearchUShort(int32_t start_index,
int32_t start_offset,
int32_t end_index,
int32_t end_offset,
int32_t length,
int32_t key) {
int32_t location = 0;
int32_t bottom = 0;
int32_t top = length;
while (top != bottom) {
location = (top + bottom) / 2;
int32_t location_start = ReadUShort(start_index + location * start_offset);
if (key < location_start) {
// location is below current location
top = location;
} else {
// is key below the upper bound?
int32_t location_end = ReadUShort(end_index + location * end_offset);
#if defined (SFNTLY_DEBUG_FONTDATA)
fprintf(stderr, "**start: %d; end: %d\n", location_start, location_end);
#endif
if (key <= location_end) {
return location;
} else {
// location is above the current location
bottom = location + 1;
}
}
}
return -1;
}
int32_t ReadableFontData::SearchUShort(int32_t start_index,
int32_t start_offset,
int32_t length,
int32_t key) {
int32_t location = 0;
int32_t bottom = 0;
int32_t top = length;
while (top != bottom) {
location = (top + bottom) / 2;
int32_t location_start = ReadUShort(start_index + location * start_offset);
if (key < location_start) {
// location is below current location
top = location;
} else if (key > location_start) {
// location is above current location
bottom = location + 1;
} else {
return location;
}
}
return -1;
}
int32_t ReadableFontData::SearchULong(int32_t start_index,
int32_t start_offset,
int32_t end_index,
int32_t end_offset,
int32_t length,
int32_t key) {
int32_t location = 0;
int32_t bottom = 0;
int32_t top = length;
while (top != bottom) {
location = (top + bottom) / 2;
int32_t location_start = ReadULongAsInt(start_index
+ location * start_offset);
if (key < location_start) {
// location is below current location
top = location;
} else {
// is key below the upper bound?
int32_t location_end = ReadULongAsInt(end_index + location * end_offset);
#if defined (SFNTLY_DEBUG_FONTDATA)
fprintf(stderr, "**start: %d; end: %d\n", location_start, location_end);
#endif
if (key <= location_end) {
return location;
} else {
// location is above the current location
bottom = location + 1;
}
}
}
return -1;
}
CALLER_ATTACH FontData* ReadableFontData::Slice(int32_t offset,
int32_t length) {
if (offset < 0 || offset + length > Size()) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundsException(
"Attempt to bind data outside of its limits");
#endif
return NULL;
}
FontDataPtr slice = new ReadableFontData(this, offset, length);
return slice.Detach();
}
CALLER_ATTACH FontData* ReadableFontData::Slice(int32_t offset) {
if (offset < 0 || offset > Size()) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundsException(
"Attempt to bind data outside of its limits");
#endif
return NULL;
}
FontDataPtr slice = new ReadableFontData(this, offset);
return slice.Detach();
}
ReadableFontData::ReadableFontData(ReadableFontData* data, int32_t offset)
: FontData(data, offset),
checksum_set_(false),
checksum_(0) {
}
ReadableFontData::ReadableFontData(ReadableFontData* data,
int32_t offset,
int32_t length)
: FontData(data, offset, length),
checksum_set_(false),
checksum_(0) {
}
void ReadableFontData::ComputeChecksum() {
// TODO(arthurhsu): IMPLEMENT: synchronization/atomicity
int64_t sum = 0;
if (checksum_range_.empty()) {
sum = ComputeCheckSum(0, Length());
} else {
for (uint32_t low_bound_index = 0; low_bound_index < checksum_range_.size();
low_bound_index += 2) {
int32_t low_bound = checksum_range_[low_bound_index];
int32_t high_bound = (low_bound_index == checksum_range_.size() - 1) ?
Length() :
checksum_range_[low_bound_index + 1];
sum += ComputeCheckSum(low_bound, high_bound);
}
}
checksum_ = sum & 0xffffffffL;
checksum_set_ = true;
}
int64_t ReadableFontData::ComputeCheckSum(int32_t low_bound,
int32_t high_bound) {
int64_t sum = 0;
// Checksum all whole 4-byte chunks.
for (int32_t i = low_bound; i <= high_bound - 4; i += 4) {
sum += ReadULong(i);
}
// Add last fragment if not 4-byte multiple
int32_t off = high_bound & -4;
if (off < high_bound) {
int32_t b3 = ReadUByte(off);
int32_t b2 = (off + 1 < high_bound) ? ReadUByte(off + 1) : 0;
int32_t b1 = (off + 2 < high_bound) ? ReadUByte(off + 2) : 0;
int32_t b0 = 0;
sum += (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
}
return sum;
}
} // namespace sfntly

View File

@ -1,308 +0,0 @@
/*
* 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_DATA_READABLE_FONT_DATA_H_
#define SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_
#include "sfntly/data/font_data.h"
#include "sfntly/port/lock.h"
namespace sfntly {
class WritableFontData;
class OutputStream;
// Writable font data wrapper. Supports reading of data primitives in the
// TrueType / OpenType spec.
// The data types used are as listed:
// BYTE 8-bit unsigned integer.
// CHAR 8-bit signed integer.
// USHORT 16-bit unsigned integer.
// SHORT 16-bit signed integer.
// UINT24 24-bit unsigned integer.
// ULONG 32-bit unsigned integer.
// LONG 32-bit signed integer.
// Fixed 32-bit signed fixed-point number (16.16)
// FUNIT Smallest measurable distance in the em space.
// FWORD 16-bit signed integer (SHORT) that describes a quantity in FUnits.
// UFWORD 16-bit unsigned integer (USHORT) that describes a quantity in
// FUnits.
// F2DOT14 16-bit signed fixed number with the low 14 bits of fraction (2.14)
// LONGDATETIME Date represented in number of seconds since 12:00 midnight,
// January 1, 1904. The value is represented as a signed 64-bit
// integer.
class ReadableFontData : public FontData,
public RefCounted<ReadableFontData> {
public:
explicit ReadableFontData(ByteArray* array);
virtual ~ReadableFontData();
static CALLER_ATTACH ReadableFontData* CreateReadableFontData(ByteVector* b);
// Gets a computed checksum for the data. This checksum uses the OpenType spec
// calculation. Every ULong value (32 bit unsigned) in the data is summed and
// the resulting value is truncated to 32 bits. If the data length in bytes is
// not an integral multiple of 4 then any remaining bytes are treated as the
// start of a 4 byte sequence whose remaining bytes are zero.
// @return the checksum
int64_t Checksum();
// Sets the bounds to use for computing the checksum. These bounds are in
// begin and end pairs. If an odd number is given then the final range is
// assumed to extend to the end of the data. The lengths of each range must be
// a multiple of 4.
// @param ranges the range bounds to use for the checksum
void SetCheckSumRanges(const IntegerList& ranges);
// Read the UBYTE at the given index.
// @param index index into the font data
// @return the UBYTE; -1 if outside the bounds of the font data
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t ReadUByte(int32_t index);
// Read the BYTE at the given index.
// @param index index into the font data
// @return the BYTE
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t ReadByte(int32_t index);
// Read the bytes at the given index into the array.
// @param index index into the font data
// @param b the destination for the bytes read
// @param offset offset in the byte array to place the bytes
// @param length the length of bytes to read
// @return the number of bytes actually read; -1 if the index is outside the
// bounds of the font data
virtual int32_t ReadBytes(int32_t index,
byte_t* b,
int32_t offset,
int32_t length);
// Read the CHAR at the given index.
// @param index index into the font data
// @return the CHAR
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t ReadChar(int32_t index);
// Read the USHORT at the given index.
// @param index index into the font data
// @return the USHORT
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t ReadUShort(int32_t index);
// Read the SHORT at the given index.
// @param index index into the font data
// @return the SHORT
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t ReadShort(int32_t index);
// Read the UINT24 at the given index.
// @param index index into the font data
// @return the UINT24
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t ReadUInt24(int32_t index);
// Read the ULONG at the given index.
// @param index index into the font data
// @return the ULONG
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int64_t ReadULong(int32_t index);
// Read the ULONG at the given index as int32_t.
// @param index index into the font data
// @return the ULONG
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t ReadULongAsInt(int32_t index);
// Read the ULONG at the given index, little-endian variant
// @param index index into the font data
// @return the ULONG
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int64_t ReadULongLE(int32_t index);
// Read the LONG at the given index.
// @param index index into the font data
// @return the LONG
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t ReadLong(int32_t index);
// Read the Fixed at the given index.
// @param index index into the font data
// @return the Fixed
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t ReadFixed(int32_t index);
// Read the LONGDATETIME at the given index.
// @param index index into the font data
// @return the LONGDATETIME
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int64_t ReadDateTimeAsLong(int32_t index);
// Read the FWORD at the given index.
// @param index index into the font data
// @return the FWORD
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t ReadFWord(int32_t index);
// Read the UFWORD at the given index.
// @param index index into the font data
// @return the UFWORD
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t ReadFUFWord(int32_t index);
// Note: Not ported because they just throw UnsupportedOperationException()
// in Java.
/*
virtual int32_t ReadFUnit(int32_t index);
virtual int64_t ReadF2Dot14(int32_t index);
*/
// Copy the FontData to an OutputStream.
// @param os the destination
// @return number of bytes copied
// @throws IOException
virtual int32_t CopyTo(OutputStream* os);
// Copy the FontData to a WritableFontData.
// @param wfd the destination
// @return number of bytes copied
// @throws IOException
virtual int32_t CopyTo(WritableFontData* wfd);
// Make gcc -Woverloaded-virtual happy.
virtual int32_t CopyTo(ByteArray* ba);
// Search for the key value in the range tables provided.
// The search looks through the start-end pairs looking for the key value. It
// is assumed that the start-end pairs are both represented by UShort values,
// ranges do not overlap, and are monotonically increasing.
// @param startIndex the position to read the first start value from
// @param startOffset the offset between subsequent start values
// @param endIndex the position to read the first end value from
// @param endOffset the offset between subsequent end values
// @param length the number of start-end pairs
// @param key the value to search for
// @return the index of the start-end pairs in which the key was found; -1
// otherwise
int32_t SearchUShort(int32_t start_index,
int32_t start_offset,
int32_t end_index,
int32_t end_offset,
int32_t length,
int32_t key);
// Search for the key value in the table provided.
// The search looks through the values looking for the key value. It is
// assumed that the are represented by UShort values and are monotonically
// increasing.
// @param startIndex the position to read the first start value from
// @param startOffset the offset between subsequent start values
// @param length the number of start-end pairs
// @param key the value to search for
// @return the index of the start-end pairs in which the key was found; -1
// otherwise
int32_t SearchUShort(int32_t start_index,
int32_t start_offset,
int32_t length,
int32_t key);
// Search for the key value in the range tables provided.
// The search looks through the start-end pairs looking for the key value. It
// is assumed that the start-end pairs are both represented by ULong values
// that can be represented within 31 bits, ranges do not overlap, and are
// monotonically increasing.
// @param startIndex the position to read the first start value from
// @param startOffset the offset between subsequent start values
// @param endIndex the position to read the first end value from
// @param endOffset the offset between subsequent end values
// @param length the number of start-end pairs
// @param key the value to search for
// @return the index of the start-end pairs in which the key was found; -1
// otherwise
int32_t SearchULong(int32_t start_index,
int32_t start_offset,
int32_t end_index,
int32_t end_offset,
int32_t length,
int32_t key);
// TODO(arthurhsu): IMPLEMENT
/*
virtual int32_t ReadFUnit(int32_t index);
virtual int64_t ReadF2Dot14(int32_t index);
virtual int64_t ReadLongDateTime(int32_t index);
*/
// Makes a slice of this FontData. The returned slice will share the data with
// the original FontData.
// @param offset the start of the slice
// @param length the number of bytes in the slice
// @return a slice of the original FontData
// Note: C++ polymorphism requires return type to be consistent
virtual CALLER_ATTACH FontData* Slice(int32_t offset, int32_t length);
// Makes a bottom bound only slice of this array. The returned slice will
// share the data with the original FontData.
// @param offset the start of the slice
// @return a slice of the original FontData
// Note: C++ polymorphism requires return type to be consistent
virtual CALLER_ATTACH FontData* Slice(int32_t offset);
// Not Ported: toString()
protected:
// Constructor. Creates a bounded wrapper of another ReadableFontData from the
// given offset until the end of the original ReadableFontData.
// @param data data to wrap
// @param offset the start of this data's view of the original data
ReadableFontData(ReadableFontData* data, int32_t offset);
// Constructor. Creates a bounded wrapper of another ReadableFontData from the
// given offset until the end of the original ReadableFontData.
// @param data data to wrap
// @param offset the start of this data's view of the original data
// @param length the length of the other FontData to use
ReadableFontData(ReadableFontData* data, int32_t offset, int32_t length);
private:
// Compute the checksum for the font data using any ranges set for the
// calculation.
void ComputeChecksum();
// Do the actual computation of the checksum for a range using the
// TrueType/OpenType checksum algorithm. The range used is from the low bound
// to the high bound in steps of four bytes. If any of the bytes within that 4
// byte segment are not readable then it will considered a zero for
// calculation.
// Only called from within a synchronized method so it does not need to be
// synchronized itself.
// @param lowBound first position to start a 4 byte segment on
// @param highBound last possible position to start a 4 byte segment on
// @return the checksum for the total range
int64_t ComputeCheckSum(int32_t low_bound, int32_t high_bound);
Lock checksum_lock_;
bool checksum_set_;
int64_t checksum_;
IntegerList checksum_range_;
};
typedef Ptr<ReadableFontData> ReadableFontDataPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_

View File

@ -1,201 +0,0 @@
/*
* 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.
*/
#include "sfntly/data/writable_font_data.h"
#include "sfntly/data/memory_byte_array.h"
#include "sfntly/data/growable_memory_byte_array.h"
namespace sfntly {
WritableFontData::WritableFontData(ByteArray* ba) : ReadableFontData(ba) {
}
WritableFontData::~WritableFontData() {}
// static
CALLER_ATTACH
WritableFontData* WritableFontData::CreateWritableFontData(int32_t length) {
ByteArrayPtr ba;
if (length > 0) {
ba = new MemoryByteArray(length);
ba->SetFilledLength(length);
} else {
ba = new GrowableMemoryByteArray();
}
WritableFontDataPtr wfd = new WritableFontData(ba);
return wfd.Detach();
}
// TODO(arthurhsu): re-investigate the memory model of this function. It's
// not too useful without copying, but it's not performance
// savvy to do copying.
CALLER_ATTACH
WritableFontData* WritableFontData::CreateWritableFontData(ByteVector* b) {
ByteArrayPtr ba = new GrowableMemoryByteArray();
ba->Put(0, b);
WritableFontDataPtr wfd = new WritableFontData(ba);
return wfd.Detach();
}
int32_t WritableFontData::WriteByte(int32_t index, byte_t b) {
array_->Put(BoundOffset(index), b);
return 1;
}
int32_t WritableFontData::WriteBytes(int32_t index,
byte_t* b,
int32_t offset,
int32_t length) {
return array_->Put(BoundOffset(index),
b,
offset,
BoundLength(index, length));
}
int32_t WritableFontData::WriteBytes(int32_t index, ByteVector* b) {
assert(b);
return WriteBytes(index, &((*b)[0]), 0, b->size());
}
int32_t WritableFontData::WriteBytesPad(int32_t index,
ByteVector* b,
int32_t offset,
int32_t length,
byte_t pad) {
int32_t written =
array_->Put(BoundOffset(index),
&((*b)[0]),
offset,
BoundLength(index,
std::min<int32_t>(length, b->size() - offset)));
written += WritePadding(written + index, length - written, pad);
return written;
}
int32_t WritableFontData::WritePadding(int32_t index, int32_t count) {
return WritePadding(index, count, (byte_t)0);
}
int32_t WritableFontData::WritePadding(int32_t index, int32_t count,
byte_t pad) {
for (int32_t i = 0; i < count; ++i) {
array_->Put(index + i, pad);
}
return count;
}
int32_t WritableFontData::WriteChar(int32_t index, byte_t c) {
return WriteByte(index, c);
}
int32_t WritableFontData::WriteUShort(int32_t index, int32_t us) {
WriteByte(index, (byte_t)((us >> 8) & 0xff));
WriteByte(index + 1, (byte_t)(us & 0xff));
return 2;
}
int32_t WritableFontData::WriteUShortLE(int32_t index, int32_t us) {
WriteByte(index, (byte_t)(us & 0xff));
WriteByte(index + 1, (byte_t)((us >> 8) & 0xff));
return 2;
}
int32_t WritableFontData::WriteShort(int32_t index, int32_t s) {
return WriteUShort(index, s);
}
int32_t WritableFontData::WriteUInt24(int32_t index, int32_t ui) {
WriteByte(index, (byte_t)((ui >> 16) & 0xff));
WriteByte(index + 1, (byte_t)((ui >> 8) & 0xff));
WriteByte(index + 2, (byte_t)(ui & 0xff));
return 3;
}
int32_t WritableFontData::WriteULong(int32_t index, int64_t ul) {
WriteByte(index, (byte_t)((ul >> 24) & 0xff));
WriteByte(index + 1, (byte_t)((ul >> 16) & 0xff));
WriteByte(index + 2, (byte_t)((ul >> 8) & 0xff));
WriteByte(index + 3, (byte_t)(ul & 0xff));
return 4;
}
int32_t WritableFontData::WriteULongLE(int32_t index, int64_t ul) {
WriteByte(index, (byte_t)(ul & 0xff));
WriteByte(index + 1, (byte_t)((ul >> 8) & 0xff));
WriteByte(index + 2, (byte_t)((ul >> 16) & 0xff));
WriteByte(index + 3, (byte_t)((ul >> 24) & 0xff));
return 4;
}
int32_t WritableFontData::WriteLong(int32_t index, int64_t l) {
return WriteULong(index, l);
}
int32_t WritableFontData::WriteFixed(int32_t index, int32_t f) {
return WriteLong(index, f);
}
int32_t WritableFontData::WriteDateTime(int32_t index, int64_t date) {
WriteULong(index, (date >> 32) & 0xffffffff);
WriteULong(index + 4, date & 0xffffffff);
return 8;
}
void WritableFontData::CopyFrom(InputStream* is, int32_t length) {
array_->CopyFrom(is, length);
}
void WritableFontData::CopyFrom(InputStream* is) {
array_->CopyFrom(is);
}
CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset,
int32_t length) {
if (offset < 0 || offset + length > Size()) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundsException(
"Attempt to bind data outside of its limits");
#endif
return NULL;
}
FontDataPtr slice = new WritableFontData(this, offset, length);
return slice.Detach();
}
CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset) {
if (offset > Size()) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundsException(
"Attempt to bind data outside of its limits");
#endif
return NULL;
}
FontDataPtr slice = new WritableFontData(this, offset);
return slice.Detach();
}
WritableFontData::WritableFontData(WritableFontData* data, int32_t offset)
: ReadableFontData(data, offset) {
}
WritableFontData::WritableFontData(WritableFontData* data,
int32_t offset,
int32_t length)
: ReadableFontData(data, offset, length) {
}
} // namespace sfntly

View File

@ -1,211 +0,0 @@
/*
* 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_DATA_WRITABLE_FONT_DATA_H_
#define SFNTLY_CPP_SRC_SFNTLY_DATA_WRITABLE_FONT_DATA_H_
#include "sfntly/data/readable_font_data.h"
namespace sfntly {
// Writable font data wrapper. Supports writing of data primitives in the
// TrueType / OpenType spec.
class WritableFontData : public ReadableFontData {
public:
explicit WritableFontData(ByteArray* ba);
virtual ~WritableFontData();
// Constructs a writable font data object. If the length is specified as
// positive then a fixed size font data object will be created. If the length
// is zero or less then a growable font data object will be created and the
// size will be used as an estimate to help in allocating the original space.
// @param length if length > 0 create a fixed length font data; otherwise
// create a growable font data
// @return a new writable font data
static CALLER_ATTACH WritableFontData* CreateWritableFontData(int32_t length);
// Constructs a writable font data object. The new font data object will wrap
// the bytes passed in to the factory and it will take make a copy of those
// bytes.
// @param b the byte vector to wrap
// @return a new writable font data
static CALLER_ATTACH WritableFontData* CreateWritableFontData(ByteVector* b);
// Write a byte at the given index.
// @param index index into the font data
// @param b the byte to write
// @return the number of bytes written
virtual int32_t WriteByte(int32_t index, byte_t b);
// Write the bytes from the array.
// @param index index into the font data
// @param b the source for the bytes to be written
// @param offset offset in the byte array
// @param length the length of the bytes to be written
// @return the number of bytes actually written; -1 if the index is outside
// the FontData's range
virtual int32_t WriteBytes(int32_t index,
byte_t* b,
int32_t offset,
int32_t length);
// Write the bytes from the array.
// @param index index into the font data
// @param b the source for the bytes to be written
// @return the number of bytes actually written; -1 if the index is outside
// the FontData's range
virtual int32_t WriteBytes(int32_t index, ByteVector* b);
// Write the bytes from the array and pad if necessary.
// Write to the length given using the byte array provided and if there are
// not enough bytes in the array then pad to the requested length using the
// pad byte specified.
// @param index index into the font data
// @param b the source for the bytes to be written
// @param offset offset in the byte array
// @param length the length of the bytes to be written
// @param pad the padding byte to be used if necessary
// @return the number of bytes actually written
virtual int32_t WriteBytesPad(int32_t index,
ByteVector* b,
int32_t offset,
int32_t length,
byte_t pad);
// Writes padding to the FontData. The padding byte written is 0x00.
// @param index index into the font data
// @param count the number of pad bytes to write
// @return the number of pad bytes written
virtual int32_t WritePadding(int32_t index, int32_t count);
// Writes padding to the FontData.
// @param index index into the font data
// @param count the number of pad bytes to write
// @param pad the byte value to use as padding
// @return the number of pad bytes written
virtual int32_t WritePadding(int32_t index, int32_t count, byte_t pad);
// Write the CHAR at the given index.
// @param index index into the font data
// @param c the CHAR
// @return the number of bytes actually written
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t WriteChar(int32_t index, byte_t c);
// Write the USHORT at the given index.
// @param index index into the font data
// @param us the USHORT
// @return the number of bytes actually written
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t WriteUShort(int32_t index, int32_t us);
// Write the USHORT at the given index in little endian format.
// @param index index into the font data
// @param us the USHORT
// @return the number of bytes actually written
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t WriteUShortLE(int32_t index, int32_t us);
// Write the SHORT at the given index.
// @param index index into the font data
// @param s the SHORT
// @return the number of bytes actually written
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t WriteShort(int32_t index, int32_t s);
// Write the UINT24 at the given index.
// @param index index into the font data
// @param ui the UINT24
// @return the number of bytes actually written
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t WriteUInt24(int32_t index, int32_t ui);
// Write the ULONG at the given index.
// @param index index into the font data
// @param ul the ULONG
// @return the number of bytes actually written
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t WriteULong(int32_t index, int64_t ul);
// Write the ULONG at the given index in little endian format.
// @param index index into the font data
// @param ul the ULONG
// @return the number of bytes actually written
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t WriteULongLE(int32_t index, int64_t ul);
// Write the LONG at the given index.
// @param index index into the font data
// @param l the LONG
// @return the number of bytes actually written
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t WriteLong(int32_t index, int64_t l);
// Write the Fixed at the given index.
// @param index index into the font data
// @param f the Fixed
// @return the number of bytes actually written
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t WriteFixed(int32_t index, int32_t f);
// Write the LONGDATETIME at the given index.
// @param index index into the font data
// @param date the LONGDATETIME
// @return the number of bytes actually written
// @throws IndexOutOfBoundsException if index is outside the FontData's range
virtual int32_t WriteDateTime(int32_t index, int64_t date);
// Copy from the InputStream into this FontData.
// @param is the source
// @param length the number of bytes to copy
// @throws IOException
virtual void CopyFrom(InputStream* is, int32_t length);
// Copy everything from the InputStream into this FontData.
// @param is the source
// @throws IOException
virtual void CopyFrom(InputStream* is);
// Makes a slice of this FontData. The returned slice will share the data with
// the original FontData.
// @param offset the start of the slice
// @param length the number of bytes in the slice
// @return a slice of the original FontData
virtual CALLER_ATTACH FontData* Slice(int32_t offset, int32_t length);
// Makes a bottom bound only slice of this array. The returned slice will
// share the data with the original FontData.
// @param offset the start of the slice
// @return a slice of the original FontData
virtual CALLER_ATTACH FontData* Slice(int32_t offset);
private:
// Constructor with a lower bound.
// @param data other WritableFontData object to share data with
// @param offset offset from the other WritableFontData's data
WritableFontData(WritableFontData* data, int32_t offset);
// Constructor with lower bound and a length bound.
// @param data other WritableFontData object to share data with
// @param offset offset from the other WritableFontData's data
// @param length length of other WritableFontData's data to use
WritableFontData(WritableFontData* data, int32_t offset, int32_t length);
};
typedef Ptr<WritableFontData> WritableFontDataPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_WRITABLE_FONT_DATA_H_

View File

@ -1,568 +0,0 @@
/*
* 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.
*/
#include "sfntly/font.h"
#include <stdio.h>
#include <functional>
#include <algorithm>
#include <map>
#include <string>
#include <typeinfo>
#include <iterator>
#include "sfntly/data/font_input_stream.h"
#include "sfntly/font_factory.h"
#include "sfntly/math/fixed1616.h"
#include "sfntly/math/font_math.h"
#include "sfntly/port/exception_type.h"
#include "sfntly/table/core/font_header_table.h"
#include "sfntly/table/core/horizontal_device_metrics_table.h"
#include "sfntly/table/core/horizontal_header_table.h"
#include "sfntly/table/core/horizontal_metrics_table.h"
#include "sfntly/table/core/maximum_profile_table.h"
#include "sfntly/table/truetype/loca_table.h"
#include "sfntly/tag.h"
namespace sfntly {
const int32_t SFNTVERSION_MAJOR = 1;
const int32_t SFNTVERSION_MINOR = 0;
/******************************************************************************
* Font class
******************************************************************************/
Font::~Font() {}
bool Font::HasTable(int32_t tag) {
TableMap::const_iterator result = tables_.find(tag);
TableMap::const_iterator end = tables_.end();
return (result != end);
}
// Changed by Kovid: these four methods cannot be inlined, if they are they
// return incorrect values when compiled with -fPIC
int32_t Font::sfnt_version() { return sfnt_version_; }
ByteVector* Font::digest() { return &digest_; }
int64_t Font::checksum() { return checksum_; }
int32_t Font::num_tables() { return (int32_t)tables_.size(); }
Table* Font::GetTable(int32_t tag) {
if (!HasTable(tag)) {
return NULL;
}
return tables_[tag];
}
const TableMap* Font::GetTableMap() {
return &tables_;
}
void Font::Serialize(OutputStream* os, IntegerList* table_ordering) {
assert(table_ordering);
IntegerList final_table_ordering;
GenerateTableOrdering(table_ordering, &final_table_ordering);
TableHeaderList table_records;
BuildTableHeadersForSerialization(&final_table_ordering, &table_records);
FontOutputStream fos(os);
SerializeHeader(&fos, &table_records);
SerializeTables(&fos, &table_records);
}
Font::Font(int32_t sfnt_version, ByteVector* digest)
: sfnt_version_(sfnt_version) {
// non-trivial assignments that makes debugging hard if placed in
// initialization list
digest_ = *digest;
}
void Font::BuildTableHeadersForSerialization(IntegerList* table_ordering,
TableHeaderList* table_headers) {
assert(table_headers);
assert(table_ordering);
IntegerList final_table_ordering;
GenerateTableOrdering(table_ordering, &final_table_ordering);
int32_t table_offset = Offset::kTableRecordBegin + num_tables() *
Offset::kTableRecordSize;
for (IntegerList::iterator tag = final_table_ordering.begin(),
tag_end = final_table_ordering.end();
tag != tag_end; ++tag) {
if (tables_.find(*tag) == tables_.end()) {
continue;
}
TablePtr table = tables_[*tag];
if (table != NULL) {
HeaderPtr header =
new Header(*tag, table->CalculatedChecksum(), table_offset,
table->header()->length());
table_headers->push_back(header);
table_offset += (table->DataLength() + 3) & ~3;
}
}
}
void Font::SerializeHeader(FontOutputStream* fos,
TableHeaderList* table_headers) {
fos->WriteFixed(sfnt_version_);
fos->WriteUShort(table_headers->size());
int32_t log2_of_max_power_of_2 = FontMath::Log2(table_headers->size());
int32_t search_range = 2 << (log2_of_max_power_of_2 - 1 + 4);
fos->WriteUShort(search_range);
fos->WriteUShort(log2_of_max_power_of_2);
fos->WriteUShort((table_headers->size() * 16) - search_range);
HeaderTagSortedSet sorted_headers;
std::copy(table_headers->begin(),
table_headers->end(),
std::inserter(sorted_headers, sorted_headers.end()));
for (HeaderTagSortedSet::iterator record = sorted_headers.begin(),
record_end = sorted_headers.end();
record != record_end; ++record) {
fos->WriteULong((*record)->tag());
fos->WriteULong((int32_t)((*record)->checksum()));
fos->WriteULong((*record)->offset());
fos->WriteULong((*record)->length());
}
}
void Font::SerializeTables(FontOutputStream* fos,
TableHeaderList* table_headers) {
assert(fos);
assert(table_headers);
for (TableHeaderList::iterator record = table_headers->begin(),
end_of_headers = table_headers->end();
record != end_of_headers; ++record) {
TablePtr target_table = GetTable((*record)->tag());
if (target_table == NULL) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("Table out of sync with font header.");
#endif
return;
}
int32_t table_size = target_table->Serialize(fos);
if (table_size != (*record)->length()) {
assert(false);
}
int32_t filler_size = ((table_size + 3) & ~3) - table_size;
for (int32_t i = 0; i < filler_size; ++i) {
fos->Write(static_cast<byte_t>(0));
}
}
}
void Font::GenerateTableOrdering(IntegerList* default_table_ordering,
IntegerList* table_ordering) {
assert(default_table_ordering);
assert(table_ordering);
table_ordering->clear();
if (default_table_ordering->empty()) {
DefaultTableOrdering(default_table_ordering);
}
typedef std::map<int32_t, bool> Int2Bool;
typedef std::pair<int32_t, bool> Int2BoolEntry;
Int2Bool tables_in_font;
for (TableMap::iterator table = tables_.begin(), table_end = tables_.end();
table != table_end; ++table) {
tables_in_font.insert(Int2BoolEntry(table->first, false));
}
for (IntegerList::iterator tag = default_table_ordering->begin(),
tag_end = default_table_ordering->end();
tag != tag_end; ++tag) {
if (HasTable(*tag)) {
table_ordering->push_back(*tag);
tables_in_font[*tag] = true;
}
}
for (Int2Bool::iterator table = tables_in_font.begin(),
table_end = tables_in_font.end();
table != table_end; ++table) {
if (table->second == false)
table_ordering->push_back(table->first);
}
}
void Font::DefaultTableOrdering(IntegerList* default_table_ordering) {
assert(default_table_ordering);
default_table_ordering->clear();
if (HasTable(Tag::CFF)) {
default_table_ordering->resize(CFF_TABLE_ORDERING_SIZE);
std::copy(CFF_TABLE_ORDERING, CFF_TABLE_ORDERING + CFF_TABLE_ORDERING_SIZE,
default_table_ordering->begin());
return;
}
default_table_ordering->resize(TRUE_TYPE_TABLE_ORDERING_SIZE);
std::copy(TRUE_TYPE_TABLE_ORDERING,
TRUE_TYPE_TABLE_ORDERING + TRUE_TYPE_TABLE_ORDERING_SIZE,
default_table_ordering->begin());
}
/******************************************************************************
* Font::Builder class
******************************************************************************/
Font::Builder::~Builder() {}
CALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(FontFactory* factory,
InputStream* is) {
FontBuilderPtr builder = new Builder(factory);
builder->LoadFont(is);
return builder.Detach();
}
CALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(
FontFactory* factory,
WritableFontData* wfd,
int32_t offset_to_offset_table) {
FontBuilderPtr builder = new Builder(factory);
builder->LoadFont(wfd, offset_to_offset_table);
return builder.Detach();
}
CALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(
FontFactory* factory) {
FontBuilderPtr builder = new Builder(factory);
return builder.Detach();
}
bool Font::Builder::ReadyToBuild() {
// just read in data with no manipulation
if (table_builders_.empty() && !data_blocks_.empty()) {
return true;
}
// TODO(stuartg): font level checks - required tables etc?
for (TableBuilderMap::iterator table_builder = table_builders_.begin(),
table_builder_end = table_builders_.end();
table_builder != table_builder_end;
++table_builder) {
if (!table_builder->second->ReadyToBuild())
return false;
}
return true;
}
CALLER_ATTACH Font* Font::Builder::Build() {
FontPtr font = new Font(sfnt_version_, &digest_);
if (!table_builders_.empty()) {
// Note: Different from Java. Directly use font->tables_ here to avoid
// STL container copying.
BuildTablesFromBuilders(font, &table_builders_, &font->tables_);
}
table_builders_.clear();
data_blocks_.clear();
return font.Detach();
}
void Font::Builder::SetDigest(ByteVector* digest) {
digest_.clear();
digest_ = *digest;
}
void Font::Builder::ClearTableBuilders() {
table_builders_.clear();
}
bool Font::Builder::HasTableBuilder(int32_t tag) {
return (table_builders_.find(tag) != table_builders_.end());
}
Table::Builder* Font::Builder::GetTableBuilder(int32_t tag) {
if (HasTableBuilder(tag))
return table_builders_[tag];
return NULL;
}
Table::Builder* Font::Builder::NewTableBuilder(int32_t tag) {
HeaderPtr header = new Header(tag);
TableBuilderPtr builder;
builder.Attach(Table::Builder::GetBuilder(header, NULL));
table_builders_.insert(TableBuilderEntry(header->tag(), builder));
return builder;
}
Table::Builder* Font::Builder::NewTableBuilder(int32_t tag,
ReadableFontData* src_data) {
assert(src_data);
WritableFontDataPtr data;
data.Attach(WritableFontData::CreateWritableFontData(src_data->Length()));
// TODO(stuarg): take over original data instead?
src_data->CopyTo(data);
HeaderPtr header = new Header(tag, data->Length());
TableBuilderPtr builder;
builder.Attach(Table::Builder::GetBuilder(header, data));
table_builders_.insert(TableBuilderEntry(tag, builder));
return builder;
}
void Font::Builder::RemoveTableBuilder(int32_t tag) {
TableBuilderMap::iterator target = table_builders_.find(tag);
if (target != table_builders_.end()) {
table_builders_.erase(target);
}
}
Font::Builder::Builder(FontFactory* factory)
: factory_(factory),
sfnt_version_(Fixed1616::Fixed(SFNTVERSION_MAJOR, SFNTVERSION_MINOR)) {
}
void Font::Builder::LoadFont(InputStream* is) {
// Note: we do not throw exception here for is. This is more of an assertion.
assert(is);
FontInputStream font_is(is);
HeaderOffsetSortedSet records;
ReadHeader(&font_is, &records);
LoadTableData(&records, &font_is, &data_blocks_);
BuildAllTableBuilders(&data_blocks_, &table_builders_);
font_is.Close();
}
void Font::Builder::LoadFont(WritableFontData* wfd,
int32_t offset_to_offset_table) {
// Note: we do not throw exception here for is. This is more of an assertion.
assert(wfd);
HeaderOffsetSortedSet records;
ReadHeader(wfd, offset_to_offset_table, &records);
LoadTableData(&records, wfd, &data_blocks_);
BuildAllTableBuilders(&data_blocks_, &table_builders_);
}
int32_t Font::Builder::SfntWrapperSize() {
return Offset::kSfntHeaderSize +
(Offset::kTableRecordSize * table_builders_.size());
}
void Font::Builder::BuildAllTableBuilders(DataBlockMap* table_data,
TableBuilderMap* builder_map) {
for (DataBlockMap::iterator record = table_data->begin(),
record_end = table_data->end();
record != record_end; ++record) {
TableBuilderPtr builder;
builder.Attach(GetTableBuilder(record->first.p_, record->second.p_));
builder_map->insert(TableBuilderEntry(record->first->tag(), builder));
}
InterRelateBuilders(&table_builders_);
}
CALLER_ATTACH
Table::Builder* Font::Builder::GetTableBuilder(Header* header,
WritableFontData* data) {
return Table::Builder::GetBuilder(header, data);
}
void Font::Builder::BuildTablesFromBuilders(Font* font,
TableBuilderMap* builder_map,
TableMap* table_map) {
UNREFERENCED_PARAMETER(font);
InterRelateBuilders(builder_map);
// Now build all the tables.
for (TableBuilderMap::iterator builder = builder_map->begin(),
builder_end = builder_map->end();
builder != builder_end; ++builder) {
TablePtr table;
if (builder->second && builder->second->ReadyToBuild()) {
table.Attach(down_cast<Table*>(builder->second->Build()));
}
if (table == NULL) {
table_map->clear();
#if !defined (SFNTLY_NO_EXCEPTION)
std::string builder_string = "Unable to build table - ";
char* table_name = TagToString(builder->first);
builder_string += table_name;
delete[] table_name;
throw RuntimeException(builder_string.c_str());
#endif
return;
}
table_map->insert(TableMapEntry(table->header()->tag(), table));
}
}
static Table::Builder* GetBuilder(TableBuilderMap* builder_map, int32_t tag) {
if (builder_map) {
TableBuilderMap::iterator target = builder_map->find(tag);
if (target != builder_map->end()) {
return target->second.p_;
}
}
return NULL;
}
void Font::Builder::InterRelateBuilders(TableBuilderMap* builder_map) {
Table::Builder* raw_head_builder = GetBuilder(builder_map, Tag::head);
FontHeaderTableBuilderPtr header_table_builder;
if (raw_head_builder != NULL) {
header_table_builder =
down_cast<FontHeaderTable::Builder*>(raw_head_builder);
}
Table::Builder* raw_hhea_builder = GetBuilder(builder_map, Tag::hhea);
HorizontalHeaderTableBuilderPtr horizontal_header_builder;
if (raw_head_builder != NULL) {
horizontal_header_builder =
down_cast<HorizontalHeaderTable::Builder*>(raw_hhea_builder);
}
Table::Builder* raw_maxp_builder = GetBuilder(builder_map, Tag::maxp);
MaximumProfileTableBuilderPtr max_profile_builder;
if (raw_maxp_builder != NULL) {
max_profile_builder =
down_cast<MaximumProfileTable::Builder*>(raw_maxp_builder);
}
Table::Builder* raw_loca_builder = GetBuilder(builder_map, Tag::loca);
LocaTableBuilderPtr loca_table_builder;
if (raw_loca_builder != NULL) {
loca_table_builder = down_cast<LocaTable::Builder*>(raw_loca_builder);
}
Table::Builder* raw_hmtx_builder = GetBuilder(builder_map, Tag::hmtx);
HorizontalMetricsTableBuilderPtr horizontal_metrics_builder;
if (raw_hmtx_builder != NULL) {
horizontal_metrics_builder =
down_cast<HorizontalMetricsTable::Builder*>(raw_hmtx_builder);
}
#if defined (SFNTLY_EXPERIMENTAL)
Table::Builder* raw_hdmx_builder = GetBuilder(builder_map, Tag::hdmx);
HorizontalDeviceMetricsTableBuilderPtr hdmx_table_builder;
if (raw_hdmx_builder != NULL) {
hdmx_table_builder =
down_cast<HorizontalDeviceMetricsTable::Builder*>(raw_hdmx_builder);
}
#endif
// set the inter table data required to build certain tables
if (horizontal_metrics_builder != NULL) {
if (max_profile_builder != NULL) {
horizontal_metrics_builder->SetNumGlyphs(
max_profile_builder->NumGlyphs());
}
if (horizontal_header_builder != NULL) {
horizontal_metrics_builder->SetNumberOfHMetrics(
horizontal_header_builder->NumberOfHMetrics());
}
}
if (loca_table_builder != NULL) {
if (max_profile_builder != NULL) {
loca_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs());
}
if (header_table_builder != NULL) {
loca_table_builder->set_format_version(
header_table_builder->IndexToLocFormat());
}
}
#if defined (SFNTLY_EXPERIMENTAL)
// Note: In C++, hdmx_table_builder can be NULL in a subsetter.
if (max_profile_builder != NULL && hdmx_table_builder != NULL) {
hdmx_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs());
}
#endif
}
void Font::Builder::ReadHeader(FontInputStream* is,
HeaderOffsetSortedSet* records) {
assert(records);
sfnt_version_ = is->ReadFixed();
num_tables_ = is->ReadUShort();
search_range_ = is->ReadUShort();
entry_selector_ = is->ReadUShort();
range_shift_ = is->ReadUShort();
for (int32_t table_number = 0; table_number < num_tables_; ++table_number) {
// Need to use temporary vars here. C++ evaluates function parameters from
// right to left and thus breaks the order of input stream.
int32_t tag = is->ReadULongAsInt();
int64_t checksum = is->ReadULong();
int32_t offset = is->ReadULongAsInt();
int32_t length = is->ReadULongAsInt();
HeaderPtr table = new Header(tag, checksum, offset, length);
records->insert(table);
}
}
void Font::Builder::ReadHeader(ReadableFontData* fd,
int32_t offset,
HeaderOffsetSortedSet* records) {
assert(records);
sfnt_version_ = fd->ReadFixed(offset + Offset::kSfntVersion);
num_tables_ = fd->ReadUShort(offset + Offset::kNumTables);
search_range_ = fd->ReadUShort(offset + Offset::kSearchRange);
entry_selector_ = fd->ReadUShort(offset + Offset::kEntrySelector);
range_shift_ = fd->ReadUShort(offset + Offset::kRangeShift);
int32_t table_offset = offset + Offset::kTableRecordBegin;
for (int32_t table_number = 0;
table_number < num_tables_;
table_number++, table_offset += Offset::kTableRecordSize) {
int32_t tag = fd->ReadULongAsInt(table_offset + Offset::kTableTag);
int64_t checksum = fd->ReadULong(table_offset + Offset::kTableCheckSum);
int32_t offset = fd->ReadULongAsInt(table_offset + Offset::kTableOffset);
int32_t length = fd->ReadULongAsInt(table_offset + Offset::kTableLength);
HeaderPtr table = new Header(tag, checksum, offset, length);
records->insert(table);
}
}
void Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers,
FontInputStream* is,
DataBlockMap* table_data) {
assert(table_data);
for (HeaderOffsetSortedSet::iterator table_header = headers->begin(),
table_end = headers->end();
table_header != table_end;
++table_header) {
is->Skip((*table_header)->offset() - is->position());
FontInputStream table_is(is, (*table_header)->length());
WritableFontDataPtr data;
data.Attach(
WritableFontData::CreateWritableFontData((*table_header)->length()));
data->CopyFrom(&table_is, (*table_header)->length());
table_data->insert(DataBlockEntry(*table_header, data));
}
}
void Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers,
WritableFontData* fd,
DataBlockMap* table_data) {
for (HeaderOffsetSortedSet::iterator table_header = headers->begin(),
table_end = headers->end();
table_header != table_end;
++table_header) {
FontDataPtr sliced_data;
sliced_data.Attach(
fd->Slice((*table_header)->offset(), (*table_header)->length()));
WritableFontDataPtr data = down_cast<WritableFontData*>(sliced_data.p_);
table_data->insert(DataBlockEntry(*table_header, data));
}
}
} // namespace sfntly

View File

@ -1,352 +0,0 @@
/*
* 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();
// 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();
// Get the checksum for this font.
int64_t checksum();
// Get the number of tables in this font.
int32_t num_tables();
// Whether the font has a particular table.
bool HasTable(int32_t tag);
// 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_

View File

@ -1,214 +0,0 @@
/*
* 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.
*/
#include "sfntly/font_factory.h"
#include <string.h>
#include "sfntly/tag.h"
namespace sfntly {
FontFactory::~FontFactory() {
}
CALLER_ATTACH FontFactory* FontFactory::GetInstance() {
FontFactoryPtr instance = new FontFactory();
return instance.Detach();
}
void FontFactory::FingerprintFont(bool fingerprint) {
fingerprint_ = fingerprint;
}
bool FontFactory::FingerprintFont() {
return fingerprint_;
}
void FontFactory::LoadFonts(InputStream* is, FontArray* output) {
assert(output);
PushbackInputStream* pbis = down_cast<PushbackInputStream*>(is);
if (IsCollection(pbis)) {
LoadCollection(pbis, output);
return;
}
FontPtr font;
font.Attach(LoadSingleOTF(pbis));
if (font) {
output->push_back(font);
}
}
void FontFactory::LoadFonts(ByteVector* b, FontArray* output) {
WritableFontDataPtr wfd;
wfd.Attach(WritableFontData::CreateWritableFontData(b));
if (IsCollection(wfd)) {
LoadCollection(wfd, output);
return;
}
FontPtr font;
font.Attach(LoadSingleOTF(wfd));
if (font) {
output->push_back(font);
}
}
void FontFactory::LoadFontsForBuilding(InputStream* is,
FontBuilderArray* output) {
PushbackInputStream* pbis = down_cast<PushbackInputStream*>(is);
if (IsCollection(pbis)) {
LoadCollectionForBuilding(pbis, output);
return;
}
FontBuilderPtr builder;
builder.Attach(LoadSingleOTFForBuilding(pbis));
if (builder) {
output->push_back(builder);
}
}
void FontFactory::LoadFontsForBuilding(ByteVector* b,
FontBuilderArray* output) {
WritableFontDataPtr wfd;
wfd.Attach(WritableFontData::CreateWritableFontData(b));
if (IsCollection(wfd)) {
LoadCollectionForBuilding(wfd, output);
return;
}
FontBuilderPtr builder;
builder.Attach(LoadSingleOTFForBuilding(wfd, 0));
if (builder) {
output->push_back(builder);
}
}
void FontFactory::SerializeFont(Font* font, OutputStream* os) {
font->Serialize(os, &table_ordering_);
}
void FontFactory::SetSerializationTableOrdering(
const IntegerList& table_ordering) {
table_ordering_ = table_ordering;
}
CALLER_ATTACH Font::Builder* FontFactory::NewFontBuilder() {
return Font::Builder::GetOTFBuilder(this);
}
CALLER_ATTACH Font* FontFactory::LoadSingleOTF(InputStream* is) {
FontBuilderPtr builder;
builder.Attach(LoadSingleOTFForBuilding(is));
return builder->Build();
}
CALLER_ATTACH Font* FontFactory::LoadSingleOTF(WritableFontData* wfd) {
FontBuilderPtr builder;
builder.Attach(LoadSingleOTFForBuilding(wfd, 0));
return builder->Build();
}
void FontFactory::LoadCollection(InputStream* is, FontArray* output) {
FontBuilderArray ba;
LoadCollectionForBuilding(is, &ba);
output->reserve(ba.size());
for (FontBuilderArray::iterator builder = ba.begin(), builders_end = ba.end();
builder != builders_end; ++builder) {
FontPtr font;
font.Attach((*builder)->Build());
output->push_back(font);
}
}
void FontFactory::LoadCollection(WritableFontData* wfd, FontArray* output) {
FontBuilderArray builders;
LoadCollectionForBuilding(wfd, &builders);
output->reserve(builders.size());
for (FontBuilderArray::iterator builder = builders.begin(),
builders_end = builders.end();
builder != builders_end; ++builder) {
FontPtr font;
font.Attach((*builder)->Build());
output->push_back(font);
}
}
CALLER_ATTACH
Font::Builder* FontFactory::LoadSingleOTFForBuilding(InputStream* is) {
// UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream
Font::Builder* builder = Font::Builder::GetOTFBuilder(this, is);
// UNIMPLEMENTED: setDigest
return builder;
}
CALLER_ATTACH Font::Builder*
FontFactory::LoadSingleOTFForBuilding(WritableFontData* wfd,
int32_t offset_to_offset_table) {
// UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream
Font::Builder* builder =
Font::Builder::GetOTFBuilder(this, wfd, offset_to_offset_table);
// UNIMPLEMENTED: setDigest
return builder;
}
void FontFactory::LoadCollectionForBuilding(InputStream* is,
FontBuilderArray* builders) {
assert(is);
assert(builders);
WritableFontDataPtr wfd;
wfd.Attach(WritableFontData::CreateWritableFontData(is->Available()));
wfd->CopyFrom(is);
LoadCollectionForBuilding(wfd, builders);
}
void FontFactory::LoadCollectionForBuilding(WritableFontData* wfd,
FontBuilderArray* builders) {
int32_t ttc_tag = wfd->ReadULongAsInt(Offset::kTTCTag);
UNREFERENCED_PARAMETER(ttc_tag);
int32_t version = wfd->ReadFixed(Offset::kVersion);
UNREFERENCED_PARAMETER(version);
int32_t num_fonts = wfd->ReadULongAsInt(Offset::kNumFonts);
builders->reserve(num_fonts);
int32_t offset_table_offset = Offset::kOffsetTable;
for (int32_t font_number = 0;
font_number < num_fonts;
font_number++, offset_table_offset += DataSize::kULONG) {
int32_t offset = wfd->ReadULongAsInt(offset_table_offset);
FontBuilderPtr builder;
builder.Attach(LoadSingleOTFForBuilding(wfd, offset));
builders->push_back(builder);
}
}
bool FontFactory::IsCollection(PushbackInputStream* pbis) {
ByteVector tag(4);
pbis->Read(&tag);
pbis->Unread(&tag);
return Tag::ttcf == GenerateTag(tag[0], tag[1], tag[2], tag[3]);
}
bool FontFactory::IsCollection(ReadableFontData* rfd) {
ByteVector tag(4);
rfd->ReadBytes(0, &(tag[0]), 0, tag.size());
return Tag::ttcf ==
GenerateTag(tag[0], tag[1], tag[2], tag[3]);
}
FontFactory::FontFactory()
: fingerprint_(false) {
}
} // namespace sfntly

View File

@ -1,140 +0,0 @@
/*
* 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_FACTORY_H_
#define SFNTLY_CPP_SRC_SFNTLY_FONT_FACTORY_H_
#include <vector>
#include "sfntly/port/refcount.h"
#include "sfntly/port/type.h"
#include "sfntly/font.h"
namespace sfntly {
class FontFactory : public RefCounted<FontFactory> {
public:
virtual ~FontFactory();
// Factory method for the construction of a font factory.
static CALLER_ATTACH FontFactory* GetInstance();
// Toggle whether fonts that are loaded are fingerprinted with a SHA-1 hash.
// If a font is fingerprinted then a SHA-1 hash is generated at load time and
// stored in the font. This is useful for uniquely identifying fonts. By
// default this is turned on.
// @param fingerprint whether fingerprinting should be turned on or off
// TODO(arthurhsu): IMPLEMENT: C++ port currently don't do any SHA-1
void FingerprintFont(bool fingerprint);
bool FingerprintFont();
// Load the font(s) from the input stream. The current settings on the factory
// are used during the loading process. One or more fonts are returned if the
// stream contains valid font data. Some font container formats may have more
// than one font and in this case multiple font objects will be returned. If
// the data in the stream cannot be parsed or is invalid an array of size zero
// will be returned.
void LoadFonts(InputStream* is, FontArray* output);
// ByteArray font loading
// Load the font(s) from the byte array. The current settings on the factory
// are used during the loading process. One or more fonts are returned if the
// stream contains valid font data. Some font container formats may have more
// than one font and in this case multiple font objects will be returned. If
// the data in the stream cannot be parsed or is invalid an array of size zero
// will be returned.
void LoadFonts(ByteVector* b, FontArray* output);
// Load the font(s) from the input stream into font builders. The current
// settings on the factory are used during the loading process. One or more
// font builders are returned if the stream contains valid font data. Some
// font container formats may have more than one font and in this case
// multiple font builder objects will be returned. If the data in the stream
// cannot be parsed or is invalid an array of size zero will be returned.
void LoadFontsForBuilding(InputStream* is, FontBuilderArray* output);
// Load the font(s) from the byte array into font builders. The current
// settings on the factory are used during the loading process. One or more
// font builders are returned if the stream contains valid font data. Some
// font container formats may have more than one font and in this case
// multiple font builder objects will be returned. If the data in the stream
// cannot be parsed or is invalid an array of size zero will be returned.
void LoadFontsForBuilding(ByteVector* b, FontBuilderArray* output);
// Font serialization
// Serialize the font to the output stream.
// NOTE: in this port we attempted not to implement I/O stream because dealing
// with cross-platform I/O stream itself is big enough as a project.
// Byte buffer it is.
void SerializeFont(Font* font, OutputStream* os);
// Set the table ordering to be used in serializing a font. The table ordering
// is an ordered list of table ids and tables will be serialized in the order
// given. Any tables whose id is not listed in the ordering will be placed in
// an unspecified order following those listed.
void SetSerializationTableOrdering(const IntegerList& table_ordering);
// Get an empty font builder for creating a new font from scratch.
CALLER_ATTACH Font::Builder* NewFontBuilder();
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.
kTTCTag = 0,
kVersion = 4,
kNumFonts = 8,
kOffsetTable = 12,
// TTC Version 2.0 extensions.
// Offsets from end of OffsetTable.
kulDsigTag = 0,
kulDsigLength = 4,
kulDsigOffset = 8
};
};
FontFactory();
CALLER_ATTACH Font* LoadSingleOTF(InputStream* is);
CALLER_ATTACH Font* LoadSingleOTF(WritableFontData* wfd);
void LoadCollection(InputStream* is, FontArray* output);
void LoadCollection(WritableFontData* wfd, FontArray* output);
CALLER_ATTACH Font::Builder* LoadSingleOTFForBuilding(InputStream* is);
CALLER_ATTACH Font::Builder*
LoadSingleOTFForBuilding(WritableFontData* wfd,
int32_t offset_to_offset_table);
void LoadCollectionForBuilding(InputStream* is, FontBuilderArray* builders);
void LoadCollectionForBuilding(WritableFontData* ba,
FontBuilderArray* builders);
static bool IsCollection(PushbackInputStream* pbis);
static bool IsCollection(ReadableFontData* wfd);
bool fingerprint_;
IntegerList table_ordering_;
};
typedef Ptr<FontFactory> FontFactoryPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_FONT_FACTORY_H_

View File

@ -1,41 +0,0 @@
/*
* 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_MATH_FIXED1616_H_
#define SFNTLY_CPP_SRC_SFNTLY_MATH_FIXED1616_H_
#include "sfntly/port/type.h"
namespace sfntly {
class Fixed1616 {
public:
static inline int32_t Integral(int32_t fixed) {
return (fixed >> 16);
}
static inline int32_t Fractional(int32_t fixed) {
return (fixed & 0xffff);
}
static inline int32_t Fixed(int32_t integral, int32_t fractional) {
return ((integral & 0xffff) << 16) | (fractional & 0xffff);
}
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_MATH_FIXED1616_H_

View File

@ -1,49 +0,0 @@
/*
* 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_MATH_FONT_MATH_H_
#define SFNTLY_CPP_SRC_SFNTLY_MATH_FONT_MATH_H_
#include "sfntly/port/type.h"
namespace sfntly {
class FontMath {
public:
static int32_t Log2(int32_t a) {
int r = 0; // r will be lg(a)
while (a != 0) {
a >>= 1;
r++;
}
return r - 1;
}
// Calculates the amount of padding needed. The values provided need to be in
// the same units. So, if the size is given as the number of bytes then the
// alignment size must also be specified as byte size to align to.
// @param size the size of the data that may need padding
// @param alignmentSize the number of units to align to
// @return the number of units needing to be added for alignment
static int32_t PaddingRequired(int32_t size, int32_t alignment_size) {
int32_t padding = alignment_size - (size % alignment_size);
return padding == alignment_size ? 0 : padding;
}
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_MATH_FONT_MATH_H_

View File

@ -1,71 +0,0 @@
/*
* 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_PORT_ATOMIC_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_ATOMIC_H_
#if defined (WIN32)
#include <windows.h>
static inline size_t AtomicIncrement(size_t* address) {
#if defined (_WIN64)
return InterlockedIncrement64(reinterpret_cast<LONGLONG*>(address));
#else
return InterlockedIncrement(reinterpret_cast<LONG*>(address));
#endif
}
static inline size_t AtomicDecrement(size_t* address) {
#if defined (_WIN64)
return InterlockedDecrement64(reinterpret_cast<LONGLONG*>(address));
#else
return InterlockedDecrement(reinterpret_cast<LONG*>(address));
#endif
}
#elif defined (__APPLE__)
#include <libkern/OSAtomic.h>
static inline size_t AtomicIncrement(size_t* address) {
return OSAtomicIncrement32Barrier(reinterpret_cast<int32_t*>(address));
}
static inline size_t AtomicDecrement(size_t* address) {
return OSAtomicDecrement32Barrier(reinterpret_cast<int32_t*>(address));
}
// Originally we check __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4, however, there are
// issues that clang not carring over this definition. Therefore we boldly
// assume it's gcc or gcc-compatible here. Compilation shall still fail since
// the intrinsics used are GCC-specific.
#else
#include <stddef.h>
static inline size_t AtomicIncrement(size_t* address) {
return __sync_add_and_fetch(address, 1);
}
static inline size_t AtomicDecrement(size_t* address) {
return __sync_sub_and_fetch(address, 1);
}
#endif // WIN32
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_ATOMIC_H_

View File

@ -1,28 +0,0 @@
/*
* 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_PORT_CONFIG_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_CONFIG_H_
#if !defined(SFNTLY_BIG_ENDIAN) && !defined(SFNTLY_LITTLE_ENDIAN)
#if defined (__ppc__) || defined (__ppc64__)
#define SFNTLY_BIG_ENDIAN
#else
#define SFNTLY_LITTLE_ENDIAN
#endif
#endif
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_CONFIG_H_

View File

@ -1,77 +0,0 @@
/*
* 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_PORT_ENDIAN_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_ENDIAN_H_
#include "sfntly/port/config.h"
#include "sfntly/port/type.h"
namespace sfntly {
static inline uint16_t EndianSwap16(uint16_t value) {
return (uint16_t)((value >> 8) | (value << 8));
}
static inline int32_t EndianSwap32(int32_t value) {
return (((value & 0x000000ff) << 24) |
((value & 0x0000ff00) << 8) |
((value & 0x00ff0000) >> 8) |
((value & 0xff000000) >> 24));
}
static inline uint64_t EndianSwap64(uint64_t value) {
return (((value & 0x00000000000000ffLL) << 56) |
((value & 0x000000000000ff00LL) << 40) |
((value & 0x0000000000ff0000LL) << 24) |
((value & 0x00000000ff000000LL) << 8) |
((value & 0x000000ff00000000LL) >> 8) |
((value & 0x0000ff0000000000LL) >> 24) |
((value & 0x00ff000000000000LL) >> 40) |
((value & 0xff00000000000000LL) >> 56));
}
#ifdef SFNTLY_LITTLE_ENDIAN
#define ToBE16(n) EndianSwap16(n)
#define ToBE32(n) EndianSwap32(n)
#define ToBE64(n) EndianSwap64(n)
#define ToLE16(n) (n)
#define ToLE32(n) (n)
#define ToLE64(n) (n)
#define FromBE16(n) EndianSwap16(n)
#define FromBE32(n) EndianSwap32(n)
#define FromBE64(n) EndianSwap64(n)
#define FromLE16(n) (n)
#define FromLE32(n) (n)
#define FromLE64(n) (n)
#else // SFNTLY_BIG_ENDIAN
#define ToBE16(n) (n)
#define ToBE32(n) (n)
#define ToBE64(n) (n)
#define ToLE16(n) EndianSwap16(n)
#define ToLE32(n) EndianSwap32(n)
#define ToLE64(n) EndianSwap64(n)
#define FromBE16(n) (n)
#define FromBE32(n) (n)
#define FromBE64(n) (n)
#define FromLE16(n) EndianSwap16(n)
#define FromLE32(n) EndianSwap32(n)
#define FromLE64(n) EndianSwap64(n)
#endif
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_ENDIAN_H_

View File

@ -1,125 +0,0 @@
/*
* 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.
*/
// Exceptions used in sfntly
#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_EXCEPTION_TYPE_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_EXCEPTION_TYPE_H_
#if !defined (SFNTLY_NO_EXCEPTION)
#include <exception>
#include <string>
#include <sstream>
namespace sfntly {
class Exception : public std::exception {
public:
Exception() : what_("Unknown exception") {}
explicit Exception(const char* message) throw() { SetMessage(message); }
virtual ~Exception() throw() {}
virtual const char* what() const throw() { return what_.c_str(); }
protected:
void SetMessage(const char* message) throw() {
try {
what_ = message;
} catch (...) {}
}
private:
std::string what_;
};
class IndexOutOfBoundException : public Exception {
public:
IndexOutOfBoundException() throw() : Exception("Index out of bound") {}
explicit IndexOutOfBoundException(const char* message) throw()
: Exception(message) {}
IndexOutOfBoundException(const char* message, int32_t index) throw() {
try {
std::ostringstream msg;
msg << message;
msg << ":";
msg << index;
SetMessage(msg.str().c_str());
} catch (...) {}
}
virtual ~IndexOutOfBoundException() throw() {}
};
class IOException : public Exception {
public:
IOException() throw() : Exception("I/O exception") {}
explicit IOException(const char* message) throw() : Exception(message) {}
virtual ~IOException() throw() {}
};
class ArithmeticException : public Exception {
public:
ArithmeticException() throw() : Exception("Arithmetic exception") {}
explicit ArithmeticException(const char* message) throw()
: Exception(message) {}
virtual ~ArithmeticException() throw() {}
};
class UnsupportedOperationException : public Exception {
public:
UnsupportedOperationException() throw() :
Exception("Operation not supported") {}
explicit UnsupportedOperationException(const char* message) throw()
: Exception(message) {}
virtual ~UnsupportedOperationException() throw() {}
};
class RuntimeException : public Exception {
public:
RuntimeException() throw() : Exception("Runtime exception") {}
explicit RuntimeException(const char* message) throw()
: Exception(message) {}
virtual ~RuntimeException() throw() {}
};
class NoSuchElementException : public Exception {
public:
NoSuchElementException() throw() : Exception("No such element") {}
explicit NoSuchElementException(const char* message) throw()
: Exception(message) {}
virtual ~NoSuchElementException() throw() {}
};
class IllegalArgumentException : public Exception {
public:
IllegalArgumentException() throw() : Exception("Illegal argument") {}
explicit IllegalArgumentException(const char* message) throw()
: Exception(message) {}
virtual ~IllegalArgumentException() throw() {}
};
class IllegalStateException : public Exception {
public:
IllegalStateException() throw() : Exception("Illegal state") {}
explicit IllegalStateException(const char* message) throw()
: Exception(message) {}
virtual ~IllegalStateException() throw() {}
};
} // namespace sfntly
#endif // #if !defined (SFNTLY_NO_EXCEPTION)
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_EXCEPTION_TYPE_H_

View File

@ -1,169 +0,0 @@
/*
* 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.
*/
#if defined (WIN32)
#include <windows.h>
#endif
#include "sfntly/port/file_input_stream.h"
#include "sfntly/port/exception_type.h"
namespace sfntly {
FileInputStream::FileInputStream()
: file_(NULL),
position_(0),
length_(0) {
}
FileInputStream::~FileInputStream() {
Close();
}
int32_t FileInputStream::Available() {
return length_ - position_;
}
void FileInputStream::Close() {
if (file_) {
fclose(file_);
length_ = 0;
position_ = 0;
file_ = NULL;
}
}
void FileInputStream::Mark(int32_t readlimit) {
// NOP
UNREFERENCED_PARAMETER(readlimit);
}
bool FileInputStream::MarkSupported() {
return false;
}
int32_t FileInputStream::Read() {
if (!file_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("no opened file");
#endif
return 0;
}
if (feof(file_)) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("eof reached");
#endif
return 0;
}
byte_t value;
size_t length = fread(&value, 1, 1, file_);
position_ += length;
return value;
}
int32_t FileInputStream::Read(ByteVector* b) {
return Read(b, 0, b->size());
}
int32_t FileInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
assert(b);
if (!file_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("no opened file");
#endif
return 0;
}
if (feof(file_)) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("eof reached");
#endif
return 0;
}
size_t read_count = std::min<size_t>(length_ - position_, length);
if (b->size() < (size_t)(offset + read_count)) {
b->resize((size_t)(offset + read_count));
}
int32_t actual_read = fread(&((*b)[offset]), 1, read_count, file_);
position_ += actual_read;
return actual_read;
}
void FileInputStream::Reset() {
// NOP
}
int64_t FileInputStream::Skip(int64_t n) {
if (!file_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("no opened file");
#endif
return 0;
}
int64_t skip_count = 0;
if (n < 0) { // move backwards
skip_count = std::max<int64_t>(0 - (int64_t)position_, n);
position_ -= (size_t)(0 - skip_count);
fseek(file_, position_, SEEK_SET);
} else {
skip_count = std::min<size_t>(length_ - position_, (size_t)n);
position_ += (size_t)skip_count;
fseek(file_, (size_t)skip_count, SEEK_CUR);
}
return skip_count;
}
void FileInputStream::Unread(ByteVector* b) {
Unread(b, 0, b->size());
}
void FileInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) {
assert(b);
assert(b->size() >= size_t(offset + length));
if (!file_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("no opened file");
#endif
return;
}
size_t unread_count = std::min<size_t>(position_, length);
fseek(file_, position_ - unread_count, SEEK_SET);
position_ -= unread_count;
Read(b, offset, length);
fseek(file_, position_ - unread_count, SEEK_SET);
position_ -= unread_count;
}
bool FileInputStream::Open(const char* file_path) {
assert(file_path);
if (file_) {
Close();
}
#if defined (WIN32)
fopen_s(&file_, file_path, "rb");
#else
file_ = fopen(file_path, "rb");
#endif
if (file_ == NULL) {
return false;
}
fseek(file_, 0, SEEK_END);
length_ = ftell(file_);
fseek(file_, 0, SEEK_SET);
return true;
}
} // namespace sfntly

View File

@ -1,57 +0,0 @@
/*
* 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_PORT_FILE_INPUT_STREAM_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_FILE_INPUT_STREAM_H_
#include <stdio.h>
#include "sfntly/port/input_stream.h"
namespace sfntly {
class FileInputStream : public PushbackInputStream {
public:
FileInputStream();
virtual ~FileInputStream();
// InputStream methods
virtual int32_t Available();
virtual void Close();
virtual void Mark(int32_t readlimit);
virtual bool MarkSupported();
virtual int32_t Read();
virtual int32_t Read(ByteVector* b);
virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length);
virtual void Reset();
virtual int64_t Skip(int64_t n);
// PushbackInputStream methods
virtual void Unread(ByteVector* b);
virtual void Unread(ByteVector* b, int32_t offset, int32_t length);
// Own methods
virtual bool Open(const char* file_path);
private:
FILE* file_;
size_t position_;
size_t length_;
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_FILE_INPUT_STREAM_H_

View File

@ -1,49 +0,0 @@
/*
* 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_PORT_INPUT_STREAM_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_INPUT_STREAM_H_
#include "sfntly/port/type.h"
namespace sfntly {
// C++ equivalent to Java's OutputStream class
class InputStream {
public:
// Make gcc -Wnon-virtual-dtor happy.
virtual ~InputStream() {}
virtual int32_t Available() = 0;
virtual void Close() = 0;
virtual void Mark(int32_t readlimit) = 0;
virtual bool MarkSupported() = 0;
virtual int32_t Read() = 0;
virtual int32_t Read(ByteVector* b) = 0;
virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length) = 0;
virtual void Reset() = 0;
virtual int64_t Skip(int64_t n) = 0;
};
class PushbackInputStream : public InputStream {
public:
virtual void Unread(ByteVector* b) = 0;
virtual void Unread(ByteVector* b, int32_t offset, int32_t length) = 0;
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_INPUT_STREAM_H_

View File

@ -1,94 +0,0 @@
/*
* 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_PORT_JAVA_ITERATOR_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_JAVA_ITERATOR_H_
#include "sfntly/port/refcount.h"
// Interface of Java iterator.
// This is a forward read-only iterator that represents java.util.Iterator<E>
namespace sfntly {
template <typename ReturnType, typename ContainerBase>
class Iterator : public virtual RefCount {
public:
virtual ~Iterator() {}
virtual ContainerBase* container_base() = 0;
protected:
Iterator() {}
NO_COPY_AND_ASSIGN(Iterator);
};
template <typename ReturnType, typename Container,
typename ContainerBase = Container>
class PODIterator : public Iterator<ReturnType, ContainerBase>,
public RefCounted< PODIterator<ReturnType, Container> > {
public:
explicit PODIterator(Container* container) : container_(container) {}
virtual ~PODIterator() {}
virtual ContainerBase* container_base() {
return static_cast<ContainerBase*>(container_);
}
virtual bool HasNext() = 0;
virtual ReturnType Next() = 0;
virtual void Remove() {
#if !defined (SFNTLY_NO_EXCEPTION)
// Default to no support.
throw UnsupportedOperationException();
#endif
}
protected:
Container* container() { return container_; }
private:
Container* container_; // Dumb pointer is used to avoid circular ref-counting
};
template <typename ReturnType, typename Container,
typename ContainerBase = Container>
class RefIterator : public Iterator<ReturnType, ContainerBase>,
public RefCounted< RefIterator<ReturnType, Container> > {
public:
explicit RefIterator(Container* container) : container_(container) {}
virtual ~RefIterator() {}
virtual ContainerBase* container_base() {
return static_cast<ContainerBase*>(container_);
}
virtual bool HasNext() = 0;
CALLER_ATTACH virtual ReturnType* Next() = 0;
virtual void Remove() {
#if !defined (SFNTLY_NO_EXCEPTION)
// Default to no support.
throw UnsupportedOperationException();
#endif
}
protected:
Container* container() { return container_; }
private:
Container* container_; // Dumb pointer is used to avoid circular ref-counting
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_JAVA_ITERATOR_H_

View File

@ -1,72 +0,0 @@
/*
* 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.
*/
#include "sfntly/port/lock.h"
namespace sfntly {
#if defined (WIN32)
Lock::Lock() {
// The second parameter is the spin count, for short-held locks it avoid the
// contending thread from going to sleep which helps performance greatly.
::InitializeCriticalSectionAndSpinCount(&os_lock_, 2000);
}
Lock::~Lock() {
::DeleteCriticalSection(&os_lock_);
}
bool Lock::Try() {
if (::TryEnterCriticalSection(&os_lock_) != FALSE) {
return true;
}
return false;
}
void Lock::Acquire() {
::EnterCriticalSection(&os_lock_);
}
void Lock::Unlock() {
::LeaveCriticalSection(&os_lock_);
}
#else // We assume it's pthread
Lock::Lock() {
pthread_mutex_init(&os_lock_, NULL);
}
Lock::~Lock() {
pthread_mutex_destroy(&os_lock_);
}
bool Lock::Try() {
return (pthread_mutex_trylock(&os_lock_) == 0);
}
void Lock::Acquire() {
pthread_mutex_lock(&os_lock_);
}
void Lock::Unlock() {
pthread_mutex_unlock(&os_lock_);
}
#endif
} // namespace sfntly

View File

@ -1,76 +0,0 @@
/*
* 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_PORT_LOCK_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_LOCK_H_
#if defined (WIN32)
#include <windows.h>
#else // Assume pthread.
#include <pthread.h>
#include <errno.h>
#endif
#include "sfntly/port/type.h"
namespace sfntly {
#if defined (WIN32)
typedef CRITICAL_SECTION OSLockType;
#else // Assume pthread.
typedef pthread_mutex_t OSLockType;
#endif
class Lock {
public:
Lock();
~Lock();
// If the lock is not held, take it and return true. If the lock is already
// held by something else, immediately return false.
bool Try();
// Take the lock, blocking until it is available if necessary.
void Acquire();
// Release the lock. This must only be called by the lock's holder: after
// a successful call to Try, or a call to Lock.
void Unlock();
private:
OSLockType os_lock_;
NO_COPY_AND_ASSIGN(Lock);
};
// A helper class that acquires the given Lock while the AutoLock is in scope.
class AutoLock {
public:
explicit AutoLock(Lock& lock) : lock_(lock) {
lock_.Acquire();
}
~AutoLock() {
lock_.Unlock();
}
private:
Lock& lock_;
NO_COPY_AND_ASSIGN(AutoLock);
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_LOCK_H_

View File

@ -1,147 +0,0 @@
/*
* 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.
*/
#if defined (WIN32)
#include <windows.h>
#endif
#include <string.h>
#include "sfntly/port/memory_input_stream.h"
#include "sfntly/port/exception_type.h"
namespace sfntly {
MemoryInputStream::MemoryInputStream()
: buffer_(NULL),
position_(0),
length_(0) {
}
MemoryInputStream::~MemoryInputStream() {
Close();
}
int32_t MemoryInputStream::Available() {
return length_ - position_;
}
void MemoryInputStream::Close() {
}
void MemoryInputStream::Mark(int32_t readlimit) {
// NOP
UNREFERENCED_PARAMETER(readlimit);
}
bool MemoryInputStream::MarkSupported() {
return false;
}
int32_t MemoryInputStream::Read() {
if (!buffer_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("no memory attached");
#endif
return 0;
}
if (position_ >= length_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("eof reached");
#endif
return 0;
}
byte_t value = buffer_[position_++];
return value;
}
int32_t MemoryInputStream::Read(ByteVector* b) {
return Read(b, 0, b->size());
}
int32_t MemoryInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
assert(b);
if (!buffer_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("no memory attached");
#endif
return 0;
}
if (position_ >= length_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("eof reached");
#endif
return 0;
}
size_t read_count = std::min<size_t>(length_ - position_, length);
if (b->size() < (size_t)(offset + read_count)) {
b->resize((size_t)(offset + read_count));
}
memcpy(&((*b)[offset]), buffer_ + position_, read_count);
position_ += read_count;
return read_count;
}
void MemoryInputStream::Reset() {
// NOP
}
int64_t MemoryInputStream::Skip(int64_t n) {
if (!buffer_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("no memory attached");
#endif
return 0;
}
int64_t skip_count = 0;
if (n < 0) { // move backwards
skip_count = std::max<int64_t>(0 - (int64_t)position_, n);
position_ -= (size_t)(0 - skip_count);
} else {
skip_count = std::min<size_t>(length_ - position_, (size_t)n);
position_ += (size_t)skip_count;
}
return skip_count;
}
void MemoryInputStream::Unread(ByteVector* b) {
Unread(b, 0, b->size());
}
void MemoryInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) {
assert(b);
assert(b->size() >= size_t(offset + length));
if (!buffer_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("no memory attached");
#endif
return;
}
size_t unread_count = std::min<size_t>(position_, length);
position_ -= unread_count;
Read(b, offset, length);
position_ -= unread_count;
}
bool MemoryInputStream::Attach(const byte_t* buffer, size_t length) {
assert(buffer);
assert(length);
buffer_ = buffer;
length_ = length;
return true;
}
} // namespace sfntly

View File

@ -1,57 +0,0 @@
/*
* 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_PORT_MEMORY_INPUT_STREAM_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_INPUT_STREAM_H_
#include <stdio.h>
#include "sfntly/port/input_stream.h"
namespace sfntly {
class MemoryInputStream : public PushbackInputStream {
public:
MemoryInputStream();
virtual ~MemoryInputStream();
// InputStream methods
virtual int32_t Available();
virtual void Close();
virtual void Mark(int32_t readlimit);
virtual bool MarkSupported();
virtual int32_t Read();
virtual int32_t Read(ByteVector* b);
virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length);
virtual void Reset();
virtual int64_t Skip(int64_t n);
// PushbackInputStream methods
virtual void Unread(ByteVector* b);
virtual void Unread(ByteVector* b, int32_t offset, int32_t length);
// Own methods
virtual bool Attach(const byte_t* buffer, size_t length);
private:
const byte_t* buffer_;
size_t position_;
size_t length_;
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_INPUT_STREAM_H_

View File

@ -1,72 +0,0 @@
/*
* 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.
*/
#include "sfntly/port/memory_output_stream.h"
namespace sfntly {
MemoryOutputStream::MemoryOutputStream() {
}
MemoryOutputStream::~MemoryOutputStream() {
}
void MemoryOutputStream::Write(ByteVector* buffer) {
store_.insert(store_.end(), buffer->begin(), buffer->end());
}
void MemoryOutputStream::Write(ByteVector* buffer,
int32_t offset,
int32_t length) {
assert(buffer);
if (offset >= 0 && length > 0) {
store_.insert(store_.end(),
buffer->begin() + offset,
buffer->begin() + offset + length);
} else {
#if !defined(SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundException();
#endif
}
}
void MemoryOutputStream::Write(byte_t* buffer, int32_t offset, int32_t length) {
assert(buffer);
if (offset >= 0 && length > 0) {
store_.insert(store_.end(), buffer + offset, buffer + offset + length);
} else {
#if !defined(SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundException();
#endif
}
}
void MemoryOutputStream::Write(byte_t b) {
store_.push_back(b);
}
byte_t* MemoryOutputStream::Get() {
if (store_.empty()) {
return NULL;
}
return &(store_[0]);
}
size_t MemoryOutputStream::Size() {
return store_.size();
}
} // namespace sfntly

View File

@ -1,51 +0,0 @@
/*
* 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_PORT_MEMORY_OUTPUT_STREAM_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_OUTPUT_STREAM_H_
#include <cstddef>
#include <vector>
#include "sfntly/port/type.h"
#include "sfntly/port/output_stream.h"
namespace sfntly {
// OutputStream backed by STL vector
class MemoryOutputStream : public OutputStream {
public:
MemoryOutputStream();
virtual ~MemoryOutputStream();
virtual void Close() {} // no-op
virtual void Flush() {} // no-op
virtual void Write(ByteVector* buffer);
virtual void Write(ByteVector* buffer, int32_t offset, int32_t length);
virtual void Write(byte_t* buffer, int32_t offset, int32_t length);
virtual void Write(byte_t b);
byte_t* Get();
size_t Size();
private:
std::vector<byte_t> store_;
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_OUTPUT_STREAM_H_

View File

@ -1,46 +0,0 @@
/*
* 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_PORT_OUTPUT_STREAM_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_OUTPUT_STREAM_H_
#include "sfntly/port/type.h"
namespace sfntly {
// C++ equivalent to Java's OutputStream class
class OutputStream {
public:
// Make gcc -Wnon-virtual-dtor happy.
virtual ~OutputStream() {}
virtual void Close() = 0;
virtual void Flush() = 0;
virtual void Write(ByteVector* buffer) = 0;
virtual void Write(byte_t b) = 0;
// Note: C++ port offered both versions of Write() here. The first one is
// better because it does check bounds. The second one is there for
// performance concerns.
virtual void Write(ByteVector* buffer, int32_t offset, int32_t length) = 0;
// Note: Caller is responsible for the boundary of buffer.
virtual void Write(byte_t* buffer, int32_t offset, int32_t length) = 0;
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_OUTPUT_STREAM_H_

View File

@ -1,277 +0,0 @@
/*
* 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.
*/
// Object reference count and smart pointer implementation.
// Smart pointer usage in sfntly:
//
// sfntly carries a smart pointer implementation like COM. Ref-countable object
// type inherits from RefCounted<>, which have AddRef and Release just like
// IUnknown (but no QueryInterface). Use a Ptr<> based smart pointer to hold
// the object so that the object ref count is handled correctly.
//
// class Foo : public RefCounted<Foo> {
// public:
// static Foo* CreateInstance() {
// Ptr<Foo> obj = new Foo(); // ref count = 1
// return obj.Detach();
// }
// };
// typedef Ptr<Foo> FooPtr; // common short-hand notation
// FooPtr obj;
// obj.Attach(Foo::CreatedInstance()); // ref count = 1
// {
// FooPtr obj2 = obj; // ref count = 2
// } // ref count = 1, obj2 out of scope
// obj.Release(); // ref count = 0, object destroyed
// Notes on usage:
// 1. Virtual inherit from RefCount interface in base class if smart pointers
// are going to be defined.
// 2. All RefCounted objects must be instantiated on the heap. Allocating the
// object on stack will cause crash.
// 3. Be careful when you have complex inheritance. For example,
// class A : public RefCounted<A>;
// class B : public A, public RefCounted<B>;
// In this case the smart pointer is pretty dumb and don't count on it to
// nicely destroy your objects as designed. Try refactor your code like
// class I; // the common interface and implementations
// class A : public I, public RefCounted<A>; // A specific implementation
// class B : public I, public RefCounted<B>; // B specific implementation
// 4. Smart pointers here are very bad candidates for function parameters. Use
// dumb pointers in function parameter list.
// 5. When down_cast is performed on a dangling pointer due to bugs in code,
// VC++ will generate SEH which is not handled well in VC++ debugger. One
// can use WinDBG to run it and get the faulting stack.
// 6. Idioms for heap object as return value
// Foo* createFoo() { FooPtr obj = new Foo(); return obj.Detach(); }
// Foo* passthru() { FooPtr obj = createFoo(), return obj; }
// FooPtr end_scope_pointer;
// end_scope_pointer.Attach(passThrough);
// If you are not passing that object back, you are the end of scope.
#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_REFCOUNT_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_REFCOUNT_H_
#if !defined (NDEBUG)
#define ENABLE_OBJECT_COUNTER
// #define REF_COUNT_DEBUGGING
#endif
#if defined (REF_COUNT_DEBUGGING)
#include <stdio.h>
#include <typeinfo>
#endif
#include "sfntly/port/atomic.h"
#include "sfntly/port/type.h"
// Special tag for functions that requires caller to attach instead of using
// assignment operators.
#define CALLER_ATTACH
#if defined (REF_COUNT_DEBUGGING)
#define DEBUG_OUTPUT(a) \
fprintf(stderr, "%s%s:oc=%d,oid=%d,rc=%d\n", a, \
typeid(this).name(), object_counter_, object_id_, ref_count_)
#else
#define DEBUG_OUTPUT(a)
#endif
#if defined (_MSC_VER)
// VC 2008/2010 incorrectly gives this warning for pure virtual functions
// in virtual inheritance. The only way to get around it is to disable it.
#pragma warning(disable:4250)
#endif
namespace sfntly {
class RefCount {
public:
// Make gcc -Wnon-virtual-dtor happy.
virtual ~RefCount() {}
virtual size_t AddRef() const = 0;
virtual size_t Release() const = 0;
};
template <typename T>
class NoAddRefRelease : public T {
public:
NoAddRefRelease();
~NoAddRefRelease();
private:
virtual size_t AddRef() const = 0;
virtual size_t Release() const = 0;
};
template <typename TDerived>
class RefCounted : virtual public RefCount {
public:
RefCounted() : ref_count_(0) {
#if defined (ENABLE_OBJECT_COUNTER)
object_id_ = AtomicIncrement(&next_id_);
AtomicIncrement(&object_counter_);
DEBUG_OUTPUT("C ");
#endif
}
RefCounted(const RefCounted<TDerived>&) : ref_count_(0) {}
virtual ~RefCounted() {
#if defined (ENABLE_OBJECT_COUNTER)
AtomicDecrement(&object_counter_);
DEBUG_OUTPUT("D ");
#endif
}
RefCounted<TDerived>& operator=(const RefCounted<TDerived>&) {
// Each object maintains own ref count, don't propagate.
return *this;
}
virtual size_t AddRef() const {
size_t new_count = AtomicIncrement(&ref_count_);
DEBUG_OUTPUT("A ");
return new_count;
}
virtual size_t Release() const {
size_t new_ref_count = AtomicDecrement(&ref_count_);
DEBUG_OUTPUT("R ");
if (new_ref_count == 0) {
// A C-style is used to cast away const-ness and to derived.
// lint does not like this but this is how it works.
delete (TDerived*)(this);
}
return new_ref_count;
}
mutable size_t ref_count_; // reference count of current object
#if defined (ENABLE_OBJECT_COUNTER)
static size_t object_counter_;
static size_t next_id_;
mutable size_t object_id_;
#endif
};
#if defined (ENABLE_OBJECT_COUNTER)
template <typename TDerived> size_t RefCounted<TDerived>::object_counter_ = 0;
template <typename TDerived> size_t RefCounted<TDerived>::next_id_ = 0;
#endif
// semi-smart pointer for RefCount derived objects, similar to CComPtr
template <typename T>
class Ptr {
public:
Ptr() : p_(NULL) {
}
// This constructor shall not be explicit.
// lint does not like this but this is how it works.
Ptr(T* pT) : p_(NULL) {
*this = pT;
}
Ptr(const Ptr<T>& p) : p_(NULL) {
*this = p;
}
~Ptr() {
Release();
}
T* operator=(T* pT) {
if (p_ == pT) {
return p_;
}
if (pT) {
RefCount* p = static_cast<RefCount*>(pT);
if (p == NULL) {
return NULL;
}
p->AddRef(); // always AddRef() before Release()
}
Release();
p_ = pT;
return p_;
}
T* operator=(const Ptr<T>& p) {
if (p_ == p.p_) {
return p_;
}
return operator=(p.p_);
}
operator T*&() {
return p_;
}
T& operator*() const {
return *p_; // It can throw!
}
NoAddRefRelease<T>* operator->() const {
return (NoAddRefRelease<T>*)p_; // It can throw!
}
bool operator!() const {
return (p_ == NULL);
}
bool operator<(const Ptr<T>& p) const {
return (p_ < p.p_);
}
bool operator!=(T* pT) const {
return !operator==(pT);
}
bool operator==(T* pT) const {
return (p_ == pT);
}
size_t Release() const {
size_t ref_count = 0;
if (p_) {
RefCount* p = static_cast<RefCount*>(p_);
if (p) {
ref_count = p->Release();
}
p_ = NULL;
}
return ref_count;
}
void Attach(T* pT) {
if (p_ != pT) {
Release();
p_ = pT;
}
}
T* Detach() {
T* pT = p_;
p_ = NULL;
return pT;
}
mutable T* p_;
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_REFCOUNT_H_

View File

@ -1,102 +0,0 @@
/*
* 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_PORT_TYPE_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_TYPE_H_
#include <assert.h>
#if defined (_MSC_VER) && (_MSC_VER < 1600)
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned __int16 uint16_t;
typedef signed __int16 int16_t;
typedef unsigned __int32 uint32_t;
typedef signed __int32 int32_t;
typedef unsigned __int64 uint64_t;
typedef signed __int64 int64_t;
// Definitions to avoid ICU redefinition issue
#define U_HAVE_INT8_T 1
#define U_HAVE_UINT8_T 1
#define U_HAVE_INT16_T 1
#define U_HAVE_UINT16_T 1
#define U_HAVE_INT32_T 1
#define U_HAVE_UINT32_T 1
#define U_HAVE_INT64_T 1
#define U_HAVE_UINT64_T 1
#else
#include <stdint.h>
#endif
#include <cstddef>
#include <vector>
#include <set>
namespace sfntly {
typedef uint8_t byte_t;
typedef uint16_t word_t;
typedef uint32_t dword_t;
typedef uint64_t qword_t;
typedef std::vector<byte_t> ByteVector;
typedef std::vector<int32_t> IntegerList;
typedef std::set<int32_t> IntegerSet;
// A macro to disallow the copy constructor and operator= functions.
// This should be used in the private: declarations for a class.
#define NO_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
} // namespace sfntly
// Make google3 happy since it prohibits RTTI.
template<typename To, typename From>
inline To implicit_cast(From const &f) {
return f;
}
template<typename To, typename From> // use like this: down_cast<T*>(foo);
inline To down_cast(From* f) { // so we only accept pointers
// Ensures that To is a sub-type of From *. This test is here only
// for compile-time type checking, and has no overhead in an
// optimized build at run-time, as it will be optimized away
// completely.
#if defined (_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4127) // disable "conditional expression is constant"
#endif
if (false) {
implicit_cast<From*, To>(0);
}
#if defined (_MSC_VER)
#pragma warning(pop)
#endif
// The following code is the only place for RTTI. It is done so to allow
// additional type checking when SFNTLY_TYPE_VERIFICATION is defined.
#if defined (SFNTLY_TYPE_VERIFICATION)
assert(f == NULL || dynamic_cast<To>(f) != NULL);
#endif
return static_cast<To>(f);
}
#if !defined(WIN32)
#define UNREFERENCED_PARAMETER(p) do { (void)p; } while (0)
#endif
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_TYPE_H_

View File

@ -1,171 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/big_glyph_metrics.h"
namespace sfntly {
/******************************************************************************
* BigGlyphMetrics class
******************************************************************************/
BigGlyphMetrics::BigGlyphMetrics(ReadableFontData* data)
: GlyphMetrics(data) {
}
BigGlyphMetrics::~BigGlyphMetrics() {
}
int32_t BigGlyphMetrics::Height() {
return data_->ReadByte(Offset::kHeight);
}
int32_t BigGlyphMetrics::Width() {
return data_->ReadByte(Offset::kWidth);
}
int32_t BigGlyphMetrics::HoriBearingX() {
return data_->ReadByte(Offset::kHoriBearingX);
}
int32_t BigGlyphMetrics::HoriBearingY() {
return data_->ReadByte(Offset::kHoriBearingY);
}
int32_t BigGlyphMetrics::HoriAdvance() {
return data_->ReadByte(Offset::kHoriAdvance);
}
int32_t BigGlyphMetrics::VertBearingX() {
return data_->ReadByte(Offset::kVertBearingX);
}
int32_t BigGlyphMetrics::VertBearingY() {
return data_->ReadByte(Offset::kVertBearingY);
}
int32_t BigGlyphMetrics::VertAdvance() {
return data_->ReadByte(Offset::kVertAdvance);
}
/******************************************************************************
* BigGlyphMetrics::Builder class
******************************************************************************/
BigGlyphMetrics::Builder::Builder(WritableFontData* data)
: GlyphMetrics::Builder(data) {
}
BigGlyphMetrics::Builder::Builder(ReadableFontData* data)
: GlyphMetrics::Builder(data) {
}
BigGlyphMetrics::Builder::~Builder() {
}
int32_t BigGlyphMetrics::Builder::Height() {
return InternalReadData()->ReadByte(Offset::kHeight);
}
void BigGlyphMetrics::Builder::SetHeight(byte_t height) {
InternalWriteData()->WriteByte(Offset::kHeight, height);
}
int32_t BigGlyphMetrics::Builder::Width() {
return InternalReadData()->ReadByte(Offset::kWidth);
}
void BigGlyphMetrics::Builder::SetWidth(byte_t width) {
InternalWriteData()->WriteByte(Offset::kWidth, width);
}
int32_t BigGlyphMetrics::Builder::HoriBearingX() {
return InternalReadData()->ReadByte(Offset::kHoriBearingX);
}
void BigGlyphMetrics::Builder::SetHoriBearingX(byte_t bearing) {
InternalWriteData()->WriteByte(Offset::kHoriBearingX, bearing);
}
int32_t BigGlyphMetrics::Builder::HoriBearingY() {
return InternalReadData()->ReadByte(Offset::kHoriBearingY);
}
void BigGlyphMetrics::Builder::SetHoriBearingY(byte_t bearing) {
InternalWriteData()->WriteByte(Offset::kHoriBearingY, bearing);
}
int32_t BigGlyphMetrics::Builder::HoriAdvance() {
return InternalReadData()->ReadByte(Offset::kHoriAdvance);
}
void BigGlyphMetrics::Builder::SetHoriAdvance(byte_t advance) {
InternalWriteData()->WriteByte(Offset::kHoriAdvance, advance);
}
int32_t BigGlyphMetrics::Builder::VertBearingX() {
return InternalReadData()->ReadByte(Offset::kVertBearingX);
}
void BigGlyphMetrics::Builder::SetVertBearingX(byte_t bearing) {
InternalWriteData()->WriteByte(Offset::kVertBearingX, bearing);
}
int32_t BigGlyphMetrics::Builder::VertBearingY() {
return InternalReadData()->ReadByte(Offset::kVertBearingY);
}
void BigGlyphMetrics::Builder::SetVertBearingY(byte_t bearing) {
InternalWriteData()->WriteByte(Offset::kVertBearingY, bearing);
}
int32_t BigGlyphMetrics::Builder::VertAdvance() {
return InternalReadData()->ReadByte(Offset::kVertAdvance);
}
void BigGlyphMetrics::Builder::SetVertAdvance(byte_t advance) {
InternalWriteData()->WriteByte(Offset::kVertAdvance, advance);
}
CALLER_ATTACH FontDataTable*
BigGlyphMetrics::Builder::SubBuildTable(ReadableFontData* data) {
BigGlyphMetricsPtr output = new BigGlyphMetrics(data);
return output.Detach();
}
void BigGlyphMetrics::Builder::SubDataSet() {
// NOP.
}
int32_t BigGlyphMetrics::Builder::SubDataSizeToSerialize() {
return 0;
}
bool BigGlyphMetrics::Builder::SubReadyToSerialize() {
return false;
}
int32_t BigGlyphMetrics::Builder::SubSerialize(WritableFontData* new_data) {
return Data()->CopyTo(new_data);
}
// static
CALLER_ATTACH
BigGlyphMetrics::Builder* BigGlyphMetrics::Builder::CreateBuilder() {
WritableFontDataPtr data;
data.Attach(WritableFontData::CreateWritableFontData(Offset::kMetricsLength));
BigGlyphMetricsBuilderPtr output = new BigGlyphMetrics::Builder(data);
return output.Detach();
}
} // namespace sfntly

View File

@ -1,96 +0,0 @@
/*
* 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_TABLE_BITMAP_BIG_GLYPH_METRICS_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BIG_GLYPH_METRICS_H_
#include "sfntly/table/bitmap/glyph_metrics.h"
namespace sfntly {
class BigGlyphMetrics : public GlyphMetrics,
public RefCounted<BigGlyphMetrics> {
public:
struct Offset {
enum {
kMetricsLength = 8,
kHeight = 0,
kWidth = 1,
kHoriBearingX = 2,
kHoriBearingY = 3,
kHoriAdvance = 4,
kVertBearingX = 5,
kVertBearingY = 6,
kVertAdvance = 7,
};
};
class Builder : public GlyphMetrics::Builder,
public RefCounted<Builder> {
public:
// Constructor scope altered to public because C++ does not allow base
// class to instantiate derived class with protected constructors.
explicit Builder(WritableFontData* data);
explicit Builder(ReadableFontData* data);
virtual ~Builder();
int32_t Height();
void SetHeight(byte_t height);
int32_t Width();
void SetWidth(byte_t width);
int32_t HoriBearingX();
void SetHoriBearingX(byte_t bearing);
int32_t HoriBearingY();
void SetHoriBearingY(byte_t bearing);
int32_t HoriAdvance();
void SetHoriAdvance(byte_t advance);
int32_t VertBearingX();
void SetVertBearingX(byte_t bearing);
int32_t VertBearingY();
void SetVertBearingY(byte_t bearing);
int32_t VertAdvance();
void SetVertAdvance(byte_t advance);
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
virtual int32_t SubDataSizeToSerialize();
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
// Static instantiation function.
static CALLER_ATTACH Builder* CreateBuilder();
};
explicit BigGlyphMetrics(ReadableFontData* data);
virtual ~BigGlyphMetrics();
int32_t Height();
int32_t Width();
int32_t HoriBearingX();
int32_t HoriBearingY();
int32_t HoriAdvance();
int32_t VertBearingX();
int32_t VertBearingY();
int32_t VertAdvance();
};
typedef Ptr<BigGlyphMetrics> BigGlyphMetricsPtr;
typedef Ptr<BigGlyphMetrics::Builder> BigGlyphMetricsBuilderPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BIG_GLYPH_METRICS_H_

View File

@ -1,101 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/bitmap_glyph.h"
#include "sfntly/table/bitmap/simple_bitmap_glyph.h"
#include "sfntly/table/bitmap/composite_bitmap_glyph.h"
namespace sfntly {
/******************************************************************************
* BitmapGlyph class
******************************************************************************/
BitmapGlyph::~BitmapGlyph() {
}
CALLER_ATTACH BitmapGlyph* BitmapGlyph::CreateGlyph(ReadableFontData* data,
int32_t format) {
BitmapGlyphPtr glyph;
BitmapGlyphBuilderPtr builder;
builder.Attach(Builder::CreateGlyphBuilder(data, format));
if (builder) {
glyph.Attach(down_cast<BitmapGlyph*>(builder->Build()));
}
return glyph;
}
BitmapGlyph::BitmapGlyph(ReadableFontData* data, int32_t format)
: SubTable(data), format_(format) {
}
/******************************************************************************
* BitmapGlyph::Builder class
******************************************************************************/
BitmapGlyph::Builder::~Builder() {
}
CALLER_ATTACH BitmapGlyph::Builder*
BitmapGlyph::Builder::CreateGlyphBuilder(ReadableFontData* data,
int32_t format) {
BitmapGlyphBuilderPtr builder;
switch (format) {
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
builder = new SimpleBitmapGlyph::Builder(data, format);
break;
case 8:
case 9:
builder = new CompositeBitmapGlyph::Builder(data, format);
break;
}
return builder.Detach();
}
BitmapGlyph::Builder::Builder(WritableFontData* data, int32_t format)
: SubTable::Builder(data), format_(format) {
}
BitmapGlyph::Builder::Builder(ReadableFontData* data, int32_t format)
: SubTable::Builder(data), format_(format) {
}
CALLER_ATTACH
FontDataTable* BitmapGlyph::Builder::SubBuildTable(ReadableFontData* data) {
UNREFERENCED_PARAMETER(data);
return NULL;
}
void BitmapGlyph::Builder::SubDataSet() {
// NOP
}
int32_t BitmapGlyph::Builder::SubDataSizeToSerialize() {
return InternalReadData()->Length();
}
bool BitmapGlyph::Builder::SubReadyToSerialize() {
return true;
}
int32_t BitmapGlyph::Builder::SubSerialize(WritableFontData* new_data) {
return InternalReadData()->CopyTo(new_data);
}
} // namespace sfntly

View File

@ -1,119 +0,0 @@
/*
* 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_TABLE_BITMAP_BITMAP_GLYPH_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_GLYPH_H_
#include <vector>
#include <map>
#include "sfntly/table/subtable.h"
namespace sfntly {
class BitmapGlyph : public SubTable {
public:
struct Offset {
enum {
// header
kVersion = 0,
kSmallGlyphMetricsLength = 5,
kBigGlyphMetricsLength = 8,
// format 1
kGlyphFormat1_imageData = kSmallGlyphMetricsLength,
// format 2
kGlyphFormat2_imageData = kSmallGlyphMetricsLength,
// format 3
// format 4
// format 5
kGlyphFormat5_imageData = 0,
// format 6
kGlyphFormat6_imageData = kBigGlyphMetricsLength,
// format 7
kGlyphFormat7_imageData = kBigGlyphMetricsLength,
// format 8
kGlyphFormat8_numComponents = kSmallGlyphMetricsLength + 1,
kGlyphFormat8_componentArray = kGlyphFormat8_numComponents +
DataSize::kUSHORT,
// format 9
kGlyphFormat9_numComponents = kBigGlyphMetricsLength,
kGlyphFormat9_componentArray = kGlyphFormat9_numComponents +
DataSize::kUSHORT,
// ebdtComponent
kEbdtComponentLength = DataSize::kUSHORT + 2 * DataSize::kCHAR,
kEbdtComponent_glyphCode = 0,
kEbdtComponent_xOffset = 2,
kEbdtComponent_yOffset = 3,
};
};
// TODO(stuartg): builder is not functional at all
// - need to add subclasses for each type of bitmap glyph
class Builder : public SubTable::Builder {
public:
virtual ~Builder();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
virtual int32_t SubDataSizeToSerialize();
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
int32_t format() { return format_; }
static CALLER_ATTACH Builder* CreateGlyphBuilder(ReadableFontData* data,
int32_t format);
protected:
Builder(WritableFontData* data, int32_t format);
Builder(ReadableFontData* data, int32_t format);
private:
int32_t format_;
};
virtual ~BitmapGlyph();
static CALLER_ATTACH BitmapGlyph* CreateGlyph(ReadableFontData* data,
int32_t format);
int32_t format() { return format_; }
// UNIMPLEMENTED: toString()
protected:
BitmapGlyph(ReadableFontData* data, int32_t format);
private:
int32_t format_;
};
typedef Ptr<BitmapGlyph> BitmapGlyphPtr;
typedef Ptr<BitmapGlyph::Builder> BitmapGlyphBuilderPtr;
typedef std::map<int32_t, BitmapGlyphBuilderPtr> BitmapGlyphBuilderMap;
typedef std::vector<BitmapGlyphBuilderMap> BitmapGlyphBuilderList;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_GLYPH_H_

View File

@ -1,68 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/bitmap_glyph_info.h"
namespace sfntly {
BitmapGlyphInfo::BitmapGlyphInfo(int32_t glyph_id,
int32_t block_offset,
int32_t start_offset,
int32_t length,
int32_t format)
: glyph_id_(glyph_id),
relative_(true),
block_offset_(block_offset),
start_offset_(start_offset),
length_(length),
format_(format) {
}
BitmapGlyphInfo::BitmapGlyphInfo(int32_t glyph_id,
int32_t start_offset,
int32_t length,
int32_t format)
: glyph_id_(glyph_id),
relative_(false),
block_offset_(0),
start_offset_(start_offset),
length_(length),
format_(format) {
}
bool BitmapGlyphInfo::operator==(const BitmapGlyphInfo& rhs) const {
return (format_ == rhs.format_ &&
glyph_id_ == rhs.glyph_id_ &&
length_ == rhs.length_ &&
offset() == rhs.offset());
}
bool BitmapGlyphInfo::operator==(BitmapGlyphInfo* rhs) {
if (rhs == NULL) {
return this == NULL;
}
return (format_ == rhs->format() &&
glyph_id_ == rhs->glyph_id() &&
length_ == rhs->length() &&
offset() == rhs->offset());
}
bool StartOffsetComparator::operator()(BitmapGlyphInfo* lhs,
BitmapGlyphInfo* rhs) {
return lhs->start_offset() > rhs->start_offset();
}
} // namespace sfntly

View File

@ -1,85 +0,0 @@
/*
* 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_TABLE_BITMAP_GLYPH_INFO_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_INFO_H_
#include <vector>
#include <map>
#include "sfntly/table/subtable.h"
namespace sfntly {
// An immutable class holding bitmap glyph information.
class BitmapGlyphInfo : public RefCounted<BitmapGlyphInfo> {
public:
// Constructor for a relative located glyph. The glyph's position in the EBDT
// table is a combination of it's block offset and it's own start offset.
// @param glyphId the glyph id
// @param blockOffset the offset of the block to which the glyph belongs
// @param startOffset the offset of the glyph within the block
// @param length the byte length
// @param format the glyph image format
BitmapGlyphInfo(int32_t glyph_id,
int32_t block_offset,
int32_t start_offset,
int32_t length,
int32_t format);
// Constructor for an absolute located glyph. The glyph's position in the EBDT
// table is only given by it's own start offset.
// @param glyphId the glyph id
// @param startOffset the offset of the glyph within the block
// @param length the byte length
// @param format the glyph image format
BitmapGlyphInfo(int32_t glyph_id,
int32_t start_offset,
int32_t length,
int32_t format);
int32_t glyph_id() const { return glyph_id_; }
bool relative() const { return relative_; }
int32_t block_offset() const { return block_offset_; }
int32_t offset() const { return block_offset() + start_offset(); }
int32_t start_offset() const { return start_offset_; }
int32_t length() const { return length_; }
int32_t format() const { return format_; }
// UNIMPLEMENTED: hashCode()
bool operator==(const BitmapGlyphInfo& rhs) const;
bool operator==(BitmapGlyphInfo* rhs);
private:
int32_t glyph_id_;
bool relative_;
int32_t block_offset_;
int32_t start_offset_;
int32_t length_;
int32_t format_;
};
typedef Ptr<BitmapGlyphInfo> BitmapGlyphInfoPtr;
typedef std::map<int32_t, BitmapGlyphInfoPtr> BitmapGlyphInfoMap;
typedef std::vector<BitmapGlyphInfoMap> BitmapLocaList;
class StartOffsetComparator {
public:
bool operator()(BitmapGlyphInfo* lhs, BitmapGlyphInfo* rhs);
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_INFO_H_

View File

@ -1,604 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/bitmap_size_table.h"
#include <stdio.h>
#include <stdlib.h>
#include "sfntly/math/font_math.h"
#include "sfntly/table/bitmap/eblc_table.h"
#include "sfntly/table/bitmap/index_sub_table_format1.h"
#include "sfntly/table/bitmap/index_sub_table_format2.h"
#include "sfntly/table/bitmap/index_sub_table_format3.h"
#include "sfntly/table/bitmap/index_sub_table_format4.h"
#include "sfntly/table/bitmap/index_sub_table_format5.h"
namespace sfntly {
/******************************************************************************
* BitmapSizeTable class
******************************************************************************/
BitmapSizeTable::~BitmapSizeTable() {
}
int32_t BitmapSizeTable::IndexSubTableArrayOffset() {
return data_->ReadULongAsInt(
EblcTable::Offset::kBitmapSizeTable_indexSubTableArrayOffset);
}
int32_t BitmapSizeTable::IndexTableSize() {
return data_->ReadULongAsInt(
EblcTable::Offset::kBitmapSizeTable_indexTableSize);
}
int32_t BitmapSizeTable::NumberOfIndexSubTables() {
return NumberOfIndexSubTables(data_, 0);
}
int32_t BitmapSizeTable::ColorRef() {
return data_->ReadULongAsInt(EblcTable::Offset::kBitmapSizeTable_colorRef);
}
int32_t BitmapSizeTable::StartGlyphIndex() {
return data_->ReadUShort(EblcTable::Offset::kBitmapSizeTable_startGlyphIndex);
}
int32_t BitmapSizeTable::EndGlyphIndex() {
return data_->ReadUShort(EblcTable::Offset::kBitmapSizeTable_endGlyphIndex);
}
int32_t BitmapSizeTable::PpemX() {
return data_->ReadByte(EblcTable::Offset::kBitmapSizeTable_ppemX);
}
int32_t BitmapSizeTable::PpemY() {
return data_->ReadByte(EblcTable::Offset::kBitmapSizeTable_ppemY);
}
int32_t BitmapSizeTable::BitDepth() {
return data_->ReadByte(EblcTable::Offset::kBitmapSizeTable_bitDepth);
}
int32_t BitmapSizeTable::FlagsAsInt() {
return data_->ReadChar(EblcTable::Offset::kBitmapSizeTable_flags);
}
IndexSubTable* BitmapSizeTable::GetIndexSubTable(int32_t index) {
IndexSubTableList* subtable_list = GetIndexSubTableList();
if (index >= 0 && (size_t)index < subtable_list->size()) {
return (*subtable_list)[index];
}
return NULL;
}
int32_t BitmapSizeTable::GlyphOffset(int32_t glyph_id) {
IndexSubTable* subtable = SearchIndexSubTables(glyph_id);
if (subtable == NULL) {
return -1;
}
return subtable->GlyphOffset(glyph_id);
}
int32_t BitmapSizeTable::GlyphLength(int32_t glyph_id) {
IndexSubTable* subtable = SearchIndexSubTables(glyph_id);
if (subtable == NULL) {
return -1;
}
return subtable->GlyphLength(glyph_id);
}
CALLER_ATTACH BitmapGlyphInfo* BitmapSizeTable::GlyphInfo(int32_t glyph_id) {
IndexSubTable* sub_table = SearchIndexSubTables(glyph_id);
if (sub_table == NULL) {
return NULL;
}
return sub_table->GlyphInfo(glyph_id);
}
int32_t BitmapSizeTable::GlyphFormat(int32_t glyph_id) {
IndexSubTable* subtable = SearchIndexSubTables(glyph_id);
if (subtable == NULL) {
return -1;
}
return subtable->image_format();
}
BitmapSizeTable::BitmapSizeTable(ReadableFontData* data,
ReadableFontData* master_data)
: SubTable(data, master_data) {
}
// static
int32_t BitmapSizeTable::NumberOfIndexSubTables(ReadableFontData* data,
int32_t table_offset) {
return data->ReadULongAsInt(table_offset +
EblcTable::Offset::kBitmapSizeTable_numberOfIndexSubTables);
}
IndexSubTable* BitmapSizeTable::SearchIndexSubTables(int32_t glyph_id) {
// would be faster to binary search but too many size tables don't have
// sorted subtables
#if (SFNTLY_BITMAPSIZE_USE_BINARY_SEARCH)
return BinarySearchIndexSubTables(glyph_id);
#else
return LinearSearchIndexSubTables(glyph_id);
#endif
}
IndexSubTable* BitmapSizeTable::LinearSearchIndexSubTables(int32_t glyph_id) {
IndexSubTableList* subtable_list = GetIndexSubTableList();
for (IndexSubTableList::iterator b = subtable_list->begin(),
e = subtable_list->end(); b != e; b++) {
if ((*b)->first_glyph_index() <= glyph_id &&
(*b)->last_glyph_index() >= glyph_id) {
return *b;
}
}
return NULL;
}
IndexSubTable* BitmapSizeTable::BinarySearchIndexSubTables(int32_t glyph_id) {
IndexSubTableList* subtable_list = GetIndexSubTableList();
int32_t index = 0;
int32_t bottom = 0;
int32_t top = subtable_list->size();
while (top != bottom) {
index = (top + bottom) / 2;
IndexSubTable* subtable = (*subtable_list)[index];
if (glyph_id < subtable->first_glyph_index()) {
// Location beow current location
top = index;
} else {
if (glyph_id <= subtable->last_glyph_index()) {
return subtable;
} else {
bottom = index + 1;
}
}
}
return NULL;
}
CALLER_ATTACH
IndexSubTable* BitmapSizeTable::CreateIndexSubTable(int32_t index) {
return IndexSubTable::CreateIndexSubTable(master_read_data(),
IndexSubTableArrayOffset(),
index);
}
IndexSubTableList* BitmapSizeTable::GetIndexSubTableList() {
AutoLock lock(index_subtables_lock_);
if (index_subtables_.empty()) {
for (int32_t i = 0; i < NumberOfIndexSubTables(); ++i) {
IndexSubTablePtr table;
table.Attach(CreateIndexSubTable(i));
index_subtables_.push_back(table);
}
}
return &index_subtables_;
}
/******************************************************************************
* BitmapSizeTable::Builder class
******************************************************************************/
BitmapSizeTable::Builder::~Builder() {
}
CALLER_ATTACH
FontDataTable* BitmapSizeTable::Builder::SubBuildTable(ReadableFontData* data) {
BitmapSizeTablePtr output = new BitmapSizeTable(data, master_read_data());
return output.Detach();
}
void BitmapSizeTable::Builder::SubDataSet() {
Revert();
}
int32_t BitmapSizeTable::Builder::SubDataSizeToSerialize() {
IndexSubTableBuilderList* builders = IndexSubTableBuilders();
if (builders->empty()) {
return 0;
}
int32_t size = EblcTable::Offset::kBitmapSizeTableLength;
bool variable = false;
for (IndexSubTableBuilderList::iterator b = builders->begin(),
e = builders->end(); b != e; b++) {
size += EblcTable::Offset::kIndexSubTableEntryLength;
int32_t sub_table_size = (*b)->SubDataSizeToSerialize();
int32_t padding = FontMath::PaddingRequired(abs(sub_table_size),
DataSize::kULONG);
#if defined (SFNTLY_DEBUG_BITMAP)
fprintf(stderr, "subtable size=%d\n", sub_table_size);
#endif
variable = (sub_table_size > 0) ? variable : true;
size += abs(sub_table_size) + padding;
}
#if defined (SFNTLY_DEBUG_BITMAP)
fprintf(stderr, "bitmap table size=%d\n", variable ? -size : size);
#endif
return variable ? -size : size;
}
bool BitmapSizeTable::Builder::SubReadyToSerialize() {
if (IndexSubTableBuilders()->empty()) {
return false;
}
return true;
}
int32_t BitmapSizeTable::Builder::SubSerialize(WritableFontData* new_data) {
SetNumberOfIndexSubTables(IndexSubTableBuilders()->size());
int32_t size = InternalReadData()->CopyTo(new_data);
return size;
}
CALLER_ATTACH BitmapSizeTable::Builder*
BitmapSizeTable::Builder::CreateBuilder(WritableFontData* data,
ReadableFontData* master_data) {
BitmapSizeTableBuilderPtr output =
new BitmapSizeTable::Builder(data, master_data);
return output.Detach();
}
CALLER_ATTACH BitmapSizeTable::Builder*
BitmapSizeTable::Builder::CreateBuilder(ReadableFontData* data,
ReadableFontData* master_data) {
BitmapSizeTableBuilderPtr output =
new BitmapSizeTable::Builder(data, master_data);
return output.Detach();
}
int32_t BitmapSizeTable::Builder::IndexSubTableArrayOffset() {
return InternalReadData()->ReadULongAsInt(
EblcTable::Offset::kBitmapSizeTable_indexSubTableArrayOffset);
}
void BitmapSizeTable::Builder::SetIndexSubTableArrayOffset(int32_t offset) {
InternalWriteData()->WriteULong(
EblcTable::Offset::kBitmapSizeTable_indexSubTableArrayOffset, offset);
}
int32_t BitmapSizeTable::Builder::IndexTableSize() {
return InternalReadData()->ReadULongAsInt(
EblcTable::Offset::kBitmapSizeTable_indexTableSize);
}
void BitmapSizeTable::Builder::SetIndexTableSize(int32_t size) {
InternalWriteData()->WriteULong(
EblcTable::Offset::kBitmapSizeTable_indexTableSize, size);
}
int32_t BitmapSizeTable::Builder::NumberOfIndexSubTables() {
return GetIndexSubTableBuilders()->size();
}
int32_t BitmapSizeTable::Builder::ColorRef() {
return InternalReadData()->ReadULongAsInt(
EblcTable::Offset::kBitmapSizeTable_colorRef);
}
int32_t BitmapSizeTable::Builder::StartGlyphIndex() {
return InternalReadData()->ReadUShort(
EblcTable::Offset::kBitmapSizeTable_startGlyphIndex);
}
int32_t BitmapSizeTable::Builder::EndGlyphIndex() {
return InternalReadData()->ReadUShort(
EblcTable::Offset::kBitmapSizeTable_endGlyphIndex);
}
int32_t BitmapSizeTable::Builder::PpemX() {
return InternalReadData()->ReadByte(
EblcTable::Offset::kBitmapSizeTable_ppemX);
}
int32_t BitmapSizeTable::Builder::PpemY() {
return InternalReadData()->ReadByte(
EblcTable::Offset::kBitmapSizeTable_ppemY);
}
int32_t BitmapSizeTable::Builder::BitDepth() {
return InternalReadData()->ReadByte(
EblcTable::Offset::kBitmapSizeTable_bitDepth);
}
int32_t BitmapSizeTable::Builder::FlagsAsInt() {
return InternalReadData()->ReadChar(
EblcTable::Offset::kBitmapSizeTable_flags);
}
IndexSubTable::Builder* BitmapSizeTable::Builder::IndexSubTableBuilder(
int32_t index) {
IndexSubTableBuilderList* sub_table_list = GetIndexSubTableBuilders();
return sub_table_list->at(index);
}
CALLER_ATTACH BitmapGlyphInfo* BitmapSizeTable::Builder::GlyphInfo(
int32_t glyph_id) {
IndexSubTable::Builder* sub_table = SearchIndexSubTables(glyph_id);
if (sub_table == NULL) {
return NULL;
}
return sub_table->GlyphInfo(glyph_id);
}
int32_t BitmapSizeTable::Builder::GlyphOffset(int32_t glyph_id) {
IndexSubTable::Builder* subtable = SearchIndexSubTables(glyph_id);
if (subtable == NULL) {
return -1;
}
return subtable->GlyphOffset(glyph_id);
}
int32_t BitmapSizeTable::Builder::GlyphLength(int32_t glyph_id) {
IndexSubTable::Builder* subtable = SearchIndexSubTables(glyph_id);
if (subtable == NULL) {
return -1;
}
return subtable->GlyphLength(glyph_id);
}
int32_t BitmapSizeTable::Builder::GlyphFormat(int32_t glyph_id) {
IndexSubTable::Builder* subtable = SearchIndexSubTables(glyph_id);
if (subtable == NULL) {
return -1;
}
return subtable->image_format();
}
IndexSubTableBuilderList* BitmapSizeTable::Builder::IndexSubTableBuilders() {
return GetIndexSubTableBuilders();
}
CALLER_ATTACH BitmapSizeTable::Builder::BitmapGlyphInfoIterator*
BitmapSizeTable::Builder::GetIterator() {
Ptr<BitmapSizeTable::Builder::BitmapGlyphInfoIterator> output =
new BitmapSizeTable::Builder::BitmapGlyphInfoIterator(this);
return output.Detach();
}
void BitmapSizeTable::Builder::GenerateLocaMap(BitmapGlyphInfoMap* output) {
assert(output);
Ptr<BitmapSizeTable::Builder::BitmapGlyphInfoIterator> it;
it.Attach(GetIterator());
while (it->HasNext()) {
BitmapGlyphInfoPtr info;
info.Attach(it->Next());
(*output)[info->glyph_id()] = info;
}
}
void BitmapSizeTable::Builder::Revert() {
index_sub_tables_.clear();
set_model_changed(false);
}
BitmapSizeTable::Builder::Builder(WritableFontData* data,
ReadableFontData* master_data)
: SubTable::Builder(data, master_data) {
}
BitmapSizeTable::Builder::Builder(ReadableFontData* data,
ReadableFontData* master_data)
: SubTable::Builder(data, master_data) {
}
void BitmapSizeTable::Builder::SetNumberOfIndexSubTables(int32_t count) {
InternalWriteData()->WriteULong(
EblcTable::Offset::kBitmapSizeTable_numberOfIndexSubTables, count);
}
IndexSubTable::Builder* BitmapSizeTable::Builder::SearchIndexSubTables(
int32_t glyph_id) {
// would be faster to binary search but too many size tables don't have
// sorted subtables
#if (SFNTLY_BITMAPSIZE_USE_BINARY_SEARCH)
return BinarySearchIndexSubTables(glyph_id);
#else
return LinearSearchIndexSubTables(glyph_id);
#endif
}
IndexSubTable::Builder* BitmapSizeTable::Builder::LinearSearchIndexSubTables(
int32_t glyph_id) {
IndexSubTableBuilderList* subtable_list = GetIndexSubTableBuilders();
for (IndexSubTableBuilderList::iterator b = subtable_list->begin(),
e = subtable_list->end();
b != e; b++) {
if ((*b)->first_glyph_index() <= glyph_id &&
(*b)->last_glyph_index() >= glyph_id) {
return *b;
}
}
return NULL;
}
IndexSubTable::Builder* BitmapSizeTable::Builder::BinarySearchIndexSubTables(
int32_t glyph_id) {
IndexSubTableBuilderList* subtable_list = GetIndexSubTableBuilders();
int32_t index = 0;
int32_t bottom = 0;
int32_t top = subtable_list->size();
while (top != bottom) {
index = (top + bottom) / 2;
IndexSubTable::Builder* subtable = subtable_list->at(index);
if (glyph_id < subtable->first_glyph_index()) {
// Location beow current location
top = index;
} else {
if (glyph_id <= subtable->last_glyph_index()) {
return subtable;
} else {
bottom = index + 1;
}
}
}
return NULL;
}
IndexSubTableBuilderList* BitmapSizeTable::Builder::GetIndexSubTableBuilders() {
if (index_sub_tables_.empty()) {
Initialize(InternalReadData());
set_model_changed();
}
return &index_sub_tables_;
}
void BitmapSizeTable::Builder::Initialize(ReadableFontData* data) {
index_sub_tables_.clear();
if (data) {
int32_t number_of_index_subtables =
BitmapSizeTable::NumberOfIndexSubTables(data, 0);
index_sub_tables_.resize(number_of_index_subtables);
for (int32_t i = 0; i < number_of_index_subtables; ++i) {
index_sub_tables_[i].Attach(CreateIndexSubTableBuilder(i));
}
}
}
CALLER_ATTACH IndexSubTable::Builder*
BitmapSizeTable::Builder::CreateIndexSubTableBuilder(int32_t index) {
return IndexSubTable::Builder::CreateBuilder(master_read_data(),
IndexSubTableArrayOffset(),
index);
}
/******************************************************************************
* BitmapSizeTable::Builder::BitmapGlyphInfoIterator class
******************************************************************************/
BitmapSizeTable::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
BitmapSizeTable::Builder* container)
: RefIterator<BitmapGlyphInfo, BitmapSizeTable::Builder>(container) {
sub_table_iter_ = container->IndexSubTableBuilders()->begin();
sub_table_glyph_info_iter_.Attach((*sub_table_iter_)->GetIterator());
}
bool BitmapSizeTable::Builder::BitmapGlyphInfoIterator::HasNext() {
if (sub_table_glyph_info_iter_ && HasNext(sub_table_glyph_info_iter_)) {
return true;
}
while (++sub_table_iter_ != container()->IndexSubTableBuilders()->end()) {
sub_table_glyph_info_iter_.Attach((*sub_table_iter_)->GetIterator());
if (HasNext(sub_table_glyph_info_iter_)) {
return true;
}
}
return false;
}
CALLER_ATTACH
BitmapGlyphInfo* BitmapSizeTable::Builder::BitmapGlyphInfoIterator::Next() {
if (!HasNext()) {
// Note: In C++, we do not throw exception when there's no element.
return NULL;
}
return Next(sub_table_glyph_info_iter_);
}
bool BitmapSizeTable::Builder::BitmapGlyphInfoIterator::HasNext(
BitmapGlyphInfoIter* iterator_base) {
if (iterator_base) {
switch (iterator_base->container_base()->index_format()) {
case 1: {
IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator* it =
down_cast<IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator*>(
iterator_base);
return it->HasNext();
}
case 2: {
IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator* it =
down_cast<IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator*>(
iterator_base);
return it->HasNext();
}
case 3: {
IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator* it =
down_cast<IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator*>(
iterator_base);
return it->HasNext();
}
case 4: {
IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator* it =
down_cast<IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator*>(
iterator_base);
return it->HasNext();
}
case 5: {
IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator* it =
down_cast<IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator*>(
iterator_base);
return it->HasNext();
}
default:
break;
}
}
return false;
}
CALLER_ATTACH
BitmapGlyphInfo* BitmapSizeTable::Builder::BitmapGlyphInfoIterator::Next(
BitmapGlyphInfoIter* iterator_base) {
if (iterator_base) {
switch (iterator_base->container_base()->index_format()) {
case 1: {
IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator* it =
down_cast<IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator*>(
iterator_base);
return it->Next();
}
case 2: {
IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator* it =
down_cast<IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator*>(
iterator_base);
return it->Next();
}
case 3: {
IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator* it =
down_cast<IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator*>(
iterator_base);
return it->Next();
}
case 4: {
IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator* it =
down_cast<IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator*>(
iterator_base);
return it->Next();
}
case 5: {
IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator* it =
down_cast<IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator*>(
iterator_base);
return it->Next();
}
default:
break;
}
}
return NULL;
}
} // namespace sfntly

View File

@ -1,173 +0,0 @@
/*
* 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_TABLE_BITMAP_BITMAP_SIZE_TABLE_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_SIZE_TABLE_H_
#include "sfntly/port/lock.h"
#include "sfntly/table/bitmap/bitmap_glyph_info.h"
#include "sfntly/table/bitmap/index_sub_table.h"
namespace sfntly {
// Binary search would be faster but many fonts have index subtables that
// aren't sorted.
// Note: preprocessor define is used to avoid const expression warnings in C++
// code.
#define SFNTLY_BITMAPSIZE_USE_BINARY_SEARCH 0
class BitmapSizeTable : public SubTable,
public RefCounted<BitmapSizeTable> {
public:
class Builder : public SubTable::Builder,
public RefCounted<Builder> {
public:
class BitmapGlyphInfoIterator :
public RefIterator<BitmapGlyphInfo, Builder> {
public:
explicit BitmapGlyphInfoIterator(Builder* container);
virtual ~BitmapGlyphInfoIterator() {}
virtual bool HasNext();
CALLER_ATTACH virtual BitmapGlyphInfo* Next();
private:
bool HasNext(BitmapGlyphInfoIter* iterator_base);
CALLER_ATTACH BitmapGlyphInfo* Next(BitmapGlyphInfoIter* iterator_base);
IndexSubTableBuilderList::iterator sub_table_iter_;
BitmapGlyphInfoIterPtr sub_table_glyph_info_iter_;
};
virtual ~Builder();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
virtual int32_t SubDataSizeToSerialize();
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
ReadableFontData* master_data);
static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
ReadableFontData* master_data);
// Gets the subtable array offset as set in the original table as read from
// the font file. This value cannot be explicitly set and will be generated
// during table building.
// @return the subtable array offset
int32_t IndexSubTableArrayOffset();
// Sets the subtable array offset. This is used only during the building
// process when the objects are being serialized.
// @param offset the offset to the index subtable array
void SetIndexSubTableArrayOffset(int32_t offset);
// Gets the subtable array size as set in the original table as read from
// the font file. This value cannot be explicitly set and will be generated
// during table building.
// @return the subtable array size
int32_t IndexTableSize();
// Sets the subtable size. This is used only during the building process
// when the objects are being serialized.
// @param size the offset to the index subtable array
void SetIndexTableSize(int32_t size);
int32_t NumberOfIndexSubTables();
int32_t ColorRef();
// TODO(stuartg): SBitLineMetrics hori();
// TODO(stuartg): SBitLineMetrics vert();
int32_t StartGlyphIndex();
int32_t EndGlyphIndex();
int32_t PpemX();
int32_t PpemY();
int32_t BitDepth();
int32_t FlagsAsInt();
IndexSubTable::Builder* IndexSubTableBuilder(int32_t index);
CALLER_ATTACH BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
int32_t GlyphOffset(int32_t glyph_id);
int32_t GlyphLength(int32_t glyph_id);
int32_t GlyphFormat(int32_t glyph_id);
IndexSubTableBuilderList* IndexSubTableBuilders();
// Note: renamed from iterator(), type is the derived type.
CALLER_ATTACH BitmapGlyphInfoIterator* GetIterator();
void GenerateLocaMap(BitmapGlyphInfoMap* output);
protected:
void Revert();
private:
Builder(WritableFontData* data, ReadableFontData* master_data);
Builder(ReadableFontData* data, ReadableFontData* master_data);
void SetNumberOfIndexSubTables(int32_t count);
IndexSubTable::Builder* SearchIndexSubTables(int32_t glyph_id);
IndexSubTable::Builder* LinearSearchIndexSubTables(int32_t glyph_id);
IndexSubTable::Builder* BinarySearchIndexSubTables(int32_t glyph_id);
IndexSubTableBuilderList* GetIndexSubTableBuilders();
void Initialize(ReadableFontData* data);
CALLER_ATTACH IndexSubTable::Builder* CreateIndexSubTableBuilder(
int32_t index);
IndexSubTableBuilderList index_sub_tables_;
};
virtual ~BitmapSizeTable();
int32_t IndexSubTableArrayOffset();
int32_t IndexTableSize();
int32_t NumberOfIndexSubTables();
int32_t ColorRef();
// TODO(stuartg): SBitLineMetrics hori();
// TODO(stuartg): SBitLineMetrics vert();
int32_t StartGlyphIndex();
int32_t EndGlyphIndex();
int32_t PpemX();
int32_t PpemY();
int32_t BitDepth();
int32_t FlagsAsInt();
// Note: renamed from indexSubTable()
IndexSubTable* GetIndexSubTable(int32_t index);
int32_t GlyphOffset(int32_t glyph_id);
int32_t GlyphLength(int32_t glyph_id);
CALLER_ATTACH BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
int32_t GlyphFormat(int32_t glyph_id);
protected:
BitmapSizeTable(ReadableFontData* data,
ReadableFontData* master_data);
private:
static int32_t NumberOfIndexSubTables(ReadableFontData* data,
int32_t table_offset);
IndexSubTable* SearchIndexSubTables(int32_t glyph_id);
IndexSubTable* LinearSearchIndexSubTables(int32_t glyph_id);
IndexSubTable* BinarySearchIndexSubTables(int32_t glyph_id);
CALLER_ATTACH IndexSubTable* CreateIndexSubTable(int32_t index);
IndexSubTableList* GetIndexSubTableList();
Lock index_subtables_lock_;
IndexSubTableList index_subtables_;
};
typedef Ptr<BitmapSizeTable> BitmapSizeTablePtr;
typedef std::vector<BitmapSizeTablePtr> BitmapSizeTableList;
typedef Ptr<BitmapSizeTable::Builder> BitmapSizeTableBuilderPtr;
typedef std::vector<BitmapSizeTableBuilderPtr> BitmapSizeTableBuilderList;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_SIZE_TABLE_H_

View File

@ -1,109 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/composite_bitmap_glyph.h"
namespace sfntly {
/******************************************************************************
* CompositeBitmapGlyph class
******************************************************************************/
CompositeBitmapGlyph::CompositeBitmapGlyph(ReadableFontData* data,
int32_t format)
: BitmapGlyph(data, format) {
Initialize(format);
}
CompositeBitmapGlyph::~CompositeBitmapGlyph() {
}
int32_t CompositeBitmapGlyph::NumComponents() {
return data_->ReadUShort(num_components_offset_);
}
CompositeBitmapGlyph::Component CompositeBitmapGlyph::GetComponent(
int32_t component_num) const {
int32_t component_offset = component_array_offset_ +
component_num * Offset::kEbdtComponentLength;
return CompositeBitmapGlyph::Component(
data_->ReadUShort(component_offset + Offset::kEbdtComponent_glyphCode),
data_->ReadChar(component_offset + Offset::kEbdtComponent_xOffset),
data_->ReadChar(component_offset + Offset::kEbdtComponent_yOffset));
}
void CompositeBitmapGlyph::Initialize(int32_t format) {
if (format == 8) {
num_components_offset_ = Offset::kGlyphFormat8_numComponents;
component_array_offset_ = Offset::kGlyphFormat8_componentArray;
} else if (format == 9) {
num_components_offset_ = Offset::kGlyphFormat9_numComponents;
component_array_offset_ = Offset::kGlyphFormat9_componentArray;
} else {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IllegalStateException("Attempt to create a Composite Bitmap Glyph "
"with a non-composite format.");
#endif
}
}
/******************************************************************************
* CompositeBitmapGlyph::Component class
******************************************************************************/
CompositeBitmapGlyph::Component::Component(const Component& rhs)
: glyph_code_(rhs.glyph_code_),
x_offset_(rhs.x_offset_),
y_offset_(rhs.y_offset_) {
}
bool CompositeBitmapGlyph::Component::operator==(
const CompositeBitmapGlyph::Component& rhs) {
return glyph_code_ == rhs.glyph_code_;
}
CompositeBitmapGlyph::Component& CompositeBitmapGlyph::Component::operator=(
const CompositeBitmapGlyph::Component& rhs) {
glyph_code_ = rhs.glyph_code_;
x_offset_ = rhs.x_offset_;
y_offset_ = rhs.y_offset_;
return *this;
}
CompositeBitmapGlyph::Component::Component(int32_t glyph_code,
int32_t x_offset,
int32_t y_offset)
: glyph_code_(glyph_code), x_offset_(x_offset), y_offset_(y_offset) {
}
/******************************************************************************
* CompositeBitmapGlyph::Builder class
******************************************************************************/
CompositeBitmapGlyph::Builder::Builder(ReadableFontData* data, int32_t format)
: BitmapGlyph::Builder(data, format) {
}
CompositeBitmapGlyph::Builder::Builder(WritableFontData* data, int32_t format)
: BitmapGlyph::Builder(data, format) {
}
CompositeBitmapGlyph::Builder::~Builder() {
}
CALLER_ATTACH FontDataTable*
CompositeBitmapGlyph::Builder::SubBuildTable(ReadableFontData* data) {
Ptr<CompositeBitmapGlyph> glyph = new CompositeBitmapGlyph(data, format());
return glyph.Detach();
}
} // namespace sfntly

View File

@ -1,75 +0,0 @@
/*
* 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_TABLE_BITMAP_COMPOSITE_BITMAP_GLYPH_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_COMPOSITE_BITMAP_GLYPH_H_
#include "sfntly/table/bitmap/bitmap_glyph.h"
namespace sfntly {
class CompositeBitmapGlyph : public BitmapGlyph,
public RefCounted<CompositeBitmapGlyph> {
public:
class Component {
public:
Component(const Component& rhs);
int32_t glyph_code() { return glyph_code_; }
int32_t x_offset() { return x_offset_; }
int32_t y_offset() { return y_offset_; }
// UNIMPLEMENTED: int hashCode()
bool operator==(const Component& rhs);
Component& operator=(const Component& rhs);
protected:
Component(int32_t glyph_code, int32_t x_offset, int32_t y_offset);
private:
int32_t glyph_code_;
int32_t x_offset_;
int32_t y_offset_;
friend class CompositeBitmapGlyph;
};
class Builder : public BitmapGlyph::Builder,
public RefCounted<Builder> {
public:
Builder(WritableFontData* data, int32_t format);
Builder(ReadableFontData* data, int32_t format);
virtual ~Builder();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
};
CompositeBitmapGlyph(ReadableFontData* data, int32_t format);
virtual ~CompositeBitmapGlyph();
int32_t NumComponents();
// Note: returned immutable object over stack.
Component GetComponent(int32_t component_num) const;
private:
void Initialize(int32_t format);
int32_t num_components_offset_;
int32_t component_array_offset_;
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_COMPOSITE_BITMAP_GLYPH_H_

View File

@ -1,236 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/ebdt_table.h"
#include <stdlib.h>
#include "sfntly/table/bitmap/composite_bitmap_glyph.h"
#include "sfntly/table/bitmap/simple_bitmap_glyph.h"
namespace sfntly {
/******************************************************************************
* EbdtTable class
******************************************************************************/
EbdtTable::~EbdtTable() {
}
int32_t EbdtTable::Version() {
return data_->ReadFixed(Offset::kVersion);
}
CALLER_ATTACH
BitmapGlyph* EbdtTable::Glyph(int32_t offset, int32_t length, int32_t format) {
ReadableFontDataPtr glyph_data;
glyph_data.Attach(down_cast<ReadableFontData*>(data_->Slice(offset, length)));
return BitmapGlyph::CreateGlyph(glyph_data, format);
}
EbdtTable::EbdtTable(Header* header, ReadableFontData* data)
: SubTableContainerTable(header, data) {
}
/******************************************************************************
* EbdtTable::Builder class
******************************************************************************/
EbdtTable::Builder::Builder(Header* header, WritableFontData* data)
: SubTableContainerTable::Builder(header, data) {
}
EbdtTable::Builder::Builder(Header* header, ReadableFontData* data)
: SubTableContainerTable::Builder(header, data) {
}
EbdtTable::Builder::~Builder() {
}
CALLER_ATTACH FontDataTable*
EbdtTable::Builder::SubBuildTable(ReadableFontData* data) {
FontDataTablePtr table = new EbdtTable(header(), data);
return table.Detach();
}
void EbdtTable::Builder::SubDataSet() {
Revert();
}
int32_t EbdtTable::Builder::SubDataSizeToSerialize() {
if (glyph_builders_.empty()) {
return 0;
}
bool fixed = true;
int32_t size = Offset::kHeaderLength;
for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
builder_end = glyph_builders_.end();
builder_map != builder_end;
builder_map++) {
for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
glyph_entry_end = builder_map->end();
glyph_entry != glyph_entry_end;
glyph_entry++) {
int32_t glyph_size = glyph_entry->second->SubDataSizeToSerialize();
size += abs(glyph_size);
fixed = (glyph_size <= 0) ? false : fixed;
}
}
return (fixed ? 1 : -1) * size;
}
bool EbdtTable::Builder::SubReadyToSerialize() {
if (glyph_builders_.empty()) {
return false;
}
return true;
}
int32_t EbdtTable::Builder::SubSerialize(WritableFontData* new_data) {
int32_t size = 0;
size += new_data->WriteFixed(Offset::kVersion, kVersion);
for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
builder_end = glyph_builders_.end();
builder_map != builder_end;
builder_map++) {
for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
glyph_entry_end = builder_map->end();
glyph_entry != glyph_entry_end;
glyph_entry++) {
WritableFontDataPtr slice;
slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
size += glyph_entry->second->SubSerialize(slice);
}
}
return size;
}
void EbdtTable::Builder::SetLoca(BitmapLocaList* loca_list) {
assert(loca_list);
Revert();
glyph_loca_.resize(loca_list->size());
std::copy(loca_list->begin(), loca_list->end(), glyph_loca_.begin());
}
void EbdtTable::Builder::GenerateLocaList(BitmapLocaList* output) {
assert(output);
output->clear();
if (glyph_builders_.empty()) {
if (glyph_loca_.empty()) {
return;
}
}
int start_offset = Offset::kHeaderLength;
for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
builder_end = glyph_builders_.end();
builder_map != builder_end;
builder_map++) {
BitmapGlyphInfoMap new_loca_map;
int32_t glyph_offset = 0;
for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
glyph_end = builder_map->end();
glyph_entry != glyph_end;
glyph_entry++) {
BitmapGlyphBuilderPtr builder = glyph_entry->second;
int32_t size = builder->SubDataSizeToSerialize();
BitmapGlyphInfoPtr info = new BitmapGlyphInfo(glyph_entry->first,
start_offset + glyph_offset, size, builder->format());
new_loca_map[glyph_entry->first] = info;
glyph_offset += size;
}
start_offset += glyph_offset;
output->push_back(new_loca_map);
}
}
BitmapGlyphBuilderList* EbdtTable::Builder::GlyphBuilders() {
return GetGlyphBuilders();
}
void EbdtTable::Builder::SetGlyphBuilders(
BitmapGlyphBuilderList* glyph_builders) {
glyph_builders_.clear();
std::copy(glyph_builders->begin(), glyph_builders->end(),
glyph_builders_.begin());
set_model_changed();
}
void EbdtTable::Builder::Revert() {
glyph_loca_.clear();
glyph_builders_.clear();
set_model_changed(false);
}
CALLER_ATTACH
EbdtTable::Builder* EbdtTable::Builder::CreateBuilder(Header* header,
WritableFontData* data) {
Ptr<EbdtTable::Builder> builder;
builder = new Builder(header, data);
return builder.Detach();
}
CALLER_ATTACH
EbdtTable::Builder* EbdtTable::Builder::CreateBuilder(Header* header,
ReadableFontData* data) {
Ptr<EbdtTable::Builder> builder;
builder = new Builder(header, data);
return builder.Detach();
}
BitmapGlyphBuilderList* EbdtTable::Builder::GetGlyphBuilders() {
if (glyph_builders_.empty()) {
if (glyph_loca_.empty()) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IllegalStateException(
"Loca values not set - unable to parse glyph data.");
#endif
return NULL;
}
Initialize(InternalReadData(), &glyph_loca_, &glyph_builders_);
set_model_changed();
}
return &glyph_builders_;
}
void EbdtTable::Builder::Initialize(ReadableFontData* data,
BitmapLocaList* loca_list,
BitmapGlyphBuilderList* output) {
assert(loca_list);
assert(output);
output->clear();
if (data) {
for (BitmapLocaList::iterator loca_map = loca_list->begin(),
loca_end = loca_list->end();
loca_map != loca_end; loca_map++) {
BitmapGlyphBuilderMap glyph_builder_map;
for (BitmapGlyphInfoMap::iterator entry = loca_map->begin(),
entry_end = loca_map->end();
entry != entry_end; entry++) {
BitmapGlyphInfoPtr info = entry->second;
ReadableFontDataPtr slice;
slice.Attach(down_cast<ReadableFontData*>(data->Slice(
info->offset(), info->length())));
BitmapGlyphBuilderPtr glyph_builder;
glyph_builder.Attach(BitmapGlyph::Builder::CreateGlyphBuilder(
slice, info->format()));
glyph_builder_map[entry->first] = glyph_builder;
}
output->push_back(glyph_builder_map);
}
}
}
} // namespace sfntly

View File

@ -1,108 +0,0 @@
/*
* 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_TABLE_BITMAP_EBDT_TABLE_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBDT_TABLE_H_
#include "sfntly/table/bitmap/bitmap_glyph.h"
#include "sfntly/table/bitmap/bitmap_glyph_info.h"
#include "sfntly/table/subtable_container_table.h"
namespace sfntly {
class EbdtTable : public SubTableContainerTable,
public RefCounted<EbdtTable> {
public:
struct Offset {
enum {
kVersion = 0,
kHeaderLength = DataSize::kFixed,
};
};
class Builder : public SubTableContainerTable::Builder,
public RefCounted<Builder> {
public:
// Constructor scope altered to public because C++ does not allow base
// class to instantiate derived class with protected constructors.
Builder(Header* header, WritableFontData* data);
Builder(Header* header, ReadableFontData* data);
virtual ~Builder();
virtual int32_t SubSerialize(WritableFontData* new_data);
virtual bool SubReadyToSerialize();
virtual int32_t SubDataSizeToSerialize();
virtual void SubDataSet();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
void SetLoca(BitmapLocaList* loca_list);
void GenerateLocaList(BitmapLocaList* output);
// Gets the List of glyph builders for the glyph table builder. These may be
// manipulated in any way by the caller and the changes will be reflected in
// the final glyph table produced.
// If there is no current data for the glyph builder or the glyph builders
// have not been previously set then this will return an empty glyph builder
// List. If there is current data (i.e. data read from an existing font) and
// the loca list has not been set or is null, empty, or invalid, then an
// empty glyph builder List will be returned.
// @return the list of glyph builders
BitmapGlyphBuilderList* GlyphBuilders();
// Replace the internal glyph builders with the one provided. The provided
// list and all contained objects belong to this builder.
// This call is only required if the entire set of glyphs in the glyph
// table builder are being replaced. If the glyph builder list provided from
// the {@link EbdtTable.Builder#glyphBuilders()} is being used and modified
// then those changes will already be reflected in the glyph table builder.
// @param glyphBuilders the new glyph builders
void SetGlyphBuilders(BitmapGlyphBuilderList* glyph_builders);
void Revert();
// Create a new builder using the header information and data provided.
// @param header the header information
// @param data the data holding the table
static CALLER_ATTACH Builder* CreateBuilder(Header* header,
WritableFontData* data);
static CALLER_ATTACH Builder* CreateBuilder(Header* header,
ReadableFontData* data);
private:
BitmapGlyphBuilderList* GetGlyphBuilders();
static void Initialize(ReadableFontData* data,
BitmapLocaList* loca_list,
BitmapGlyphBuilderList* output);
static const int32_t kVersion = 0x00020000; // TODO(stuartg): const/enum
BitmapLocaList glyph_loca_;
BitmapGlyphBuilderList glyph_builders_;
};
virtual ~EbdtTable();
int32_t Version();
CALLER_ATTACH BitmapGlyph* Glyph(int32_t offset,
int32_t length,
int32_t format);
protected:
EbdtTable(Header* header, ReadableFontData* data);
};
typedef Ptr<EbdtTable> EbdtTablePtr;
typedef Ptr<EbdtTable::Builder> EbdtTableBuilderPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBDT_TABLE_H_

View File

@ -1,313 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/eblc_table.h"
#include <stdio.h>
#include <stdlib.h>
#include "sfntly/math/font_math.h"
namespace sfntly {
/******************************************************************************
* EblcTable class
******************************************************************************/
int32_t EblcTable::Version() {
return data_->ReadFixed(Offset::kVersion);
}
int32_t EblcTable::NumSizes() {
return data_->ReadULongAsInt(Offset::kNumSizes);
}
BitmapSizeTable* EblcTable::GetBitmapSizeTable(int32_t index) {
if (index < 0 || index > NumSizes()) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundException(
"Size table index is outside the range of tables.");
#endif
return NULL;
}
BitmapSizeTableList* bitmap_size_table_list = GetBitmapSizeTableList();
if (bitmap_size_table_list) {
return (*bitmap_size_table_list)[index];
}
return NULL;
}
EblcTable::EblcTable(Header* header, ReadableFontData* data)
: SubTableContainerTable(header, data) {
}
BitmapSizeTableList* EblcTable::GetBitmapSizeTableList() {
AutoLock lock(bitmap_size_table_lock_);
if (bitmap_size_table_.empty()) {
CreateBitmapSizeTable(data_, NumSizes(), &bitmap_size_table_);
}
return &bitmap_size_table_;
}
// static
void EblcTable::CreateBitmapSizeTable(ReadableFontData* data,
int32_t num_sizes,
BitmapSizeTableList* output) {
assert(data);
assert(output);
for (int32_t i = 0; i < num_sizes; ++i) {
ReadableFontDataPtr new_data;
new_data.Attach(down_cast<ReadableFontData*>(
data->Slice(Offset::kBitmapSizeTableArrayStart +
i * Offset::kBitmapSizeTableLength,
Offset::kBitmapSizeTableLength)));
BitmapSizeTableBuilderPtr size_builder;
size_builder.Attach(
BitmapSizeTable::Builder::CreateBuilder(new_data, data));
BitmapSizeTablePtr size;
size.Attach(down_cast<BitmapSizeTable*>(size_builder->Build()));
output->push_back(size);
}
}
/******************************************************************************
* EblcTable::Builder class
******************************************************************************/
EblcTable::Builder::Builder(Header* header, WritableFontData* data)
: SubTableContainerTable::Builder(header, data) {
}
EblcTable::Builder::Builder(Header* header, ReadableFontData* data)
: SubTableContainerTable::Builder(header, data) {
}
EblcTable::Builder::~Builder() {
}
int32_t EblcTable::Builder::SubSerialize(WritableFontData* new_data) {
// header
int32_t size = new_data->WriteFixed(0, kVersion);
size += new_data->WriteULong(size, size_table_builders_.size());
// calculate the offsets
// offset to the start of the size table array
int32_t size_table_start_offset = size;
// walking offset in the size table array
int32_t size_table_offset = size_table_start_offset;
// offset to the start of the whole index subtable block
int32_t sub_table_block_start_offset = size_table_offset +
size_table_builders_.size() * Offset::kBitmapSizeTableLength;
// walking offset in the index subtable
// points to the start of the current subtable block
int32_t current_sub_table_block_start_offset = sub_table_block_start_offset;
#if defined (SFNTLY_DEBUG_BITMAP)
int32_t size_index = 0;
#endif
for (BitmapSizeTableBuilderList::iterator
size_builder = size_table_builders_.begin(),
size_builder_end = size_table_builders_.end();
size_builder != size_builder_end; size_builder++) {
(*size_builder)->SetIndexSubTableArrayOffset(
current_sub_table_block_start_offset);
IndexSubTableBuilderList* index_sub_table_builder_list =
(*size_builder)->IndexSubTableBuilders();
// walking offset within the current subTable array
int32_t index_sub_table_array_offset = current_sub_table_block_start_offset;
// walking offset within the subTable entries
int32_t index_sub_table_offset = index_sub_table_array_offset +
index_sub_table_builder_list->size() * Offset::kIndexSubHeaderLength;
#if defined (SFNTLY_DEBUG_BITMAP)
fprintf(stderr, "size %d: sizeTable=%x, current subTable Block=%x, ",
size_index, size_table_offset,
current_sub_table_block_start_offset);
fprintf(stderr, "index subTableStart=%x\n", index_sub_table_offset);
size_index++;
int32_t sub_table_index = 0;
#endif
for (IndexSubTableBuilderList::iterator
index_sub_table_builder = index_sub_table_builder_list->begin(),
index_sub_table_builder_end = index_sub_table_builder_list->end();
index_sub_table_builder != index_sub_table_builder_end;
index_sub_table_builder++) {
#if defined (SFNTLY_DEBUG_BITMAP)
fprintf(stderr, "\tsubTableIndex %d: format=%x, ", sub_table_index,
(*index_sub_table_builder)->index_format());
fprintf(stderr, "indexSubTableArrayOffset=%x, indexSubTableOffset=%x\n",
index_sub_table_array_offset, index_sub_table_offset);
sub_table_index++;
#endif
// array entry
index_sub_table_array_offset += new_data->WriteUShort(
index_sub_table_array_offset,
(*index_sub_table_builder)->first_glyph_index());
index_sub_table_array_offset += new_data->WriteUShort(
index_sub_table_array_offset,
(*index_sub_table_builder)->last_glyph_index());
index_sub_table_array_offset += new_data->WriteULong(
index_sub_table_array_offset,
index_sub_table_offset - current_sub_table_block_start_offset);
// index sub table
WritableFontDataPtr slice_index_sub_table;
slice_index_sub_table.Attach(down_cast<WritableFontData*>(
new_data->Slice(index_sub_table_offset)));
int32_t current_sub_table_size =
(*index_sub_table_builder)->SubSerialize(slice_index_sub_table);
int32_t padding = FontMath::PaddingRequired(current_sub_table_size,
DataSize::kULONG);
#if defined (SFNTLY_DEBUG_BITMAP)
fprintf(stderr, "\t\tsubTableSize = %x, padding = %x\n",
current_sub_table_size, padding);
#endif
index_sub_table_offset += current_sub_table_size;
index_sub_table_offset +=
new_data->WritePadding(index_sub_table_offset, padding);
}
// serialize size table
(*size_builder)->SetIndexTableSize(
index_sub_table_offset - current_sub_table_block_start_offset);
WritableFontDataPtr slice_size_table;
slice_size_table.Attach(down_cast<WritableFontData*>(
new_data->Slice(size_table_offset)));
size_table_offset += (*size_builder)->SubSerialize(slice_size_table);
current_sub_table_block_start_offset = index_sub_table_offset;
}
return size + current_sub_table_block_start_offset;
}
bool EblcTable::Builder::SubReadyToSerialize() {
if (size_table_builders_.empty()) {
return false;
}
for (BitmapSizeTableBuilderList::iterator b = size_table_builders_.begin(),
e = size_table_builders_.end();
b != e; b++) {
if (!(*b)->SubReadyToSerialize()) {
return false;
}
}
return true;
}
int32_t EblcTable::Builder::SubDataSizeToSerialize() {
if (size_table_builders_.empty()) {
return 0;
}
int32_t size = Offset::kHeaderLength;
bool variable = false;
#if defined (SFNTLY_DEBUG_BITMAP)
size_t size_index = 0;
#endif
for (BitmapSizeTableBuilderList::iterator b = size_table_builders_.begin(),
e = size_table_builders_.end();
b != e; b++) {
int32_t size_builder_size = (*b)->SubDataSizeToSerialize();
#if defined (SFNTLY_DEBUG_BITMAP)
fprintf(stderr, "sizeIndex = %d, sizeBuilderSize=0x%x (%d)\n",
size_index++, size_builder_size, size_builder_size);
#endif
variable = size_builder_size > 0 ? variable : true;
size += abs(size_builder_size);
}
#if defined (SFNTLY_DEBUG_BITMAP)
fprintf(stderr, "eblc size=%d\n", size);
#endif
return variable ? -size : size;
}
void EblcTable::Builder::SubDataSet() {
Revert();
}
BitmapSizeTableBuilderList* EblcTable::Builder::BitmapSizeBuilders() {
return GetSizeList();
}
void EblcTable::Builder::Revert() {
size_table_builders_.clear();
set_model_changed(false);
}
void EblcTable::Builder::GenerateLocaList(BitmapLocaList* output) {
assert(output);
BitmapSizeTableBuilderList* size_builder_list = GetSizeList();
output->clear();
#if defined (SFNTLY_DEBUG_BITMAP)
int32_t size_index = 0;
#endif
for (BitmapSizeTableBuilderList::iterator b = size_builder_list->begin(),
e = size_builder_list->end();
b != e; b++) {
#if defined (SFNTLY_DEBUG_BITMAP)
fprintf(stderr, "size table = %d\n", size_index++);
#endif
BitmapGlyphInfoMap loca_map;
(*b)->GenerateLocaMap(&loca_map);
output->push_back(loca_map);
}
}
CALLER_ATTACH
FontDataTable* EblcTable::Builder::SubBuildTable(ReadableFontData* data) {
Ptr<EblcTable> new_table = new EblcTable(header(), data);
return new_table.Detach();
}
// static
CALLER_ATTACH EblcTable::Builder*
EblcTable::Builder::CreateBuilder(Header* header, WritableFontData* data) {
Ptr<EblcTable::Builder> new_builder = new EblcTable::Builder(header, data);
return new_builder.Detach();
}
// static
CALLER_ATTACH EblcTable::Builder*
EblcTable::Builder::CreateBuilder(Header* header, ReadableFontData* data) {
Ptr<EblcTable::Builder> new_builder = new EblcTable::Builder(header, data);
return new_builder.Detach();
}
BitmapSizeTableBuilderList* EblcTable::Builder::GetSizeList() {
if (size_table_builders_.empty()) {
Initialize(InternalReadData(), &size_table_builders_);
set_model_changed();
}
return &size_table_builders_;
}
void EblcTable::Builder::Initialize(ReadableFontData* data,
BitmapSizeTableBuilderList* output) {
assert(output);
if (data) {
int32_t num_sizes = data->ReadULongAsInt(Offset::kNumSizes);
for (int32_t i = 0; i < num_sizes; ++i) {
ReadableFontDataPtr new_data;
new_data.Attach(down_cast<ReadableFontData*>(
data->Slice(Offset::kBitmapSizeTableArrayStart +
i * Offset::kBitmapSizeTableLength,
Offset::kBitmapSizeTableLength)));
BitmapSizeTableBuilderPtr size_builder;
size_builder.Attach(BitmapSizeTable::Builder::CreateBuilder(
new_data, data));
output->push_back(size_builder);
}
}
}
} // namespace sfntly

View File

@ -1,194 +0,0 @@
/*
* 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_TABLE_BITMAP_EBLC_TABLE_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBLC_TABLE_H_
#include "sfntly/port/lock.h"
#include "sfntly/table/bitmap/big_glyph_metrics.h"
#include "sfntly/table/bitmap/bitmap_glyph.h"
#include "sfntly/table/bitmap/bitmap_size_table.h"
#include "sfntly/table/subtable_container_table.h"
namespace sfntly {
class EblcTable : public SubTableContainerTable,
public RefCounted<EblcTable> {
public:
struct Offset {
enum {
// header
kVersion = 0,
kNumSizes = 4,
kHeaderLength = kNumSizes + DataSize::kULONG,
// bitmapSizeTable
kBitmapSizeTableArrayStart = kHeaderLength,
kBitmapSizeTableLength = 48,
kBitmapSizeTable_indexSubTableArrayOffset = 0,
kBitmapSizeTable_indexTableSize = 4,
kBitmapSizeTable_numberOfIndexSubTables = 8,
kBitmapSizeTable_colorRef = 12,
kBitmapSizeTable_hori = 16,
kBitmapSizeTable_vert = 28,
kBitmapSizeTable_startGlyphIndex = 40,
kBitmapSizeTable_endGlyphIndex = 42,
kBitmapSizeTable_ppemX = 44,
kBitmapSizeTable_ppemY = 45,
kBitmapSizeTable_bitDepth = 46,
kBitmapSizeTable_flags = 47,
// sbitLineMetrics
kSbitLineMetricsLength = 12,
kSbitLineMetrics_ascender = 0,
kSbitLineMetrics_descender = 1,
kSbitLineMetrics_widthMax = 2,
kSbitLineMetrics_caretSlopeNumerator = 3,
kSbitLineMetrics_caretSlopeDenominator = 4,
kSbitLineMetrics_caretOffset = 5,
kSbitLineMetrics_minOriginSB = 6,
kSbitLineMetrics_minAdvanceSB = 7,
kSbitLineMetrics_maxBeforeBL = 8,
kSbitLineMetrics_minAfterBL = 9,
kSbitLineMetrics_pad1 = 10,
kSbitLineMetrics_pad2 = 11,
// indexSubTable
kIndexSubTableEntryLength = 8,
kIndexSubTableEntry_firstGlyphIndex = 0,
kIndexSubTableEntry_lastGlyphIndex = 2,
kIndexSubTableEntry_additionalOffsetToIndexSubTable = 4,
// indexSubHeader
kIndexSubHeaderLength = 8,
kIndexSubHeader_indexFormat = 0,
kIndexSubHeader_imageFormat = 2,
kIndexSubHeader_imageDataOffset = 4,
// indexSubTable - all offset relative to the subtable start
// indexSubTable1
kIndexSubTable1_offsetArray = kIndexSubHeaderLength,
kIndexSubTable1_builderDataSize = kIndexSubHeaderLength,
// kIndexSubTable2
kIndexSubTable2Length = kIndexSubHeaderLength +
DataSize::kULONG +
BitmapGlyph::Offset::kBigGlyphMetricsLength,
kIndexSubTable2_imageSize = kIndexSubHeaderLength,
kIndexSubTable2_bigGlyphMetrics = kIndexSubTable2_imageSize +
DataSize::kULONG,
kIndexSubTable2_builderDataSize = kIndexSubTable2_bigGlyphMetrics +
BigGlyphMetrics::Offset::kMetricsLength,
// kIndexSubTable3
kIndexSubTable3_offsetArray = kIndexSubHeaderLength,
kIndexSubTable3_builderDataSize = kIndexSubTable3_offsetArray,
// kIndexSubTable4
kIndexSubTable4_numGlyphs = kIndexSubHeaderLength,
kIndexSubTable4_glyphArray = kIndexSubTable4_numGlyphs +
DataSize::kULONG,
kIndexSubTable4_codeOffsetPairLength = 2 * DataSize::kUSHORT,
kIndexSubTable4_codeOffsetPair_glyphCode = 0,
kIndexSubTable4_codeOffsetPair_offset = DataSize::kUSHORT,
kIndexSubTable4_builderDataSize = kIndexSubTable4_glyphArray,
// kIndexSubTable5
kIndexSubTable5_imageSize = kIndexSubHeaderLength,
kIndexSubTable5_bigGlyphMetrics = kIndexSubTable5_imageSize +
DataSize::kULONG,
kIndexSubTable5_numGlyphs = kIndexSubTable5_bigGlyphMetrics +
BitmapGlyph::Offset::kBigGlyphMetricsLength,
kIndexSubTable5_glyphArray = kIndexSubTable5_numGlyphs +
DataSize::kULONG,
kIndexSubTable5_builderDataSize = kIndexSubTable5_glyphArray,
// codeOffsetPair
kCodeOffsetPairLength = 2 * DataSize::kUSHORT,
kCodeOffsetPair_glyphCode = 0,
kCodeOffsetPair_offset = DataSize::kUSHORT,
};
};
class Builder : public SubTableContainerTable::Builder,
public RefCounted<Builder> {
public:
// Constructor scope altered to public because C++ does not allow base
// class to instantiate derived class with protected constructors.
Builder(Header* header, WritableFontData* data);
Builder(Header* header, ReadableFontData* data);
virtual ~Builder();
virtual int32_t SubSerialize(WritableFontData* new_data);
virtual bool SubReadyToSerialize();
virtual int32_t SubDataSizeToSerialize();
virtual void SubDataSet();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
BitmapSizeTableBuilderList* BitmapSizeBuilders();
void Revert();
// Generates the loca list for the EBDT table. The list is intended to be
// used by the EBDT to allow it to parse the glyph data and generate glyph
// objects. After returning from this method the list belongs to the caller.
// The list entries are in the same order as the size table builders are at
// the time of this call.
// @return the list of loca maps with one for each size table builder
void GenerateLocaList(BitmapLocaList* output);
// Create a new builder using the header information and data provided.
// @param header the header information
// @param data the data holding the table
static CALLER_ATTACH Builder* CreateBuilder(Header* header,
WritableFontData* data);
static CALLER_ATTACH Builder* CreateBuilder(Header* header,
ReadableFontData* data);
private:
BitmapSizeTableBuilderList* GetSizeList();
void Initialize(ReadableFontData* data, BitmapSizeTableBuilderList* output);
static const int32_t kVersion = 0x00020000;
BitmapSizeTableBuilderList size_table_builders_;
};
int32_t Version();
int32_t NumSizes();
// UNIMPLEMENTED: toString()
BitmapSizeTable* GetBitmapSizeTable(int32_t index);
static const int32_t NOTDEF = -1;
protected:
EblcTable(Header* header, ReadableFontData* data);
private:
BitmapSizeTableList* GetBitmapSizeTableList();
static void CreateBitmapSizeTable(ReadableFontData* data,
int32_t num_sizes,
BitmapSizeTableList* output);
Lock bitmap_size_table_lock_;
BitmapSizeTableList bitmap_size_table_;
};
typedef Ptr<EblcTable> EblcTablePtr;
typedef Ptr<EblcTable::Builder> EblcTableBuilderPtr;
}
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBLC_TABLE_H_

View File

@ -1,107 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/ebsc_table.h"
namespace sfntly {
/******************************************************************************
* EbscTable class
******************************************************************************/
EbscTable::~EbscTable() {
}
int32_t EbscTable::Version() {
return data_->ReadFixed(Offset::kVersion);
}
int32_t EbscTable::NumSizes() {
return data_->ReadULongAsInt(Offset::kNumSizes);
}
EbscTable::EbscTable(Header* header, ReadableFontData* data)
: Table(header, data) {
}
/******************************************************************************
* EbscTable::BitmapScaleTable class
******************************************************************************/
EbscTable::BitmapScaleTable::~BitmapScaleTable() {
}
EbscTable::BitmapScaleTable::BitmapScaleTable(ReadableFontData* data)
: SubTable(data) {
}
int32_t EbscTable::BitmapScaleTable::PpemX() {
return data_->ReadByte(Offset::kBitmapScaleTable_ppemX);
}
int32_t EbscTable::BitmapScaleTable::PpemY() {
return data_->ReadByte(Offset::kBitmapScaleTable_ppemY);
}
int32_t EbscTable::BitmapScaleTable::SubstitutePpemX() {
return data_->ReadByte(Offset::kBitmapScaleTable_substitutePpemX);
}
int32_t EbscTable::BitmapScaleTable::SubstitutePpemY() {
return data_->ReadByte(Offset::kBitmapScaleTable_substitutePpemY);
}
/******************************************************************************
* EbscTable::Builder class
******************************************************************************/
EbscTable::Builder::~Builder() {
}
CALLER_ATTACH EbscTable::Builder* EbscTable::Builder::CreateBuilder(
Header* header, WritableFontData* data) {
EbscTableBuilderPtr builder = new EbscTable::Builder(header, data);
return builder.Detach();
}
EbscTable::Builder::Builder(Header* header, WritableFontData* data)
: Table::Builder(header, data) {
}
EbscTable::Builder::Builder(Header* header, ReadableFontData* data)
: Table::Builder(header, data) {
}
CALLER_ATTACH
FontDataTable* EbscTable::Builder::SubBuildTable(ReadableFontData* data) {
EbscTablePtr output = new EbscTable(header(), data);
return output.Detach();
}
void EbscTable::Builder::SubDataSet() {
// NOP
}
int32_t EbscTable::Builder::SubDataSizeToSerialize() {
return 0;
}
bool EbscTable::Builder::SubReadyToSerialize() {
return false;
}
int32_t EbscTable::Builder::SubSerialize(WritableFontData* new_data) {
UNREFERENCED_PARAMETER(new_data);
return 0;
}
} // namespace sfntly

View File

@ -1,101 +0,0 @@
/*
* 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_TABLE_BITMAP_EBSC_TABLE_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBSC_TABLE_H_
#include "sfntly/table/bitmap/eblc_table.h"
namespace sfntly {
class EbscTable : public Table,
public RefCounted<EbscTable> {
public:
struct Offset {
enum {
// header
kVersion = 0,
kNumSizes = DataSize::kFixed,
kHeaderLength = kNumSizes + DataSize::kULONG,
kBitmapScaleTableStart = kHeaderLength,
// bitmapScaleTable
kBitmapScaleTable_hori = 0,
kBitmapScaleTable_vert = EblcTable::Offset::kSbitLineMetricsLength,
kBitmapScaleTable_ppemX = kBitmapScaleTable_vert +
EblcTable::Offset::kSbitLineMetricsLength,
kBitmapScaleTable_ppemY = kBitmapScaleTable_ppemX + DataSize::kBYTE,
kBitmapScaleTable_substitutePpemX = kBitmapScaleTable_ppemY +
DataSize::kBYTE,
kBitmapScaleTable_substitutePpemY = kBitmapScaleTable_substitutePpemX +
DataSize::kBYTE,
kBitmapScaleTableLength = kBitmapScaleTable_substitutePpemY +
DataSize::kBYTE,
};
};
class BitmapScaleTable : public SubTable,
public RefCounted<BitmapScaleTable> {
public:
virtual ~BitmapScaleTable();
int32_t PpemX();
int32_t PpemY();
int32_t SubstitutePpemX();
int32_t SubstitutePpemY();
protected:
// Note: caller to do data->Slice(offset, Offset::kBitmapScaleTableLength)
explicit BitmapScaleTable(ReadableFontData* data);
};
// TODO(stuartg): currently the builder just builds from initial data
// - need to make fully working but few if any examples to test with
class Builder : public Table::Builder,
public RefCounted<Builder> {
public:
virtual ~Builder();
static CALLER_ATTACH Builder* CreateBuilder(Header* header,
WritableFontData* data);
protected:
Builder(Header* header, WritableFontData* data);
Builder(Header* header, ReadableFontData* data);
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
virtual int32_t SubDataSizeToSerialize();
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
};
virtual ~EbscTable();
int32_t Version();
int32_t NumSizes();
// Note: renamed from bitmapScaleTable
CALLER_ATTACH BitmapScaleTable* GetBitmapScaleTable(int32_t index);
private:
EbscTable(Header* header, ReadableFontData* data);
friend class Builder;
};
typedef Ptr<EbscTable> EbscTablePtr;
typedef Ptr<EbscTable::Builder> EbscTableBuilderPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBSC_TABLE_H_

View File

@ -1,39 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/glyph_metrics.h"
namespace sfntly {
GlyphMetrics::~GlyphMetrics() {
}
GlyphMetrics::GlyphMetrics(ReadableFontData* data)
: SubTable(data) {
}
GlyphMetrics::Builder::~Builder() {
}
GlyphMetrics::Builder::Builder(WritableFontData* data)
: SubTable::Builder(data) {
}
GlyphMetrics::Builder::Builder(ReadableFontData* data)
: SubTable::Builder(data) {
}
} // namespace sfntly

View File

@ -1,43 +0,0 @@
/*
* 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_TABLE_BITMAP_GLYPH_METRICS_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_METRICS_H_
#include "sfntly/table/subtable.h"
namespace sfntly {
class GlyphMetrics : public SubTable {
public:
virtual ~GlyphMetrics();
protected:
class Builder : public SubTable::Builder {
public:
virtual ~Builder();
protected:
explicit Builder(WritableFontData* data);
explicit Builder(ReadableFontData* data);
};
explicit GlyphMetrics(ReadableFontData* data);
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_METRICS_H_

View File

@ -1,278 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/index_sub_table.h"
#include "sfntly/table/bitmap/eblc_table.h"
#include "sfntly/table/bitmap/index_sub_table_format1.h"
#include "sfntly/table/bitmap/index_sub_table_format2.h"
#include "sfntly/table/bitmap/index_sub_table_format3.h"
#include "sfntly/table/bitmap/index_sub_table_format4.h"
#include "sfntly/table/bitmap/index_sub_table_format5.h"
namespace sfntly {
/******************************************************************************
* IndexSubTable class
******************************************************************************/
CALLER_ATTACH BitmapGlyphInfo* IndexSubTable::GlyphInfo(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return NULL;
}
if (GlyphStartOffset(glyph_id) == -1) {
return NULL;
}
BitmapGlyphInfoPtr output = new BitmapGlyphInfo(glyph_id,
image_data_offset(),
GlyphStartOffset(glyph_id),
GlyphLength(glyph_id),
image_format());
return output.Detach();
}
int32_t IndexSubTable::GlyphOffset(int32_t glyph_id) {
int32_t glyph_start_offset = GlyphStartOffset(glyph_id);
if (glyph_start_offset == -1) {
return -1;
}
return image_data_offset() + glyph_start_offset;
}
// static
CALLER_ATTACH IndexSubTable*
IndexSubTable::CreateIndexSubTable(ReadableFontData* data,
int32_t offset_to_index_sub_table_array,
int32_t array_index) {
IndexSubTableBuilderPtr builder;
builder.Attach(IndexSubTable::Builder::CreateBuilder(
data, offset_to_index_sub_table_array, array_index));
return down_cast<IndexSubTable*>(builder->Build());
}
IndexSubTable::IndexSubTable(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: SubTable(data),
first_glyph_index_(first_glyph_index),
last_glyph_index_(last_glyph_index) {
index_format_ =
data_->ReadUShort(EblcTable::Offset::kIndexSubHeader_indexFormat);
image_format_ =
data_->ReadUShort(EblcTable::Offset::kIndexSubHeader_imageFormat);
image_data_offset_ =
data_->ReadULongAsInt(EblcTable::Offset::kIndexSubHeader_imageDataOffset);
}
int32_t IndexSubTable::CheckGlyphRange(int32_t glyph_id) {
return CheckGlyphRange(glyph_id, first_glyph_index(), last_glyph_index());
}
// static
int32_t IndexSubTable::CheckGlyphRange(int32_t glyph_id,
int32_t first_glyph_id,
int32_t last_glyph_id) {
if (glyph_id < first_glyph_id || glyph_id > last_glyph_id) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundException("Glyph ID is outside of the allowed range.");
#endif
return -1;
}
return glyph_id - first_glyph_id;
}
/******************************************************************************
* IndexSubTable::Builder class
******************************************************************************/
IndexSubTable::Builder::~Builder() {
}
void IndexSubTable::Builder::Revert() {
set_model_changed(false);
Initialize(InternalReadData());
}
CALLER_ATTACH BitmapGlyphInfo* IndexSubTable::Builder::GlyphInfo(
int32_t glyph_id) {
BitmapGlyphInfoPtr glyph_info =
new BitmapGlyphInfo(glyph_id,
image_data_offset(),
GlyphStartOffset(glyph_id),
GlyphLength(glyph_id),
image_format());
return glyph_info.Detach();
}
int32_t IndexSubTable::Builder::GlyphOffset(int32_t glyph_id) {
return image_data_offset() + GlyphStartOffset(glyph_id);
}
// static
CALLER_ATTACH IndexSubTable::Builder*
IndexSubTable::Builder::CreateBuilder(int32_t index_format) {
switch (index_format) {
case Format::FORMAT_1:
return IndexSubTableFormat1::Builder::CreateBuilder();
case Format::FORMAT_2:
return IndexSubTableFormat2::Builder::CreateBuilder();
case Format::FORMAT_3:
return IndexSubTableFormat3::Builder::CreateBuilder();
case Format::FORMAT_4:
return IndexSubTableFormat4::Builder::CreateBuilder();
case Format::FORMAT_5:
return IndexSubTableFormat5::Builder::CreateBuilder();
default:
#if !defined (SFNTLY_NO_EXCEPTION)
throw IllegalArgumentException("Invalid index subtable format");
#endif
return NULL;
}
}
// static
CALLER_ATTACH IndexSubTable::Builder*
IndexSubTable::Builder::CreateBuilder(ReadableFontData* data,
int32_t offset_to_index_sub_table_array, int32_t array_index) {
int32_t index_sub_table_entry_offset =
offset_to_index_sub_table_array +
array_index * EblcTable::Offset::kIndexSubTableEntryLength;
int32_t first_glyph_index =
data->ReadUShort(index_sub_table_entry_offset +
EblcTable::Offset::kIndexSubTableEntry_firstGlyphIndex);
int32_t last_glyph_index =
data->ReadUShort(index_sub_table_entry_offset +
EblcTable::Offset::kIndexSubTableEntry_lastGlyphIndex);
int32_t additional_offset_to_index_subtable = data->ReadULongAsInt(
index_sub_table_entry_offset +
EblcTable::Offset::kIndexSubTableEntry_additionalOffsetToIndexSubTable);
int32_t index_sub_table_offset = offset_to_index_sub_table_array +
additional_offset_to_index_subtable;
int32_t index_format = data->ReadUShort(index_sub_table_offset);
switch (index_format) {
case 1:
return IndexSubTableFormat1::Builder::CreateBuilder(
data, index_sub_table_offset, first_glyph_index, last_glyph_index);
case 2:
return IndexSubTableFormat2::Builder::CreateBuilder(
data, index_sub_table_offset, first_glyph_index, last_glyph_index);
case 3:
return IndexSubTableFormat3::Builder::CreateBuilder(
data, index_sub_table_offset, first_glyph_index, last_glyph_index);
case 4:
return IndexSubTableFormat4::Builder::CreateBuilder(
data, index_sub_table_offset, first_glyph_index, last_glyph_index);
case 5:
return IndexSubTableFormat5::Builder::CreateBuilder(
data, index_sub_table_offset, first_glyph_index, last_glyph_index);
default:
// Unknown format and unable to process.
#if !defined (SFNTLY_NO_EXCEPTION)
throw IllegalArgumentException("Invalid Index Subtable Format");
#endif
break;
}
return NULL;
}
CALLER_ATTACH
FontDataTable* IndexSubTable::Builder::SubBuildTable(ReadableFontData* data) {
UNREFERENCED_PARAMETER(data);
return NULL;
}
void IndexSubTable::Builder::SubDataSet() {
// NOP
}
int32_t IndexSubTable::Builder::SubDataSizeToSerialize() {
return 0;
}
bool IndexSubTable::Builder::SubReadyToSerialize() {
return false;
}
int32_t IndexSubTable::Builder::SubSerialize(WritableFontData* new_data) {
UNREFERENCED_PARAMETER(new_data);
return 0;
}
IndexSubTable::Builder::Builder(int32_t data_size, int32_t index_format)
: SubTable::Builder(data_size),
first_glyph_index_(0),
last_glyph_index_(0),
index_format_(index_format),
image_format_(0),
image_data_offset_(0) {
}
IndexSubTable::Builder::Builder(int32_t index_format,
int32_t image_format,
int32_t image_data_offset,
int32_t data_size)
: SubTable::Builder(data_size),
first_glyph_index_(0),
last_glyph_index_(0),
index_format_(index_format),
image_format_(image_format),
image_data_offset_(image_data_offset) {
}
IndexSubTable::Builder::Builder(WritableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: SubTable::Builder(data),
first_glyph_index_(first_glyph_index),
last_glyph_index_(last_glyph_index) {
Initialize(data);
}
IndexSubTable::Builder::Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: SubTable::Builder(data),
first_glyph_index_(first_glyph_index),
last_glyph_index_(last_glyph_index) {
Initialize(data);
}
int32_t IndexSubTable::Builder::CheckGlyphRange(int32_t glyph_id) {
return IndexSubTable::CheckGlyphRange(glyph_id,
first_glyph_index(),
last_glyph_index());
}
int32_t IndexSubTable::Builder::SerializeIndexSubHeader(
WritableFontData* data) {
int32_t size =
data->WriteUShort(EblcTable::Offset::kIndexSubHeader_indexFormat,
index_format());
size += data->WriteUShort(EblcTable::Offset::kIndexSubHeader_imageFormat,
image_format());
size += data->WriteULong(EblcTable::Offset::kIndexSubHeader_imageDataOffset,
image_data_offset());
return size;
}
void IndexSubTable::Builder::Initialize(ReadableFontData* data) {
index_format_ =
data->ReadUShort(EblcTable::Offset::kIndexSubHeader_indexFormat);
image_format_ =
data->ReadUShort(EblcTable::Offset::kIndexSubHeader_imageFormat);
image_data_offset_ =
data->ReadULongAsInt(EblcTable::Offset::kIndexSubHeader_imageDataOffset);
}
} // namespace sfntly

View File

@ -1,178 +0,0 @@
/*
* 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_TABLE_BITMAP_INDEX_SUBTABLE_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_H_
#include <vector>
#include "sfntly/port/java_iterator.h"
#include "sfntly/table/subtable.h"
#include "sfntly/table/bitmap/bitmap_glyph_info.h"
namespace sfntly {
class IndexSubTable : public SubTable {
public:
struct Format {
enum {
FORMAT_1 = 1,
FORMAT_2 = 2,
FORMAT_3 = 3,
FORMAT_4 = 4,
FORMAT_5 = 5,
};
};
class Builder : public SubTable::Builder {
public:
virtual ~Builder();
void Revert();
int32_t index_format() { return index_format_; }
int32_t first_glyph_index() { return first_glyph_index_; }
void set_first_glyph_index(int32_t v) { first_glyph_index_ = v; }
int32_t last_glyph_index() { return last_glyph_index_; }
void set_last_glyph_index(int32_t v) { last_glyph_index_ = v; }
int32_t image_format() { return image_format_; }
void set_image_format(int32_t v) { image_format_ = v; }
int32_t image_data_offset() { return image_data_offset_; }
void set_image_data_offset(int32_t v) { image_data_offset_ = v; }
virtual int32_t NumGlyphs() = 0;
// Gets the glyph info for the specified glyph id.
// @param glyphId the glyph id to look up
// @return the glyph info
CALLER_ATTACH virtual BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
// Gets the full offset of the glyph within the EBDT table.
// @param glyphId the glyph id
// @return the glyph offset
virtual int32_t GlyphOffset(int32_t glyph_id);
// Gets the offset of the glyph relative to the block for this index
// subtable.
// @param glyphId the glyph id
// @return the glyph offset
virtual int32_t GlyphStartOffset(int32_t glyph_id) = 0;
// Gets the length of the glyph within the EBDT table.
// @param glyphId the glyph id
// @return the glyph offset
virtual int32_t GlyphLength(int32_t glyph_id) = 0;
// Note: renamed from java iterator()
CALLER_ATTACH virtual Iterator<BitmapGlyphInfo, IndexSubTable::Builder>*
GetIterator() = 0;
// Static instantiation function.
static CALLER_ATTACH Builder* CreateBuilder(int32_t index_format);
static CALLER_ATTACH Builder*
CreateBuilder(ReadableFontData* data,
int32_t offset_to_index_sub_table_array,
int32_t array_index);
// The following methods will never be called but they need to be here to
// allow the BitmapSizeTable to see these methods through an abstract
// reference.
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
virtual int32_t SubDataSizeToSerialize();
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
protected:
Builder(int32_t data_size, int32_t index_format);
Builder(int32_t index_format,
int32_t image_format,
int32_t image_data_offset,
int32_t data_size);
Builder(WritableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
// Checks that the glyph id is within the correct range. If it returns the
// offset of the glyph id from the start of the range.
// @param glyphId
// @return the offset of the glyphId from the start of the glyph range
// @throws IndexOutOfBoundsException if the glyph id is not within the
// correct range
int32_t CheckGlyphRange(int32_t glyph_id);
int32_t SerializeIndexSubHeader(WritableFontData* data);
private:
void Initialize(ReadableFontData* data);
int32_t first_glyph_index_;
int32_t last_glyph_index_;
int32_t index_format_;
int32_t image_format_;
int32_t image_data_offset_;
};
int32_t index_format() { return index_format_; }
int32_t first_glyph_index() { return first_glyph_index_; }
int32_t last_glyph_index() { return last_glyph_index_; }
int32_t image_format() { return image_format_; }
int32_t image_data_offset() { return image_data_offset_; }
CALLER_ATTACH BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
virtual int32_t GlyphOffset(int32_t glyph_id);
virtual int32_t GlyphStartOffset(int32_t glyph_id) = 0;
virtual int32_t GlyphLength(int32_t glyph_id) = 0;
virtual int32_t NumGlyphs() = 0;
static CALLER_ATTACH IndexSubTable*
CreateIndexSubTable(ReadableFontData* data,
int32_t offset_to_index_sub_table_array,
int32_t array_index);
protected:
// Note: the constructor does not implement offset/length form provided in
// Java to avoid heavy lifting in constructors. Callers to call
// GetDataLength() static method of the derived class to get proper
// length and slice ahead.
IndexSubTable(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
int32_t CheckGlyphRange(int32_t glyph_id);
static int32_t CheckGlyphRange(int32_t glyph_id,
int32_t first_glyph_id,
int32_t last_glyph_id);
private:
int32_t first_glyph_index_;
int32_t last_glyph_index_;
int32_t index_format_;
int32_t image_format_;
int32_t image_data_offset_;
};
typedef Ptr<IndexSubTable> IndexSubTablePtr;
typedef std::vector<IndexSubTablePtr> IndexSubTableList;
typedef Ptr<IndexSubTable::Builder> IndexSubTableBuilderPtr;
typedef std::vector<IndexSubTableBuilderPtr> IndexSubTableBuilderList;
typedef Iterator<BitmapGlyphInfo, IndexSubTable::Builder> BitmapGlyphInfoIter;
typedef Ptr<BitmapGlyphInfoIter> BitmapGlyphInfoIterPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_H_

View File

@ -1,299 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/index_sub_table_format1.h"
#include "sfntly/table/bitmap/eblc_table.h"
namespace sfntly {
/******************************************************************************
* IndexSubTableFormat1 class
******************************************************************************/
// static
int32_t IndexSubTableFormat1::GetDataLength(ReadableFontData* data,
int32_t offset,
int32_t first,
int32_t last) {
UNREFERENCED_PARAMETER(data);
UNREFERENCED_PARAMETER(offset);
return (last - first + 1 + 1) * DataSize::kULONG;
}
IndexSubTableFormat1::~IndexSubTableFormat1() {
}
int32_t IndexSubTableFormat1::NumGlyphs() {
return last_glyph_index() - first_glyph_index() + 1;
}
int32_t IndexSubTableFormat1::GlyphStartOffset(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return -1;
}
return Loca(loca);
}
int32_t IndexSubTableFormat1::GlyphLength(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return -1;
}
return Loca(loca + 1) - Loca(loca);
}
IndexSubTableFormat1::IndexSubTableFormat1(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: IndexSubTable(data, first_glyph_index, last_glyph_index) {
}
int32_t IndexSubTableFormat1::Loca(int32_t loca) {
return image_data_offset() +
data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable1_offsetArray +
loca * DataSize::kULONG);
}
/******************************************************************************
* IndexSubTableFormat1::Builder class
******************************************************************************/
IndexSubTableFormat1::Builder::~Builder() {
}
int32_t IndexSubTableFormat1::Builder::NumGlyphs() {
return GetOffsetArray()->size() - 1;
}
int32_t IndexSubTableFormat1::Builder::GlyphLength(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return 0;
}
IntegerList* offset_array = GetOffsetArray();
return offset_array->at(loca + 1) - offset_array->at(loca);
}
int32_t IndexSubTableFormat1::Builder::GlyphStartOffset(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return -1;
}
return GetOffsetArray()->at(loca);
}
CALLER_ATTACH IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator*
IndexSubTableFormat1::Builder::GetIterator() {
Ptr<IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator> it =
new IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator(this);
return it.Detach();
}
// static
CALLER_ATTACH IndexSubTableFormat1::Builder*
IndexSubTableFormat1::Builder::CreateBuilder() {
IndexSubTableFormat1BuilderPtr output = new IndexSubTableFormat1::Builder();
return output.Detach();
}
// static
CALLER_ATTACH IndexSubTableFormat1::Builder*
IndexSubTableFormat1::Builder::CreateBuilder(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
int32_t length = Builder::DataLength(data,
index_sub_table_offset,
first_glyph_index,
last_glyph_index);
ReadableFontDataPtr new_data;
new_data.Attach(down_cast<ReadableFontData*>(
data->Slice(index_sub_table_offset, length)));
IndexSubTableFormat1BuilderPtr output =
new IndexSubTableFormat1::Builder(new_data,
first_glyph_index,
last_glyph_index);
return output.Detach();
}
// static
CALLER_ATTACH IndexSubTableFormat1::Builder*
IndexSubTableFormat1::Builder::CreateBuilder(WritableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
int32_t length = Builder::DataLength(data,
index_sub_table_offset,
first_glyph_index,
last_glyph_index);
WritableFontDataPtr new_data;
new_data.Attach(down_cast<WritableFontData*>(
data->Slice(index_sub_table_offset, length)));
IndexSubTableFormat1BuilderPtr output =
new IndexSubTableFormat1::Builder(new_data,
first_glyph_index,
last_glyph_index);
return output.Detach();
}
CALLER_ATTACH FontDataTable* IndexSubTableFormat1::Builder::SubBuildTable(
ReadableFontData* data) {
IndexSubTableFormat1Ptr output = new IndexSubTableFormat1(
data, first_glyph_index(), last_glyph_index());
return output.Detach();
}
void IndexSubTableFormat1::Builder::SubDataSet() {
Revert();
}
int32_t IndexSubTableFormat1::Builder::SubDataSizeToSerialize() {
if (offset_array_.empty()) {
return InternalReadData()->Length();
}
return EblcTable::Offset::kIndexSubHeaderLength +
offset_array_.size() * DataSize::kULONG;
}
bool IndexSubTableFormat1::Builder::SubReadyToSerialize() {
if (!offset_array_.empty()) {
return true;
}
return false;
}
int32_t IndexSubTableFormat1::Builder::SubSerialize(
WritableFontData* new_data) {
int32_t size = SerializeIndexSubHeader(new_data);
if (!model_changed()) {
if (InternalReadData() == NULL) {
return size;
}
ReadableFontDataPtr source;
WritableFontDataPtr target;
source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
EblcTable::Offset::kIndexSubTable1_offsetArray)));
target.Attach(down_cast<WritableFontData*>(new_data->Slice(
EblcTable::Offset::kIndexSubTable1_offsetArray)));
size += source->CopyTo(target);
} else {
for (IntegerList::iterator b = GetOffsetArray()->begin(),
e = GetOffsetArray()->end(); b != e; b++) {
size += new_data->WriteLong(size, *b);
}
}
return size;
}
IntegerList* IndexSubTableFormat1::Builder::OffsetArray() {
return GetOffsetArray();
}
void IndexSubTableFormat1::Builder::SetOffsetArray(
const IntegerList& offset_array) {
offset_array_.clear();
offset_array_ = offset_array;
set_model_changed();
}
void IndexSubTableFormat1::Builder::Revert() {
offset_array_.clear();
IndexSubTable::Builder::Revert();
}
IndexSubTableFormat1::Builder::Builder()
: IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable1_builderDataSize,
IndexSubTable::Format::FORMAT_1) {
}
IndexSubTableFormat1::Builder::Builder(WritableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
}
IndexSubTableFormat1::Builder::Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
}
IntegerList* IndexSubTableFormat1::Builder::GetOffsetArray() {
if (offset_array_.empty()) {
Initialize(InternalReadData());
set_model_changed();
}
return &offset_array_;
}
void IndexSubTableFormat1::Builder::Initialize(ReadableFontData* data) {
offset_array_.clear();
if (data) {
int32_t num_offsets = (last_glyph_index() - first_glyph_index() + 1) + 1;
for (int32_t i = 0; i < num_offsets; ++i) {
offset_array_.push_back(data->ReadULongAsInt(
EblcTable::Offset::kIndexSubTable1_offsetArray +
i * DataSize::kULONG));
}
}
}
// static
int32_t IndexSubTableFormat1::Builder::DataLength(
ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
UNREFERENCED_PARAMETER(data);
UNREFERENCED_PARAMETER(index_sub_table_offset);
return EblcTable::Offset::kIndexSubHeaderLength +
(last_glyph_index - first_glyph_index + 1 + 1) * DataSize::kULONG;
}
/******************************************************************************
* IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator class
******************************************************************************/
IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
IndexSubTableFormat1::Builder* container)
: RefIterator<BitmapGlyphInfo, IndexSubTableFormat1::Builder,
IndexSubTable::Builder>(container) {
glyph_id_ = container->first_glyph_index();
}
bool IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator::HasNext() {
if (glyph_id_ <= container()->last_glyph_index()) {
return true;
}
return false;
}
CALLER_ATTACH BitmapGlyphInfo*
IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator::Next() {
BitmapGlyphInfoPtr output;
if (!HasNext()) {
// Note: In C++, we do not throw exception when there's no element.
return NULL;
}
output = new BitmapGlyphInfo(glyph_id_,
container()->image_data_offset(),
container()->GlyphStartOffset(glyph_id_),
container()->GlyphLength(glyph_id_),
container()->image_format());
glyph_id_++;
return output.Detach();
}
} // namespace sfntly

View File

@ -1,116 +0,0 @@
/*
* 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_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT1_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT1_H_
#include "sfntly/port/java_iterator.h"
#include "sfntly/table/bitmap/index_sub_table.h"
namespace sfntly {
// Format 1 Index Subtable Entry.
class IndexSubTableFormat1 : public IndexSubTable,
public RefCounted<IndexSubTableFormat1> {
public:
class Builder : public IndexSubTable::Builder,
public RefCounted<Builder> {
public:
class BitmapGlyphInfoIterator
: public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
public:
explicit BitmapGlyphInfoIterator(Builder* container);
virtual ~BitmapGlyphInfoIterator() {}
virtual bool HasNext();
CALLER_ATTACH virtual BitmapGlyphInfo* Next();
private:
int32_t glyph_id_;
};
virtual ~Builder();
virtual int32_t NumGlyphs();
virtual int32_t GlyphLength(int32_t glyph_id);
virtual int32_t GlyphStartOffset(int32_t glyph_id);
CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
virtual int32_t SubDataSizeToSerialize();
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
IntegerList* OffsetArray();
void SetOffsetArray(const IntegerList& offset_array);
CALLER_ATTACH BitmapGlyphInfoIter* Iterator();
static CALLER_ATTACH Builder* CreateBuilder();
static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
protected:
void Revert();
private:
Builder();
Builder(WritableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
IntegerList* GetOffsetArray();
void Initialize(ReadableFontData* data);
static int32_t DataLength(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
IntegerList offset_array_;
};
virtual ~IndexSubTableFormat1();
virtual int32_t NumGlyphs();
virtual int32_t GlyphStartOffset(int32_t glyph_id);
virtual int32_t GlyphLength(int32_t glyph_id);
static int32_t GetDataLength(ReadableFontData* data,
int32_t offset,
int32_t first,
int32_t last);
private:
IndexSubTableFormat1(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
int32_t Loca(int32_t loca_index);
friend class Builder;
};
typedef Ptr<IndexSubTableFormat1> IndexSubTableFormat1Ptr;
typedef Ptr<IndexSubTableFormat1::Builder> IndexSubTableFormat1BuilderPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT1_H_

View File

@ -1,272 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/index_sub_table_format2.h"
#include "sfntly/table/bitmap/eblc_table.h"
namespace sfntly {
/******************************************************************************
* IndexSubTableFormat2 class
******************************************************************************/
IndexSubTableFormat2::~IndexSubTableFormat2() {
}
int32_t IndexSubTableFormat2::ImageSize() {
return data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable2_imageSize);
}
CALLER_ATTACH BigGlyphMetrics* IndexSubTableFormat2::BigMetrics() {
ReadableFontDataPtr slice;
slice.Attach(down_cast<ReadableFontData*>(
data_->Slice(EblcTable::Offset::kIndexSubTable2_bigGlyphMetrics,
BigGlyphMetrics::Offset::kMetricsLength)));
BigGlyphMetricsPtr output = new BigGlyphMetrics(slice);
return output.Detach();
}
int32_t IndexSubTableFormat2::NumGlyphs() {
return last_glyph_index() - first_glyph_index() + 1;
}
int32_t IndexSubTableFormat2::GlyphStartOffset(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return -1;
}
return loca * image_size_;
}
int32_t IndexSubTableFormat2::GlyphLength(int32_t glyph_id) {
if (CheckGlyphRange(glyph_id) == -1) {
return 0;
}
return image_size_;
}
IndexSubTableFormat2::IndexSubTableFormat2(ReadableFontData* data,
int32_t first,
int32_t last)
: IndexSubTable(data, first, last) {
image_size_ =
data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable2_imageSize);
}
/******************************************************************************
* IndexSubTableFormat2::Builder class
******************************************************************************/
IndexSubTableFormat2::Builder::~Builder() {
}
int32_t IndexSubTableFormat2::Builder::NumGlyphs() {
return last_glyph_index() - first_glyph_index() + 1;
}
int32_t IndexSubTableFormat2::Builder::GlyphStartOffset(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return -1;
}
return loca * ImageSize();
}
int32_t IndexSubTableFormat2::Builder::GlyphLength(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return 0;
}
return ImageSize();
}
CALLER_ATTACH IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator*
IndexSubTableFormat2::Builder::GetIterator() {
Ptr<IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator> it =
new IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator(this);
return it.Detach();
}
int32_t IndexSubTableFormat2::Builder::ImageSize() {
return InternalReadData()->ReadULongAsInt(
EblcTable::Offset::kIndexSubTable2_imageSize);
}
void IndexSubTableFormat2::Builder::SetImageSize(int32_t image_size) {
InternalWriteData()->WriteULong(EblcTable::Offset::kIndexSubTable2_imageSize,
image_size);
}
BigGlyphMetrics::Builder* IndexSubTableFormat2::Builder::BigMetrics() {
if (metrics_ == NULL) {
WritableFontDataPtr data;
data.Attach(down_cast<WritableFontData*>(InternalWriteData()->Slice(
EblcTable::Offset::kIndexSubTable2_bigGlyphMetrics,
BigGlyphMetrics::Offset::kMetricsLength)));
metrics_ = new BigGlyphMetrics::Builder(data);
}
return metrics_;
}
// static
CALLER_ATTACH IndexSubTableFormat2::Builder*
IndexSubTableFormat2::Builder::CreateBuilder() {
IndexSubTableFormat2BuilderPtr output = new IndexSubTableFormat2::Builder();
return output.Detach();
}
// static
CALLER_ATTACH IndexSubTableFormat2::Builder*
IndexSubTableFormat2::Builder::CreateBuilder(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
int32_t length = Builder::DataLength(data,
index_sub_table_offset,
first_glyph_index,
last_glyph_index);
ReadableFontDataPtr new_data;
new_data.Attach(down_cast<ReadableFontData*>(
data->Slice(index_sub_table_offset, length)));
IndexSubTableFormat2BuilderPtr output =
new IndexSubTableFormat2::Builder(new_data,
first_glyph_index,
last_glyph_index);
return output.Detach();
}
// static
CALLER_ATTACH IndexSubTableFormat2::Builder*
IndexSubTableFormat2::Builder::CreateBuilder(WritableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
int32_t length = Builder::DataLength(data,
index_sub_table_offset,
first_glyph_index,
last_glyph_index);
WritableFontDataPtr new_data;
new_data.Attach(down_cast<WritableFontData*>(
data->Slice(index_sub_table_offset, length)));
IndexSubTableFormat2BuilderPtr output =
new IndexSubTableFormat2::Builder(new_data,
first_glyph_index,
last_glyph_index);
return output.Detach();
}
CALLER_ATTACH FontDataTable* IndexSubTableFormat2::Builder::SubBuildTable(
ReadableFontData* data) {
IndexSubTableFormat2Ptr output = new IndexSubTableFormat2(
data, first_glyph_index(), last_glyph_index());
return output.Detach();
}
void IndexSubTableFormat2::Builder::SubDataSet() {
Revert();
}
int32_t IndexSubTableFormat2::Builder::SubDataSizeToSerialize() {
return EblcTable::Offset::kIndexSubTable2Length;
}
bool IndexSubTableFormat2::Builder::SubReadyToSerialize() {
return true;
}
int32_t IndexSubTableFormat2::Builder::SubSerialize(
WritableFontData* new_data) {
int32_t size = SerializeIndexSubHeader(new_data);
if (metrics_ == NULL) {
ReadableFontDataPtr source;
WritableFontDataPtr target;
source.Attach(down_cast<ReadableFontData*>(
InternalReadData()->Slice(size)));
target.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
size += source->CopyTo(target);
} else {
WritableFontDataPtr slice;
size += new_data->WriteLong(EblcTable::Offset::kIndexSubTable2_imageSize,
ImageSize());
slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
size += metrics_->SubSerialize(slice);
}
return size;
}
IndexSubTableFormat2::Builder::Builder()
: IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable3_builderDataSize,
IndexSubTable::Format::FORMAT_2) {
metrics_.Attach(BigGlyphMetrics::Builder::CreateBuilder());
}
IndexSubTableFormat2::Builder::Builder(WritableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
}
IndexSubTableFormat2::Builder::Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
}
// static
int32_t IndexSubTableFormat2::Builder::DataLength(
ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
UNREFERENCED_PARAMETER(data);
UNREFERENCED_PARAMETER(index_sub_table_offset);
UNREFERENCED_PARAMETER(first_glyph_index);
UNREFERENCED_PARAMETER(last_glyph_index);
return EblcTable::Offset::kIndexSubTable2Length;
}
/******************************************************************************
* IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator class
******************************************************************************/
IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
IndexSubTableFormat2::Builder* container)
: RefIterator<BitmapGlyphInfo, IndexSubTableFormat2::Builder,
IndexSubTable::Builder>(container) {
glyph_id_ = container->first_glyph_index();
}
bool IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::HasNext() {
if (glyph_id_ <= container()->last_glyph_index()) {
return true;
}
return false;
}
CALLER_ATTACH BitmapGlyphInfo*
IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::Next() {
BitmapGlyphInfoPtr output;
if (!HasNext()) {
// Note: In C++, we do not throw exception when there's no element.
return NULL;
}
output = new BitmapGlyphInfo(glyph_id_,
container()->image_data_offset(),
container()->GlyphStartOffset(glyph_id_),
container()->GlyphLength(glyph_id_),
container()->image_format());
glyph_id_++;
return output.Detach();
}
} // namespace sfntly

View File

@ -1,106 +0,0 @@
/*
* 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_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT2_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT2_H_
#include "sfntly/table/bitmap/index_sub_table.h"
#include "sfntly/table/bitmap/big_glyph_metrics.h"
namespace sfntly {
// Format 2 Index Subtable Entry.
class IndexSubTableFormat2 : public IndexSubTable,
public RefCounted<IndexSubTableFormat2> {
public:
class Builder : public IndexSubTable::Builder,
public RefCounted<Builder> {
public:
class BitmapGlyphInfoIterator
: public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
public:
explicit BitmapGlyphInfoIterator(Builder* container);
virtual ~BitmapGlyphInfoIterator() {}
virtual bool HasNext();
CALLER_ATTACH virtual BitmapGlyphInfo* Next();
private:
int32_t glyph_id_;
};
virtual ~Builder();
virtual int32_t NumGlyphs();
virtual int32_t GlyphStartOffset(int32_t glyph_id);
virtual int32_t GlyphLength(int32_t glyph_id);
CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
virtual int32_t SubDataSizeToSerialize();
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
int32_t ImageSize();
void SetImageSize(int32_t image_size);
BigGlyphMetrics::Builder* BigMetrics();
static CALLER_ATTACH Builder* CreateBuilder();
static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
private:
Builder();
Builder(WritableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
static int32_t DataLength(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
BigGlyphMetricsBuilderPtr metrics_;
};
virtual ~IndexSubTableFormat2();
int32_t ImageSize();
CALLER_ATTACH BigGlyphMetrics* BigMetrics();
virtual int32_t NumGlyphs();
virtual int32_t GlyphStartOffset(int32_t glyph_id);
virtual int32_t GlyphLength(int32_t glyph_id);
private:
IndexSubTableFormat2(ReadableFontData* data, int32_t first, int32_t last);
int32_t image_size_;
friend class Builder;
};
typedef Ptr<IndexSubTableFormat2> IndexSubTableFormat2Ptr;
typedef Ptr<IndexSubTableFormat2::Builder> IndexSubTableFormat2BuilderPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT1_H_

View File

@ -1,295 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/index_sub_table_format3.h"
#include "sfntly/table/bitmap/eblc_table.h"
namespace sfntly {
/******************************************************************************
* IndexSubTableFormat3 class
******************************************************************************/
IndexSubTableFormat3::~IndexSubTableFormat3() {
}
int32_t IndexSubTableFormat3::NumGlyphs() {
return last_glyph_index() - first_glyph_index() + 1;
}
int32_t IndexSubTableFormat3::GlyphStartOffset(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca != -1) {
return Loca(loca);
}
return -1;
}
int32_t IndexSubTableFormat3::GlyphLength(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca != -1) {
return Loca(glyph_id + 1) - Loca(glyph_id);
}
return 0;
}
// static
int32_t IndexSubTableFormat3::GetDataLength(ReadableFontData* data,
int32_t offset,
int32_t first,
int32_t last) {
UNREFERENCED_PARAMETER(data);
UNREFERENCED_PARAMETER(offset);
return (last - first + 1 + 1) * DataSize::kUSHORT;
}
IndexSubTableFormat3::IndexSubTableFormat3(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: IndexSubTable(data, first_glyph_index, last_glyph_index) {
}
int32_t IndexSubTableFormat3::Loca(int32_t loca) {
int32_t read_offset =
data_->ReadUShort(EblcTable::Offset::kIndexSubTable3_offsetArray +
loca * DataSize::kUSHORT);
return read_offset;
}
/******************************************************************************
* IndexSubTableFormat3::Builder class
******************************************************************************/
IndexSubTableFormat3::Builder::~Builder() {
}
int32_t IndexSubTableFormat3::Builder::NumGlyphs() {
return GetOffsetArray()->size() - 1;
}
int32_t IndexSubTableFormat3::Builder::GlyphStartOffset(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return -1;
}
return GetOffsetArray()->at(loca);
}
int32_t IndexSubTableFormat3::Builder::GlyphLength(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return 0;
}
IntegerList* offset_array = GetOffsetArray();
return offset_array->at(loca + 1) - offset_array->at(loca);
}
CALLER_ATTACH IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator*
IndexSubTableFormat3::Builder::GetIterator() {
Ptr<IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator> it =
new IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator(this);
return it.Detach();
}
void IndexSubTableFormat3::Builder::Revert() {
offset_array_.clear();
IndexSubTable::Builder::Revert();
}
void IndexSubTableFormat3::Builder::SetOffsetArray(
const IntegerList& offset_array) {
offset_array_.clear();
offset_array_ = offset_array;
set_model_changed();
}
// static
CALLER_ATTACH IndexSubTableFormat3::Builder*
IndexSubTableFormat3::Builder::CreateBuilder() {
IndexSubTableFormat3BuilderPtr output = new IndexSubTableFormat3::Builder();
return output.Detach();
}
// static
CALLER_ATTACH IndexSubTableFormat3::Builder*
IndexSubTableFormat3::Builder::CreateBuilder(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
int32_t length = Builder::DataLength(data,
index_sub_table_offset,
first_glyph_index,
last_glyph_index);
ReadableFontDataPtr new_data;
new_data.Attach(down_cast<ReadableFontData*>(
data->Slice(index_sub_table_offset, length)));
IndexSubTableFormat3BuilderPtr output =
new IndexSubTableFormat3::Builder(new_data,
first_glyph_index,
last_glyph_index);
return output.Detach();
}
// static
CALLER_ATTACH IndexSubTableFormat3::Builder*
IndexSubTableFormat3::Builder::CreateBuilder(WritableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
int32_t length = Builder::DataLength(data,
index_sub_table_offset,
first_glyph_index,
last_glyph_index);
WritableFontDataPtr new_data;
new_data.Attach(down_cast<WritableFontData*>(
data->Slice(index_sub_table_offset, length)));
IndexSubTableFormat3BuilderPtr output =
new IndexSubTableFormat3::Builder(new_data,
first_glyph_index,
last_glyph_index);
return output.Detach();
}
CALLER_ATTACH FontDataTable* IndexSubTableFormat3::Builder::SubBuildTable(
ReadableFontData* data) {
IndexSubTableFormat3Ptr output = new IndexSubTableFormat3(
data, first_glyph_index(), last_glyph_index());
return output.Detach();
}
void IndexSubTableFormat3::Builder::SubDataSet() {
Revert();
}
int32_t IndexSubTableFormat3::Builder::SubDataSizeToSerialize() {
if (offset_array_.empty()) {
return InternalReadData()->Length();
}
return EblcTable::Offset::kIndexSubHeaderLength +
offset_array_.size() * DataSize::kULONG;
}
bool IndexSubTableFormat3::Builder::SubReadyToSerialize() {
if (!offset_array_.empty()) {
return true;
}
return false;
}
int32_t IndexSubTableFormat3::Builder::SubSerialize(
WritableFontData* new_data) {
int32_t size = SerializeIndexSubHeader(new_data);
if (!model_changed()) {
if (InternalReadData() == NULL) {
return size;
}
ReadableFontDataPtr source;
WritableFontDataPtr target;
source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
EblcTable::Offset::kIndexSubTable3_offsetArray)));
target.Attach(down_cast<WritableFontData*>(new_data->Slice(
EblcTable::Offset::kIndexSubTable3_offsetArray)));
size += source->CopyTo(target);
} else {
for (IntegerList::iterator b = GetOffsetArray()->begin(),
e = GetOffsetArray()->end(); b != e; b++) {
size += new_data->WriteUShort(size, *b);
}
}
return size;
}
IndexSubTableFormat3::Builder::Builder()
: IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable3_builderDataSize,
IndexSubTable::Format::FORMAT_3) {
}
IndexSubTableFormat3::Builder::Builder(WritableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
}
IndexSubTableFormat3::Builder::Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
}
IntegerList* IndexSubTableFormat3::Builder::GetOffsetArray() {
if (offset_array_.empty()) {
Initialize(InternalReadData());
set_model_changed();
}
return &offset_array_;
}
void IndexSubTableFormat3::Builder::Initialize(ReadableFontData* data) {
offset_array_.clear();
if (data) {
int32_t num_offsets = (last_glyph_index() - first_glyph_index() + 1) + 1;
for (int32_t i = 0; i < num_offsets; ++i) {
offset_array_.push_back(data->ReadUShort(
EblcTable::Offset::kIndexSubTable3_offsetArray +
i * DataSize::kUSHORT));
}
}
}
// static
int32_t IndexSubTableFormat3::Builder::DataLength(
ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
UNREFERENCED_PARAMETER(data);
UNREFERENCED_PARAMETER(index_sub_table_offset);
return EblcTable::Offset::kIndexSubHeaderLength +
(last_glyph_index - first_glyph_index + 1 + 1) * DataSize::kUSHORT;
}
/******************************************************************************
* IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator class
******************************************************************************/
IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
IndexSubTableFormat3::Builder* container)
: RefIterator<BitmapGlyphInfo, IndexSubTableFormat3::Builder,
IndexSubTable::Builder>(container) {
glyph_id_ = container->first_glyph_index();
}
bool IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator::HasNext() {
if (glyph_id_ <= container()->last_glyph_index()) {
return true;
}
return false;
}
CALLER_ATTACH BitmapGlyphInfo*
IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator::Next() {
BitmapGlyphInfoPtr output;
if (!HasNext()) {
// Note: In C++, we do not throw exception when there's no element.
return NULL;
}
output = new BitmapGlyphInfo(glyph_id_,
container()->image_data_offset(),
container()->GlyphStartOffset(glyph_id_),
container()->GlyphLength(glyph_id_),
container()->image_format());
glyph_id_++;
return output.Detach();
}
} // namespace sfntly

View File

@ -1,113 +0,0 @@
/*
* 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_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT3_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT3_H_
#include "sfntly/table/bitmap/index_sub_table.h"
namespace sfntly {
// Format 3 Index Subtable Entry.
class IndexSubTableFormat3 : public IndexSubTable,
public RefCounted<IndexSubTableFormat3> {
public:
class Builder : public IndexSubTable::Builder,
public RefCounted<Builder> {
public:
class BitmapGlyphInfoIterator
: public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
public:
explicit BitmapGlyphInfoIterator(Builder* container);
virtual ~BitmapGlyphInfoIterator() {}
virtual bool HasNext();
CALLER_ATTACH virtual BitmapGlyphInfo* Next();
private:
int32_t glyph_id_;
};
virtual ~Builder();
virtual int32_t NumGlyphs();
virtual int32_t GlyphStartOffset(int32_t glyph_id);
virtual int32_t GlyphLength(int32_t glyph_id);
CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
virtual int32_t SubDataSizeToSerialize();
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
void SetOffsetArray(const IntegerList& offset_array);
static CALLER_ATTACH Builder* CreateBuilder();
static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
protected:
void Revert();
private:
Builder();
Builder(WritableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
IntegerList* GetOffsetArray();
void Initialize(ReadableFontData* data);
static int32_t DataLength(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
IntegerList offset_array_;
};
virtual ~IndexSubTableFormat3();
virtual int32_t NumGlyphs();
virtual int32_t GlyphStartOffset(int32_t glyph_id);
virtual int32_t GlyphLength(int32_t glyph_id);
static int32_t GetDataLength(ReadableFontData* data,
int32_t offset,
int32_t first,
int32_t last);
private:
IndexSubTableFormat3(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
int32_t Loca(int32_t loca_index);
friend class Builder;
};
typedef Ptr<IndexSubTableFormat3> IndexSubTableFormat3Ptr;
typedef Ptr<IndexSubTableFormat3::Builder> IndexSubTableFormat3BuilderPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT3_H_

View File

@ -1,381 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/index_sub_table_format4.h"
#include "sfntly/table/bitmap/eblc_table.h"
namespace sfntly {
/******************************************************************************
* IndexSubTableFormat4 class
******************************************************************************/
IndexSubTableFormat4::~IndexSubTableFormat4() {
}
int32_t IndexSubTableFormat4::NumGlyphs() {
return IndexSubTableFormat4::NumGlyphs(data_, 0);
}
int32_t IndexSubTableFormat4::GlyphStartOffset(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return -1;
}
int32_t pair_index = FindCodeOffsetPair(glyph_id);
if (pair_index < 0) {
return -1;
}
return data_->ReadUShort(EblcTable::Offset::kIndexSubTable4_glyphArray +
pair_index *
EblcTable::Offset::kCodeOffsetPairLength +
EblcTable::Offset::kCodeOffsetPair_offset);
}
int32_t IndexSubTableFormat4::GlyphLength(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return -1;
}
int32_t pair_index = FindCodeOffsetPair(glyph_id);
if (pair_index < 0) {
return -1;
}
return data_->ReadUShort(
EblcTable::Offset::kIndexSubTable4_glyphArray +
(pair_index + 1) * EblcTable::Offset::kCodeOffsetPairLength +
EblcTable::Offset::kCodeOffsetPair_offset) -
data_->ReadUShort(
EblcTable::Offset::kIndexSubTable4_glyphArray +
(pair_index) * EblcTable::Offset::kCodeOffsetPairLength +
EblcTable::Offset::kCodeOffsetPair_offset);
}
IndexSubTableFormat4::IndexSubTableFormat4(ReadableFontData* data,
int32_t first,
int32_t last)
: IndexSubTable(data, first, last) {
}
int32_t IndexSubTableFormat4::FindCodeOffsetPair(int32_t glyph_id) {
return data_->SearchUShort(EblcTable::Offset::kIndexSubTable4_glyphArray,
EblcTable::Offset::kCodeOffsetPairLength,
NumGlyphs(),
glyph_id);
}
int32_t IndexSubTableFormat4::NumGlyphs(ReadableFontData* data,
int32_t table_offset) {
int32_t num_glyphs = data->ReadULongAsInt(table_offset +
EblcTable::Offset::kIndexSubTable4_numGlyphs);
return num_glyphs;
}
/******************************************************************************
* IndexSubTableFormat4::CodeOffsetPair related class
******************************************************************************/
IndexSubTableFormat4::CodeOffsetPair::CodeOffsetPair(int32_t glyph_code,
int32_t offset)
: glyph_code_(glyph_code), offset_(offset) {
}
IndexSubTableFormat4::CodeOffsetPairBuilder::CodeOffsetPairBuilder()
: CodeOffsetPair(0, 0) {
}
IndexSubTableFormat4::CodeOffsetPairBuilder::CodeOffsetPairBuilder(
int32_t glyph_code, int32_t offset)
: CodeOffsetPair(glyph_code, offset) {
}
bool IndexSubTableFormat4::CodeOffsetPairGlyphCodeComparator::operator()(
const CodeOffsetPair& lhs, const CodeOffsetPair& rhs) {
return lhs.glyph_code() < rhs.glyph_code();
}
/******************************************************************************
* IndexSubTableFormat4::Builder class
******************************************************************************/
IndexSubTableFormat4::Builder::~Builder() {
}
int32_t IndexSubTableFormat4::Builder::NumGlyphs() {
return GetOffsetArray()->size() - 1;
}
int32_t IndexSubTableFormat4::Builder::GlyphLength(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return 0;
}
int32_t pair_index = FindCodeOffsetPair(glyph_id);
if (pair_index == -1) {
return 0;
}
return GetOffsetArray()->at(pair_index + 1).offset() -
GetOffsetArray()->at(pair_index).offset();
}
int32_t IndexSubTableFormat4::Builder::GlyphStartOffset(int32_t glyph_id) {
int32_t loca = CheckGlyphRange(glyph_id);
if (loca == -1) {
return -1;
}
int32_t pair_index = FindCodeOffsetPair(glyph_id);
if (pair_index == -1) {
return -1;
}
return GetOffsetArray()->at(pair_index).offset();
}
CALLER_ATTACH IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator*
IndexSubTableFormat4::Builder::GetIterator() {
Ptr<IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator> it =
new IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator(this);
return it.Detach();
}
// static
CALLER_ATTACH IndexSubTableFormat4::Builder*
IndexSubTableFormat4::Builder::CreateBuilder() {
IndexSubTableFormat4BuilderPtr output = new IndexSubTableFormat4::Builder();
return output.Detach();
}
// static
CALLER_ATTACH IndexSubTableFormat4::Builder*
IndexSubTableFormat4::Builder::CreateBuilder(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
int32_t length = Builder::DataLength(data,
index_sub_table_offset,
first_glyph_index,
last_glyph_index);
ReadableFontDataPtr new_data;
new_data.Attach(down_cast<ReadableFontData*>(
data->Slice(index_sub_table_offset, length)));
IndexSubTableFormat4BuilderPtr output =
new IndexSubTableFormat4::Builder(new_data,
first_glyph_index,
last_glyph_index);
return output.Detach();
}
// static
CALLER_ATTACH IndexSubTableFormat4::Builder*
IndexSubTableFormat4::Builder::CreateBuilder(WritableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
int32_t length = Builder::DataLength(data,
index_sub_table_offset,
first_glyph_index,
last_glyph_index);
WritableFontDataPtr new_data;
new_data.Attach(down_cast<WritableFontData*>(
data->Slice(index_sub_table_offset, length)));
IndexSubTableFormat4BuilderPtr output =
new IndexSubTableFormat4::Builder(new_data,
first_glyph_index,
last_glyph_index);
return output.Detach();
}
CALLER_ATTACH FontDataTable* IndexSubTableFormat4::Builder::SubBuildTable(
ReadableFontData* data) {
IndexSubTableFormat4Ptr output = new IndexSubTableFormat4(
data, first_glyph_index(), last_glyph_index());
return output.Detach();
}
void IndexSubTableFormat4::Builder::SubDataSet() {
Revert();
}
int32_t IndexSubTableFormat4::Builder::SubDataSizeToSerialize() {
if (offset_pair_array_.empty()) {
return InternalReadData()->Length();
}
return EblcTable::Offset::kIndexSubHeaderLength + DataSize::kULONG +
GetOffsetArray()->size() *
EblcTable::Offset::kIndexSubTable4_codeOffsetPairLength;
}
bool IndexSubTableFormat4::Builder::SubReadyToSerialize() {
if (!offset_pair_array_.empty()) {
return true;
}
return false;
}
int32_t IndexSubTableFormat4::Builder::SubSerialize(
WritableFontData* new_data) {
int32_t size = SerializeIndexSubHeader(new_data);
if (!model_changed()) {
if (InternalReadData() == NULL) {
return size;
}
ReadableFontDataPtr source;
WritableFontDataPtr target;
source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
EblcTable::Offset::kIndexSubTable4_glyphArray)));
target.Attach(down_cast<WritableFontData*>(new_data->Slice(
EblcTable::Offset::kIndexSubTable4_glyphArray)));
size += source->CopyTo(target);
} else {
size += new_data->WriteLong(size, offset_pair_array_.size() - 1);
for (std::vector<CodeOffsetPairBuilder>::iterator
b = GetOffsetArray()->begin(), e = GetOffsetArray()->end();
b != e; b++) {
size += new_data->WriteUShort(size, b->glyph_code());
size += new_data->WriteUShort(size, b->offset());
}
}
return size;
}
void IndexSubTableFormat4::Builder::Revert() {
offset_pair_array_.clear();
IndexSubTable::Builder::Revert();
}
void IndexSubTableFormat4::Builder::SetOffsetArray(
const std::vector<CodeOffsetPairBuilder>& pair_array) {
offset_pair_array_.clear();
offset_pair_array_ = pair_array;
set_model_changed();
}
IndexSubTableFormat4::Builder::Builder()
: IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable4_builderDataSize,
Format::FORMAT_4) {
}
IndexSubTableFormat4::Builder::Builder(WritableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
}
IndexSubTableFormat4::Builder::Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
}
std::vector<IndexSubTableFormat4::CodeOffsetPairBuilder>*
IndexSubTableFormat4::Builder::GetOffsetArray() {
if (offset_pair_array_.empty()) {
Initialize(InternalReadData());
set_model_changed();
}
return &offset_pair_array_;
}
void IndexSubTableFormat4::Builder::Initialize(ReadableFontData* data) {
offset_pair_array_.clear();
if (data) {
int32_t num_pairs = IndexSubTableFormat4::NumGlyphs(data, 0) + 1;
int32_t offset = EblcTable::Offset::kIndexSubTable4_glyphArray;
for (int32_t i = 0; i < num_pairs; ++i) {
int32_t glyph_code = data->ReadUShort(offset +
EblcTable::Offset::kIndexSubTable4_codeOffsetPair_glyphCode);
int32_t glyph_offset = data->ReadUShort(offset +
EblcTable::Offset::kIndexSubTable4_codeOffsetPair_offset);
offset += EblcTable::Offset::kIndexSubTable4_codeOffsetPairLength;
CodeOffsetPairBuilder pair_builder(glyph_code, glyph_offset);
offset_pair_array_.push_back(pair_builder);
}
}
}
int32_t IndexSubTableFormat4::Builder::FindCodeOffsetPair(int32_t glyph_id) {
std::vector<CodeOffsetPairBuilder>* pair_list = GetOffsetArray();
int32_t location = 0;
int32_t bottom = 0;
int32_t top = pair_list->size();
while (top != bottom) {
location = (top + bottom) / 2;
CodeOffsetPairBuilder* pair = &(pair_list->at(location));
if (glyph_id < pair->glyph_code()) {
// location is below current location
top = location;
} else if (glyph_id > pair->glyph_code()) {
// location is above current location
bottom = location + 1;
} else {
return location;
}
}
return -1;
}
// static
int32_t IndexSubTableFormat4::Builder::DataLength(
ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
int32_t num_glyphs = IndexSubTableFormat4::NumGlyphs(data,
index_sub_table_offset);
UNREFERENCED_PARAMETER(first_glyph_index);
UNREFERENCED_PARAMETER(last_glyph_index);
return EblcTable::Offset::kIndexSubTable4_glyphArray +
num_glyphs * EblcTable::Offset::kIndexSubTable4_codeOffsetPair_offset;
}
/******************************************************************************
* IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator class
******************************************************************************/
IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
IndexSubTableFormat4::Builder* container)
: RefIterator<BitmapGlyphInfo, IndexSubTableFormat4::Builder,
IndexSubTable::Builder>(container),
code_offset_pair_index_(0) {
}
bool IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator::HasNext() {
if (code_offset_pair_index_ <
(int32_t)(container()->GetOffsetArray()->size() - 1)) {
return true;
}
return false;
}
CALLER_ATTACH BitmapGlyphInfo*
IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator::Next() {
BitmapGlyphInfoPtr output;
if (!HasNext()) {
// Note: In C++, we do not throw exception when there's no element.
return NULL;
}
std::vector<CodeOffsetPairBuilder>* offset_array =
container()->GetOffsetArray();
int32_t offset = offset_array->at(code_offset_pair_index_).offset();
int32_t next_offset = offset_array->at(code_offset_pair_index_ + 1).offset();
int32_t glyph_code = offset_array->at(code_offset_pair_index_).glyph_code();
output = new BitmapGlyphInfo(glyph_code,
container()->image_data_offset(),
offset,
next_offset - offset,
container()->image_format());
code_offset_pair_index_++;
return output.Detach();
}
} // namespace sfntly

View File

@ -1,135 +0,0 @@
/*
* 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_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT4_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT4_H_
#include "sfntly/table/bitmap/index_sub_table.h"
namespace sfntly {
class IndexSubTableFormat4 : public IndexSubTable,
public RefCounted<IndexSubTableFormat4> {
public:
class CodeOffsetPair {
public:
int32_t glyph_code() const { return glyph_code_; }
int32_t offset() const { return offset_; }
protected:
CodeOffsetPair(int32_t glyph_code, int32_t offset);
// TODO(arthurhsu): C++ style guide prohibits protected members.
int32_t glyph_code_;
int32_t offset_;
};
class CodeOffsetPairBuilder : public CodeOffsetPair {
public:
CodeOffsetPairBuilder();
CodeOffsetPairBuilder(int32_t glyph_code, int32_t offset);
void set_glyph_code(int32_t v) { glyph_code_ = v; }
void set_offset(int32_t v) { offset_ = v; }
};
class CodeOffsetPairGlyphCodeComparator {
public:
bool operator()(const CodeOffsetPair& lhs, const CodeOffsetPair& rhs);
};
class Builder : public IndexSubTable::Builder,
public RefCounted<Builder> {
public:
class BitmapGlyphInfoIterator
: public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
public:
explicit BitmapGlyphInfoIterator(Builder* container);
virtual ~BitmapGlyphInfoIterator() {}
virtual bool HasNext();
CALLER_ATTACH virtual BitmapGlyphInfo* Next();
private:
int32_t code_offset_pair_index_;
};
virtual ~Builder();
virtual int32_t NumGlyphs();
virtual int32_t GlyphLength(int32_t glyph_id);
virtual int32_t GlyphStartOffset(int32_t glyph_id);
CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
virtual int32_t SubDataSizeToSerialize();
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
void Revert();
void SetOffsetArray(const std::vector<CodeOffsetPairBuilder>& pair_array);
static CALLER_ATTACH Builder* CreateBuilder();
static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
private:
Builder();
Builder(WritableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
std::vector<CodeOffsetPairBuilder>* GetOffsetArray();
void Initialize(ReadableFontData* data);
int32_t FindCodeOffsetPair(int32_t glyph_id);
static int32_t DataLength(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
std::vector<CodeOffsetPairBuilder> offset_pair_array_;
};
virtual ~IndexSubTableFormat4();
virtual int32_t NumGlyphs();
virtual int32_t GlyphStartOffset(int32_t glyph_id);
virtual int32_t GlyphLength(int32_t glyph_id);
private:
IndexSubTableFormat4(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
int32_t FindCodeOffsetPair(int32_t glyph_id);
static int32_t NumGlyphs(ReadableFontData* data, int32_t table_offset);
friend class Builder;
};
typedef Ptr<IndexSubTableFormat4> IndexSubTableFormat4Ptr;
typedef Ptr<IndexSubTableFormat4::Builder> IndexSubTableFormat4BuilderPtr;
typedef std::vector<IndexSubTableFormat4::CodeOffsetPairBuilder>
CodeOffsetPairBuilderList;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT4_H_

View File

@ -1,344 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/index_sub_table_format5.h"
#include <algorithm>
#include "sfntly/table/bitmap/eblc_table.h"
namespace sfntly {
/******************************************************************************
* IndexSubTableFormat5 class
******************************************************************************/
IndexSubTableFormat5::~IndexSubTableFormat5() {
}
int32_t IndexSubTableFormat5::NumGlyphs() {
return NumGlyphs(data_, 0);
}
int32_t IndexSubTableFormat5::GlyphStartOffset(int32_t glyph_id) {
int32_t check = CheckGlyphRange(glyph_id);
if (check == -1) {
return -1;
}
int32_t loca = ReadFontData()->SearchUShort(
EblcTable::Offset::kIndexSubTable5_glyphArray,
DataSize::kUSHORT,
NumGlyphs(),
glyph_id);
if (loca == -1) {
return loca;
}
return loca * ImageSize();
}
int32_t IndexSubTableFormat5::GlyphLength(int32_t glyph_id) {
int32_t check = CheckGlyphRange(glyph_id);
if (check == -1) {
return 0;
}
return image_size_;
}
int32_t IndexSubTableFormat5::ImageSize() {
return data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable5_imageSize);
}
CALLER_ATTACH BigGlyphMetrics* IndexSubTableFormat5::BigMetrics() {
ReadableFontDataPtr data;
data.Attach(down_cast<ReadableFontData*>(data_->Slice(
EblcTable::Offset::kIndexSubTable5_bigGlyphMetrics,
BigGlyphMetrics::Offset::kMetricsLength)));
BigGlyphMetricsPtr output = new BigGlyphMetrics(data);
return output.Detach();
}
IndexSubTableFormat5::IndexSubTableFormat5(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: IndexSubTable(data, first_glyph_index, last_glyph_index) {
image_size_ = data_->ReadULongAsInt(
EblcTable::Offset::kIndexSubTable5_imageSize);
}
// static
int32_t IndexSubTableFormat5::NumGlyphs(ReadableFontData* data,
int32_t table_offset) {
int32_t num_glyphs = data->ReadULongAsInt(table_offset +
EblcTable::Offset::kIndexSubTable5_numGlyphs);
return num_glyphs;
}
/******************************************************************************
* IndexSubTableFormat5::Builder class
******************************************************************************/
IndexSubTableFormat5::Builder::~Builder() {
}
int32_t IndexSubTableFormat5::Builder::NumGlyphs() {
return GetGlyphArray()->size();
}
int32_t IndexSubTableFormat5::Builder::GlyphLength(int32_t glyph_id) {
UNREFERENCED_PARAMETER(glyph_id);
return ImageSize();
}
int32_t IndexSubTableFormat5::Builder::GlyphStartOffset(int32_t glyph_id) {
int32_t check = CheckGlyphRange(glyph_id);
if (check == -1) {
return -1;
}
IntegerList* glyph_array = GetGlyphArray();
IntegerList::iterator it = std::find(glyph_array->begin(),
glyph_array->end(),
glyph_id);
if (it == glyph_array->end()) {
return -1;
}
return (it - glyph_array->begin()) * ImageSize();
}
CALLER_ATTACH IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator*
IndexSubTableFormat5::Builder::GetIterator() {
Ptr<IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator> it =
new IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator(this);
return it.Detach();
}
// static
CALLER_ATTACH IndexSubTableFormat5::Builder*
IndexSubTableFormat5::Builder::CreateBuilder() {
IndexSubTableFormat5BuilderPtr output = new IndexSubTableFormat5::Builder();
return output.Detach();
}
// static
CALLER_ATTACH IndexSubTableFormat5::Builder*
IndexSubTableFormat5::Builder::CreateBuilder(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
int32_t length = Builder::DataLength(data,
index_sub_table_offset,
first_glyph_index,
last_glyph_index);
ReadableFontDataPtr new_data;
new_data.Attach(down_cast<ReadableFontData*>(
data->Slice(index_sub_table_offset, length)));
IndexSubTableFormat5BuilderPtr output =
new IndexSubTableFormat5::Builder(new_data,
first_glyph_index,
last_glyph_index);
return output.Detach();
}
// static
CALLER_ATTACH IndexSubTableFormat5::Builder*
IndexSubTableFormat5::Builder::CreateBuilder(WritableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
int32_t length = Builder::DataLength(data,
index_sub_table_offset,
first_glyph_index,
last_glyph_index);
WritableFontDataPtr new_data;
new_data.Attach(down_cast<WritableFontData*>(
data->Slice(index_sub_table_offset, length)));
IndexSubTableFormat5BuilderPtr output =
new IndexSubTableFormat5::Builder(new_data,
first_glyph_index,
last_glyph_index);
return output.Detach();
}
CALLER_ATTACH FontDataTable* IndexSubTableFormat5::Builder::SubBuildTable(
ReadableFontData* data) {
IndexSubTableFormat5Ptr output = new IndexSubTableFormat5(
data, first_glyph_index(), last_glyph_index());
return output.Detach();
}
void IndexSubTableFormat5::Builder::SubDataSet() {
Revert();
}
int32_t IndexSubTableFormat5::Builder::SubDataSizeToSerialize() {
if (glyph_array_.empty()) {
return InternalReadData()->Length();
}
return EblcTable::Offset::kIndexSubTable5_builderDataSize +
glyph_array_.size() * DataSize::kUSHORT;
}
bool IndexSubTableFormat5::Builder::SubReadyToSerialize() {
if (!glyph_array_.empty()) {
return true;
}
return false;
}
int32_t IndexSubTableFormat5::Builder::SubSerialize(
WritableFontData* new_data) {
int32_t size = SerializeIndexSubHeader(new_data);
if (!model_changed()) {
ReadableFontDataPtr source;
WritableFontDataPtr target;
source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
EblcTable::Offset::kIndexSubTable5_imageSize)));
target.Attach(down_cast<WritableFontData*>(new_data->Slice(
EblcTable::Offset::kIndexSubTable5_imageSize)));
size += source->CopyTo(target);
} else {
size += new_data->WriteULong(EblcTable::Offset::kIndexSubTable5_imageSize,
ImageSize());
WritableFontDataPtr slice;
slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
size += BigMetrics()->SubSerialize(slice);
size += new_data->WriteULong(size, glyph_array_.size());
for (IntegerList::iterator b = glyph_array_.begin(), e = glyph_array_.end();
b != e; b++) {
size += new_data->WriteUShort(size, *b);
}
}
return size;
}
int32_t IndexSubTableFormat5::Builder::ImageSize() {
return InternalReadData()->ReadULongAsInt(
EblcTable::Offset::kIndexSubTable5_imageSize);
}
void IndexSubTableFormat5::Builder::SetImageSize(int32_t image_size) {
InternalWriteData()->WriteULong(
EblcTable::Offset::kIndexSubTable5_imageSize, image_size);
}
BigGlyphMetrics::Builder* IndexSubTableFormat5::Builder::BigMetrics() {
if (metrics_ == NULL) {
WritableFontDataPtr data;
data.Attach(down_cast<WritableFontData*>(InternalWriteData()->Slice(
EblcTable::Offset::kIndexSubTable5_bigGlyphMetrics,
BigGlyphMetrics::Offset::kMetricsLength)));
metrics_ = new BigGlyphMetrics::Builder(data);
set_model_changed();
}
return metrics_;
}
IntegerList* IndexSubTableFormat5::Builder::GlyphArray() {
return GetGlyphArray();
}
void IndexSubTableFormat5::Builder::SetGlyphArray(const IntegerList& v) {
glyph_array_.clear();
glyph_array_ = v;
set_model_changed();
}
void IndexSubTableFormat5::Builder::Revert() {
glyph_array_.clear();
IndexSubTable::Builder::Revert();
}
IndexSubTableFormat5::Builder::Builder()
: IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable5_builderDataSize,
IndexSubTable::Format::FORMAT_5) {
}
IndexSubTableFormat5::Builder::Builder(WritableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
}
IndexSubTableFormat5::Builder::Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index)
: IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
}
IntegerList* IndexSubTableFormat5::Builder::GetGlyphArray() {
if (glyph_array_.empty()) {
Initialize(InternalReadData());
set_model_changed();
}
return &glyph_array_;
}
void IndexSubTableFormat5::Builder::Initialize(ReadableFontData* data) {
glyph_array_.clear();
if (data) {
int32_t num_glyphs = IndexSubTableFormat5::NumGlyphs(data, 0);
for (int32_t i = 0; i < num_glyphs; ++i) {
glyph_array_.push_back(data->ReadUShort(
EblcTable::Offset::kIndexSubTable5_glyphArray +
i * DataSize::kUSHORT));
}
}
}
// static
int32_t IndexSubTableFormat5::Builder::DataLength(
ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index) {
int32_t num_glyphs = IndexSubTableFormat5::NumGlyphs(data,
index_sub_table_offset);
UNREFERENCED_PARAMETER(first_glyph_index);
UNREFERENCED_PARAMETER(last_glyph_index);
return EblcTable::Offset::kIndexSubTable5_glyphArray +
num_glyphs * DataSize::kUSHORT;
}
/******************************************************************************
* IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator class
******************************************************************************/
IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
IndexSubTableFormat5::Builder* container)
: RefIterator<BitmapGlyphInfo, IndexSubTableFormat5::Builder,
IndexSubTable::Builder>(container),
offset_index_(0) {
}
bool IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator::HasNext() {
if (offset_index_ < (int32_t)(container()->GetGlyphArray()->size())) {
return true;
}
return false;
}
CALLER_ATTACH BitmapGlyphInfo*
IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator::Next() {
BitmapGlyphInfoPtr output;
if (!HasNext()) {
// Note: In C++, we do not throw exception when there's no element.
return NULL;
}
output = new BitmapGlyphInfo(container()->GetGlyphArray()->at(offset_index_),
container()->image_data_offset(),
offset_index_ * container()->ImageSize(),
container()->ImageSize(),
container()->image_format());
offset_index_++;
return output.Detach();
}
} // namespace sfntly

View File

@ -1,118 +0,0 @@
/*
* 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_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT5_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT5_H_
#include "sfntly/table/bitmap/big_glyph_metrics.h"
#include "sfntly/table/bitmap/index_sub_table.h"
namespace sfntly {
class IndexSubTableFormat5 : public IndexSubTable,
public RefCounted<IndexSubTableFormat5> {
public:
class Builder : public IndexSubTable::Builder,
public RefCounted<Builder> {
public:
class BitmapGlyphInfoIterator
: public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
public:
explicit BitmapGlyphInfoIterator(Builder* container);
virtual ~BitmapGlyphInfoIterator() {}
virtual bool HasNext();
CALLER_ATTACH virtual BitmapGlyphInfo* Next();
private:
int32_t offset_index_;
};
virtual ~Builder();
virtual int32_t NumGlyphs();
virtual int32_t GlyphLength(int32_t glyph_id);
virtual int32_t GlyphStartOffset(int32_t glyph_id);
CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
virtual int32_t SubDataSizeToSerialize();
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
int32_t ImageSize();
void SetImageSize(int32_t image_size);
BigGlyphMetrics::Builder* BigMetrics();
IntegerList* GlyphArray();
void SetGlyphArray(const IntegerList& v);
static CALLER_ATTACH Builder* CreateBuilder();
static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
protected:
void Revert();
private:
Builder();
Builder(WritableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
IntegerList* GetGlyphArray();
void Initialize(ReadableFontData* data);
static int32_t DataLength(ReadableFontData* data,
int32_t index_sub_table_offset,
int32_t first_glyph_index,
int32_t last_glyph_index);
IntegerList glyph_array_;
BigGlyphMetricsBuilderPtr metrics_;
};
virtual ~IndexSubTableFormat5();
virtual int32_t NumGlyphs();
virtual int32_t GlyphStartOffset(int32_t glyph_id);
virtual int32_t GlyphLength(int32_t glyph_id);
int32_t ImageSize();
CALLER_ATTACH BigGlyphMetrics* BigMetrics();
private:
IndexSubTableFormat5(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
static int32_t NumGlyphs(ReadableFontData* dta, int32_t table_offset);
int32_t image_size_;
friend class Builder;
};
typedef Ptr<IndexSubTableFormat5> IndexSubTableFormat5Ptr;
typedef Ptr<IndexSubTableFormat5::Builder> IndexSubTableFormat5BuilderPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT5_H_

View File

@ -1,45 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/simple_bitmap_glyph.h"
namespace sfntly {
SimpleBitmapGlyph::SimpleBitmapGlyph(ReadableFontData* data, int32_t format)
: BitmapGlyph(data, format) {
}
SimpleBitmapGlyph::~SimpleBitmapGlyph() {
}
SimpleBitmapGlyph::Builder::Builder(ReadableFontData* data, int32_t format)
: BitmapGlyph::Builder(data, format) {
}
SimpleBitmapGlyph::Builder::Builder(WritableFontData* data, int32_t format)
: BitmapGlyph::Builder(data, format) {
}
SimpleBitmapGlyph::Builder::~Builder() {
}
CALLER_ATTACH FontDataTable*
SimpleBitmapGlyph::Builder::SubBuildTable(ReadableFontData* data) {
Ptr<SimpleBitmapGlyph> glyph = new SimpleBitmapGlyph(data, format());
return glyph.Detach();
}
} // namespace sfntly

View File

@ -1,44 +0,0 @@
/*
* 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_TABLE_BITMAP_SIMPLE_BITMAP_GLYPH_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SIMPLE_BITMAP_GLYPH_H_
#include "sfntly/table/bitmap/bitmap_glyph.h"
namespace sfntly {
class SimpleBitmapGlyph : public BitmapGlyph,
public RefCounted<SimpleBitmapGlyph> {
public:
class Builder : public BitmapGlyph::Builder,
public RefCounted<Builder> {
public:
Builder(WritableFontData* data, int32_t format);
Builder(ReadableFontData* data, int32_t format);
virtual ~Builder();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
};
SimpleBitmapGlyph(ReadableFontData* data, int32_t format);
virtual ~SimpleBitmapGlyph();
};
typedef Ptr<SimpleBitmapGlyph> SimpleBitmapGlyphPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SIMPLE_BITMAP_GLYPH_H_

View File

@ -1,126 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/bitmap/small_glyph_metrics.h"
namespace sfntly {
/******************************************************************************
* SmallGlyphMetrics class
******************************************************************************/
SmallGlyphMetrics::SmallGlyphMetrics(ReadableFontData* data)
: GlyphMetrics(data) {
}
SmallGlyphMetrics::~SmallGlyphMetrics() {
}
int32_t SmallGlyphMetrics::Height() {
return data_->ReadByte(Offset::kHeight);
}
int32_t SmallGlyphMetrics::Width() {
return data_->ReadByte(Offset::kWidth);
}
int32_t SmallGlyphMetrics::BearingX() {
return data_->ReadByte(Offset::kBearingX);
}
int32_t SmallGlyphMetrics::BearingY() {
return data_->ReadByte(Offset::kBearingY);
}
int32_t SmallGlyphMetrics::Advance() {
return data_->ReadByte(Offset::kAdvance);
}
/******************************************************************************
* SmallGlyphMetrics::Builder class
******************************************************************************/
SmallGlyphMetrics::Builder::Builder(WritableFontData* data)
: GlyphMetrics::Builder(data) {
}
SmallGlyphMetrics::Builder::Builder(ReadableFontData* data)
: GlyphMetrics::Builder(data) {
}
SmallGlyphMetrics::Builder::~Builder() {
}
int32_t SmallGlyphMetrics::Builder::Height() {
return InternalReadData()->ReadByte(Offset::kHeight);
}
void SmallGlyphMetrics::Builder::SetHeight(byte_t height) {
InternalWriteData()->WriteByte(Offset::kHeight, height);
}
int32_t SmallGlyphMetrics::Builder::Width() {
return InternalReadData()->ReadByte(Offset::kWidth);
}
void SmallGlyphMetrics::Builder::SetWidth(byte_t width) {
InternalWriteData()->WriteByte(Offset::kWidth, width);
}
int32_t SmallGlyphMetrics::Builder::BearingX() {
return InternalReadData()->ReadByte(Offset::kBearingX);
}
void SmallGlyphMetrics::Builder::SetBearingX(byte_t bearing) {
InternalWriteData()->WriteByte(Offset::kBearingX, bearing);
}
int32_t SmallGlyphMetrics::Builder::BearingY() {
return InternalReadData()->ReadByte(Offset::kBearingY);
}
void SmallGlyphMetrics::Builder::SetBearingY(byte_t bearing) {
InternalWriteData()->WriteByte(Offset::kBearingY, bearing);
}
int32_t SmallGlyphMetrics::Builder::Advance() {
return InternalReadData()->ReadByte(Offset::kAdvance);
}
void SmallGlyphMetrics::Builder::SetAdvance(byte_t advance) {
InternalWriteData()->WriteByte(Offset::kAdvance, advance);
}
CALLER_ATTACH FontDataTable*
SmallGlyphMetrics::Builder::SubBuildTable(ReadableFontData* data) {
SmallGlyphMetricsPtr output = new SmallGlyphMetrics(data);
return output.Detach();
}
void SmallGlyphMetrics::Builder::SubDataSet() {
// NOP.
}
int32_t SmallGlyphMetrics::Builder::SubDataSizeToSerialize() {
return 0;
}
bool SmallGlyphMetrics::Builder::SubReadyToSerialize() {
return false;
}
int32_t SmallGlyphMetrics::Builder::SubSerialize(WritableFontData* new_data) {
return Data()->CopyTo(new_data);
}
} // namespace sfntly

View File

@ -1,79 +0,0 @@
/*
* 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_TABLE_BITMAP_SMALL_GLYPH_METRICS_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SMALL_GLYPH_METRICS_H_
#include "sfntly/port/refcount.h"
#include "sfntly/table/bitmap/glyph_metrics.h"
namespace sfntly {
class SmallGlyphMetrics : public GlyphMetrics,
public RefCounted<SmallGlyphMetrics> {
public:
struct Offset {
enum {
kMetricsLength = 5,
kHeight = 0,
kWidth = 1,
kBearingX = 2,
kBearingY = 3,
kAdvance = 4,
};
};
class Builder : public GlyphMetrics::Builder,
public RefCounted<Builder> {
public:
// Constructor scope altered to public because C++ does not allow base
// class to instantiate derived class with protected constructors.
explicit Builder(WritableFontData* data);
explicit Builder(ReadableFontData* data);
virtual ~Builder();
int32_t Height();
void SetHeight(byte_t height);
int32_t Width();
void SetWidth(byte_t width);
int32_t BearingX();
void SetBearingX(byte_t bearing);
int32_t BearingY();
void SetBearingY(byte_t bearing);
int32_t Advance();
void SetAdvance(byte_t advance);
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
virtual int32_t SubDataSizeToSerialize();
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
};
explicit SmallGlyphMetrics(ReadableFontData* data);
virtual ~SmallGlyphMetrics();
int32_t Height();
int32_t Width();
int32_t BearingX();
int32_t BearingY();
int32_t Advance();
};
typedef Ptr<SmallGlyphMetrics> SmallGlyphMetricsPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SMALL_GLYPH_METRICS_H_

View File

@ -1,70 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/byte_array_table_builder.h"
namespace sfntly {
ByteArrayTableBuilder::~ByteArrayTableBuilder() {}
int32_t ByteArrayTableBuilder::ByteValue(int32_t index) {
ReadableFontDataPtr data = InternalReadData();
if (data == NULL) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("No font data for the table");
#endif
return -1;
}
return data->ReadByte(index);
}
void ByteArrayTableBuilder::SetByteValue(int32_t index, byte_t b) {
WritableFontDataPtr data = InternalWriteData();
if (data == NULL) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("No font data for the table");
#endif
return;
}
data->WriteByte(index, b);
}
int32_t ByteArrayTableBuilder::ByteCount() {
ReadableFontDataPtr data = InternalReadData();
if (data == NULL) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IOException("No font data for the table");
#endif
return 0;
}
return data->Length();
}
ByteArrayTableBuilder::ByteArrayTableBuilder(Header* header,
WritableFontData* data)
: TableBasedTableBuilder(header, data) {
}
ByteArrayTableBuilder::ByteArrayTableBuilder(Header* header,
ReadableFontData* data)
: TableBasedTableBuilder(header, data) {
}
ByteArrayTableBuilder::ByteArrayTableBuilder(Header* header)
: TableBasedTableBuilder(header) {
}
} // namespace sfntly

View File

@ -1,53 +0,0 @@
/*
* 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_TABLE_BYTE_ARRAY_TABLE_BUILDER_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BYTE_ARRAY_TABLE_BUILDER_H_
#include "sfntly/table/table_based_table_builder.h"
namespace sfntly {
// An abstract builder base for byte array based tables.
class ByteArrayTableBuilder : public TableBasedTableBuilder {
public:
virtual ~ByteArrayTableBuilder();
// Get the byte value at the specified index. The index is relative to the
// start of the table.
// @param index index relative to the start of the table
// @return byte value at the given index
virtual int32_t ByteValue(int32_t index);
// Set the byte value at the specified index. The index is relative to the
// start of the table.
// @param index index relative to the start of the table
// @param b byte value to set
virtual void SetByteValue(int32_t index, byte_t b);
// Get the number of bytes set for this table. It may include padding bytes at
// the end.
virtual int32_t ByteCount();
protected:
ByteArrayTableBuilder(Header* header, WritableFontData* data);
ByteArrayTableBuilder(Header* header, ReadableFontData* data);
explicit ByteArrayTableBuilder(Header* header);
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BYTE_ARRAY_TABLE_BUILDER_H_

File diff suppressed because it is too large Load Diff

View File

@ -1,711 +0,0 @@
/*
* 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_TABLE_CORE_CMAP_TABLE_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_
// type.h needs to be included first because of building issues on Windows
// Type aliases we delcare are defined in other headers and make the build
// fail otherwise.
#include "sfntly/port/type.h"
#include <vector>
#include <map>
#include "sfntly/port/refcount.h"
#include "sfntly/table/subtable.h"
#include "sfntly/table/subtable_container_table.h"
namespace sfntly {
// CMap subtable formats
struct CMapFormat {
enum {
kFormat0 = 0,
kFormat2 = 2,
kFormat4 = 4,
kFormat6 = 6,
kFormat8 = 8,
kFormat10 = 10,
kFormat12 = 12,
kFormat13 = 13,
kFormat14 = 14
};
};
// A CMap table
class CMapTable : public SubTableContainerTable, public RefCounted<CMapTable> {
public:
// CMapTable::CMapId
struct CMapId {
int32_t platform_id;
int32_t encoding_id;
bool operator==(const CMapId& obj) const {
return platform_id == obj.platform_id && encoding_id == obj.encoding_id;
}
};
static CMapId WINDOWS_BMP;
static CMapId WINDOWS_UCS4;
static CMapId MAC_ROMAN;
// CMapTable::CMapIdComparator
class CMapIdComparator {
public:
bool operator()(const CMapId& lhs, const CMapId& rhs) const;
};
// A filter on cmap
// CMapTable::CMapFilter
class CMapFilter {
public:
// Test on whether the cmap is acceptable or not
// @param cmap_id the id of the cmap
// @return true if the cmap is acceptable; false otherwise
virtual bool accept(const CMapId& cmap_id) const = 0;
// Make gcc -Wnon-virtual-dtor happy.
virtual ~CMapFilter() {}
};
// Filters CMaps by CMapId to implement CMapTable::get()
// wanted_id is the CMap we'd like to find.
// We compare the current CMap to it either by equality (==) or using a
// comparator.
// CMapTable::CMapIdFilter
class CMapIdFilter : public CMapFilter {
public:
explicit CMapIdFilter(const CMapId wanted_id);
CMapIdFilter(const CMapId wanted_id,
const CMapIdComparator* comparator);
~CMapIdFilter() {}
virtual bool accept(const CMapId& cmap_id) const;
private:
CMapIdFilter& operator=(const CMapIdFilter& that);
const CMapId wanted_id_;
const CMapIdComparator *comparator_;
};
// The abstract base class for all cmaps.
//
// CMap equality is based on the equality of the (@link {@link CMapId} that
// defines the CMap. In the cmap table for a font there can only be one cmap
// with a given cmap id (pair of platform and encoding ids) no matter what the
// type of the cmap is.
//
// The cmap offers CharacterIterator to allow iteration over
// characters that are mapped by the cmap. This iteration mostly returns the
// characters mapped by the cmap. It will return all characters mapped by the
// cmap to anything but .notdef <b>but</b> it may return some that are not
// mapped or are mapped to .notdef. Various cmap tables provide ranges and
// such to describe characters for lookup but without going the full way to
// mapping to the glyph id it isn't always possible to tell if a character
// will end up with a valid glyph id. So, some of the characters returned from
// the Iterator may still end up pointing to the .notdef glyph. However, the
// number of such characters should be small in most cases with well designed
// cmaps.
class Builder;
class CMap : public SubTable {
public:
// CMapTable::CMap::Builder
class Builder : public SubTable::Builder {
public:
virtual ~Builder();
CALLER_ATTACH static Builder*
GetBuilder(ReadableFontData* data,
int32_t offset,
const CMapId& cmap_id);
CALLER_ATTACH static Builder*
GetBuilder(int32_t format,
const CMapId& cmap_id);
// Note: yes, an object is returned on stack since it's small enough.
virtual CMapId cmap_id() { return cmap_id_; }
virtual int32_t platform_id() { return cmap_id_.platform_id; }
virtual int32_t encoding_id() { return cmap_id_.encoding_id; }
virtual int32_t format() { return format_; }
virtual int32_t language() { return language_; }
virtual void set_language(int32_t language) { language_ = language; }
protected:
Builder(ReadableFontData* data,
int32_t format,
const CMapId& cmap_id);
Builder(WritableFontData* data,
int32_t format,
const CMapId& cmap_id);
virtual int32_t SubSerialize(WritableFontData* new_data);
virtual bool SubReadyToSerialize();
virtual int32_t SubDataSizeToSerialize();
virtual void SubDataSet();
private:
int32_t format_;
CMapId cmap_id_;
int32_t language_;
friend class CMapTable::Builder;
};
// Abstract CMap character iterator
// The fully qualified name is CMapTable::CMap::CharacterIterator
class CharacterIterator {
public:
virtual ~CharacterIterator() {}
virtual bool HasNext() = 0;
// Returns -1 if there are no more characters to iterate through
// and exceptions are turned off
virtual int32_t Next() = 0;
protected:
// Use the CMap::Iterator method below instead of directly requesting
// a CharacterIterator.
CharacterIterator() {}
};
CMap(ReadableFontData* data, int32_t format, const CMapId& cmap_id);
virtual ~CMap();
virtual CMap::CharacterIterator* Iterator() = 0;
virtual int32_t format() { return format_; }
virtual CMapId cmap_id() { return cmap_id_; }
virtual int32_t platform_id() { return cmap_id_.platform_id; }
virtual int32_t encoding_id() { return cmap_id_.encoding_id; }
// Get the language of the cmap.
//
// Note on the language field in 'cmap' subtables: The language field must
// be set to zero for all cmap subtables whose platform IDs are other than
// Macintosh (platform ID 1). For cmap subtables whose platform IDs are
// Macintosh, set this field to the Macintosh language ID of the cmap
// subtable plus one, or to zero if the cmap subtable is not
// language-specific. For example, a Mac OS Turkish cmap subtable must set
// this field to 18, since the Macintosh language ID for Turkish is 17. A
// Mac OS Roman cmap subtable must set this field to 0, since Mac OS Roman
// is not a language-specific encoding.
//
// @return the language id
virtual int32_t Language() = 0;
// Gets the glyph id for the character code provided.
// The character code provided must be in the encoding used by the cmap
// table.
virtual int32_t GlyphId(int32_t character) = 0;
private:
int32_t format_;
CMapId cmap_id_;
};
typedef Ptr<CMap> CMapPtr;
typedef Ptr<CMap::Builder> CMapBuilderPtr;
typedef std::map<CMapId, CMapBuilderPtr, CMapIdComparator> CMapBuilderMap;
// A cmap format 0 sub table
class CMapFormat0 : public CMap, public RefCounted<CMapFormat0> {
public:
// The fully qualified name is CMapTable::CMapFormat0::Builder
class Builder : public CMap::Builder,
public RefCounted<Builder> {
public:
CALLER_ATTACH static Builder* NewInstance(ReadableFontData* data,
int32_t offset,
const CMapId& cmap_id);
CALLER_ATTACH static Builder* NewInstance(WritableFontData* data,
int32_t offset,
const CMapId& cmap_id);
CALLER_ATTACH static Builder* NewInstance(const CMapId& cmap_id);
virtual ~Builder();
protected:
virtual CALLER_ATTACH FontDataTable*
SubBuildTable(ReadableFontData* data);
private:
// When creating a new CMapFormat0 Builder, use NewInstance instead of
// the constructors! This avoids a memory leak when slicing the FontData.
Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id);
Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id);
Builder(const CMapId& cmap_id);
};
// The fully qualified name is CMapTable::CMapFormat0::CharacterIterator
class CharacterIterator : public CMap::CharacterIterator {
public:
virtual ~CharacterIterator();
virtual bool HasNext();
virtual int32_t Next();
private:
CharacterIterator(int32_t start, int32_t end);
friend class CMapFormat0;
int32_t character_, max_character_;
};
virtual ~CMapFormat0();
virtual int32_t Language();
virtual int32_t GlyphId(int32_t character);
CMap::CharacterIterator* Iterator();
private:
CMapFormat0(ReadableFontData* data, const CMapId& cmap_id);
};
// A cmap format 2 sub table
// The format 2 cmap is used for multi-byte encodings such as SJIS,
// EUC-JP/KR/CN, Big5, etc.
class CMapFormat2 : public CMap, public RefCounted<CMapFormat2> {
public:
// CMapTable::CMapFormat2::Builder
class Builder : public CMap::Builder,
public RefCounted<Builder> {
public:
Builder(ReadableFontData* data,
int32_t offset,
const CMapId& cmap_id);
Builder(WritableFontData* data,
int32_t offset,
const CMapId& cmap_id);
virtual ~Builder();
protected:
virtual CALLER_ATTACH FontDataTable*
SubBuildTable(ReadableFontData* data);
};
// CMapTable::CMapFormat2::CharacterIterator
class CharacterIterator : public CMap::CharacterIterator {
public:
virtual ~CharacterIterator();
virtual bool hasNext();
virtual int32_t next();
private:
CharacterIterator();
};
virtual int32_t Language();
virtual int32_t GlyphId(int32_t character);
// Returns how many bytes would be consumed by a lookup of this character
// with this cmap. This comes about because the cmap format 2 table is
// designed around multi-byte encodings such as SJIS, EUC-JP, Big5, etc.
// return the number of bytes consumed from this "character" - either 1 or 2
virtual int32_t BytesConsumed(int32_t character);
virtual ~CMapFormat2();
private:
CMapFormat2(ReadableFontData* data, const CMapId& cmap_id);
int32_t SubHeaderOffset(int32_t sub_header_index);
int32_t FirstCode(int32_t sub_header_index);
int32_t EntryCount(int32_t sub_header_index);
int32_t IdRangeOffset(int32_t sub_header_index);
int32_t IdDelta(int32_t sub_header_index);
CMap::CharacterIterator* Iterator();
};
// CMapTable::CMapFormat4
class CMapFormat4 : public CMap,
public RefCounted<CMapFormat4> {
public:
// CMapTable::CMapFormat4::Builder
class Builder : public CMap::Builder,
public RefCounted<Builder> {
public:
// CMapTable::CMapFormat4::Builder::Segment
class Segment : public RefCounted<Segment> {
public:
Segment();
explicit Segment(Segment* other);
Segment(int32_t start_count,
int32_t end_count,
int32_t id_delta,
int32_t id_range_offset);
~Segment();
// @return the startCount
int32_t start_count();
// @param startCount the startCount to set
void set_start_count(int32_t start_count);
// @return the endCount
int32_t end_count();
// @param endcount the endCount to set
void set_end_count(int32_t end_count);
// @return the idDelta
int32_t id_delta();
// @param idDelta the idDelta to set
void set_id_delta(int32_t id_delta);
// @return the idRangeOffset
int32_t id_range_offset();
// @param idRangeOffset the idRangeOffset to set
void set_id_range_offset(int32_t id_range_offset);
static CALLER_ATTACH
std::vector<Ptr<Segment> >*
DeepCopy(std::vector<Ptr<Segment> >* original);
private:
int32_t start_count_;
int32_t end_count_;
int32_t id_delta_;
int32_t id_range_offset_;
};
typedef std::vector<Ptr<Segment> > SegmentList;
static CALLER_ATTACH Builder* NewInstance(WritableFontData* data,
int32_t offset,
const CMapId& cmap_id);
static CALLER_ATTACH Builder* NewInstance(ReadableFontData* data,
int32_t offset,
const CMapId& cmap_id);
static CALLER_ATTACH Builder* NewInstance(const CMapId& cmap_id);
virtual ~Builder();
SegmentList* segments();
void set_segments(SegmentList* segments);
IntegerList* glyph_id_array();
void set_glyph_id_array(IntegerList* glyph_id_array);
protected:
Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id);
Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id);
Builder(SegmentList* segments, IntegerList* glyph_id_array,
const CMapId& cmap_id);
explicit Builder(const CMapId& cmap_id);
virtual CALLER_ATTACH FontDataTable* SubBuildTable(
ReadableFontData* data);
virtual void SubDataSet();
virtual int32_t SubDataSizeToSerialize();
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
private:
void Initialize(ReadableFontData* data);
SegmentList segments_;
IntegerList glyph_id_array_;
};
CMap::CharacterIterator* Iterator();
// CMapTable::CMapFormat4::CharacterIterator
class CharacterIterator : public CMap::CharacterIterator {
public:
bool HasNext();
int32_t Next();
virtual ~CharacterIterator() {}
private:
explicit CharacterIterator(CMapFormat4 *parent);
friend CMap::CharacterIterator* CMapFormat4::Iterator();
CMapFormat4* parent_;
int32_t segment_index_;
int32_t first_char_in_segment_;
int32_t last_char_in_segment_;
int32_t next_char_;
bool next_char_set_;
};
virtual int32_t GlyphId(int32_t character);
// Lower level glyph code retrieval that requires processing the Format 4
// segments to use.
// @param segment the cmap segment
// @param startCode the start code for the segment
// @param character the character to be looked up
// @return the glyph id for the character; CMapTable.NOTDEF if not found
int32_t RetrieveGlyphId(int32_t segment,
int32_t start_count,
int32_t character);
virtual int32_t Language();
// Get the count of the number of segments in this cmap.
// @return the number of segments
int32_t seg_count();
int32_t Length();
// Get the start code for a segment.
// @param segment the segment in the lookup table
// @return the start code for a segment
int32_t StartCode(int32_t segment);
// Get the end code for a segment.
// @param segment the segment in the look up table
// @return the end code for the segment
int32_t EndCode(int32_t segment);
// Get the id delta for a segment
// @param segment the segment in the look up table
// @return the id delta for the segment
int32_t IdDelta(int32_t segment);
// Get the id range offset for a segment
// @param segment the segment in the look up table
// @return the id range offset for the segment
int32_t IdRangeOffset(int32_t segment);
// Get the location of the id range offset for a segment
// @param segment the segment in the look up table
// @return the location of the id range offset for the segment
int32_t IdRangeOffsetLocation(int32_t segment);
// Declared above to allow friending inside CharacterIterator class.
// CMap::CharacterIterator* Iterator();
virtual ~CMapFormat4();
protected:
CMapFormat4(ReadableFontData* data, const CMapId& cmap_id);
private:
static int32_t Language(ReadableFontData* data);
static int32_t Length(ReadableFontData* data);
static int32_t SegCount(ReadableFontData* data);
static int32_t StartCode(ReadableFontData* data,
int32_t seg_count,
int32_t index);
static int32_t StartCodeOffset(int32_t seg_count);
static int32_t EndCode(ReadableFontData* data,
int32_t seg_count,
int32_t index);
static int32_t IdDelta(ReadableFontData* data,
int32_t seg_count,
int32_t index);
static int32_t IdDeltaOffset(int32_t seg_count);
static int32_t IdRangeOffset(ReadableFontData* data,
int32_t seg_count,
int32_t index);
static int32_t IdRangeOffsetOffset(int32_t seg_count);
static int32_t GlyphIdArrayOffset(int32_t seg_count);
// Refactored void to bool to work without exceptions.
bool IsValidIndex(int32_t segment);
int32_t GlyphIdArray(int32_t index);
int32_t seg_count_;
int32_t start_code_offset_;
int32_t end_code_offset_;
int32_t id_delta_offset_;
int32_t id_range_offset_offset_;
int32_t glyph_id_array_offset_;
};
// CMapTable::Builder
class Builder : public SubTableContainerTable::Builder,
public RefCounted<Builder> {
public:
// Constructor scope is public because C++ does not allow base class to
// instantiate derived class with protected constructors.
Builder(Header* header, WritableFontData* data);
Builder(Header* header, ReadableFontData* data);
virtual ~Builder();
virtual int32_t SubSerialize(WritableFontData* new_data);
virtual bool SubReadyToSerialize();
virtual int32_t SubDataSizeToSerialize();
virtual void SubDataSet();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
static CALLER_ATTACH Builder* CreateBuilder(Header* header,
WritableFontData* data);
CMap::Builder* NewCMapBuilder(const CMapId& cmap_id,
ReadableFontData* data);
// Create a new empty CMapBuilder of the type specified in the id.
CMap::Builder* NewCMapBuilder(int32_t format, const CMapId& cmap_id);
CMap::Builder* CMapBuilder(const CMapId& cmap_id);
int32_t NumCMaps();
void SetVersion(int32_t version);
CMapBuilderMap* GetCMapBuilders();
protected:
static CALLER_ATTACH CMap::Builder* CMapBuilder(ReadableFontData* data,
int32_t index);
private:
void Initialize(ReadableFontData* data);
static int32_t NumCMaps(ReadableFontData* data);
int32_t version_;
CMapBuilderMap cmap_builders_;
};
typedef Ptr<Builder> CMapTableBuilderPtr;
class CMapIterator {
public:
// If filter is NULL, filter through all tables.
CMapIterator(CMapTable* table, const CMapFilter* filter);
bool HasNext();
CMap* Next();
private:
int32_t table_index_;
const CMapFilter* filter_;
CMapTable* table_;
};
// Make a CMapId from a platform_id, encoding_id pair
static CMapId NewCMapId(int32_t platform_id, int32_t encoding_id);
// Make a CMapId from another CMapId
static CMapId NewCMapId(const CMapId& obj);
// Get the CMap with the specified parameters if it exists.
// Returns NULL otherwise.
CALLER_ATTACH CMap* GetCMap(const int32_t index);
CALLER_ATTACH CMap* GetCMap(const int32_t platform_id,
const int32_t encoding_id);
CALLER_ATTACH CMap* GetCMap(const CMapId GetCMap_id);
// Get the table version.
virtual int32_t Version();
// Get the number of cmaps within the CMap table.
virtual int32_t NumCMaps();
// Get the cmap id for the cmap with the given index.
// Note: yes, an object is returned on stack since it's small enough.
// This function is renamed from cmapId to GetCMapId().
virtual CMapId GetCMapId(int32_t index);
virtual int32_t PlatformId(int32_t index);
virtual int32_t EncodingId(int32_t index);
// Get the offset in the table data for the cmap table with the given index.
// The offset is from the beginning of the table.
virtual int32_t Offset(int32_t index);
virtual ~CMapTable();
static const int32_t NOTDEF;
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 {
kVersion = 0,
kNumTables = 2,
kEncodingRecordStart = 4,
// offsets relative to the encoding record
kEncodingRecordPlatformId = 0,
kEncodingRecordEncodingId = 2,
kEncodingRecordOffset = 4,
kEncodingRecordSize = 8,
kFormat = 0,
// Format 0: Byte encoding table
kFormat0Format = 0,
kFormat0Length = 2,
kFormat0Language = 4,
kFormat0GlyphIdArray = 6,
// Format 2: High-byte mapping through table
kFormat2Format = 0,
kFormat2Length = 2,
kFormat2Language = 4,
kFormat2SubHeaderKeys = 6,
kFormat2SubHeaders = 518,
// offset relative to the subHeader structure
kFormat2SubHeader_firstCode = 0,
kFormat2SubHeader_entryCount = 2,
kFormat2SubHeader_idDelta = 4,
kFormat2SubHeader_idRangeOffset = 6,
kFormat2SubHeader_structLength = 8,
// Format 4: Segment mapping to delta values
kFormat4Format = 0,
kFormat4Length = 2,
kFormat4Language = 4,
kFormat4SegCountX2 = 6,
kFormat4SearchRange = 8,
kFormat4EntrySelector = 10,
kFormat4RangeShift = 12,
kFormat4EndCount = 14,
kFormat4FixedSize = 16,
// format 6: Trimmed table mapping
kFormat6Format = 0,
kFormat6Length = 2,
kFormat6Language = 4,
kFormat6FirstCode = 6,
kFormat6EntryCount = 8,
kFormat6GlyphIdArray = 10,
// Format 8: mixed 16-bit and 32-bit coverage
kFormat8Format = 0,
kFormat8Length = 4,
kFormat8Language = 8,
kFormat8Is32 = 12,
kFormat8nGroups204 = 8204,
kFormat8Groups208 = 8208,
// offset relative to the group structure
kFormat8Group_startCharCode = 0,
kFormat8Group_endCharCode = 4,
kFormat8Group_startGlyphId = 8,
kFormat8Group_structLength = 12,
// Format 10: Trimmed array
kFormat10Format = 0,
kFormat10Length = 4,
kFormat10Language = 8,
kFormat10StartCharCode = 12,
kFormat10NumChars = 16,
kFormat10Glyphs0 = 20,
// Format 12: Segmented coverage
kFormat12Format = 0,
kFormat12Length = 4,
kFormat12Language = 8,
kFormat12nGroups = 12,
kFormat12Groups = 16,
kFormat12Groups_structLength = 12,
// offsets within the group structure
kFormat12_startCharCode = 0,
kFormat12_endCharCode = 4,
kFormat12_startGlyphId = 8,
// Format 13: Last Resort Font
kFormat13Format = 0,
kFormat13Length = 4,
kFormat13Language = 8,
kFormat13nGroups = 12,
kFormat13Groups = 16,
kFormat13Groups_structLength = 12,
// offsets within the group structure
kFormat13_startCharCode = 0,
kFormat13_endCharCode = 4,
kFormat13_glyphId = 8,
// Format 14: Unicode Variation Sequences
kFormat14Format = 0,
kFormat14Length = 2,
// TODO(stuartg): finish tables
// Default UVS Table
// Non-default UVS Table
kLast = -1
};
};
CMapTable(Header* header, ReadableFontData* data);
// Get the offset in the table data for the encoding record for the cmap with
// the given index. The offset is from the beginning of the table.
static int32_t OffsetForEncodingRecord(int32_t index);
};
typedef std::vector<CMapTable::CMapId> CMapIdList;
typedef Ptr<CMapTable> CMapTablePtr;
typedef std::vector<Ptr<CMapTable::CMapFormat4::Builder::Segment> > SegmentList;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_

View File

@ -1,265 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/core/font_header_table.h"
namespace sfntly {
/******************************************************************************
* FontHeaderTable class
******************************************************************************/
FontHeaderTable::~FontHeaderTable() {}
int32_t FontHeaderTable::TableVersion() {
return data_->ReadFixed(Offset::kTableVersion);
}
int32_t FontHeaderTable::FontRevision() {
return data_->ReadFixed(Offset::kFontRevision);
}
int64_t FontHeaderTable::ChecksumAdjustment() {
return data_->ReadULong(Offset::kCheckSumAdjustment);
}
int64_t FontHeaderTable::MagicNumber() {
return data_->ReadULong(Offset::kMagicNumber);
}
int32_t FontHeaderTable::FlagsAsInt() {
return data_->ReadUShort(Offset::kFlags);
}
int32_t FontHeaderTable::UnitsPerEm() {
return data_->ReadUShort(Offset::kUnitsPerEm);
}
int64_t FontHeaderTable::Created() {
return data_->ReadDateTimeAsLong(Offset::kCreated);
}
int64_t FontHeaderTable::Modified() {
return data_->ReadDateTimeAsLong(Offset::kModified);
}
int32_t FontHeaderTable::XMin() {
return data_->ReadUShort(Offset::kXMin);
}
int32_t FontHeaderTable::YMin() {
return data_->ReadUShort(Offset::kYMin);
}
int32_t FontHeaderTable::XMax() {
return data_->ReadUShort(Offset::kXMax);
}
int32_t FontHeaderTable::YMax() {
return data_->ReadUShort(Offset::kYMax);
}
int32_t FontHeaderTable::MacStyleAsInt() {
return data_->ReadUShort(Offset::kMacStyle);
}
int32_t FontHeaderTable::LowestRecPPEM() {
return data_->ReadUShort(Offset::kLowestRecPPEM);
}
int32_t FontHeaderTable::FontDirectionHint() {
return data_->ReadShort(Offset::kFontDirectionHint);
}
int32_t FontHeaderTable::IndexToLocFormat() {
return data_->ReadShort(Offset::kIndexToLocFormat);
}
int32_t FontHeaderTable::GlyphDataFormat() {
return data_->ReadShort(Offset::kGlyphDataFormat);
}
FontHeaderTable::FontHeaderTable(Header* header, ReadableFontData* data)
: Table(header, data) {
IntegerList checksum_ranges;
checksum_ranges.push_back(0);
checksum_ranges.push_back(Offset::kCheckSumAdjustment);
checksum_ranges.push_back(Offset::kMagicNumber);
data_->SetCheckSumRanges(checksum_ranges);
}
/******************************************************************************
* FontHeaderTable::Builder class
******************************************************************************/
FontHeaderTable::Builder::Builder(Header* header, WritableFontData* data)
: TableBasedTableBuilder(header, data) {
}
FontHeaderTable::Builder::Builder(Header* header, ReadableFontData* data)
: TableBasedTableBuilder(header, data) {
}
FontHeaderTable::Builder::~Builder() {}
CALLER_ATTACH FontDataTable* FontHeaderTable::Builder::SubBuildTable(
ReadableFontData* data) {
FontDataTablePtr table = new FontHeaderTable(header(), data);
return table.Detach();
}
int32_t FontHeaderTable::Builder::TableVersion() {
return down_cast<FontHeaderTable*>(GetTable())->TableVersion();
}
void FontHeaderTable::Builder::SetTableVersion(int32_t version) {
InternalWriteData()->WriteFixed(Offset::kTableVersion, version);
}
int32_t FontHeaderTable::Builder::FontRevision() {
return down_cast<FontHeaderTable*>(GetTable())->FontRevision();
}
void FontHeaderTable::Builder::SetFontRevision(int32_t revision) {
InternalWriteData()->WriteFixed(Offset::kFontRevision, revision);
}
int64_t FontHeaderTable::Builder::ChecksumAdjustment() {
return down_cast<FontHeaderTable*>(GetTable())->ChecksumAdjustment();
}
void FontHeaderTable::Builder::SetChecksumAdjustment(int64_t adjustment) {
InternalWriteData()->WriteULong(Offset::kCheckSumAdjustment, adjustment);
}
int64_t FontHeaderTable::Builder::MagicNumber() {
return down_cast<FontHeaderTable*>(GetTable())->MagicNumber();
}
void FontHeaderTable::Builder::SetMagicNumber(int64_t magic_number) {
InternalWriteData()->WriteULong(Offset::kMagicNumber, magic_number);
}
int32_t FontHeaderTable::Builder::FlagsAsInt() {
return down_cast<FontHeaderTable*>(GetTable())->FlagsAsInt();
}
void FontHeaderTable::Builder::SetFlagsAsInt(int32_t flags) {
InternalWriteData()->WriteUShort(Offset::kFlags, flags);
}
int32_t FontHeaderTable::Builder::UnitsPerEm() {
return down_cast<FontHeaderTable*>(GetTable())->UnitsPerEm();
}
void FontHeaderTable::Builder::SetUnitsPerEm(int32_t units) {
InternalWriteData()->WriteUShort(Offset::kUnitsPerEm, units);
}
int64_t FontHeaderTable::Builder::Created() {
return down_cast<FontHeaderTable*>(GetTable())->Created();
}
void FontHeaderTable::Builder::SetCreated(int64_t date) {
InternalWriteData()->WriteDateTime(Offset::kCreated, date);
}
int64_t FontHeaderTable::Builder::Modified() {
return down_cast<FontHeaderTable*>(GetTable())->Modified();
}
void FontHeaderTable::Builder::SetModified(int64_t date) {
InternalWriteData()->WriteDateTime(Offset::kModified, date);
}
int32_t FontHeaderTable::Builder::XMin() {
return down_cast<FontHeaderTable*>(GetTable())->XMin();
}
void FontHeaderTable::Builder::SetXMin(int32_t xmin) {
InternalWriteData()->WriteShort(Offset::kXMin, xmin);
}
int32_t FontHeaderTable::Builder::YMin() {
return down_cast<FontHeaderTable*>(GetTable())->YMin();
}
void FontHeaderTable::Builder::SetYMin(int32_t ymin) {
InternalWriteData()->WriteShort(Offset::kYMin, ymin);
}
int32_t FontHeaderTable::Builder::XMax() {
return down_cast<FontHeaderTable*>(GetTable())->XMax();
}
void FontHeaderTable::Builder::SetXMax(int32_t xmax) {
InternalWriteData()->WriteShort(Offset::kXMax, xmax);
}
int32_t FontHeaderTable::Builder::YMax() {
return down_cast<FontHeaderTable*>(GetTable())->YMax();
}
void FontHeaderTable::Builder::SetYMax(int32_t ymax) {
InternalWriteData()->WriteShort(Offset::kYMax, ymax);
}
int32_t FontHeaderTable::Builder::MacStyleAsInt() {
return down_cast<FontHeaderTable*>(GetTable())->MacStyleAsInt();
}
void FontHeaderTable::Builder::SetMacStyleAsInt(int32_t style) {
InternalWriteData()->WriteUShort(Offset::kMacStyle, style);
}
int32_t FontHeaderTable::Builder::LowestRecPPEM() {
return down_cast<FontHeaderTable*>(GetTable())->LowestRecPPEM();
}
void FontHeaderTable::Builder::SetLowestRecPPEM(int32_t size) {
InternalWriteData()->WriteUShort(Offset::kLowestRecPPEM, size);
}
int32_t FontHeaderTable::Builder::FontDirectionHint() {
return down_cast<FontHeaderTable*>(GetTable())->FontDirectionHint();
}
void FontHeaderTable::Builder::SetFontDirectionHint(int32_t hint) {
InternalWriteData()->WriteShort(Offset::kFontDirectionHint, hint);
}
int32_t FontHeaderTable::Builder::IndexToLocFormat() {
return down_cast<FontHeaderTable*>(GetTable())->IndexToLocFormat();
}
void FontHeaderTable::Builder::SetIndexToLocFormat(int32_t format) {
InternalWriteData()->WriteShort(Offset::kIndexToLocFormat, format);
}
int32_t FontHeaderTable::Builder::GlyphDataFormat() {
return down_cast<FontHeaderTable*>(GetTable())->GlyphDataFormat();
}
void FontHeaderTable::Builder::SetGlyphDataFormat(int32_t format) {
InternalWriteData()->WriteShort(Offset::kGlyphDataFormat, format);
}
CALLER_ATTACH FontHeaderTable::Builder*
FontHeaderTable::Builder::CreateBuilder(Header* header,
WritableFontData* data) {
Ptr<FontHeaderTable::Builder> builder;
builder = new FontHeaderTable::Builder(header, data);
return builder.Detach();
}
} // namespace sfntly

View File

@ -1,168 +0,0 @@
/*
* 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_TABLE_CORE_FONT_HEADER_TABLE_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_FONT_HEADER_TABLE_H_
#include "sfntly/table/table.h"
#include "sfntly/table/table_based_table_builder.h"
namespace sfntly {
struct IndexToLocFormat {
enum {
kShortOffset = 0,
kLongOffset = 1
};
};
struct FontDirectionHint {
enum {
kFullyMixed = 0,
kOnlyStrongLTR = 1,
kStrongLTRAndNeutral = 2,
kOnlyStrongRTL = -1,
kStrongRTLAndNeutral = -2
};
};
class FontHeaderTable : public Table, public RefCounted<FontHeaderTable> {
public:
class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
public:
// Constructor scope altered to public because C++ does not allow base
// class to instantiate derived class with protected constructors.
Builder(Header* header, WritableFontData* data);
Builder(Header* header, ReadableFontData* data);
virtual ~Builder();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual int32_t TableVersion();
virtual void SetTableVersion(int32_t version);
virtual int32_t FontRevision();
virtual void SetFontRevision(int32_t revision);
virtual int64_t ChecksumAdjustment();
virtual void SetChecksumAdjustment(int64_t adjustment);
virtual int64_t MagicNumber();
virtual void SetMagicNumber(int64_t magic_number);
virtual int32_t FlagsAsInt();
virtual void SetFlagsAsInt(int32_t flags);
// TODO(arthurhsu): IMPLEMENT EnumSet<Flags> Flags()
// TODO(arthurhsu): IMPLEMENT setFlags(EnumSet<Flags> flags)
virtual int32_t UnitsPerEm();
virtual void SetUnitsPerEm(int32_t units);
virtual int64_t Created();
virtual void SetCreated(int64_t date);
virtual int64_t Modified();
virtual void SetModified(int64_t date);
virtual int32_t XMin();
virtual void SetXMin(int32_t xmin);
virtual int32_t YMin();
virtual void SetYMin(int32_t ymin);
virtual int32_t XMax();
virtual void SetXMax(int32_t xmax);
virtual int32_t YMax();
virtual void SetYMax(int32_t ymax);
virtual int32_t MacStyleAsInt();
virtual void SetMacStyleAsInt(int32_t style);
// TODO(arthurhsu): IMPLEMENT EnumSet<MacStyle> macStyle()
// TODO(arthurhsu): IMPLEMENT setMacStyle(EnumSet<MacStyle> style)
virtual int32_t LowestRecPPEM();
virtual void SetLowestRecPPEM(int32_t size);
virtual int32_t FontDirectionHint();
virtual void SetFontDirectionHint(int32_t hint);
virtual int32_t IndexToLocFormat();
virtual void SetIndexToLocFormat(int32_t format);
virtual int32_t GlyphDataFormat();
virtual void SetGlyphDataFormat(int32_t format);
static CALLER_ATTACH Builder* CreateBuilder(Header* header,
WritableFontData* data);
};
virtual ~FontHeaderTable();
int32_t TableVersion();
int32_t FontRevision();
// Get the checksum adjustment. To compute: set it to 0, sum the entire font
// as ULONG, then store 0xB1B0AFBA - sum.
int64_t ChecksumAdjustment();
// Get the magic number. Set to 0x5F0F3CF5.
int64_t MagicNumber();
// TODO(arthurhsu): IMPLEMENT: EnumSet<Flags>
int32_t FlagsAsInt();
// TODO(arthurhsu): IMPLEMENT: Flags() returning EnumSet<Flags>
int32_t UnitsPerEm();
// Get the created date. Number of seconds since 12:00 midnight, January 1,
// 1904. 64-bit integer.
int64_t Created();
// Get the modified date. Number of seconds since 12:00 midnight, January 1,
// 1904. 64-bit integer.
int64_t Modified();
// Get the x min. For all glyph bounding boxes.
int32_t XMin();
// Get the y min. For all glyph bounding boxes.
int32_t YMin();
// Get the x max. For all glyph bounding boxes.
int32_t XMax();
// Get the y max. For all glyph bounding boxes.
int32_t YMax();
// TODO(arthurhsu): IMPLEMENT: EnumSet<MacStyle>
int32_t MacStyleAsInt();
// TODO(arthurhsu): IMPLEMENT: macStyle() returning EnumSet<MacStyle>
int32_t LowestRecPPEM();
int32_t FontDirectionHint(); // Note: no AsInt() form, already int
int32_t IndexToLocFormat(); // Note: no AsInt() form, already int
int32_t GlyphDataFormat();
private:
struct Offset {
enum {
kTableVersion = 0,
kFontRevision = 4,
kCheckSumAdjustment = 8,
kMagicNumber = 12,
kFlags = 16,
kUnitsPerEm = 18,
kCreated = 20,
kModified = 28,
kXMin = 36,
kYMin = 38,
kXMax = 40,
kYMax = 42,
kMacStyle = 44,
kLowestRecPPEM = 46,
kFontDirectionHint = 48,
kIndexToLocFormat = 50,
kGlyphDataFormat = 52
};
};
FontHeaderTable(Header* header, ReadableFontData* data);
};
typedef Ptr<FontHeaderTable> FontHeaderTablePtr;
typedef Ptr<FontHeaderTable::Builder> FontHeaderTableBuilderPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_FONT_HEADER_TABLE_H_

View File

@ -1,124 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/core/horizontal_device_metrics_table.h"
namespace sfntly {
/******************************************************************************
* HorizontalDeviceMetricsTable class
******************************************************************************/
HorizontalDeviceMetricsTable:: ~HorizontalDeviceMetricsTable() {}
int32_t HorizontalDeviceMetricsTable::Version() {
return data_->ReadUShort(Offset::kVersion);
}
int32_t HorizontalDeviceMetricsTable::NumRecords() {
return data_->ReadShort(Offset::kNumRecords);
}
int32_t HorizontalDeviceMetricsTable::RecordSize() {
return data_->ReadLong(Offset::kSizeDeviceRecord);
}
int32_t HorizontalDeviceMetricsTable::PixelSize(int32_t record_index) {
if (record_index < 0 || record_index >= NumRecords()) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundsException();
#endif
return -1;
}
return data_->ReadUByte(Offset::kRecords + record_index * RecordSize() +
Offset::kDeviceRecordPixelSize);
}
int32_t HorizontalDeviceMetricsTable::MaxWidth(int32_t record_index) {
if (record_index < 0 || record_index >= NumRecords()) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundsException();
#endif
return -1;
}
return data_->ReadUByte(Offset::kRecords + record_index * RecordSize() +
Offset::kDeviceRecordMaxWidth);
}
int32_t HorizontalDeviceMetricsTable::Width(int32_t record_index,
int32_t glyph_num) {
if (record_index < 0 || record_index >= NumRecords() ||
glyph_num < 0 || glyph_num >= num_glyphs_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundsException();
#endif
return -1;
}
return data_->ReadUByte(Offset::kRecords + record_index * RecordSize() +
Offset::kDeviceRecordWidths + glyph_num);
}
HorizontalDeviceMetricsTable::HorizontalDeviceMetricsTable(
Header* header,
ReadableFontData* data,
int32_t num_glyphs)
: Table(header, data), num_glyphs_(num_glyphs) {
}
/******************************************************************************
* HorizontalDeviceMetricsTable::Builder class
******************************************************************************/
HorizontalDeviceMetricsTable::Builder::Builder(Header* header,
WritableFontData* data)
: TableBasedTableBuilder(header, data), num_glyphs_(-1) {
}
HorizontalDeviceMetricsTable::Builder::Builder(Header* header,
ReadableFontData* data)
: TableBasedTableBuilder(header, data), num_glyphs_(-1) {
}
HorizontalDeviceMetricsTable::Builder::~Builder() {}
CALLER_ATTACH FontDataTable*
HorizontalDeviceMetricsTable::Builder::SubBuildTable(ReadableFontData* data) {
FontDataTablePtr table = new HorizontalDeviceMetricsTable(header(), data,
num_glyphs_);
return table.Detach();
}
void HorizontalDeviceMetricsTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
if (num_glyphs < 0) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IllegalArgumentException("Number of glyphs can't be negative.");
#endif
return;
}
num_glyphs_ = num_glyphs;
HorizontalDeviceMetricsTable* table =
down_cast<HorizontalDeviceMetricsTable*>(GetTable());
if (table) {
table->num_glyphs_ = num_glyphs;
}
}
CALLER_ATTACH HorizontalDeviceMetricsTable::Builder*
HorizontalDeviceMetricsTable::Builder::CreateBuilder(Header* header,
WritableFontData* data) {
Ptr<HorizontalDeviceMetricsTable::Builder> builder;
builder = new HorizontalDeviceMetricsTable::Builder(header, data);
return builder.Detach();
}
} // namespace sfntly

View File

@ -1,82 +0,0 @@
/*
* 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_TABLE_CORE_HORIZONTAL_DEVICE_METRICS_TABLE_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_DEVICE_METRICS_TABLE_H_
#include "sfntly/table/table.h"
#include "sfntly/table/table_based_table_builder.h"
namespace sfntly {
// A Horizontal Device Metrics table - 'hdmx'
class HorizontalDeviceMetricsTable
: public Table,
public RefCounted<HorizontalDeviceMetricsTable> {
public:
class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
public:
// Constructor scope altered to public because C++ does not allow base
// class to instantiate derived class with protected constructors.
Builder(Header* header, WritableFontData* data);
Builder(Header* header, ReadableFontData* data);
virtual ~Builder();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
static CALLER_ATTACH Builder* CreateBuilder(Header* header,
WritableFontData* data);
void SetNumGlyphs(int32_t num_glyphs);
private:
int32_t num_glyphs_;
};
virtual ~HorizontalDeviceMetricsTable();
int32_t Version();
int32_t NumRecords();
int32_t RecordSize();
int32_t PixelSize(int32_t record_index);
int32_t MaxWidth(int32_t record_index);
int32_t Width(int32_t record_index, int32_t glyph_num);
private:
struct Offset {
enum {
kVersion = 0,
kNumRecords = 2,
kSizeDeviceRecord = 4,
kRecords = 8,
// Offsets within a device record
kDeviceRecordPixelSize = 0,
kDeviceRecordMaxWidth = 1,
kDeviceRecordWidths = 2,
};
};
HorizontalDeviceMetricsTable(Header* header,
ReadableFontData* data,
int32_t num_glyphs);
int32_t num_glyphs_;
};
typedef Ptr<HorizontalDeviceMetricsTable> HorizontalDeviceMetricsTablePtr;
typedef Ptr<HorizontalDeviceMetricsTable::Builder>
HorizontalDeviceMetricsTableBuilderPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_DEVICE_METRICS_TABLE_H_

View File

@ -1,213 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/core/horizontal_header_table.h"
namespace sfntly {
/******************************************************************************
* HorizontalHeaderTable class
******************************************************************************/
HorizontalHeaderTable:: ~HorizontalHeaderTable() {}
int32_t HorizontalHeaderTable::TableVersion() {
return data_->ReadFixed(Offset::kVersion);
}
int32_t HorizontalHeaderTable::Ascender() {
return data_->ReadShort(Offset::kAscender);
}
int32_t HorizontalHeaderTable::Descender() {
return data_->ReadShort(Offset::kDescender);
}
int32_t HorizontalHeaderTable::LineGap() {
return data_->ReadShort(Offset::kLineGap);
}
int32_t HorizontalHeaderTable::AdvanceWidthMax() {
return data_->ReadUShort(Offset::kAdvanceWidthMax);
}
int32_t HorizontalHeaderTable::MinLeftSideBearing() {
return data_->ReadShort(Offset::kMinLeftSideBearing);
}
int32_t HorizontalHeaderTable::MinRightSideBearing() {
return data_->ReadShort(Offset::kMinRightSideBearing);
}
int32_t HorizontalHeaderTable::XMaxExtent() {
return data_->ReadShort(Offset::kXMaxExtent);
}
int32_t HorizontalHeaderTable::CaretSlopeRise() {
return data_->ReadShort(Offset::kCaretSlopeRise);
}
int32_t HorizontalHeaderTable::CaretSlopeRun() {
return data_->ReadShort(Offset::kCaretSlopeRun);
}
int32_t HorizontalHeaderTable::CaretOffset() {
return data_->ReadShort(Offset::kCaretOffset);
}
int32_t HorizontalHeaderTable::MetricDataFormat() {
return data_->ReadShort(Offset::kMetricDataFormat);
}
int32_t HorizontalHeaderTable::NumberOfHMetrics() {
return data_->ReadUShort(Offset::kNumberOfHMetrics);
}
HorizontalHeaderTable:: HorizontalHeaderTable(Header* header,
ReadableFontData* data)
: Table(header, data) {
}
/******************************************************************************
* HorizontalHeaderTable::Builder class
******************************************************************************/
HorizontalHeaderTable::Builder::Builder(Header* header, WritableFontData* data)
: TableBasedTableBuilder(header, data) {
}
HorizontalHeaderTable::Builder::Builder(Header* header, ReadableFontData* data)
: TableBasedTableBuilder(header, data) {
}
HorizontalHeaderTable::Builder::~Builder() {}
CALLER_ATTACH FontDataTable*
HorizontalHeaderTable::Builder::SubBuildTable(ReadableFontData* data) {
FontDataTablePtr table = new HorizontalHeaderTable(header(), data);
return table.Detach();
}
CALLER_ATTACH HorizontalHeaderTable::Builder*
HorizontalHeaderTable::Builder::CreateBuilder(Header* header,
WritableFontData* data) {
Ptr<HorizontalHeaderTable::Builder> builder;
builder = new HorizontalHeaderTable::Builder(header, data);
return builder.Detach();
}
int32_t HorizontalHeaderTable::Builder::TableVersion() {
return InternalReadData()->ReadFixed(Offset::kVersion);
}
void HorizontalHeaderTable::Builder::SetTableVersion(int32_t version) {
InternalWriteData()->WriteFixed(Offset::kVersion, version);
}
int32_t HorizontalHeaderTable::Builder::Ascender() {
return InternalReadData()->ReadShort(Offset::kAscender);
}
void HorizontalHeaderTable::Builder::SetAscender(int32_t ascender) {
InternalWriteData()->WriteShort(Offset::kVersion, ascender);
}
int32_t HorizontalHeaderTable::Builder::Descender() {
return InternalReadData()->ReadShort(Offset::kDescender);
}
void HorizontalHeaderTable::Builder::SetDescender(int32_t descender) {
InternalWriteData()->WriteShort(Offset::kDescender, descender);
}
int32_t HorizontalHeaderTable::Builder::LineGap() {
return InternalReadData()->ReadShort(Offset::kLineGap);
}
void HorizontalHeaderTable::Builder::SetLineGap(int32_t line_gap) {
InternalWriteData()->WriteShort(Offset::kLineGap, line_gap);
}
int32_t HorizontalHeaderTable::Builder::AdvanceWidthMax() {
return InternalReadData()->ReadUShort(Offset::kAdvanceWidthMax);
}
void HorizontalHeaderTable::Builder::SetAdvanceWidthMax(int32_t value) {
InternalWriteData()->WriteUShort(Offset::kAdvanceWidthMax, value);
}
int32_t HorizontalHeaderTable::Builder::MinLeftSideBearing() {
return InternalReadData()->ReadShort(Offset::kMinLeftSideBearing);
}
void HorizontalHeaderTable::Builder::SetMinLeftSideBearing(int32_t value) {
InternalWriteData()->WriteShort(Offset::kMinLeftSideBearing, value);
}
int32_t HorizontalHeaderTable::Builder::MinRightSideBearing() {
return InternalReadData()->ReadShort(Offset::kMinRightSideBearing);
}
void HorizontalHeaderTable::Builder::SetMinRightSideBearing(int32_t value) {
InternalWriteData()->WriteShort(Offset::kMinRightSideBearing, value);
}
int32_t HorizontalHeaderTable::Builder::XMaxExtent() {
return InternalReadData()->ReadShort(Offset::kXMaxExtent);
}
void HorizontalHeaderTable::Builder::SetXMaxExtent(int32_t value) {
InternalWriteData()->WriteShort(Offset::kXMaxExtent, value);
}
int32_t HorizontalHeaderTable::Builder::CaretSlopeRise() {
return InternalReadData()->ReadUShort(Offset::kCaretSlopeRise);
}
void HorizontalHeaderTable::Builder::SetCaretSlopeRise(int32_t value) {
InternalWriteData()->WriteUShort(Offset::kCaretSlopeRise, value);
}
int32_t HorizontalHeaderTable::Builder::CaretSlopeRun() {
return InternalReadData()->ReadUShort(Offset::kCaretSlopeRun);
}
void HorizontalHeaderTable::Builder::SetCaretSlopeRun(int32_t value) {
InternalWriteData()->WriteUShort(Offset::kCaretSlopeRun, value);
}
int32_t HorizontalHeaderTable::Builder::CaretOffset() {
return InternalReadData()->ReadUShort(Offset::kCaretOffset);
}
void HorizontalHeaderTable::Builder::SetCaretOffset(int32_t value) {
InternalWriteData()->WriteUShort(Offset::kCaretOffset, value);
}
int32_t HorizontalHeaderTable::Builder::MetricDataFormat() {
return InternalReadData()->ReadUShort(Offset::kMetricDataFormat);
}
void HorizontalHeaderTable::Builder::SetMetricDataFormat(int32_t value) {
InternalWriteData()->WriteUShort(Offset::kMetricDataFormat, value);
}
int32_t HorizontalHeaderTable::Builder::NumberOfHMetrics() {
return InternalReadData()->ReadUShort(Offset::kNumberOfHMetrics);
}
void HorizontalHeaderTable::Builder::SetNumberOfHMetrics(int32_t value) {
InternalWriteData()->WriteUShort(Offset::kNumberOfHMetrics, value);
}
} // namespace sfntly

View File

@ -1,111 +0,0 @@
/*
* 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_TABLE_CORE_HORIZONTAL_HEADER_TABLE_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_HEADER_TABLE_H_
#include "sfntly/table/table.h"
#include "sfntly/table/table_based_table_builder.h"
namespace sfntly {
// A Horizontal Header table - 'hhea'.
class HorizontalHeaderTable : public Table,
public RefCounted<HorizontalHeaderTable> {
public:
// Builder for a Horizontal Header table - 'hhea'.
class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
public:
// Constructor scope altered to public because C++ does not allow base
// class to instantiate derived class with protected constructors.
Builder(Header* header, WritableFontData* data);
Builder(Header* header, ReadableFontData* data);
virtual ~Builder();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
static CALLER_ATTACH Builder* CreateBuilder(Header* header,
WritableFontData* data);
int32_t TableVersion();
void SetTableVersion(int32_t version);
int32_t Ascender();
void SetAscender(int32_t ascender);
int32_t Descender();
void SetDescender(int32_t descender);
int32_t LineGap();
void SetLineGap(int32_t line_gap);
int32_t AdvanceWidthMax();
void SetAdvanceWidthMax(int32_t value);
int32_t MinLeftSideBearing();
void SetMinLeftSideBearing(int32_t value);
int32_t MinRightSideBearing();
void SetMinRightSideBearing(int32_t value);
int32_t XMaxExtent();
void SetXMaxExtent(int32_t value);
int32_t CaretSlopeRise();
void SetCaretSlopeRise(int32_t value);
int32_t CaretSlopeRun();
void SetCaretSlopeRun(int32_t value);
int32_t CaretOffset();
void SetCaretOffset(int32_t value);
int32_t MetricDataFormat();
void SetMetricDataFormat(int32_t value);
int32_t NumberOfHMetrics();
void SetNumberOfHMetrics(int32_t value);
};
virtual ~HorizontalHeaderTable();
int32_t TableVersion();
int32_t Ascender();
int32_t Descender();
int32_t LineGap();
int32_t AdvanceWidthMax();
int32_t MinLeftSideBearing();
int32_t MinRightSideBearing();
int32_t XMaxExtent();
int32_t CaretSlopeRise();
int32_t CaretSlopeRun();
int32_t CaretOffset();
int32_t MetricDataFormat();
int32_t NumberOfHMetrics();
private:
struct Offset {
enum {
kVersion = 0,
kAscender = 4,
kDescender = 6,
kLineGap = 8,
kAdvanceWidthMax = 10,
kMinLeftSideBearing = 12,
kMinRightSideBearing = 14,
kXMaxExtent = 16,
kCaretSlopeRise = 18,
kCaretSlopeRun = 20,
kCaretOffset = 22,
kMetricDataFormat = 32,
kNumberOfHMetrics = 34,
};
};
HorizontalHeaderTable(Header* header, ReadableFontData* data);
};
typedef Ptr<HorizontalHeaderTable> HorizontalHeaderTablePtr;
typedef Ptr<HorizontalHeaderTable::Builder> HorizontalHeaderTableBuilderPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_HEADER_TABLE_H_

View File

@ -1,138 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/core/horizontal_metrics_table.h"
#include "sfntly/port/exception_type.h"
namespace sfntly {
/******************************************************************************
* HorizontalMetricsTable class
******************************************************************************/
HorizontalMetricsTable::~HorizontalMetricsTable() {}
int32_t HorizontalMetricsTable::NumberOfHMetrics() {
return num_hmetrics_;
}
int32_t HorizontalMetricsTable::NumberOfLSBs() {
return num_glyphs_ - num_hmetrics_;
}
int32_t HorizontalMetricsTable::HMetricAdvanceWidth(int32_t entry) {
if (entry > num_hmetrics_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundException();
#endif
return 0;
}
int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) +
Offset::kHMetricsAdvanceWidth;
return data_->ReadUShort(offset);
}
int32_t HorizontalMetricsTable::HMetricLSB(int32_t entry) {
if (entry > num_hmetrics_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundException();
#endif
return 0;
}
int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) +
Offset::kHMetricsLeftSideBearing;
return data_->ReadShort(offset);
}
int32_t HorizontalMetricsTable::LsbTableEntry(int32_t entry) {
if (entry > num_hmetrics_) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundException();
#endif
return 0;
}
int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) +
Offset::kLeftSideBearingSize;
return data_->ReadShort(offset);
}
int32_t HorizontalMetricsTable::AdvanceWidth(int32_t glyph_id) {
if (glyph_id < num_hmetrics_) {
return HMetricAdvanceWidth(glyph_id);
}
return HMetricAdvanceWidth(glyph_id - num_hmetrics_);
}
int32_t HorizontalMetricsTable::LeftSideBearing(int32_t glyph_id) {
if (glyph_id < num_hmetrics_) {
return HMetricLSB(glyph_id);
}
return LsbTableEntry(glyph_id - num_hmetrics_);
}
HorizontalMetricsTable::HorizontalMetricsTable(Header* header,
ReadableFontData* data,
int32_t num_hmetrics,
int32_t num_glyphs)
: Table(header, data),
num_hmetrics_(num_hmetrics),
num_glyphs_(num_glyphs) {
}
/******************************************************************************
* HorizontalMetricsTable::Builder class
******************************************************************************/
HorizontalMetricsTable::Builder::Builder(Header* header, WritableFontData* data)
: TableBasedTableBuilder(header, data), num_hmetrics_(-1), num_glyphs_(-1) {
}
HorizontalMetricsTable::Builder::Builder(Header* header, ReadableFontData* data)
: TableBasedTableBuilder(header, data), num_hmetrics_(-1), num_glyphs_(-1) {
}
HorizontalMetricsTable::Builder::~Builder() {}
CALLER_ATTACH FontDataTable*
HorizontalMetricsTable::Builder::SubBuildTable(ReadableFontData* data) {
FontDataTablePtr table =
new HorizontalMetricsTable(header(), data, num_hmetrics_, num_glyphs_);
return table.Detach();
}
CALLER_ATTACH HorizontalMetricsTable::Builder*
HorizontalMetricsTable::Builder::CreateBuilder(Header* header,
WritableFontData* data) {
Ptr<HorizontalMetricsTable::Builder> builder;
builder = new HorizontalMetricsTable::Builder(header, data);
return builder.Detach();
}
void HorizontalMetricsTable::Builder::SetNumberOfHMetrics(
int32_t num_hmetrics) {
assert(num_hmetrics >= 0);
num_hmetrics_ = num_hmetrics;
HorizontalMetricsTable* table =
down_cast<HorizontalMetricsTable*>(this->GetTable());
table->num_hmetrics_ = num_hmetrics;
}
void HorizontalMetricsTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
assert(num_glyphs >= 0);
num_glyphs_ = num_glyphs;
HorizontalMetricsTable* table =
down_cast<HorizontalMetricsTable*>(this->GetTable());
table->num_glyphs_ = num_glyphs;
}
} // namespace sfntly

View File

@ -1,87 +0,0 @@
/*
* 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_TABLE_CORE_HORIZONTAL_METRICS_TABLE_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_METRICS_TABLE_H_
#include "sfntly/table/table.h"
#include "sfntly/table/table_based_table_builder.h"
namespace sfntly {
// A Horizontal Metrics table - 'hmtx'.
class HorizontalMetricsTable : public Table,
public RefCounted<HorizontalMetricsTable> {
public:
// Builder for a Horizontal Metrics Table - 'hmtx'.
class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
public:
// Constructor scope altered to public because C++ does not allow base
// class to instantiate derived class with protected constructors.
Builder(Header* header, WritableFontData* data);
Builder(Header* header, ReadableFontData* data);
virtual ~Builder();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
static CALLER_ATTACH Builder* CreateBuilder(Header* header,
WritableFontData* data);
void SetNumberOfHMetrics(int32_t num_hmetrics);
void SetNumGlyphs(int32_t num_glyphs);
private:
int32_t num_hmetrics_;
int32_t num_glyphs_;
};
virtual ~HorizontalMetricsTable();
int32_t NumberOfHMetrics();
int32_t NumberOfLSBs();
int32_t HMetricAdvanceWidth(int32_t entry);
int32_t HMetricLSB(int32_t entry);
int32_t LsbTableEntry(int32_t entry);
int32_t AdvanceWidth(int32_t glyph_id);
int32_t LeftSideBearing(int32_t glyph_id);
private:
struct Offset {
enum {
// hMetrics
kHMetricsStart = 0,
kHMetricsSize = 4,
// Offset within an hMetric
kHMetricsAdvanceWidth = 0,
kHMetricsLeftSideBearing = 2,
kLeftSideBearingSize = 2
};
};
HorizontalMetricsTable(Header* header,
ReadableFontData* data,
int32_t num_hmetrics,
int32_t num_glyphs);
int32_t num_hmetrics_;
int32_t num_glyphs_;
};
typedef Ptr<HorizontalMetricsTable> HorizontalMetricsTablePtr;
typedef Ptr<HorizontalMetricsTable::Builder> HorizontalMetricsTableBuilderPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_METRICS_TABLE_H_

View File

@ -1,240 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/core/maximum_profile_table.h"
namespace sfntly {
/******************************************************************************
* MaximumProfileTable class
******************************************************************************/
MaximumProfileTable::~MaximumProfileTable() {}
int32_t MaximumProfileTable::TableVersion() {
return data_->ReadFixed(Offset::kVersion);
}
int32_t MaximumProfileTable::NumGlyphs() {
return data_->ReadUShort(Offset::kNumGlyphs);
}
int32_t MaximumProfileTable::MaxPoints() {
return data_->ReadUShort(Offset::kMaxPoints);
}
int32_t MaximumProfileTable::MaxContours() {
return data_->ReadUShort(Offset::kMaxContours);
}
int32_t MaximumProfileTable::MaxCompositePoints() {
return data_->ReadUShort(Offset::kMaxCompositePoints);
}
int32_t MaximumProfileTable::MaxCompositeContours() {
return data_->ReadUShort(Offset::kMaxCompositeContours);
}
int32_t MaximumProfileTable::MaxZones() {
return data_->ReadUShort(Offset::kMaxZones);
}
int32_t MaximumProfileTable::MaxTwilightPoints() {
return data_->ReadUShort(Offset::kMaxTwilightPoints);
}
int32_t MaximumProfileTable::MaxStorage() {
return data_->ReadUShort(Offset::kMaxStorage);
}
int32_t MaximumProfileTable::MaxFunctionDefs() {
return data_->ReadUShort(Offset::kMaxFunctionDefs);
}
int32_t MaximumProfileTable::MaxStackElements() {
return data_->ReadUShort(Offset::kMaxStackElements);
}
int32_t MaximumProfileTable::MaxSizeOfInstructions() {
return data_->ReadUShort(Offset::kMaxSizeOfInstructions);
}
int32_t MaximumProfileTable::MaxComponentElements() {
return data_->ReadUShort(Offset::kMaxComponentElements);
}
int32_t MaximumProfileTable::MaxComponentDepth() {
return data_->ReadUShort(Offset::kMaxComponentDepth);
}
MaximumProfileTable::MaximumProfileTable(Header* header,
ReadableFontData* data)
: Table(header, data) {
}
/******************************************************************************
* MaximumProfileTable::Builder class
******************************************************************************/
MaximumProfileTable::Builder::Builder(Header* header, WritableFontData* data)
: TableBasedTableBuilder(header, data) {
}
MaximumProfileTable::Builder::Builder(Header* header, ReadableFontData* data)
: TableBasedTableBuilder(header, data) {
}
MaximumProfileTable::Builder::~Builder() {}
CALLER_ATTACH FontDataTable*
MaximumProfileTable::Builder::SubBuildTable(ReadableFontData* data) {
FontDataTablePtr table = new MaximumProfileTable(header(), data);
return table.Detach();
}
CALLER_ATTACH MaximumProfileTable::Builder*
MaximumProfileTable::Builder::CreateBuilder(Header* header,
WritableFontData* data) {
Ptr<MaximumProfileTable::Builder> builder;
builder = new MaximumProfileTable::Builder(header, data);
return builder.Detach();
}
int32_t MaximumProfileTable::Builder::TableVersion() {
return InternalReadData()->ReadUShort(Offset::kVersion);
}
void MaximumProfileTable::Builder::SetTableVersion(int32_t version) {
InternalWriteData()->WriteUShort(Offset::kVersion, version);
}
int32_t MaximumProfileTable::Builder::NumGlyphs() {
return InternalReadData()->ReadUShort(Offset::kNumGlyphs);
}
void MaximumProfileTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
InternalWriteData()->WriteUShort(Offset::kNumGlyphs, num_glyphs);
}
int32_t MaximumProfileTable::Builder::MaxPoints() {
return InternalReadData()->ReadUShort(Offset::kMaxPoints);
}
void MaximumProfileTable::Builder::SetMaxPoints(int32_t max_points) {
InternalWriteData()->WriteUShort(Offset::kMaxPoints, max_points);
}
int32_t MaximumProfileTable::Builder::MaxContours() {
return InternalReadData()->ReadUShort(Offset::kMaxContours);
}
void MaximumProfileTable::Builder::SetMaxContours(int32_t max_contours) {
InternalWriteData()->WriteUShort(Offset::kMaxContours, max_contours);
}
int32_t MaximumProfileTable::Builder::MaxCompositePoints() {
return InternalReadData()->ReadUShort(Offset::kMaxCompositePoints);
}
void MaximumProfileTable::Builder::SetMaxCompositePoints(
int32_t max_composite_points) {
InternalWriteData()->WriteUShort(Offset::kMaxCompositePoints,
max_composite_points);
}
int32_t MaximumProfileTable::Builder::MaxCompositeContours() {
return InternalReadData()->ReadUShort(Offset::kMaxCompositeContours);
}
void MaximumProfileTable::Builder::SetMaxCompositeContours(
int32_t max_composite_contours) {
InternalWriteData()->WriteUShort(Offset::kMaxCompositeContours,
max_composite_contours);
}
int32_t MaximumProfileTable::Builder::MaxZones() {
return InternalReadData()->ReadUShort(Offset::kMaxZones);
}
void MaximumProfileTable::Builder::SetMaxZones(int32_t max_zones) {
InternalWriteData()->WriteUShort(Offset::kMaxZones, max_zones);
}
int32_t MaximumProfileTable::Builder::MaxTwilightPoints() {
return InternalReadData()->ReadUShort(Offset::kMaxTwilightPoints);
}
void MaximumProfileTable::Builder::SetMaxTwilightPoints(
int32_t max_twilight_points) {
InternalWriteData()->WriteUShort(Offset::kMaxTwilightPoints,
max_twilight_points);
}
int32_t MaximumProfileTable::Builder::MaxStorage() {
return InternalReadData()->ReadUShort(Offset::kMaxStorage);
}
void MaximumProfileTable::Builder::SetMaxStorage(int32_t max_storage) {
InternalWriteData()->WriteUShort(Offset::kMaxStorage, max_storage);
}
int32_t MaximumProfileTable::Builder::MaxFunctionDefs() {
return InternalReadData()->ReadUShort(Offset::kMaxFunctionDefs);
}
void MaximumProfileTable::Builder::SetMaxFunctionDefs(
int32_t max_function_defs) {
InternalWriteData()->WriteUShort(Offset::kMaxFunctionDefs, max_function_defs);
}
int32_t MaximumProfileTable::Builder::MaxStackElements() {
return InternalReadData()->ReadUShort(Offset::kMaxStackElements);
}
void MaximumProfileTable::Builder::SetMaxStackElements(
int32_t max_stack_elements) {
InternalWriteData()->WriteUShort(Offset::kMaxStackElements,
max_stack_elements);
}
int32_t MaximumProfileTable::Builder::MaxSizeOfInstructions() {
return InternalReadData()->ReadUShort(Offset::kMaxSizeOfInstructions);
}
void MaximumProfileTable::Builder::SetMaxSizeOfInstructions(
int32_t max_size_of_instructions) {
InternalWriteData()->WriteUShort(Offset::kMaxSizeOfInstructions,
max_size_of_instructions);
}
int32_t MaximumProfileTable::Builder::MaxComponentElements() {
return InternalReadData()->ReadUShort(Offset::kMaxComponentElements);
}
void MaximumProfileTable::Builder::SetMaxComponentElements(
int32_t max_component_elements) {
InternalWriteData()->WriteUShort(Offset::kMaxComponentElements,
max_component_elements);
}
int32_t MaximumProfileTable::Builder::MaxComponentDepth() {
return InternalReadData()->ReadUShort(Offset::kMaxComponentDepth);
}
void MaximumProfileTable::Builder::SetMaxComponentDepth(
int32_t max_component_depth) {
InternalWriteData()->WriteUShort(Offset::kMaxComponentDepth,
max_component_depth);
}
} // namespace sfntly

View File

@ -1,120 +0,0 @@
/*
* 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_TABLE_CORE_MAXIMUM_PROFILE_TABLE_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_MAXIMUM_PROFILE_TABLE_H_
#include "sfntly/port/refcount.h"
#include "sfntly/table/table.h"
#include "sfntly/table/table_based_table_builder.h"
namespace sfntly {
// A Maximum Profile table - 'maxp'.
class MaximumProfileTable : public Table,
public RefCounted<MaximumProfileTable> {
public:
// Builder for a Maximum Profile table - 'maxp'.
class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
public:
// Constructor scope altered to public because C++ does not allow base
// class to instantiate derived class with protected constructors.
Builder(Header* header, WritableFontData* data);
Builder(Header* header, ReadableFontData* data);
virtual ~Builder();
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
static CALLER_ATTACH Builder* CreateBuilder(Header* header,
WritableFontData* data);
int32_t TableVersion();
void SetTableVersion(int32_t version);
int32_t NumGlyphs();
void SetNumGlyphs(int32_t num_glyphs);
int32_t MaxPoints();
void SetMaxPoints(int32_t max_points);
int32_t MaxContours();
void SetMaxContours(int32_t max_contours);
int32_t MaxCompositePoints();
void SetMaxCompositePoints(int32_t max_composite_points);
int32_t MaxCompositeContours();
void SetMaxCompositeContours(int32_t max_composite_contours);
int32_t MaxZones();
void SetMaxZones(int32_t max_zones);
int32_t MaxTwilightPoints();
void SetMaxTwilightPoints(int32_t max_twilight_points);
int32_t MaxStorage();
void SetMaxStorage(int32_t max_storage);
int32_t MaxFunctionDefs();
void SetMaxFunctionDefs(int32_t max_function_defs);
int32_t MaxStackElements();
void SetMaxStackElements(int32_t max_stack_elements);
int32_t MaxSizeOfInstructions();
void SetMaxSizeOfInstructions(int32_t max_size_of_instructions);
int32_t MaxComponentElements();
void SetMaxComponentElements(int32_t max_component_elements);
int32_t MaxComponentDepth();
void SetMaxComponentDepth(int32_t max_component_depth);
};
virtual ~MaximumProfileTable();
int32_t TableVersion();
int32_t NumGlyphs();
int32_t MaxPoints();
int32_t MaxContours();
int32_t MaxCompositePoints();
int32_t MaxCompositeContours();
int32_t MaxZones();
int32_t MaxTwilightPoints();
int32_t MaxStorage();
int32_t MaxFunctionDefs();
int32_t MaxStackElements();
int32_t MaxSizeOfInstructions();
int32_t MaxComponentElements();
int32_t MaxComponentDepth();
private:
struct Offset {
enum {
// version 0.5 and 1.0
kVersion = 0,
kNumGlyphs = 4,
// version 1.0
kMaxPoints = 6,
kMaxContours = 8,
kMaxCompositePoints = 10,
kMaxCompositeContours = 12,
kMaxZones = 14,
kMaxTwilightPoints = 16,
kMaxStorage = 18,
kMaxFunctionDefs = 20,
kMaxInstructionDefs = 22,
kMaxStackElements = 24,
kMaxSizeOfInstructions = 26,
kMaxComponentElements = 28,
kMaxComponentDepth = 30,
};
};
MaximumProfileTable(Header* header, ReadableFontData* data);
};
typedef Ptr<MaximumProfileTable> MaximumProfileTablePtr;
typedef Ptr<MaximumProfileTable::Builder> MaximumProfileTableBuilderPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_MAXIMUM_PROFILE_TABLE_H_

View File

@ -1,721 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/core/name_table.h"
#include <stdio.h>
#include <string.h>
#include <unicode/unistr.h>
#include "sfntly/font.h"
#include "sfntly/port/exception_type.h"
namespace sfntly {
/******************************************************************************
* NameTable::NameEntryId class
******************************************************************************/
NameTable::NameEntryId::NameEntryId()
: platform_id_(0),
encoding_id_(0),
language_id_(0),
name_id_(0) {
}
NameTable::NameEntryId::NameEntryId(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id)
: platform_id_(platform_id),
encoding_id_(encoding_id),
language_id_(language_id),
name_id_(name_id) {
}
NameTable::NameEntryId::NameEntryId(const NameTable::NameEntryId& rhs) {
*this = rhs;
}
const NameTable::NameEntryId&
NameTable::NameEntryId::operator=(const NameTable::NameEntryId& rhs) const {
platform_id_ = rhs.platform_id_;
encoding_id_ = rhs.encoding_id_;
language_id_ = rhs.language_id_;
name_id_ = rhs.name_id_;
return *this;
}
bool NameTable::NameEntryId::operator==(const NameEntryId& rhs) const {
return platform_id_ == rhs.platform_id_ &&
encoding_id_ == rhs.encoding_id_ &&
language_id_ == rhs.language_id_ &&
name_id_ == rhs.name_id_;
}
bool NameTable::NameEntryId::operator<(const NameEntryId& rhs) const {
if (platform_id_ != rhs.platform_id_) return platform_id_ < rhs.platform_id_;
if (encoding_id_ != rhs.encoding_id_) return encoding_id_ < rhs.encoding_id_;
if (language_id_ != rhs.language_id_) return language_id_ < rhs.language_id_;
return name_id_ < rhs.name_id_;
}
/******************************************************************************
* NameTable::NameEntry class
******************************************************************************/
NameTable::NameEntry::NameEntry() {
Init(0, 0, 0, 0, NULL);
}
NameTable::NameEntry::NameEntry(const NameEntryId& name_entry_id,
const ByteVector& name_bytes) {
Init(name_entry_id.platform_id(),
name_entry_id.encoding_id(),
name_entry_id.language_id(),
name_entry_id.name_id(),
&name_bytes);
}
NameTable::NameEntry::NameEntry(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id,
const ByteVector& name_bytes) {
Init(platform_id, encoding_id, language_id, name_id, &name_bytes);
}
NameTable::NameEntry::~NameEntry() {}
ByteVector* NameTable::NameEntry::NameAsBytes() {
return &name_bytes_;
}
int32_t NameTable::NameEntry::NameBytesLength() {
return name_bytes_.size();
}
UChar* NameTable::NameEntry::Name() {
return NameTable::ConvertFromNameBytes(&name_bytes_,
platform_id(),
encoding_id());
}
bool NameTable::NameEntry::operator==(const NameEntry& rhs) const {
return (name_entry_id_ == rhs.name_entry_id_ &&
name_bytes_ == rhs.name_bytes_);
}
void NameTable::NameEntry::Init(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id,
const ByteVector* name_bytes) {
name_entry_id_ = NameEntryId(platform_id, encoding_id, language_id, name_id);
if (name_bytes) {
name_bytes_ = *name_bytes;
} else {
name_bytes_.clear();
}
}
/******************************************************************************
* NameTable::NameEntryBuilder class
******************************************************************************/
NameTable::NameEntryBuilder::NameEntryBuilder() {
Init(0, 0, 0, 0, NULL);
}
NameTable::NameEntryBuilder::NameEntryBuilder(const NameEntryId& name_entry_id,
const ByteVector& name_bytes) {
Init(name_entry_id.platform_id(),
name_entry_id.encoding_id(),
name_entry_id.language_id(),
name_entry_id.name_id(),
&name_bytes);
}
NameTable::NameEntryBuilder::NameEntryBuilder(
const NameEntryId& name_entry_id) {
Init(name_entry_id.platform_id(),
name_entry_id.encoding_id(),
name_entry_id.language_id(),
name_entry_id.name_id(),
NULL);
}
NameTable::NameEntryBuilder::NameEntryBuilder(NameEntry* b) {
Init(b->platform_id(),
b->encoding_id(),
b->language_id(),
b->name_id(),
b->NameAsBytes());
}
NameTable::NameEntryBuilder::~NameEntryBuilder() {}
void NameTable::NameEntryBuilder::SetName(const UChar* name) {
if (name == NULL) {
name_entry_->name_bytes_.clear();
return;
}
NameTable::ConvertToNameBytes(name,
name_entry_->platform_id(),
name_entry_->encoding_id(),
&name_entry_->name_bytes_);
}
void NameTable::NameEntryBuilder::SetName(const ByteVector& name_bytes) {
name_entry_->name_bytes_.clear();
std::copy(name_bytes.begin(),
name_bytes.end(),
name_entry_->name_bytes_.begin());
}
void NameTable::NameEntryBuilder::SetName(const ByteVector& name_bytes,
int32_t offset,
int32_t length) {
name_entry_->name_bytes_.clear();
std::copy(name_bytes.begin() + offset,
name_bytes.begin() + offset + length,
name_entry_->name_bytes_.begin());
}
void NameTable::NameEntryBuilder::Init(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id,
const ByteVector* name_bytes) {
name_entry_ = new NameEntry();
name_entry_->Init(platform_id, encoding_id, language_id, name_id, name_bytes);
}
/******************************************************************************
* NameTable::NameEntryFilterInPlace class (C++ port only)
******************************************************************************/
NameTable::NameEntryFilterInPlace::NameEntryFilterInPlace(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id)
: platform_id_(platform_id),
encoding_id_(encoding_id),
language_id_(language_id),
name_id_(name_id) {
}
bool NameTable::NameEntryFilterInPlace::Accept(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id) {
return (platform_id_ == platform_id &&
encoding_id_ == encoding_id &&
language_id_ == language_id &&
name_id_ == name_id);
}
/******************************************************************************
* NameTable::NameEntryIterator class
******************************************************************************/
NameTable::NameEntryIterator::NameEntryIterator(NameTable* table)
: RefIterator<NameEntry, NameTable>(table),
name_index_(0),
filter_(NULL) {
}
NameTable::NameEntryIterator::NameEntryIterator(NameTable* table,
NameEntryFilter* filter)
: RefIterator<NameEntry, NameTable>(table),
name_index_(0),
filter_(filter) {
}
bool NameTable::NameEntryIterator::HasNext() {
if (!filter_) {
if (name_index_ < container()->NameCount()) {
return true;
}
return false;
}
for (; name_index_ < container()->NameCount(); ++name_index_) {
if (filter_->Accept(container()->PlatformId(name_index_),
container()->EncodingId(name_index_),
container()->LanguageId(name_index_),
container()->NameId(name_index_))) {
return true;
}
}
return false;
}
CALLER_ATTACH NameTable::NameEntry* NameTable::NameEntryIterator::Next() {
if (!HasNext())
return NULL;
return container()->GetNameEntry(name_index_++);
}
/******************************************************************************
* NameTable::Builder class
******************************************************************************/
NameTable::Builder::Builder(Header* header, WritableFontData* data)
: SubTableContainerTable::Builder(header, data) {
}
NameTable::Builder::Builder(Header* header, ReadableFontData* data)
: SubTableContainerTable::Builder(header, data) {
}
CALLER_ATTACH NameTable::Builder*
NameTable::Builder::CreateBuilder(Header* header,
WritableFontData* data) {
Ptr<NameTable::Builder> builder;
builder = new NameTable::Builder(header, data);
return builder.Detach();
}
void NameTable::Builder::RevertNames() {
name_entry_map_.clear();
set_model_changed(false);
}
int32_t NameTable::Builder::BuilderCount() {
GetNameBuilders(); // Ensure name_entry_map_ is built.
return (int32_t)name_entry_map_.size();
}
bool NameTable::Builder::Has(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id) {
NameEntryId probe(platform_id, encoding_id, language_id, name_id);
GetNameBuilders(); // Ensure name_entry_map_ is built.
return (name_entry_map_.find(probe) != name_entry_map_.end());
}
CALLER_ATTACH NameTable::NameEntryBuilder*
NameTable::Builder::NameBuilder(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id) {
NameEntryId probe(platform_id, encoding_id, language_id, name_id);
NameEntryBuilderMap builders;
GetNameBuilders(); // Ensure name_entry_map_ is built.
if (name_entry_map_.find(probe) != name_entry_map_.end()) {
return name_entry_map_[probe];
}
NameEntryBuilderPtr builder = new NameEntryBuilder(probe);
name_entry_map_[probe] = builder;
return builder.Detach();
}
bool NameTable::Builder::Remove(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id) {
NameEntryId probe(platform_id, encoding_id, language_id, name_id);
GetNameBuilders(); // Ensure name_entry_map_ is built.
NameEntryBuilderMap::iterator position = name_entry_map_.find(probe);
if (position != name_entry_map_.end()) {
name_entry_map_.erase(position);
return true;
}
return false;
}
CALLER_ATTACH FontDataTable*
NameTable::Builder::SubBuildTable(ReadableFontData* data) {
FontDataTablePtr table = new NameTable(header(), data);
return table.Detach();
}
void NameTable::Builder::SubDataSet() {
name_entry_map_.clear();
set_model_changed(false);
}
int32_t NameTable::Builder::SubDataSizeToSerialize() {
if (name_entry_map_.empty()) {
return 0;
}
int32_t size = NameTable::Offset::kNameRecordStart +
name_entry_map_.size() * NameTable::Offset::kNameRecordSize;
for (NameEntryBuilderMap::iterator b = name_entry_map_.begin(),
end = name_entry_map_.end();
b != end; ++b) {
NameEntryBuilderPtr p = b->second;
NameEntry* entry = p->name_entry();
size += entry->NameBytesLength();
}
return size;
}
bool NameTable::Builder::SubReadyToSerialize() {
return !name_entry_map_.empty();
}
int32_t NameTable::Builder::SubSerialize(WritableFontData* new_data) {
int32_t string_table_start_offset =
NameTable::Offset::kNameRecordStart +
name_entry_map_.size() * NameTable::Offset::kNameRecordSize;
// Header
new_data->WriteUShort(NameTable::Offset::kFormat, 0);
new_data->WriteUShort(NameTable::Offset::kCount, name_entry_map_.size());
new_data->WriteUShort(NameTable::Offset::kStringOffset,
string_table_start_offset);
int32_t name_record_offset = NameTable::Offset::kNameRecordStart;
int32_t string_offset = 0;
// Note: we offered operator< in NameEntryId, which will be used by std::less,
// and therefore our map will act like TreeMap in Java to provide
// sorted key set.
for (NameEntryBuilderMap::iterator b = name_entry_map_.begin(),
end = name_entry_map_.end();
b != end; ++b) {
new_data->WriteUShort(
name_record_offset + NameTable::Offset::kNameRecordPlatformId,
b->first.platform_id());
new_data->WriteUShort(
name_record_offset + NameTable::Offset::kNameRecordEncodingId,
b->first.encoding_id());
new_data->WriteUShort(
name_record_offset + NameTable::Offset::kNameRecordLanguageId,
b->first.language_id());
new_data->WriteUShort(
name_record_offset + NameTable::Offset::kNameRecordNameId,
b->first.name_id());
NameEntry* builder_entry = b->second->name_entry();
new_data->WriteUShort(
name_record_offset + NameTable::Offset::kNameRecordStringLength,
builder_entry->NameBytesLength());
new_data->WriteUShort(
name_record_offset + NameTable::Offset::kNameRecordStringOffset,
string_offset);
name_record_offset += NameTable::Offset::kNameRecordSize;
string_offset += new_data->WriteBytes(
string_offset + string_table_start_offset,
builder_entry->NameAsBytes());
}
return string_offset + string_table_start_offset;
}
void NameTable::Builder::Initialize(ReadableFontData* data) {
if (data) {
NameTablePtr table = new NameTable(header(), data);
Ptr<NameEntryIterator> name_iter;
name_iter.Attach(table->Iterator());
while (name_iter->HasNext()) {
NameEntryPtr name_entry;
name_entry.Attach(name_iter->Next());
NameEntryBuilderPtr name_entry_builder = new NameEntryBuilder(name_entry);
NameEntry* builder_entry = name_entry_builder->name_entry();
NameEntryId probe = builder_entry->name_entry_id();
name_entry_map_[probe] = name_entry_builder;
}
}
}
NameTable::NameEntryBuilderMap* NameTable::Builder::GetNameBuilders() {
if (name_entry_map_.empty()) {
Initialize(InternalReadData());
}
set_model_changed();
return &name_entry_map_;
}
/******************************************************************************
* NameTable class
******************************************************************************/
NameTable::~NameTable() {}
int32_t NameTable::Format() {
return data_->ReadUShort(Offset::kFormat);
}
int32_t NameTable::NameCount() {
return data_->ReadUShort(Offset::kCount);
}
int32_t NameTable::PlatformId(int32_t index) {
return data_->ReadUShort(Offset::kNameRecordPlatformId +
OffsetForNameRecord(index));
}
int32_t NameTable::EncodingId(int32_t index) {
return data_->ReadUShort(Offset::kNameRecordEncodingId +
OffsetForNameRecord(index));
}
int32_t NameTable::LanguageId(int32_t index) {
return data_->ReadUShort(Offset::kNameRecordLanguageId +
OffsetForNameRecord(index));
}
int32_t NameTable::NameId(int32_t index) {
return data_->ReadUShort(Offset::kNameRecordNameId +
OffsetForNameRecord(index));
}
void NameTable::NameAsBytes(int32_t index, ByteVector* b) {
assert(b);
int32_t length = NameLength(index);
b->clear();
b->resize(length);
data_->ReadBytes(NameOffset(index), &((*b)[0]), 0, length);
}
void NameTable::NameAsBytes(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id,
ByteVector* b) {
assert(b);
NameEntryPtr entry;
entry.Attach(GetNameEntry(platform_id, encoding_id, language_id, name_id));
if (entry) {
ByteVector* name = entry->NameAsBytes();
std::copy(name->begin(), name->end(), b->begin());
}
}
UChar* NameTable::Name(int32_t index) {
ByteVector b;
NameAsBytes(index, &b);
return ConvertFromNameBytes(&b, PlatformId(index), EncodingId(index));
}
UChar* NameTable::Name(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id) {
NameEntryPtr entry;
entry.Attach(GetNameEntry(platform_id, encoding_id, language_id, name_id));
if (entry) {
return entry->Name();
}
return NULL;
}
CALLER_ATTACH NameTable::NameEntry* NameTable::GetNameEntry(int32_t index) {
ByteVector b;
NameAsBytes(index, &b);
NameEntryPtr instance = new NameEntry(PlatformId(index),
EncodingId(index),
LanguageId(index),
NameId(index), b);
return instance.Detach();
}
CALLER_ATTACH NameTable::NameEntry* NameTable::GetNameEntry(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id) {
NameTable::NameEntryFilterInPlace
filter(platform_id, encoding_id, language_id, name_id);
Ptr<NameTable::NameEntryIterator> name_entry_iter;
name_entry_iter.Attach(Iterator(&filter));
NameEntryPtr result;
if (name_entry_iter->HasNext()) {
result = name_entry_iter->Next();
}
return result;
}
CALLER_ATTACH NameTable::NameEntryIterator* NameTable::Iterator() {
Ptr<NameEntryIterator> output = new NameTable::NameEntryIterator(this);
return output.Detach();
}
CALLER_ATTACH
NameTable::NameEntryIterator* NameTable::Iterator(NameEntryFilter* filter) {
Ptr<NameEntryIterator> output =
new NameTable::NameEntryIterator(this, filter);
return output.Detach();
}
NameTable::NameTable(Header* header, ReadableFontData* data)
: SubTableContainerTable(header, data) {}
int32_t NameTable::StringOffset() {
return data_->ReadUShort(Offset::kStringOffset);
}
int32_t NameTable::OffsetForNameRecord(int32_t index) {
return Offset::kNameRecordStart + index * Offset::kNameRecordSize;
}
int32_t NameTable::NameLength(int32_t index) {
return data_->ReadUShort(Offset::kNameRecordStringLength +
OffsetForNameRecord(index));
}
int32_t NameTable::NameOffset(int32_t index) {
return data_->ReadUShort(Offset::kNameRecordStringOffset +
OffsetForNameRecord(index)) + StringOffset();
}
const char* NameTable::GetEncodingName(int32_t platform_id,
int32_t encoding_id) {
switch (platform_id) {
case PlatformId::kUnicode:
return "UTF-16BE";
case PlatformId::kMacintosh:
switch (encoding_id) {
case MacintoshEncodingId::kRoman:
return "MacRoman";
case MacintoshEncodingId::kJapanese:
return "Shift-JIS";
case MacintoshEncodingId::kChineseTraditional:
return "Big5";
case MacintoshEncodingId::kKorean:
return "EUC-KR";
case MacintoshEncodingId::kArabic:
return "MacArabic";
case MacintoshEncodingId::kHebrew:
return "MacHebrew";
case MacintoshEncodingId::kGreek:
return "MacGreek";
case MacintoshEncodingId::kRussian:
return "MacCyrillic";
case MacintoshEncodingId::kRSymbol:
return "MacSymbol";
case MacintoshEncodingId::kThai:
return "MacThai";
case MacintoshEncodingId::kChineseSimplified:
return "EUC-CN";
default: // Note: unknown/unconfirmed cases are not ported.
break;
}
break;
case PlatformId::kISO:
break;
case PlatformId::kWindows:
switch (encoding_id) {
case WindowsEncodingId::kSymbol:
case WindowsEncodingId::kUnicodeUCS2:
return "UTF-16BE";
case WindowsEncodingId::kShiftJIS:
return "windows-933";
case WindowsEncodingId::kPRC:
return "windows-936";
case WindowsEncodingId::kBig5:
return "windows-950";
case WindowsEncodingId::kWansung:
return "windows-949";
case WindowsEncodingId::kJohab:
return "ms1361";
case WindowsEncodingId::kUnicodeUCS4:
return "UCS-4";
}
break;
case PlatformId::kCustom:
break;
default:
break;
}
return NULL;
}
UConverter* NameTable::GetCharset(int32_t platform_id, int32_t encoding_id) {
UErrorCode error_code = U_ZERO_ERROR;
UConverter* conv = ucnv_open(GetEncodingName(platform_id, encoding_id),
&error_code);
if (U_SUCCESS(error_code)) {
return conv;
}
if (conv) {
ucnv_close(conv);
}
return NULL;
}
void NameTable::ConvertToNameBytes(const UChar* name,
int32_t platform_id,
int32_t encoding_id,
ByteVector* b) {
assert(b);
assert(name);
b->clear();
UConverter* cs = GetCharset(platform_id, encoding_id);
if (cs == NULL) {
return;
}
// Preflight to get buffer size.
UErrorCode error_code = U_ZERO_ERROR;
int32_t length = ucnv_fromUChars(cs, NULL, 0, name, -1, &error_code);
b->resize(length + 4); // The longest termination "\0" is 4 bytes.
memset(&((*b)[0]), 0, length + 4);
error_code = U_ZERO_ERROR;
ucnv_fromUChars(cs,
reinterpret_cast<char*>(&((*b)[0])),
length + 4,
name,
-1,
&error_code);
if (!U_SUCCESS(error_code)) {
b->clear();
}
ucnv_close(cs);
}
UChar* NameTable::ConvertFromNameBytes(ByteVector* name_bytes,
int32_t platform_id,
int32_t encoding_id) {
if (name_bytes == NULL) {
return NULL;
}
UConverter* cs = GetCharset(platform_id, encoding_id);
UErrorCode error_code = U_ZERO_ERROR;
if (cs == NULL) {
char buffer[11] = {0};
#if defined (WIN32)
_itoa_s(platform_id, buffer, 16);
#else
snprintf(buffer, sizeof(buffer), "%x", platform_id);
#endif
UChar* result = new UChar[12];
memset(result, 0, sizeof(UChar) * 12);
cs = ucnv_open("utf-8", &error_code);
if (U_SUCCESS(error_code)) {
ucnv_toUChars(cs, result, 12, buffer, 11, &error_code);
ucnv_close(cs);
if (U_SUCCESS(error_code)) {
return result;
}
}
delete[] result;
return NULL;
}
// No preflight needed here, we will be bigger.
UChar* output_buffer = new UChar[name_bytes->size() + 1];
memset(output_buffer, 0, sizeof(UChar) * (name_bytes->size() + 1));
int32_t length = ucnv_toUChars(cs,
output_buffer,
name_bytes->size(),
reinterpret_cast<char*>(&((*name_bytes)[0])),
name_bytes->size(),
&error_code);
ucnv_close(cs);
if (length > 0) {
return output_buffer;
}
delete[] output_buffer;
return NULL;
}
} // namespace sfntly

View File

@ -1,744 +0,0 @@
/*
* 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_TABLE_CORE_NAME_TABLE_H_
#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_
// Must include this before ICU to avoid stdint redefinition issue.
#include "sfntly/port/type.h"
#include <unicode/ucnv.h>
#include <unicode/ustring.h>
#include <map>
#include <utility>
#include "sfntly/port/java_iterator.h"
#include "sfntly/table/subtable_container_table.h"
namespace sfntly {
// The following code implements the name table defined in TTF/OTF spec, which
// can be found at http://www.microsoft.com/typography/otspec/name.htm.
// Name IDs defined in TTF/OTF spec.
struct NameId {
enum {
kUnknown = -1,
kCopyrightNotice = 0,
kFontFamilyName = 1,
kFontSubfamilyName = 2,
kUniqueFontIdentifier = 3,
kFullFontName = 4,
kVersionString = 5,
kPostscriptName = 6,
kTrademark = 7,
kManufacturerName = 8,
kDesigner = 9,
kDescription = 10,
kVendorURL = 11,
kDesignerURL = 12,
kLicenseDescription = 13,
kLicenseInfoURL = 14,
kReserved15 = 15,
kPreferredFamily = 16,
kPreferredSubfamily = 17,
kCompatibleFullName = 18,
kSampleText = 19,
kPostscriptCID = 20,
kWWSFamilyName = 21,
kWWSSubfamilyName = 22
};
};
// Unicode language IDs used in Name Records.
struct UnicodeLanguageId {
enum {
kUnknown = -1,
kAll = 0
};
};
// Macintosh Language IDs (platform ID = 1)
struct MacintoshLanguageId {
enum {
kUnknown = -1,
kEnglish = 0,
kFrench = 1,
kGerman = 2,
kItalian = 3,
kDutch = 4,
kSwedish = 5,
kSpanish = 6,
kDanish = 7,
kPortuguese = 8,
kNorwegian = 9,
kHebrew = 10,
kJapanese = 11,
kArabic = 12,
kFinnish = 13,
kGreek = 14,
kIcelandic = 15,
kMaltese = 16,
kTurkish = 17,
kCroatian = 18,
kChinese_Traditional = 19,
kUrdu = 20,
kHindi = 21,
kThai = 22,
kKorean = 23,
kLithuanian = 24,
kPolish = 25,
kHungarian = 26,
kEstonian = 27,
kLatvian = 28,
kSami = 29,
kFaroese = 30,
kFarsiPersian = 31,
kRussian = 32,
kChinese_Simplified = 33,
kFlemish = 34,
kIrishGaelic = 35,
kAlbanian = 36,
kRomanian = 37,
kCzech = 38,
kSlovak = 39,
kSlovenian = 40,
kYiddish = 41,
kSerbian = 42,
kMacedonian = 43,
kBulgarian = 44,
kUkrainian = 45,
kByelorussian = 46,
kUzbek = 47,
kKazakh = 48,
kAzerbaijani_Cyrillic = 49,
kAzerbaijani_Arabic = 50,
kArmenian = 51,
kGeorgian = 52,
kMoldavian = 53,
kKirghiz = 54,
kTajiki = 55,
kTurkmen = 56,
kMongolian_Mongolian = 57,
kMongolian_Cyrillic = 58,
kPashto = 59,
kKurdish = 60,
kKashmiri = 61,
kSindhi = 62,
kTibetan = 63,
kNepali = 64,
kSanskrit = 65,
kMarathi = 66,
kBengali = 67,
kAssamese = 68,
kGujarati = 69,
kPunjabi = 70,
kOriya = 71,
kMalayalam = 72,
kKannada = 73,
kTamil = 74,
kTelugu = 75,
kSinhalese = 76,
kBurmese = 77,
kKhmer = 78,
kLao = 79,
kVietnamese = 80,
kIndonesian = 81,
kTagalong = 82,
kMalay_Roman = 83,
kMalay_Arabic = 84,
kAmharic = 85,
kTigrinya = 86,
kGalla = 87,
kSomali = 88,
kSwahili = 89,
kKinyarwandaRuanda = 90,
kRundi = 91,
kNyanjaChewa = 92,
kMalagasy = 93,
kEsperanto = 94,
kWelsh = 128,
kBasque = 129,
kCatalan = 130,
kLatin = 131,
kQuenchua = 132,
kGuarani = 133,
kAymara = 134,
kTatar = 135,
kUighur = 136,
kDzongkha = 137,
kJavanese_Roman = 138,
kSundanese_Roman = 139,
kGalician = 140,
kAfrikaans = 141,
kBreton = 142,
kInuktitut = 143,
kScottishGaelic = 144,
kManxGaelic = 145,
kIrishGaelic_WithDotAbove = 146,
kTongan = 147,
kGreek_Polytonic = 148,
kGreenlandic = 149,
kAzerbaijani_Roman = 150
};
};
// Windows Language IDs (platformID = 3)
struct WindowsLanguageId {
enum {
kUnknown = -1,
kAfrikaans_SouthAfrica = 0x0436,
kAlbanian_Albania = 0x041C,
kAlsatian_France = 0x0484,
kAmharic_Ethiopia = 0x045E,
kArabic_Algeria = 0x1401,
kArabic_Bahrain = 0x3C01,
kArabic_Egypt = 0x0C01,
kArabic_Iraq = 0x0801,
kArabic_Jordan = 0x2C01,
kArabic_Kuwait = 0x3401,
kArabic_Lebanon = 0x3001,
kArabic_Libya = 0x1001,
kArabic_Morocco = 0x1801,
kArabic_Oman = 0x2001,
kArabic_Qatar = 0x4001,
kArabic_SaudiArabia = 0x0401,
kArabic_Syria = 0x2801,
kArabic_Tunisia = 0x1C01,
kArabic_UAE = 0x3801,
kArabic_Yemen = 0x2401,
kArmenian_Armenia = 0x042B,
kAssamese_India = 0x044D,
kAzeri_Cyrillic_Azerbaijan = 0x082C,
kAzeri_Latin_Azerbaijan = 0x042C,
kBashkir_Russia = 0x046D,
kBasque_Basque = 0x042D,
kBelarusian_Belarus = 0x0423,
kBengali_Bangladesh = 0x0845,
kBengali_India = 0x0445,
kBosnian_Cyrillic_BosniaAndHerzegovina = 0x201A,
kBosnian_Latin_BosniaAndHerzegovina = 0x141A,
kBreton_France = 0x047E,
kBulgarian_Bulgaria = 0x0402,
kCatalan_Catalan = 0x0403,
kChinese_HongKongSAR = 0x0C04,
kChinese_MacaoSAR = 0x1404,
kChinese_PeoplesRepublicOfChina = 0x0804,
kChinese_Singapore = 0x1004,
kChinese_Taiwan = 0x0404,
kCorsican_France = 0x0483,
kCroatian_Croatia = 0x041A,
kCroatian_Latin_BosniaAndHerzegovina = 0x101A,
kCzech_CzechRepublic = 0x0405,
kDanish_Denmark = 0x0406,
kDari_Afghanistan = 0x048C,
kDivehi_Maldives = 0x0465,
kDutch_Belgium = 0x0813,
kDutch_Netherlands = 0x0413,
kEnglish_Australia = 0x0C09,
kEnglish_Belize = 0x2809,
kEnglish_Canada = 0x1009,
kEnglish_Caribbean = 0x2409,
kEnglish_India = 0x4009,
kEnglish_Ireland = 0x1809,
kEnglish_Jamaica = 0x2009,
kEnglish_Malaysia = 0x4409,
kEnglish_NewZealand = 0x1409,
kEnglish_RepublicOfThePhilippines = 0x3409,
kEnglish_Singapore = 0x4809,
kEnglish_SouthAfrica = 0x1C09,
kEnglish_TrinidadAndTobago = 0x2C09,
kEnglish_UnitedKingdom = 0x0809,
kEnglish_UnitedStates = 0x0409,
kEnglish_Zimbabwe = 0x3009,
kEstonian_Estonia = 0x0425,
kFaroese_FaroeIslands = 0x0438,
kFilipino_Philippines = 0x0464,
kFinnish_Finland = 0x040B,
kFrench_Belgium = 0x080C,
kFrench_Canada = 0x0C0C,
kFrench_France = 0x040C,
kFrench_Luxembourg = 0x140c,
kFrench_PrincipalityOfMonoco = 0x180C,
kFrench_Switzerland = 0x100C,
kFrisian_Netherlands = 0x0462,
kGalician_Galician = 0x0456,
kGeorgian_Georgia = 0x0437,
kGerman_Austria = 0x0C07,
kGerman_Germany = 0x0407,
kGerman_Liechtenstein = 0x1407,
kGerman_Luxembourg = 0x1007,
kGerman_Switzerland = 0x0807,
kGreek_Greece = 0x0408,
kGreenlandic_Greenland = 0x046F,
kGujarati_India = 0x0447,
kHausa_Latin_Nigeria = 0x0468,
kHebrew_Israel = 0x040D,
kHindi_India = 0x0439,
kHungarian_Hungary = 0x040E,
kIcelandic_Iceland = 0x040F,
kIgbo_Nigeria = 0x0470,
kIndonesian_Indonesia = 0x0421,
kInuktitut_Canada = 0x045D,
kInuktitut_Latin_Canada = 0x085D,
kIrish_Ireland = 0x083C,
kisiXhosa_SouthAfrica = 0x0434,
kisiZulu_SouthAfrica = 0x0435,
kItalian_Italy = 0x0410,
kItalian_Switzerland = 0x0810,
kJapanese_Japan = 0x0411,
kKannada_India = 0x044B,
kKazakh_Kazakhstan = 0x043F,
kKhmer_Cambodia = 0x0453,
kKiche_Guatemala = 0x0486,
kKinyarwanda_Rwanda = 0x0487,
kKiswahili_Kenya = 0x0441,
kKonkani_India = 0x0457,
kKorean_Korea = 0x0412,
kKyrgyz_Kyrgyzstan = 0x0440,
kLao_LaoPDR = 0x0454,
kLatvian_Latvia = 0x0426,
kLithuanian_Lithuania = 0x0427,
kLowerSorbian_Germany = 0x082E,
kLuxembourgish_Luxembourg = 0x046E,
kMacedonian_FYROM_FormerYugoslavRepublicOfMacedonia = 0x042F,
kMalay_BruneiDarussalam = 0x083E,
kMalay_Malaysia = 0x043E,
kMalayalam_India = 0x044C,
kMaltese_Malta = 0x043A,
kMaori_NewZealand = 0x0481,
kMapudungun_Chile = 0x047A,
kMarathi_India = 0x044E,
kMohawk_Mohawk = 0x047C,
kMongolian_Cyrillic_Mongolia = 0x0450,
kMongolian_Traditional_PeoplesRepublicOfChina = 0x0850,
kNepali_Nepal = 0x0461,
kNorwegian_Bokmal_Norway = 0x0414,
kNorwegian_Nynorsk_Norway = 0x0814,
kOccitan_France = 0x0482,
kOriya_India = 0x0448,
kPashto_Afghanistan = 0x0463,
kPolish_Poland = 0x0415,
kPortuguese_Brazil = 0x0416,
kPortuguese_Portugal = 0x0816,
kPunjabi_India = 0x0446,
kQuechua_Bolivia = 0x046B,
kQuechua_Ecuador = 0x086B,
kQuechua_Peru = 0x0C6B,
kRomanian_Romania = 0x0418,
kRomansh_Switzerland = 0x0417,
kRussian_Russia = 0x0419,
kSami_Inari_Finland = 0x243B,
kSami_Lule_Norway = 0x103B,
kSami_Lule_Sweden = 0x143B,
kSami_Northern_Finland = 0x0C3B,
kSami_Northern_Norway = 0x043B,
kSami_Northern_Sweden = 0x083B,
kSami_Skolt_Finland = 0x203B,
kSami_Southern_Norway = 0x183B,
kSami_Southern_Sweden = 0x1C3B,
kSanskrit_India = 0x044F,
kSerbian_Cyrillic_BosniaAndHerzegovina = 0x1C1A,
kSerbian_Cyrillic_Serbia = 0x0C1A,
kSerbian_Latin_BosniaAndHerzegovina = 0x181A,
kSerbian_Latin_Serbia = 0x081A,
kSesothoSaLeboa_SouthAfrica = 0x046C,
kSetswana_SouthAfrica = 0x0432,
kSinhala_SriLanka = 0x045B,
kSlovak_Slovakia = 0x041B,
kSlovenian_Slovenia = 0x0424,
kSpanish_Argentina = 0x2C0A,
kSpanish_Bolivia = 0x400A,
kSpanish_Chile = 0x340A,
kSpanish_Colombia = 0x240A,
kSpanish_CostaRica = 0x140A,
kSpanish_DominicanRepublic = 0x1C0A,
kSpanish_Ecuador = 0x300A,
kSpanish_ElSalvador = 0x440A,
kSpanish_Guatemala = 0x100A,
kSpanish_Honduras = 0x480A,
kSpanish_Mexico = 0x080A,
kSpanish_Nicaragua = 0x4C0A,
kSpanish_Panama = 0x180A,
kSpanish_Paraguay = 0x3C0A,
kSpanish_Peru = 0x280A,
kSpanish_PuertoRico = 0x500A,
kSpanish_ModernSort_Spain = 0x0C0A,
kSpanish_TraditionalSort_Spain = 0x040A,
kSpanish_UnitedStates = 0x540A,
kSpanish_Uruguay = 0x380A,
kSpanish_Venezuela = 0x200A,
kSweden_Finland = 0x081D,
kSwedish_Sweden = 0x041D,
kSyriac_Syria = 0x045A,
kTajik_Cyrillic_Tajikistan = 0x0428,
kTamazight_Latin_Algeria = 0x085F,
kTamil_India = 0x0449,
kTatar_Russia = 0x0444,
kTelugu_India = 0x044A,
kThai_Thailand = 0x041E,
kTibetan_PRC = 0x0451,
kTurkish_Turkey = 0x041F,
kTurkmen_Turkmenistan = 0x0442,
kUighur_PRC = 0x0480,
kUkrainian_Ukraine = 0x0422,
kUpperSorbian_Germany = 0x042E,
kUrdu_IslamicRepublicOfPakistan = 0x0420,
kUzbek_Cyrillic_Uzbekistan = 0x0843,
kUzbek_Latin_Uzbekistan = 0x0443,
kVietnamese_Vietnam = 0x042A,
kWelsh_UnitedKingdom = 0x0452,
kWolof_Senegal = 0x0448,
kYakut_Russia = 0x0485,
kYi_PRC = 0x0478,
kYoruba_Nigeria = 0x046A
};
};
class NameTable : public SubTableContainerTable, public RefCounted<NameTable> {
public:
// Unique identifier for a given name record.
class NameEntryId {
public:
NameEntryId(); // C++ port only, must provide default constructor.
NameEntryId(int32_t platform_id, int32_t encoding_id, int32_t language_id,
int32_t name_id);
NameEntryId(const NameEntryId&);
// Make gcc -Wnon-virtual-dtor happy.
virtual ~NameEntryId() {}
int32_t platform_id() const { return platform_id_; }
int32_t encoding_id() const { return encoding_id_; }
int32_t language_id() const { return language_id_; }
int32_t name_id() const { return name_id_; }
const NameEntryId& operator=(const NameEntryId& rhs) const;
bool operator==(const NameEntryId& rhs) const;
bool operator<(const NameEntryId& rhs) const;
// UNIMPLEMENTED: int hashCode()
// String toString()
private:
mutable int32_t platform_id_;
mutable int32_t encoding_id_;
mutable int32_t language_id_;
mutable int32_t name_id_;
};
class NameEntryBuilder;
// Class to represent a name entry in the name table.
class NameEntry : public RefCounted<NameEntry> {
public:
NameEntry();
NameEntry(const NameEntryId& name_entry_id, const ByteVector& name_bytes);
NameEntry(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id,
const ByteVector& name_bytes);
virtual ~NameEntry();
NameEntryId& name_entry_id() { return name_entry_id_; }
int32_t platform_id() const { return name_entry_id_.platform_id(); }
int32_t encoding_id() const { return name_entry_id_.encoding_id(); }
int32_t language_id() const { return name_entry_id_.language_id(); }
int32_t name_id() const { return name_entry_id_.name_id(); }
// Get the bytes for name. Returned pointer is the address of private
// member of this class, do not attempt to delete.
ByteVector* NameAsBytes();
// C++ port only: get the length of NameAsBytes.
int32_t NameBytesLength();
// Returns the name in Unicode as UChar array.
// Note: ICU UChar* convention requires caller to delete[] it.
UChar* Name();
bool operator==(const NameEntry& rhs) const;
// UNIMPLEMENTED: String toString()
// int hashCode()
private:
void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id,
int32_t name_id, const ByteVector* name_bytes);
NameEntryId name_entry_id_;
int32_t length_;
ByteVector name_bytes_;
friend class NameEntryBuilder;
};
// Builder of a name entry.
// C++ port: original Java hierarchy inherits from NameEntry. In C++ port, we
// opted not doing so to avoid ref count issues and nasty protected members.
class NameEntryBuilder : public RefCounted<NameEntryBuilder> {
public:
NameEntryBuilder();
NameEntryBuilder(const NameEntryId& name_entry_id,
const ByteVector& name_bytes);
explicit NameEntryBuilder(const NameEntryId& name_entry_id);
explicit NameEntryBuilder(NameEntry* entry);
virtual ~NameEntryBuilder();
virtual void SetName(const UChar* name);
virtual void SetName(const ByteVector& name_bytes);
virtual void SetName(const ByteVector& name_bytes,
int32_t offset,
int32_t length);
// C++ port only. CALLER_ATTACH is not added because the lifetime shall be
// controlled by this class, therefore the caller shall not increase the ref
// count.
NameEntry* name_entry() { return name_entry_; }
private:
void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id,
int32_t name_id, const ByteVector* name_bytes);
Ptr<NameEntry> name_entry_;
};
typedef std::map<NameEntryId, Ptr<NameEntryBuilder> > NameEntryBuilderMap;
// An interface for a filter to use with the name entry iterator. This allows
// name entries to be iterated and only those acceptable to the filter will be
// returned.
class NameEntryFilter {
public:
virtual bool Accept(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id) = 0;
// Make gcc -Wnon-virtual-dtor happy.
virtual ~NameEntryFilter() {}
};
// C++ port only: an in-place filter to mimic Java Iterator's filtering.
class NameEntryFilterInPlace : public NameEntryFilter {
public:
NameEntryFilterInPlace(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id);
// Make gcc -Wnon-virtual-dtor happy.
virtual ~NameEntryFilterInPlace() {}
virtual bool Accept(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id);
private:
int32_t platform_id_;
int32_t encoding_id_;
int32_t language_id_;
int32_t name_id_;
};
class NameEntryIterator : public RefIterator<NameEntry, NameTable> {
public:
// If filter is NULL, filter through all tables.
explicit NameEntryIterator(NameTable* table);
NameEntryIterator(NameTable* table, NameEntryFilter* filter);
virtual ~NameEntryIterator() {}
virtual bool HasNext();
virtual CALLER_ATTACH NameEntry* Next();
private:
int32_t name_index_;
NameEntryFilter* filter_;
};
// The builder to construct name table for outputting.
class Builder : public SubTableContainerTable::Builder,
public RefCounted<Builder> {
public:
// Constructor scope altered to public because C++ does not allow base
// class to instantiate derived class with protected constructors.
Builder(Header* header, WritableFontData* data);
Builder(Header* header, ReadableFontData* data);
static CALLER_ATTACH Builder* CreateBuilder(Header* header,
WritableFontData* data);
// Revert the name builders for the name table to the last version that came
// from data.
void RevertNames();
// Number of name entry builders contained.
int32_t BuilderCount();
// Note: For C++ port, clear() is not implemented. The clear() function
// implies completely remove name entry builders, which is easy in
// Java but will take a lot of efforts in C++ to release the builders
// nicely and correctly.
// TODO(arthurhsu): IMPLEMENT
// Clear the name builders for the name table.
// void clear();
// Check the existance of a name entry builder by key.
bool Has(int32_t platform_id, int32_t encoding_id, int32_t language_id,
int32_t name_id);
// Get name entry builder by key.
CALLER_ATTACH NameEntryBuilder* NameBuilder(int32_t platform_id,
int32_t encoding_id, int32_t language_id, int32_t name_id);
// Remove name entry builder by key.
bool Remove(int32_t platform_id, int32_t encoding_id, int32_t language_id,
int32_t name_id);
// FontDataTable::Builder API implementation
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
virtual int32_t SubDataSizeToSerialize();
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
private:
void Initialize(ReadableFontData* data);
NameEntryBuilderMap* GetNameBuilders();
// Note: callers should use the getter funtion provided above to ensure that
// this is lazily initialized instead of accessing directly.
NameEntryBuilderMap name_entry_map_;
};
/****************************************************************************
* public methods of NameTable class
****************************************************************************/
virtual ~NameTable();
// Get the format used in the name table.
virtual int32_t Format();
// Get the number of names in the name table.
virtual int32_t NameCount();
// Get the platform id for the given name record.
virtual int32_t PlatformId(int32_t index);
// Get the encoding id for the given name record.
// see MacintoshEncodingId, WindowsEncodingId, UnicodeEncodingId
virtual int32_t EncodingId(int32_t index);
// Get the language id for the given name record.
virtual int32_t LanguageId(int32_t index);
// Get the name id for given name record.
virtual int32_t NameId(int32_t index);
// Get the name as bytes for the specified name. If there is no entry for the
// requested name, then empty vector is returned.
virtual void NameAsBytes(int32_t index, ByteVector* b);
virtual void NameAsBytes(int32_t platform_id, int32_t encoding_id,
int32_t language_id, int32_t name_id,
ByteVector* b);
// Get the name as a UChar* for the given name record. If there is no
// encoding conversion available for the name record then a best attempt
// UChar* will be returned.
// Note: ICU UChar* convention requires caller to delete[] it.
virtual UChar* Name(int32_t index);
// Get the name as a UChar* for the specified name. If there is no entry for
// the requested name then NULL is returned. If there is no encoding
// conversion available for the name then a best attempt UChar* will be
// returned.
// Note: ICU UChar* convention requires caller to delete[] it.
virtual UChar* Name(int32_t platform_id, int32_t encoding_id,
int32_t language_id, int32_t name_id);
// Note: These functions are renamed in C++ port. Their original Java name is
// nameEntry().
virtual CALLER_ATTACH NameEntry* GetNameEntry(int32_t index);
virtual CALLER_ATTACH NameEntry* GetNameEntry(int32_t platform_id,
int32_t encoding_id, int32_t language_id, int32_t name_id);
// Note: Not implemented in C++ port due to complexity and low usage.
// virtual void names(std::set<NameEntryPtr>*);
// Get the iterator to iterate through all name entries.
virtual CALLER_ATTACH NameEntryIterator* Iterator();
virtual CALLER_ATTACH NameEntryIterator* Iterator(NameEntryFilter* filter);
private:
struct Offset {
enum {
kFormat = 0,
kCount = 2,
kStringOffset = 4,
kNameRecordStart = 6,
// Format 1 - offset from the end of the name records
kLangTagCount = 0,
kLangTagRecord = 2,
kNameRecordSize = 12,
// Name Records
kNameRecordPlatformId = 0,
kNameRecordEncodingId = 2,
kNameRecordLanguageId = 4,
kNameRecordNameId = 6,
kNameRecordStringLength = 8,
kNameRecordStringOffset = 10
};
};
// The table shall be constructed using Builder, no direct instantiation.
NameTable(Header* header, ReadableFontData* data);
// Get the offset to the string data in the name table.
int32_t StringOffset();
// Get the offset for the given name record.
int32_t OffsetForNameRecord(int32_t index);
// Get the length of the string data for the given name record.
int32_t NameLength(int32_t index);
// Get the offset of the string data for the given name record.
int32_t NameOffset(int32_t index);
// Note: string literals are returned. Caller shall not attempt to manipulate
// the returned pointer.
static const char* GetEncodingName(int32_t platform_id, int32_t encoding_id);
// Note: ICU UConverter* convention requires caller to ucnv_close() it.
static UConverter* GetCharset(int32_t platform_id, int32_t encoding_id);
// Note: Output will be stored in ByteVector* b. Original data in b will be
// erased and replaced with converted name bytes.
static void ConvertToNameBytes(const UChar* name, int32_t platform_id,
int32_t encoding_id, ByteVector* b);
// Note: ICU UChar* convention requires caller to delete[] it.
static UChar* ConvertFromNameBytes(ByteVector* name_bytes,
int32_t platform_id, int32_t encoding_id);
}; // class NameTable
typedef Ptr<NameTable> NameTablePtr;
typedef Ptr<NameTable::NameEntry> NameEntryPtr;
typedef Ptr<NameTable::Builder> NameTableBuilderPtr;
typedef Ptr<NameTable::NameEntryBuilder> NameEntryBuilderPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_

View File

@ -1,608 +0,0 @@
/*
* 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.
*/
#include "sfntly/table/core/os2_table.h"
namespace sfntly {
/******************************************************************************
* Constants
******************************************************************************/
const int64_t CodePageRange::kLatin1_1252 = (int64_t)1 << 0;
const int64_t CodePageRange::kLatin2_1250 = (int64_t)1 << (int64_t)1;
const int64_t CodePageRange::kCyrillic_1251 = (int64_t)1 << 2;
const int64_t CodePageRange::kGreek_1253 = (int64_t)1 << 3;
const int64_t CodePageRange::kTurkish_1254 = (int64_t)1 << 4;
const int64_t CodePageRange::kHebrew_1255 = (int64_t)1 << 5;
const int64_t CodePageRange::kArabic_1256 = (int64_t)1 << 6;
const int64_t CodePageRange::kWindowsBaltic_1257 = (int64_t)1 << 7;
const int64_t CodePageRange::kVietnamese_1258 = (int64_t)1 << 8;
const int64_t CodePageRange::kAlternateANSI9 = (int64_t)1 << 9;
const int64_t CodePageRange::kAlternateANSI10 = (int64_t)1 << 10;
const int64_t CodePageRange::kAlternateANSI11 = (int64_t)1 << 11;
const int64_t CodePageRange::kAlternateANSI12 = (int64_t)1 << 12;
const int64_t CodePageRange::kAlternateANSI13 = (int64_t)1 << 13;
const int64_t CodePageRange::kAlternateANSI14 = (int64_t)1 << 14;
const int64_t CodePageRange::kAlternateANSI15 = (int64_t)1 << 15;
const int64_t CodePageRange::kThai_874 = (int64_t)1 << 16;
const int64_t CodePageRange::kJapanJIS_932 = (int64_t)1 << 17;
const int64_t CodePageRange::kChineseSimplified_936 = (int64_t)1 << 18;
const int64_t CodePageRange::kKoreanWansung_949 = (int64_t)1 << 19;
const int64_t CodePageRange::kChineseTraditional_950 = (int64_t)1 << 20;
const int64_t CodePageRange::kKoreanJohab_1361 = (int64_t)1 << 21;
const int64_t CodePageRange::kAlternateANSI22 = (int64_t)1 << 22;
const int64_t CodePageRange::kAlternateANSI23 = (int64_t)1 << 23;
const int64_t CodePageRange::kAlternateANSI24 = (int64_t)1 << 24;
const int64_t CodePageRange::kAlternateANSI25 = (int64_t)1 << 25;
const int64_t CodePageRange::kAlternateANSI26 = (int64_t)1 << 26;
const int64_t CodePageRange::kAlternateANSI27 = (int64_t)1 << 27;
const int64_t CodePageRange::kAlternateANSI28 = (int64_t)1 << 28;
const int64_t CodePageRange::kMacintoshCharacterSet = (int64_t)1 << 29;
const int64_t CodePageRange::kOEMCharacterSet = (int64_t)1 << 30;
const int64_t CodePageRange::kSymbolCharacterSet = (int64_t)1 << 31;
const int64_t CodePageRange::kReservedForOEM32 = (int64_t)1 << 32;
const int64_t CodePageRange::kReservedForOEM33 = (int64_t)1 << 33;
const int64_t CodePageRange::kReservedForOEM34 = (int64_t)1 << 34;
const int64_t CodePageRange::kReservedForOEM35 = (int64_t)1 << 35;
const int64_t CodePageRange::kReservedForOEM36 = (int64_t)1 << 36;
const int64_t CodePageRange::kReservedForOEM37 = (int64_t)1 << 37;
const int64_t CodePageRange::kReservedForOEM38 = (int64_t)1 << 38;
const int64_t CodePageRange::kReservedForOEM39 = (int64_t)1 << 39;
const int64_t CodePageRange::kReservedForOEM40 = (int64_t)1 << 40;
const int64_t CodePageRange::kReservedForOEM41 = (int64_t)1 << 41;
const int64_t CodePageRange::kReservedForOEM42 = (int64_t)1 << 42;
const int64_t CodePageRange::kReservedForOEM43 = (int64_t)1 << 43;
const int64_t CodePageRange::kReservedForOEM44 = (int64_t)1 << 44;
const int64_t CodePageRange::kReservedForOEM45 = (int64_t)1 << 45;
const int64_t CodePageRange::kReservedForOEM46 = (int64_t)1 << 46;
const int64_t CodePageRange::kReservedForOEM47 = (int64_t)1 << 47;
const int64_t CodePageRange::kIBMGreek_869 = (int64_t)1 << 48;
const int64_t CodePageRange::kMSDOSRussion_866 = (int64_t)1 << 49;
const int64_t CodePageRange::kMSDOSNordic_865 = (int64_t)1 << 50;
const int64_t CodePageRange::kArabic_864 = (int64_t)1 << 51;
const int64_t CodePageRange::kMSDOSCanadianFrench_863 = (int64_t)1 << 52;
const int64_t CodePageRange::kHebrew_862 = (int64_t)1 << 53;
const int64_t CodePageRange::kMSDOSIcelandic_861 = (int64_t)1 << 54;
const int64_t CodePageRange::kMSDOSPortugese_860 = (int64_t)1 << 55;
const int64_t CodePageRange::kIBMTurkish_857 = (int64_t)1 << 56;
const int64_t CodePageRange::kIBMCyrillic_855 = (int64_t)1 << 57;
const int64_t CodePageRange::kLatin2_852 = (int64_t)1 << 58;
const int64_t CodePageRange::kMSDOSBaltic_775 = (int64_t)1 << 59;
const int64_t CodePageRange::kGreek_737 = (int64_t)1 << 60;
const int64_t CodePageRange::kArabic_708 = (int64_t)1 << 61;
const int64_t CodePageRange::kLatin1_850 = (int64_t)1 << 62;
const int64_t CodePageRange::kUS_437 = (int64_t)1 << 63;
/******************************************************************************
* struct UnicodeRange
******************************************************************************/
int32_t UnicodeRange::range(int32_t bit) {
if (bit < 0 || bit > kLast) {
return -1;
}
return bit;
}
/******************************************************************************
* class OS2Table
******************************************************************************/
OS2Table::~OS2Table() {}
int32_t OS2Table::TableVersion() {
return data_->ReadUShort(Offset::kVersion);
}
int32_t OS2Table::XAvgCharWidth() {
return data_->ReadShort(Offset::kXAvgCharWidth);
}
int32_t OS2Table::UsWeightClass() {
return data_->ReadUShort(Offset::kUsWeightClass);
}
int32_t OS2Table::UsWidthClass() {
return data_->ReadUShort(Offset::kUsWidthClass);
}
int32_t OS2Table::FsType() {
return data_->ReadUShort(Offset::kFsType);
}
int32_t OS2Table::YSubscriptXSize() {
return data_->ReadShort(Offset::kYSubscriptXSize);
}
int32_t OS2Table::YSubscriptYSize() {
return data_->ReadShort(Offset::kYSubscriptYSize);
}
int32_t OS2Table::YSubscriptXOffset() {
return data_->ReadShort(Offset::kYSubscriptXOffset);
}
int32_t OS2Table::YSubscriptYOffset() {
return data_->ReadShort(Offset::kYSubscriptYOffset);
}
int32_t OS2Table::YSuperscriptXSize() {
return data_->ReadShort(Offset::kYSuperscriptXSize);
}
int32_t OS2Table::YSuperscriptYSize() {
return data_->ReadShort(Offset::kYSuperscriptYSize);
}
int32_t OS2Table::YSuperscriptXOffset() {
return data_->ReadShort(Offset::kYSuperscriptXOffset);
}
int32_t OS2Table::YSuperscriptYOffset() {
return data_->ReadShort(Offset::kYSuperscriptYOffset);
}
int32_t OS2Table::YStrikeoutSize() {
return data_->ReadShort(Offset::kYStrikeoutSize);
}
int32_t OS2Table::YStrikeoutPosition() {
return data_->ReadShort(Offset::kYStrikeoutPosition);
}
int32_t OS2Table::SFamilyClass() {
return data_->ReadShort(Offset::kSFamilyClass);
}
void OS2Table::Panose(ByteVector* value) {
assert(value);
value->clear();
value->resize(10);
data_->ReadBytes(Offset::kPanose, &((*value)[0]), 0, 10);
}
int64_t OS2Table::UlUnicodeRange1() {
return data_->ReadULong(Offset::kUlUnicodeRange1);
}
int64_t OS2Table::UlUnicodeRange2() {
return data_->ReadULong(Offset::kUlUnicodeRange2);
}
int64_t OS2Table::UlUnicodeRange3() {
return data_->ReadULong(Offset::kUlUnicodeRange3);
}
int64_t OS2Table::UlUnicodeRange4() {
return data_->ReadULong(Offset::kUlUnicodeRange4);
}
void OS2Table::AchVendId(ByteVector* b) {
assert(b);
b->clear();
b->resize(4);
data_->ReadBytes(Offset::kAchVendId, &((*b)[0]), 0, 4);
}
int32_t OS2Table::FsSelection() {
return data_->ReadUShort(Offset::kFsSelection);
}
int32_t OS2Table::UsFirstCharIndex() {
return data_->ReadUShort(Offset::kUsFirstCharIndex);
}
int32_t OS2Table::UsLastCharIndex() {
return data_->ReadUShort(Offset::kUsLastCharIndex);
}
int32_t OS2Table::STypoAscender() {
return data_->ReadShort(Offset::kSTypoAscender);
}
int32_t OS2Table::STypoDescender() {
return data_->ReadShort(Offset::kSTypoDescender);
}
int32_t OS2Table::STypoLineGap() {
return data_->ReadShort(Offset::kSTypoLineGap);
}
int32_t OS2Table::UsWinAscent() {
return data_->ReadUShort(Offset::kUsWinAscent);
}
int32_t OS2Table::UsWinDescent() {
return data_->ReadUShort(Offset::kUsWinDescent);
}
int64_t OS2Table::UlCodePageRange1() {
return data_->ReadULong(Offset::kUlCodePageRange1);
}
int64_t OS2Table::UlCodePageRange2() {
return data_->ReadULong(Offset::kUlCodePageRange2);
}
int32_t OS2Table::SxHeight() {
return data_->ReadShort(Offset::kSxHeight);
}
int32_t OS2Table::SCapHeight() {
return data_->ReadShort(Offset::kSCapHeight);
}
int32_t OS2Table::UsDefaultChar() {
return data_->ReadUShort(Offset::kUsDefaultChar);
}
int32_t OS2Table::UsBreakChar() {
return data_->ReadUShort(Offset::kUsBreakChar);
}
int32_t OS2Table::UsMaxContext() {
return data_->ReadUShort(Offset::kUsMaxContext);
}
OS2Table::OS2Table(Header* header, ReadableFontData* data)
: Table(header, data) {
}
/******************************************************************************
* class OS2Table::Builder
******************************************************************************/
OS2Table::Builder::Builder(Header* header, WritableFontData* data)
: TableBasedTableBuilder(header, data) {
}
OS2Table::Builder::Builder(Header* header, ReadableFontData* data)
: TableBasedTableBuilder(header, data) {
}
OS2Table::Builder::~Builder() {}
CALLER_ATTACH FontDataTable* OS2Table::Builder::SubBuildTable(
ReadableFontData* data) {
FontDataTablePtr table = new OS2Table(header(), data);
return table.Detach();
}
CALLER_ATTACH OS2Table::Builder*
OS2Table::Builder::CreateBuilder(Header* header,
WritableFontData* data) {
Ptr<OS2Table::Builder> builder;
builder = new OS2Table::Builder(header, data);
return builder.Detach();
}
int32_t OS2Table::Builder::TableVersion() {
return InternalReadData()->ReadUShort(Offset::kVersion);
}
void OS2Table::Builder::SetTableVersion(int32_t version) {
InternalWriteData()->WriteUShort(Offset::kVersion, version);
}
int32_t OS2Table::Builder::XAvgCharWidth() {
return InternalReadData()->ReadShort(Offset::kXAvgCharWidth);
}
void OS2Table::Builder::SetXAvgCharWidth(int32_t width) {
InternalWriteData()->WriteShort(Offset::kXAvgCharWidth, width);
}
int32_t OS2Table::Builder::UsWeightClass() {
return InternalReadData()->ReadUShort(Offset::kUsWeightClass);
}
void OS2Table::Builder::SetUsWeightClass(int32_t weight) {
InternalWriteData()->WriteUShort(Offset::kUsWeightClass, weight);
}
int32_t OS2Table::Builder::UsWidthClass() {
return InternalReadData()->ReadUShort(Offset::kUsWidthClass);
}
void OS2Table::Builder::SetUsWidthClass(int32_t width) {
InternalWriteData()->WriteUShort(Offset::kUsWidthClass, width);
}
int32_t OS2Table::Builder::FsType() {
return InternalReadData()->ReadUShort(Offset::kFsType);
}
void OS2Table::Builder::SetFsType(int32_t fs_type) {
InternalWriteData()->WriteUShort(Offset::kFsType, fs_type);
}
int32_t OS2Table::Builder::YSubscriptXSize() {
return InternalReadData()->ReadShort(Offset::kYSubscriptXSize);
}
void OS2Table::Builder::SetYSubscriptXSize(int32_t size) {
InternalWriteData()->WriteShort(Offset::kYSubscriptXSize, size);
}
int32_t OS2Table::Builder::YSubscriptYSize() {
return InternalReadData()->ReadShort(Offset::kYSubscriptYSize);
}
void OS2Table::Builder::SetYSubscriptYSize(int32_t size) {
InternalWriteData()->WriteShort(Offset::kYSubscriptYSize, size);
}
int32_t OS2Table::Builder::YSubscriptXOffset() {
return InternalReadData()->ReadShort(Offset::kYSubscriptXOffset);
}
void OS2Table::Builder::SetYSubscriptXOffset(int32_t offset) {
InternalWriteData()->WriteShort(Offset::kYSubscriptXOffset, offset);
}
int32_t OS2Table::Builder::YSubscriptYOffset() {
return InternalReadData()->ReadShort(Offset::kYSubscriptYOffset);
}
void OS2Table::Builder::SetYSubscriptYOffset(int32_t offset) {
InternalWriteData()->WriteShort(Offset::kYSubscriptYOffset, offset);
}
int32_t OS2Table::Builder::YSuperscriptXSize() {
return InternalReadData()->ReadShort(Offset::kYSuperscriptXSize);
}
void OS2Table::Builder::SetYSuperscriptXSize(int32_t size) {
InternalWriteData()->WriteShort(Offset::kYSuperscriptXSize, size);
}
int32_t OS2Table::Builder::YSuperscriptYSize() {
return InternalReadData()->ReadShort(Offset::kYSuperscriptYSize);
}
void OS2Table::Builder::SetYSuperscriptYSize(int32_t size) {
InternalWriteData()->WriteShort(Offset::kYSuperscriptYSize, size);
}
int32_t OS2Table::Builder::YSuperscriptXOffset() {
return InternalReadData()->ReadShort(Offset::kYSuperscriptXOffset);
}
void OS2Table::Builder::SetYSuperscriptXOffset(int32_t offset) {
InternalWriteData()->WriteShort(Offset::kYSuperscriptXOffset, offset);
}
int32_t OS2Table::Builder::YSuperscriptYOffset() {
return InternalReadData()->ReadShort(Offset::kYSuperscriptYOffset);
}
void OS2Table::Builder::SetYSuperscriptYOffset(int32_t offset) {
InternalWriteData()->WriteShort(Offset::kYSuperscriptYOffset, offset);
}
int32_t OS2Table::Builder::YStrikeoutSize() {
return InternalReadData()->ReadShort(Offset::kYStrikeoutSize);
}
void OS2Table::Builder::SetYStrikeoutSize(int32_t size) {
InternalWriteData()->WriteShort(Offset::kYStrikeoutSize, size);
}
int32_t OS2Table::Builder::YStrikeoutPosition() {
return InternalReadData()->ReadShort(Offset::kYStrikeoutPosition);
}
void OS2Table::Builder::SetYStrikeoutPosition(int32_t position) {
InternalWriteData()->WriteShort(Offset::kYStrikeoutPosition, position);
}
int32_t OS2Table::Builder::SFamilyClass() {
return InternalReadData()->ReadShort(Offset::kSFamilyClass);
}
void OS2Table::Builder::SetSFamilyClass(int32_t family) {
InternalWriteData()->WriteShort(Offset::kSFamilyClass, family);
}
void OS2Table::Builder::Panose(ByteVector* value) {
assert(value);
value->clear();
value->resize(Offset::kPanoseLength);
InternalReadData()->ReadBytes(Offset::kPanose,
&((*value)[0]),
0,
Offset::kPanoseLength);
}
void OS2Table::Builder::SetPanose(ByteVector* panose) {
assert(panose);
if (panose->size() != Offset::kPanoseLength) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IllegalArgumentException("Panose bytes must be exactly 10 in length");
#endif
return;
}
InternalWriteData()->WriteBytes(Offset::kPanose, panose);
}
int64_t OS2Table::Builder::UlUnicodeRange1() {
return InternalReadData()->ReadULong(Offset::kUlUnicodeRange1);
}
void OS2Table::Builder::SetUlUnicodeRange1(int64_t range) {
InternalWriteData()->WriteULong(Offset::kUlUnicodeRange1, range);
}
int64_t OS2Table::Builder::UlUnicodeRange2() {
return InternalReadData()->ReadULong(Offset::kUlUnicodeRange2);
}
void OS2Table::Builder::SetUlUnicodeRange2(int64_t range) {
InternalWriteData()->WriteULong(Offset::kUlUnicodeRange2, range);
}
int64_t OS2Table::Builder::UlUnicodeRange3() {
return InternalReadData()->ReadULong(Offset::kUlUnicodeRange3);
}
void OS2Table::Builder::SetUlUnicodeRange3(int64_t range) {
InternalWriteData()->WriteULong(Offset::kUlUnicodeRange3, range);
}
int64_t OS2Table::Builder::UlUnicodeRange4() {
return InternalReadData()->ReadULong(Offset::kUlUnicodeRange4);
}
void OS2Table::Builder::SetUlUnicodeRange4(int64_t range) {
InternalWriteData()->WriteULong(Offset::kUlUnicodeRange4, range);
}
void OS2Table::Builder::AchVendId(ByteVector* b) {
assert(b);
b->clear();
b->resize(4);
InternalReadData()->ReadBytes(Offset::kAchVendId, &((*b)[0]), 0, 4);
}
void OS2Table::Builder::SetAchVendId(ByteVector* b) {
assert(b);
assert(b->size());
InternalWriteData()->WriteBytesPad(Offset::kAchVendId,
b,
0,
std::min<size_t>(
(size_t)Offset::kAchVendIdLength,
b->size()),
static_cast<byte_t>(' '));
}
int32_t OS2Table::Builder::FsSelection() {
return InternalReadData()->ReadUShort(Offset::kFsSelection);
}
void OS2Table::Builder::SetFsSelection(int32_t fs_selection) {
InternalWriteData()->WriteUShort(Offset::kFsSelection, fs_selection);
}
int32_t OS2Table::Builder::UsFirstCharIndex() {
return InternalReadData()->ReadUShort(Offset::kUsFirstCharIndex);
}
void OS2Table::Builder::SetUsFirstCharIndex(int32_t first_index) {
InternalWriteData()->WriteUShort(Offset::kUsFirstCharIndex, first_index);
}
int32_t OS2Table::Builder::UsLastCharIndex() {
return InternalReadData()->ReadUShort(Offset::kUsLastCharIndex);
}
void OS2Table::Builder::SetUsLastCharIndex(int32_t last_index) {
InternalWriteData()->WriteUShort(Offset::kUsLastCharIndex, last_index);
}
int32_t OS2Table::Builder::STypoAscender() {
return InternalReadData()->ReadShort(Offset::kSTypoAscender);
}
void OS2Table::Builder::SetSTypoAscender(int32_t ascender) {
InternalWriteData()->WriteShort(Offset::kSTypoAscender, ascender);
}
int32_t OS2Table::Builder::STypoDescender() {
return InternalReadData()->ReadShort(Offset::kSTypoDescender);
}
void OS2Table::Builder::SetSTypoDescender(int32_t descender) {
InternalWriteData()->WriteShort(Offset::kSTypoDescender, descender);
}
int32_t OS2Table::Builder::STypoLineGap() {
return InternalReadData()->ReadShort(Offset::kSTypoLineGap);
}
void OS2Table::Builder::SetSTypoLineGap(int32_t line_gap) {
InternalWriteData()->WriteShort(Offset::kSTypoLineGap, line_gap);
}
int32_t OS2Table::Builder::UsWinAscent() {
return InternalReadData()->ReadUShort(Offset::kUsWinAscent);
}
void OS2Table::Builder::SetUsWinAscent(int32_t ascent) {
InternalWriteData()->WriteUShort(Offset::kUsWinAscent, ascent);
}
int32_t OS2Table::Builder::UsWinDescent() {
return InternalReadData()->ReadUShort(Offset::kUsWinDescent);
}
void OS2Table::Builder::SetUsWinDescent(int32_t descent) {
InternalWriteData()->WriteUShort(Offset::kUsWinDescent, descent);
}
int64_t OS2Table::Builder::UlCodePageRange1() {
return InternalReadData()->ReadULong(Offset::kUlCodePageRange1);
}
void OS2Table::Builder::SetUlCodePageRange1(int64_t range) {
InternalWriteData()->WriteULong(Offset::kUlCodePageRange1, range);
}
int64_t OS2Table::Builder::UlCodePageRange2() {
return InternalReadData()->ReadULong(Offset::kUlCodePageRange2);
}
void OS2Table::Builder::SetUlCodePageRange2(int64_t range) {
InternalWriteData()->WriteULong(Offset::kUlCodePageRange2, range);
}
int32_t OS2Table::Builder::SxHeight() {
return InternalReadData()->ReadShort(Offset::kSxHeight);
}
void OS2Table::Builder::SetSxHeight(int32_t height) {
InternalWriteData()->WriteShort(Offset::kSxHeight, height);
}
int32_t OS2Table::Builder::SCapHeight() {
return InternalReadData()->ReadShort(Offset::kSCapHeight);
}
void OS2Table::Builder::SetSCapHeight(int32_t height) {
InternalWriteData()->WriteShort(Offset::kSCapHeight, height);
}
int32_t OS2Table::Builder::UsDefaultChar() {
return InternalReadData()->ReadUShort(Offset::kUsDefaultChar);
}
void OS2Table::Builder::SetUsDefaultChar(int32_t default_char) {
InternalWriteData()->WriteUShort(Offset::kUsDefaultChar, default_char);
}
int32_t OS2Table::Builder::UsBreakChar() {
return InternalReadData()->ReadUShort(Offset::kUsBreakChar);
}
void OS2Table::Builder::SetUsBreakChar(int32_t break_char) {
InternalWriteData()->WriteUShort(Offset::kUsBreakChar, break_char);
}
int32_t OS2Table::Builder::UsMaxContext() {
return InternalReadData()->ReadUShort(Offset::kUsMaxContext);
}
void OS2Table::Builder::SetUsMaxContext(int32_t max_context) {
InternalWriteData()->WriteUShort(Offset::kUsMaxContext, max_context);
}
} // namespace sfntly

Some files were not shown because too many files have changed in this diff Show More