Bug 1716117 - Build SkiaPDF with harfbuzz subsetting, and eliminate use of sfntly. r=jrmuizel

Differential Revision: https://phabricator.services.mozilla.com/D117586
This commit is contained in:
Jonathan Kew 2021-06-15 16:45:30 +00:00
Родитель 3050aa82c8
Коммит 5820669ad6
194 изменённых файлов: 2 добавлений и 33802 удалений

Просмотреть файл

@ -35,9 +35,6 @@ DIRS += [
if CONFIG["MOZ_ENABLE_SKIA"]:
DIRS += ["skia"]
if CONFIG["MOZ_ENABLE_SKIA_PDF_SFNTLY"]:
DIRS += ["sfntly/cpp/src"]
if CONFIG["ENABLE_TESTS"]:
DIRS += ["tests/gtest"]

Просмотреть файл

@ -1,5 +0,0 @@
This directory contains the C++ port of SFNTLY,
from https://github.com/googlei18n/sfntly/tree/master/cpp.
SFNTLY is distributed under the Apache license v2.0
(see cpp/COPYING.txt).

Просмотреть файл

@ -1,73 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS += [
'sample/chromium/font_subsetter.h',
]
UNIFIED_SOURCES += [
'sample/chromium/font_subsetter.cc',
'sample/chromium/subsetter_impl.cc',
'sfntly/data/byte_array.cc',
'sfntly/data/font_data.cc',
'sfntly/data/font_input_stream.cc',
'sfntly/data/font_output_stream.cc',
'sfntly/data/growable_memory_byte_array.cc',
'sfntly/data/memory_byte_array.cc',
'sfntly/data/readable_font_data.cc',
'sfntly/data/writable_font_data.cc',
'sfntly/font.cc',
'sfntly/font_factory.cc',
'sfntly/port/file_input_stream.cc',
'sfntly/port/lock.cc',
'sfntly/port/memory_input_stream.cc',
'sfntly/port/memory_output_stream.cc',
'sfntly/table/bitmap/big_glyph_metrics.cc',
'sfntly/table/bitmap/bitmap_glyph.cc',
'sfntly/table/bitmap/bitmap_glyph_info.cc',
'sfntly/table/bitmap/bitmap_size_table.cc',
'sfntly/table/bitmap/composite_bitmap_glyph.cc',
'sfntly/table/bitmap/ebdt_table.cc',
'sfntly/table/bitmap/eblc_table.cc',
'sfntly/table/bitmap/ebsc_table.cc',
'sfntly/table/bitmap/glyph_metrics.cc',
'sfntly/table/bitmap/index_sub_table.cc',
'sfntly/table/bitmap/index_sub_table_format1.cc',
'sfntly/table/bitmap/index_sub_table_format2.cc',
'sfntly/table/bitmap/index_sub_table_format3.cc',
'sfntly/table/bitmap/index_sub_table_format4.cc',
'sfntly/table/bitmap/index_sub_table_format5.cc',
'sfntly/table/bitmap/simple_bitmap_glyph.cc',
'sfntly/table/bitmap/small_glyph_metrics.cc',
'sfntly/table/byte_array_table_builder.cc',
'sfntly/table/core/cmap_table.cc',
'sfntly/table/core/font_header_table.cc',
'sfntly/table/core/horizontal_device_metrics_table.cc',
'sfntly/table/core/horizontal_header_table.cc',
'sfntly/table/core/horizontal_metrics_table.cc',
'sfntly/table/core/maximum_profile_table.cc',
'sfntly/table/core/name_table.cc',
'sfntly/table/core/os2_table.cc',
'sfntly/table/font_data_table.cc',
'sfntly/table/generic_table_builder.cc',
'sfntly/table/header.cc',
'sfntly/table/subtable.cc',
'sfntly/table/table.cc',
'sfntly/table/table_based_table_builder.cc',
'sfntly/table/truetype/glyph_table.cc',
'sfntly/table/truetype/loca_table.cc',
'sfntly/tag.cc',
'sfntly/tools/subsetter/glyph_table_subsetter.cc',
'sfntly/tools/subsetter/subsetter.cc',
'sfntly/tools/subsetter/table_subsetter_impl.cc',
]
# We allow warnings for third-party code that can be updated from upstream.
AllowCompilerWarnings()
FINAL_LIBRARY = 'gkmedias'
DEFINES['SFNTLY_NO_EXCEPTION'] = 1

Просмотреть файл

@ -1,131 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 <stdio.h>
#include <vector>
#include <string>
#include <sstream>
#include "sfntly/port/type.h"
#include "font_subsetter.h"
template <typename T>
class HexTo {
public:
explicit HexTo(const char* in) {
std::stringstream ss;
ss << std::hex << in;
ss >> value_;
}
operator T() const { return value_; }
private:
T value_;
};
bool LoadFile(const char* input_file_path, sfntly::ByteVector* input_buffer) {
assert(input_file_path);
assert(input_buffer);
FILE* input_file = NULL;
#if defined WIN32
fopen_s(&input_file, input_file_path, "rb");
#else
input_file = fopen(input_file_path, "rb");
#endif
if (input_file == NULL) {
return false;
}
fseek(input_file, 0, SEEK_END);
size_t file_size = ftell(input_file);
fseek(input_file, 0, SEEK_SET);
input_buffer->resize(file_size);
size_t bytes_read = fread(&((*input_buffer)[0]), 1, file_size, input_file);
fclose(input_file);
return bytes_read == file_size;
}
bool SaveFile(const char* output_file_path, const unsigned char* output_buffer,
int buffer_length) {
int byte_count = 0;
if (buffer_length > 0) {
FILE* output_file = NULL;
#if defined WIN32
fopen_s(&output_file, output_file_path, "wb");
#else
output_file = fopen(output_file_path, "wb");
#endif
if (output_file) {
byte_count = fwrite(output_buffer, 1, buffer_length, output_file);
fflush(output_file);
fclose(output_file);
}
return buffer_length == byte_count;
}
return false;
}
bool StringToGlyphId(const char* input, std::vector<unsigned int>* glyph_ids) {
assert(input);
std::string hex_csv = input;
size_t start = 0;
size_t end = hex_csv.find_first_of(",");
while (end != std::string::npos) {
glyph_ids->push_back(
HexTo<unsigned int>(hex_csv.substr(start, end - start).c_str()));
start = end + 1;
end = hex_csv.find_first_of(",", start);
}
glyph_ids->push_back(HexTo<unsigned int>(hex_csv.substr(start).c_str()));
return glyph_ids->size() > 0;
}
int main(int argc, char** argv) {
if (argc < 5) {
fprintf(stderr,
"Usage: %s <input path> <output path> <font name> <glyph ids>\n",
argv[0]);
fprintf(stderr, "\tGlyph ids are comma separated hex values\n");
fprintf(stderr, "\te.g. 20,1a,3b,4f\n");
return 0;
}
sfntly::ByteVector input_buffer;
if (!LoadFile(argv[1], &input_buffer)) {
fprintf(stderr, "ERROR: unable to load font file %s\n", argv[1]);
return 0;
}
std::vector<unsigned int> glyph_ids;
if (!StringToGlyphId(argv[4], &glyph_ids)) {
fprintf(stderr, "ERROR: unable to parse input glyph id\n");
return 0;
}
unsigned char* output_buffer = NULL;
int output_length =
SfntlyWrapper::SubsetFont(argv[3],
&(input_buffer[0]),
input_buffer.size(),
&(glyph_ids[0]),
glyph_ids.size(),
&output_buffer);
int result = SaveFile(argv[2], output_buffer, output_length) ? 1 : 0;
delete[] output_buffer;
return result;
}

Просмотреть файл

@ -1,60 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 "font_subsetter.h"
#include "subsetter_impl.h"
int SfntlyWrapper::SubsetFont(const char* font_name,
const unsigned char* original_font,
size_t font_size,
const unsigned int* glyph_ids,
size_t glyph_count,
unsigned char** output_buffer) {
if (output_buffer == NULL ||
original_font == NULL || font_size == 0 ||
glyph_ids == NULL || glyph_count == 0) {
return 0;
}
sfntly::SubsetterImpl subsetter;
if (!subsetter.LoadFont(font_name, original_font, font_size)) {
return -1; // Load error or font not found.
}
return subsetter.SubsetFont(glyph_ids, glyph_count, output_buffer);
}
int SfntlyWrapper::SubsetFont(int font_index,
const unsigned char* original_font,
size_t font_size,
const unsigned int* glyph_ids,
size_t glyph_count,
unsigned char** output_buffer) {
if (output_buffer == NULL ||
original_font == NULL || font_size == 0 ||
glyph_ids == NULL || glyph_count == 0) {
return 0;
}
sfntly::SubsetterImpl subsetter;
if (!subsetter.LoadFont(font_index, original_font, font_size)) {
return -1; // Load error or font not found.
}
return subsetter.SubsetFont(glyph_ids, glyph_count, output_buffer);
}

Просмотреть файл

@ -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.
*/
// File is originally from Chromium third_party/sfntly/src/subsetter.
// Use as test case in sfntly so that problems can be caught in upstream early.
#ifndef SFNTLY_CPP_SRC_TEST_FONT_SUBSETTER_H_
#define SFNTLY_CPP_SRC_TEST_FONT_SUBSETTER_H_
#include <stddef.h>
class SfntlyWrapper {
public:
// Font subsetting API
//
// Input TTF/TTC/OTF fonts, specify the glyph IDs to subset, and the subset
// font is returned in |output_buffer| (caller to delete[]). Return value is
// the length of output_buffer allocated.
//
// If subsetting fails, a negative value is returned. If none of the glyph
// IDs specified is found, the function will return 0.
//
// |font_name| Font name, required for TTC files. If specified NULL,
// the first available font is selected.
// |original_font| Original font file contents.
// |font_size| Size of |original_font| in bytes.
// |glyph_ids| Glyph IDs to subset. If the specified glyph ID is not
// found in the font file, it will be ignored silently.
// |glyph_count| Number of glyph IDs in |glyph_ids|
// |output_buffer| Generated subset font. Caller to delete[].
static int SubsetFont(const char* font_name,
const unsigned char* original_font,
size_t font_size,
const unsigned int* glyph_ids,
size_t glyph_count,
unsigned char** output_buffer);
// Font subsetting API
//
// Input TTF/TTC/OTF fonts, specify the glyph IDs to subset, and the subset
// font is returned in |output_buffer| (caller to delete[]). Return value is
// the length of output_buffer allocated.
//
// If subsetting fails, a negative value is returned. If none of the glyph
// IDs specified is found, the function will return 0.
//
// |font_name| Font index, ignored for non-TTC files, 0-indexed.
// |original_font| Original font file contents.
// |font_size| Size of |original_font| in bytes.
// |glyph_ids| Glyph IDs to subset. If the specified glyph ID is not
// found in the font file, it will be ignored silently.
// |glyph_count| Number of glyph IDs in |glyph_ids|
// |output_buffer| Generated subset font. Caller to delete[].
static int SubsetFont(int font_index,
const unsigned char* original_font,
size_t font_size,
const unsigned int* glyph_ids,
size_t glyph_count,
unsigned char** output_buffer);
};
#endif // SFNTLY_CPP_SRC_TEST_FONT_SUBSETTER_H_

Просмотреть файл

@ -1,848 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 "subsetter_impl.h"
#include <string.h>
#include <algorithm>
#include <iterator>
#include <limits>
#include <map>
#include <set>
#include <string>
#include <unicode/ustring.h>
#include <unicode/uversion.h>
#include "sfntly/table/bitmap/eblc_table.h"
#include "sfntly/table/bitmap/ebdt_table.h"
#include "sfntly/table/bitmap/index_sub_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"
#include "sfntly/table/core/name_table.h"
#include "sfntly/tag.h"
#include "sfntly/data/memory_byte_array.h"
#include "sfntly/port/memory_input_stream.h"
#include "sfntly/port/memory_output_stream.h"
namespace {
using namespace sfntly;
/**
* std::u16string and icu::UnicodeString can't be used here.
* UChar is not always char16_t in some platforms. std::u16string is avoided.
* icu::UnicodeString C++ API is also avoided to make it more portable across
* platforms due to C++ ABI compatility issue.
*/
typedef std::basic_string<UChar> UCharString;
// The bitmap tables must be greater than 16KB to trigger bitmap subsetter.
static const int BITMAP_SIZE_THRESHOLD = 16384;
void ConstructName(UChar* name_part, UCharString* name, int32_t name_id) {
switch (name_id) {
case NameId::kFullFontName:
*name = name_part;
break;
case NameId::kFontFamilyName:
case NameId::kPreferredFamily:
case NameId::kWWSFamilyName: {
UCharString original = *name;
*name = name_part;
*name += original;
break;
}
case NameId::kFontSubfamilyName:
case NameId::kPreferredSubfamily:
case NameId::kWWSSubfamilyName:
*name += name_part;
break;
default:
// This name part is not used to construct font name (e.g. copyright).
// Simply ignore it.
break;
}
}
// Convert UTF-8 string into UTF-16 string.
//
// Ill-formed input is replaced with U+FFFD.
// Otherwise, return empty string if other error occurs during the conversion.
UCharString ConvertFromUtf8(const char* src) {
int32_t srcLength = strlen(src);
int32_t destCapacity = srcLength + 1;
UChar* buffer = new UChar[destCapacity];
UCharString dest;
if (buffer == NULL) {
return dest;
}
int32_t destLength;
UErrorCode errorCode = U_ZERO_ERROR;
u_strFromUTF8WithSub(buffer, destCapacity, &destLength, src, srcLength,
0xfffd, // Unicode replacement character
NULL,
&errorCode);
if (U_SUCCESS(errorCode)) {
dest.append(buffer, destLength);
}
delete[] buffer;
return dest;
}
int32_t CaseCompareUtf16(const UCharString& str1,
const UCharString& str2, uint32_t option) {
UErrorCode errorCode = U_ZERO_ERROR;
return u_strCaseCompare(str1.c_str(), str1.length(), str2.c_str(),
str2.length(), option, &errorCode);
}
int32_t HashCode(int32_t platform_id, int32_t encoding_id, int32_t language_id,
int32_t name_id) {
int32_t result = platform_id << 24 | encoding_id << 16 | language_id << 8;
if (name_id == NameId::kFullFontName) {
result |= 0xff;
} else if (name_id == NameId::kPreferredFamily ||
name_id == NameId::kPreferredSubfamily) {
result |= 0xf;
} else if (name_id == NameId::kWWSFamilyName ||
name_id == NameId::kWWSSubfamilyName) {
result |= 1;
}
return result;
}
bool HasName(const char* font_name, Font* font) {
UCharString font_string = ConvertFromUtf8(font_name);
if (font_string.empty())
return false;
UCharString regular_suffix = ConvertFromUtf8(" Regular");
UCharString alt_font_string = font_string;
alt_font_string += regular_suffix;
typedef std::map<int32_t, UCharString> NameMap;
NameMap names;
NameTablePtr name_table = down_cast<NameTable*>(font->GetTable(Tag::name));
if (name_table == NULL) {
return false;
}
for (int32_t i = 0; i < name_table->NameCount(); ++i) {
switch (name_table->NameId(i)) {
case NameId::kFontFamilyName:
case NameId::kFontSubfamilyName:
case NameId::kFullFontName:
case NameId::kPreferredFamily:
case NameId::kPreferredSubfamily:
case NameId::kWWSFamilyName:
case NameId::kWWSSubfamilyName: {
UChar* name_part = name_table->Name(i);
if (name_part == NULL) {
continue;
}
int32_t hash_code = HashCode(name_table->PlatformId(i),
name_table->EncodingId(i),
name_table->LanguageId(i),
name_table->NameId(i));
ConstructName(name_part, &(names[hash_code]), name_table->NameId(i));
delete[] name_part;
break;
}
default:
break;
}
}
if (!names.empty()) {
for (NameMap::iterator i = names.begin(), e = names.end(); i != e; ++i) {
if (CaseCompareUtf16(i->second, font_string, 0) == 0 ||
CaseCompareUtf16(i->second, alt_font_string, 0) == 0) {
return true;
}
}
}
return false;
}
Font* FindFont(const char* font_name, const FontArray& font_array) {
if (font_array.empty() || font_array[0] == NULL) {
return NULL;
}
if (font_name && strlen(font_name)) {
for (FontArray::const_iterator i = font_array.begin(), e = font_array.end();
i != e; ++i) {
if (HasName(font_name, i->p_)) {
return i->p_;
}
}
}
return font_array[0].p_;
}
bool ResolveCompositeGlyphs(GlyphTable* glyph_table,
LocaTable* loca_table,
const unsigned int* glyph_ids,
size_t glyph_count,
IntegerSet* glyph_id_processed) {
if (glyph_table == NULL || loca_table == NULL ||
glyph_ids == NULL || glyph_count == 0 || glyph_id_processed == NULL) {
return false;
}
// Sort and uniquify glyph ids.
IntegerSet glyph_id_remaining;
glyph_id_remaining.insert(0); // Always include glyph id 0.
for (size_t i = 0; i < glyph_count; ++i) {
glyph_id_remaining.insert(glyph_ids[i]);
}
// Identify if any given glyph id maps to a composite glyph. If so, include
// the glyphs referenced by that composite glyph.
while (!glyph_id_remaining.empty()) {
IntegerSet comp_glyph_id;
for (IntegerSet::iterator i = glyph_id_remaining.begin(),
e = glyph_id_remaining.end(); i != e; ++i) {
if (*i < 0 || *i >= loca_table->num_glyphs()) {
// Invalid glyph id, ignore.
continue;
}
int32_t length = loca_table->GlyphLength(*i);
if (length == 0) {
// Empty glyph, ignore.
continue;
}
int32_t offset = loca_table->GlyphOffset(*i);
GlyphPtr glyph;
glyph.Attach(glyph_table->GetGlyph(offset, length));
if (glyph == NULL) {
// Error finding glyph, ignore.
continue;
}
if (glyph->GlyphType() == GlyphType::kComposite) {
Ptr<GlyphTable::CompositeGlyph> comp_glyph =
down_cast<GlyphTable::CompositeGlyph*>(glyph.p_);
for (int32_t j = 0; j < comp_glyph->NumGlyphs(); ++j) {
int32_t glyph_id = comp_glyph->GlyphIndex(j);
if (glyph_id_processed->find(glyph_id) == glyph_id_processed->end() &&
glyph_id_remaining.find(glyph_id) == glyph_id_remaining.end()) {
comp_glyph_id.insert(comp_glyph->GlyphIndex(j));
}
}
}
glyph_id_processed->insert(*i);
}
glyph_id_remaining.clear();
glyph_id_remaining = comp_glyph_id;
}
return true;
}
bool SetupGlyfBuilders(Font::Builder* font_builder,
GlyphTable* glyph_table,
LocaTable* loca_table,
const IntegerSet& glyph_ids) {
if (!font_builder || !glyph_table || !loca_table) {
return false;
}
GlyphTableBuilderPtr glyph_table_builder =
down_cast<GlyphTable::Builder*>(font_builder->NewTableBuilder(Tag::glyf));
LocaTableBuilderPtr loca_table_builder =
down_cast<LocaTable::Builder*>(font_builder->NewTableBuilder(Tag::loca));
if (glyph_table_builder == NULL || loca_table_builder == NULL) {
// Out of memory.
return false;
}
// Extract glyphs and setup loca list.
IntegerList loca_list;
loca_list.resize(loca_table->num_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 (IntegerSet::const_iterator i = glyph_ids.begin(), e = glyph_ids.end();
i != e; ++i) {
int32_t length = loca_table->GlyphLength(*i);
int32_t offset = loca_table->GlyphOffset(*i);
GlyphPtr glyph;
glyph.Attach(glyph_table->GetGlyph(offset, length));
// Add glyph to new glyf table.
ReadableFontDataPtr data = glyph->ReadFontData();
WritableFontDataPtr 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);
// Configure loca list.
for (int32_t j = last_glyph_id + 1; j <= *i; ++j) {
loca_list[j] = last_offset;
}
if (last_offset > std::numeric_limits<int32_t>::max() - length)
return false;
last_offset += length;
loca_list[*i + 1] = last_offset;
last_glyph_id = *i;
}
for (int32_t j = last_glyph_id + 1; j <= loca_table->num_glyphs(); ++j) {
loca_list[j] = last_offset;
}
loca_table_builder->SetLocaList(&loca_list);
return true;
}
bool HasOverlap(int32_t range_begin, int32_t range_end,
const IntegerSet& glyph_ids) {
if (range_begin == range_end)
return glyph_ids.find(range_begin) != glyph_ids.end();
if (range_begin >= range_end)
return false;
IntegerSet::const_iterator left = glyph_ids.lower_bound(range_begin);
IntegerSet::const_iterator right = glyph_ids.lower_bound(range_end);
return left != right;
}
// Initialize builder, returns false if glyph_id subset is not covered.
// Not thread-safe, caller to ensure object life-time.
bool InitializeBitmapBuilder(EbdtTable::Builder* ebdt, EblcTable::Builder* eblc,
const IntegerSet& glyph_ids) {
BitmapLocaList loca_list;
BitmapSizeTableBuilderList* strikes = eblc->BitmapSizeBuilders();
// Note: Do not call eblc_builder->GenerateLocaList(&loca_list) and then
// ebdt_builder->SetLoca(loca_list). For fonts like SimSun, there are
// >28K glyphs inside, where a typical usage will be <1K glyphs. Doing
// the calls improperly will result in creation of >100K objects that
// will be destroyed immediately, inducing significant slowness.
IntegerList removed_strikes;
for (size_t i = 0; i < strikes->size(); i++) {
if (!HasOverlap((*strikes)[i]->StartGlyphIndex(),
(*strikes)[i]->EndGlyphIndex(), glyph_ids)) {
removed_strikes.push_back(i);
continue;
}
IndexSubTableBuilderList* index_builders =
(*strikes)[i]->IndexSubTableBuilders();
IntegerList removed_indexes;
BitmapGlyphInfoMap info_map;
for (size_t j = 0; j < index_builders->size(); ++j) {
if ((*index_builders)[j] == NULL) {
// Subtable is malformed, let's just skip it.
removed_indexes.push_back(j);
continue;
}
int32_t first_glyph_id = (*index_builders)[j]->first_glyph_index();
int32_t last_glyph_id = (*index_builders)[j]->last_glyph_index();
if (!HasOverlap(first_glyph_id, last_glyph_id, glyph_ids)) {
removed_indexes.push_back(j);
continue;
}
for (IntegerSet::const_iterator gid = glyph_ids.begin(),
gid_end = glyph_ids.end();
gid != gid_end; gid++) {
if (*gid < first_glyph_id) {
continue;
}
if (*gid > last_glyph_id) {
break;
}
BitmapGlyphInfoPtr info;
info.Attach((*index_builders)[j]->GlyphInfo(*gid));
if (info && info->length()) { // Do not include gid without bitmap
info_map[*gid] = info;
}
}
}
if (!info_map.empty()) {
loca_list.push_back(info_map);
} else {
removed_strikes.push_back(i); // Detected null entries.
}
// Remove unused index sub tables
for (IntegerList::reverse_iterator j = removed_indexes.rbegin(),
e = removed_indexes.rend();
j != e; j++) {
index_builders->erase(index_builders->begin() + *j);
}
}
if (removed_strikes.size() == strikes->size() || loca_list.empty()) {
return false;
}
for (IntegerList::reverse_iterator i = removed_strikes.rbegin(),
e = removed_strikes.rend(); i != e; i++) {
strikes->erase(strikes->begin() + *i);
}
if (strikes->empty()) { // no glyph covered, can safely drop the builders.
return false;
}
ebdt->SetLoca(&loca_list);
ebdt->GlyphBuilders(); // Initialize the builder.
return true;
}
void CopyBigGlyphMetrics(BigGlyphMetrics::Builder* source,
BigGlyphMetrics::Builder* target) {
target->SetHeight(static_cast<uint8_t>(source->Height()));
target->SetWidth(static_cast<uint8_t>(source->Width()));
target->SetHoriBearingX(static_cast<uint8_t>(source->HoriBearingX()));
target->SetHoriBearingY(static_cast<uint8_t>(source->HoriBearingY()));
target->SetHoriAdvance(static_cast<uint8_t>(source->HoriAdvance()));
target->SetVertBearingX(static_cast<uint8_t>(source->VertBearingX()));
target->SetVertBearingY(static_cast<uint8_t>(source->VertBearingY()));
target->SetVertAdvance(static_cast<uint8_t>(source->VertAdvance()));
}
CALLER_ATTACH IndexSubTable::Builder*
ConstructIndexFormat4(IndexSubTable::Builder* b, const BitmapGlyphInfoMap& loca,
int32_t* image_data_offset) {
IndexSubTableFormat4BuilderPtr builder4;
builder4.Attach(IndexSubTableFormat4::Builder::CreateBuilder());
CodeOffsetPairBuilderList offset_pairs;
size_t offset = 0;
int32_t lower_bound = b->first_glyph_index();
int32_t upper_bound = b->last_glyph_index();
int32_t last_gid = -1;
BitmapGlyphInfoMap::const_iterator i = loca.lower_bound(lower_bound);
BitmapGlyphInfoMap::const_iterator end = loca.end();
if (i != end) {
last_gid = i->first;
builder4->set_first_glyph_index(last_gid);
builder4->set_image_format(b->image_format());
builder4->set_image_data_offset(*image_data_offset);
}
for (; i != end; i++) {
int32_t gid = i->first;
if (gid > upper_bound) {
break;
}
offset_pairs.push_back(
IndexSubTableFormat4::CodeOffsetPairBuilder(gid, offset));
offset += i->second->length();
last_gid = gid;
}
offset_pairs.push_back(
IndexSubTableFormat4::CodeOffsetPairBuilder(-1, offset));
builder4->set_last_glyph_index(last_gid);
*image_data_offset += offset;
builder4->SetOffsetArray(offset_pairs);
return builder4.Detach();
}
CALLER_ATTACH IndexSubTable::Builder*
ConstructIndexFormat5(IndexSubTable::Builder* b, const BitmapGlyphInfoMap& loca,
int32_t* image_data_offset) {
IndexSubTableFormat5BuilderPtr new_builder;
new_builder.Attach(IndexSubTableFormat5::Builder::CreateBuilder());
// Copy BigMetrics
int32_t image_size = 0;
if (b->index_format() == IndexSubTable::Format::FORMAT_2) {
IndexSubTableFormat2BuilderPtr builder2 =
down_cast<IndexSubTableFormat2::Builder*>(b);
CopyBigGlyphMetrics(builder2->BigMetrics(), new_builder->BigMetrics());
image_size = builder2->ImageSize();
} else {
IndexSubTableFormat5BuilderPtr builder5 =
down_cast<IndexSubTableFormat5::Builder*>(b);
BigGlyphMetricsBuilderPtr metrics_builder;
CopyBigGlyphMetrics(builder5->BigMetrics(), new_builder->BigMetrics());
image_size = builder5->ImageSize();
}
IntegerList* glyph_array = new_builder->GlyphArray();
size_t offset = 0;
int32_t lower_bound = b->first_glyph_index();
int32_t upper_bound = b->last_glyph_index();
int32_t last_gid = -1;
BitmapGlyphInfoMap::const_iterator i = loca.lower_bound(lower_bound);
BitmapGlyphInfoMap::const_iterator end = loca.end();
if (i != end) {
last_gid = i->first;
new_builder->set_first_glyph_index(last_gid);
new_builder->set_image_format(b->image_format());
new_builder->set_image_data_offset(*image_data_offset);
new_builder->SetImageSize(image_size);
}
for (; i != end; i++) {
int32_t gid = i->first;
if (gid > upper_bound) {
break;
}
glyph_array->push_back(gid);
offset += i->second->length();
last_gid = gid;
}
new_builder->set_last_glyph_index(last_gid);
*image_data_offset += offset;
return new_builder.Detach();
}
CALLER_ATTACH IndexSubTable::Builder*
SubsetIndexSubTable(IndexSubTable::Builder* builder,
const BitmapGlyphInfoMap& loca,
int32_t* image_data_offset) {
switch (builder->index_format()) {
case IndexSubTable::Format::FORMAT_1:
case IndexSubTable::Format::FORMAT_3:
case IndexSubTable::Format::FORMAT_4:
return ConstructIndexFormat4(builder, loca, image_data_offset);
case IndexSubTable::Format::FORMAT_2:
case IndexSubTable::Format::FORMAT_5:
return ConstructIndexFormat5(builder, loca, image_data_offset);
default:
assert(false);
break;
}
return NULL;
}
}
namespace sfntly {
// Not thread-safe, caller to ensure object life-time.
void SubsetEBLC(EblcTable::Builder* eblc, const BitmapLocaList& new_loca) {
BitmapSizeTableBuilderList* size_builders = eblc->BitmapSizeBuilders();
if (size_builders == NULL) {
return;
}
int32_t image_data_offset = EbdtTable::Offset::kHeaderLength;
for (size_t strike = 0; strike < size_builders->size(); ++strike) {
IndexSubTableBuilderList* index_builders =
(*size_builders)[strike]->IndexSubTableBuilders();
for (size_t index = 0; index < index_builders->size(); ++index) {
IndexSubTable::Builder* new_builder_raw =
SubsetIndexSubTable((*index_builders)[index], new_loca[strike],
&image_data_offset);
if (NULL != new_builder_raw) {
(*index_builders)[index].Attach(new_builder_raw);
}
}
}
}
// EBLC structure (from stuartg)
// header
// bitmapSizeTable[]
// one per strike
// holds strike metrics - sbitLineMetrics
// holds info about indexSubTableArray
// indexSubTableArray[][]
// one per strike and then one per indexSubTable for that strike
// holds info about the indexSubTable
// the indexSubTable entries pointed to can be of different formats
// indexSubTable
// one per indexSubTableArray entry
// tells how to get the glyphs
// may hold the glyph metrics if they are uniform for all the glyphs in range
// Please note that the structure can also be
// {indexSubTableArray[], indexSubTables[]}[]
// This way is also legal and in fact how Microsoft fonts are laid out.
//
// There is nothing that says that the indexSubTableArray entries and/or the
// indexSubTable items need to be unique. They may be shared between strikes.
//
// EBDT structure:
// header
// glyphs
// amorphous blob of data
// different glyphs that are only able to be figured out from the EBLC table
// may hold metrics - depends on the EBLC entry that pointed to them
// Subsetting EBLC table (from arthurhsu)
// Most pages use only a fraction (hundreds or less) glyphs out of a given font
// (which can have >20K glyphs for CJK). It's safe to assume that the subset
// font will have sparse bitmap glyphs. So we reconstruct the EBLC table as
// format 4 or 5 here.
enum BuildersToRemove {
kRemoveNone,
kRemoveBDAT,
kRemoveBDATAndEBDT,
kRemoveEBDT
};
int SetupBitmapBuilders(Font* font, Font::Builder* font_builder,
const IntegerSet& glyph_ids) {
if (!font || !font_builder) {
return false;
}
// Check if bitmap table exists.
EbdtTablePtr ebdt_table = down_cast<EbdtTable*>(font->GetTable(Tag::EBDT));
EblcTablePtr eblc_table = down_cast<EblcTable*>(font->GetTable(Tag::EBLC));
bool use_ebdt = (ebdt_table != NULL && eblc_table != NULL);
if (!use_ebdt) {
ebdt_table = down_cast<EbdtTable*>(font->GetTable(Tag::bdat));
eblc_table = down_cast<EblcTable*>(font->GetTable(Tag::bloc));
if (ebdt_table == NULL || eblc_table == NULL) {
return kRemoveNone;
}
}
// If the bitmap table's size is too small, skip subsetting.
if (ebdt_table->DataLength() + eblc_table->DataLength() <
BITMAP_SIZE_THRESHOLD) {
return use_ebdt ? kRemoveBDAT : kRemoveNone;
}
// Get the builders.
EbdtTableBuilderPtr ebdt_table_builder = down_cast<EbdtTable::Builder*>(
font_builder->NewTableBuilder(use_ebdt ? Tag::EBDT : Tag::bdat,
ebdt_table->ReadFontData()));
EblcTableBuilderPtr eblc_table_builder = down_cast<EblcTable::Builder*>(
font_builder->NewTableBuilder(use_ebdt ? Tag::EBLC : Tag::bloc,
eblc_table->ReadFontData()));
if (ebdt_table_builder == NULL || eblc_table_builder == NULL) {
// Out of memory.
return use_ebdt ? kRemoveBDAT : kRemoveNone;
}
if (!InitializeBitmapBuilder(ebdt_table_builder, eblc_table_builder,
glyph_ids)) {
// Bitmap tables do not cover the glyphs in our subset.
font_builder->RemoveTableBuilder(use_ebdt ? Tag::EBLC : Tag::bloc);
font_builder->RemoveTableBuilder(use_ebdt ? Tag::EBDT : Tag::bdat);
return use_ebdt ? kRemoveBDATAndEBDT : kRemoveEBDT;
}
BitmapLocaList new_loca;
ebdt_table_builder->GenerateLocaList(&new_loca);
SubsetEBLC(eblc_table_builder, new_loca);
return use_ebdt ? kRemoveBDAT : kRemoveNone;
}
SubsetterImpl::SubsetterImpl() {
}
SubsetterImpl::~SubsetterImpl() {
}
bool SubsetterImpl::LoadFont(int font_index,
const unsigned char* original_font,
size_t font_size) {
MemoryInputStream mis;
mis.Attach(original_font, font_size);
if (factory_ == NULL) {
factory_.Attach(FontFactory::GetInstance());
}
FontArray font_array;
factory_->LoadFonts(&mis, &font_array);
if (font_index < 0 || (size_t)font_index >= font_array.size()) {
return false;
}
font_ = font_array[font_index].p_;
return font_ != NULL;
}
bool SubsetterImpl::LoadFont(const char* font_name,
const unsigned char* original_font,
size_t font_size) {
MemoryInputStream mis;
mis.Attach(original_font, font_size);
if (factory_ == NULL) {
factory_.Attach(FontFactory::GetInstance());
}
FontArray font_array;
factory_->LoadFonts(&mis, &font_array);
font_ = FindFont(font_name, font_array);
return font_ != NULL;
}
int SubsetterImpl::SubsetFont(const unsigned int* glyph_ids,
size_t glyph_count,
unsigned char** output_buffer) {
if (factory_ == NULL || font_ == NULL) {
return -1;
}
// Find glyf and loca table.
GlyphTablePtr glyph_table =
down_cast<GlyphTable*>(font_->GetTable(Tag::glyf));
LocaTablePtr loca_table = down_cast<LocaTable*>(font_->GetTable(Tag::loca));
if (glyph_table == NULL || loca_table == NULL) {
// We are not able to subset the font.
return 0;
}
IntegerSet glyph_id_processed;
if (!ResolveCompositeGlyphs(glyph_table, loca_table,
glyph_ids, glyph_count, &glyph_id_processed) ||
glyph_id_processed.empty()) {
return 0;
}
FontPtr new_font;
new_font.Attach(Subset(glyph_id_processed, glyph_table, loca_table));
if (new_font == NULL) {
return 0;
}
MemoryOutputStream output_stream;
factory_->SerializeFont(new_font, &output_stream);
size_t length = output_stream.Size();
if (length == 0 ||
length > static_cast<size_t>(std::numeric_limits<int>::max())) {
return 0;
}
*output_buffer = new unsigned char[length];
memcpy(*output_buffer, output_stream.Get(), length);
return length;
}
// Long comments regarding TTF tables and PDF (from stuartg)
//
// According to PDF spec 1.4 (section 5.8), the following tables must be
// present:
// head, hhea, loca, maxp, cvt, prep, glyf, hmtx, fpgm
// cmap if font is used with a simple font dict and not a CIDFont dict
//
// Other tables we need to keep for PDF rendering to support zoom in/out:
// bdat, bloc, ebdt, eblc, ebsc, gasp
//
// Special table:
// CFF - if you have this table then you shouldn't have a glyf table and this
// is the table with all the glyphs. Shall skip subsetting completely
// since sfntly is not capable of subsetting it for now.
// post - extra info here for printing on PostScript printers but maybe not
// enough to outweigh the space taken by the names
//
// Tables to break apart:
// name - could throw away all but one language and one platform strings/ might
// throw away some of the name entries
// cmap - could strip out non-needed cmap subtables
// - format 4 subtable can be subsetted as well using sfntly
//
// Graphite tables:
// silf, glat, gloc, feat - should be okay to strip out
//
// Tables that can be discarded:
// OS/2 - everything here is for layout and description of the font that is
// elsewhere (some in the PDF objects)
// BASE, GDEF, GSUB, GPOS, JSTF - all used for layout
// kern - old style layout
// DSIG - this will be invalid after subsetting
// hdmx - layout
// PCLT - metadata that's not needed
// vmtx - layout
// vhea - layout
// VDMX
// VORG - not used by TT/OT - used by CFF
// hsty - would be surprised to see one of these - used on the Newton
// AAT tables - mort, morx, feat, acnt, bsin, just, lcar, fdsc, fmtx, prop,
// Zapf, opbd, trak, fvar, gvar, avar, cvar
// - these are all layout tables and once layout happens are not
// needed anymore
// LTSH - layout
CALLER_ATTACH
Font* SubsetterImpl::Subset(const IntegerSet& glyph_ids, GlyphTable* glyf,
LocaTable* loca) {
// The const is initialized here to workaround VC bug of rendering all Tag::*
// as 0. These tags represents the TTF tables that we will embed in subset
// font.
const int32_t TABLES_IN_SUBSET[] = {
Tag::head, Tag::hhea, Tag::loca, Tag::maxp, Tag::cvt,
Tag::prep, Tag::glyf, Tag::hmtx, Tag::fpgm, Tag::EBDT,
Tag::EBLC, Tag::EBSC, Tag::bdat, Tag::bloc, Tag::bhed,
Tag::cmap, // Keep here for future tagged PDF development.
Tag::name, // Keep here due to legal concerns: copyright info inside.
};
const size_t kTablesInSubSetSize =
sizeof(TABLES_IN_SUBSET) / sizeof(TABLES_IN_SUBSET[0]);
// Setup font builders we need.
FontBuilderPtr font_builder;
font_builder.Attach(factory_->NewFontBuilder());
IntegerSet remove_tags;
if (SetupGlyfBuilders(font_builder, glyf, loca, glyph_ids)) {
remove_tags.insert(Tag::glyf);
remove_tags.insert(Tag::loca);
}
// For old Apple bitmap fonts, they have only bdats and bhed is identical
// to head. As a result, we can't remove bdat tables for those fonts.
int setup_result = SetupBitmapBuilders(font_, font_builder, glyph_ids);
if (setup_result == kRemoveBDATAndEBDT || setup_result == kRemoveEBDT) {
remove_tags.insert(Tag::EBDT);
remove_tags.insert(Tag::EBLC);
remove_tags.insert(Tag::EBSC);
}
if (setup_result == kRemoveBDAT || setup_result == kRemoveBDATAndEBDT) {
remove_tags.insert(Tag::bdat);
remove_tags.insert(Tag::bloc);
remove_tags.insert(Tag::bhed);
}
IntegerSet allowed_tags;
for (size_t i = 0; i < kTablesInSubSetSize; ++i)
allowed_tags.insert(TABLES_IN_SUBSET[i]);
IntegerSet result;
std::set_difference(allowed_tags.begin(), allowed_tags.end(),
remove_tags.begin(), remove_tags.end(),
std::inserter(result, result.end()));
allowed_tags = result;
// Setup remaining builders.
for (IntegerSet::const_iterator it = allowed_tags.begin();
it != allowed_tags.end(); ++it) {
int32_t tag = *it;
Table* table = font_->GetTable(tag);
if (table)
font_builder->NewTableBuilder(tag, table->ReadFontData());
}
return font_builder->Build();
}
} // namespace sfntly

Просмотреть файл

@ -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.
*/
// File is originally from Chromium third_party/sfntly/src/subsetter.
// Use as test case in sfntly so that problems can be caught in upstream early.
#ifndef SFNTLY_CPP_SRC_TEST_SUBSETTER_IMPL_H_
#define SFNTLY_CPP_SRC_TEST_SUBSETTER_IMPL_H_
#include "sfntly/font.h"
#include "sfntly/font_factory.h"
#include "sfntly/table/truetype/glyph_table.h"
#include "sfntly/table/truetype/loca_table.h"
#include "sfntly/tag.h"
namespace sfntly {
// 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
class SubsetterImpl {
public:
SubsetterImpl();
~SubsetterImpl();
bool LoadFont(const char* font_name,
const unsigned char* original_font,
size_t font_size);
bool LoadFont(int font_index,
const unsigned char* original_font,
size_t font_size);
int SubsetFont(const unsigned int* glyph_ids,
size_t glyph_count,
unsigned char** output_buffer);
private:
CALLER_ATTACH Font* Subset(const IntegerSet& glyph_ids,
GlyphTable* glyf, LocaTable* loca);
FontFactoryPtr factory_;
FontPtr font_;
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_TEST_SUBSETTER_IMPL_H_

Просмотреть файл

@ -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.
*/
#include <stdio.h>
#if _MSC_VER > 12
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif
#include "sample/subsetter/subset_util.h"
int main(int argc, char** argv) {
#ifdef _CRTDBG_MAP_ALLOC
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
if (argc < 3) {
printf("Usage: subsetter <font file> <output file>\n");
return 0;
}
sfntly::SubsetUtil subset_util;
subset_util.Subset(argv[1], argv[2]);
#ifdef _CRTDBG_MAP_ALLOC
_CrtDumpMemoryLeaks();
#endif
return 0;
}

Просмотреть файл

@ -1,98 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Remove VC++ nag on fopen.
#define _CRT_SECURE_NO_WARNINGS
#include "sample/subsetter/subset_util.h"
#include <stdio.h>
#include <vector>
#include <memory>
#include "sfntly/font.h"
#include "sfntly/data/memory_byte_array.h"
#include "sfntly/port/memory_output_stream.h"
#include "sfntly/port/type.h"
#include "sfntly/tag.h"
#include "sfntly/tools/subsetter/subsetter.h"
namespace sfntly {
SubsetUtil::SubsetUtil() {
}
SubsetUtil::~SubsetUtil() {
}
void SubsetUtil::Subset(const char *input_file_path,
const char *output_file_path) {
UNREFERENCED_PARAMETER(output_file_path);
ByteVector input_buffer;
FILE* input_file = fopen(input_file_path, "rb");
if (input_file == NULL) {
fprintf(stderr, "file not found\n");
return;
}
fseek(input_file, 0, SEEK_END);
size_t file_size = ftell(input_file);
fseek(input_file, 0, SEEK_SET);
input_buffer.resize(file_size);
size_t bytes_read = fread(&(input_buffer[0]), 1, file_size, input_file);
UNREFERENCED_PARAMETER(bytes_read);
fclose(input_file);
FontFactoryPtr factory;
factory.Attach(FontFactory::GetInstance());
FontArray font_array;
factory->LoadFonts(&input_buffer, &font_array);
if (font_array.empty() || font_array[0] == NULL)
return;
IntegerList glyphs;
for (int32_t i = 0; i < 10; i++) {
glyphs.push_back(i);
}
glyphs.push_back(11);
glyphs.push_back(10);
Ptr<Subsetter> subsetter = new Subsetter(font_array[0], factory);
subsetter->SetGlyphs(&glyphs);
IntegerSet remove_tables;
remove_tables.insert(Tag::DSIG);
subsetter->SetRemoveTables(&remove_tables);
FontBuilderPtr font_builder;
font_builder.Attach(subsetter->Subset());
FontPtr new_font;
new_font.Attach(font_builder->Build());
// TODO(arthurhsu): glyph renumbering/Loca table
// TODO(arthurhsu): alter CMaps
MemoryOutputStream output_stream;
factory->SerializeFont(new_font, &output_stream);
FILE* output_file = fopen(output_file_path, "wb");
fwrite(output_stream.Get(), 1, output_stream.Size(), output_file);
fflush(output_file);
fclose(output_file);
}
} // namespace sfntly

Просмотреть файл

@ -1,32 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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_SAMPLE_SUBSETTER_SUBSET_UTIL_H_
#define SFNTLY_CPP_SRC_SAMPLE_SUBSETTER_SUBSET_UTIL_H_
namespace sfntly {
class SubsetUtil {
public:
SubsetUtil();
virtual ~SubsetUtil();
void Subset(const char* input_file_path, const char* output_file_path);
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SAMPLE_SUBSETTER_SUBSET_UTIL_H_

Просмотреть файл

@ -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.
*/
#include "sfntly/port/refcount.h"
#include "subtly/character_predicate.h"
namespace subtly {
using namespace sfntly;
// AcceptRange predicate
AcceptRange::AcceptRange(int32_t start, int32_t end)
: start_(start),
end_(end) {
}
AcceptRange::~AcceptRange() {}
bool AcceptRange::operator()(int32_t character) const {
return start_ <= character && character <= end_;
}
// AcceptSet predicate
AcceptSet::AcceptSet(IntegerSet* characters)
: characters_(characters) {
}
AcceptSet::~AcceptSet() {
delete characters_;
}
bool AcceptSet::operator()(int32_t character) const {
return characters_->find(character) != characters_->end();
}
// AcceptAll predicate
bool AcceptAll::operator()(int32_t character) const {
UNREFERENCED_PARAMETER(character);
return true;
}
}

Просмотреть файл

@ -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.
*/
#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_CHARACTER_PREDICATE_H_
#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_CHARACTER_PREDICATE_H_
#include "sfntly/port/refcount.h"
#include "sfntly/port/type.h"
namespace subtly {
class CharacterPredicate : virtual public sfntly::RefCount {
public:
CharacterPredicate() {}
virtual ~CharacterPredicate() {}
virtual bool operator()(int32_t character) const = 0;
};
// All characters except for those between [start, end] are rejected
class AcceptRange : public CharacterPredicate,
public sfntly::RefCounted<AcceptRange> {
public:
AcceptRange(int32_t start, int32_t end);
~AcceptRange();
virtual bool operator()(int32_t character) const;
private:
int32_t start_;
int32_t end_;
};
// All characters in IntegerSet
// The set is OWNED by the predicate! Do not modify it.
// It will be freed when the predicate is destroyed.
class AcceptSet : public CharacterPredicate,
public sfntly::RefCounted<AcceptSet> {
public:
explicit AcceptSet(sfntly::IntegerSet* characters);
~AcceptSet();
virtual bool operator()(int32_t character) const;
private:
sfntly::IntegerSet* characters_;
};
// All characters
class AcceptAll : public CharacterPredicate,
public sfntly::RefCounted<AcceptAll> {
public:
AcceptAll() {}
~AcceptAll() {}
virtual bool operator()(int32_t character) const;
};
}
#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_CHARACTER_PREDICATE_H_

Просмотреть файл

@ -1,64 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 <stdio.h>
#include <stdlib.h>
#include <map>
#include <utility>
#include "sfntly/font.h"
#include "sfntly/table/core/cmap_table.h"
#include "sfntly/tag.h"
#include "subtly/stats.h"
#include "subtly/subsetter.h"
#include "subtly/utils.h"
using namespace subtly;
void PrintUsage(const char* program_name) {
fprintf(stdout, "Usage: %s <input_font_file>\n", program_name);
}
int main(int argc, const char** argv) {
const char* program_name = argv[0];
if (argc < 2) {
PrintUsage(program_name);
exit(1);
}
const char* input_font_path = argv[1];
const char* output_font_path = argv[2];
FontPtr font;
font.Attach(subtly::LoadFont(input_font_path));
int32_t original_size = TotalFontSize(font);
Ptr<Subsetter> subsetter = new Subsetter(font, NULL);
Ptr<Font> new_font;
new_font.Attach(subsetter->Subset());
if (!new_font) {
fprintf(stdout, "Cannot create subset.\n");
return 0;
}
subtly::SerializeFont(output_font_path, new_font);
subtly::PrintComparison(stdout, font, new_font);
int32_t new_size = TotalFontSize(new_font);
fprintf(stdout, "Went from %d to %d: %lf%% of original\n",
original_size, new_size,
static_cast<double>(new_size) / original_size * 100);
return 0;
}

Просмотреть файл

@ -1,229 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 "subtly/font_assembler.h"
#include <stdio.h>
#include <set>
#include <map>
#include "sfntly/tag.h"
#include "sfntly/font.h"
#include "sfntly/font_factory.h"
#include "sfntly/table/core/cmap_table.h"
#include "sfntly/table/truetype/loca_table.h"
#include "sfntly/table/truetype/glyph_table.h"
#include "sfntly/table/core/maximum_profile_table.h"
#include "sfntly/port/type.h"
#include "sfntly/port/refcount.h"
#include "subtly/font_info.h"
namespace subtly {
using namespace sfntly;
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();
}
void FontAssembler::Initialize() {
font_factory_.Attach(sfntly::FontFactory::GetInstance());
font_builder_.Attach(font_factory_->NewFontBuilder());
}
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();
}
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.
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 suficient!
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.
loca_list.resize(std::max(loca_list.size(),
static_cast<size_t>(resolved_glyph_id + 2)));
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;
}
}

Просмотреть файл

@ -1,67 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_ASSEMBLER_H_
#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_ASSEMBLER_H_
#include <set>
#include <map>
#include "subtly/font_info.h"
#include "sfntly/tag.h"
#include "sfntly/font.h"
#include "sfntly/port/type.h"
#include "sfntly/port/refcount.h"
#include "sfntly/table/core/cmap_table.h"
#include "sfntly/table/truetype/glyph_table.h"
#include "sfntly/table/truetype/loca_table.h"
namespace subtly {
// Assembles FontInfo into font builders.
// Does not take ownership of data passed to it.
class FontAssembler : public sfntly::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, sfntly::IntegerSet* table_blacklist);
explicit FontAssembler(FontInfo* font_info);
~FontAssembler() { }
// Assemble a new font from the font info object.
virtual CALLER_ATTACH sfntly::Font* Assemble();
sfntly::IntegerSet* table_blacklist() const { return table_blacklist_; }
void set_table_blacklist(sfntly::IntegerSet* table_blacklist) {
table_blacklist_ = table_blacklist;
}
protected:
virtual bool AssembleCMapTable();
virtual bool AssembleGlyphAndLocaTables();
virtual void Initialize();
private:
sfntly::Ptr<FontInfo> font_info_;
sfntly::Ptr<sfntly::FontFactory> font_factory_;
sfntly::Ptr<sfntly::Font::Builder> font_builder_;
sfntly::IntegerSet* table_blacklist_;
};
}
#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_ASSEMBLER_H_

