summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DEPS7
-rw-r--r--skia/skia.gyp1
-rw-r--r--third_party/sfntly/COPYING.txt203
-rw-r--r--third_party/sfntly/README.chromium18
-rw-r--r--third_party/sfntly/sfntly.gyp89
-rw-r--r--third_party/sfntly/src/subsetter/font_subsetter.cc39
-rw-r--r--third_party/sfntly/src/subsetter/font_subsetter.h50
-rw-r--r--third_party/sfntly/src/subsetter/subsetter_impl.cc289
-rw-r--r--third_party/sfntly/src/subsetter/subsetter_impl.h71
9 files changed, 767 insertions, 0 deletions
diff --git a/DEPS b/DEPS
index 47ee3be..3030497 100644
--- a/DEPS
+++ b/DEPS
@@ -21,6 +21,7 @@ vars = {
"libjingle_revision": "73",
"libvpx_revision": "90416",
"ffmpeg_revision": "91042",
+ "sfntly_revision": "20",
"skia_revision": "1919",
"v8_revision": "8695",
"webrtc_revision": "232",
@@ -98,6 +99,12 @@ deps = {
Var("nacl_trunk") + "/src/native_client/tests/prebuilt@" +
Var("nacl_revision"),
+ "src/third_party/sfntly/src/sfntly":
+ "http://sfntly.googlecode.com/svn/trunk/cpp/src/sfntly@" +
+ #TODO(arthurhsu): replace above line with this after mirror is setup.
+ #(Var("googlecode_url") % "sfntly") + "/trunk/cpp/src/sfntly@" +
+ Var("sfntly_revision"),
+
"src/third_party/skia/gpu":
(Var("googlecode_url") % "skia") + "/trunk/gpu@" + Var("skia_revision"),
diff --git a/skia/skia.gyp b/skia/skia.gyp
index a4b53af..2644d47 100644
--- a/skia/skia.gyp
+++ b/skia/skia.gyp
@@ -843,6 +843,7 @@
'skia_opts',
'skia_libtess',
'../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
+ '../third_party/sfntly/sfntly.gyp:sfntly',
'../third_party/zlib/zlib.gyp:zlib',
],
'direct_dependent_settings': {
diff --git a/third_party/sfntly/COPYING.txt b/third_party/sfntly/COPYING.txt
new file mode 100644
index 0000000..c61423c
--- /dev/null
+++ b/third_party/sfntly/COPYING.txt
@@ -0,0 +1,203 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2011 Google Inc. All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
diff --git a/third_party/sfntly/README.chromium b/third_party/sfntly/README.chromium
new file mode 100644
index 0000000..bf00b8c
--- /dev/null
+++ b/third_party/sfntly/README.chromium
@@ -0,0 +1,18 @@
+Name: sfntly
+URL: http://code.google.com/p/sfntly/
+Version: unknown
+Revision: 9
+Security Critical: yes
+
+Description:
+sfntly is a C++ library for using, editing, and creating sfnt container based
+fonts (e.g. OpenType, TrueType). We use it to subset the embedded font in the
+PDF generated in print preview so that the result PDF documents are
+significantly smaller and loaded faster.
+
+Local files (not taken from upstream):
+README.chromium
+src/subsetter/*
+
+COPYING.txt is the license file copied from upstream.
+A sfntly.gyp file has been added for building with Chromium.
diff --git a/third_party/sfntly/sfntly.gyp b/third_party/sfntly/sfntly.gyp
new file mode 100644
index 0000000..21b50ee
--- /dev/null
+++ b/third_party/sfntly/sfntly.gyp
@@ -0,0 +1,89 @@
+# Copyright (c) 2011 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'targets': [
+ {
+ 'target_name': 'sfntly',
+ 'type': 'static_library',
+ 'sources': [
+ 'src/sfntly/cmap_table.cc',
+ 'src/sfntly/cmap_table.h',
+ 'src/sfntly/data/byte_array.cc',
+ 'src/sfntly/data/byte_array.h',
+ 'src/sfntly/data/font_data.cc',
+ 'src/sfntly/data/font_data.h',
+ 'src/sfntly/data/font_input_stream.cc',
+ 'src/sfntly/data/font_input_stream.h',
+ 'src/sfntly/data/font_output_stream.cc',
+ 'src/sfntly/data/font_output_stream.h',
+ 'src/sfntly/data/growable_memory_byte_array.cc',
+ 'src/sfntly/data/growable_memory_byte_array.h',
+ 'src/sfntly/data/memory_byte_array.cc',
+ 'src/sfntly/data/memory_byte_array.h',
+ 'src/sfntly/data/readable_font_data.cc',
+ 'src/sfntly/data/readable_font_data.h',
+ 'src/sfntly/data/writable_font_data.cc',
+ 'src/sfntly/data/writable_font_data.h',
+ 'src/sfntly/font.cc',
+ 'src/sfntly/font.h',
+ 'src/sfntly/font_data_table.cc',
+ 'src/sfntly/font_data_table.h',
+ 'src/sfntly/font_data_table_builder_container.h',
+ 'src/sfntly/font_factory.cc',
+ 'src/sfntly/font_factory.h',
+ 'src/sfntly/font_header_table.cc',
+ 'src/sfntly/font_header_table.h',
+ 'src/sfntly/glyph_table.cc',
+ 'src/sfntly/glyph_table.h',
+ 'src/sfntly/horizontal_header_table.cc',
+ 'src/sfntly/horizontal_header_table.h',
+ 'src/sfntly/horizontal_metrics_table.cc',
+ 'src/sfntly/horizontal_metrics_table.h',
+ 'src/sfntly/loca_table.cc',
+ 'src/sfntly/loca_table.h',
+ 'src/sfntly/math/fixed1616.h',
+ 'src/sfntly/math/font_math.h',
+ 'src/sfntly/maximum_profile_table.cc',
+ 'src/sfntly/maximum_profile_table.h',
+ 'src/sfntly/name_table.cc',
+ 'src/sfntly/name_table.h',
+ 'src/sfntly/os2_table.cc',
+ 'src/sfntly/os2_table.h',
+ 'src/sfntly/port/atomic.h',
+ 'src/sfntly/port/config.h',
+ 'src/sfntly/port/endian.h',
+ 'src/sfntly/port/exception_type.h',
+ 'src/sfntly/port/file_input_stream.cc',
+ 'src/sfntly/port/file_input_stream.h',
+ 'src/sfntly/port/input_stream.h',
+ 'src/sfntly/port/memory_output_stream.cc',
+ 'src/sfntly/port/memory_output_stream.h',
+ 'src/sfntly/port/output_stream.h',
+ 'src/sfntly/port/refcount.h',
+ 'src/sfntly/port/type.h',
+ 'src/sfntly/subtable.cc',
+ 'src/sfntly/subtable.h',
+ 'src/sfntly/table.cc',
+ 'src/sfntly/table.h',
+ 'src/sfntly/tag.cc',
+ 'src/sfntly/tag.h',
+ 'src/subsetter/font_subsetter.cc',
+ 'src/subsetter/font_subsetter.h',
+ 'src/subsetter/subsetter_impl.cc',
+ 'src/subsetter/subsetter_impl.h',
+ ],
+ 'include_dirs': [
+ 'src', '../..',
+ ],
+ # This macro must be define to suppress the use of exception
+ 'defines': [
+ 'SFNTLY_NO_EXCEPTION',
+ ],
+ 'dependencies' : [
+ '../icu/icu.gyp:icuuc',
+ ],
+ },
+ ]
+}
diff --git a/third_party/sfntly/src/subsetter/font_subsetter.cc b/third_party/sfntly/src/subsetter/font_subsetter.cc
new file mode 100644
index 0000000..c045790
--- /dev/null
+++ b/third_party/sfntly/src/subsetter/font_subsetter.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "third_party/sfntly/src/subsetter/font_subsetter.h"
+
+#include "third_party/sfntly/src/subsetter/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);
+}
diff --git a/third_party/sfntly/src/subsetter/font_subsetter.h b/third_party/sfntly/src/subsetter/font_subsetter.h
new file mode 100644
index 0000000..9055cd3
--- /dev/null
+++ b/third_party/sfntly/src/subsetter/font_subsetter.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 THIRD_PARTY_SFNTLY_SRC_SUBSETTER_FONT_SUBSETTER_H_
+#define THIRD_PARTY_SFNTLY_SRC_SUBSETTER_FONT_SUBSETTER_H_
+
+#include <cstddef>
+
+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);
+};
+
+#endif // THIRD_PARTY_SFNTLY_SRC_SUBSETTER_FONT_SUBSETTER_H_
diff --git a/third_party/sfntly/src/subsetter/subsetter_impl.cc b/third_party/sfntly/src/subsetter/subsetter_impl.cc
new file mode 100644
index 0000000..290ae9f
--- /dev/null
+++ b/third_party/sfntly/src/subsetter/subsetter_impl.cc
@@ -0,0 +1,289 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "third_party/sfntly/src/subsetter/subsetter_impl.h"
+
+#include <string.h>
+
+#include <map>
+#include <set>
+
+#include "third_party/sfntly/src/sfntly/glyph_table.h"
+#include "third_party/sfntly/src/sfntly/loca_table.h"
+#include "third_party/sfntly/src/sfntly/name_table.h"
+#include "third_party/sfntly/src/sfntly/tag.h"
+#include "third_party/sfntly/src/sfntly/data/memory_byte_array.h"
+#include "third_party/sfntly/src/sfntly/port/memory_output_stream.h"
+
+namespace sfntly {
+
+void ConstructName(UChar* name_part, UnicodeString* name, int32_t name_id) {
+ switch(name_id) {
+ case NameId::kFullFontName:
+ *name = name_part;
+ break;
+ case NameId::kFontFamilyName:
+ case NameId::kPreferredFamily:
+ case NameId::kWWSFamilyName: {
+ UnicodeString 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;
+ }
+}
+
+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;
+}
+
+SubsetterImpl::SubsetterImpl() {
+}
+
+SubsetterImpl::~SubsetterImpl() {
+}
+
+bool SubsetterImpl::LoadFont(const char* font_name,
+ const unsigned char* original_font,
+ size_t font_size) {
+ ByteArrayPtr raw_font =
+ new MemoryByteArray((byte_t*)original_font, font_size);
+ if (factory_ == NULL) {
+ factory_.attach(FontFactory::getInstance());
+ }
+
+ FontArray font_array;
+ factory_->loadFonts(raw_font, &font_array);
+ font_ = FindFont(font_name, font_array);
+ if (font_ == NULL) {
+ return false;
+ }
+
+ return true;
+}
+
+int SubsetterImpl::SubsetFont(const unsigned int* glyph_ids,
+ size_t glyph_count,
+ unsigned char** output_buffer) {
+ if (factory_ == NULL || font_ == NULL) {
+ return -1;
+ }
+
+ FontPtr new_font;
+ new_font.attach(Subset(glyph_ids, glyph_count));
+ if (new_font == NULL) {
+ return 0;
+ }
+
+ MemoryOutputStream output_stream;
+ factory_->serializeFont(new_font, &output_stream);
+ int length = static_cast<int>(output_stream.size());
+ if (length > 0) {
+ *output_buffer = new unsigned char[length];
+ memcpy(*output_buffer, output_stream.get(), length);
+ }
+
+ return length;
+}
+
+Font* SubsetterImpl::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 b = font_array.begin(), e = font_array.end();
+ b != e; ++b) {
+ if (HasName(font_name, (*b).p_)) {
+ return (*b).p_;
+ }
+ }
+ }
+
+ return font_array[0].p_;
+}
+
+bool SubsetterImpl::HasName(const char* font_name, Font* font) {
+ UnicodeString font_string = UnicodeString::fromUTF8(font_name);
+ if (font_string.isEmpty())
+ return false;
+ UnicodeString regular_suffix = UnicodeString::fromUTF8(" Regular");
+ UnicodeString alt_font_string = font_string;
+ alt_font_string += regular_suffix;
+
+ typedef std::map<int32_t, UnicodeString> NameMap;
+ NameMap names;
+ NameTablePtr name_table = down_cast<NameTable*>(font->table(Tag::name));
+
+ 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: {
+ int32_t hash_code = HashCode(name_table->platformId(i),
+ name_table->encodingId(i),
+ name_table->languageId(i),
+ name_table->nameId(i));
+ UChar* name_part = name_table->name(i);
+ ConstructName(name_part, &(names[hash_code]), name_table->nameId(i));
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (!names.empty()) {
+ for (NameMap::iterator b = names.begin(), e = names.end(); b != e; ++b) {
+ if (b->second.caseCompare(font_string, 0) == 0 ||
+ b->second.caseCompare(alt_font_string, 0) == 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+CALLER_ATTACH Font* SubsetterImpl::Subset(const unsigned int* glyph_ids,
+ size_t glyph_count) {
+ if (glyph_ids == NULL || glyph_count == 0) {
+ return NULL;
+ }
+
+ // Find glyf and loca table.
+ GlyphTablePtr glyph_table = down_cast<GlyphTable*>(font_->table(Tag::glyf));
+ LocaTablePtr loca_table = down_cast<LocaTable*>(font_->table(Tag::loca));
+ if (glyph_table == NULL || loca_table == NULL) {
+ // The font is invalid.
+ return NULL;
+ }
+
+ // Setup font builders we need.
+ FontBuilderPtr font_builder;
+ font_builder.attach(factory_->newFontBuilder());
+
+ GlyphTableBuilderPtr glyph_table_builder;
+ glyph_table_builder.attach(down_cast<GlyphTable::Builder*>(
+ font_builder->newTableBuilder(Tag::glyf)));
+ LocaTableBuilderPtr loca_table_builder;
+ loca_table_builder.attach(down_cast<LocaTable::Builder*>(
+ font_builder->newTableBuilder(Tag::loca)));
+ if (glyph_table_builder == NULL || loca_table_builder == NULL) {
+ // Out of memory.
+ return NULL;
+ }
+
+ // Sort and uniquify glyph ids.
+ IntegerSet glyph_id_set;
+ glyph_id_set.insert(0); // Always include glyph id 0.
+ for (size_t i = 0; i < glyph_count; ++i) {
+ glyph_id_set.insert(glyph_ids[i]);
+ }
+
+ // Extract glyphs and setup loca list.
+ IntegerList loca_list;
+ loca_list.resize(loca_table->numGlyphs());
+ 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::iterator i = glyph_id_set.begin(), e = glyph_id_set.end();
+ i != e; ++i) {
+ if (*i < 0 || *i >= loca_table->numGlyphs()) {
+ // 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->glyph(offset, length));
+ if (glyph == NULL) {
+ // Error finding glyph, ignore.
+ continue;
+ }
+
+ // Add glyph to new glyf table.
+ ReadableFontDataPtr data = glyph->readFontData();
+ WritableFontDataPtr copy_data;
+ copy_data.attach(font_builder->getNewData(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;
+ }
+ last_offset += length;
+ loca_list[*i + 1] = last_offset;
+ last_glyph_id = *i;
+ }
+ for (int32_t j = last_glyph_id + 1; j <= loca_table->numGlyphs(); ++j) {
+ loca_list[j] = last_offset;
+ }
+ loca_table_builder->setLocaList(&loca_list);
+
+ // Setup remaining builders.
+ for (TableMap::iterator i = font_->tables()->begin(),
+ e = font_->tables()->end(); i != e; ++i) {
+ // We already build the builder for glyph and loca.
+ if (i->first != Tag::glyf && i->first != Tag::loca) {
+ // The newTableBuilder() call will alter internal state of font_builder
+ // AND the reference count of returned object. Therefore we need to
+ // dereference it.
+ TableBuilderPtr dereference;
+ dereference.attach(
+ font_builder->newTableBuilder(i->first, i->second->readFontData()));
+ }
+ }
+
+ return font_builder->build();
+}
+
+} // namespace sfntly
diff --git a/third_party/sfntly/src/subsetter/subsetter_impl.h b/third_party/sfntly/src/subsetter/subsetter_impl.h
new file mode 100644
index 0000000..7994689
--- /dev/null
+++ b/third_party/sfntly/src/subsetter/subsetter_impl.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 THIRD_PARTY_SFNTLY_SRC_SUBSETTER_SUBSETTER_IMPL_H_
+#define THIRD_PARTY_SFNTLY_SRC_SUBSETTER_SUBSETTER_IMPL_H_
+
+#include "third_party/sfntly/src/sfntly/font.h"
+#include "third_party/sfntly/src/sfntly/font_factory.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);
+ int SubsetFont(const unsigned int* glyph_ids,
+ size_t glyph_count,
+ unsigned char** output_buffer);
+
+ private:
+ Font* FindFont(const char* font_name, const FontArray& font_array);
+ bool HasName(const char* font_name, Font* font);
+ CALLER_ATTACH Font* Subset(const unsigned int* glyph_ids,
+ size_t glyph_count);
+
+ FontFactoryPtr factory_;
+ FontPtr font_;
+};
+
+} // namespace sfntly
+
+#endif // THIRD_PARTY_SFNTLY_SRC_SUBSETTER_SUBSETTER_IMPL_H_