aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2019-05-03 15:19:10 -0700
committerHaibo Huang <hhb@google.com>2019-05-03 22:40:58 +0000
commit29d542f77dfe291616322f469e777e43ecca88f9 (patch)
treeafb7377913edde6f710eac5369d710595f7ae4b6
parent7515f315c3f168e48946ef4b3e9f6d0b63747b59 (diff)
parent9620b607af5b796badefebcf16d7ce6e6786f205 (diff)
downloadsfntly-29d542f77dfe291616322f469e777e43ecca88f9.tar.gz
Merge remote-tracking branch 'aosp/upstream-master' into update
Bug: 129498355 Bug: 116114182 Test: build Change-Id: I16095748d0ed921fbf1e4f473fa91f271648f673
-rw-r--r--Android.bp53
-rw-r--r--COPYING.android2
l---------LICENSE1
-rw-r--r--METADATA8
l---------[-rw-r--r--]NOTICE204
-rw-r--r--README.md19
-rw-r--r--cpp/CMakeLists.txt34
-rw-r--r--cpp/README.txt3
-rw-r--r--cpp/src/sample/chromium/subsetter_impl.cc70
-rw-r--r--cpp/src/sfntly/data/byte_array.cc28
-rw-r--r--cpp/src/sfntly/data/byte_array.h26
-rw-r--r--cpp/src/sfntly/data/font_data.cc4
-rw-r--r--cpp/src/sfntly/data/font_data.h4
-rw-r--r--cpp/src/sfntly/data/font_input_stream.cc15
-rw-r--r--cpp/src/sfntly/data/font_input_stream.h6
-rw-r--r--cpp/src/sfntly/data/font_output_stream.cc28
-rw-r--r--cpp/src/sfntly/data/font_output_stream.h12
-rw-r--r--cpp/src/sfntly/data/growable_memory_byte_array.cc10
-rw-r--r--cpp/src/sfntly/data/growable_memory_byte_array.h12
-rw-r--r--cpp/src/sfntly/data/memory_byte_array.cc14
-rw-r--r--cpp/src/sfntly/data/memory_byte_array.h16
-rw-r--r--cpp/src/sfntly/data/readable_font_data.cc12
-rw-r--r--cpp/src/sfntly/data/readable_font_data.h8
-rw-r--r--cpp/src/sfntly/data/writable_font_data.cc48
-rw-r--r--cpp/src/sfntly/data/writable_font_data.h16
-rw-r--r--cpp/src/sfntly/font.cc92
-rw-r--r--cpp/src/sfntly/font.h20
-rw-r--r--cpp/src/sfntly/font_factory.cc23
-rw-r--r--cpp/src/sfntly/font_factory.h11
-rw-r--r--cpp/src/sfntly/port/file_input_stream.cc14
-rw-r--r--cpp/src/sfntly/port/file_input_stream.h9
-rw-r--r--cpp/src/sfntly/port/input_stream.h15
-rwxr-xr-xcpp/src/sfntly/port/memory_input_stream.cc16
-rwxr-xr-xcpp/src/sfntly/port/memory_input_stream.h13
-rw-r--r--cpp/src/sfntly/port/memory_output_stream.cc10
-rw-r--r--cpp/src/sfntly/port/memory_output_stream.h12
-rw-r--r--cpp/src/sfntly/port/output_stream.h8
-rw-r--r--cpp/src/sfntly/port/refcount.h3
-rw-r--r--cpp/src/sfntly/port/type.h33
-rw-r--r--cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc16
-rw-r--r--cpp/src/sfntly/table/bitmap/big_glyph_metrics.h16
-rw-r--r--cpp/src/sfntly/table/bitmap/eblc_table.cc30
-rw-r--r--cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc10
-rw-r--r--cpp/src/sfntly/table/bitmap/index_sub_table_format1.h8
-rw-r--r--cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc8
-rw-r--r--cpp/src/sfntly/table/bitmap/index_sub_table_format3.h6
-rw-r--r--cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc12
-rw-r--r--cpp/src/sfntly/table/bitmap/index_sub_table_format5.h8
-rw-r--r--cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc10
-rw-r--r--cpp/src/sfntly/table/bitmap/small_glyph_metrics.h10
-rw-r--r--cpp/src/sfntly/table/byte_array_table_builder.cc2
-rw-r--r--cpp/src/sfntly/table/byte_array_table_builder.h2
-rw-r--r--cpp/src/sfntly/table/core/cmap_table.cc10
-rw-r--r--cpp/src/sfntly/table/core/cmap_table.h8
-rw-r--r--cpp/src/sfntly/table/core/font_header_table.cc2
-rw-r--r--cpp/src/sfntly/table/core/name_table.cc36
-rw-r--r--cpp/src/sfntly/table/core/name_table.h28
-rw-r--r--cpp/src/sfntly/table/core/os2_table.cc14
-rw-r--r--cpp/src/sfntly/table/core/os2_table.h12
-rw-r--r--cpp/src/sfntly/table/header.h28
-rw-r--r--cpp/src/sfntly/table/truetype/glyph_table.cc87
-rw-r--r--cpp/src/sfntly/table/truetype/glyph_table.h25
-rw-r--r--cpp/src/sfntly/table/truetype/loca_table.cc15
-rw-r--r--cpp/src/sfntly/table/truetype/loca_table.h8
-rw-r--r--cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.cc6
-rw-r--r--cpp/src/sfntly/tools/subsetter/subsetter.cc16
-rw-r--r--cpp/src/sfntly/tools/subsetter/subsetter.h10
-rw-r--r--cpp/src/sfntly/tools/subsetter/table_subsetter.h2
-rw-r--r--cpp/src/sfntly/tools/subsetter/table_subsetter_impl.cc2
-rw-r--r--cpp/src/sfntly/tools/subsetter/table_subsetter_impl.h4
-rw-r--r--cpp/src/test/bitmap_table_test.cc7
-rw-r--r--cpp/src/test/byte_array_test.cc2
-rw-r--r--cpp/src/test/endian_test.cc2
-rw-r--r--cpp/src/test/font_data_test.cc6
-rw-r--r--cpp/src/test/open_type_data_test.cc6
-rw-r--r--cpp/src/test/otf_basic_editing_test.cc31
-rw-r--r--cpp/src/test/test_utils_test.cc2
-rw-r--r--cpp/src/test/verify_hhea.cc2
-rw-r--r--cpp/src/test/verify_maxp.cc2
-rw-r--r--cpp/src/test/verify_os2.cc4
-rw-r--r--doc/MicroTypeExpress.md42
-rw-r--r--doc/SfntlyCPlusPlusNotes.md164
-rw-r--r--doc/Useful_links.md25
-rw-r--r--doc/build_cpp.md150
-rw-r--r--doc/smart_pointer_usage.md145
-rw-r--r--doc/unit_tests.md32
86 files changed, 1137 insertions, 868 deletions
diff --git a/Android.bp b/Android.bp
index f26585d..1354a5a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2,55 +2,10 @@ cc_library_static {
name: "libsfntly",
host_supported: true,
srcs: [
- "cpp/src/sfntly/data/byte_array.cc",
- "cpp/src/sfntly/data/font_data.cc",
- "cpp/src/sfntly/data/font_input_stream.cc",
- "cpp/src/sfntly/data/font_output_stream.cc",
- "cpp/src/sfntly/data/growable_memory_byte_array.cc",
- "cpp/src/sfntly/data/memory_byte_array.cc",
- "cpp/src/sfntly/data/readable_font_data.cc",
- "cpp/src/sfntly/data/writable_font_data.cc",
- "cpp/src/sfntly/font.cc",
- "cpp/src/sfntly/font_factory.cc",
- "cpp/src/sfntly/port/file_input_stream.cc",
- "cpp/src/sfntly/port/lock.cc",
- "cpp/src/sfntly/port/memory_input_stream.cc",
- "cpp/src/sfntly/port/memory_output_stream.cc",
- "cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc",
- "cpp/src/sfntly/table/bitmap/bitmap_glyph.cc",
- "cpp/src/sfntly/table/bitmap/bitmap_glyph_info.cc",
- "cpp/src/sfntly/table/bitmap/bitmap_size_table.cc",
- "cpp/src/sfntly/table/bitmap/composite_bitmap_glyph.cc",
- "cpp/src/sfntly/table/bitmap/ebdt_table.cc",
- "cpp/src/sfntly/table/bitmap/eblc_table.cc",
- "cpp/src/sfntly/table/bitmap/ebsc_table.cc",
- "cpp/src/sfntly/table/bitmap/glyph_metrics.cc",
- "cpp/src/sfntly/table/bitmap/index_sub_table.cc",
- "cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc",
- "cpp/src/sfntly/table/bitmap/index_sub_table_format2.cc",
- "cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc",
- "cpp/src/sfntly/table/bitmap/index_sub_table_format4.cc",
- "cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc",
- "cpp/src/sfntly/table/bitmap/simple_bitmap_glyph.cc",
- "cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc",
- "cpp/src/sfntly/table/byte_array_table_builder.cc",
- "cpp/src/sfntly/table/core/cmap_table.cc",
- "cpp/src/sfntly/table/core/font_header_table.cc",
- "cpp/src/sfntly/table/core/horizontal_device_metrics_table.cc",
- "cpp/src/sfntly/table/core/horizontal_header_table.cc",
- "cpp/src/sfntly/table/core/horizontal_metrics_table.cc",
- "cpp/src/sfntly/table/core/maximum_profile_table.cc",
- "cpp/src/sfntly/table/core/name_table.cc",
- "cpp/src/sfntly/table/core/os2_table.cc",
- "cpp/src/sfntly/table/font_data_table.cc",
- "cpp/src/sfntly/table/generic_table_builder.cc",
- "cpp/src/sfntly/table/header.cc",
- "cpp/src/sfntly/table/subtable.cc",
- "cpp/src/sfntly/table/table.cc",
- "cpp/src/sfntly/table/table_based_table_builder.cc",
- "cpp/src/sfntly/table/truetype/glyph_table.cc",
- "cpp/src/sfntly/table/truetype/loca_table.cc",
- "cpp/src/sfntly/tag.cc",
+ "cpp/src/sfntly/*.cc",
+ "cpp/src/sfntly/data/*.cc",
+ "cpp/src/sfntly/port/*.cc",
+ "cpp/src/sfntly/table/**/*.cc",
"cpp/src/sample/chromium/font_subsetter.cc",
"cpp/src/sample/chromium/subsetter_impl.cc",
],
diff --git a/COPYING.android b/COPYING.android
deleted file mode 100644
index 13bcce2..0000000
--- a/COPYING.android
+++ /dev/null
@@ -1,2 +0,0 @@
-See cpp/COPYING for license details.
-
diff --git a/LICENSE b/LICENSE
new file mode 120000
index 0000000..3cb12fe
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+cpp/COPYING.txt \ No newline at end of file
diff --git a/METADATA b/METADATA
index 00e2d3a..b02a109 100644
--- a/METADATA
+++ b/METADATA
@@ -5,10 +5,10 @@ third_party {
type: GIT
value: "https://github.com/googlefonts/sfntly.git"
}
- version: "64f78562d2003eb7cacaaa86a398cbd41881ba6f"
+ version: "9620b607af5b796badefebcf16d7ce6e6786f205"
last_upgrade_date {
- year: 2017
- month: 4
- day: 11
+ year: 2019
+ month: 5
+ day: 3
}
}
diff --git a/NOTICE b/NOTICE
index c61423c..7a694c9 100644..120000
--- a/NOTICE
+++ b/NOTICE
@@ -1,203 +1 @@
-
- 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.
-
+LICENSE \ No newline at end of file
diff --git a/README.md b/README.md
index 9961600..7419f81 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,6 @@
-# What is sfntly?
+# sfntly
-sfntly is pronounced "esfontlee".
+This project is not developed any further.
+Only Bug fixes will be merged, but new features won't.
-sfntly is a Java and C++ library for using, editing, and creating sfnt container based fonts (e.g. OpenType, TrueType). This library was initially created by Google's Font Team and the C++ port was done by the Chrome team. It has been made open source.
-
-The basic features of sfntly are the reading, editing, and writing of an sfnt container font. Fonts that use an sfnt container include OpenType, TrueType, AAT/GX, and Graphite. sfntly isn't itself a tool that is usable by an end user - it is a library that allows software developers to build tools that manipulate fonts in ways that haven't been easily accessible to most developers. The sfntly library is available in Java with a partial C++ port. However, we have included some font tools that are built on top of sfntly: a font subsetter, font dumper, a font linter, some compression utilities.
-
-The uses of sfntly are really anything that you can think of that involves reading and/or editing fonts. Right now, the Java version is the core library used to power Google's Web Fonts project. There it is used for all font manipulation - to read font data, to pull apart fonts, and to then reassemble them before they are streamed out to a user. Portions of the font that are not needed - specific glyph ranges or features - are stripped using sfntly to minimize the size of the streamed font. The C++ port is used somewhat similarly within Chrome to subset fonts for insertion into a PDF for viewing or printing. Though the features stripped in the font are different in Chrome than in Web Fonts because the end use is different.
-
-Using sfntly you can read and extract any of the tables in a font. The tables are the individual data structures within the font for each of the features and functionality: glyph outlines, character maps, kerning, meta data, etc. If you look over the OpenType and TrueType specs, you will see a number of categories of tables. sfntly currently supports all of the required tables, the TrueType outline tables, bitmap glyph tables, and a couple of the other miscellaneous tables. This level of support provides for many of the needs developers have related to the informational reading of font data. It also covers a lot of the editing needs.
-
-To get started with sfntly: clone the repository and follow the quickstart.txt guide in the Java directory
-
-have fun
-
-Stuart Gill - sfntly Architect and Lead Developer
+An actively maintained fork with new features is available at <https://github.com/rillig/sfntly>
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index 85932bc..57bcabc 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -6,13 +6,15 @@ set(CMAKE_LEGACY_CYGWIN_WIN32 0)
project(sfntly)
+set(GCC_OR_CLANG ((CMAKE_CXX_COMPILER_ID MATCHES "Clang") OR CMAKE_COMPILER_IS_GNUCXX))
+
# For gcc, make the default be debug build and valgrind friendly.
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
add_definitions("-DDEBUG -D_DEBUG -g -fno-inline -fno-omit-frame-pointer -fno-builtin")
endif(NOT CMAKE_BUILD_TYPE)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/lib)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/bin)
@@ -21,9 +23,9 @@ endif(CMAKE_COMPILER_IS_GNUCXX)
# The following simulates Chrome compilation flags
add_definitions(-DSFNTLY_NO_EXCEPTION)
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
add_definitions(-D__wur=__attribute__\(\(warn_unused_result\)\) -Wall -Werror -fno-exceptions)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
# Use STL for TinyXML library
add_definitions(-DTIXML_USE_STL)
@@ -69,9 +71,9 @@ endif(MSVC10 OR MSVC90)
src/sfntly/tools/*.h src/sfntly/tools/*.cc)
add_executable(subsetter ${SIMPLE_SUBSETTER})
target_link_libraries(subsetter sfntly icuuc)
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
target_link_libraries(subsetter pthread)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
file(GLOB TINYXML src/test/tinyxml/*.cpp)
add_library(tinyxml
${TINYXML})
@@ -86,9 +88,9 @@ endif(CMAKE_COMPILER_IS_GNUCXX)
ext/gtest/src/gtest-all.cc
ext/gtest/src/gtest_main.cc)
target_link_libraries(unit_test sfntly icuuc tinyxml)
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
target_link_libraries(unit_test pthread)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
# subtly targets
file(GLOB SUBTLY_FILES src/sample/subtly/*.h src/sample/subtly/*.cc)
file(GLOB SUBTLY_MAINS src/sample/subtly/*main.cc)
@@ -98,26 +100,26 @@ endif(CMAKE_COMPILER_IS_GNUCXX)
add_executable(subtly_subsetter
src/sample/subtly/subsetter_main.cc)
target_link_libraries(subtly_subsetter subtly sfntly icuuc)
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
target_link_libraries(subtly_subsetter pthread)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
add_executable(subtly_merger
src/sample/subtly/merger_main.cc)
target_link_libraries(subtly_merger subtly sfntly icuuc)
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
target_link_libraries(subtly_merger pthread)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
add_executable(subtly_debug
src/sample/subtly/debug_main.cc)
target_link_libraries(subtly_debug subtly sfntly icuuc)
-if(CMAKE_COMPILER_IS_GNUCXX)
+if(GCC_OR_CLANG)
target_link_libraries(subtly_debug pthread)
-endif(CMAKE_COMPILER_IS_GNUCXX)
+endif(GCC_OR_CLANG)
add_executable(chrome_subsetter
${CHROME_SUBSETTER_LIB}
src/sample/chromium/chrome_subsetter.cc
)
target_link_libraries(chrome_subsetter sfntly icuuc)
- if(CMAKE_COMPILER_IS_GNUCXX)
+ if(GCC_OR_CLANG)
target_link_libraries(chrome_subsetter pthread)
- endif(CMAKE_COMPILER_IS_GNUCXX)
+ endif(GCC_OR_CLANG)
diff --git a/cpp/README.txt b/cpp/README.txt
deleted file mode 100644
index ac2b43a..0000000
--- a/cpp/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Please refer to http://code.google.com/p/sfntly/wiki/build_cpp regarding how to build sfntly.
-
-sfntly wiki contains other useful documents: http://code.google.com/p/sfntly/w/list \ No newline at end of file
diff --git a/cpp/src/sample/chromium/subsetter_impl.cc b/cpp/src/sample/chromium/subsetter_impl.cc
index fc82ef1..d6c3216 100644
--- a/cpp/src/sample/chromium/subsetter_impl.cc
+++ b/cpp/src/sample/chromium/subsetter_impl.cc
@@ -20,11 +20,13 @@
#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"
@@ -306,6 +308,10 @@ bool SetupGlyfBuilders(Font::Builder* font_builder,
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;
@@ -320,14 +326,15 @@ bool SetupGlyfBuilders(Font::Builder* font_builder,
bool HasOverlap(int32_t range_begin, int32_t range_end,
const IntegerSet& glyph_ids) {
- if (range_begin == range_end) {
+ if (range_begin == range_end)
return glyph_ids.find(range_begin) != glyph_ids.end();
- } else if (range_end > range_begin) {
- IntegerSet::const_iterator left = glyph_ids.lower_bound(range_begin);
- IntegerSet::const_iterator right = glyph_ids.lower_bound(range_end);
- return right != left;
- }
- return false;
+
+ 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.
@@ -415,14 +422,14 @@ bool InitializeBitmapBuilder(EbdtTable::Builder* ebdt, EblcTable::Builder* eblc,
void CopyBigGlyphMetrics(BigGlyphMetrics::Builder* source,
BigGlyphMetrics::Builder* target) {
- target->SetHeight(static_cast<byte_t>(source->Height()));
- target->SetWidth(static_cast<byte_t>(source->Width()));
- target->SetHoriBearingX(static_cast<byte_t>(source->HoriBearingX()));
- target->SetHoriBearingY(static_cast<byte_t>(source->HoriBearingY()));
- target->SetHoriAdvance(static_cast<byte_t>(source->HoriAdvance()));
- target->SetVertBearingX(static_cast<byte_t>(source->VertBearingX()));
- target->SetVertBearingY(static_cast<byte_t>(source->VertBearingY()));
- target->SetVertAdvance(static_cast<byte_t>(source->VertAdvance()));
+ 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*
@@ -685,11 +692,7 @@ bool SubsetterImpl::LoadFont(const char* font_name,
FontArray font_array;
factory_->LoadFonts(&mis, &font_array);
font_ = FindFont(font_name, font_array);
- if (font_ == NULL) {
- return false;
- }
-
- return true;
+ return font_ != NULL;
}
int SubsetterImpl::SubsetFont(const unsigned int* glyph_ids,
@@ -723,12 +726,14 @@ int SubsetterImpl::SubsetFont(const unsigned int* glyph_ids,
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);
+ 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;
}
@@ -790,6 +795,8 @@ Font* SubsetterImpl::Subset(const IntegerSet& glyph_ids, GlyphTable* glyf,
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;
@@ -817,9 +824,8 @@ Font* SubsetterImpl::Subset(const IntegerSet& glyph_ids, GlyphTable* glyf,
}
IntegerSet allowed_tags;
- for (size_t i = 0; i < sizeof(TABLES_IN_SUBSET) / sizeof(int32_t); ++i) {
+ 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(),
@@ -828,12 +834,12 @@ Font* SubsetterImpl::Subset(const IntegerSet& glyph_ids, GlyphTable* glyf,
allowed_tags = result;
// Setup remaining builders.
- for (IntegerSet::iterator i = allowed_tags.begin(), e = allowed_tags.end();
- i != e; ++i) {
- Table* table = font_->GetTable(*i);
- if (table) {
- font_builder->NewTableBuilder(*i, table->ReadFontData());
- }
+ 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();
diff --git a/cpp/src/sfntly/data/byte_array.cc b/cpp/src/sfntly/data/byte_array.cc
index 57f9eed..f510881 100644
--- a/cpp/src/sfntly/data/byte_array.cc
+++ b/cpp/src/sfntly/data/byte_array.cc
@@ -26,9 +26,6 @@ const int32_t ByteArray::COPY_BUFFER_SIZE = 8192;
ByteArray::~ByteArray() {}
-int32_t ByteArray::Length() { return filled_length_; }
-int32_t ByteArray::Size() { return storage_length_; }
-
int32_t ByteArray::SetFilledLength(int32_t filled_length) {
filled_length_ = std::min<int32_t>(filled_length, storage_length_);
return filled_length_;
@@ -40,24 +37,27 @@ int32_t ByteArray::Get(int32_t index) {
return InternalGet(index) & 0xff;
}
-int32_t ByteArray::Get(int32_t index, ByteVector* b) {
+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,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length) {
assert(b);
- if (index < 0 || index >= filled_length_) {
+ 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, byte_t b) {
+void ByteArray::Put(int32_t index, uint8_t b) {
if (index < 0 || index >= Size()) {
#if defined (SFNTLY_NO_EXCEPTION)
return;
@@ -70,13 +70,13 @@ void ByteArray::Put(int32_t index, byte_t b) {
filled_length_ = std::max<int32_t>(filled_length_, index + 1);
}
-int32_t ByteArray::Put(int index, ByteVector* b) {
+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,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length) {
assert(b);
@@ -109,7 +109,7 @@ int32_t ByteArray::CopyTo(int32_t dst_offset, ByteArray* array,
return -1;
}
- ByteVector b(COPY_BUFFER_SIZE);
+ std::vector<uint8_t> b(COPY_BUFFER_SIZE);
int32_t bytes_read = 0;
int32_t index = 0;
int32_t remaining_length = length;
@@ -130,7 +130,7 @@ int32_t ByteArray::CopyTo(OutputStream* os) {
}
int32_t ByteArray::CopyTo(OutputStream* os, int32_t offset, int32_t length) {
- ByteVector b(COPY_BUFFER_SIZE);
+ 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);
@@ -143,7 +143,7 @@ int32_t ByteArray::CopyTo(OutputStream* os, int32_t offset, int32_t length) {
}
bool ByteArray::CopyFrom(InputStream* is, int32_t length) {
- ByteVector b(COPY_BUFFER_SIZE);
+ 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);
@@ -163,7 +163,7 @@ bool ByteArray::CopyFrom(InputStream* is, int32_t length) {
}
bool ByteArray::CopyFrom(InputStream* is) {
- ByteVector b(COPY_BUFFER_SIZE);
+ std::vector<uint8_t> b(COPY_BUFFER_SIZE);
int32_t bytes_read = 0;
int32_t index = 0;
int32_t buffer_length = COPY_BUFFER_SIZE;
diff --git a/cpp/src/sfntly/data/byte_array.h b/cpp/src/sfntly/data/byte_array.h
index 70dc92f..c5e3788 100644
--- a/cpp/src/sfntly/data/byte_array.h
+++ b/cpp/src/sfntly/data/byte_array.h
@@ -32,15 +32,15 @@ class ByteArray : virtual public RefCount {
virtual ~ByteArray();
// Gets the current filled and readable length of the array.
- int32_t Length();
+ 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();
+ int32_t Size() const { return storage_length_; }
// Determines whether or not this array is growable or of fixed size.
- bool growable() { return growable_; }
+ bool growable() const { return growable_; }
int32_t SetFilledLength(int32_t filled_length);
@@ -55,7 +55,7 @@ class ByteArray : virtual public RefCount {
// @param index the index into the byte array
// @param b the buffer to put the bytes read into
// @return the number of bytes read from the buffer
- virtual int32_t Get(int32_t index, ByteVector* b);
+ 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
@@ -66,18 +66,18 @@ class ByteArray : virtual public RefCount {
// @param length the number of bytes to put into the buffer
// @return the number of bytes read from the buffer
virtual int32_t Get(int32_t index,
- byte_t* b,
+ 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, byte_t b);
+ 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, ByteVector* b);
+ 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
@@ -89,7 +89,7 @@ class ByteArray : virtual public RefCount {
// @param length the number of bytes to copy into the array
// @return the number of bytes actually written
virtual int32_t Put(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length);
@@ -149,7 +149,7 @@ class ByteArray : virtual public RefCount {
// Stores the byte at the index given.
// @param index the location to store at
// @param b the byte to store
- virtual void InternalPut(int32_t index, byte_t b) = 0;
+ 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
@@ -158,14 +158,14 @@ class ByteArray : virtual public RefCount {
// @param length the length of the byte array to store from the offset
// @return the number of bytes actually stored
virtual int32_t InternalPut(int32_t index,
- byte_t* b,
+ 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 byte_t InternalGet(int32_t index) = 0;
+ 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
@@ -174,7 +174,7 @@ class ByteArray : virtual public RefCount {
// @param length the length of bytes to read
// @return the number of bytes actually ready
virtual int32_t InternalGet(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length) = 0;
@@ -182,7 +182,7 @@ class ByteArray : virtual public RefCount {
virtual void Close() = 0;
// C++ port only, raw pointer to the first element of storage.
- virtual byte_t* Begin() = 0;
+ virtual uint8_t* Begin() = 0;
// Java toString() not ported.
diff --git a/cpp/src/sfntly/data/font_data.cc b/cpp/src/sfntly/data/font_data.cc
index 95bee3e..8fa8610 100644
--- a/cpp/src/sfntly/data/font_data.cc
+++ b/cpp/src/sfntly/data/font_data.cc
@@ -81,11 +81,11 @@ void FontData::Init(ByteArray* ba) {
bound_length_ = GROWABLE_SIZE;
}
-int32_t FontData::BoundOffset(int32_t offset) {
+int32_t FontData::BoundOffset(int32_t offset) const {
return offset + bound_offset_;
}
-int32_t FontData::BoundLength(int32_t offset, int32_t length) {
+int32_t FontData::BoundLength(int32_t offset, int32_t length) const {
return std::min<int32_t>(length, bound_length_ - offset);
}
diff --git a/cpp/src/sfntly/data/font_data.h b/cpp/src/sfntly/data/font_data.h
index e0e7e79..20c7e37 100644
--- a/cpp/src/sfntly/data/font_data.h
+++ b/cpp/src/sfntly/data/font_data.h
@@ -99,14 +99,14 @@ class FontData : virtual public RefCount {
// the data.
// @param offset the offset to get the bound compensated offset for
// @return the bound compensated offset
- int32_t BoundOffset(int32_t 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);
+ int32_t BoundLength(int32_t offset, int32_t length) const;
static const int32_t GROWABLE_SIZE = INT_MAX;
diff --git a/cpp/src/sfntly/data/font_input_stream.cc b/cpp/src/sfntly/data/font_input_stream.cc
index dcf8be3..87a515b 100644
--- a/cpp/src/sfntly/data/font_input_stream.cc
+++ b/cpp/src/sfntly/data/font_input_stream.cc
@@ -32,10 +32,17 @@ 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_) {
+ if (stream_)
return stream_->Available();
- }
return 0;
}
@@ -75,7 +82,7 @@ int32_t FontInputStream::Read() {
return b;
}
-int32_t FontInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
+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;
@@ -88,7 +95,7 @@ int32_t FontInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
return bytes_read;
}
-int32_t FontInputStream::Read(ByteVector* b) {
+int32_t FontInputStream::Read(std::vector<uint8_t>* b) {
return Read(b, 0, b->size());
}
diff --git a/cpp/src/sfntly/data/font_input_stream.h b/cpp/src/sfntly/data/font_input_stream.h
index 9992b07..c02848d 100644
--- a/cpp/src/sfntly/data/font_input_stream.h
+++ b/cpp/src/sfntly/data/font_input_stream.h
@@ -59,7 +59,7 @@ class FontInputStream : public InputStream {
virtual ~FontInputStream();
-
+ virtual int32_t Length();
virtual int32_t Available();
virtual void Close();
virtual void Mark(int32_t readlimit);
@@ -67,8 +67,8 @@ class FontInputStream : public InputStream {
virtual void Reset();
virtual int32_t Read();
- virtual int32_t Read(ByteVector* buffer);
- virtual int32_t Read(ByteVector* buffer, int32_t offset, int32_t length);
+ 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
diff --git a/cpp/src/sfntly/data/font_output_stream.cc b/cpp/src/sfntly/data/font_output_stream.cc
index 3422a22..169b02f 100644
--- a/cpp/src/sfntly/data/font_output_stream.cc
+++ b/cpp/src/sfntly/data/font_output_stream.cc
@@ -29,21 +29,21 @@ FontOutputStream::~FontOutputStream() {
// Do not close, underlying stream shall clean up themselves.
}
-void FontOutputStream::Write(byte_t b) {
+void FontOutputStream::Write(uint8_t b) {
if (stream_) {
stream_->Write(b);
position_++;
}
}
-void FontOutputStream::Write(ByteVector* b) {
+void FontOutputStream::Write(std::vector<uint8_t>* b) {
if (b) {
Write(b, 0, b->size());
position_ += b->size();
}
}
-void FontOutputStream::Write(ByteVector* b, int32_t off, int32_t len) {
+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 ||
@@ -59,7 +59,7 @@ void FontOutputStream::Write(ByteVector* b, int32_t off, int32_t len) {
position_ += len;
}
-void FontOutputStream::Write(byte_t* b, int32_t off, int32_t 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) {
@@ -74,13 +74,13 @@ void FontOutputStream::Write(byte_t* b, int32_t off, int32_t len) {
position_ += len;
}
-void FontOutputStream::WriteChar(byte_t c) {
+void FontOutputStream::WriteChar(uint8_t c) {
Write(c);
}
void FontOutputStream::WriteUShort(int32_t us) {
- Write((byte_t)((us >> 8) & 0xff));
- Write((byte_t)(us & 0xff));
+ Write((uint8_t)((us >> 8) & 0xff));
+ Write((uint8_t)(us & 0xff));
}
void FontOutputStream::WriteShort(int32_t s) {
@@ -88,16 +88,16 @@ void FontOutputStream::WriteShort(int32_t s) {
}
void FontOutputStream::WriteUInt24(int32_t ui) {
- Write((byte_t)(ui >> 16) & 0xff);
- Write((byte_t)(ui >> 8) & 0xff);
- Write((byte_t)ui & 0xff);
+ Write((uint8_t)(ui >> 16) & 0xff);
+ Write((uint8_t)(ui >> 8) & 0xff);
+ Write((uint8_t)ui & 0xff);
}
void FontOutputStream::WriteULong(int64_t ul) {
- Write((byte_t)((ul >> 24) & 0xff));
- Write((byte_t)((ul >> 16) & 0xff));
- Write((byte_t)((ul >> 8) & 0xff));
- Write((byte_t)(ul & 0xff));
+ 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) {
diff --git a/cpp/src/sfntly/data/font_output_stream.h b/cpp/src/sfntly/data/font_output_stream.h
index fcd48e8..fa4d346 100644
--- a/cpp/src/sfntly/data/font_output_stream.h
+++ b/cpp/src/sfntly/data/font_output_stream.h
@@ -48,13 +48,11 @@ class FontOutputStream : public OutputStream {
explicit FontOutputStream(OutputStream* os);
virtual ~FontOutputStream();
- virtual size_t position() { return position_; }
-
- virtual void Write(byte_t b);
- virtual void Write(ByteVector* b);
- virtual void Write(ByteVector* b, int32_t off, int32_t len);
- virtual void Write(byte_t* b, int32_t off, int32_t len);
- virtual void WriteChar(byte_t c);
+ virtual void 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);
diff --git a/cpp/src/sfntly/data/growable_memory_byte_array.cc b/cpp/src/sfntly/data/growable_memory_byte_array.cc
index c335614..b7b10fc 100644
--- a/cpp/src/sfntly/data/growable_memory_byte_array.cc
+++ b/cpp/src/sfntly/data/growable_memory_byte_array.cc
@@ -39,7 +39,7 @@ int32_t GrowableMemoryByteArray::CopyTo(OutputStream* os,
return length;
}
-void GrowableMemoryByteArray::InternalPut(int32_t index, byte_t b) {
+void GrowableMemoryByteArray::InternalPut(int32_t index, uint8_t b) {
if ((size_t)index >= b_.size()) {
b_.resize((size_t)(index + 1));
}
@@ -47,7 +47,7 @@ void GrowableMemoryByteArray::InternalPut(int32_t index, byte_t b) {
}
int32_t GrowableMemoryByteArray::InternalPut(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length) {
if ((size_t)index + length >= b_.size()) {
@@ -59,12 +59,12 @@ int32_t GrowableMemoryByteArray::InternalPut(int32_t index,
return length;
}
-byte_t GrowableMemoryByteArray::InternalGet(int32_t index) {
+uint8_t GrowableMemoryByteArray::InternalGet(int32_t index) {
return b_[index];
}
int32_t GrowableMemoryByteArray::InternalGet(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length) {
memcpy(b + offset, &(b_[0]) + index, length);
@@ -75,7 +75,7 @@ void GrowableMemoryByteArray::Close() {
b_.clear();
}
-byte_t* GrowableMemoryByteArray::Begin() {
+uint8_t* GrowableMemoryByteArray::Begin() {
return &(b_[0]);
}
diff --git a/cpp/src/sfntly/data/growable_memory_byte_array.h b/cpp/src/sfntly/data/growable_memory_byte_array.h
index 8583a0d..370d2cb 100644
--- a/cpp/src/sfntly/data/growable_memory_byte_array.h
+++ b/cpp/src/sfntly/data/growable_memory_byte_array.h
@@ -44,21 +44,21 @@ class GrowableMemoryByteArray : public ByteArray,
virtual int32_t CopyTo(OutputStream* os) { return ByteArray::CopyTo(os); }
protected:
- virtual void InternalPut(int32_t index, byte_t b);
+ virtual void InternalPut(int32_t index, uint8_t b);
virtual int32_t InternalPut(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length);
- virtual byte_t InternalGet(int32_t index);
+ virtual uint8_t InternalGet(int32_t index);
virtual int32_t InternalGet(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length);
virtual void Close();
- virtual byte_t* Begin();
+ virtual uint8_t* Begin();
private:
- ByteVector b_;
+ std::vector<uint8_t> b_;
};
} // namespace sfntly
diff --git a/cpp/src/sfntly/data/memory_byte_array.cc b/cpp/src/sfntly/data/memory_byte_array.cc
index d6c9c48..9a81cf6 100644
--- a/cpp/src/sfntly/data/memory_byte_array.cc
+++ b/cpp/src/sfntly/data/memory_byte_array.cc
@@ -24,7 +24,7 @@ MemoryByteArray::MemoryByteArray(int32_t length)
: ByteArray(0, length), b_(NULL), allocated_(true) {
}
-MemoryByteArray::MemoryByteArray(byte_t* b, int32_t filled_length)
+MemoryByteArray::MemoryByteArray(uint8_t* b, int32_t filled_length)
: ByteArray(filled_length, filled_length), b_(b), allocated_(false) {
assert(b);
}
@@ -43,18 +43,18 @@ int32_t MemoryByteArray::CopyTo(OutputStream* os,
void MemoryByteArray::Init() {
if (allocated_ && b_ == NULL) {
- b_ = new byte_t[Size()];
+ b_ = new uint8_t[Size()];
memset(b_, 0, Size());
}
}
-void MemoryByteArray::InternalPut(int32_t index, byte_t b) {
+void MemoryByteArray::InternalPut(int32_t index, uint8_t b) {
Init();
b_[index] = b;
}
int32_t MemoryByteArray::InternalPut(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length) {
assert(b);
@@ -63,13 +63,13 @@ int32_t MemoryByteArray::InternalPut(int32_t index,
return length;
}
-byte_t MemoryByteArray::InternalGet(int32_t index) {
+uint8_t MemoryByteArray::InternalGet(int32_t index) {
Init();
return b_[index];
}
int32_t MemoryByteArray::InternalGet(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length) {
assert(b);
@@ -85,7 +85,7 @@ void MemoryByteArray::Close() {
b_ = NULL;
}
-byte_t* MemoryByteArray::Begin() {
+uint8_t* MemoryByteArray::Begin() {
Init();
return b_;
}
diff --git a/cpp/src/sfntly/data/memory_byte_array.h b/cpp/src/sfntly/data/memory_byte_array.h
index 838fd1a..b84cc5a 100644
--- a/cpp/src/sfntly/data/memory_byte_array.h
+++ b/cpp/src/sfntly/data/memory_byte_array.h
@@ -28,7 +28,7 @@ class MemoryByteArray : public ByteArray, public RefCounted<MemoryByteArray> {
explicit MemoryByteArray(int32_t length);
// Note: not implemented due to dangerous operations in constructor.
- //explicit MemoryByteArray(ByteVector* b);
+ //explicit MemoryByteArray(std::vector<uint8_t>* b);
// Construct a new MemoryByteArray using byte array.
// @param b the byte array that provides the actual storage
@@ -37,7 +37,7 @@ class MemoryByteArray : public ByteArray, public RefCounted<MemoryByteArray> {
// ownership of b. Caller is responsible for handling the lifetime
// of b. C++ port also assumes filled_length is buffer_length since
// there is not a reliable way to identify the actual size of buffer.
- MemoryByteArray(byte_t* b, int32_t filled_length);
+ MemoryByteArray(uint8_t* b, int32_t filled_length);
virtual ~MemoryByteArray();
virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
@@ -56,23 +56,23 @@ class MemoryByteArray : public ByteArray, public RefCounted<MemoryByteArray> {
virtual int32_t CopyTo(OutputStream* os) { return ByteArray::CopyTo(os); }
protected:
- virtual void InternalPut(int32_t index, byte_t b);
+ virtual void InternalPut(int32_t index, uint8_t b);
virtual int32_t InternalPut(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length);
- virtual byte_t InternalGet(int32_t index);
+ virtual uint8_t InternalGet(int32_t index);
virtual int32_t InternalGet(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length);
virtual void Close();
- virtual byte_t* Begin();
+ virtual uint8_t* Begin();
private:
void Init(); // C++ port only, used to allocate memory outside constructor.
- byte_t* b_;
+ uint8_t* b_;
bool allocated_;
};
diff --git a/cpp/src/sfntly/data/readable_font_data.cc b/cpp/src/sfntly/data/readable_font_data.cc
index 07a0db6..b7c5332 100644
--- a/cpp/src/sfntly/data/readable_font_data.cc
+++ b/cpp/src/sfntly/data/readable_font_data.cc
@@ -38,7 +38,7 @@ ReadableFontData::~ReadableFontData() {}
// not too useful without copying, but it's not performance
// savvy to do copying.
CALLER_ATTACH
-ReadableFontData* ReadableFontData::CreateReadableFontData(ByteVector* b) {
+ReadableFontData* ReadableFontData::CreateReadableFontData(std::vector<uint8_t>* b) {
assert(b);
ByteArrayPtr ba = new MemoryByteArray(b->size());
ba->Put(0, b);
@@ -54,7 +54,7 @@ int64_t ReadableFontData::Checksum() {
return checksum_;
}
-void ReadableFontData::SetCheckSumRanges(const IntegerList& ranges) {
+void ReadableFontData::SetCheckSumRanges(const std::vector<int32_t>& ranges) {
checksum_range_ = ranges;
checksum_set_ = false; // UNIMPLEMENTED: atomicity
}
@@ -84,7 +84,7 @@ int32_t ReadableFontData::ReadByte(int32_t index) {
}
int32_t ReadableFontData::ReadBytes(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length) {
return array_->Get(BoundOffset(index), b, offset, BoundLength(index, length));
@@ -192,13 +192,13 @@ int32_t ReadableFontData::ReadFixed(int32_t index) {
}
int64_t ReadableFontData::ReadDateTimeAsLong(int32_t index) {
- int32_t high = ReadULong(index);
+ int64_t high = ReadULong(index);
if (high == kInvalidUnsigned)
return kInvalidLongDateTime;
- int32_t low = ReadULong(index + 4);
+ int64_t low = ReadULong(index + 4);
if (low == kInvalidUnsigned)
return kInvalidLongDateTime;
- return (int64_t)high << 32 | low;
+ return high << 32 | low;
}
int32_t ReadableFontData::ReadFWord(int32_t index) {
diff --git a/cpp/src/sfntly/data/readable_font_data.h b/cpp/src/sfntly/data/readable_font_data.h
index 37a0918..db5e70c 100644
--- a/cpp/src/sfntly/data/readable_font_data.h
+++ b/cpp/src/sfntly/data/readable_font_data.h
@@ -57,7 +57,7 @@ class ReadableFontData : public FontData,
static const int32_t kInvalidUnsigned = -1;
static const int64_t kInvalidLongDateTime = -1;
- static CALLER_ATTACH ReadableFontData* CreateReadableFontData(ByteVector* b);
+ 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
@@ -72,7 +72,7 @@ class ReadableFontData : public FontData,
// assumed to extend to the end of the data. The lengths of each range must be
// a multiple of 4.
// @param ranges the range bounds to use for the checksum
- void SetCheckSumRanges(const IntegerList& ranges);
+ void SetCheckSumRanges(const std::vector<int32_t>& ranges);
// Read the UBYTE at the given index.
// @param index index into the font data
@@ -94,7 +94,7 @@ class ReadableFontData : public FontData,
// @return the number of bytes actually read; -1 if the index is outside the
// bounds of the font data
virtual int32_t ReadBytes(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length);
@@ -306,7 +306,7 @@ class ReadableFontData : public FontData,
Lock checksum_lock_;
bool checksum_set_;
int64_t checksum_;
- IntegerList checksum_range_;
+ std::vector<int32_t> checksum_range_;
};
typedef Ptr<ReadableFontData> ReadableFontDataPtr;
diff --git a/cpp/src/sfntly/data/writable_font_data.cc b/cpp/src/sfntly/data/writable_font_data.cc
index 073e9df..40c778e 100644
--- a/cpp/src/sfntly/data/writable_font_data.cc
+++ b/cpp/src/sfntly/data/writable_font_data.cc
@@ -47,20 +47,20 @@ WritableFontData* WritableFontData::CreateWritableFontData(int32_t length) {
// not too useful without copying, but it's not performance
// savvy to do copying.
CALLER_ATTACH
-WritableFontData* WritableFontData::CreateWritableFontData(ByteVector* b) {
+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, byte_t b) {
+int32_t WritableFontData::WriteByte(int32_t index, uint8_t b) {
array_->Put(BoundOffset(index), b);
return 1;
}
int32_t WritableFontData::WriteBytes(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length) {
return array_->Put(BoundOffset(index),
@@ -69,16 +69,16 @@ int32_t WritableFontData::WriteBytes(int32_t index,
BoundLength(index, length));
}
-int32_t WritableFontData::WriteBytes(int32_t index, ByteVector* b) {
+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,
- ByteVector* b,
+ std::vector<uint8_t>* b,
int32_t offset,
int32_t length,
- byte_t pad) {
+ uint8_t pad) {
int32_t written =
array_->Put(BoundOffset(index),
&((*b)[0]),
@@ -90,30 +90,30 @@ int32_t WritableFontData::WriteBytesPad(int32_t index,
}
int32_t WritableFontData::WritePadding(int32_t index, int32_t count) {
- return WritePadding(index, count, (byte_t)0);
+ return WritePadding(index, count, (uint8_t)0);
}
int32_t WritableFontData::WritePadding(int32_t index, int32_t count,
- byte_t pad) {
+ 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, byte_t c) {
+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, (byte_t)((us >> 8) & 0xff));
- WriteByte(index + 1, (byte_t)(us & 0xff));
+ 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, (byte_t)(us & 0xff));
- WriteByte(index + 1, (byte_t)((us >> 8) & 0xff));
+ WriteByte(index, (uint8_t)(us & 0xff));
+ WriteByte(index + 1, (uint8_t)((us >> 8) & 0xff));
return 2;
}
@@ -122,25 +122,25 @@ int32_t WritableFontData::WriteShort(int32_t index, int32_t s) {
}
int32_t WritableFontData::WriteUInt24(int32_t index, int32_t ui) {
- WriteByte(index, (byte_t)((ui >> 16) & 0xff));
- WriteByte(index + 1, (byte_t)((ui >> 8) & 0xff));
- WriteByte(index + 2, (byte_t)(ui & 0xff));
+ 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, (byte_t)((ul >> 24) & 0xff));
- WriteByte(index + 1, (byte_t)((ul >> 16) & 0xff));
- WriteByte(index + 2, (byte_t)((ul >> 8) & 0xff));
- WriteByte(index + 3, (byte_t)(ul & 0xff));
+ 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, (byte_t)(ul & 0xff));
- WriteByte(index + 1, (byte_t)((ul >> 8) & 0xff));
- WriteByte(index + 2, (byte_t)((ul >> 16) & 0xff));
- WriteByte(index + 3, (byte_t)((ul >> 24) & 0xff));
+ 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;
}
diff --git a/cpp/src/sfntly/data/writable_font_data.h b/cpp/src/sfntly/data/writable_font_data.h
index d2a049e..61fc6a9 100644
--- a/cpp/src/sfntly/data/writable_font_data.h
+++ b/cpp/src/sfntly/data/writable_font_data.h
@@ -42,13 +42,13 @@ class WritableFontData : public ReadableFontData {
// bytes.
// @param b the byte vector to wrap
// @return a new writable font data
- static CALLER_ATTACH WritableFontData* CreateWritableFontData(ByteVector* b);
+ 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, byte_t b);
+ virtual int32_t WriteByte(int32_t index, uint8_t b);
// Write the bytes from the array.
// @param index index into the font data
@@ -58,7 +58,7 @@ class WritableFontData : public ReadableFontData {
// @return the number of bytes actually written; -1 if the index is outside
// the FontData's range
virtual int32_t WriteBytes(int32_t index,
- byte_t* b,
+ uint8_t* b,
int32_t offset,
int32_t length);
@@ -67,7 +67,7 @@ class WritableFontData : public ReadableFontData {
// @param b the source for the bytes to be written
// @return the number of bytes actually written; -1 if the index is outside
// the FontData's range
- virtual int32_t WriteBytes(int32_t index, ByteVector* b);
+ 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
@@ -80,10 +80,10 @@ class WritableFontData : public ReadableFontData {
// @param pad the padding byte to be used if necessary
// @return the number of bytes actually written
virtual int32_t WriteBytesPad(int32_t index,
- ByteVector* b,
+ std::vector<uint8_t>* b,
int32_t offset,
int32_t length,
- byte_t pad);
+ uint8_t pad);
// Writes padding to the FontData. The padding byte written is 0x00.
// @param index index into the font data
@@ -96,14 +96,14 @@ class WritableFontData : public ReadableFontData {
// @param count the number of pad bytes to write
// @param pad the byte value to use as padding
// @return the number of pad bytes written
- virtual int32_t WritePadding(int32_t index, int32_t count, byte_t pad);
+ 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, byte_t c);
+ virtual int32_t WriteChar(int32_t index, uint8_t c);
// Write the USHORT at the given index.
// @param index index into the font data
diff --git a/cpp/src/sfntly/font.cc b/cpp/src/sfntly/font.cc
index ca35048..eec7bec 100644
--- a/cpp/src/sfntly/font.cc
+++ b/cpp/src/sfntly/font.cc
@@ -18,12 +18,13 @@
#include <stdio.h>
-#include <functional>
#include <algorithm>
+#include <functional>
+#include <iterator>
+#include <limits>
#include <map>
#include <string>
#include <typeinfo>
-#include <iterator>
#include "sfntly/data/font_input_stream.h"
#include "sfntly/font_factory.h"
@@ -47,6 +48,12 @@ 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
/******************************************************************************
@@ -68,9 +75,9 @@ const TableMap* Font::GetTableMap() {
return &tables_;
}
-void Font::Serialize(OutputStream* os, IntegerList* table_ordering) {
+void Font::Serialize(OutputStream* os, std::vector<int32_t>* table_ordering) {
assert(table_ordering);
- IntegerList final_table_ordering;
+ std::vector<int32_t> final_table_ordering;
GenerateTableOrdering(table_ordering, &final_table_ordering);
TableHeaderList table_records;
BuildTableHeadersForSerialization(&final_table_ordering, &table_records);
@@ -80,36 +87,32 @@ void Font::Serialize(OutputStream* os, IntegerList* table_ordering) {
SerializeTables(&fos, &table_records);
}
-Font::Font(int32_t sfnt_version, ByteVector* digest)
+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(IntegerList* table_ordering,
+void Font::BuildTableHeadersForSerialization(std::vector<int32_t>* table_ordering,
TableHeaderList* table_headers) {
assert(table_headers);
assert(table_ordering);
- IntegerList final_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 (IntegerList::iterator tag = final_table_ordering.begin(),
- tag_end = final_table_ordering.end();
- tag != tag_end; ++tag) {
- if (tables_.find(*tag) == tables_.end()) {
+ 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;
- }
- TablePtr table = tables_[*tag];
- if (table != NULL) {
- HeaderPtr header =
- new Header(*tag, table->CalculatedChecksum(), table_offset,
- table->header()->length());
- table_headers->push_back(header);
- table_offset += (table->DataLength() + 3) & ~3;
- }
+
+ HeaderPtr header = new Header(tag, table->CalculatedChecksum(),
+ table_offset, table->header()->length());
+ table_headers->push_back(header);
+ table_offset += (table->DataLength() + 3) & ~3;
}
}
@@ -142,10 +145,9 @@ void Font::SerializeTables(FontOutputStream* fos,
TableHeaderList* table_headers) {
assert(fos);
assert(table_headers);
- for (TableHeaderList::iterator record = table_headers->begin(),
- end_of_headers = table_headers->end();
- record != end_of_headers; ++record) {
- TablePtr target_table = GetTable((*record)->tag());
+ 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.");
@@ -153,18 +155,17 @@ void Font::SerializeTables(FontOutputStream* fos,
return;
}
int32_t table_size = target_table->Serialize(fos);
- if (table_size != (*record)->length()) {
- assert(false);
- }
+ 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<byte_t>(0));
+ fos->Write(static_cast<uint8_t>(0));
}
}
}
-void Font::GenerateTableOrdering(IntegerList* default_table_ordering,
- IntegerList* table_ordering) {
+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();
@@ -179,7 +180,7 @@ void Font::GenerateTableOrdering(IntegerList* default_table_ordering,
table != table_end; ++table) {
tables_in_font.insert(Int2BoolEntry(table->first, false));
}
- for (IntegerList::iterator tag = default_table_ordering->begin(),
+ for (std::vector<int32_t>::iterator tag = default_table_ordering->begin(),
tag_end = default_table_ordering->end();
tag != tag_end; ++tag) {
if (HasTable(*tag)) {
@@ -195,7 +196,7 @@ void Font::GenerateTableOrdering(IntegerList* default_table_ordering,
}
}
-void Font::DefaultTableOrdering(IntegerList* default_table_ordering) {
+void Font::DefaultTableOrdering(std::vector<int32_t>* default_table_ordering) {
assert(default_table_ordering);
default_table_ordering->clear();
if (HasTable(Tag::CFF)) {
@@ -268,7 +269,7 @@ CALLER_ATTACH Font* Font::Builder::Build() {
return font.Detach();
}
-void Font::Builder::SetDigest(ByteVector* digest) {
+void Font::Builder::SetDigest(std::vector<uint8_t>* digest) {
digest_.clear();
digest_ = *digest;
}
@@ -440,7 +441,7 @@ void Font::Builder::InterRelateBuilders(TableBuilderMap* builder_map) {
loca_table_builder = down_cast<LocaTable::Builder*>(raw_loca_builder);
}
- Table::Builder* raw_hmtx_builder = GetBuilder(builder_map, Tag::hmtx);
+ Table::Builder* raw_hmtx_builder = GetReadBuilder(builder_map, Tag::hmtx);
HorizontalMetricsTableBuilderPtr horizontal_metrics_builder;
if (raw_hmtx_builder != NULL) {
horizontal_metrics_builder =
@@ -459,18 +460,22 @@ void Font::Builder::InterRelateBuilders(TableBuilderMap* builder_map) {
// set the inter table data required to build certain tables
if (horizontal_metrics_builder != NULL) {
if (max_profile_builder != NULL) {
- horizontal_metrics_builder->SetNumGlyphs(
- max_profile_builder->NumGlyphs());
+ int32_t num_glyphs = max_profile_builder->NumGlyphs();
+ if (num_glyphs >= 0)
+ horizontal_metrics_builder->SetNumGlyphs(num_glyphs);
}
if (horizontal_header_builder != NULL) {
- horizontal_metrics_builder->SetNumberOfHMetrics(
- horizontal_header_builder->NumberOfHMetrics());
+ 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) {
- loca_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs());
+ 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(
@@ -502,6 +507,9 @@ void Font::Builder::ReadHeader(FontInputStream* is,
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);
}
@@ -517,6 +525,9 @@ void Font::Builder::ReadHeader(ReadableFontData* fd,
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_;
@@ -525,6 +536,9 @@ void Font::Builder::ReadHeader(ReadableFontData* fd,
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);
}
diff --git a/cpp/src/sfntly/font.h b/cpp/src/sfntly/font.h
index 2220adb..3187c11 100644
--- a/cpp/src/sfntly/font.h
+++ b/cpp/src/sfntly/font.h
@@ -149,7 +149,7 @@ class Font : public RefCounted<Font> {
CALLER_ATTACH Font* Build();
// Set a unique fingerprint for the font object.
- void SetDigest(ByteVector* digest);
+ void SetDigest(std::vector<uint8_t>* digest);
// Clear all table builders.
void ClearTableBuilders();
@@ -226,7 +226,7 @@ class Font : public RefCounted<Font> {
int32_t entry_selector_;
int32_t range_shift_;
DataBlockMap data_blocks_;
- ByteVector digest_;
+ std::vector<uint8_t> digest_;
};
virtual ~Font();
@@ -236,7 +236,7 @@ class Font : public RefCounted<Font> {
// Gets a copy of the fonts digest that was created when the font was read. If
// no digest was set at creation time then the return result will be null.
- ByteVector* digest() { return &digest_; }
+ std::vector<uint8_t>* digest() { return &digest_; }
// Get the checksum for this font.
int64_t checksum() { return checksum_; }
@@ -265,7 +265,7 @@ class Font : public RefCounted<Font> {
// Serialize the font to the output stream.
// @param os the destination for the font serialization
// @param tableOrdering the table ordering to apply
- void Serialize(OutputStream* os, IntegerList* table_ordering);
+ void Serialize(OutputStream* os, std::vector<int32_t>* table_ordering);
private:
// Offsets to specific elements in the underlying data. These offsets are
@@ -300,7 +300,7 @@ class Font : public RefCounted<Font> {
// @param digest the computed digest for the font; null if digest was not
// computed
// Note: Current C++ port does not support SHA digest validation.
- Font(int32_t sfnt_version, ByteVector* digest);
+ 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
@@ -309,7 +309,7 @@ class Font : public RefCounted<Font> {
// @param tableOrdering the tables to generate headers for and the order to
// sort them
// @return a list of table headers ready for serialization
- void BuildTableHeadersForSerialization(IntegerList* table_ordering,
+ void BuildTableHeadersForSerialization(std::vector<int32_t>* table_ordering,
TableHeaderList* table_headers);
// Searialize the headers.
@@ -330,15 +330,15 @@ class Font : public RefCounted<Font> {
// @param defaultTableOrdering the partial ordering to be used as a seed for
// the full ordering
// @param (out) table_ordering the full ordering for serialization
- void GenerateTableOrdering(IntegerList* default_table_ordering,
- IntegerList* table_ordering);
+ 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(IntegerList* default_table_ordering);
+ void DefaultTableOrdering(std::vector<int32_t>* default_table_ordering);
int32_t sfnt_version_;
- ByteVector digest_;
+ std::vector<uint8_t> digest_;
int64_t checksum_;
TableMap tables_;
};
diff --git a/cpp/src/sfntly/font_factory.cc b/cpp/src/sfntly/font_factory.cc
index c162a77..bb1986f 100644
--- a/cpp/src/sfntly/font_factory.cc
+++ b/cpp/src/sfntly/font_factory.cc
@@ -52,7 +52,7 @@ void FontFactory::LoadFonts(InputStream* is, FontArray* output) {
}
}
-void FontFactory::LoadFonts(ByteVector* b, FontArray* output) {
+void FontFactory::LoadFonts(std::vector<uint8_t>* b, FontArray* output) {
WritableFontDataPtr wfd;
wfd.Attach(WritableFontData::CreateWritableFontData(b));
if (IsCollection(wfd)) {
@@ -80,7 +80,7 @@ void FontFactory::LoadFontsForBuilding(InputStream* is,
}
}
-void FontFactory::LoadFontsForBuilding(ByteVector* b,
+void FontFactory::LoadFontsForBuilding(std::vector<uint8_t>* b,
FontBuilderArray* output) {
WritableFontDataPtr wfd;
wfd.Attach(WritableFontData::CreateWritableFontData(b));
@@ -96,12 +96,8 @@ void FontFactory::LoadFontsForBuilding(ByteVector* b,
}
void FontFactory::SerializeFont(Font* font, OutputStream* os) {
- font->Serialize(os, &table_ordering_);
-}
-
-void FontFactory::SetSerializationTableOrdering(
- const IntegerList& table_ordering) {
- table_ordering_ = table_ordering;
+ std::vector<int32_t> table_ordering;
+ font->Serialize(os, &table_ordering);
}
CALLER_ATTACH Font::Builder* FontFactory::NewFontBuilder() {
@@ -180,6 +176,10 @@ void FontFactory::LoadCollectionForBuilding(WritableFontData* wfd,
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;
@@ -187,6 +187,9 @@ void FontFactory::LoadCollectionForBuilding(WritableFontData* wfd,
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);
@@ -194,14 +197,14 @@ void FontFactory::LoadCollectionForBuilding(WritableFontData* wfd,
}
bool FontFactory::IsCollection(PushbackInputStream* pbis) {
- ByteVector tag(4);
+ 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) {
- ByteVector tag(4);
+ 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]);
diff --git a/cpp/src/sfntly/font_factory.h b/cpp/src/sfntly/font_factory.h
index 63deff4..12e54a5 100644
--- a/cpp/src/sfntly/font_factory.h
+++ b/cpp/src/sfntly/font_factory.h
@@ -56,7 +56,7 @@ class FontFactory : public RefCounted<FontFactory> {
// than one font and in this case multiple font objects will be returned. If
// the data in the stream cannot be parsed or is invalid an array of size zero
// will be returned.
- void LoadFonts(ByteVector* b, FontArray* output);
+ 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
@@ -72,7 +72,7 @@ class FontFactory : public RefCounted<FontFactory> {
// font container formats may have more than one font and in this case
// multiple font builder objects will be returned. If the data in the stream
// cannot be parsed or is invalid an array of size zero will be returned.
- void LoadFontsForBuilding(ByteVector* b, FontBuilderArray* output);
+ void LoadFontsForBuilding(std::vector<uint8_t>* b, FontBuilderArray* output);
// Font serialization
// Serialize the font to the output stream.
@@ -81,12 +81,6 @@ class FontFactory : public RefCounted<FontFactory> {
// Byte buffer it is.
void SerializeFont(Font* font, OutputStream* os);
- // Set the table ordering to be used in serializing a font. The table ordering
- // is an ordered list of table ids and tables will be serialized in the order
- // given. Any tables whose id is not listed in the ordering will be placed in
- // an unspecified order following those listed.
- void SetSerializationTableOrdering(const IntegerList& table_ordering);
-
// Get an empty font builder for creating a new font from scratch.
CALLER_ATTACH Font::Builder* NewFontBuilder();
@@ -131,7 +125,6 @@ class FontFactory : public RefCounted<FontFactory> {
static bool IsCollection(ReadableFontData* wfd);
bool fingerprint_;
- IntegerList table_ordering_;
};
typedef Ptr<FontFactory> FontFactoryPtr;
diff --git a/cpp/src/sfntly/port/file_input_stream.cc b/cpp/src/sfntly/port/file_input_stream.cc
index dfe9a7b..12c1e12 100644
--- a/cpp/src/sfntly/port/file_input_stream.cc
+++ b/cpp/src/sfntly/port/file_input_stream.cc
@@ -35,6 +35,10 @@ FileInputStream::~FileInputStream() {
Close();
}
+int32_t FileInputStream::Length() {
+ return length_;
+}
+
int32_t FileInputStream::Available() {
return length_ - position_;
}
@@ -70,17 +74,17 @@ int32_t FileInputStream::Read() {
#endif
return 0;
}
- byte_t value;
+ uint8_t value;
size_t length = fread(&value, 1, 1, file_);
position_ += length;
return value;
}
-int32_t FileInputStream::Read(ByteVector* b) {
+int32_t FileInputStream::Read(std::vector<uint8_t>* b) {
return Read(b, 0, b->size());
}
-int32_t FileInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
+int32_t FileInputStream::Read(std::vector<uint8_t>* b, int32_t offset, int32_t length) {
assert(b);
if (!file_) {
#if !defined (SFNTLY_NO_EXCEPTION)
@@ -127,11 +131,11 @@ int64_t FileInputStream::Skip(int64_t n) {
return skip_count;
}
-void FileInputStream::Unread(ByteVector* b) {
+void FileInputStream::Unread(std::vector<uint8_t>* b) {
Unread(b, 0, b->size());
}
-void FileInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) {
+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_) {
diff --git a/cpp/src/sfntly/port/file_input_stream.h b/cpp/src/sfntly/port/file_input_stream.h
index cbca25f..1128444 100644
--- a/cpp/src/sfntly/port/file_input_stream.h
+++ b/cpp/src/sfntly/port/file_input_stream.h
@@ -29,19 +29,20 @@ class FileInputStream : public PushbackInputStream {
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(ByteVector* b);
- virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length);
+ 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(ByteVector* b);
- virtual void Unread(ByteVector* b, int32_t offset, int32_t length);
+ 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);
diff --git a/cpp/src/sfntly/port/input_stream.h b/cpp/src/sfntly/port/input_stream.h
index 5d24036..a403c11 100644
--- a/cpp/src/sfntly/port/input_stream.h
+++ b/cpp/src/sfntly/port/input_stream.h
@@ -24,24 +24,25 @@ namespace sfntly {
// C++ equivalent to Java's OutputStream class
class InputStream {
public:
- // Make gcc -Wnon-virtual-dtor happy.
- virtual ~InputStream() {}
-
+ 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(ByteVector* b) = 0;
- virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length) = 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(ByteVector* b) = 0;
- virtual void Unread(ByteVector* b, int32_t offset, int32_t length) = 0;
+ 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
diff --git a/cpp/src/sfntly/port/memory_input_stream.cc b/cpp/src/sfntly/port/memory_input_stream.cc
index f6f2b9b..73f03f5 100755
--- a/cpp/src/sfntly/port/memory_input_stream.cc
+++ b/cpp/src/sfntly/port/memory_input_stream.cc
@@ -37,6 +37,10 @@ MemoryInputStream::~MemoryInputStream() {
Close();
}
+int32_t MemoryInputStream::Length() {
+ return length_;
+}
+
int32_t MemoryInputStream::Available() {
return length_ - position_;
}
@@ -66,15 +70,15 @@ int32_t MemoryInputStream::Read() {
#endif
return 0;
}
- byte_t value = buffer_[position_++];
+ uint8_t value = buffer_[position_++];
return value;
}
-int32_t MemoryInputStream::Read(ByteVector* b) {
+int32_t MemoryInputStream::Read(std::vector<uint8_t>* b) {
return Read(b, 0, b->size());
}
-int32_t MemoryInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
+int32_t MemoryInputStream::Read(std::vector<uint8_t>* b, int32_t offset, int32_t length) {
assert(b);
if (!buffer_) {
#if !defined (SFNTLY_NO_EXCEPTION)
@@ -119,11 +123,11 @@ int64_t MemoryInputStream::Skip(int64_t n) {
return skip_count;
}
-void MemoryInputStream::Unread(ByteVector* b) {
+void MemoryInputStream::Unread(std::vector<uint8_t>* b) {
Unread(b, 0, b->size());
}
-void MemoryInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) {
+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_) {
@@ -138,7 +142,7 @@ void MemoryInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) {
position_ -= unread_count;
}
-bool MemoryInputStream::Attach(const byte_t* buffer, size_t length) {
+bool MemoryInputStream::Attach(const uint8_t* buffer, size_t length) {
assert(buffer);
assert(length);
buffer_ = buffer;
diff --git a/cpp/src/sfntly/port/memory_input_stream.h b/cpp/src/sfntly/port/memory_input_stream.h
index bc861c3..2478893 100755
--- a/cpp/src/sfntly/port/memory_input_stream.h
+++ b/cpp/src/sfntly/port/memory_input_stream.h
@@ -29,25 +29,26 @@ class MemoryInputStream : public PushbackInputStream {
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(ByteVector* b);
- virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length);
+ 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(ByteVector* b);
- virtual void Unread(ByteVector* b, int32_t offset, int32_t length);
+ 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 byte_t* buffer, size_t length);
+ virtual bool Attach(const uint8_t* buffer, size_t length);
private:
- const byte_t* buffer_;
+ const uint8_t* buffer_;
size_t position_;
size_t length_;
};
diff --git a/cpp/src/sfntly/port/memory_output_stream.cc b/cpp/src/sfntly/port/memory_output_stream.cc
index f2ff2e3..f071c97 100644
--- a/cpp/src/sfntly/port/memory_output_stream.cc
+++ b/cpp/src/sfntly/port/memory_output_stream.cc
@@ -24,11 +24,11 @@ MemoryOutputStream::MemoryOutputStream() {
MemoryOutputStream::~MemoryOutputStream() {
}
-void MemoryOutputStream::Write(ByteVector* buffer) {
+void MemoryOutputStream::Write(std::vector<uint8_t>* buffer) {
store_.insert(store_.end(), buffer->begin(), buffer->end());
}
-void MemoryOutputStream::Write(ByteVector* buffer,
+void MemoryOutputStream::Write(std::vector<uint8_t>* buffer,
int32_t offset,
int32_t length) {
assert(buffer);
@@ -43,7 +43,7 @@ void MemoryOutputStream::Write(ByteVector* buffer,
}
}
-void MemoryOutputStream::Write(byte_t* buffer, int32_t offset, int32_t length) {
+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);
@@ -54,11 +54,11 @@ void MemoryOutputStream::Write(byte_t* buffer, int32_t offset, int32_t length) {
}
}
-void MemoryOutputStream::Write(byte_t b) {
+void MemoryOutputStream::Write(uint8_t b) {
store_.push_back(b);
}
-byte_t* MemoryOutputStream::Get() {
+uint8_t* MemoryOutputStream::Get() {
if (store_.empty()) {
return NULL;
}
diff --git a/cpp/src/sfntly/port/memory_output_stream.h b/cpp/src/sfntly/port/memory_output_stream.h
index d1eda7f..586c9d9 100644
--- a/cpp/src/sfntly/port/memory_output_stream.h
+++ b/cpp/src/sfntly/port/memory_output_stream.h
@@ -34,16 +34,16 @@ class MemoryOutputStream : public OutputStream {
virtual void Close() {} // no-op
virtual void Flush() {} // no-op
- virtual void Write(ByteVector* buffer);
- virtual void Write(ByteVector* buffer, int32_t offset, int32_t length);
- virtual void Write(byte_t* buffer, int32_t offset, int32_t length);
- virtual void Write(byte_t b);
+ 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);
- byte_t* Get();
+ uint8_t* Get();
size_t Size();
private:
- std::vector<byte_t> store_;
+ std::vector<uint8_t> store_;
};
} // namespace sfntly
diff --git a/cpp/src/sfntly/port/output_stream.h b/cpp/src/sfntly/port/output_stream.h
index 64a6024..8dd2e5c 100644
--- a/cpp/src/sfntly/port/output_stream.h
+++ b/cpp/src/sfntly/port/output_stream.h
@@ -29,16 +29,16 @@ class OutputStream {
virtual void Close() = 0;
virtual void Flush() = 0;
- virtual void Write(ByteVector* buffer) = 0;
- virtual void Write(byte_t b) = 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(ByteVector* buffer, int32_t offset, int32_t length) = 0;
+ 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(byte_t* buffer, int32_t offset, int32_t length) = 0;
+ virtual void Write(uint8_t* buffer, int32_t offset, int32_t length) = 0;
};
} // namespace sfntly
diff --git a/cpp/src/sfntly/port/refcount.h b/cpp/src/sfntly/port/refcount.h
index 6353b08..d083c73 100644
--- a/cpp/src/sfntly/port/refcount.h
+++ b/cpp/src/sfntly/port/refcount.h
@@ -97,6 +97,8 @@
#pragma warning(disable:4250)
#endif
+bool TestSmartPointer();
+
namespace sfntly {
template <typename T>
@@ -157,6 +159,7 @@ class RefCounted : virtual public RefCount {
}
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_;
diff --git a/cpp/src/sfntly/port/type.h b/cpp/src/sfntly/port/type.h
index 9f82a5a..cb8c1ea 100644
--- a/cpp/src/sfntly/port/type.h
+++ b/cpp/src/sfntly/port/type.h
@@ -17,42 +17,21 @@
#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_TYPE_H_
#define SFNTLY_CPP_SRC_SFNTLY_PORT_TYPE_H_
-#include <assert.h>
+#include <stdint.h>
-#if defined (_MSC_VER) && (_MSC_VER < 1600)
- typedef unsigned char uint8_t;
- typedef signed char int8_t;
- typedef unsigned __int16 uint16_t;
- typedef signed __int16 int16_t;
- typedef unsigned __int32 uint32_t;
- typedef signed __int32 int32_t;
- typedef unsigned __int64 uint64_t;
- typedef signed __int64 int64_t;
- // Definitions to avoid ICU redefinition issue
- #define U_HAVE_INT8_T 1
- #define U_HAVE_UINT8_T 1
- #define U_HAVE_INT16_T 1
- #define U_HAVE_UINT16_T 1
- #define U_HAVE_INT32_T 1
- #define U_HAVE_UINT32_T 1
- #define U_HAVE_INT64_T 1
- #define U_HAVE_UINT64_T 1
-#else
- #include <stdint.h>
-#endif
-
-#include <stddef.h>
-#include <vector>
+#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<byte_t> ByteVector;
+typedef std::vector<uint8_t> ByteVector;
typedef std::vector<int32_t> IntegerList;
typedef std::set<int32_t> IntegerSet;
diff --git a/cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc b/cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc
index d853212..041366f 100644
--- a/cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc
+++ b/cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc
@@ -77,7 +77,7 @@ int32_t BigGlyphMetrics::Builder::Height() {
return InternalReadData()->ReadByte(Offset::kHeight);
}
-void BigGlyphMetrics::Builder::SetHeight(byte_t height) {
+void BigGlyphMetrics::Builder::SetHeight(uint8_t height) {
InternalWriteData()->WriteByte(Offset::kHeight, height);
}
@@ -85,7 +85,7 @@ int32_t BigGlyphMetrics::Builder::Width() {
return InternalReadData()->ReadByte(Offset::kWidth);
}
-void BigGlyphMetrics::Builder::SetWidth(byte_t width) {
+void BigGlyphMetrics::Builder::SetWidth(uint8_t width) {
InternalWriteData()->WriteByte(Offset::kWidth, width);
}
@@ -93,7 +93,7 @@ int32_t BigGlyphMetrics::Builder::HoriBearingX() {
return InternalReadData()->ReadByte(Offset::kHoriBearingX);
}
-void BigGlyphMetrics::Builder::SetHoriBearingX(byte_t bearing) {
+void BigGlyphMetrics::Builder::SetHoriBearingX(uint8_t bearing) {
InternalWriteData()->WriteByte(Offset::kHoriBearingX, bearing);
}
@@ -101,7 +101,7 @@ int32_t BigGlyphMetrics::Builder::HoriBearingY() {
return InternalReadData()->ReadByte(Offset::kHoriBearingY);
}
-void BigGlyphMetrics::Builder::SetHoriBearingY(byte_t bearing) {
+void BigGlyphMetrics::Builder::SetHoriBearingY(uint8_t bearing) {
InternalWriteData()->WriteByte(Offset::kHoriBearingY, bearing);
}
@@ -109,7 +109,7 @@ int32_t BigGlyphMetrics::Builder::HoriAdvance() {
return InternalReadData()->ReadByte(Offset::kHoriAdvance);
}
-void BigGlyphMetrics::Builder::SetHoriAdvance(byte_t advance) {
+void BigGlyphMetrics::Builder::SetHoriAdvance(uint8_t advance) {
InternalWriteData()->WriteByte(Offset::kHoriAdvance, advance);
}
@@ -117,7 +117,7 @@ int32_t BigGlyphMetrics::Builder::VertBearingX() {
return InternalReadData()->ReadByte(Offset::kVertBearingX);
}
-void BigGlyphMetrics::Builder::SetVertBearingX(byte_t bearing) {
+void BigGlyphMetrics::Builder::SetVertBearingX(uint8_t bearing) {
InternalWriteData()->WriteByte(Offset::kVertBearingX, bearing);
}
@@ -125,7 +125,7 @@ int32_t BigGlyphMetrics::Builder::VertBearingY() {
return InternalReadData()->ReadByte(Offset::kVertBearingY);
}
-void BigGlyphMetrics::Builder::SetVertBearingY(byte_t bearing) {
+void BigGlyphMetrics::Builder::SetVertBearingY(uint8_t bearing) {
InternalWriteData()->WriteByte(Offset::kVertBearingY, bearing);
}
@@ -133,7 +133,7 @@ int32_t BigGlyphMetrics::Builder::VertAdvance() {
return InternalReadData()->ReadByte(Offset::kVertAdvance);
}
-void BigGlyphMetrics::Builder::SetVertAdvance(byte_t advance) {
+void BigGlyphMetrics::Builder::SetVertAdvance(uint8_t advance) {
InternalWriteData()->WriteByte(Offset::kVertAdvance, advance);
}
diff --git a/cpp/src/sfntly/table/bitmap/big_glyph_metrics.h b/cpp/src/sfntly/table/bitmap/big_glyph_metrics.h
index a91601c..84783c2 100644
--- a/cpp/src/sfntly/table/bitmap/big_glyph_metrics.h
+++ b/cpp/src/sfntly/table/bitmap/big_glyph_metrics.h
@@ -50,21 +50,21 @@ class BigGlyphMetrics : public GlyphMetrics,
virtual ~Builder();
int32_t Height();
- void SetHeight(byte_t height);
+ void SetHeight(uint8_t height);
int32_t Width();
- void SetWidth(byte_t width);
+ void SetWidth(uint8_t width);
int32_t HoriBearingX();
- void SetHoriBearingX(byte_t bearing);
+ void SetHoriBearingX(uint8_t bearing);
int32_t HoriBearingY();
- void SetHoriBearingY(byte_t bearing);
+ void SetHoriBearingY(uint8_t bearing);
int32_t HoriAdvance();
- void SetHoriAdvance(byte_t advance);
+ void SetHoriAdvance(uint8_t advance);
int32_t VertBearingX();
- void SetVertBearingX(byte_t bearing);
+ void SetVertBearingX(uint8_t bearing);
int32_t VertBearingY();
- void SetVertBearingY(byte_t bearing);
+ void SetVertBearingY(uint8_t bearing);
int32_t VertAdvance();
- void SetVertAdvance(byte_t advance);
+ void SetVertAdvance(uint8_t advance);
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
diff --git a/cpp/src/sfntly/table/bitmap/eblc_table.cc b/cpp/src/sfntly/table/bitmap/eblc_table.cc
index 0ad2764..d0700d9 100644
--- a/cpp/src/sfntly/table/bitmap/eblc_table.cc
+++ b/cpp/src/sfntly/table/bitmap/eblc_table.cc
@@ -294,19 +294,23 @@ BitmapSizeTableBuilderList* EblcTable::Builder::GetSizeList() {
void EblcTable::Builder::Initialize(ReadableFontData* data,
BitmapSizeTableBuilderList* output) {
assert(output);
- if (data) {
- int32_t num_sizes = data->ReadULongAsInt(Offset::kNumSizes);
- for (int32_t i = 0; i < num_sizes; ++i) {
- ReadableFontDataPtr new_data;
- new_data.Attach(down_cast<ReadableFontData*>(
- data->Slice(Offset::kBitmapSizeTableArrayStart +
- i * Offset::kBitmapSizeTableLength,
- Offset::kBitmapSizeTableLength)));
- BitmapSizeTableBuilderPtr size_builder;
- size_builder.Attach(BitmapSizeTable::Builder::CreateBuilder(
- new_data, data));
- output->push_back(size_builder);
- }
+ 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);
}
}
diff --git a/cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc b/cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc
index 5199e18..42d21ab 100644
--- a/cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc
+++ b/cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc
@@ -82,7 +82,7 @@ int32_t IndexSubTableFormat1::Builder::GlyphLength(int32_t glyph_id) {
if (loca == -1) {
return 0;
}
- IntegerList* offset_array = GetOffsetArray();
+ std::vector<int32_t>* offset_array = GetOffsetArray();
return offset_array->at(loca + 1) - offset_array->at(loca);
}
@@ -193,7 +193,7 @@ int32_t IndexSubTableFormat1::Builder::SubSerialize(
EblcTable::Offset::kIndexSubTable1_offsetArray)));
size += source->CopyTo(target);
} else {
- for (IntegerList::iterator b = GetOffsetArray()->begin(),
+ for (std::vector<int32_t>::iterator b = GetOffsetArray()->begin(),
e = GetOffsetArray()->end(); b != e; b++) {
size += new_data->WriteLong(size, *b);
}
@@ -201,12 +201,12 @@ int32_t IndexSubTableFormat1::Builder::SubSerialize(
return size;
}
-IntegerList* IndexSubTableFormat1::Builder::OffsetArray() {
+std::vector<int32_t>* IndexSubTableFormat1::Builder::OffsetArray() {
return GetOffsetArray();
}
void IndexSubTableFormat1::Builder::SetOffsetArray(
- const IntegerList& offset_array) {
+ const std::vector<int32_t>& offset_array) {
offset_array_.clear();
offset_array_ = offset_array;
set_model_changed();
@@ -234,7 +234,7 @@ IndexSubTableFormat1::Builder::Builder(ReadableFontData* data,
: IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
}
-IntegerList* IndexSubTableFormat1::Builder::GetOffsetArray() {
+std::vector<int32_t>* IndexSubTableFormat1::Builder::GetOffsetArray() {
if (offset_array_.empty()) {
Initialize(InternalReadData());
set_model_changed();
diff --git a/cpp/src/sfntly/table/bitmap/index_sub_table_format1.h b/cpp/src/sfntly/table/bitmap/index_sub_table_format1.h
index 33171c1..58a6ce7 100644
--- a/cpp/src/sfntly/table/bitmap/index_sub_table_format1.h
+++ b/cpp/src/sfntly/table/bitmap/index_sub_table_format1.h
@@ -53,8 +53,8 @@ class IndexSubTableFormat1 : public IndexSubTable,
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
- IntegerList* OffsetArray();
- void SetOffsetArray(const IntegerList& offset_array);
+ std::vector<int32_t>* OffsetArray();
+ void SetOffsetArray(const std::vector<int32_t>& offset_array);
CALLER_ATTACH BitmapGlyphInfoIter* Iterator();
static CALLER_ATTACH Builder* CreateBuilder();
@@ -78,7 +78,7 @@ class IndexSubTableFormat1 : public IndexSubTable,
Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
- IntegerList* GetOffsetArray();
+ std::vector<int32_t>* GetOffsetArray();
void Initialize(ReadableFontData* data);
static int32_t DataLength(ReadableFontData* data,
@@ -86,7 +86,7 @@ class IndexSubTableFormat1 : public IndexSubTable,
int32_t first_glyph_index,
int32_t last_glyph_index);
- IntegerList offset_array_;
+ std::vector<int32_t> offset_array_;
};
virtual ~IndexSubTableFormat1();
diff --git a/cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc b/cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc
index e2679b7..abd5517 100644
--- a/cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc
+++ b/cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc
@@ -91,7 +91,7 @@ int32_t IndexSubTableFormat3::Builder::GlyphLength(int32_t glyph_id) {
if (loca == -1) {
return 0;
}
- IntegerList* offset_array = GetOffsetArray();
+ std::vector<int32_t>* offset_array = GetOffsetArray();
return offset_array->at(loca + 1) - offset_array->at(loca);
}
@@ -108,7 +108,7 @@ void IndexSubTableFormat3::Builder::Revert() {
}
void IndexSubTableFormat3::Builder::SetOffsetArray(
- const IntegerList& offset_array) {
+ const std::vector<int32_t>& offset_array) {
offset_array_.clear();
offset_array_ = offset_array;
set_model_changed();
@@ -205,7 +205,7 @@ int32_t IndexSubTableFormat3::Builder::SubSerialize(
EblcTable::Offset::kIndexSubTable3_offsetArray)));
size += source->CopyTo(target);
} else {
- for (IntegerList::iterator b = GetOffsetArray()->begin(),
+ for (std::vector<int32_t>::iterator b = GetOffsetArray()->begin(),
e = GetOffsetArray()->end(); b != e; b++) {
size += new_data->WriteUShort(size, *b);
}
@@ -230,7 +230,7 @@ IndexSubTableFormat3::Builder::Builder(ReadableFontData* data,
: IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
}
-IntegerList* IndexSubTableFormat3::Builder::GetOffsetArray() {
+std::vector<int32_t>* IndexSubTableFormat3::Builder::GetOffsetArray() {
if (offset_array_.empty()) {
Initialize(InternalReadData());
set_model_changed();
diff --git a/cpp/src/sfntly/table/bitmap/index_sub_table_format3.h b/cpp/src/sfntly/table/bitmap/index_sub_table_format3.h
index d71f857..1f2f0aa 100644
--- a/cpp/src/sfntly/table/bitmap/index_sub_table_format3.h
+++ b/cpp/src/sfntly/table/bitmap/index_sub_table_format3.h
@@ -52,7 +52,7 @@ class IndexSubTableFormat3 : public IndexSubTable,
virtual bool SubReadyToSerialize();
virtual int32_t SubSerialize(WritableFontData* new_data);
- void SetOffsetArray(const IntegerList& offset_array);
+ void SetOffsetArray(const std::vector<int32_t>& offset_array);
static CALLER_ATTACH Builder* CreateBuilder();
static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
@@ -75,7 +75,7 @@ class IndexSubTableFormat3 : public IndexSubTable,
Builder(ReadableFontData* data,
int32_t first_glyph_index,
int32_t last_glyph_index);
- IntegerList* GetOffsetArray();
+ std::vector<int32_t>* GetOffsetArray();
void Initialize(ReadableFontData* data);
static int32_t DataLength(ReadableFontData* data,
@@ -83,7 +83,7 @@ class IndexSubTableFormat3 : public IndexSubTable,
int32_t first_glyph_index,
int32_t last_glyph_index);
- IntegerList offset_array_;
+ std::vector<int32_t> offset_array_;
};
virtual ~IndexSubTableFormat3();
diff --git a/cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc b/cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc
index 0ca21fe..b1f773a 100644
--- a/cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc
+++ b/cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc
@@ -104,8 +104,8 @@ int32_t IndexSubTableFormat5::Builder::GlyphStartOffset(int32_t glyph_id) {
if (check == -1) {
return -1;
}
- IntegerList* glyph_array = GetGlyphArray();
- IntegerList::iterator it = std::find(glyph_array->begin(),
+ 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()) {
@@ -215,7 +215,7 @@ int32_t IndexSubTableFormat5::Builder::SubSerialize(
slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
size += BigMetrics()->SubSerialize(slice);
size += new_data->WriteULong(size, glyph_array_.size());
- for (IntegerList::iterator b = glyph_array_.begin(), e = glyph_array_.end();
+ for (std::vector<int32_t>::iterator b = glyph_array_.begin(), e = glyph_array_.end();
b != e; b++) {
size += new_data->WriteUShort(size, *b);
}
@@ -245,11 +245,11 @@ BigGlyphMetrics::Builder* IndexSubTableFormat5::Builder::BigMetrics() {
return metrics_;
}
-IntegerList* IndexSubTableFormat5::Builder::GlyphArray() {
+std::vector<int32_t>* IndexSubTableFormat5::Builder::GlyphArray() {
return GetGlyphArray();
}
-void IndexSubTableFormat5::Builder::SetGlyphArray(const IntegerList& v) {
+void IndexSubTableFormat5::Builder::SetGlyphArray(const std::vector<int32_t>& v) {
glyph_array_.clear();
glyph_array_ = v;
set_model_changed();
@@ -277,7 +277,7 @@ IndexSubTableFormat5::Builder::Builder(ReadableFontData* data,
: IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
}
-IntegerList* IndexSubTableFormat5::Builder::GetGlyphArray() {
+std::vector<int32_t>* IndexSubTableFormat5::Builder::GetGlyphArray() {
if (glyph_array_.empty()) {
Initialize(InternalReadData());
set_model_changed();
diff --git a/cpp/src/sfntly/table/bitmap/index_sub_table_format5.h b/cpp/src/sfntly/table/bitmap/index_sub_table_format5.h
index a39e88c..b6534e7 100644
--- a/cpp/src/sfntly/table/bitmap/index_sub_table_format5.h
+++ b/cpp/src/sfntly/table/bitmap/index_sub_table_format5.h
@@ -55,8 +55,8 @@ class IndexSubTableFormat5 : public IndexSubTable,
int32_t ImageSize();
void SetImageSize(int32_t image_size);
BigGlyphMetrics::Builder* BigMetrics();
- IntegerList* GlyphArray();
- void SetGlyphArray(const IntegerList& v);
+ 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,
@@ -79,7 +79,7 @@ class IndexSubTableFormat5 : public IndexSubTable,
int32_t first_glyph_index,
int32_t last_glyph_index);
- IntegerList* GetGlyphArray();
+ std::vector<int32_t>* GetGlyphArray();
void Initialize(ReadableFontData* data);
static int32_t DataLength(ReadableFontData* data,
@@ -87,7 +87,7 @@ class IndexSubTableFormat5 : public IndexSubTable,
int32_t first_glyph_index,
int32_t last_glyph_index);
- IntegerList glyph_array_;
+ std::vector<int32_t> glyph_array_;
BigGlyphMetricsBuilderPtr metrics_;
};
virtual ~IndexSubTableFormat5();
diff --git a/cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc b/cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc
index 0f3c1e9..24ff624 100644
--- a/cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc
+++ b/cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc
@@ -65,7 +65,7 @@ int32_t SmallGlyphMetrics::Builder::Height() {
return InternalReadData()->ReadByte(Offset::kHeight);
}
-void SmallGlyphMetrics::Builder::SetHeight(byte_t height) {
+void SmallGlyphMetrics::Builder::SetHeight(uint8_t height) {
InternalWriteData()->WriteByte(Offset::kHeight, height);
}
@@ -73,7 +73,7 @@ int32_t SmallGlyphMetrics::Builder::Width() {
return InternalReadData()->ReadByte(Offset::kWidth);
}
-void SmallGlyphMetrics::Builder::SetWidth(byte_t width) {
+void SmallGlyphMetrics::Builder::SetWidth(uint8_t width) {
InternalWriteData()->WriteByte(Offset::kWidth, width);
}
@@ -81,7 +81,7 @@ int32_t SmallGlyphMetrics::Builder::BearingX() {
return InternalReadData()->ReadByte(Offset::kBearingX);
}
-void SmallGlyphMetrics::Builder::SetBearingX(byte_t bearing) {
+void SmallGlyphMetrics::Builder::SetBearingX(uint8_t bearing) {
InternalWriteData()->WriteByte(Offset::kBearingX, bearing);
}
@@ -89,7 +89,7 @@ int32_t SmallGlyphMetrics::Builder::BearingY() {
return InternalReadData()->ReadByte(Offset::kBearingY);
}
-void SmallGlyphMetrics::Builder::SetBearingY(byte_t bearing) {
+void SmallGlyphMetrics::Builder::SetBearingY(uint8_t bearing) {
InternalWriteData()->WriteByte(Offset::kBearingY, bearing);
}
@@ -97,7 +97,7 @@ int32_t SmallGlyphMetrics::Builder::Advance() {
return InternalReadData()->ReadByte(Offset::kAdvance);
}
-void SmallGlyphMetrics::Builder::SetAdvance(byte_t advance) {
+void SmallGlyphMetrics::Builder::SetAdvance(uint8_t advance) {
InternalWriteData()->WriteByte(Offset::kAdvance, advance);
}
diff --git a/cpp/src/sfntly/table/bitmap/small_glyph_metrics.h b/cpp/src/sfntly/table/bitmap/small_glyph_metrics.h
index ea13720..57cc06e 100644
--- a/cpp/src/sfntly/table/bitmap/small_glyph_metrics.h
+++ b/cpp/src/sfntly/table/bitmap/small_glyph_metrics.h
@@ -46,15 +46,15 @@ class SmallGlyphMetrics : public GlyphMetrics,
virtual ~Builder();
int32_t Height();
- void SetHeight(byte_t height);
+ void SetHeight(uint8_t height);
int32_t Width();
- void SetWidth(byte_t width);
+ void SetWidth(uint8_t width);
int32_t BearingX();
- void SetBearingX(byte_t bearing);
+ void SetBearingX(uint8_t bearing);
int32_t BearingY();
- void SetBearingY(byte_t bearing);
+ void SetBearingY(uint8_t bearing);
int32_t Advance();
- void SetAdvance(byte_t advance);
+ void SetAdvance(uint8_t advance);
virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
virtual void SubDataSet();
diff --git a/cpp/src/sfntly/table/byte_array_table_builder.cc b/cpp/src/sfntly/table/byte_array_table_builder.cc
index 631a05f..2fc982f 100644
--- a/cpp/src/sfntly/table/byte_array_table_builder.cc
+++ b/cpp/src/sfntly/table/byte_array_table_builder.cc
@@ -31,7 +31,7 @@ int32_t ByteArrayTableBuilder::ByteValue(int32_t index) {
return data->ReadByte(index);
}
-void ByteArrayTableBuilder::SetByteValue(int32_t index, byte_t b) {
+void ByteArrayTableBuilder::SetByteValue(int32_t index, uint8_t b) {
WritableFontDataPtr data = InternalWriteData();
if (data == NULL) {
#if !defined (SFNTLY_NO_EXCEPTION)
diff --git a/cpp/src/sfntly/table/byte_array_table_builder.h b/cpp/src/sfntly/table/byte_array_table_builder.h
index 42d27a8..a3df0f8 100644
--- a/cpp/src/sfntly/table/byte_array_table_builder.h
+++ b/cpp/src/sfntly/table/byte_array_table_builder.h
@@ -36,7 +36,7 @@ class ByteArrayTableBuilder : public TableBasedTableBuilder {
// start of the table.
// @param index index relative to the start of the table
// @param b byte value to set
- virtual void SetByteValue(int32_t index, byte_t b);
+ virtual void SetByteValue(int32_t index, uint8_t b);
// Get the number of bytes set for this table. It may include padding bytes at
// the end.
diff --git a/cpp/src/sfntly/table/core/cmap_table.cc b/cpp/src/sfntly/table/core/cmap_table.cc
index 1c83d2e..1f1668e 100644
--- a/cpp/src/sfntly/table/core/cmap_table.cc
+++ b/cpp/src/sfntly/table/core/cmap_table.cc
@@ -469,8 +469,8 @@ int32_t CMapTable::CMapFormat2::GlyphId(int32_t character) {
}
uint32_t c = ToBE32(character);
- byte_t high_byte = (c >> 8) & 0xff;
- byte_t low_byte = c & 0xff;
+ uint8_t high_byte = (c >> 8) & 0xff;
+ uint8_t low_byte = c & 0xff;
int32_t offset = SubHeaderOffset(high_byte);
if (offset == 0) {
@@ -956,7 +956,7 @@ CMapTable::CMapFormat4::Builder::Builder(WritableFontData* data, int32_t offset,
}
CMapTable::CMapFormat4::Builder::Builder(SegmentList* segments,
- IntegerList* glyph_id_array,
+ std::vector<int32_t>* glyph_id_array,
const CMapId& cmap_id)
: CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL),
CMapFormat::kFormat4, cmap_id),
@@ -1016,7 +1016,7 @@ void CMapTable::CMapFormat4::Builder::set_segments(SegmentList* segments) {
set_model_changed();
}
-IntegerList* CMapTable::CMapFormat4::Builder::glyph_id_array() {
+std::vector<int32_t>* CMapTable::CMapFormat4::Builder::glyph_id_array() {
if (glyph_id_array_.empty()) {
Initialize(InternalReadData());
set_model_changed();
@@ -1025,7 +1025,7 @@ IntegerList* CMapTable::CMapFormat4::Builder::glyph_id_array() {
}
void CMapTable::CMapFormat4::Builder::
-set_glyph_id_array(IntegerList* glyph_id_array) {
+set_glyph_id_array(std::vector<int32_t>* glyph_id_array) {
glyph_id_array_.assign(glyph_id_array->begin(), glyph_id_array->end());
set_model_changed();
}
diff --git a/cpp/src/sfntly/table/core/cmap_table.h b/cpp/src/sfntly/table/core/cmap_table.h
index b264b07..81f0a5d 100644
--- a/cpp/src/sfntly/table/core/cmap_table.h
+++ b/cpp/src/sfntly/table/core/cmap_table.h
@@ -374,13 +374,13 @@ public:
virtual ~Builder();
SegmentList* segments();
void set_segments(SegmentList* segments);
- IntegerList* glyph_id_array();
- void set_glyph_id_array(IntegerList* glyph_id_array);
+ std::vector<int32_t>* glyph_id_array();
+ void set_glyph_id_array(std::vector<int32_t>* glyph_id_array);
protected:
Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id);
Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id);
- Builder(SegmentList* segments, IntegerList* glyph_id_array,
+ Builder(SegmentList* segments, std::vector<int32_t>* glyph_id_array,
const CMapId& cmap_id);
explicit Builder(const CMapId& cmap_id);
@@ -395,7 +395,7 @@ public:
void Initialize(ReadableFontData* data);
SegmentList segments_;
- IntegerList glyph_id_array_;
+ std::vector<int32_t> glyph_id_array_;
};
CMap::CharacterIterator* Iterator();
diff --git a/cpp/src/sfntly/table/core/font_header_table.cc b/cpp/src/sfntly/table/core/font_header_table.cc
index a848afd..e089c7e 100644
--- a/cpp/src/sfntly/table/core/font_header_table.cc
+++ b/cpp/src/sfntly/table/core/font_header_table.cc
@@ -92,7 +92,7 @@ int32_t FontHeaderTable::GlyphDataFormat() {
FontHeaderTable::FontHeaderTable(Header* header, ReadableFontData* data)
: Table(header, data) {
- IntegerList checksum_ranges;
+ std::vector<int32_t> checksum_ranges;
checksum_ranges.push_back(0);
checksum_ranges.push_back(Offset::kCheckSumAdjustment);
checksum_ranges.push_back(Offset::kMagicNumber);
diff --git a/cpp/src/sfntly/table/core/name_table.cc b/cpp/src/sfntly/table/core/name_table.cc
index 4eb54ad..0e1fff9 100644
--- a/cpp/src/sfntly/table/core/name_table.cc
+++ b/cpp/src/sfntly/table/core/name_table.cc
@@ -78,7 +78,7 @@ NameTable::NameEntry::NameEntry() {
}
NameTable::NameEntry::NameEntry(const NameEntryId& name_entry_id,
- const ByteVector& name_bytes) {
+ const std::vector<uint8_t>& name_bytes) {
Init(name_entry_id.platform_id(),
name_entry_id.encoding_id(),
name_entry_id.language_id(),
@@ -90,13 +90,13 @@ NameTable::NameEntry::NameEntry(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id,
- const ByteVector& name_bytes) {
+ const std::vector<uint8_t>& name_bytes) {
Init(platform_id, encoding_id, language_id, name_id, &name_bytes);
}
NameTable::NameEntry::~NameEntry() {}
-ByteVector* NameTable::NameEntry::NameAsBytes() {
+std::vector<uint8_t>* NameTable::NameEntry::NameAsBytes() {
return &name_bytes_;
}
@@ -119,7 +119,7 @@ void NameTable::NameEntry::Init(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id,
- const ByteVector* name_bytes) {
+ const std::vector<uint8_t>* name_bytes) {
name_entry_id_ = NameEntryId(platform_id, encoding_id, language_id, name_id);
if (name_bytes) {
name_bytes_ = *name_bytes;
@@ -136,7 +136,7 @@ NameTable::NameEntryBuilder::NameEntryBuilder() {
}
NameTable::NameEntryBuilder::NameEntryBuilder(const NameEntryId& name_entry_id,
- const ByteVector& name_bytes) {
+ const std::vector<uint8_t>& name_bytes) {
Init(name_entry_id.platform_id(),
name_entry_id.encoding_id(),
name_entry_id.language_id(),
@@ -174,14 +174,14 @@ void NameTable::NameEntryBuilder::SetName(const UChar* name) {
&name_entry_->name_bytes_);
}
-void NameTable::NameEntryBuilder::SetName(const ByteVector& name_bytes) {
+void NameTable::NameEntryBuilder::SetName(const std::vector<uint8_t>& name_bytes) {
name_entry_->name_bytes_.clear();
std::copy(name_bytes.begin(),
name_bytes.end(),
name_entry_->name_bytes_.begin());
}
-void NameTable::NameEntryBuilder::SetName(const ByteVector& name_bytes,
+void NameTable::NameEntryBuilder::SetName(const std::vector<uint8_t>& name_bytes,
int32_t offset,
int32_t length) {
name_entry_->name_bytes_.clear();
@@ -194,7 +194,7 @@ void NameTable::NameEntryBuilder::Init(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id,
- const ByteVector* name_bytes) {
+ const std::vector<uint8_t>* name_bytes) {
name_entry_ = new NameEntry();
name_entry_->Init(platform_id, encoding_id, language_id, name_id, name_bytes);
}
@@ -465,7 +465,7 @@ int32_t NameTable::NameId(int32_t index) {
OffsetForNameRecord(index));
}
-void NameTable::NameAsBytes(int32_t index, ByteVector* b) {
+void NameTable::NameAsBytes(int32_t index, std::vector<uint8_t>* b) {
assert(b);
b->clear();
@@ -473,26 +473,30 @@ void NameTable::NameAsBytes(int32_t index, ByteVector* b) {
if (length <= 0)
return;
+ int32_t offset = NameOffset(index);
+ if (offset < 0)
+ return;
+
b->resize(length);
- data_->ReadBytes(NameOffset(index), &((*b)[0]), 0, length);
+ data_->ReadBytes(offset, &((*b)[0]), 0, length);
}
void NameTable::NameAsBytes(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id,
- ByteVector* b) {
+ std::vector<uint8_t>* b) {
assert(b);
NameEntryPtr entry;
entry.Attach(GetNameEntry(platform_id, encoding_id, language_id, name_id));
if (entry) {
- ByteVector* name = entry->NameAsBytes();
+ std::vector<uint8_t>* name = entry->NameAsBytes();
std::copy(name->begin(), name->end(), b->begin());
}
}
UChar* NameTable::Name(int32_t index) {
- ByteVector b;
+ std::vector<uint8_t> b;
NameAsBytes(index, &b);
return ConvertFromNameBytes(&b, PlatformId(index), EncodingId(index));
}
@@ -510,7 +514,7 @@ UChar* NameTable::Name(int32_t platform_id,
}
CALLER_ATTACH NameTable::NameEntry* NameTable::GetNameEntry(int32_t index) {
- ByteVector b;
+ std::vector<uint8_t> b;
NameAsBytes(index, &b);
NameEntryPtr instance = new NameEntry(PlatformId(index),
EncodingId(index),
@@ -646,7 +650,7 @@ UConverter* NameTable::GetCharset(int32_t platform_id, int32_t encoding_id) {
void NameTable::ConvertToNameBytes(const UChar* name,
int32_t platform_id,
int32_t encoding_id,
- ByteVector* b) {
+ std::vector<uint8_t>* b) {
assert(b);
assert(name);
b->clear();
@@ -673,7 +677,7 @@ void NameTable::ConvertToNameBytes(const UChar* name,
ucnv_close(cs);
}
-UChar* NameTable::ConvertFromNameBytes(ByteVector* name_bytes,
+UChar* NameTable::ConvertFromNameBytes(std::vector<uint8_t>* name_bytes,
int32_t platform_id,
int32_t encoding_id) {
if (name_bytes == NULL || name_bytes->size() == 0) {
diff --git a/cpp/src/sfntly/table/core/name_table.h b/cpp/src/sfntly/table/core/name_table.h
index 4eaafbb..ac109df 100644
--- a/cpp/src/sfntly/table/core/name_table.h
+++ b/cpp/src/sfntly/table/core/name_table.h
@@ -446,12 +446,12 @@ class NameTable : public SubTableContainerTable, public RefCounted<NameTable> {
class NameEntry : public RefCounted<NameEntry> {
public:
NameEntry();
- NameEntry(const NameEntryId& name_entry_id, const ByteVector& name_bytes);
+ NameEntry(const NameEntryId& name_entry_id, const std::vector<uint8_t>& name_bytes);
NameEntry(int32_t platform_id,
int32_t encoding_id,
int32_t language_id,
int32_t name_id,
- const ByteVector& name_bytes);
+ const std::vector<uint8_t>& name_bytes);
virtual ~NameEntry();
NameEntryId& name_entry_id() { return name_entry_id_; }
@@ -462,7 +462,7 @@ class NameTable : public SubTableContainerTable, public RefCounted<NameTable> {
// Get the bytes for name. Returned pointer is the address of private
// member of this class, do not attempt to delete.
- ByteVector* NameAsBytes();
+ std::vector<uint8_t>* NameAsBytes();
// C++ port only: get the length of NameAsBytes.
int32_t NameBytesLength();
@@ -477,10 +477,10 @@ class NameTable : public SubTableContainerTable, public RefCounted<NameTable> {
private:
void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id,
- int32_t name_id, const ByteVector* name_bytes);
+ int32_t name_id, const std::vector<uint8_t>* name_bytes);
NameEntryId name_entry_id_;
- ByteVector name_bytes_;
+ std::vector<uint8_t> name_bytes_;
friend class NameEntryBuilder;
};
@@ -492,14 +492,14 @@ class NameTable : public SubTableContainerTable, public RefCounted<NameTable> {
public:
NameEntryBuilder();
NameEntryBuilder(const NameEntryId& name_entry_id,
- const ByteVector& name_bytes);
+ const std::vector<uint8_t>& name_bytes);
explicit NameEntryBuilder(const NameEntryId& name_entry_id);
explicit NameEntryBuilder(NameEntry* entry);
virtual ~NameEntryBuilder();
virtual void SetName(const UChar* name);
- virtual void SetName(const ByteVector& name_bytes);
- virtual void SetName(const ByteVector& name_bytes,
+ virtual void SetName(const std::vector<uint8_t>& name_bytes);
+ virtual void SetName(const std::vector<uint8_t>& name_bytes,
int32_t offset,
int32_t length);
@@ -510,7 +510,7 @@ class NameTable : public SubTableContainerTable, public RefCounted<NameTable> {
private:
void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id,
- int32_t name_id, const ByteVector* name_bytes);
+ int32_t name_id, const std::vector<uint8_t>* name_bytes);
Ptr<NameEntry> name_entry_;
};
@@ -647,10 +647,10 @@ class NameTable : public SubTableContainerTable, public RefCounted<NameTable> {
// Get the name as bytes for the specified name. If there is no entry for the
// requested name, then empty vector is returned.
- virtual void NameAsBytes(int32_t index, ByteVector* b);
+ virtual void NameAsBytes(int32_t index, std::vector<uint8_t>* b);
virtual void NameAsBytes(int32_t platform_id, int32_t encoding_id,
int32_t language_id, int32_t name_id,
- ByteVector* b);
+ std::vector<uint8_t>* b);
// Get the name as a UChar* for the given name record. If there is no
// encoding conversion available for the name record then a best attempt
@@ -724,13 +724,13 @@ class NameTable : public SubTableContainerTable, public RefCounted<NameTable> {
// Note: ICU UConverter* convention requires caller to ucnv_close() it.
static UConverter* GetCharset(int32_t platform_id, int32_t encoding_id);
- // Note: Output will be stored in ByteVector* b. Original data in b will be
+ // Note: Output will be stored in std::vector<uint8_t>* b. Original data in b will be
// erased and replaced with converted name bytes.
static void ConvertToNameBytes(const UChar* name, int32_t platform_id,
- int32_t encoding_id, ByteVector* b);
+ int32_t encoding_id, std::vector<uint8_t>* b);
// Note: ICU UChar* convention requires caller to delete[] it.
- static UChar* ConvertFromNameBytes(ByteVector* name_bytes,
+ static UChar* ConvertFromNameBytes(std::vector<uint8_t>* name_bytes,
int32_t platform_id, int32_t encoding_id);
}; // class NameTable
typedef Ptr<NameTable> NameTablePtr;
diff --git a/cpp/src/sfntly/table/core/os2_table.cc b/cpp/src/sfntly/table/core/os2_table.cc
index 1fef309..0d37db1 100644
--- a/cpp/src/sfntly/table/core/os2_table.cc
+++ b/cpp/src/sfntly/table/core/os2_table.cc
@@ -166,7 +166,7 @@ int32_t OS2Table::SFamilyClass() {
return data_->ReadShort(Offset::kSFamilyClass);
}
-void OS2Table::Panose(ByteVector* value) {
+void OS2Table::Panose(std::vector<uint8_t>* value) {
assert(value);
value->clear();
value->resize(10);
@@ -189,7 +189,7 @@ int64_t OS2Table::UlUnicodeRange4() {
return data_->ReadULong(Offset::kUlUnicodeRange4);
}
-void OS2Table::AchVendId(ByteVector* b) {
+void OS2Table::AchVendId(std::vector<uint8_t>* b) {
assert(b);
b->clear();
b->resize(4);
@@ -415,7 +415,7 @@ void OS2Table::Builder::SetSFamilyClass(int32_t family) {
InternalWriteData()->WriteShort(Offset::kSFamilyClass, family);
}
-void OS2Table::Builder::Panose(ByteVector* value) {
+void OS2Table::Builder::Panose(std::vector<uint8_t>* value) {
assert(value);
value->clear();
value->resize(Offset::kPanoseLength);
@@ -425,7 +425,7 @@ void OS2Table::Builder::Panose(ByteVector* value) {
Offset::kPanoseLength);
}
-void OS2Table::Builder::SetPanose(ByteVector* panose) {
+void OS2Table::Builder::SetPanose(std::vector<uint8_t>* panose) {
assert(panose);
if (panose->size() != Offset::kPanoseLength) {
#if !defined (SFNTLY_NO_EXCEPTION)
@@ -468,14 +468,14 @@ void OS2Table::Builder::SetUlUnicodeRange4(int64_t range) {
InternalWriteData()->WriteULong(Offset::kUlUnicodeRange4, range);
}
-void OS2Table::Builder::AchVendId(ByteVector* b) {
+void OS2Table::Builder::AchVendId(std::vector<uint8_t>* b) {
assert(b);
b->clear();
b->resize(4);
InternalReadData()->ReadBytes(Offset::kAchVendId, &((*b)[0]), 0, 4);
}
-void OS2Table::Builder::SetAchVendId(ByteVector* b) {
+void OS2Table::Builder::SetAchVendId(std::vector<uint8_t>* b) {
assert(b);
assert(b->size());
InternalWriteData()->WriteBytesPad(Offset::kAchVendId,
@@ -484,7 +484,7 @@ void OS2Table::Builder::SetAchVendId(ByteVector* b) {
std::min<size_t>(
(size_t)Offset::kAchVendIdLength,
b->size()),
- static_cast<byte_t>(' '));
+ static_cast<uint8_t>(' '));
}
int32_t OS2Table::Builder::FsSelection() {
diff --git a/cpp/src/sfntly/table/core/os2_table.h b/cpp/src/sfntly/table/core/os2_table.h
index 00d26d2..6057412 100644
--- a/cpp/src/sfntly/table/core/os2_table.h
+++ b/cpp/src/sfntly/table/core/os2_table.h
@@ -357,8 +357,8 @@ class OS2Table : public Table, public RefCounted<OS2Table> {
void SetYStrikeoutPosition(int32_t position);
int32_t SFamilyClass();
void SetSFamilyClass(int32_t family);
- void Panose(ByteVector* value);
- void SetPanose(ByteVector* panose);
+ void Panose(std::vector<uint8_t>* value);
+ void SetPanose(std::vector<uint8_t>* panose);
int64_t UlUnicodeRange1();
void SetUlUnicodeRange1(int64_t range);
int64_t UlUnicodeRange2();
@@ -369,12 +369,12 @@ class OS2Table : public Table, public RefCounted<OS2Table> {
void SetUlUnicodeRange4(int64_t range);
// UNIMPLEMENTED: EnumSet<UnicodeRange> UlUnicodeRange()
// setUlUnicodeRange(EnumSet<UnicodeRange> rangeSet)
- void AchVendId(ByteVector* b);
+ void AchVendId(std::vector<uint8_t>* b);
// This field is 4 bytes in length and only the first 4 bytes of the byte
// array will be written. If the byte array is less than 4 bytes it will be
// padded out with space characters (0x20).
// @param b ach Vendor Id
- void SetAchVendId(ByteVector* b);
+ void SetAchVendId(std::vector<uint8_t>* b);
// UNIMPLEMENTED: public EnumSet<FsSelection> fsSelection()
int32_t FsSelection();
void SetFsSelection(int32_t fs_selection);
@@ -429,13 +429,13 @@ class OS2Table : public Table, public RefCounted<OS2Table> {
int32_t YStrikeoutSize();
int32_t YStrikeoutPosition();
int32_t SFamilyClass();
- void Panose(ByteVector* value);
+ void Panose(std::vector<uint8_t>* value);
int64_t UlUnicodeRange1();
int64_t UlUnicodeRange2();
int64_t UlUnicodeRange3();
int64_t UlUnicodeRange4();
// UNIMPLEMENTED: public EnumSet<UnicodeRange> UlUnicodeRange()
- void AchVendId(ByteVector* b);
+ void AchVendId(std::vector<uint8_t>* b);
// UNIMPLEMENTED: public EnumSet<FsSelection> fsSelection()
int32_t FsSelection();
int32_t UsFirstCharIndex();
diff --git a/cpp/src/sfntly/table/header.h b/cpp/src/sfntly/table/header.h
index 7744a21..1a4cba1 100644
--- a/cpp/src/sfntly/table/header.h
+++ b/cpp/src/sfntly/table/header.h
@@ -34,51 +34,51 @@ class Header : public RefCounted<Header> {
virtual ~Header();
// Get the table tag.
- int32_t tag() { return tag_; }
+ int32_t tag() const { return tag_; }
// Get the table offset. The offset is from the start of the font file. This
// offset value is what was read from the font file during construction of the
// font. It may not be meaningful if the font was maninpulated through the
// builders.
- int32_t offset() { return offset_; }
+ int32_t offset() const { return offset_; }
// Is the offset in the header valid. The offset will not be valid if the
// table was constructed during building and has no physical location in a
// font file.
- bool offset_valid() { return offset_valid_; }
+ bool offset_valid() const { return offset_valid_; }
// Get the length of the table as recorded in the table record header. During
// building the header length will reflect the length that was initially read
// from the font file. This may not be consistent with the current state of
// the data.
- int32_t length() { return length_; }
+ int32_t length() const { return length_; }
// Is the length in the header valid. The length will not be valid if the
// table was constructed during building and has no physical location in a
// font file until the table is built from the builder.
- bool length_valid() { return length_valid_; }
+ bool length_valid() const { return length_valid_; }
// Get the checksum for the table as recorded in the table record header.
- int64_t checksum() { return checksum_; }
+ int64_t checksum() const { return checksum_; }
// Is the checksum valid. The checksum will not be valid if the table was
// constructed during building and has no physical location in a font file.
// Note that this does *NOT* check the validity of the checksum against
// the calculated checksum for the table data.
- bool checksum_valid() { return checksum_valid_; }
+ bool checksum_valid() const { return checksum_valid_; }
// UNIMPLEMENTED: boolean equals(Object obj)
// int hashCode()
// string toString()
private:
- int32_t tag_;
- int32_t offset_;
- bool offset_valid_;
- int32_t length_;
- bool length_valid_;
- int64_t checksum_;
- bool checksum_valid_;
+ const int32_t tag_;
+ const int32_t offset_;
+ const bool offset_valid_;
+ const int32_t length_;
+ const bool length_valid_;
+ const int64_t checksum_;
+ const bool checksum_valid_;
friend class HeaderComparatorByOffset;
friend class HeaderComparatorByTag;
diff --git a/cpp/src/sfntly/table/truetype/glyph_table.cc b/cpp/src/sfntly/table/truetype/glyph_table.cc
index 0c1e841..32b76b6 100644
--- a/cpp/src/sfntly/table/truetype/glyph_table.cc
+++ b/cpp/src/sfntly/table/truetype/glyph_table.cc
@@ -69,13 +69,13 @@ GlyphTable::Builder::Builder(Header* header, ReadableFontData* data)
GlyphTable::Builder::~Builder() {
}
-void GlyphTable::Builder::SetLoca(const IntegerList& loca) {
+void GlyphTable::Builder::SetLoca(const std::vector<int32_t>& loca) {
loca_ = loca;
set_model_changed(false);
glyph_builders_.clear();
}
-void GlyphTable::Builder::GenerateLocaList(IntegerList* locas) {
+void GlyphTable::Builder::GenerateLocaList(std::vector<int32_t>* locas) {
assert(locas);
GlyphBuilderList* glyph_builders = GetGlyphBuilders();
locas->push_back(0);
@@ -158,7 +158,7 @@ int32_t GlyphTable::Builder::SubSerialize(WritableFontData* new_data) {
}
void GlyphTable::Builder::Initialize(ReadableFontData* data,
- const IntegerList& loca) {
+ const std::vector<int32_t>& loca) {
if (data != NULL) {
if (loca_.empty()) {
return;
@@ -181,7 +181,7 @@ void GlyphTable::Builder::Initialize(ReadableFontData* data,
GlyphTable::GlyphBuilderList* GlyphTable::Builder::GetGlyphBuilders() {
if (glyph_builders_.empty()) {
- if (InternalReadData() && !loca_.empty()) {
+ if (InternalReadData() && loca_.empty()) {
#if !defined (SFNTLY_NO_EXCEPTION)
throw IllegalStateException(
"Loca values not set - unable to parse glyph data.");
@@ -354,29 +354,6 @@ CALLER_ATTACH ReadableFontData* GlyphTable::SimpleGlyph::Instructions() {
data_->Slice(instructions_offset_, InstructionSize()));
}
-int32_t GlyphTable::SimpleGlyph::NumberOfPoints(int32_t contour) {
- Initialize();
- if (contour >= NumberOfContours()) {
- return 0;
- }
- return contour_index_[contour + 1] - contour_index_[contour];
-}
-
-int32_t GlyphTable::SimpleGlyph::XCoordinate(int32_t contour, int32_t point) {
- Initialize();
- return x_coordinates_[contour_index_[contour] + point];
-}
-
-int32_t GlyphTable::SimpleGlyph::YCoordinate(int32_t contour, int32_t point) {
- Initialize();
- return y_coordinates_[contour_index_[contour] + point];
-}
-
-bool GlyphTable::SimpleGlyph::OnCurve(int32_t contour, int32_t point) {
- Initialize();
- return on_curve_[contour_index_[contour] + point];
-}
-
void GlyphTable::SimpleGlyph::Initialize() {
AutoLock lock(initialization_lock_);
if (initialized_) {
@@ -545,6 +522,8 @@ GlyphTable::CompositeGlyph::~CompositeGlyph() {
}
int32_t GlyphTable::CompositeGlyph::Flags(int32_t contour) {
+ if (contour < 0 || static_cast<size_t>(contour) >= contour_index_.size())
+ return ReadableFontData::kInvalidUnsigned;
return data_->ReadUShort(contour_index_[contour]);
}
@@ -553,58 +532,11 @@ int32_t GlyphTable::CompositeGlyph::NumGlyphs() {
}
int32_t GlyphTable::CompositeGlyph::GlyphIndex(int32_t contour) {
+ if (contour < 0 || static_cast<size_t>(contour) >= contour_index_.size())
+ return ReadableFontData::kInvalidUnsigned;
return data_->ReadUShort(DataSize::kUSHORT + contour_index_[contour]);
}
-int32_t GlyphTable::CompositeGlyph::Argument1(int32_t contour) {
- int32_t index = 2 * DataSize::kUSHORT + contour_index_[contour];
- int32_t contour_flags = Flags(contour);
- if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) ==
- kFLAG_ARG_1_AND_2_ARE_WORDS) {
- return data_->ReadUShort(index);
- }
- return data_->ReadByte(index);
-}
-
-int32_t GlyphTable::CompositeGlyph::Argument2(int32_t contour) {
- int32_t index = 2 * DataSize::kUSHORT + contour_index_[contour];
- int32_t contour_flags = Flags(contour);
- if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) ==
- kFLAG_ARG_1_AND_2_ARE_WORDS) {
- return data_->ReadUShort(index + DataSize::kUSHORT);
- }
- return data_->ReadByte(index + DataSize::kUSHORT);
-}
-
-int32_t GlyphTable::CompositeGlyph::TransformationSize(int32_t contour) {
- int32_t contour_flags = Flags(contour);
- if ((contour_flags & kFLAG_WE_HAVE_A_SCALE) == kFLAG_WE_HAVE_A_SCALE) {
- return DataSize::kF2DOT14;
- } else if ((contour_flags & kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) ==
- kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) {
- return 2 * DataSize::kF2DOT14;
- } else if ((contour_flags & kFLAG_WE_HAVE_A_TWO_BY_TWO) ==
- kFLAG_WE_HAVE_A_TWO_BY_TWO) {
- return 4 * DataSize::kF2DOT14;
- }
- return 0;
-}
-
-void GlyphTable::CompositeGlyph::Transformation(int32_t contour,
- ByteVector* transformation) {
- int32_t contour_flags = Flags(contour);
- int32_t index = contour_index_[contour] + 2 * DataSize::kUSHORT;
- if ((contour_flags & kFLAG_ARG_1_AND_2_ARE_WORDS) ==
- kFLAG_ARG_1_AND_2_ARE_WORDS) {
- index += 2 * DataSize::kSHORT;
- } else {
- index += 2 * DataSize::kBYTE;
- }
- int32_t tsize = TransformationSize(contour);
- transformation->resize(tsize);
- data_->ReadBytes(index, &((*transformation)[0]), 0, tsize);
-}
-
int32_t GlyphTable::CompositeGlyph::InstructionSize() {
return instruction_size_;
}
@@ -626,6 +558,9 @@ void GlyphTable::CompositeGlyph::Initialize() {
while ((flags & kFLAG_MORE_COMPONENTS) == kFLAG_MORE_COMPONENTS) {
contour_index_.push_back(index);
flags = data_->ReadUShort(index);
+ if (flags == ReadableFontData::kInvalidUnsigned)
+ break;
+
index += 2 * DataSize::kUSHORT; // flags and glyphIndex
if ((flags & kFLAG_ARG_1_AND_2_ARE_WORDS) == kFLAG_ARG_1_AND_2_ARE_WORDS) {
index += 2 * DataSize::kSHORT;
diff --git a/cpp/src/sfntly/table/truetype/glyph_table.h b/cpp/src/sfntly/table/truetype/glyph_table.h
index 4ffddda..e16c8c8 100644
--- a/cpp/src/sfntly/table/truetype/glyph_table.h
+++ b/cpp/src/sfntly/table/truetype/glyph_table.h
@@ -115,8 +115,8 @@ class GlyphTable : public SubTableContainerTable,
Builder(Header* header, ReadableFontData* data);
virtual ~Builder();
- virtual void SetLoca(const IntegerList& loca);
- virtual void GenerateLocaList(IntegerList* locas);
+ virtual void SetLoca(const std::vector<int32_t>& loca);
+ virtual void GenerateLocaList(std::vector<int32_t>* locas);
static CALLER_ATTACH Builder* CreateBuilder(Header* header,
WritableFontData* data);
@@ -150,12 +150,12 @@ class GlyphTable : public SubTableContainerTable,
virtual int32_t SubSerialize(WritableFontData* new_data);
private:
- void Initialize(ReadableFontData* data, const IntegerList& loca);
+ void Initialize(ReadableFontData* data, const std::vector<int32_t>& loca);
GlyphBuilderList* GetGlyphBuilders();
void Revert();
GlyphBuilderList glyph_builders_;
- IntegerList loca_;
+ std::vector<int32_t> loca_;
};
class SimpleGlyph : public Glyph, public RefCounted<SimpleGlyph> {
@@ -199,11 +199,6 @@ class GlyphTable : public SubTableContainerTable,
virtual CALLER_ATTACH ReadableFontData* Instructions();
virtual void Initialize();
- int32_t NumberOfPoints(int32_t contour);
- int32_t XCoordinate(int32_t contour, int32_t point);
- int32_t YCoordinate(int32_t contour, int32_t point);
- bool OnCurve(int32_t contour, int32_t point);
-
private:
void ParseData(bool fill_arrays);
int32_t FlagAsInt(int32_t index);
@@ -224,10 +219,10 @@ class GlyphTable : public SubTableContainerTable,
int32_t x_byte_count_;
int32_t y_byte_count_;
- IntegerList x_coordinates_;
- IntegerList y_coordinates_;
+ std::vector<int32_t> x_coordinates_;
+ std::vector<int32_t> y_coordinates_;
std::vector<bool> on_curve_;
- IntegerList contour_index_;
+ std::vector<int32_t> contour_index_;
};
class CompositeGlyph : public Glyph, public RefCounted<CompositeGlyph> {
@@ -272,10 +267,6 @@ class GlyphTable : public SubTableContainerTable,
int32_t Flags(int32_t contour);
int32_t NumGlyphs();
int32_t GlyphIndex(int32_t contour);
- int32_t Argument1(int32_t contour);
- int32_t Argument2(int32_t contour);
- int32_t TransformationSize(int32_t contour);
- void Transformation(int32_t contour, ByteVector* transformation);
virtual int32_t InstructionSize();
virtual CALLER_ATTACH ReadableFontData* Instructions();
@@ -283,7 +274,7 @@ class GlyphTable : public SubTableContainerTable,
virtual void Initialize();
private:
- IntegerList contour_index_;
+ std::vector<int32_t> contour_index_;
int32_t instruction_size_;
int32_t instructions_offset_;
bool initialized_;
diff --git a/cpp/src/sfntly/table/truetype/loca_table.cc b/cpp/src/sfntly/table/truetype/loca_table.cc
index c692155..a1e82a4 100644
--- a/cpp/src/sfntly/table/truetype/loca_table.cc
+++ b/cpp/src/sfntly/table/truetype/loca_table.cc
@@ -40,7 +40,11 @@ int32_t LocaTable::GlyphLength(int32_t glyph_id) {
#endif
return 0;
}
- return Loca(glyph_id + 1) - Loca(glyph_id);
+ int32_t glyph_val = Loca(glyph_id);
+ int32_t glyph_next_val = Loca(glyph_id + 1);
+ if (glyph_val < 0 || glyph_next_val < 0 || glyph_next_val <= glyph_val)
+ return 0;
+ return glyph_next_val - glyph_val;
}
int32_t LocaTable::NumLocas() {
@@ -109,11 +113,11 @@ LocaTable::Builder* LocaTable::Builder::CreateBuilder(Header* header,
return builder.Detach();
}
-IntegerList* LocaTable::Builder::LocaList() {
+std::vector<int32_t>* LocaTable::Builder::LocaList() {
return GetLocaList();
}
-void LocaTable::Builder::SetLocaList(IntegerList* list) {
+void LocaTable::Builder::SetLocaList(std::vector<int32_t>* list) {
loca_.clear();
if (list) {
loca_ = *list;
@@ -136,6 +140,7 @@ int32_t LocaTable::Builder::GlyphLength(int32_t glyph_id) {
}
void LocaTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
+ assert(num_glyphs >= 0);
num_glyphs_ = num_glyphs;
}
@@ -183,7 +188,7 @@ bool LocaTable::Builder::SubReadyToSerialize() {
int32_t LocaTable::Builder::SubSerialize(WritableFontData* new_data) {
int32_t size = 0;
- for (IntegerList::iterator l = loca_.begin(), end = loca_.end();
+ for (std::vector<int32_t>::iterator l = loca_.begin(), end = loca_.end();
l != end; ++l) {
if (format_version_ == IndexToLocFormat::kLongOffset) {
size += new_data->WriteULong(size, *l);
@@ -228,7 +233,7 @@ int32_t LocaTable::Builder::LastGlyphIndex() {
return !loca_.empty() ? loca_.size() - 2 : num_glyphs_ - 1;
}
-IntegerList* LocaTable::Builder::GetLocaList() {
+std::vector<int32_t>* LocaTable::Builder::GetLocaList() {
if (loca_.empty()) {
Initialize(InternalReadData());
set_model_changed();
diff --git a/cpp/src/sfntly/table/truetype/loca_table.h b/cpp/src/sfntly/table/truetype/loca_table.h
index 67c5749..fe1dd4a 100644
--- a/cpp/src/sfntly/table/truetype/loca_table.h
+++ b/cpp/src/sfntly/table/truetype/loca_table.h
@@ -60,12 +60,12 @@ class LocaTable : public Table, public RefCounted<LocaTable> {
// SetLocaList(List) method.
// If there is no current data for the loca table builder or the loca list
// have not been previously set then this will return an empty List.
- IntegerList* LocaList();
+ std::vector<int32_t>* LocaList();
// Set the list of locas to be used for building this table. If any existing
// list was already retrieved with the LocaList() method then the
// connection of that previous list to this builder will be broken.
- void SetLocaList(IntegerList* list);
+ void SetLocaList(std::vector<int32_t>* list);
// Return the offset for the given glyph id. Valid glyph ids are from 0 to
// one less than the number of glyphs. The zero entry is the special entry
@@ -129,13 +129,13 @@ class LocaTable : public Table, public RefCounted<LocaTable> {
// Internal method to get the loca list if already generated and if not to
// initialize the state of the builder.
// @return the loca list
- IntegerList* GetLocaList();
+ std::vector<int32_t>* GetLocaList();
void ClearLoca(bool nullify);
int32_t format_version_; // Note: IndexToLocFormat
int32_t num_glyphs_;
- IntegerList loca_;
+ std::vector<int32_t> loca_;
};
virtual ~LocaTable();
diff --git a/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.cc b/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.cc
index b3d6b07..02cc149 100644
--- a/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.cc
+++ b/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.cc
@@ -39,7 +39,7 @@ bool GlyphTableSubsetter::Subset(Subsetter* subsetter,
assert(subsetter);
assert(font_builder);
- IntegerList* permutation_table = subsetter->GlyphPermutationTable();
+ std::vector<int32_t>* permutation_table = subsetter->GlyphPermutationTable();
if (!permutation_table || permutation_table->empty())
return false;
@@ -66,7 +66,7 @@ bool GlyphTableSubsetter::Subset(Subsetter* subsetter,
}
GlyphTable::GlyphBuilderList* glyph_builders =
glyph_table_builder->GlyphBuilders();
- for (IntegerList::iterator old_glyph_id = permutation_table->begin(),
+ for (std::vector<int32_t>::iterator old_glyph_id = permutation_table->begin(),
old_glyph_id_end = permutation_table->end();
old_glyph_id != old_glyph_id_end; ++old_glyph_id) {
int old_offset = loca_table->GlyphOffset(*old_glyph_id);
@@ -81,7 +81,7 @@ bool GlyphTableSubsetter::Subset(Subsetter* subsetter,
glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data));
glyph_builders->push_back(glyph_builder);
}
- IntegerList loca_list;
+ std::vector<int32_t> loca_list;
glyph_table_builder->GenerateLocaList(&loca_list);
loca_table_builder->SetLocaList(&loca_list);
return true;
diff --git a/cpp/src/sfntly/tools/subsetter/subsetter.cc b/cpp/src/sfntly/tools/subsetter/subsetter.cc
index 7d98779..3019cad 100644
--- a/cpp/src/sfntly/tools/subsetter/subsetter.cc
+++ b/cpp/src/sfntly/tools/subsetter/subsetter.cc
@@ -37,7 +37,7 @@ Subsetter::~Subsetter() {
table_subsetters_.clear();
}
-void Subsetter::SetGlyphs(IntegerList* glyphs) {
+void Subsetter::SetGlyphs(std::vector<int32_t>* glyphs) {
new_to_old_glyphs_ = *glyphs;
}
@@ -47,7 +47,7 @@ void Subsetter::SetCMaps(CMapIdList* cmap_ids, int32_t number) {
// TODO(arthurhsu): IMPLEMENT
}
-void Subsetter::SetRemoveTables(IntegerSet* remove_tables) {
+void Subsetter::SetRemoveTables(std::set<int32_t>* remove_tables) {
remove_tables_ = *remove_tables;
}
@@ -55,13 +55,13 @@ CALLER_ATTACH Font::Builder* Subsetter::Subset() {
FontBuilderPtr font_builder;
font_builder.Attach(font_factory_->NewFontBuilder());
- IntegerSet table_tags;
+ std::set<int32_t> table_tags;
for (TableMap::const_iterator i = font_->GetTableMap()->begin(),
e = font_->GetTableMap()->end(); i != e; ++i) {
table_tags.insert(i->first);
}
if (!remove_tables_.empty()) {
- IntegerSet result;
+ std::set<int32_t> result;
std::set_difference(table_tags.begin(), table_tags.end(),
remove_tables_.begin(), remove_tables_.end(),
std::inserter(result, result.end()));
@@ -73,15 +73,15 @@ CALLER_ATTACH Font::Builder* Subsetter::Subset() {
table_subsetter != table_subsetter_end; ++table_subsetter) {
bool handled = (*table_subsetter)->Subset(this, font_, font_builder);
if (handled) {
- IntegerSet* handled_tags = (*table_subsetter)->TagsHandled();
- IntegerSet result;
+ std::set<int32_t>* handled_tags = (*table_subsetter)->TagsHandled();
+ std::set<int32_t> result;
std::set_difference(table_tags.begin(), table_tags.end(),
handled_tags->begin(), handled_tags->end(),
std::inserter(result, result.end()));
table_tags = result;
}
}
- for (IntegerSet::iterator tag = table_tags.begin(),
+ for (std::set<int32_t>::iterator tag = table_tags.begin(),
tag_end = table_tags.end(); tag != tag_end; ++tag) {
Table* table = font_->GetTable(*tag);
if (table) {
@@ -91,7 +91,7 @@ CALLER_ATTACH Font::Builder* Subsetter::Subset() {
return font_builder.Detach();
}
-IntegerList* Subsetter::GlyphPermutationTable() {
+std::vector<int32_t>* Subsetter::GlyphPermutationTable() {
return &new_to_old_glyphs_;
}
diff --git a/cpp/src/sfntly/tools/subsetter/subsetter.h b/cpp/src/sfntly/tools/subsetter/subsetter.h
index 85940a7..d0a2607 100644
--- a/cpp/src/sfntly/tools/subsetter/subsetter.h
+++ b/cpp/src/sfntly/tools/subsetter/subsetter.h
@@ -31,7 +31,7 @@ class Subsetter : public RefCounted<Subsetter> {
Subsetter(Font* font, FontFactory* font_factory);
virtual ~Subsetter();
- virtual void SetGlyphs(IntegerList* glyphs);
+ virtual void SetGlyphs(std::vector<int32_t>* glyphs);
// Set the cmaps to be used in the subsetted font. The cmaps are listed in
// order of priority and the number parameter gives a count of how many of the
@@ -51,9 +51,9 @@ class Subsetter : public RefCounted<Subsetter> {
// @param number the maximum number of cmaps to place in the subsetted font
virtual void SetCMaps(CMapIdList* cmap_ids, int32_t number);
- virtual void SetRemoveTables(IntegerSet* remove_tables);
+ virtual void SetRemoveTables(std::set<int32_t>* remove_tables);
virtual CALLER_ATTACH Font::Builder* Subset();
- virtual IntegerList* GlyphPermutationTable();
+ virtual std::vector<int32_t>* GlyphPermutationTable();
virtual CMapIdList* CMapId();
private:
@@ -62,8 +62,8 @@ class Subsetter : public RefCounted<Subsetter> {
TableSubsetterList table_subsetters_;
// Settings from user
- IntegerSet remove_tables_;
- IntegerList new_to_old_glyphs_;
+ std::set<int32_t> remove_tables_;
+ std::vector<int32_t> new_to_old_glyphs_;
CMapIdList cmap_ids_;
};
diff --git a/cpp/src/sfntly/tools/subsetter/table_subsetter.h b/cpp/src/sfntly/tools/subsetter/table_subsetter.h
index 1336615..6a39f73 100644
--- a/cpp/src/sfntly/tools/subsetter/table_subsetter.h
+++ b/cpp/src/sfntly/tools/subsetter/table_subsetter.h
@@ -26,7 +26,7 @@ namespace sfntly {
class Subsetter;
class TableSubsetter : virtual public RefCount {
public:
- virtual IntegerSet* TagsHandled() = 0;
+ virtual std::set<int32_t>* TagsHandled() = 0;
virtual bool TagHandled(int32_t tag) = 0;
virtual bool Subset(Subsetter* subsetter, Font* font,
Font::Builder* font_builder) = 0;
diff --git a/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.cc b/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.cc
index f239c78..d2085a1 100644
--- a/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.cc
+++ b/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.cc
@@ -31,7 +31,7 @@ bool TableSubsetterImpl::TagHandled(int32_t tag) {
return tags_.find(tag) != tags_.end();
}
-IntegerSet* TableSubsetterImpl::TagsHandled() {
+std::set<int32_t>* TableSubsetterImpl::TagsHandled() {
return &tags_;
}
diff --git a/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.h b/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.h
index de0d9a9..14c770a 100644
--- a/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.h
+++ b/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.h
@@ -26,10 +26,10 @@ class TableSubsetterImpl : public TableSubsetter {
TableSubsetterImpl(const int32_t* tags, size_t tags_length);
virtual ~TableSubsetterImpl();
virtual bool TagHandled(int32_t tag);
- virtual IntegerSet* TagsHandled();
+ virtual std::set<int32_t>* TagsHandled();
protected:
- IntegerSet tags_;
+ std::set<int32_t> tags_;
};
} // namespace sfntly
diff --git a/cpp/src/test/bitmap_table_test.cc b/cpp/src/test/bitmap_table_test.cc
index df3ffc0..e9eacc7 100644
--- a/cpp/src/test/bitmap_table_test.cc
+++ b/cpp/src/test/bitmap_table_test.cc
@@ -58,11 +58,18 @@ bool CommonReadingTest(Font* raw_font) {
EXPECT_FALSE(bitmap_loca == NULL);
EXPECT_FALSE(bitmap_table == NULL);
+ if (!bitmap_loca) {
+ return false;
+ }
+
EXPECT_EQ(bitmap_loca->NumSizes(), NUM_STRIKES);
// Strike 1
BitmapSizeTablePtr strike1 = bitmap_loca->GetBitmapSizeTable(0);
EXPECT_FALSE(strike1 == NULL);
+ if (!strike1) {
+ return false;
+ }
EXPECT_EQ(strike1->IndexSubTableArrayOffset(), STRIKE1_ARRAY_OFFSET);
EXPECT_EQ(strike1->NumberOfIndexSubTables(), STRIKE1_NUM_INDEX_TABLES);
EXPECT_EQ(strike1->ColorRef(), STRIKE1_COLOR_REF);
diff --git a/cpp/src/test/byte_array_test.cc b/cpp/src/test/byte_array_test.cc
index 40a6489..de50089 100644
--- a/cpp/src/test/byte_array_test.cc
+++ b/cpp/src/test/byte_array_test.cc
@@ -28,7 +28,7 @@ const int32_t BYTE_ARRAY_SIZES[] =
void FillTestByteArray(ByteArray* ba, int32_t size) {
for (int32_t i = 0; i < size; ++i) {
- ba->Put(i, (byte_t)(i % 256));
+ ba->Put(i, (uint8_t)(i % 256));
}
}
diff --git a/cpp/src/test/endian_test.cc b/cpp/src/test/endian_test.cc
index 0d9da09..80cce68 100644
--- a/cpp/src/test/endian_test.cc
+++ b/cpp/src/test/endian_test.cc
@@ -25,7 +25,7 @@
namespace sfntly {
bool TestEndian() {
- byte_t test_data[] = {
+ uint8_t test_data[] = {
0x68, 0x65, 0x61, 0x64, // 0: head
0xca, 0xca, 0xca, 0xca, // 4: ubyte, byte, char
0x00, 0x18, 0x80, 0x18, // 8: ushort, short
diff --git a/cpp/src/test/font_data_test.cc b/cpp/src/test/font_data_test.cc
index 4b0db64..5ed041c 100644
--- a/cpp/src/test/font_data_test.cc
+++ b/cpp/src/test/font_data_test.cc
@@ -136,14 +136,14 @@ bool TestReadableFontDataSearching() {
void FillTestByteArray(ByteArray* ba, int32_t size) {
for (int32_t i = 0; i < size; ++i) {
- ba->Put(i, (byte_t)(i % 256));
+ ba->Put(i, (uint8_t)(i % 256));
}
}
void ReadFontDataWithSingleByte(ReadableFontData* rfd, ByteVector* buffer) {
buffer->resize(rfd->Length());
for (int32_t index = 0; index < rfd->Length(); ++index) {
- (*buffer)[index] = (byte_t)(rfd->ReadByte(index));
+ (*buffer)[index] = (uint8_t)(rfd->ReadByte(index));
}
}
@@ -178,7 +178,7 @@ void ReadFontDataWithSlidingWindow(ReadableFontData* rfd, int32_t window_size,
void WriteFontDataWithSingleByte(ReadableFontData* rfd, WritableFontData* wfd) {
for (int32_t index = 0; index < rfd->Length(); ++index) {
- byte_t b = (byte_t)(rfd->ReadByte(index));
+ uint8_t b = (uint8_t)(rfd->ReadByte(index));
wfd->WriteByte(index, b);
}
}
diff --git a/cpp/src/test/open_type_data_test.cc b/cpp/src/test/open_type_data_test.cc
index 0917aab..5d73e84 100644
--- a/cpp/src/test/open_type_data_test.cc
+++ b/cpp/src/test/open_type_data_test.cc
@@ -20,12 +20,12 @@
namespace sfntly {
-const byte_t TEST_OTF_DATA[] =
+const uint8_t TEST_OTF_DATA[] =
{0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
bool TestOTFRead() {
ByteVector bytes;
- for (size_t i = 0; i < sizeof(TEST_OTF_DATA) / sizeof(byte_t); ++i) {
+ for (size_t i = 0; i < sizeof(TEST_OTF_DATA) / sizeof(uint8_t); ++i) {
bytes.push_back(TEST_OTF_DATA[i]);
}
ByteArrayPtr array = new MemoryByteArray(&(bytes[0]), bytes.size());
@@ -45,7 +45,7 @@ bool TestOTFRead() {
bool TestOTFCopy() {
ByteVector source_bytes(1024);
for (size_t i = 0; i < source_bytes.size(); ++i) {
- source_bytes[i] = (byte_t)(i & 0xff);
+ source_bytes[i] = (uint8_t)(i & 0xff);
}
ByteArrayPtr source_array = new MemoryByteArray(&(source_bytes[0]), 1024);
ReadableFontDataPtr source = new ReadableFontData(source_array);
diff --git a/cpp/src/test/otf_basic_editing_test.cc b/cpp/src/test/otf_basic_editing_test.cc
index 7388fac..04c8778 100644
--- a/cpp/src/test/otf_basic_editing_test.cc
+++ b/cpp/src/test/otf_basic_editing_test.cc
@@ -33,30 +33,41 @@ bool TestOTFBasicEditing() {
factory.Attach(FontFactory::GetInstance());
FontBuilderArray font_builder_array;
BuilderForFontFile(SAMPLE_TTF_FILE, factory, &font_builder_array);
+ if (font_builder_array.size() != 1) {
+ EXPECT_TRUE(false);
+ return false;
+ }
FontBuilderPtr font_builder = font_builder_array[0];
// ensure the builder is not bogus
- EXPECT_TRUE(font_builder != NULL);
+ if (!font_builder) {
+ EXPECT_TRUE(false);
+ return false;
+ }
TableBuilderMap* builder_map = font_builder->table_builders();
- EXPECT_TRUE(builder_map != NULL);
+ if (!builder_map) {
+ EXPECT_TRUE(false);
+ return false;
+ }
IntegerSet builder_tags;
for (TableBuilderMap::iterator i = builder_map->begin(),
e = builder_map->end(); i != e; ++i) {
- EXPECT_TRUE(i->second != NULL);
- if (i->second == NULL) {
+ if (!i->second) {
+ EXPECT_TRUE(false);
char tag[5] = {0};
int32_t value = ToBE32(i->first);
memcpy(tag, &value, 4);
fprintf(stderr, "tag %s does not have valid builder\n", tag);
- } else {
- builder_tags.insert(i->first);
+ continue;
}
+ builder_tags.insert(i->first);
}
FontHeaderTableBuilderPtr header_builder =
down_cast<FontHeaderTable::Builder*>(
font_builder->GetTableBuilder(Tag::head));
int64_t mod_date = header_builder->Modified();
+ EXPECT_EQ(3397043097, mod_date);
header_builder->SetModified(mod_date + 1);
FontPtr font;
font.Attach(font_builder->Build());
@@ -65,10 +76,10 @@ bool TestOTFBasicEditing() {
const TableMap* table_map = font->GetTableMap();
for (TableMap::const_iterator i = table_map->begin(), e = table_map->end();
i != e; ++i) {
- TablePtr table = (*i).second;
+ TablePtr table = i->second;
HeaderPtr header = table->header();
- EXPECT_TRUE(builder_tags.find(header->tag()) != builder_tags.end());
- builder_tags.erase(header->tag());
+ size_t erased = builder_tags.erase(header->tag());
+ EXPECT_EQ(1U, erased);
}
EXPECT_TRUE(builder_tags.empty());
@@ -79,7 +90,7 @@ bool TestOTFBasicEditing() {
// Checksum correctness of builder.
TablePtr post = font->GetTable(Tag::post);
- EXPECT_EQ(post->CalculatedChecksum(), TTF_CHECKSUM[SAMPLE_TTF_POST]);
+ EXPECT_EQ(TTF_CHECKSUM[SAMPLE_TTF_POST], post->CalculatedChecksum());
return true;
}
diff --git a/cpp/src/test/test_utils_test.cc b/cpp/src/test/test_utils_test.cc
index 9afc03c..fbd5ed1 100644
--- a/cpp/src/test/test_utils_test.cc
+++ b/cpp/src/test/test_utils_test.cc
@@ -40,7 +40,7 @@ bool TestEncoding() {
for (i = 0; i < 7; ++i) {
int32_t encoded = TestUtils::EncodeOneChar(conv, (int16_t)from[i]);
for (; encoded; encoded <<= 8) {
- byte_t b = (encoded & 0xff000000) >> 24;
+ uint8_t b = (encoded & 0xff000000) >> 24;
if (!b)
continue;
EXPECT_EQ(want[j], b);
diff --git a/cpp/src/test/verify_hhea.cc b/cpp/src/test/verify_hhea.cc
index 81ddb58..1e1001c 100644
--- a/cpp/src/test/verify_hhea.cc
+++ b/cpp/src/test/verify_hhea.cc
@@ -24,7 +24,7 @@ namespace sfntly {
const int32_t HHEA_ASCENDER = 2023;
const int32_t HHEA_DESCENDER = -648;
-const int32_t HHEA_LINE_GAP = 93;
+// const int32_t HHEA_LINE_GAP = 93;
const int32_t HHEA_ADVANCE_WIDTH_MAX = 2753;
const int32_t HHEA_MIN_LSB = -968;
const int32_t HHEA_MIN_RSB = -411;
diff --git a/cpp/src/test/verify_maxp.cc b/cpp/src/test/verify_maxp.cc
index dcd776e..074042a 100644
--- a/cpp/src/test/verify_maxp.cc
+++ b/cpp/src/test/verify_maxp.cc
@@ -31,7 +31,7 @@ const int32_t MAXP_MAX_ZONES = 2;
const int32_t MAXP_MAX_TWILIGHT_POINTS = 0;
const int32_t MAXP_MAX_STORAGE = 1;
const int32_t MAXP_MAX_FUNCTION_DEFS = 1;
-const int32_t MAXP_MAX_INSTR_DEFS = 0;
+// const int32_t MAXP_MAX_INSTR_DEFS = 0;
const int32_t MAXP_MAX_STACK_ELEMENTS = 64;
const int32_t MAXP_MAX_INSTR_SIZE = 46;
const int32_t MAXP_MAX_COMPONENT_ELEMENTS = 4;
diff --git a/cpp/src/test/verify_os2.cc b/cpp/src/test/verify_os2.cc
index 4897e87..c80c58a 100644
--- a/cpp/src/test/verify_os2.cc
+++ b/cpp/src/test/verify_os2.cc
@@ -37,12 +37,12 @@ const int32_t OS2_YSUPS_YOFFSET = 1;
const int32_t OS2_YSTRIKEOUT_SIZE = 12312;
const int32_t OS2_YSTRIKEOUT_POS = -16224;
const int32_t OS2_SFAMILY_CLASS = 0;
-const byte_t OS2_PANOSE[] = { 2, 11, 6, 3, 6, 1, 0, 0, 0, 0 };
+const uint8_t OS2_PANOSE[] = { 2, 11, 6, 3, 6, 1, 0, 0, 0, 0 };
const int64_t OS2_UL_UNICODE_RANGE1 = 0xE00002FFL;
const int64_t OS2_UL_UNICODE_RANGE2 = 0x520020FBL;
const int64_t OS2_UL_UNICODE_RANGE3 = 0L;
const int64_t OS2_UL_UNICODE_RANGE4 = 0L;
-const byte_t OS2_ACH_VEND_ID[] = { 'P', 'f', 'E', 'd' };
+const uint8_t OS2_ACH_VEND_ID[] = { 'P', 'f', 'E', 'd' };
const int32_t OS2_FS_SELECTION = 0x0040;
const int32_t OS2_US_FIRST_CHAR_IDX = 0x0020;
const int32_t OS2_US_LAST_CHAR_IDX = 0xFFFF;
diff --git a/doc/MicroTypeExpress.md b/doc/MicroTypeExpress.md
new file mode 100644
index 0000000..97f55d0
--- /dev/null
+++ b/doc/MicroTypeExpress.md
@@ -0,0 +1,42 @@
+# MicroType Express in sfntly
+
+This page describes sfntly’s implementation of MicroType Express
+compression.
+
+The MicroType Express format is [documented](http://www.w3.org/Submission/MTX/),
+and is recently available under license terms we believe are friendly to
+open source (as well as proprietary) implementation. The most popular
+implementation of a decoder is Internet Explorer, as a compression
+option in its Embedded OpenType (EOT) format. Since MicroType Express
+gives an approximate 15% gain in compression over gzip, a web font
+service striving for maximum performance can benefit from implementing
+EOT compression.
+
+The current codebase in sfntly is for compression only (this is by far
+the most useful for web serving). The easiest way to get started is with
+the command line tool, sfnttool:
+
+```
+sfnttool -e -x source.ttf source.eot
+```
+
+The code has been tested extensively against IE, and is currently in
+production in Google Web Fonts, both for full fonts and for subsetting
+(using the text= parameter). This serving path also uses sfntly to
+compute the subsets, and is essentially the same as the -s parameter to
+sfnttool.
+
+If you’re interested in the code and details of the compression
+algorithm, here’s a bit of a guide:
+
+The top-level MicroType Express compression code is in MtxWriter.java
+(in the tools/conversion/eot directory). This code implements almost all
+of the MicroType Express format, including the hdmx tables, push
+sequences, and jump coding. The main feature missing is the VDMX table
+(vertical device metrics), which is very rarely used in web fonts.
+
+Patches are welcome -- possible areas include: implementing the VDMX
+table, speeding up the LZCOMP entropy coder (the match finding code is a
+straightforward adaptation of the algorithm in the format document),
+implementing a decoder in addition to an encoder, and porting the Java
+implementation to C++.
diff --git a/doc/SfntlyCPlusPlusNotes.md b/doc/SfntlyCPlusPlusNotes.md
new file mode 100644
index 0000000..0a55f85
--- /dev/null
+++ b/doc/SfntlyCPlusPlusNotes.md
@@ -0,0 +1,164 @@
+Introduction
+===============================================================
+
+This document will as the C++ port matures serve as a log to how
+different parts of the library work. As of today, there is some general
+info but mostly CMap specific details.
+
+------------------------------------------------------------------------
+
+Font Data Tables
+===========================================================================
+
+One of the important goals in `sfntly` is thread safety which is why
+tables can only be created with their nested `Builder` class and are
+immutable after creation.
+
+`CMapTable`
+--------------------------------------------------------
+
+*CMap* = character map; it converts *code points* in a *code page* to
+*glyph IDs*.
+
+The CMapTable is a table of CMaps (CMaps are also tables; one for every
+encoding supported by the font). Representing an encoding-dependent
+character map is in one of 14 formats, out of which formats 0 and 4 are
+the most used; sfntly/C++ will initially only support formats 0, 2, 4
+and 12.
+
+### `CMapFormat0` Byte encoding table
+
+Format 0 is a basic table where a character’s glyph ID is looked up in a
+glyphIdArray256. As it only supports 256 characters it can only encode
+ASCII and ISO 8859-x (alphabet-based languages).
+
+### `CMapFormat2` High-byte mapping through table
+
+Chinese, Japanese and Korean (CJK) need special 2 byte encodings for
+each code point like Shift-JIS.
+
+### `CMapFormat4` Segment mapping to delta values
+
+This is the preferred format for Unicode Basic Multilingual Plane (BMP)
+encodings according to the Microsoft spec. Format 4 defines segments
+(contiguous ranges of characters; variable length). Finding a
+character’s glyph id first means finding the segment it is part of using
+a binary search (the segments are sorted). A segment has a
+**`startCode`**, an **`endCode`** (the minimum and maximum code points
+in the segment), an **`idDelta`** (delta for all code points in the
+segment) and an **`idRangeOffset`** (offset into glyphIdArray or 0).
+
+`idDelta` and `idRangeOffset` seem to be the same thing, offsets. In
+fact, `idRangeOffset` uses the glyph array to get the index by relying
+on the fact that the array is immediately after the `idRangeOffset`
+table in the font file. So, the segment’s offset is `idRangeOffset[i]`
+but since the `idRangeOffset` table contains words and not bytes, the
+value is divided by 2.
+
+``` {.prettyprint}
+glyphIndex = *(&idRangeOffset[i] + idRangeOffset[i] / 2 + (c - startCode[i]))
+```
+
+`idDelta[i]` is another kind of segment offset used when
+`idRangeOffset[i] = 0`, in which case it is added directly to the
+character code.
+
+``` {.prettyprint}
+glyphIndex = idDelta[i] + c
+```
+
+### Class Hierarchy
+
+`CMapTable` is the main class and the container for all other CMap
+related classes.
+
+#### Utility classes
+
+- `CMapTable::CMapId` describes a pair of IDs, platform ID and
+ encoding ID that form the CMaps ID. The ID a CMap has is usually a
+ good indicator as to what kind of format the CMap uses (Unicode
+ CMaps are usually either format 4 or format 12).
+- `CMapTable::CMapIdComparator`
+- `CMapTable::CMapIterator` iteration through the CMapTable is
+ supported through a Java-style iterator.
+- `CMapTable::CMapFilter` Java-style filter; CMapIterator supports
+ filtering CMaps. By default, it accepts everything CMap.
+- `CMapTable::CMapIdFilter` extends CMapFilter; only accepts one type
+ of CMap. Used in conjunction with CMapIterator, this is how the CMap
+ getters are implemented.
+- **`CMapTable::Builder`** is the only way to create a CMapTable.
+
+#### CMaps
+
+- **`CMapTable::CMap`** is the abstract base class that all
+ `CMapFormat*` derive. It defines basic functions and the abstract
+ `CMapTable::CMap::CharacterIterator` class to iterate through the
+ characters in the map. The basic implementation just loops through
+ every character between a start and an end. This is overridden so
+ that format specific iteration is performed.
+- `CMapFormat0` (mostly done?)
+- `CMapFormat2` (needs builders)
+- ... coming soon
+
+`[todo: will add images soon; need to upload to svn]`
+
+------------------------------------------------------------------------
+
+# Table Building Pipeline
+
+Building a data table in sfntly is done by the
+`FontDataTable::Builder::build` method which defines the general
+pipeline and leaves the details to each implementing subclass
+(`CMapTable::Builder` for example). Note: **`sub*`** methods are table
+specific
+
+**`ReadableFontDataPtr data = internalReadData()`**
+> There are 2 private fields in the `FontDataTable::Builder` class:
+> `rData` and `wData` for `ReadableFontData` and `WritableFontData`.
+> This function returns `rData` if there is any or `wData` (it is cast
+> to readable font data) if `rData` is null. *They hold the same data!*
+
+**`if (model_changed_)`**
+> A font is essentially a binary blob when loaded inside a `FontData`
+> object. A *model* is the Java/C++ collection of objects that represent
+> the same data in a manipulable format. If you ask for the model (even
+> if you dont write to it), it will count as changed and the underlying
+> raw data will get updated.
+
+**`if (!subReadyToSerialize())`**
+**`return NULL`**
+`else`
+1. **`size = subDataToSerialize()`**
+2. **`WritableDataPtr new_data = container_->getNewData(size)`**
+3. **`subSerialize(new_data)`**
+4. **`data = new_data`**
+
+**`FontDataTablePtr table = subBuildTable(data)`**
+> The table is actually built, where `subBuildTable` is overridden by
+> every class of table but a table header is always added.
+
+Subtable Builders
+------------------------------------------------------------------------------
+
+Subtables are lazily built
+
+When creating the object view of the font and dealing with lots of
+tables, it would be wasteful to create builders for every subtable there
+is since most users only do fairly high level manipulation of the font.
+Instead, **only the tables at font level are fully built**.
+
+All other subtables have builders that contain valid FontData but the
+object view is not created by default. For the `CMapTable`, this means
+that if you don’t go through the `getCMapBuilders()` method, the CMap
+builders are not initialized. So, the builder map would seem to be empty
+when calling its `size()` method but there are CMaps in the font when
+calling `numCMaps(internalReadFont())`.
+
+------------------------------------------------------------------------
+
+Character encoders
+---------------------------------------------------------------------------------
+
+Sfntly/Java uses a native ICU-based API for encoding characters.
+Sfntly/C++ uses ICU directly. In unit tests we assume text is encoded in
+UTF16. Public APIs will use ICU classes like `UnicodeString`.
diff --git a/doc/Useful_links.md b/doc/Useful_links.md
new file mode 100644
index 0000000..2caa409
--- /dev/null
+++ b/doc/Useful_links.md
@@ -0,0 +1,25 @@
+Wiki
+
+- TrueType
+ [http://en.wikipedia.org/wiki/TrueType](http://en.wikipedia.org/wiki/TrueType)
+- OpenType
+ [http://en.wikipedia.org/wiki/OpenType](http://en.wikipedia.org/wiki/OpenType)
+
+Microsoft Typography
+[http://www.microsoft.com/typography/default.mspx](http://www.microsoft.com/typography/default.mspx)
+
+- Font specifications
+ [http://www.microsoft.com/typography/SpecificationsOverview.mspx](http://www.microsoft.com/typography/SpecificationsOverview.mspx),
+ including OpenType and TrueType.
+- Font Tools
+ [http://www.microsoft.com/typography/tools/tools.aspx](http://www.microsoft.com/typography/tools/tools.aspx)
+
+Apple
+
+- TrueType reference manual
+ [http://developer.apple.com/fonts/TTRefMan](http://developer.apple.com/fonts/TTRefMan)
+
+Adobe
+
+- OpenType
+ [http://www.adobe.com/type/opentype/](http://www.adobe.com/type/opentype/)
diff --git a/doc/build_cpp.md b/doc/build_cpp.md
new file mode 100644
index 0000000..5e3d344
--- /dev/null
+++ b/doc/build_cpp.md
@@ -0,0 +1,150 @@
+# How to build sfntly C++ port
+
+## Build Environment Requirements
+
+* cmake 2.6 or above
+* C++ compiler requirement
+ * Windows: Visual C++ 2008, Visual C++ 2010
+ * Linux: g++ 4.3 or above.
+ g++ must support built-in atomic ops and has companion libstd++.
+ * Mac: Apple XCode 3.2.5 or above.
+
+## External Dependencies
+
+sfntly is dependent on several external packages.
+
+* [Google C++ Testing Framework](https://github.com/google/googletest)
+
+ You can download the package yourself or extract the one from `ext/redist`.
+ The package needs to be extracted to ext and rename/symbolic link to `gtest`.
+
+ sfntly C++ port had been tested with gTest 1.6.0.
+
+* ICU
+
+ For Linux, default ICU headers in system will be used.
+ Linux users please make sure you have dev packages for ICU.
+ For example, you can run `sudo apt-get install libicu-dev` in Ubuntu and see if the required library is installed.
+
+ For Windows, download from http://site.icu-project.org/download or extract the one from `ext/redist`.
+ You can also provide your own ICU package.
+ However, you need to alter the include path, library path, and provide `icudt.dll`.
+
+ Tested with ICU 4.6.1 binary release.
+
+ For Mac users, please download ICU source tarball from http://site.icu-project.org/download
+ and install according to ICU documents.
+
+## Getting the Source
+
+Clone the Git repository from https://github.com/googlei18n/sfntly.
+
+## Building on Windows
+
+Let's assume your folder for sfntly is `d:\src\sfntly`.
+
+1. If you don't have cmake installed, extract the cmake-XXX.zip
+ into `d:\src\sfntly\cpp\ext\cmake` removing the "-XXX" part.
+ The extracted binary should be in `d:\src\sfntly\cpp\ext\cmake\bin\cmake.exe`.
+2. Extract gtest-XXX.zip into `d:\src\sfntly\cpp\ext\gtest`
+ removing the "-XXX" part.
+3. Extract icu4c-XXX.zip into `d:\src\sfntly\cpp\ext\icu`
+ removing the "-XXX" part.
+4. Run the following commands to create the Visual Studio solution files:
+
+ ```
+ d:
+ cd d:\src\sfntly\cpp
+ md build
+ cd build
+ ..\ext\cmake\bin\cmake ..
+ ```
+
+You should see `sfntly.sln` in `d:\src\sfntly\cpp\build`.
+
+5. Until the test is modified to access the fonts in the `ext\data` directory:
+ copy the test fonts from `d:\src\sfntly\cpp\data\ext\` to `d:\src\sfntly\cpp\build\bin\Debug`.
+6. Open sfntly.sln.
+ Since sfntly use STL extensively, please patch your Visual Studio for any STL-related hotfixes/service packs.
+7. Build the solution (if the icuuc dll is not found,
+ you may need to add `d:\src\sfntly\cpp\ext\icu\bin` to the system path).
+
+### Building on Windows via Command Line
+
+Visual Studio 2008 and 2010 support command line building,
+therefore you dont need the IDE to build the project.
+
+For Visual Studio 2008 (assume its installed at `c:\vs08`)
+
+ cd d:\src\sfntly\cpp\build
+ ..\ext\cmake\bin\cmake .. -G "Visual Studio 9 2008"
+ c:\vs08\common7\tools\vsvars32.bat
+ vcbuild sfntly.sln
+
+We invoke the cmake with `-G` to make sure
+Visual Studio 2008 solution/project files are generated.
+You can also use `devenv sfntly.sln /build`
+to build the solution instead of using `vcbuild`.
+
+There are subtle differences between `devenv` and `vcbuild`.
+Please refer to your Visual Studio manual for more details.
+
+For Visual Studio 2010 (assume its installed at `c:\vs10`)
+
+
+ cd d:\src\sfntly\cpp\build
+ ..\ext\cmake\bin\cmake .. -G "Visual Studio 10"
+ c:\vs10\common7\tools\vsvars32.bat
+ msbuild sfntly.sln
+
+If you install both Visual Studio 2008 and 2010 on your system,
+you cant run the scripts above in the same Command Prompt window.
+`vsvars32.bat` assumes that it is run from a clean Command Prompt.
+
+## Building on Linux/Mac
+
+### Recommended Out-of-Source Building
+
+1. `cd` *&lt;sfntly dir&gt;*
+2. `mkdir build`
+3. `cd build`
+4. `cmake ..`
+5. `make`
+
+### Default In-Source Building
+
+> This is not recommended.
+> Please use out-of-source whenever possible.
+
+1. `cd` *&lt;sfntly dir&gt;*
+2. `cmake .`
+3. `make`
+
+### Using clang Instead
+
+Change the `cmake` command line to
+
+ CC=clang CXX=clang++ cmake ..
+
+The generated Makefile will use clang.
+Please note that sfntly uses a lot of advanced C++ semantics that
+might not be understood or compiled correctly by earlier versions
+of clang (2.8 and before).
+
+sfntly is tested to compile and run correctly on clang 3.0 (trunk 135314).
+clang 2.9 might work but unfortunately we dont have the resource to test it.
+
+### Debug and Release Builds
+
+Currently Debug builds are set as default.
+To build Release builds, you can either modify the `CMakeList.txt`,
+or set environment variable `CMAKE_BUILD_TYPE` to `Release`
+before invoking `cmake`.
+
+Windows users can just switch the configuration in Visual Studio.
+
+## Running Unit Test
+
+A program named `unit_test` will be generated after a full compilation.
+It expects fonts in `data/ext` to be in the same directory it resides to execute the unit tests.
+Windows users also needs to copy `icudt.dll` and `icuuc.dll` to that directory.
diff --git a/doc/smart_pointer_usage.md b/doc/smart_pointer_usage.md
new file mode 100644
index 0000000..5f77013
--- /dev/null
+++ b/doc/smart_pointer_usage.md
@@ -0,0 +1,145 @@
+Usage of smart pointers in sfntly C++ port
+=========================================================================================================================================================
+
+In sfntly C++ port, an object ref-counting and smart pointer mechanism
+is implemented. The implementation works very much like COM.
+
+Ref-countable object type inherits from RefCounted&lt;&gt;, which have
+addRef() and release() just like IUnknown in COM (but no
+QueryInterface). Ptr&lt;&gt; is a smart pointer class like
+CComPtr&lt;&gt; which is used to hold the ref-countable objects so that
+the object ref count is handled correctly.
+
+Lets take a look at the example:
+
+``` {.prettyprint}
+class Foo : public RefCounted<Foo> {
+ public:
+ static Foo* CreateInstance() {
+ Ptr<Foo> obj = new Foo(); // ref count = 1
+ return obj.detach(); // Giving away the control of this instance.
+ }
+};
+typedef Ptr<Foo> FooPtr; // Common short-hand notation.
+
+FooPtr obj;
+obj.attach(Foo::CreateInstance()); // ref count = 1
+ // Take over control but not bumping
+ // ref count.
+{
+ FooPtr obj2 = obj; // ref count = 2
+ // Assignment bumps up ref count.
+} // ref count = 1
+ // obj2 out of scope, decrements ref count
+
+obj.release(); // ref count = 0, object destroyed
+```
+
+Notes on usage
+---------------------------------------------------------------------
+
+- Virtual inherit from RefCount interface in base class if smart
+ pointers are going to be defined.
+
+<!-- -->
+
+- All RefCounted objects must be instantiated on the heap. Allocating
+ the object on stack will cause crash.
+
+<!-- -->
+
+- Be careful when you have complex inheritance. For example,
+
+> In this case the smart pointer is pretty dumb and dont count on it to
+> nicely destroy your objects as designed. Try refactor your code like
+>
+> ``` {.prettyprint}
+> 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
+> ```
+
+- Smart pointers here are very bad candidates for function parameters
+ and return values. Use dumb pointers when passing over the stack.
+
+<!-- -->
+
+- 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.
+
+<!-- -->
+
+- Idioms for heap object as return value
+
+> If you are not passing that object back, you are the end of scope.
+
+> Be very careful when using the assignment operator as opposed to
+> attaching. This can easily cause memory leaks. Have a look at [The
+> difference between assignment and attachment with ATL smart
+> pointers](http://blogs.msdn.com/b/oldnewthing/archive/2009/11/20/9925918.aspx).
+> Since were using essentially the same model, it applies in pretty much
+> the same way. The easiest way of knowing when to Attach and when to
+> assign is to check the declaration of the function you are using.
+>
+> ``` {.prettyprint}
+> // Attach to the pointer returned by GetInstance
+> static CALLER_ATTACH FontFactory* GetInstance();
+>
+> // Assign pointer returned by NewCMapBuilder
+> CMap::Builder* NewCMapBuilder(const CMapId& cmap_id,
+> ReadableFontData* data);
+> ```
+
+Detecting Memory Leak
+------------------------------------------------------------------------------------------
+
+> The implementation of COM-like ref-counting and smart pointer remedies
+> the lack of garbage collector in C++ to certain extent, however, it
+> also introduces other problems. The most common one is memory leakage.
+> How do we know that our code leak memory or not?
+
+- For Linux/Mac, valgrind
+ [http://valgrind.org](http://valgrind.org/)
+ is very useful.
+- For Windows, the easiest is to use Visual C++ built-in CRT debugging
+ [http://msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.80).aspx](http://msdn.microsoft.com/en-us/library/x98tx3cf(v=vs.80).aspx)
+
+Useful Tips for Debugging Ref-Couting Issue
+------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+- Define `ENABLE_OBJECT_COUNTER` and `REF_COUNT_DEBUGGING`. All
+ ref-count related activity will be ouput to stderr.
+
+<!-- -->
+
+- The logs will look like (under VC2010)
+
+> Use your favorite editor to transform them into SQL statements, e.g.
+> Regex pattern
+>
+> ``` {.prettyprint}
+> ^([ACDR]) class RefCounted<class sfntly::([A-Za-z0-9:]+)>[ *const]+:oc=([-0-9]+),oid=([0-9]+),rc=([-0-9]+)
+> ```
+
+> Replace to
+>
+> ``` {.prettyprint}
+> insert into log values(\1, \2, \3, \4, \5);
+> ```
+
+- Add one line to the beginning of log
+
+<!-- -->
+
+- Run sqlite shell, use .read to input the SQL file.
+
+<!-- -->
+
+- Run following commands to get the leaking object class and object
+ id:
+
+<!-- -->
+
+- Once you know which object is leaking, its much easier to setup
+ conditional breakpoints to identify the real culprit.
diff --git a/doc/unit_tests.md b/doc/unit_tests.md
new file mode 100644
index 0000000..0426979
--- /dev/null
+++ b/doc/unit_tests.md
@@ -0,0 +1,32 @@
+[]{#Unit_Test}Unit Test[](#Unit_Test){.section_anchor}
+======================================================
+
+sfntly C++ port uses Google testing framework for unit testing.
+
+All test cases are under src/test.
+
+To run the unit test, you need to compile sfntly first, then copy
+Tuffy.ttf from data/ext to the folder that unit\_test(.exe) is located.
+Run the unit\_test.
+
+If you are only interested in one test case, for example, you are
+working on name table and only wants name editing test, you can use the
+gtest\_filter flag in command line.
+
+``` {.prettyprint}
+unit_test --gtest_filter=NameEditing.*
+```
+
+For more info regarding running a subset of gtest, please see [GTest
+Advanced
+Guide](http://code.google.com/p/googletest/wiki/V1_6_AdvancedGuide).
+
+Its strongly suggested to run unit\_tests with valgrind. The following
+example shows a typical test command
+
+``` {.prettyprint}
+valgrind --leak-check=full -v ./unit_test --gtest_filter=*.*-FontData.*
+```
+
+FontData tests are the longest and you may want to bypass them during
+development. They shall be run in bots, however.