Просмотреть файл

@ -1,256 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 "subtly/font_info.h"
#include <stdio.h>
#include <set>
#include <map>
#include "subtly/character_predicate.h"
#include "sfntly/tag.h"
#include "sfntly/font.h"
#include "sfntly/font_factory.h"
#include "sfntly/table/core/cmap_table.h"
#include "sfntly/table/truetype/loca_table.h"
#include "sfntly/table/truetype/glyph_table.h"
#include "sfntly/table/core/maximum_profile_table.h"
#include "sfntly/port/type.h"
#include "sfntly/port/refcount.h"
namespace subtly {
using namespace sfntly;
/******************************************************************************
* GlyphId class
******************************************************************************/
GlyphId::GlyphId(int32_t glyph_id, FontId font_id)
: glyph_id_(glyph_id),
font_id_(font_id) {
}
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();
}
/******************************************************************************
* FontInfo class
******************************************************************************/
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();
}
void FontInfo::set_chars_to_glyph_ids(CharacterMap* chars_to_glyph_ids) {
*chars_to_glyph_ids_ = *chars_to_glyph_ids;
}
void FontInfo::set_resolved_glyph_ids(GlyphIdSet* resolved_glyph_ids) {
*resolved_glyph_ids_ = *resolved_glyph_ids;
}
void FontInfo::set_fonts(FontIdMap* fonts) {
*fonts_ = *fonts;
}
/******************************************************************************
* FontSourcedInfoBuilder class
******************************************************************************/
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();
}
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));
}
CALLER_ATTACH FontInfo* FontSourcedInfoBuilder::GetFontInfo() {
CharacterMap* chars_to_glyph_ids = new CharacterMap;
bool success = GetCharacterMap(chars_to_glyph_ids);
if (!success) {
delete chars_to_glyph_ids;
#if defined (SUBTLY_DEBUG)
fprintf(stderr, "Error creating character map.\n");
#endif
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 defined (SUBTLY_DEBUG)
fprintf(stderr, "Error resolving composite glyphs.\n");
#endif
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.
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()) {
#if defined (SUBTLY_DEBUG)
fprintf(stderr, "%d larger than %d or smaller than 0\n", glyph_id,
loca_table_->num_glyphs());
#endif
continue;
}
int32_t length = loca_table_->GlyphLength(glyph_id);
if (length == 0) {
#if defined (SUBTLY_DEBUG)
fprintf(stderr, "Zero length glyph %d\n", glyph_id);
#endif
continue;
}
int32_t offset = loca_table_->GlyphOffset(glyph_id);
GlyphPtr glyph;
glyph.Attach(glyph_table_->GetGlyph(offset, length));
if (glyph == NULL) {
#if defined (SUBTLY_DEBUG)
fprintf(stderr, "GetGlyph returned NULL for %d\n", glyph_id);
#endif
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;
}
}

