mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-12-01 02:35:03 -05:00
Get rid of the useless sfntly
This commit is contained in:
commit
491bfc24bb
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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'],
|
||||
),
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -91,7 +91,6 @@ class Plugins(collections.Mapping):
|
||||
'speedup',
|
||||
'freetype',
|
||||
'woff',
|
||||
'sfntly',
|
||||
]
|
||||
if iswindows:
|
||||
plugins.extend(['winutil', 'wpd', 'winfonts'])
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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_;
|
||||
};
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user