mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-12-01 10:45:02 -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:
|
The full text of the Apache 2.0 license is available at:
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
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/*
|
Files: resources/viewer/mathjax/*
|
||||||
Copyright: Unknown
|
Copyright: Unknown
|
||||||
License: Apache 2.0
|
License: Apache 2.0
|
||||||
|
|||||||
@ -11,7 +11,6 @@ let g:syntastic_cpp_include_dirs = [
|
|||||||
\'/usr/include/freetype2',
|
\'/usr/include/freetype2',
|
||||||
\'/usr/include/fontconfig',
|
\'/usr/include/fontconfig',
|
||||||
\'src/qtcurve/common', 'src/qtcurve',
|
\'src/qtcurve/common', 'src/qtcurve',
|
||||||
\'src/sfntly/src', 'src/sfntly/src/sample',
|
|
||||||
\'/usr/include/ImageMagick',
|
\'/usr/include/ImageMagick',
|
||||||
\]
|
\]
|
||||||
let g:syntastic_c_include_dirs = g:syntastic_cpp_include_dirs
|
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,
|
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,
|
icu_lib_dirs, win_ddk_lib_dirs, ft_libs, ft_lib_dirs, ft_inc_dirs,
|
||||||
zlib_libs, zlib_lib_dirs, zlib_inc_dirs)
|
zlib_libs, zlib_lib_dirs, zlib_inc_dirs)
|
||||||
from setup.sfntly import SfntlyBuilderMixin
|
|
||||||
MT
|
MT
|
||||||
isunix = islinux or isosx or isbsd
|
isunix = islinux or isosx or isbsd
|
||||||
|
|
||||||
@ -63,26 +62,8 @@ if isosx:
|
|||||||
icu_libs = ['icucore']
|
icu_libs = ['icucore']
|
||||||
icu_cflags = ['-DU_DISABLE_RENAMING'] # Needed to use system libicucore.dylib
|
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 = [
|
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',
|
Extension('speedup',
|
||||||
['calibre/utils/speedup.c'],
|
['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',
|
'speedup',
|
||||||
'freetype',
|
'freetype',
|
||||||
'woff',
|
'woff',
|
||||||
'sfntly',
|
|
||||||
]
|
]
|
||||||
if iswindows:
|
if iswindows:
|
||||||
plugins.extend(['winutil', 'wpd', 'winfonts'])
|
plugins.extend(['winutil', 'wpd', 'winfonts'])
|
||||||
|
|||||||
@ -37,11 +37,6 @@ def test_freetype():
|
|||||||
test()
|
test()
|
||||||
print ('FreeType OK!')
|
print ('FreeType OK!')
|
||||||
|
|
||||||
def test_sfntly():
|
|
||||||
from calibre.utils.fonts.subset import test
|
|
||||||
test()
|
|
||||||
print ('sfntly OK!')
|
|
||||||
|
|
||||||
def test_winutil():
|
def test_winutil():
|
||||||
from calibre.devices.scanner import win_pnp_drives
|
from calibre.devices.scanner import win_pnp_drives
|
||||||
matches = win_pnp_drives.scanner()
|
matches = win_pnp_drives.scanner()
|
||||||
@ -120,7 +115,6 @@ def test():
|
|||||||
test_plugins()
|
test_plugins()
|
||||||
test_lxml()
|
test_lxml()
|
||||||
test_freetype()
|
test_freetype()
|
||||||
test_sfntly()
|
|
||||||
test_sqlite()
|
test_sqlite()
|
||||||
test_imaging()
|
test_imaging()
|
||||||
test_unrar()
|
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