Просмотреть файл

@ -1,128 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_INFO_H_
#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_INFO_H_
#include <map>
#include <set>
#include "sfntly/font.h"
#include "sfntly/port/type.h"
#include "sfntly/port/refcount.h"
#include "sfntly/table/core/cmap_table.h"
#include "sfntly/table/truetype/glyph_table.h"
#include "sfntly/table/truetype/loca_table.h"
namespace subtly {
class CharacterPredicate;
typedef int32_t FontId;
typedef std::map<FontId, sfntly::Ptr<sfntly::Font> > FontIdMap;
// 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 { return glyph_id_; }
void set_glyph_id(const int32_t glyph_id) { glyph_id_ = glyph_id; }
FontId font_id() const { return font_id_; }
void set_font_id(const FontId font_id) { font_id_ = 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 sfntly::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 sfntly::FontDataTable* GetTable(FontId font_id, int32_t tag);
// Gets the table map of the font whose id is font_id
virtual const sfntly::TableMap* GetTableMap(FontId);
CharacterMap* chars_to_glyph_ids() const { return chars_to_glyph_ids_; }
// 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 { return resolved_glyph_ids_; }
// Takes ownership of the glyph_ids GlyphIdSet.
void set_resolved_glyph_ids(GlyphIdSet* glyph_ids);
FontIdMap* fonts() const { return fonts_; }
// 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 sfntly::RefCounted<FontSourcedInfoBuilder> {
public:
FontSourcedInfoBuilder(sfntly::Font* font, FontId font_id);
FontSourcedInfoBuilder(sfntly::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:
sfntly::Ptr<sfntly::Font> font_;
FontId font_id_;
CharacterPredicate* predicate_;
sfntly::Ptr<sfntly::CMapTable::CMap> cmap_;
sfntly::Ptr<sfntly::LocaTable> loca_table_;
sfntly::Ptr<sfntly::GlyphTable> glyph_table_;
};
}
#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_INFO_H_

Просмотреть файл

@ -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.
*/
#include "subtly/merger.h"
#include <stdio.h>
#include "sfntly/font.h"
#include "sfntly/font_factory.h"
#include "subtly/character_predicate.h"
#include "subtly/font_assembler.h"
#include "subtly/font_info.h"
#include "subtly/utils.h"
namespace subtly {
using namespace sfntly;
/******************************************************************************
* Merger class
******************************************************************************/
Merger::Merger(FontArray* fonts) {
if (!fonts) {
return;
}
int32_t num_fonts = fonts->size();
for (int32_t i = 0; i < num_fonts; ++i) {
fonts_.insert(std::make_pair(i, fonts->at(i)));
}
}
CALLER_ATTACH Font* Merger::Merge() {
Ptr<FontInfo> merged_info;
merged_info.Attach(MergeFontInfos());
if (!merged_info) {
#if defined (SUBTLY_DEBUG)
fprintf(stderr, "Could not create merged font info\n");
#endif
return NULL;
}
Ptr<FontAssembler> font_assembler = new FontAssembler(merged_info);
return font_assembler->Assemble();
}
CALLER_ATTACH FontInfo* Merger::MergeFontInfos() {
Ptr<FontInfo> font_info = new FontInfo;
font_info->set_fonts(&fonts_);
for (FontIdMap::iterator it = fonts_.begin(),
e = fonts_.end(); it != e; ++it) {
Ptr<FontSourcedInfoBuilder> info_builder =
new FontSourcedInfoBuilder(it->second, it->first, NULL);
Ptr<FontInfo> current_font_info;
current_font_info.Attach(info_builder->GetFontInfo());
if (!current_font_info) {
#if defined (SUBTLY_DEBUG)
fprintf(stderr, "Couldn't create font info. "
"No subset will be generated.\n");
#endif
return NULL;
}
font_info->chars_to_glyph_ids()->insert(
current_font_info->chars_to_glyph_ids()->begin(),
current_font_info->chars_to_glyph_ids()->end());
font_info->resolved_glyph_ids()->insert(
current_font_info->resolved_glyph_ids()->begin(),
current_font_info->resolved_glyph_ids()->end());
#if defined (SUBTLY_DEBUG)
fprintf(stderr, "Counts: chars_to_glyph_ids: %d; resoved_glyph_ids: %d\n",
font_info->chars_to_glyph_ids()->size(),
font_info->resolved_glyph_ids()->size());
#endif
}
return font_info.Detach();
}
}

Просмотреть файл

@ -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.
*/
#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_MERGER_H_
#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_MERGER_H_
#include "subtly/character_predicate.h"
#include "subtly/font_info.h"
namespace sfntly {
class Font;
}
namespace subtly {
// Merges the subsets in the font array into a single font.
class Merger : public sfntly::RefCounted<Merger> {
public:
explicit Merger(sfntly::FontArray* fonts);
virtual ~Merger() { }
// Performs merging returning the subsetted font.
virtual CALLER_ATTACH sfntly::Font* Merge();
protected:
virtual CALLER_ATTACH FontInfo* MergeFontInfos();
private:
FontIdMap fonts_;
};
}
#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_MERGER_H_

Просмотреть файл

@ -1,69 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 <stdio.h>
#include <stdlib.h>
#include <map>
#include <utility>
#include "sfntly/font.h"
#include "subtly/merger.h"
#include "subtly/stats.h"
#include "subtly/utils.h"
using namespace subtly;
void PrintUsage(const char* program_name) {
fprintf(stdout, "Usage: %s <input_font_file1> <input_font_file2> ..."
"<input_font_filen> <output_font_file>\n",
program_name);
}
void CheckLoading(const char* font_path, Font* font) {
if (!font || font->num_tables() == 0) {
fprintf(stderr, "Could not load font %s. Terminating.\n", font_path);
exit(1);
}
}
int main(int argc, const char** argv) {
if (argc < 3) {
PrintUsage(argv[0]);
exit(1);
}
FontArray fonts;
for (int32_t i = 1; i < argc - 1; ++i) {
Ptr<Font> font;
font.Attach(LoadFont(argv[i]));
CheckLoading(argv[i], font);
fonts.push_back(font);
}
Ptr<Merger> merger = new Merger(&fonts);
FontPtr new_font;
new_font.Attach(merger->Merge());
fprintf(stderr, "Serializing font to %s\n", argv[argc - 1]);
SerializeFont(argv[argc - 1], new_font);
if (!new_font) {
fprintf(stdout, "Cannot create merged font.\n");
return 1;
}
return 0;
}

Просмотреть файл

@ -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 <stdio.h>
#include "sfntly/font.h"
#include "sfntly/table/table.h"
#include "sfntly/tag.h"
#include "subtly/stats.h"
namespace subtly {
using namespace sfntly;
int32_t TotalFontSize(Font* font) {
int32_t size = 0;
const TableMap* table_map = font->GetTableMap();
for (TableMap::const_iterator it = table_map->begin(),
e = table_map->end(); it != e; ++it) {
size += it->second->DataLength();
}
return size;
}
double TableSizePercent(Font* font, int32_t tag) {
TablePtr table = font->GetTable(tag);
return static_cast<double>(table->DataLength()) / TotalFontSize(font) * 100;
}
void PrintComparison(FILE* out, Font* font, Font* new_font) {
fprintf(out, "====== Table Comparison (original v. subset) ======\n");
const TableMap* tables = font->GetTableMap();
for (TableMap::const_iterator it = tables->begin(),
e = tables->end(); it != e; ++it) {
char *name = TagToString(it->first);
int32_t size = it->second->DataLength();
fprintf(out, "-- %s: %d (%lf%%) ", name, size,
TableSizePercent(font, it->first));
delete[] name;
Ptr<FontDataTable> new_table = new_font->GetTable(it->first);
int32_t new_size = 0;
double size_percent = 0;
if (new_table) {
new_size = new_table->DataLength();
size_percent = subtly::TableSizePercent(new_font, it->first);
}
if (new_size == size) {
fprintf(out, "| same size\n");
} else {
fprintf(out, "-> %d (%lf%%) | %lf%% of original\n", new_size,
size_percent, static_cast<double>(new_size) / size * 100);
}
}
}
void PrintStats(FILE* out, Font* font) {
fprintf(out, "====== Table Stats ======\n");
const TableMap* tables = font->GetTableMap();
for (TableMap::const_iterator it = tables->begin(),
e = tables->end(); it != e; ++it) {
char *name = TagToString(it->first);
int32_t size = it->second->DataLength();
fprintf(out, "-- %s: %d (%lf%%)\n", name, size,
TableSizePercent(font, it->first));
delete[] name;
}
}
}

Просмотреть файл

@ -1,40 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_STATS_H_
#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_STATS_H_
#include <stdio.h>
#include "sfntly/port/type.h"
namespace sfntly {
class Font;
}
namespace subtly {
using namespace sfntly;
int32_t TotalFontSize(Font* font);
double TableSizePercent(Font* font, int32_t tag);
void PrintComparison(FILE* out, Font* font, Font* new_font);
void PrintStats(FILE* out, Font* font);
}
#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_STATS_H_

Просмотреть файл

@ -1,67 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 "subtly/subsetter.h"
#include <stdio.h>
#include "sfntly/font.h"
#include "sfntly/font_factory.h"
#include "sfntly/tag.h"
#include "subtly/character_predicate.h"
#include "subtly/font_assembler.h"
#include "subtly/font_info.h"
#include "subtly/utils.h"
namespace subtly {
using namespace sfntly;
/******************************************************************************
* Subsetter class
******************************************************************************/
Subsetter::Subsetter(Font* font, CharacterPredicate* predicate)
: font_(font),
predicate_(predicate) {
}
Subsetter::Subsetter(const char* font_path, CharacterPredicate* predicate)
: predicate_(predicate) {
font_.Attach(LoadFont(font_path));
}
CALLER_ATTACH Font* Subsetter::Subset() {
Ptr<FontSourcedInfoBuilder> info_builder =
new FontSourcedInfoBuilder(font_, 0, predicate_);
Ptr<FontInfo> font_info;
font_info.Attach(info_builder->GetFontInfo());
if (!font_info) {
#if defined (SUBTLY_DEBUG)
fprintf(stderr,
"Couldn't create font info. No subset will be generated.\n");
#endif
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;
return font_subset.Detach();
}
}

Просмотреть файл

@ -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 TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_SUBSETTER_H_
#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_SUBSETTER_H_
#include "sfntly/font.h"
// Cannot remove this header due to Ptr<T> instantiation issue
#include "subtly/character_predicate.h"
namespace subtly {
// Subsets a given font using a character predicate.
class Subsetter : public sfntly::RefCounted<Subsetter> {
public:
Subsetter(sfntly::Font* font, CharacterPredicate* predicate);
Subsetter(const char* font_path, CharacterPredicate* predicate);
virtual ~Subsetter() { }
// Performs subsetting returning the subsetted font.
virtual CALLER_ATTACH sfntly::Font* Subset();
private:
sfntly::Ptr<sfntly::Font> font_;
sfntly::Ptr<CharacterPredicate> predicate_;
};
}
#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_SUBSETTER_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 <stdio.h>
#include <stdlib.h>
#include <map>
#include <utility>
#include "sfntly/font.h"
#include "subtly/character_predicate.h"
#include "subtly/stats.h"
#include "subtly/subsetter.h"
#include "subtly/utils.h"
using namespace subtly;
void PrintUsage(const char* program_name) {
fprintf(stdout, "Usage: %s <input_font_file> <output_font_file>"
"<start_char> <end_char>\n", program_name);
}
int main(int argc, const char** argv) {
const char* program_name = argv[0];
if (argc < 5) {
PrintUsage(program_name);
exit(1);
}
const char* input_font_path = argv[1];
const char* output_font_path = argv[2];
FontPtr font;
font.Attach(subtly::LoadFont(input_font_path));
if (font->num_tables() == 0) {
fprintf(stderr, "Could not load font %s.\n", input_font_path);
exit(1);
}
const char* start_char = argv[3];
const char* end_char = argv[4];
if (start_char[1] != 0) {
fprintf(stderr, "Start character %c invalid.\n", start_char[0]);
exit(1);
}
if (end_char[1] != 0) {
fprintf(stderr, "Start character %c invalid.\n", end_char[0]);
exit(1);
}
int32_t original_size = TotalFontSize(font);
Ptr<CharacterPredicate> range_predicate =
new AcceptRange(start_char[0], end_char[0]);
Ptr<Subsetter> subsetter = new Subsetter(font, range_predicate);
Ptr<Font> new_font;
new_font.Attach(subsetter->Subset());
if (!new_font) {
fprintf(stdout, "Cannot create subset.\n");
return 0;
}
subtly::SerializeFont(output_font_path, new_font);
subtly::PrintComparison(stdout, font, new_font);
int32_t new_size = TotalFontSize(new_font);
fprintf(stdout, "Went from %d to %d: %lf%% of original\n",
original_size, new_size,
static_cast<double>(new_size) / original_size * 100);
return 0;
}

Просмотреть файл

@ -1,91 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 "subtly/utils.h"
#include "sfntly/data/growable_memory_byte_array.h"
#include "sfntly/data/memory_byte_array.h"
#include "sfntly/font.h"
#include "sfntly/font_factory.h"
#include "sfntly/port/file_input_stream.h"
#include "sfntly/port/memory_output_stream.h"
namespace subtly {
using namespace sfntly;
CALLER_ATTACH Font* LoadFont(const char* font_path) {
Ptr<FontFactory> font_factory;
font_factory.Attach(FontFactory::GetInstance());
FontArray fonts;
LoadFonts(font_path, font_factory, &fonts);
return fonts[0].Detach();
}
CALLER_ATTACH Font::Builder* LoadFontBuilder(const char* font_path) {
FontFactoryPtr font_factory;
font_factory.Attach(FontFactory::GetInstance());
FontBuilderArray builders;
LoadFontBuilders(font_path, font_factory, &builders);
return builders[0].Detach();
}
void LoadFonts(const char* font_path, FontFactory* factory, FontArray* fonts) {
FileInputStream input_stream;
input_stream.Open(font_path);
factory->LoadFonts(&input_stream, fonts);
input_stream.Close();
}
void LoadFontBuilders(const char* font_path,
FontFactory* factory,
FontBuilderArray* builders) {
FileInputStream input_stream;
input_stream.Open(font_path);
factory->LoadFontsForBuilding(&input_stream, builders);
input_stream.Close();
}
bool SerializeFont(const char* font_path, Font* font) {
if (!font_path)
return false;
FontFactoryPtr font_factory;
font_factory.Attach(FontFactory::GetInstance());
return SerializeFont(font_path, font_factory, font);
}
bool SerializeFont(const char* font_path, FontFactory* factory, Font* font) {
if (!font_path || !factory || !font)
return false;
// Serializing the font to a stream.
MemoryOutputStream output_stream;
factory->SerializeFont(font, &output_stream);
// Serializing the stream to a file.
FILE* output_file = NULL;
#if defined WIN32
fopen_s(&output_file, font_path, "wb");
#else
output_file = fopen(font_path, "wb");
#endif
if (output_file == static_cast<FILE*>(NULL))
return false;
for (size_t i = 0; i < output_stream.Size(); ++i) {
fwrite(&(output_stream.Get()[i]), 1, 1, output_file);
}
fflush(output_file);
fclose(output_file);
return true;
}
};

Просмотреть файл

@ -1,38 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_UTILS_H_
#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_UTILS_H_
#include "sfntly/font.h"
#include "sfntly/font_factory.h"
namespace subtly {
CALLER_ATTACH sfntly::Font* LoadFont(const char* font_path);
CALLER_ATTACH sfntly::Font::Builder* LoadFontBuilder(const char* font_path);
void LoadFonts(const char* font_path, sfntly::FontFactory* factory,
sfntly::FontArray* fonts);
void LoadFontBuilders(const char* font_path,
sfntly::FontFactory* factory,
sfntly::FontBuilderArray* builders);
bool SerializeFont(const char* font_path, sfntly::Font* font);
bool SerializeFont(const char* font_path, sfntly::FontFactory* factory,
sfntly::Font* font);
}
#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_UTILS_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/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::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) {
if (index < 0 || index >= Length())
return -1;
return InternalGet(index) & 0xff;
}
int32_t ByteArray::Get(int32_t index, std::vector<uint8_t>* b) {
assert(b);
return Get(index, &((*b)[0]), 0, b->size());
}
int32_t ByteArray::Get(int32_t index,
uint8_t* b,
int32_t offset,
int32_t length) {
assert(b);
if (index < 0 || index >= filled_length_)
return 0;
if (length <= 0)
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, uint8_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, std::vector<uint8_t>* b) {
assert(b);
return Put(index, &((*b)[0]), 0, b->size());
}
int32_t ByteArray::Put(int32_t index,
uint8_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;
}
std::vector<uint8_t> 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) {
std::vector<uint8_t> 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) {
std::vector<uint8_t> 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) {
std::vector<uint8_t> 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() const { return filled_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() const { return storage_length_; }
// Determines whether or not this array is growable or of fixed size.
bool growable() const { 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, std::vector<uint8_t>* 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,
uint8_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, uint8_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, std::vector<uint8_t>* 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,
uint8_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, uint8_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,
uint8_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 uint8_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,
uint8_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 uint8_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,92 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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_data.h"
#include <algorithm>
#include <functional>
#include <limits>
#include "sfntly/port/logging.h"
namespace sfntly {
int32_t FontData::Size() const {
return std::min<int32_t>(array_->Size() - bound_offset_, bound_length_);
}
void FontData::Bound(int32_t offset, int32_t length) {
// Inputs should not be negative.
CHECK(offset >= 0);
CHECK(length >= 0);
// Check to make sure |bound_offset_| will not overflow.
CHECK(bound_offset_ <= std::numeric_limits<int32_t>::max() - offset);
const int32_t new_offset = bound_offset_ + offset;
if (length == GROWABLE_SIZE) {
// When |length| has the special value of GROWABLE_SIZE, it means the size
// should not have any artificial limits, thus it is just the underlying
// |array_|'s size. Just make sure |new_offset| is still within bounds.
CHECK(new_offset <= array_->Size());
} else {
// When |length| has any other value, |new_offset| + |length| points to the
// end of the array. Make sure that is within bounds, but use subtraction to
// avoid an integer overflow.
CHECK(new_offset <= array_->Size() - length);
}
bound_offset_ = new_offset;
bound_length_ = length;
}
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) const {
return offset + bound_offset_;
}
int32_t FontData::BoundLength(int32_t offset, int32_t length) const {
return std::min<int32_t>(length, bound_length_ - offset);
}
} // namespace sfntly

Просмотреть файл

@ -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.
*/
#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_DATA_H_
#define SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_DATA_H_
#include <limits.h>
#include "sfntly/data/byte_array.h"
#include "sfntly/port/refcount.h"
#include "sfntly/port/type.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
virtual void Bound(int32_t offset, int32_t length);
// 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) const;
// 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) const;
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,148 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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::Length() {
if (bounded_)
return length_;
if (stream_)
return stream_->Length();
return 0;
}
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(std::vector<uint8_t>* 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(std::vector<uint8_t>* 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 Length();
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(std::vector<uint8_t>* buffer);
virtual int32_t Read(std::vector<uint8_t>* 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(uint8_t b) {
if (stream_) {
stream_->Write(b);
position_++;
}
}
void FontOutputStream::Write(std::vector<uint8_t>* b) {
if (b) {
Write(b, 0, b->size());
position_ += b->size();
}
}
void FontOutputStream::Write(std::vector<uint8_t>* 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(uint8_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(uint8_t c) {
Write(c);
}
void FontOutputStream::WriteUShort(int32_t us) {
Write((uint8_t)((us >> 8) & 0xff));
Write((uint8_t)(us & 0xff));
}
void FontOutputStream::WriteShort(int32_t s) {
WriteUShort(s);
}
void FontOutputStream::WriteUInt24(int32_t ui) {
Write((uint8_t)(ui >> 16) & 0xff);
Write((uint8_t)(ui >> 8) & 0xff);
Write((uint8_t)ui & 0xff);
}
void FontOutputStream::WriteULong(int64_t ul) {
Write((uint8_t)((ul >> 24) & 0xff));
Write((uint8_t)((ul >> 16) & 0xff));
Write((uint8_t)((ul >> 8) & 0xff));
Write((uint8_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,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_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 void Write(uint8_t b);
virtual void Write(std::vector<uint8_t>* b);
virtual void Write(std::vector<uint8_t>* b, int32_t off, int32_t len);
virtual void Write(uint8_t* b, int32_t off, int32_t len);
virtual void WriteChar(uint8_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, uint8_t b) {
if ((size_t)index >= b_.size()) {
b_.resize((size_t)(index + 1));
}
b_[index] = b;
}
int32_t GrowableMemoryByteArray::InternalPut(int32_t index,
uint8_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;
}
uint8_t GrowableMemoryByteArray::InternalGet(int32_t index) {
return b_[index];
}
int32_t GrowableMemoryByteArray::InternalGet(int32_t index,
uint8_t* b,
int32_t offset,
int32_t length) {
memcpy(b + offset, &(b_[0]) + index, length);
return length;
}
void GrowableMemoryByteArray::Close() {
b_.clear();
}
uint8_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, uint8_t b);
virtual int32_t InternalPut(int32_t index,
uint8_t* b,
int32_t offset,
int32_t length);
virtual uint8_t InternalGet(int32_t index);
virtual int32_t InternalGet(int32_t index,
uint8_t* b,
int32_t offset,
int32_t length);
virtual void Close();
virtual uint8_t* Begin();
private:
std::vector<uint8_t> 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(uint8_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 uint8_t[Size()];
memset(b_, 0, Size());
}
}
void MemoryByteArray::InternalPut(int32_t index, uint8_t b) {
Init();
b_[index] = b;
}
int32_t MemoryByteArray::InternalPut(int32_t index,
uint8_t* b,
int32_t offset,
int32_t length) {
assert(b);
Init();
memcpy(b_ + index, b + offset, length);
return length;
}
uint8_t MemoryByteArray::InternalGet(int32_t index) {
Init();
return b_[index];
}
int32_t MemoryByteArray::InternalGet(int32_t index,
uint8_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;
}
uint8_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(std::vector<uint8_t>* 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(uint8_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, uint8_t b);
virtual int32_t InternalPut(int32_t index,
uint8_t* b,
int32_t offset,
int32_t length);
virtual uint8_t InternalGet(int32_t index);
virtual int32_t InternalGet(int32_t index,
uint8_t* b,
int32_t offset,
int32_t length);
virtual void Close();
virtual uint8_t* Begin();
private:
void Init(); // C++ port only, used to allocate memory outside constructor.
uint8_t* b_;
bool allocated_;
};
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_MEMORY_BYTE_ARRAY_H_

Просмотреть файл

@ -1,395 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 <limits>
#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(std::vector<uint8_t>* 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 std::vector<int32_t>& ranges) {
checksum_range_ = ranges;
checksum_set_ = false; // UNIMPLEMENTED: atomicity
}
int32_t ReadableFontData::ReadUByte(int32_t index) {
int32_t b = array_->Get(BoundOffset(index));
if (b < 0) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundException(
"Index attempted to be read from is out of bounds", index);
#endif
return kInvalidUnsigned;
}
return b;
}
int32_t ReadableFontData::ReadByte(int32_t index) {
int32_t b = array_->Get(BoundOffset(index));
if (b < 0) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IndexOutOfBoundException(
"Index attempted to be read from is out of bounds", index);
#endif
return kInvalidByte;
}
return (b << 24) >> 24;
}
int32_t ReadableFontData::ReadBytes(int32_t index,
uint8_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) {
int32_t b1 = ReadUByte(index);
if (b1 < 0)
return kInvalidUnsigned;
int32_t b2 = ReadUByte(index + 1);
if (b2 < 0)
return kInvalidUnsigned;
return 0xffff & (b1 << 8 | b2);
}
int32_t ReadableFontData::ReadShort(int32_t index) {
int32_t b1 = ReadByte(index);
if (b1 == kInvalidByte)
return kInvalidShort;
int32_t b2 = ReadUByte(index + 1);
if (b2 < 0)
return kInvalidShort;
uint32_t result = static_cast<uint32_t>(b1) << 8 | b2;
return static_cast<int32_t>(result << 16) >> 16;
}
int32_t ReadableFontData::ReadUInt24(int32_t index) {
int32_t b1 = ReadUByte(index);
if (b1 < 0)
return kInvalidUnsigned;
int32_t b2 = ReadUByte(index + 1);
if (b2 < 0)
return kInvalidUnsigned;
int32_t b3 = ReadUByte(index + 2);
if (b3 < 0)
return kInvalidUnsigned;
return 0xffffff & (b1 << 16 | b2 << 8 | b3);
}
int64_t ReadableFontData::ReadULong(int32_t index) {
int32_t b1 = ReadUByte(index);
if (b1 < 0)
return kInvalidUnsigned;
int32_t b2 = ReadUByte(index + 1);
if (b2 < 0)
return kInvalidUnsigned;
int32_t b3 = ReadUByte(index + 2);
if (b3 < 0)
return kInvalidUnsigned;
int32_t b4 = ReadUByte(index + 3);
if (b4 < 0)
return kInvalidUnsigned;
return 0xffffffffL & (b1 << 24 | b2 << 16 | b3 << 8 | b4);
}
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) {
int32_t b1 = ReadUByte(index);
if (b1 < 0)
return kInvalidUnsigned;
int32_t b2 = ReadUByte(index + 1);
if (b2 < 0)
return kInvalidUnsigned;
int32_t b3 = ReadUByte(index + 2);
if (b3 < 0)
return kInvalidUnsigned;
int32_t b4 = ReadUByte(index + 3);
if (b4 < 0)
return kInvalidUnsigned;
return 0xffffffffL & (b1 | b2 << 8 | b3 << 16 | b4 << 24);
}
int32_t ReadableFontData::ReadLong(int32_t index) {
int32_t b1 = ReadByte(index);
if (b1 == kInvalidByte)
return kInvalidLong;
int32_t b2 = ReadUByte(index + 1);
if (b2 < 0)
return kInvalidLong;
int32_t b3 = ReadUByte(index + 2);
if (b3 < 0)
return kInvalidLong;
int32_t b4 = ReadUByte(index + 3);
if (b4 < 0)
return kInvalidLong;
return static_cast<uint32_t>(b1) << 24 | b2 << 16 | b3 << 8 | b4;
}
int32_t ReadableFontData::ReadFixed(int32_t index) {
return ReadLong(index);
}
int64_t ReadableFontData::ReadDateTimeAsLong(int32_t index) {
int64_t high = ReadULong(index);
if (high == kInvalidUnsigned)
return kInvalidLongDateTime;
int64_t low = ReadULong(index + 4);
if (low == kInvalidUnsigned)
return kInvalidLongDateTime;
return high << 32 | low;
}
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;
// 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)
return location;
if (key < location_start) {
// location is below current location
top = location;
} else {
// location is above current location
bottom = location + 1;
}
}
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;
// 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 || length < 0 ||
offset > std::numeric_limits<int32_t>::max() - length ||
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,315 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 OutputStream;
class WritableFontData;
// 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 const int32_t kInvalidByte = 128;
static const int32_t kInvalidShort = 32768;
static const int32_t kInvalidLong = 0xffffffff;
static const int32_t kInvalidUnsigned = -1;
static const int64_t kInvalidLongDateTime = -1;
static CALLER_ATTACH ReadableFontData* CreateReadableFontData(std::vector<uint8_t>* 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 std::vector<int32_t>& 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; |kInvalidByte| if outside the bounds of the font data
// @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,
uint8_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; -1 if outside the bounds of the font data
// @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; -1 if outside the bounds of the font data
// @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; |kInvalidShort| if outside the bounds of the font data
// @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; -1 if outside the bounds of the font data
// @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; kInvalidUnsigned if outside the bounds of the font data
// @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; kInvalidLong if outside the bounds of the font data
// @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; kInvalidLongDateTime if outside the bounds of the
// font data
// @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_;
std::vector<int32_t> checksum_range_;
};
typedef Ptr<ReadableFontData> ReadableFontDataPtr;
} // namespace sfntly
#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_

Просмотреть файл

@ -1,206 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 <algorithm>
#include <limits>
#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(std::vector<uint8_t>* b) {
ByteArrayPtr ba = new GrowableMemoryByteArray();
ba->Put(0, b);
WritableFontDataPtr wfd = new WritableFontData(ba);
return wfd.Detach();
}
int32_t WritableFontData::WriteByte(int32_t index, uint8_t b) {
array_->Put(BoundOffset(index), b);
return 1;
}
int32_t WritableFontData::WriteBytes(int32_t index,
uint8_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, std::vector<uint8_t>* b) {
assert(b);
return WriteBytes(index, &((*b)[0]), 0, b->size());
}
int32_t WritableFontData::WriteBytesPad(int32_t index,
std::vector<uint8_t>* b,
int32_t offset,
int32_t length,
uint8_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, (uint8_t)0);
}
int32_t WritableFontData::WritePadding(int32_t index, int32_t count,
uint8_t pad) {
for (int32_t i = 0; i < count; ++i) {
array_->Put(index + i, pad);
}
return count;
}
int32_t WritableFontData::WriteChar(int32_t index, uint8_t c) {
return WriteByte(index, c);
}
int32_t WritableFontData::WriteUShort(int32_t index, int32_t us) {
WriteByte(index, (uint8_t)((us >> 8) & 0xff));
WriteByte(index + 1, (uint8_t)(us & 0xff));
return 2;
}
int32_t WritableFontData::WriteUShortLE(int32_t index, int32_t us) {
WriteByte(index, (uint8_t)(us & 0xff));
WriteByte(index + 1, (uint8_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, (uint8_t)((ui >> 16) & 0xff));
WriteByte(index + 1, (uint8_t)((ui >> 8) & 0xff));
WriteByte(index + 2, (uint8_t)(ui & 0xff));
return 3;
}
int32_t WritableFontData::WriteULong(int32_t index, int64_t ul) {
WriteByte(index, (uint8_t)((ul >> 24) & 0xff));
WriteByte(index + 1, (uint8_t)((ul >> 16) & 0xff));
WriteByte(index + 2, (uint8_t)((ul >> 8) & 0xff));
WriteByte(index + 3, (uint8_t)(ul & 0xff));
return 4;
}
int32_t WritableFontData::WriteULongLE(int32_t index, int64_t ul) {
WriteByte(index, (uint8_t)(ul & 0xff));
WriteByte(index + 1, (uint8_t)((ul >> 8) & 0xff));
WriteByte(index + 2, (uint8_t)((ul >> 16) & 0xff));
WriteByte(index + 3, (uint8_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 || length < 0 ||
offset > std::numeric_limits<int32_t>::max() - length ||
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 < 0 || 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(std::vector<uint8_t>* 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, uint8_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,
uint8_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, std::vector<uint8_t>* 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,
std::vector<uint8_t>* b,
int32_t offset,
int32_t length,
uint8_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, uint8_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, uint8_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,586 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 <algorithm>
#include <functional>
#include <iterator>
#include <limits>
#include <map>
#include <string>
#include <typeinfo>
#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 {
namespace {
const int32_t kSFNTVersionMajor = 1;
const int32_t kSFNTVersionMinor = 0;
const int32_t kMaxTableSize = 200 * 1024 * 1024;
bool IsValidHeaderRegion(int32_t data_length, int32_t offset, int32_t length) {
return offset >= 0 && length >= 0 &&
offset <= std::numeric_limits<int32_t>::max() - length &&
offset + length <= data_length;
}
} // namespace
/******************************************************************************
* Font class
******************************************************************************/
Font::~Font() {}
bool Font::HasTable(int32_t tag) const {
return tables_.find(tag) != tables_.end();
}
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, std::vector<int32_t>* table_ordering) {
assert(table_ordering);
std::vector<int32_t> 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, std::vector<uint8_t>* digest)
: sfnt_version_(sfnt_version) {
// non-trivial assignments that makes debugging hard if placed in
// initialization list
digest_ = *digest;
}
void Font::BuildTableHeadersForSerialization(std::vector<int32_t>* table_ordering,
TableHeaderList* table_headers) {
assert(table_headers);
assert(table_ordering);
std::vector<int32_t> final_table_ordering;
GenerateTableOrdering(table_ordering, &final_table_ordering);
int32_t table_offset = Offset::kTableRecordBegin + num_tables() *
Offset::kTableRecordSize;
for (size_t i = 0; i < final_table_ordering.size(); ++i) {
int32_t tag = final_table_ordering[i];
TablePtr table = GetTable(tag);
if (table == NULL)
continue;
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 (size_t i = 0; i < table_headers->size(); ++i) {
const HeaderPtr& record = (*table_headers)[i];
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);
assert(table_size == record->length());
int32_t filler_size = ((table_size + 3) & ~3) - table_size;
for (int32_t i = 0; i < filler_size; ++i) {
fos->Write(static_cast<uint8_t>(0));
}
}
}
void Font::GenerateTableOrdering(std::vector<int32_t>* default_table_ordering,
std::vector<int32_t>* 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 (std::vector<int32_t>::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(std::vector<int32_t>* 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(std::vector<uint8_t>* 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) {
table_builders_.erase(tag);
}
Font::Builder::Builder(FontFactory* factory)
: factory_(factory),
sfnt_version_(Fixed1616::Fixed(kSFNTVersionMajor, kSFNTVersionMinor)) {
}
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)
return NULL;
TableBuilderMap::iterator target = builder_map->find(tag);
if (target == builder_map->end())
return NULL;
return target->second.p_;
}
// Like GetBuilder(), but the returned Builder must be able to support reads.
static Table::Builder* GetReadBuilder(TableBuilderMap* builder_map, int32_t tag) {
Table::Builder* builder = GetBuilder(builder_map, tag);
if (!builder || !builder->InternalReadData())
return NULL;
return builder;
}
void Font::Builder::InterRelateBuilders(TableBuilderMap* builder_map) {
Table::Builder* raw_head_builder = GetReadBuilder(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 = GetReadBuilder(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 = GetReadBuilder(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 = GetReadBuilder(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) {
int32_t num_glyphs = max_profile_builder->NumGlyphs();
if (num_glyphs >= 0)
horizontal_metrics_builder->SetNumGlyphs(num_glyphs);
}
if (horizontal_header_builder != NULL) {
int32_t num_hmetrics = horizontal_header_builder->NumberOfHMetrics();
if (num_hmetrics >= 0)
horizontal_metrics_builder->SetNumberOfHMetrics(num_hmetrics);
}
}
if (loca_table_builder != NULL) {
if (max_profile_builder != NULL) {
int32_t num_glyphs = max_profile_builder->NumGlyphs();
if (num_glyphs >= 0)
loca_table_builder->SetNumGlyphs(num_glyphs);
}
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();
if (!IsValidHeaderRegion(is->Length(), offset, length))
continue;
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);
if (num_tables_ > fd->Size() / Offset::kTableRecordSize)
return;
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);
if (!IsValidHeaderRegion(fd->Size(), offset, length))
continue;
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 it = headers->begin(),
table_end = headers->end();
it != table_end;
++it) {
const Ptr<Header> header = *it;
is->Skip(header->offset() - is->position());
if (header->length() > kMaxTableSize)
continue;
FontInputStream table_is(is, header->length());
WritableFontDataPtr data;
data.Attach(WritableFontData::CreateWritableFontData(header->length()));
data->CopyFrom(&table_is, header->length());
table_data->insert(DataBlockEntry(header, data));
}
}
void Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers,
WritableFontData* fd,
DataBlockMap* table_data) {
for (HeaderOffsetSortedSet::iterator it = headers->begin(),
table_end = headers->end();
it != table_end;
++it) {
const Ptr<Header> header = *it;
if (header->length() > kMaxTableSize)
continue;
FontDataPtr sliced_data;
sliced_data.Attach(fd->Slice(header->offset(), header->length()));
WritableFontDataPtr data = down_cast<WritableFontData*>(sliced_data.p_);
table_data->insert(DataBlockEntry(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(std::vector<uint8_t>* 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_;
std::vector<uint8_t> digest_;
};
virtual ~Font();
// Gets the sfnt version set in the sfnt wrapper of the font.
int32_t sfnt_version() { return sfnt_version_; }
// Gets a copy of the fonts digest that was created when the font was read. If
// no digest was set at creation time then the return result will be null.
std::vector<uint8_t>* digest() { return &digest_; }
// Get the checksum for this font.
int64_t checksum() { return checksum_; }
// Get the number of tables in this font.
int32_t num_tables() { return (int32_t)tables_.size(); }
// Whether the font has a particular table.
bool HasTable(int32_t tag) const;
// UNIMPLEMENTED: public Iterator<? extends Table> iterator
// Get the table in this font with the specified id.
// @param tag the identifier of the table
// @return the table specified if it exists; null otherwise
// C++ port: rename table() to GetTable()
Table* GetTable(int32_t tag);
// Get a map of the tables in this font accessed by table tag.
// @return an unmodifiable view of the tables in this font
// Note: renamed tableMap() to GetTableMap()
const TableMap* GetTableMap();
// UNIMPLEMENTED: toString()
// Serialize the font to the output stream.
// @param os the destination for the font serialization
// @param tableOrdering the table ordering to apply
void Serialize(OutputStream* os, std::vector<int32_t>* 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, std::vector<uint8_t>* 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(std::vector<int32_t>* 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(std::vector<int32_t>* default_table_ordering,
std::vector<int32_t>* 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(std::vector<int32_t>* default_table_ordering);
int32_t sfnt_version_;
std::vector<uint8_t> 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,217 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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(std::vector<uint8_t>* 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(std::vector<uint8_t>* 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) {
std::vector<int32_t> table_ordering;
font->Serialize(os, &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);
if (num_fonts < 0)
return;
if (num_fonts > wfd->Length() / 4)
return;
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);
if (offset < 0 || offset >= wfd->Length())
continue;
FontBuilderPtr builder;
builder.Attach(LoadSingleOTFForBuilding(wfd, offset));
builders->push_back(builder);
}
}
bool FontFactory::IsCollection(PushbackInputStream* pbis) {
std::vector<uint8_t> 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) {
std::vector<uint8_t> 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,133 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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(std::vector<uint8_t>* 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(std::vector<uint8_t>* 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);
// 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_;
};
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,175 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 <algorithm>
#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::Length() {
return length_;
}
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;
}
uint8_t value = 0;
size_t length = fread(&value, 1, 1, file_);
position_ += length;
return value;
}
int32_t FileInputStream::Read(std::vector<uint8_t>* b) {
return Read(b, 0, b->size());
}
int32_t FileInputStream::Read(std::vector<uint8_t>* 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(std::vector<uint8_t>* b) {
Unread(b, 0, b->size());
}
void FileInputStream::Unread(std::vector<uint8_t>* 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,58 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 Length();
virtual int32_t Available();
virtual void Close();
virtual void Mark(int32_t readlimit);
virtual bool MarkSupported();
virtual int32_t Read();
virtual int32_t Read(std::vector<uint8_t>* b);
virtual int32_t Read(std::vector<uint8_t>* b, int32_t offset, int32_t length);
virtual void Reset();
virtual int64_t Skip(int64_t n);
// PushbackInputStream methods
virtual void Unread(std::vector<uint8_t>* b);
virtual void Unread(std::vector<uint8_t>* 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,50 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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:
virtual int32_t Length() = 0;
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(std::vector<uint8_t>* b) = 0;
virtual int32_t Read(std::vector<uint8_t>* b, int32_t offset, int32_t length) = 0;
virtual void Reset() = 0;
virtual int64_t Skip(int64_t n) = 0;
protected:
virtual ~InputStream() {}
};
class PushbackInputStream : public InputStream {
public:
virtual void Unread(std::vector<uint8_t>* b) = 0;
virtual void Unread(std::vector<uint8_t>* 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,31 +0,0 @@
/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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_LOGGING_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_LOGGING_H_
#include <stdio.h>
#include <stdlib.h>
// Cheap base/logging.h knock off.
#define CHECK(expr) \
if (!(expr)) { \
printf("CHECK failed\n"); \
abort(); \
}
#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_LOGGING_H_

Просмотреть файл

@ -1,153 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 <algorithm>
#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::Length() {
return length_;
}
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;
}
uint8_t value = buffer_[position_++];
return value;
}
int32_t MemoryInputStream::Read(std::vector<uint8_t>* b) {
return Read(b, 0, b->size());
}
int32_t MemoryInputStream::Read(std::vector<uint8_t>* 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(std::vector<uint8_t>* b) {
Unread(b, 0, b->size());
}
void MemoryInputStream::Unread(std::vector<uint8_t>* 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 uint8_t* buffer, size_t length) {
assert(buffer);
assert(length);
buffer_ = buffer;
length_ = length;
return true;
}
} // namespace sfntly

Просмотреть файл

@ -1,58 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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 Length();
virtual int32_t Available();
virtual void Close();
virtual void Mark(int32_t readlimit);
virtual bool MarkSupported();
virtual int32_t Read();
virtual int32_t Read(std::vector<uint8_t>* b);
virtual int32_t Read(std::vector<uint8_t>* b, int32_t offset, int32_t length);
virtual void Reset();
virtual int64_t Skip(int64_t n);
// PushbackInputStream methods
virtual void Unread(std::vector<uint8_t>* b);
virtual void Unread(std::vector<uint8_t>* b, int32_t offset, int32_t length);
// Own methods
virtual bool Attach(const uint8_t* buffer, size_t length);
private:
const uint8_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(std::vector<uint8_t>* buffer) {
store_.insert(store_.end(), buffer->begin(), buffer->end());
}
void MemoryOutputStream::Write(std::vector<uint8_t>* 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(uint8_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(uint8_t b) {
store_.push_back(b);
}
uint8_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(std::vector<uint8_t>* buffer);
virtual void Write(std::vector<uint8_t>* buffer, int32_t offset, int32_t length);
virtual void Write(uint8_t* buffer, int32_t offset, int32_t length);
virtual void Write(uint8_t b);
uint8_t* Get();
size_t Size();
private:
std::vector<uint8_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(std::vector<uint8_t>* buffer) = 0;
virtual void Write(uint8_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(std::vector<uint8_t>* buffer, int32_t offset, int32_t length) = 0;
// Note: Caller is responsible for the boundary of buffer.
virtual void Write(uint8_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
bool TestSmartPointer();
namespace sfntly {
template <typename T>
class Ptr;
class RefCount {
public:
// Make gcc -Wnon-virtual-dtor happy.
virtual ~RefCount() {}
private:
template <typename T>
friend class Ptr;
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;
}
private:
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
friend bool ::TestSmartPointer();
#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!
}
T* operator->() const {
return 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,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_PORT_TYPE_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_TYPE_H_
#include <stdint.h>
#include <cassert>
#include <cstddef>
#include <set>
#include <vector>
namespace sfntly {
// deprecated
typedef uint8_t byte_t;
typedef uint16_t word_t;
typedef uint32_t dword_t;
typedef uint64_t qword_t;
typedef std::vector<uint8_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(uint8_t height) {
InternalWriteData()->WriteByte(Offset::kHeight, height);
}
int32_t BigGlyphMetrics::Builder::Width() {
return InternalReadData()->ReadByte(Offset::kWidth);
}
void BigGlyphMetrics::Builder::SetWidth(uint8_t width) {
InternalWriteData()->WriteByte(Offset::kWidth, width);
}
int32_t BigGlyphMetrics::Builder::HoriBearingX() {
return InternalReadData()->ReadByte(Offset::kHoriBearingX);
}
void BigGlyphMetrics::Builder::SetHoriBearingX(uint8_t bearing) {
InternalWriteData()->WriteByte(Offset::kHoriBearingX, bearing);
}
int32_t BigGlyphMetrics::Builder::HoriBearingY() {
return InternalReadData()->ReadByte(Offset::kHoriBearingY);
}
void BigGlyphMetrics::Builder::SetHoriBearingY(uint8_t bearing) {
InternalWriteData()->WriteByte(Offset::kHoriBearingY, bearing);
}
int32_t BigGlyphMetrics::Builder::HoriAdvance() {
return InternalReadData()->ReadByte(Offset::kHoriAdvance);
}
void BigGlyphMetrics::Builder::SetHoriAdvance(uint8_t advance) {
InternalWriteData()->WriteByte(Offset::kHoriAdvance, advance);
}
int32_t BigGlyphMetrics::Builder::VertBearingX() {
return InternalReadData()->ReadByte(Offset::kVertBearingX);
}
void BigGlyphMetrics::Builder::SetVertBearingX(uint8_t bearing) {
InternalWriteData()->WriteByte(Offset::kVertBearingX, bearing);
}
int32_t BigGlyphMetrics::Builder::VertBearingY() {
return InternalReadData()->ReadByte(Offset::kVertBearingY);
}
void BigGlyphMetrics::Builder::SetVertBearingY(uint8_t bearing) {
InternalWriteData()->WriteByte(Offset::kVertBearingY, bearing);
}
int32_t BigGlyphMetrics::Builder::VertAdvance() {
return InternalReadData()->ReadByte(Offset::kVertAdvance);
}
void BigGlyphMetrics::Builder::SetVertAdvance(uint8_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(uint8_t height);
int32_t Width();
void SetWidth(uint8_t width);
int32_t HoriBearingX();
void SetHoriBearingX(uint8_t bearing);
int32_t HoriBearingY();
void SetHoriBearingY(uint8_t bearing);
int32_t HoriAdvance();
void SetHoriAdvance(uint8_t advance);
int32_t VertBearingX();
void SetVertBearingX(uint8_t bearing);
int32_t VertBearingY();
void SetVertBearingY(uint8_t bearing);
int32_t VertAdvance();
void SetVertAdvance(uint8_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 false; // Well defined C++ code's this is always not 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,317 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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)
return;
int32_t num_sizes = data->ReadULongAsInt(Offset::kNumSizes);
if (num_sizes > data->Size() / Offset::kBitmapSizeTableLength)
return;
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,302 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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;
}
std::vector<int32_t>* 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)));
if (new_data == NULL) {
return NULL;
}
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 (std::vector<int32_t>::iterator b = GetOffsetArray()->begin(),
e = GetOffsetArray()->end(); b != e; b++) {
size += new_data->WriteLong(size, *b);
}
}
return size;
}
std::vector<int32_t>* IndexSubTableFormat1::Builder::OffsetArray() {
return GetOffsetArray();
}
void IndexSubTableFormat1::Builder::SetOffsetArray(
const std::vector<int32_t>& 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) {
}
std::vector<int32_t>* 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);
std::vector<int32_t>* OffsetArray();
void SetOffsetArray(const std::vector<int32_t>& 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);
std::vector<int32_t>* 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);
std::vector<int32_t> 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,275 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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)));
if (new_data == NULL) {
return NULL;
}
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,298 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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;
}
std::vector<int32_t>* 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 std::vector<int32_t>& 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)));
if (new_data == NULL) {
return NULL;
}
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 (std::vector<int32_t>::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) {
}
std::vector<int32_t>* 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 std::vector<int32_t>& 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);
std::vector<int32_t>* 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);
std::vector<int32_t> 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,384 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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)));
if (new_data == NULL) {
return NULL;
}
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,347 +0,0 @@
/*
* Copyright 2011 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT 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;
}
std::vector<int32_t>* glyph_array = GetGlyphArray();
std::vector<int32_t>::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)));
if (new_data == NULL) {
return NULL;
}
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 (std::vector<int32_t>::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_;
}
std::vector<int32_t>* IndexSubTableFormat5::Builder::GlyphArray() {
return GetGlyphArray();
}
void IndexSubTableFormat5::Builder::SetGlyphArray(const std::vector<int32_t>& 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) {
}
std::vector<int32_t>* 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();
std::vector<int32_t>* GlyphArray();
void SetGlyphArray(const std::vector<int32_t>& 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);
std::vector<int32_t>* 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);
std::vector<int32_t> 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_

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше