summaryrefslogtreecommitdiff
path: root/chromium/third_party/sfntly
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
committerZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
commit679147eead574d186ebf3069647b4c23e8ccace6 (patch)
treefc247a0ac8ff119f7c8550879ebb6d3dd8d1ff69 /chromium/third_party/sfntly
downloadqtwebengine-chromium-679147eead574d186ebf3069647b4c23e8ccace6.tar.gz
Initial import.
Diffstat (limited to 'chromium/third_party/sfntly')
-rw-r--r--chromium/third_party/sfntly/COPYING.txt203
-rw-r--r--chromium/third_party/sfntly/OWNERS2
-rw-r--r--chromium/third_party/sfntly/README.chromium20
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/chromium/chrome_subsetter.cc131
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/chromium/font_subsetter.cc39
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/chromium/font_subsetter.h51
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/chromium/subsetter_impl.cc785
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/chromium/subsetter_impl.h74
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subsetter/main.cc44
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subsetter/subset_util.cc98
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subsetter/subset_util.h32
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/character_predicate.cc53
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/character_predicate.h68
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/debug_main.cc64
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/font_assembler.cc227
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/font_assembler.h67
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/font_info.cc256
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/font_info.h128
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/merger.cc87
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/merger.h45
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/merger_main.cc69
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/stats.cc82
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/stats.h40
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/subsetter.cc67
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/subsetter.h41
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/subsetter_main.cc82
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/utils.cc91
-rw-r--r--chromium/third_party/sfntly/cpp/src/sample/subtly/utils.h38
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/byte_array.cc199
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/byte_array.h201
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/font_data.cc82
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/font_data.h135
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/font_input_stream.cc141
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/font_input_stream.h97
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/font_output_stream.cc130
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/font_output_stream.h79
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/growable_memory_byte_array.cc82
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/growable_memory_byte_array.h66
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/memory_byte_array.cc93
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/memory_byte_array.h81
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/readable_font_data.cc336
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/readable_font_data.h308
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/writable_font_data.cc201
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/data/writable_font_data.h211
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/font.cc557
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/font.h352
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/font_factory.cc214
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/font_factory.h140
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/math/fixed1616.h41
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/math/font_math.h49
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/atomic.h71
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/config.h28
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/endian.h77
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/exception_type.h125
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/file_input_stream.cc169
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/file_input_stream.h57
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/input_stream.h49
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/java_iterator.h94
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/lock.cc72
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/lock.h76
-rwxr-xr-xchromium/third_party/sfntly/cpp/src/sfntly/port/memory_input_stream.cc147
-rwxr-xr-xchromium/third_party/sfntly/cpp/src/sfntly/port/memory_input_stream.h57
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/memory_output_stream.cc72
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/memory_output_stream.h51
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/output_stream.h46
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/refcount.h277
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/port/type.h102
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc171
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/big_glyph_metrics.h96
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph.cc101
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph.h119
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph_info.cc68
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph_info.h85
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_size_table.cc604
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_size_table.h173
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/composite_bitmap_glyph.cc109
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/composite_bitmap_glyph.h75
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebdt_table.cc236
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebdt_table.h108
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/eblc_table.cc313
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/eblc_table.h194
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebsc_table.cc107
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebsc_table.h101
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/glyph_metrics.cc39
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/glyph_metrics.h43
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table.cc278
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table.h178
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc302
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format1.h116
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format2.cc275
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format2.h106
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc298
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format3.h113
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format4.cc384
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format4.h135
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc347
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format5.h118
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/simple_bitmap_glyph.cc45
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/simple_bitmap_glyph.h44
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc126
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/small_glyph_metrics.h79
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/byte_array_table_builder.cc70
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/byte_array_table_builder.h53
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/cmap_table.cc1287
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/cmap_table.h709
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/font_header_table.cc265
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/font_header_table.h168
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_device_metrics_table.cc124
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_device_metrics_table.h82
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_header_table.cc213
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_header_table.h111
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_metrics_table.cc138
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_metrics_table.h87
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/maximum_profile_table.cc240
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/maximum_profile_table.h120
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/name_table.cc723
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/name_table.h743
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/os2_table.cc608
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/core/os2_table.h508
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/font_data_table.cc193
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/font_data_table.h123
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/generic_table_builder.cc49
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/generic_table_builder.h42
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/header.cc66
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/header.h114
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/subtable.cc64
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/subtable.h73
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/subtable_container_table.h48
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/table.cc162
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/table.h119
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/table_based_table_builder.cc69
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/table_based_table_builder.h48
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/glyph_table.cc679
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/glyph_table.h334
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/loca_table.cc246
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/loca_table.h183
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/tag.cc110
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/tag.h123
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.cc90
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.h37
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/subsetter.cc102
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/subsetter.h72
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/table_subsetter.h39
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.cc38
-rw-r--r--chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.h37
-rw-r--r--chromium/third_party/sfntly/sfntly.gyp142
146 files changed, 23686 insertions, 0 deletions
diff --git a/chromium/third_party/sfntly/COPYING.txt b/chromium/third_party/sfntly/COPYING.txt
new file mode 100644
index 00000000000..c61423cfed5
--- /dev/null
+++ b/chromium/third_party/sfntly/COPYING.txt
@@ -0,0 +1,203 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2011 Google Inc. All Rights Reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
diff --git a/chromium/third_party/sfntly/OWNERS b/chromium/third_party/sfntly/OWNERS
new file mode 100644
index 00000000000..2fc1686a18d
--- /dev/null
+++ b/chromium/third_party/sfntly/OWNERS
@@ -0,0 +1,2 @@
+arthurhsu@chromium.org
+vandebo@chromium.org
diff --git a/chromium/third_party/sfntly/README.chromium b/chromium/third_party/sfntly/README.chromium
new file mode 100644
index 00000000000..d351bd55a37
--- /dev/null
+++ b/chromium/third_party/sfntly/README.chromium
@@ -0,0 +1,20 @@
+Name: sfntly
+URL: http://code.google.com/p/sfntly/
+Version: unknown
+Revision: 111
+Security Critical: yes
+License: Apache 2.0
+License File: COPYING.txt
+
+Description:
+sfntly is a C++ library for using, editing, and creating sfnt container based
+fonts (e.g. OpenType, TrueType). We use it to subset the embedded font in the
+PDF generated in print preview so that the result PDF documents are
+significantly smaller and loaded faster.
+
+Local files (not taken from upstream):
+README.chromium
+src/subsetter/*
+
+COPYING.txt is the license file copied from upstream.
+A sfntly.gyp file has been added for building with Chromium.
diff --git a/chromium/third_party/sfntly/cpp/src/sample/chromium/chrome_subsetter.cc b/chromium/third_party/sfntly/cpp/src/sample/chromium/chrome_subsetter.cc
new file mode 100644
index 00000000000..df15c182b7e
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/chromium/chrome_subsetter.cc
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+
+#include <vector>
+#include <string>
+#include <sstream>
+
+#include "sfntly/port/type.h"
+#include "font_subsetter.h"
+
+template <typename T>
+class HexTo {
+ public:
+ explicit HexTo(const char* in) {
+ std::stringstream ss;
+ ss << std::hex << in;
+ ss >> value_;
+ }
+ operator T() const { return value_; }
+
+ private:
+ T value_;
+};
+
+bool LoadFile(const char* input_file_path, sfntly::ByteVector* input_buffer) {
+ assert(input_file_path);
+ assert(input_buffer);
+
+ FILE* input_file = NULL;
+#if defined WIN32
+ fopen_s(&input_file, input_file_path, "rb");
+#else
+ input_file = fopen(input_file_path, "rb");
+#endif
+ if (input_file == NULL) {
+ return false;
+ }
+ fseek(input_file, 0, SEEK_END);
+ size_t file_size = ftell(input_file);
+ fseek(input_file, 0, SEEK_SET);
+ input_buffer->resize(file_size);
+ size_t bytes_read = fread(&((*input_buffer)[0]), 1, file_size, input_file);
+ fclose(input_file);
+ return bytes_read == file_size;
+}
+
+bool SaveFile(const char* output_file_path, const unsigned char* output_buffer,
+ int buffer_length) {
+ int byte_count = 0;
+ if (buffer_length > 0) {
+ FILE* output_file = NULL;
+#if defined WIN32
+ fopen_s(&output_file, output_file_path, "wb");
+#else
+ output_file = fopen(output_file_path, "wb");
+#endif
+ if (output_file) {
+ byte_count = fwrite(output_buffer, 1, buffer_length, output_file);
+ fflush(output_file);
+ fclose(output_file);
+ }
+ return buffer_length == byte_count;
+ }
+ return false;
+}
+
+bool StringToGlyphId(const char* input, std::vector<unsigned int>* glyph_ids) {
+ assert(input);
+ std::string hex_csv = input;
+ size_t start = 0;
+ size_t end = hex_csv.find_first_of(",");
+ while (end != std::string::npos) {
+ glyph_ids->push_back(
+ HexTo<unsigned int>(hex_csv.substr(start, end - start).c_str()));
+ start = end + 1;
+ end = hex_csv.find_first_of(",", start);
+ }
+ glyph_ids->push_back(HexTo<unsigned int>(hex_csv.substr(start).c_str()));
+ return glyph_ids->size() > 0;
+}
+
+int main(int argc, char** argv) {
+ if (argc < 5) {
+ fprintf(stderr,
+ "Usage: %s <input path> <output path> <font name> <glyph ids>\n",
+ argv[0]);
+ fprintf(stderr, "\tGlyph ids are comma separated hex values\n");
+ fprintf(stderr, "\te.g. 20,1a,3b,4f\n");
+ return 0;
+ }
+
+ sfntly::ByteVector input_buffer;
+ if (!LoadFile(argv[1], &input_buffer)) {
+ fprintf(stderr, "ERROR: unable to load font file %s\n", argv[1]);
+ return 0;
+ }
+
+ std::vector<unsigned int> glyph_ids;
+ if (!StringToGlyphId(argv[4], &glyph_ids)) {
+ fprintf(stderr, "ERROR: unable to parse input glyph id\n");
+ return 0;
+ }
+
+ unsigned char* output_buffer = NULL;
+ int output_length =
+ SfntlyWrapper::SubsetFont(argv[3],
+ &(input_buffer[0]),
+ input_buffer.size(),
+ &(glyph_ids[0]),
+ glyph_ids.size(),
+ &output_buffer);
+
+ int result = SaveFile(argv[2], output_buffer, output_length) ? 1 : 0;
+ delete[] output_buffer;
+ return result;
+}
diff --git a/chromium/third_party/sfntly/cpp/src/sample/chromium/font_subsetter.cc b/chromium/third_party/sfntly/cpp/src/sample/chromium/font_subsetter.cc
new file mode 100644
index 00000000000..14f5494920b
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/chromium/font_subsetter.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "font_subsetter.h"
+
+#include "subsetter_impl.h"
+
+int SfntlyWrapper::SubsetFont(const char* font_name,
+ const unsigned char* original_font,
+ size_t font_size,
+ const unsigned int* glyph_ids,
+ size_t glyph_count,
+ unsigned char** output_buffer) {
+ if (output_buffer == NULL ||
+ original_font == NULL || font_size == 0 ||
+ glyph_ids == NULL || glyph_count == 0) {
+ return 0;
+ }
+
+ sfntly::SubsetterImpl subsetter;
+ if (!subsetter.LoadFont(font_name, original_font, font_size)) {
+ return -1; // Load error or font not found.
+ }
+
+ return subsetter.SubsetFont(glyph_ids, glyph_count, output_buffer);
+}
diff --git a/chromium/third_party/sfntly/cpp/src/sample/chromium/font_subsetter.h b/chromium/third_party/sfntly/cpp/src/sample/chromium/font_subsetter.h
new file mode 100644
index 00000000000..07b1b5b0fa9
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/chromium/font_subsetter.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// File is originally from Chromium third_party/sfntly/src/subsetter.
+// Use as test case in sfntly so that problems can be caught in upstream early.
+#ifndef SFNTLY_CPP_SRC_TEST_FONT_SUBSETTER_H_
+#define SFNTLY_CPP_SRC_TEST_FONT_SUBSETTER_H_
+
+#include <cstddef>
+
+class SfntlyWrapper {
+ public:
+
+ // Font subsetting API
+ //
+ // Input TTF/TTC/OTF fonts, specify the glyph IDs to subset, and the subset
+ // font is returned in |output_buffer| (caller to delete[]). Return value is
+ // the length of output_buffer allocated.
+ //
+ // If subsetting fails, a negative value is returned. If none of the glyph
+ // IDs specified is found, the function will return 0.
+ //
+ // |font_name| Font name, required for TTC files. If specified NULL,
+ // the first available font is selected.
+ // |original_font| Original font file contents.
+ // |font_size| Size of |original_font| in bytes.
+ // |glyph_ids| Glyph IDs to subset. If the specified glyph ID is not
+ // found in the font file, it will be ignored silently.
+ // |glyph_count| Number of glyph IDs in |glyph_ids|
+ // |output_buffer| Generated subset font. Caller to delete[].
+ static int SubsetFont(const char* font_name,
+ const unsigned char* original_font,
+ size_t font_size,
+ const unsigned int* glyph_ids,
+ size_t glyph_count,
+ unsigned char** output_buffer);
+};
+
+#endif // SFNTLY_CPP_SRC_TEST_FONT_SUBSETTER_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sample/chromium/subsetter_impl.cc b/chromium/third_party/sfntly/cpp/src/sample/chromium/subsetter_impl.cc
new file mode 100644
index 00000000000..528e33612af
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/chromium/subsetter_impl.cc
@@ -0,0 +1,785 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "subsetter_impl.h"
+
+#include <string.h>
+
+#include <algorithm>
+#include <iterator>
+#include <map>
+#include <set>
+
+#include "sfntly/table/bitmap/eblc_table.h"
+#include "sfntly/table/bitmap/ebdt_table.h"
+#include "sfntly/table/bitmap/index_sub_table.h"
+#include "sfntly/table/bitmap/index_sub_table_format1.h"
+#include "sfntly/table/bitmap/index_sub_table_format2.h"
+#include "sfntly/table/bitmap/index_sub_table_format3.h"
+#include "sfntly/table/bitmap/index_sub_table_format4.h"
+#include "sfntly/table/bitmap/index_sub_table_format5.h"
+#include "sfntly/table/core/name_table.h"
+#include "sfntly/tag.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/port/memory_input_stream.h"
+#include "sfntly/port/memory_output_stream.h"
+
+#if defined U_USING_ICU_NAMESPACE
+ U_NAMESPACE_USE
+#endif
+
+namespace {
+
+using namespace sfntly;
+
+// The bitmap tables must be greater than 16KB to trigger bitmap subsetter.
+static const int BITMAP_SIZE_THRESHOLD = 16384;
+
+void ConstructName(UChar* name_part, UnicodeString* name, int32_t name_id) {
+ switch (name_id) {
+ case NameId::kFullFontName:
+ *name = name_part;
+ break;
+ case NameId::kFontFamilyName:
+ case NameId::kPreferredFamily:
+ case NameId::kWWSFamilyName: {
+ UnicodeString original = *name;
+ *name = name_part;
+ *name += original;
+ break;
+ }
+ case NameId::kFontSubfamilyName:
+ case NameId::kPreferredSubfamily:
+ case NameId::kWWSSubfamilyName:
+ *name += name_part;
+ break;
+ default:
+ // This name part is not used to construct font name (e.g. copyright).
+ // Simply ignore it.
+ break;
+ }
+}
+
+int32_t HashCode(int32_t platform_id, int32_t encoding_id, int32_t language_id,
+ int32_t name_id) {
+ int32_t result = platform_id << 24 | encoding_id << 16 | language_id << 8;
+ if (name_id == NameId::kFullFontName) {
+ result |= 0xff;
+ } else if (name_id == NameId::kPreferredFamily ||
+ name_id == NameId::kPreferredSubfamily) {
+ result |= 0xf;
+ } else if (name_id == NameId::kWWSFamilyName ||
+ name_id == NameId::kWWSSubfamilyName) {
+ result |= 1;
+ }
+ return result;
+}
+
+bool HasName(const char* font_name, Font* font) {
+ UnicodeString font_string = UnicodeString::fromUTF8(font_name);
+ if (font_string.isEmpty())
+ return false;
+ UnicodeString regular_suffix = UnicodeString::fromUTF8(" Regular");
+ UnicodeString alt_font_string = font_string;
+ alt_font_string += regular_suffix;
+
+ typedef std::map<int32_t, UnicodeString> NameMap;
+ NameMap names;
+ NameTablePtr name_table = down_cast<NameTable*>(font->GetTable(Tag::name));
+ if (name_table == NULL) {
+ return false;
+ }
+
+ for (int32_t i = 0; i < name_table->NameCount(); ++i) {
+ switch (name_table->NameId(i)) {
+ case NameId::kFontFamilyName:
+ case NameId::kFontSubfamilyName:
+ case NameId::kFullFontName:
+ case NameId::kPreferredFamily:
+ case NameId::kPreferredSubfamily:
+ case NameId::kWWSFamilyName:
+ case NameId::kWWSSubfamilyName: {
+ UChar* name_part = name_table->Name(i);
+ if (name_part == NULL) {
+ continue;
+ }
+ int32_t hash_code = HashCode(name_table->PlatformId(i),
+ name_table->EncodingId(i),
+ name_table->LanguageId(i),
+ name_table->NameId(i));
+ ConstructName(name_part, &(names[hash_code]), name_table->NameId(i));
+ delete[] name_part;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (!names.empty()) {
+ for (NameMap::iterator i = names.begin(), e = names.end(); i != e; ++i) {
+ if (i->second.caseCompare(font_string, 0) == 0 ||
+ i->second.caseCompare(alt_font_string, 0) == 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+Font* FindFont(const char* font_name, const FontArray& font_array) {
+ if (font_array.empty() || font_array[0] == NULL) {
+ return NULL;
+ }
+
+ if (font_name && strlen(font_name)) {
+ for (FontArray::const_iterator i = font_array.begin(), e = font_array.end();
+ i != e; ++i) {
+ if (HasName(font_name, i->p_)) {
+ return i->p_;
+ }
+ }
+ }
+
+ return font_array[0].p_;
+}
+
+bool ResolveCompositeGlyphs(GlyphTable* glyph_table,
+ LocaTable* loca_table,
+ const unsigned int* glyph_ids,
+ size_t glyph_count,
+ IntegerSet* glyph_id_processed) {
+ if (glyph_table == NULL || loca_table == NULL ||
+ glyph_ids == NULL || glyph_count == 0 || glyph_id_processed == NULL) {
+ return false;
+ }
+
+ // Sort and uniquify glyph ids.
+ IntegerSet glyph_id_remaining;
+ glyph_id_remaining.insert(0); // Always include glyph id 0.
+ for (size_t i = 0; i < glyph_count; ++i) {
+ glyph_id_remaining.insert(glyph_ids[i]);
+ }
+
+ // Identify if any given glyph id maps to a composite glyph. If so, include
+ // the glyphs referenced by that composite glyph.
+ while (!glyph_id_remaining.empty()) {
+ IntegerSet comp_glyph_id;
+ for (IntegerSet::iterator i = glyph_id_remaining.begin(),
+ e = glyph_id_remaining.end(); i != e; ++i) {
+ if (*i < 0 || *i >= loca_table->num_glyphs()) {
+ // Invalid glyph id, ignore.
+ continue;
+ }
+
+ int32_t length = loca_table->GlyphLength(*i);
+ if (length == 0) {
+ // Empty glyph, ignore.
+ continue;
+ }
+ int32_t offset = loca_table->GlyphOffset(*i);
+
+ GlyphPtr glyph;
+ glyph.Attach(glyph_table->GetGlyph(offset, length));
+ if (glyph == NULL) {
+ // Error finding glyph, ignore.
+ continue;
+ }
+
+ if (glyph->GlyphType() == GlyphType::kComposite) {
+ Ptr<GlyphTable::CompositeGlyph> comp_glyph =
+ down_cast<GlyphTable::CompositeGlyph*>(glyph.p_);
+ for (int32_t j = 0; j < comp_glyph->NumGlyphs(); ++j) {
+ int32_t glyph_id = comp_glyph->GlyphIndex(j);
+ if (glyph_id_processed->find(glyph_id) == glyph_id_processed->end() &&
+ glyph_id_remaining.find(glyph_id) == glyph_id_remaining.end()) {
+ comp_glyph_id.insert(comp_glyph->GlyphIndex(j));
+ }
+ }
+ }
+
+ glyph_id_processed->insert(*i);
+ }
+
+ glyph_id_remaining.clear();
+ glyph_id_remaining = comp_glyph_id;
+ }
+
+ return true;
+}
+
+bool SetupGlyfBuilders(Font::Builder* font_builder,
+ GlyphTable* glyph_table,
+ LocaTable* loca_table,
+ const IntegerSet& glyph_ids) {
+ if (!font_builder || !glyph_table || !loca_table) {
+ return false;
+ }
+
+ GlyphTableBuilderPtr glyph_table_builder =
+ down_cast<GlyphTable::Builder*>(font_builder->NewTableBuilder(Tag::glyf));
+ LocaTableBuilderPtr loca_table_builder =
+ down_cast<LocaTable::Builder*>(font_builder->NewTableBuilder(Tag::loca));
+ if (glyph_table_builder == NULL || loca_table_builder == NULL) {
+ // Out of memory.
+ return false;
+ }
+
+ // Extract glyphs and setup loca list.
+ IntegerList loca_list;
+ loca_list.resize(loca_table->num_glyphs());
+ loca_list.push_back(0);
+ int32_t last_glyph_id = 0;
+ int32_t last_offset = 0;
+ GlyphTable::GlyphBuilderList* glyph_builders =
+ glyph_table_builder->GlyphBuilders();
+ for (IntegerSet::const_iterator i = glyph_ids.begin(), e = glyph_ids.end();
+ i != e; ++i) {
+ int32_t length = loca_table->GlyphLength(*i);
+ int32_t offset = loca_table->GlyphOffset(*i);
+
+ GlyphPtr glyph;
+ glyph.Attach(glyph_table->GetGlyph(offset, length));
+
+ // Add glyph to new glyf table.
+ ReadableFontDataPtr data = glyph->ReadFontData();
+ WritableFontDataPtr copy_data;
+ copy_data.Attach(WritableFontData::CreateWritableFontData(data->Length()));
+ data->CopyTo(copy_data);
+ GlyphBuilderPtr glyph_builder;
+ glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data));
+ glyph_builders->push_back(glyph_builder);
+
+ // Configure loca list.
+ for (int32_t j = last_glyph_id + 1; j <= *i; ++j) {
+ loca_list[j] = last_offset;
+ }
+ last_offset += length;
+ loca_list[*i + 1] = last_offset;
+ last_glyph_id = *i;
+ }
+ for (int32_t j = last_glyph_id + 1; j <= loca_table->num_glyphs(); ++j) {
+ loca_list[j] = last_offset;
+ }
+ loca_table_builder->SetLocaList(&loca_list);
+
+ return true;
+}
+
+bool HasOverlap(int32_t range_begin, int32_t range_end,
+ const IntegerSet& glyph_ids) {
+ if (range_begin == range_end) {
+ return glyph_ids.find(range_begin) != glyph_ids.end();
+ } 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;
+}
+
+// Initialize builder, returns false if glyph_id subset is not covered.
+// Not thread-safe, caller to ensure object life-time.
+bool InitializeBitmapBuilder(EbdtTable::Builder* ebdt, EblcTable::Builder* eblc,
+ const IntegerSet& glyph_ids) {
+ BitmapLocaList loca_list;
+ BitmapSizeTableBuilderList* strikes = eblc->BitmapSizeBuilders();
+
+ // Note: Do not call eblc_builder->GenerateLocaList(&loca_list) and then
+ // ebdt_builder->SetLoca(loca_list). For fonts like SimSun, there are
+ // >28K glyphs inside, where a typical usage will be <1K glyphs. Doing
+ // the calls improperly will result in creation of >100K objects that
+ // will be destroyed immediately, inducing significant slowness.
+ IntegerList removed_strikes;
+ for (size_t i = 0; i < strikes->size(); i++) {
+ if (!HasOverlap((*strikes)[i]->StartGlyphIndex(),
+ (*strikes)[i]->EndGlyphIndex(), glyph_ids)) {
+ removed_strikes.push_back(i);
+ continue;
+ }
+
+ IndexSubTableBuilderList* index_builders =
+ (*strikes)[i]->IndexSubTableBuilders();
+ IntegerList removed_indexes;
+ BitmapGlyphInfoMap info_map;
+ for (size_t j = 0; j < index_builders->size(); ++j) {
+ if ((*index_builders)[j] == NULL) {
+ // Subtable is malformed, let's just skip it.
+ removed_indexes.push_back(j);
+ continue;
+ }
+ int32_t first_glyph_id = (*index_builders)[j]->first_glyph_index();
+ int32_t last_glyph_id = (*index_builders)[j]->last_glyph_index();
+ if (!HasOverlap(first_glyph_id, last_glyph_id, glyph_ids)) {
+ removed_indexes.push_back(j);
+ continue;
+ }
+ for (IntegerSet::const_iterator gid = glyph_ids.begin(),
+ gid_end = glyph_ids.end();
+ gid != gid_end; gid++) {
+ if (*gid < first_glyph_id) {
+ continue;
+ }
+ if (*gid > last_glyph_id) {
+ break;
+ }
+ BitmapGlyphInfoPtr info;
+ info.Attach((*index_builders)[j]->GlyphInfo(*gid));
+ if (info && info->length()) { // Do not include gid without bitmap
+ info_map[*gid] = info;
+ }
+ }
+ }
+ if (!info_map.empty()) {
+ loca_list.push_back(info_map);
+ } else {
+ removed_strikes.push_back(i); // Detected null entries.
+ }
+
+ // Remove unused index sub tables
+ for (IntegerList::reverse_iterator j = removed_indexes.rbegin(),
+ e = removed_indexes.rend();
+ j != e; j++) {
+ index_builders->erase(index_builders->begin() + *j);
+ }
+ }
+ if (removed_strikes.size() == strikes->size() || loca_list.empty()) {
+ return false;
+ }
+
+ for (IntegerList::reverse_iterator i = removed_strikes.rbegin(),
+ e = removed_strikes.rend(); i != e; i++) {
+ strikes->erase(strikes->begin() + *i);
+ }
+
+ if (strikes->empty()) { // no glyph covered, can safely drop the builders.
+ return false;
+ }
+
+ ebdt->SetLoca(&loca_list);
+ ebdt->GlyphBuilders(); // Initialize the builder.
+ return true;
+}
+
+void CopyBigGlyphMetrics(BigGlyphMetrics::Builder* source,
+ BigGlyphMetrics::Builder* target) {
+ target->SetHeight(static_cast<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()));
+}
+
+CALLER_ATTACH IndexSubTable::Builder*
+ConstructIndexFormat4(IndexSubTable::Builder* b, const BitmapGlyphInfoMap& loca,
+ int32_t* image_data_offset) {
+ IndexSubTableFormat4BuilderPtr builder4;
+ builder4.Attach(IndexSubTableFormat4::Builder::CreateBuilder());
+ CodeOffsetPairBuilderList offset_pairs;
+
+ size_t offset = 0;
+ int32_t lower_bound = b->first_glyph_index();
+ int32_t upper_bound = b->last_glyph_index();
+ int32_t last_gid = -1;
+ BitmapGlyphInfoMap::const_iterator i = loca.lower_bound(lower_bound);
+ BitmapGlyphInfoMap::const_iterator end = loca.end();
+ if (i != end) {
+ last_gid = i->first;
+ builder4->set_first_glyph_index(last_gid);
+ builder4->set_image_format(b->image_format());
+ builder4->set_image_data_offset(*image_data_offset);
+ }
+ for (; i != end; i++) {
+ int32_t gid = i->first;
+ if (gid > upper_bound) {
+ break;
+ }
+ offset_pairs.push_back(
+ IndexSubTableFormat4::CodeOffsetPairBuilder(gid, offset));
+ offset += i->second->length();
+ last_gid = gid;
+ }
+ offset_pairs.push_back(
+ IndexSubTableFormat4::CodeOffsetPairBuilder(-1, offset));
+ builder4->set_last_glyph_index(last_gid);
+ *image_data_offset += offset;
+ builder4->SetOffsetArray(offset_pairs);
+
+ return builder4.Detach();
+}
+
+CALLER_ATTACH IndexSubTable::Builder*
+ConstructIndexFormat5(IndexSubTable::Builder* b, const BitmapGlyphInfoMap& loca,
+ int32_t* image_data_offset) {
+ IndexSubTableFormat5BuilderPtr new_builder;
+ new_builder.Attach(IndexSubTableFormat5::Builder::CreateBuilder());
+
+ // Copy BigMetrics
+ int32_t image_size = 0;
+ if (b->index_format() == IndexSubTable::Format::FORMAT_2) {
+ IndexSubTableFormat2BuilderPtr builder2 =
+ down_cast<IndexSubTableFormat2::Builder*>(b);
+ CopyBigGlyphMetrics(builder2->BigMetrics(), new_builder->BigMetrics());
+ image_size = builder2->ImageSize();
+ } else {
+ IndexSubTableFormat5BuilderPtr builder5 =
+ down_cast<IndexSubTableFormat5::Builder*>(b);
+ BigGlyphMetricsBuilderPtr metrics_builder;
+ CopyBigGlyphMetrics(builder5->BigMetrics(), new_builder->BigMetrics());
+ image_size = builder5->ImageSize();
+ }
+
+ IntegerList* glyph_array = new_builder->GlyphArray();
+ size_t offset = 0;
+ int32_t lower_bound = b->first_glyph_index();
+ int32_t upper_bound = b->last_glyph_index();
+ int32_t last_gid = -1;
+ BitmapGlyphInfoMap::const_iterator i = loca.lower_bound(lower_bound);
+ BitmapGlyphInfoMap::const_iterator end = loca.end();
+ if (i != end) {
+ last_gid = i->first;
+ new_builder->set_first_glyph_index(last_gid);
+ new_builder->set_image_format(b->image_format());
+ new_builder->set_image_data_offset(*image_data_offset);
+ new_builder->SetImageSize(image_size);
+ }
+ for (; i != end; i++) {
+ int32_t gid = i->first;
+ if (gid > upper_bound) {
+ break;
+ }
+ glyph_array->push_back(gid);
+ offset += i->second->length();
+ last_gid = gid;
+ }
+ new_builder->set_last_glyph_index(last_gid);
+ *image_data_offset += offset;
+ return new_builder.Detach();
+}
+
+CALLER_ATTACH IndexSubTable::Builder*
+SubsetIndexSubTable(IndexSubTable::Builder* builder,
+ const BitmapGlyphInfoMap& loca,
+ int32_t* image_data_offset) {
+ switch (builder->index_format()) {
+ case IndexSubTable::Format::FORMAT_1:
+ case IndexSubTable::Format::FORMAT_3:
+ case IndexSubTable::Format::FORMAT_4:
+ return ConstructIndexFormat4(builder, loca, image_data_offset);
+ case IndexSubTable::Format::FORMAT_2:
+ case IndexSubTable::Format::FORMAT_5:
+ return ConstructIndexFormat5(builder, loca, image_data_offset);
+ default:
+ assert(false);
+ break;
+ }
+ return NULL;
+}
+
+}
+
+namespace sfntly {
+
+// Not thread-safe, caller to ensure object life-time.
+void SubsetEBLC(EblcTable::Builder* eblc, const BitmapLocaList& new_loca) {
+ BitmapSizeTableBuilderList* size_builders = eblc->BitmapSizeBuilders();
+ if (size_builders == NULL) {
+ return;
+ }
+
+ int32_t image_data_offset = EbdtTable::Offset::kHeaderLength;
+ for (size_t strike = 0; strike < size_builders->size(); ++strike) {
+ IndexSubTableBuilderList* index_builders =
+ (*size_builders)[strike]->IndexSubTableBuilders();
+ for (size_t index = 0; index < index_builders->size(); ++index) {
+ IndexSubTable::Builder* new_builder_raw =
+ SubsetIndexSubTable((*index_builders)[index], new_loca[strike],
+ &image_data_offset);
+ if (NULL != new_builder_raw) {
+ (*index_builders)[index].Attach(new_builder_raw);
+ }
+ }
+ }
+}
+
+// EBLC structure (from stuartg)
+// header
+// bitmapSizeTable[]
+// one per strike
+// holds strike metrics - sbitLineMetrics
+// holds info about indexSubTableArray
+// indexSubTableArray[][]
+// one per strike and then one per indexSubTable for that strike
+// holds info about the indexSubTable
+// the indexSubTable entries pointed to can be of different formats
+// indexSubTable
+// one per indexSubTableArray entry
+// tells how to get the glyphs
+// may hold the glyph metrics if they are uniform for all the glyphs in range
+// Please note that the structure can also be
+// {indexSubTableArray[], indexSubTables[]}[]
+// This way is also legal and in fact how Microsoft fonts are laid out.
+//
+// There is nothing that says that the indexSubTableArray entries and/or the
+// indexSubTable items need to be unique. They may be shared between strikes.
+//
+// EBDT structure:
+// header
+// glyphs
+// amorphous blob of data
+// different glyphs that are only able to be figured out from the EBLC table
+// may hold metrics - depends on the EBLC entry that pointed to them
+
+// Subsetting EBLC table (from arthurhsu)
+// Most pages use only a fraction (hundreds or less) glyphs out of a given font
+// (which can have >20K glyphs for CJK). It's safe to assume that the subset
+// font will have sparse bitmap glyphs. So we reconstruct the EBLC table as
+// format 4 or 5 here.
+
+enum BuildersToRemove {
+ kRemoveNone,
+ kRemoveBDAT,
+ kRemoveBDATAndEBDT,
+ kRemoveEBDT
+};
+
+int SetupBitmapBuilders(Font* font, Font::Builder* font_builder,
+ const IntegerSet& glyph_ids) {
+ if (!font || !font_builder) {
+ return false;
+ }
+
+ // Check if bitmap table exists.
+ EbdtTablePtr ebdt_table = down_cast<EbdtTable*>(font->GetTable(Tag::EBDT));
+ EblcTablePtr eblc_table = down_cast<EblcTable*>(font->GetTable(Tag::EBLC));
+ bool use_ebdt = (ebdt_table != NULL && eblc_table != NULL);
+ if (!use_ebdt) {
+ ebdt_table = down_cast<EbdtTable*>(font->GetTable(Tag::bdat));
+ eblc_table = down_cast<EblcTable*>(font->GetTable(Tag::bloc));
+ if (ebdt_table == NULL || eblc_table == NULL) {
+ return kRemoveNone;
+ }
+ }
+
+ // If the bitmap table's size is too small, skip subsetting.
+ if (ebdt_table->DataLength() + eblc_table->DataLength() <
+ BITMAP_SIZE_THRESHOLD) {
+ return use_ebdt ? kRemoveBDAT : kRemoveNone;
+ }
+
+ // Get the builders.
+ EbdtTableBuilderPtr ebdt_table_builder = down_cast<EbdtTable::Builder*>(
+ font_builder->NewTableBuilder(use_ebdt ? Tag::EBDT : Tag::bdat,
+ ebdt_table->ReadFontData()));
+ EblcTableBuilderPtr eblc_table_builder = down_cast<EblcTable::Builder*>(
+ font_builder->NewTableBuilder(use_ebdt ? Tag::EBLC : Tag::bloc,
+ eblc_table->ReadFontData()));
+ if (ebdt_table_builder == NULL || eblc_table_builder == NULL) {
+ // Out of memory.
+ return use_ebdt ? kRemoveBDAT : kRemoveNone;
+ }
+
+ if (!InitializeBitmapBuilder(ebdt_table_builder, eblc_table_builder,
+ glyph_ids)) {
+ // Bitmap tables do not cover the glyphs in our subset.
+ font_builder->RemoveTableBuilder(use_ebdt ? Tag::EBLC : Tag::bloc);
+ font_builder->RemoveTableBuilder(use_ebdt ? Tag::EBDT : Tag::bdat);
+ return use_ebdt ? kRemoveBDATAndEBDT : kRemoveEBDT;
+ }
+
+ BitmapLocaList new_loca;
+ ebdt_table_builder->GenerateLocaList(&new_loca);
+ SubsetEBLC(eblc_table_builder, new_loca);
+
+ return use_ebdt ? kRemoveBDAT : kRemoveNone;
+}
+
+SubsetterImpl::SubsetterImpl() {
+}
+
+SubsetterImpl::~SubsetterImpl() {
+}
+
+bool SubsetterImpl::LoadFont(const char* font_name,
+ const unsigned char* original_font,
+ size_t font_size) {
+ MemoryInputStream mis;
+ mis.Attach(original_font, font_size);
+ if (factory_ == NULL) {
+ factory_.Attach(FontFactory::GetInstance());
+ }
+
+ FontArray font_array;
+ factory_->LoadFonts(&mis, &font_array);
+ font_ = FindFont(font_name, font_array);
+ if (font_ == NULL) {
+ return false;
+ }
+
+ return true;
+}
+
+int SubsetterImpl::SubsetFont(const unsigned int* glyph_ids,
+ size_t glyph_count,
+ unsigned char** output_buffer) {
+ if (factory_ == NULL || font_ == NULL) {
+ return -1;
+ }
+
+ // Find glyf and loca table.
+ GlyphTablePtr glyph_table =
+ down_cast<GlyphTable*>(font_->GetTable(Tag::glyf));
+ LocaTablePtr loca_table = down_cast<LocaTable*>(font_->GetTable(Tag::loca));
+ if (glyph_table == NULL || loca_table == NULL) {
+ // We are not able to subset the font.
+ return 0;
+ }
+
+ IntegerSet glyph_id_processed;
+ if (!ResolveCompositeGlyphs(glyph_table, loca_table,
+ glyph_ids, glyph_count, &glyph_id_processed) ||
+ glyph_id_processed.empty()) {
+ return 0;
+ }
+
+ FontPtr new_font;
+ new_font.Attach(Subset(glyph_id_processed, glyph_table, loca_table));
+ if (new_font == NULL) {
+ return 0;
+ }
+
+ MemoryOutputStream output_stream;
+ factory_->SerializeFont(new_font, &output_stream);
+ int length = static_cast<int>(output_stream.Size());
+ if (length > 0) {
+ *output_buffer = new unsigned char[length];
+ memcpy(*output_buffer, output_stream.Get(), length);
+ }
+
+ return length;
+}
+
+// Long comments regarding TTF tables and PDF (from stuartg)
+//
+// According to PDF spec 1.4 (section 5.8), the following tables must be
+// present:
+// head, hhea, loca, maxp, cvt, prep, glyf, hmtx, fpgm
+// cmap if font is used with a simple font dict and not a CIDFont dict
+//
+// Other tables we need to keep for PDF rendering to support zoom in/out:
+// bdat, bloc, ebdt, eblc, ebsc, gasp
+//
+// Special table:
+// CFF - if you have this table then you shouldn't have a glyf table and this
+// is the table with all the glyphs. Shall skip subsetting completely
+// since sfntly is not capable of subsetting it for now.
+// post - extra info here for printing on PostScript printers but maybe not
+// enough to outweigh the space taken by the names
+//
+// Tables to break apart:
+// name - could throw away all but one language and one platform strings/ might
+// throw away some of the name entries
+// cmap - could strip out non-needed cmap subtables
+// - format 4 subtable can be subsetted as well using sfntly
+//
+// Graphite tables:
+// silf, glat, gloc, feat - should be okay to strip out
+//
+// Tables that can be discarded:
+// OS/2 - everything here is for layout and description of the font that is
+// elsewhere (some in the PDF objects)
+// BASE, GDEF, GSUB, GPOS, JSTF - all used for layout
+// kern - old style layout
+// DSIG - this will be invalid after subsetting
+// hdmx - layout
+// PCLT - metadata that's not needed
+// vmtx - layout
+// vhea - layout
+// VDMX
+// VORG - not used by TT/OT - used by CFF
+// hsty - would be surprised to see one of these - used on the Newton
+// AAT tables - mort, morx, feat, acnt, bsin, just, lcar, fdsc, fmtx, prop,
+// Zapf, opbd, trak, fvar, gvar, avar, cvar
+// - these are all layout tables and once layout happens are not
+// needed anymore
+// LTSH - layout
+
+CALLER_ATTACH
+Font* SubsetterImpl::Subset(const IntegerSet& glyph_ids, GlyphTable* glyf,
+ LocaTable* loca) {
+ // The const is initialized here to workaround VC bug of rendering all Tag::*
+ // as 0. These tags represents the TTF tables that we will embed in subset
+ // font.
+ const int32_t TABLES_IN_SUBSET[] = {
+ Tag::head, Tag::hhea, Tag::loca, Tag::maxp, Tag::cvt,
+ Tag::prep, Tag::glyf, Tag::hmtx, Tag::fpgm, Tag::EBDT,
+ Tag::EBLC, Tag::EBSC, Tag::bdat, Tag::bloc, Tag::bhed,
+ Tag::cmap, // Keep here for future tagged PDF development.
+ Tag::name, // Keep here due to legal concerns: copyright info inside.
+ };
+
+ // Setup font builders we need.
+ FontBuilderPtr font_builder;
+ font_builder.Attach(factory_->NewFontBuilder());
+ IntegerSet remove_tags;
+
+ if (SetupGlyfBuilders(font_builder, glyf, loca, glyph_ids)) {
+ remove_tags.insert(Tag::glyf);
+ remove_tags.insert(Tag::loca);
+ }
+
+ // For old Apple bitmap fonts, they have only bdats and bhed is identical
+ // to head. As a result, we can't remove bdat tables for those fonts.
+ int setup_result = SetupBitmapBuilders(font_, font_builder, glyph_ids);
+ if (setup_result == kRemoveBDATAndEBDT || setup_result == kRemoveEBDT) {
+ remove_tags.insert(Tag::EBDT);
+ remove_tags.insert(Tag::EBLC);
+ remove_tags.insert(Tag::EBSC);
+ }
+
+ if (setup_result == kRemoveBDAT || setup_result == kRemoveBDATAndEBDT) {
+ remove_tags.insert(Tag::bdat);
+ remove_tags.insert(Tag::bloc);
+ remove_tags.insert(Tag::bhed);
+ }
+
+ IntegerSet allowed_tags;
+ for (size_t i = 0; i < sizeof(TABLES_IN_SUBSET) / sizeof(int32_t); ++i) {
+ allowed_tags.insert(TABLES_IN_SUBSET[i]);
+ }
+
+ IntegerSet result;
+ std::set_difference(allowed_tags.begin(), allowed_tags.end(),
+ remove_tags.begin(), remove_tags.end(),
+ std::inserter(result, result.end()));
+ allowed_tags = result;
+
+ // Setup remaining builders.
+ for (IntegerSet::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());
+ }
+ }
+
+ return font_builder->Build();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sample/chromium/subsetter_impl.h b/chromium/third_party/sfntly/cpp/src/sample/chromium/subsetter_impl.h
new file mode 100644
index 00000000000..ffbf408f9c7
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/chromium/subsetter_impl.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// File is originally from Chromium third_party/sfntly/src/subsetter.
+// Use as test case in sfntly so that problems can be caught in upstream early.
+
+#ifndef SFNTLY_CPP_SRC_TEST_SUBSETTER_IMPL_H_
+#define SFNTLY_CPP_SRC_TEST_SUBSETTER_IMPL_H_
+
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+#include "sfntly/tag.h"
+
+namespace sfntly {
+
+// Smart pointer usage in sfntly:
+//
+// sfntly carries a smart pointer implementation like COM. Ref-countable object
+// type inherits from RefCounted<>, which have AddRef and Release just like
+// IUnknown (but no QueryInterface). Use a Ptr<> based smart pointer to hold
+// the object so that the object ref count is handled correctly.
+//
+// class Foo : public RefCounted<Foo> {
+// public:
+// static Foo* CreateInstance() {
+// Ptr<Foo> obj = new Foo(); // ref count = 1
+// return obj.detach();
+// }
+// };
+// typedef Ptr<Foo> FooPtr; // common short-hand notation
+// FooPtr obj;
+// obj.attach(Foo::CreatedInstance()); // ref count = 1
+// {
+// FooPtr obj2 = obj; // ref count = 2
+// } // ref count = 1, obj2 out of scope
+// obj.release(); // ref count = 0, object destroyed
+
+class SubsetterImpl {
+ public:
+ SubsetterImpl();
+ ~SubsetterImpl();
+
+ bool LoadFont(const char* font_name,
+ const unsigned char* original_font,
+ size_t font_size);
+ int SubsetFont(const unsigned int* glyph_ids,
+ size_t glyph_count,
+ unsigned char** output_buffer);
+
+ private:
+ CALLER_ATTACH Font* Subset(const IntegerSet& glyph_ids,
+ GlyphTable* glyf, LocaTable* loca);
+
+ FontFactoryPtr factory_;
+ FontPtr font_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_TEST_SUBSETTER_IMPL_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subsetter/main.cc b/chromium/third_party/sfntly/cpp/src/sample/subsetter/main.cc
new file mode 100644
index 00000000000..19a3e0e23f2
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subsetter/main.cc
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#if _MSC_VER > 12
+ #define _CRTDBG_MAP_ALLOC
+ #include <stdlib.h>
+ #include <crtdbg.h>
+#endif
+
+#include "sample/subsetter/subset_util.h"
+
+int main(int argc, char** argv) {
+#ifdef _CRTDBG_MAP_ALLOC
+ _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+
+ if (argc < 3) {
+ printf("Usage: subsetter <font file> <output file>\n");
+ return 0;
+ }
+
+ sfntly::SubsetUtil subset_util;
+ subset_util.Subset(argv[1], argv[2]);
+
+#ifdef _CRTDBG_MAP_ALLOC
+ _CrtDumpMemoryLeaks();
+#endif
+
+ return 0;
+}
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subsetter/subset_util.cc b/chromium/third_party/sfntly/cpp/src/sample/subsetter/subset_util.cc
new file mode 100644
index 00000000000..f35eb25cd61
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subsetter/subset_util.cc
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Remove VC++ nag on fopen.
+#define _CRT_SECURE_NO_WARNINGS
+
+#include "sample/subsetter/subset_util.h"
+
+#include <stdio.h>
+
+#include <vector>
+#include <memory>
+
+#include "sfntly/font.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/port/memory_output_stream.h"
+#include "sfntly/port/type.h"
+#include "sfntly/tag.h"
+#include "sfntly/tools/subsetter/subsetter.h"
+
+namespace sfntly {
+
+SubsetUtil::SubsetUtil() {
+}
+
+SubsetUtil::~SubsetUtil() {
+}
+
+void SubsetUtil::Subset(const char *input_file_path,
+ const char *output_file_path) {
+ UNREFERENCED_PARAMETER(output_file_path);
+ ByteVector input_buffer;
+ FILE* input_file = fopen(input_file_path, "rb");
+ if (input_file == NULL) {
+ fprintf(stderr, "file not found\n");
+ return;
+ }
+ fseek(input_file, 0, SEEK_END);
+ size_t file_size = ftell(input_file);
+ fseek(input_file, 0, SEEK_SET);
+ input_buffer.resize(file_size);
+ size_t bytes_read = fread(&(input_buffer[0]), 1, file_size, input_file);
+ UNREFERENCED_PARAMETER(bytes_read);
+ fclose(input_file);
+
+ FontFactoryPtr factory;
+ factory.Attach(FontFactory::GetInstance());
+
+ FontArray font_array;
+ factory->LoadFonts(&input_buffer, &font_array);
+ if (font_array.empty() || font_array[0] == NULL)
+ return;
+
+ IntegerList glyphs;
+ for (int32_t i = 0; i < 10; i++) {
+ glyphs.push_back(i);
+ }
+ glyphs.push_back(11);
+ glyphs.push_back(10);
+
+ Ptr<Subsetter> subsetter = new Subsetter(font_array[0], factory);
+ subsetter->SetGlyphs(&glyphs);
+ IntegerSet remove_tables;
+ remove_tables.insert(Tag::DSIG);
+ subsetter->SetRemoveTables(&remove_tables);
+
+ FontBuilderPtr font_builder;
+ font_builder.Attach(subsetter->Subset());
+
+ FontPtr new_font;
+ new_font.Attach(font_builder->Build());
+
+ // TODO(arthurhsu): glyph renumbering/Loca table
+ // TODO(arthurhsu): alter CMaps
+
+ MemoryOutputStream output_stream;
+ factory->SerializeFont(new_font, &output_stream);
+
+ FILE* output_file = fopen(output_file_path, "wb");
+ fwrite(output_stream.Get(), 1, output_stream.Size(), output_file);
+ fflush(output_file);
+ fclose(output_file);
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subsetter/subset_util.h b/chromium/third_party/sfntly/cpp/src/sample/subsetter/subset_util.h
new file mode 100644
index 00000000000..5eb4fe4169d
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subsetter/subset_util.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SAMPLE_SUBSETTER_SUBSET_UTIL_H_
+#define SFNTLY_CPP_SRC_SAMPLE_SUBSETTER_SUBSET_UTIL_H_
+
+namespace sfntly {
+
+class SubsetUtil {
+ public:
+ SubsetUtil();
+ virtual ~SubsetUtil();
+
+ void Subset(const char* input_file_path, const char* output_file_path);
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SAMPLE_SUBSETTER_SUBSET_UTIL_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/character_predicate.cc b/chromium/third_party/sfntly/cpp/src/sample/subtly/character_predicate.cc
new file mode 100644
index 00000000000..b9c6cc787b4
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/character_predicate.cc
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/port/refcount.h"
+#include "subtly/character_predicate.h"
+
+namespace subtly {
+using namespace sfntly;
+
+// AcceptRange predicate
+AcceptRange::AcceptRange(int32_t start, int32_t end)
+ : start_(start),
+ end_(end) {
+}
+
+AcceptRange::~AcceptRange() {}
+
+bool AcceptRange::operator()(int32_t character) const {
+ return start_ <= character && character <= end_;
+}
+
+// AcceptSet predicate
+AcceptSet::AcceptSet(IntegerSet* characters)
+ : characters_(characters) {
+}
+
+AcceptSet::~AcceptSet() {
+ delete characters_;
+}
+
+bool AcceptSet::operator()(int32_t character) const {
+ return characters_->find(character) != characters_->end();
+}
+
+// AcceptAll predicate
+bool AcceptAll::operator()(int32_t character) const {
+ UNREFERENCED_PARAMETER(character);
+ return true;
+}
+}
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/character_predicate.h b/chromium/third_party/sfntly/cpp/src/sample/subtly/character_predicate.h
new file mode 100644
index 00000000000..a6e3ea360e2
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/character_predicate.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_CHARACTER_PREDICATE_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_CHARACTER_PREDICATE_H_
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/port/type.h"
+
+namespace subtly {
+class CharacterPredicate : virtual public sfntly::RefCount {
+ public:
+ CharacterPredicate() {}
+ virtual ~CharacterPredicate() {}
+ virtual bool operator()(int32_t character) const = 0;
+};
+
+// All characters except for those between [start, end] are rejected
+class AcceptRange : public CharacterPredicate,
+ public sfntly::RefCounted<AcceptRange> {
+ public:
+ AcceptRange(int32_t start, int32_t end);
+ ~AcceptRange();
+ virtual bool operator()(int32_t character) const;
+
+ private:
+ int32_t start_;
+ int32_t end_;
+};
+
+// All characters in IntegerSet
+// The set is OWNED by the predicate! Do not modify it.
+// It will be freed when the predicate is destroyed.
+class AcceptSet : public CharacterPredicate,
+ public sfntly::RefCounted<AcceptSet> {
+ public:
+ explicit AcceptSet(sfntly::IntegerSet* characters);
+ ~AcceptSet();
+ virtual bool operator()(int32_t character) const;
+
+ private:
+ sfntly::IntegerSet* characters_;
+};
+
+// All characters
+class AcceptAll : public CharacterPredicate,
+ public sfntly::RefCounted<AcceptAll> {
+ public:
+ AcceptAll() {}
+ ~AcceptAll() {}
+ virtual bool operator()(int32_t character) const;
+};
+}
+
+#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_CHARACTER_PREDICATE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/debug_main.cc b/chromium/third_party/sfntly/cpp/src/sample/subtly/debug_main.cc
new file mode 100644
index 00000000000..8324cde45c2
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/debug_main.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <map>
+#include <utility>
+
+#include "sfntly/font.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/tag.h"
+#include "subtly/stats.h"
+#include "subtly/subsetter.h"
+#include "subtly/utils.h"
+
+using namespace subtly;
+
+void PrintUsage(const char* program_name) {
+ fprintf(stdout, "Usage: %s <input_font_file>\n", program_name);
+}
+
+int main(int argc, const char** argv) {
+ const char* program_name = argv[0];
+ if (argc < 2) {
+ PrintUsage(program_name);
+ exit(1);
+ }
+
+ const char* input_font_path = argv[1];
+ const char* output_font_path = argv[2];
+ FontPtr font;
+ font.Attach(subtly::LoadFont(input_font_path));
+
+ int32_t original_size = TotalFontSize(font);
+ Ptr<Subsetter> subsetter = new Subsetter(font, NULL);
+ Ptr<Font> new_font;
+ new_font.Attach(subsetter->Subset());
+ if (!new_font) {
+ fprintf(stdout, "Cannot create subset.\n");
+ return 0;
+ }
+
+ subtly::SerializeFont(output_font_path, new_font);
+ subtly::PrintComparison(stdout, font, new_font);
+ int32_t new_size = TotalFontSize(new_font);
+ fprintf(stdout, "Went from %d to %d: %lf%% of original\n",
+ original_size, new_size,
+ static_cast<double>(new_size) / original_size * 100);
+ return 0;
+}
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/font_assembler.cc b/chromium/third_party/sfntly/cpp/src/sample/subtly/font_assembler.cc
new file mode 100644
index 00000000000..2f7cd110eaf
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/font_assembler.cc
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "subtly/font_assembler.h"
+
+#include <stdio.h>
+
+#include <set>
+#include <map>
+
+#include "sfntly/tag.h"
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/core/maximum_profile_table.h"
+#include "sfntly/port/type.h"
+#include "sfntly/port/refcount.h"
+#include "subtly/font_info.h"
+
+namespace subtly {
+using namespace sfntly;
+
+FontAssembler::FontAssembler(FontInfo* font_info,
+ IntegerSet* table_blacklist)
+ : table_blacklist_(table_blacklist) {
+ font_info_ = font_info;
+ Initialize();
+}
+
+FontAssembler::FontAssembler(FontInfo* font_info)
+ : table_blacklist_(NULL) {
+ font_info_ = font_info;
+ Initialize();
+}
+
+void FontAssembler::Initialize() {
+ font_factory_.Attach(sfntly::FontFactory::GetInstance());
+ font_builder_.Attach(font_factory_->NewFontBuilder());
+}
+
+CALLER_ATTACH Font* FontAssembler::Assemble() {
+ // Assemble tables we can subset.
+ if (!AssembleCMapTable() || !AssembleGlyphAndLocaTables()) {
+ return NULL;
+ }
+ // For all other tables, either include them unmodified or don't at all.
+ const TableMap* common_table_map =
+ font_info_->GetTableMap(font_info_->fonts()->begin()->first);
+ for (TableMap::const_iterator it = common_table_map->begin(),
+ e = common_table_map->end(); it != e; ++it) {
+ if (table_blacklist_
+ && table_blacklist_->find(it->first) != table_blacklist_->end()) {
+ continue;
+ }
+ font_builder_->NewTableBuilder(it->first, it->second->ReadFontData());
+ }
+ return font_builder_->Build();
+}
+
+bool FontAssembler::AssembleCMapTable() {
+ // Creating the new CMapTable and the new format 4 CMap
+ Ptr<CMapTable::Builder> cmap_table_builder =
+ down_cast<CMapTable::Builder*>
+ (font_builder_->NewTableBuilder(Tag::cmap));
+ if (!cmap_table_builder)
+ return false;
+ Ptr<CMapTable::CMapFormat4::Builder> cmap_builder =
+ down_cast<CMapTable::CMapFormat4::Builder*>
+ (cmap_table_builder->NewCMapBuilder(CMapFormat::kFormat4,
+ CMapTable::WINDOWS_BMP));
+ if (!cmap_builder)
+ return false;
+ // Creating the segments and the glyph id array
+ CharacterMap* chars_to_glyph_ids = font_info_->chars_to_glyph_ids();
+ SegmentList* segment_list = new SegmentList;
+ IntegerList* glyph_id_array = new IntegerList;
+ int32_t last_chararacter = -2;
+ int32_t last_offset = 0;
+ Ptr<CMapTable::CMapFormat4::Builder::Segment> current_segment;
+
+ // For simplicity, we will have one segment per contiguous range.
+ // To test the algorithm, we've replaced the original CMap with the CMap
+ // generated by this code without removing any character.
+ // Tuffy.ttf: CMap went from 3146 to 3972 bytes (1.7% to 2.17% of file)
+ // AnonymousPro.ttf: CMap went from 1524 to 1900 bytes (0.96% to 1.2%)
+ for (CharacterMap::iterator it = chars_to_glyph_ids->begin(),
+ e = chars_to_glyph_ids->end(); it != e; ++it) {
+ int32_t character = it->first;
+ int32_t glyph_id = it->second.glyph_id();
+ if (character != last_chararacter + 1) { // new segment
+ if (current_segment != NULL) {
+ current_segment->set_end_count(last_chararacter);
+ segment_list->push_back(current_segment);
+ }
+ // start_code = character
+ // end_code = -1 (unknown for now)
+ // id_delta = 0 (we don't use id_delta for this representation)
+ // id_range_offset = last_offset (offset into the glyph_id_array)
+ current_segment =
+ new CMapTable::CMapFormat4::Builder::
+ Segment(character, -1, 0, last_offset);
+ }
+ glyph_id_array->push_back(glyph_id);
+ last_offset += DataSize::kSHORT;
+ last_chararacter = character;
+ }
+ // The last segment is still open.
+ current_segment->set_end_count(last_chararacter);
+ segment_list->push_back(current_segment);
+ // Updating the id_range_offset for every segment.
+ for (int32_t i = 0, num_segs = segment_list->size(); i < num_segs; ++i) {
+ Ptr<CMapTable::CMapFormat4::Builder::Segment> segment = segment_list->at(i);
+ segment->set_id_range_offset(segment->id_range_offset()
+ + (num_segs - i + 1) * DataSize::kSHORT);
+ }
+ // Adding the final, required segment.
+ current_segment =
+ new CMapTable::CMapFormat4::Builder::Segment(0xffff, 0xffff, 1, 0);
+ segment_list->push_back(current_segment);
+ // Writing the segments and glyph id array to the CMap
+ cmap_builder->set_segments(segment_list);
+ cmap_builder->set_glyph_id_array(glyph_id_array);
+ delete segment_list;
+ delete glyph_id_array;
+ return true;
+}
+
+bool FontAssembler::AssembleGlyphAndLocaTables() {
+ Ptr<LocaTable::Builder> loca_table_builder =
+ down_cast<LocaTable::Builder*>
+ (font_builder_->NewTableBuilder(Tag::loca));
+ Ptr<GlyphTable::Builder> glyph_table_builder =
+ down_cast<GlyphTable::Builder*>
+ (font_builder_->NewTableBuilder(Tag::glyf));
+
+ GlyphIdSet* resolved_glyph_ids = font_info_->resolved_glyph_ids();
+ IntegerList loca_list;
+ // Basic sanity check: all LOCA tables are of the same size
+ // This is necessary but not suficient!
+ int32_t previous_size = -1;
+ for (FontIdMap::iterator it = font_info_->fonts()->begin();
+ it != font_info_->fonts()->end(); ++it) {
+ Ptr<LocaTable> loca_table =
+ down_cast<LocaTable*>(font_info_->GetTable(it->first, Tag::loca));
+ int32_t current_size = loca_table->header_length();
+ if (previous_size != -1 && current_size != previous_size) {
+ return false;
+ }
+ previous_size = current_size;
+ }
+
+ // Assuming all fonts referenced by the FontInfo are the subsets of the same
+ // font, their loca tables should all have the same sizes.
+ // We'll just get the size of the first font's LOCA table for simplicty.
+ Ptr<LocaTable> first_loca_table =
+ down_cast<LocaTable*>
+ (font_info_->GetTable(font_info_->fonts()->begin()->first, Tag::loca));
+ int32_t num_loca_glyphs = first_loca_table->num_glyphs();
+ loca_list.resize(num_loca_glyphs);
+ loca_list.push_back(0);
+ int32_t last_glyph_id = 0;
+ int32_t last_offset = 0;
+ GlyphTable::GlyphBuilderList* glyph_builders =
+ glyph_table_builder->GlyphBuilders();
+
+ for (GlyphIdSet::iterator it = resolved_glyph_ids->begin(),
+ e = resolved_glyph_ids->end(); it != e; ++it) {
+ // Get the glyph for this resolved_glyph_id.
+ int32_t resolved_glyph_id = it->glyph_id();
+ int32_t font_id = it->font_id();
+ // Get the LOCA table for the current glyph id.
+ Ptr<LocaTable> loca_table =
+ down_cast<LocaTable*>
+ (font_info_->GetTable(font_id, Tag::loca));
+ int32_t length = loca_table->GlyphLength(resolved_glyph_id);
+ int32_t offset = loca_table->GlyphOffset(resolved_glyph_id);
+
+ // Get the GLYF table for the current glyph id.
+ Ptr<GlyphTable> glyph_table =
+ down_cast<GlyphTable*>
+ (font_info_->GetTable(font_id, Tag::glyf));
+ GlyphPtr glyph;
+ glyph.Attach(glyph_table->GetGlyph(offset, length));
+
+ // The data reference by the glyph is copied into a new glyph and
+ // added to the glyph_builders belonging to the glyph_table_builder.
+ // When Build gets called, all the glyphs will be built.
+ Ptr<ReadableFontData> data = glyph->ReadFontData();
+ Ptr<WritableFontData> copy_data;
+ copy_data.Attach(WritableFontData::CreateWritableFontData(data->Length()));
+ data->CopyTo(copy_data);
+ GlyphBuilderPtr glyph_builder;
+ glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data));
+ glyph_builders->push_back(glyph_builder);
+
+ // If there are missing glyphs between the last glyph_id and the
+ // current resolved_glyph_id, since the LOCA table needs to have the same
+ // size, the offset is kept the same.
+ for (int32_t i = last_glyph_id + 1; i <= resolved_glyph_id; ++i)
+ loca_list[i] = last_offset;
+ last_offset += length;
+ loca_list[resolved_glyph_id + 1] = last_offset;
+ last_glyph_id = resolved_glyph_id + 1;
+ }
+ // If there are missing glyph ids, their loca entries must all point
+ // to the same offset as the last valid glyph id making them all zero length.
+ for (int32_t i = last_glyph_id + 1; i <= num_loca_glyphs; ++i)
+ loca_list[i] = last_offset;
+ loca_table_builder->SetLocaList(&loca_list);
+ return true;
+}
+}
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/font_assembler.h b/chromium/third_party/sfntly/cpp/src/sample/subtly/font_assembler.h
new file mode 100644
index 00000000000..c53c21fd07b
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/font_assembler.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_ASSEMBLER_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_ASSEMBLER_H_
+
+#include <set>
+#include <map>
+
+#include "subtly/font_info.h"
+
+#include "sfntly/tag.h"
+#include "sfntly/font.h"
+#include "sfntly/port/type.h"
+#include "sfntly/port/refcount.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+
+namespace subtly {
+// Assembles FontInfo into font builders.
+// Does not take ownership of data passed to it.
+class FontAssembler : public sfntly::RefCounted<FontAssembler> {
+ public:
+ // font_info is the FontInfo which will be used for the new font
+ // table_blacklist is used to decide which tables to exclude from the
+ // final font.
+ FontAssembler(FontInfo* font_info, sfntly::IntegerSet* table_blacklist);
+ explicit FontAssembler(FontInfo* font_info);
+ ~FontAssembler() { }
+
+ // Assemble a new font from the font info object.
+ virtual CALLER_ATTACH sfntly::Font* Assemble();
+
+ sfntly::IntegerSet* table_blacklist() const { return table_blacklist_; }
+ void set_table_blacklist(sfntly::IntegerSet* table_blacklist) {
+ table_blacklist_ = table_blacklist;
+ }
+
+ protected:
+ virtual bool AssembleCMapTable();
+ virtual bool AssembleGlyphAndLocaTables();
+
+ virtual void Initialize();
+
+ private:
+ sfntly::Ptr<FontInfo> font_info_;
+ sfntly::Ptr<sfntly::FontFactory> font_factory_;
+ sfntly::Ptr<sfntly::Font::Builder> font_builder_;
+ sfntly::IntegerSet* table_blacklist_;
+};
+}
+
+#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_ASSEMBLER_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/font_info.cc b/chromium/third_party/sfntly/cpp/src/sample/subtly/font_info.cc
new file mode 100644
index 00000000000..6eb6a38070e
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/font_info.cc
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "subtly/font_info.h"
+
+#include <stdio.h>
+
+#include <set>
+#include <map>
+
+#include "subtly/character_predicate.h"
+
+#include "sfntly/tag.h"
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/core/maximum_profile_table.h"
+#include "sfntly/port/type.h"
+#include "sfntly/port/refcount.h"
+
+namespace subtly {
+using namespace sfntly;
+/******************************************************************************
+ * GlyphId class
+ ******************************************************************************/
+GlyphId::GlyphId(int32_t glyph_id, FontId font_id)
+ : glyph_id_(glyph_id),
+ font_id_(font_id) {
+}
+
+bool GlyphId::operator==(const GlyphId& other) const {
+ return glyph_id_ == other.glyph_id();
+}
+
+bool GlyphId::operator<(const GlyphId& other) const {
+ return glyph_id_ < other.glyph_id();
+}
+
+/******************************************************************************
+ * FontInfo class
+ ******************************************************************************/
+FontInfo::FontInfo()
+ : chars_to_glyph_ids_(new CharacterMap),
+ resolved_glyph_ids_(new GlyphIdSet),
+ fonts_(new FontIdMap) {
+}
+
+FontInfo::FontInfo(CharacterMap* chars_to_glyph_ids,
+ GlyphIdSet* resolved_glyph_ids,
+ FontIdMap* fonts) {
+ chars_to_glyph_ids_ = new CharacterMap(chars_to_glyph_ids->begin(),
+ chars_to_glyph_ids->end());
+ resolved_glyph_ids_ = new GlyphIdSet(resolved_glyph_ids->begin(),
+ resolved_glyph_ids->end());
+ fonts_ = new FontIdMap(fonts->begin(), fonts->end());
+}
+
+FontInfo::~FontInfo() {
+ delete chars_to_glyph_ids_;
+ delete resolved_glyph_ids_;
+ delete fonts_;
+}
+
+FontDataTable* FontInfo::GetTable(FontId font_id, int32_t tag) {
+ if (!fonts_)
+ return NULL;
+ FontIdMap::iterator it = fonts_->find(font_id);
+ if (it == fonts_->end())
+ return NULL;
+ return it->second->GetTable(tag);
+}
+
+const TableMap* FontInfo::GetTableMap(FontId font_id) {
+ if (!fonts_)
+ return NULL;
+ FontIdMap::iterator it = fonts_->find(font_id);
+ if (it == fonts_->end())
+ return NULL;
+ return it->second->GetTableMap();
+}
+
+void FontInfo::set_chars_to_glyph_ids(CharacterMap* chars_to_glyph_ids) {
+ *chars_to_glyph_ids_ = *chars_to_glyph_ids;
+}
+
+void FontInfo::set_resolved_glyph_ids(GlyphIdSet* resolved_glyph_ids) {
+ *resolved_glyph_ids_ = *resolved_glyph_ids;
+}
+
+void FontInfo::set_fonts(FontIdMap* fonts) {
+ *fonts_ = *fonts;
+}
+
+/******************************************************************************
+ * FontSourcedInfoBuilder class
+ ******************************************************************************/
+FontSourcedInfoBuilder::FontSourcedInfoBuilder(Font* font, FontId font_id)
+ : font_(font),
+ font_id_(font_id),
+ predicate_(NULL) {
+ Initialize();
+}
+
+FontSourcedInfoBuilder::FontSourcedInfoBuilder(Font* font,
+ FontId font_id,
+ CharacterPredicate* predicate)
+ : font_(font),
+ font_id_(font_id),
+ predicate_(predicate) {
+ Initialize();
+}
+
+void FontSourcedInfoBuilder::Initialize() {
+ Ptr<CMapTable> cmap_table = down_cast<CMapTable*>(font_->GetTable(Tag::cmap));
+ // We prefer Windows BMP format 4 cmaps.
+ cmap_.Attach(cmap_table->GetCMap(CMapTable::WINDOWS_BMP));
+ // But if none is found,
+ if (!cmap_) {
+ return;
+ }
+ loca_table_ = down_cast<LocaTable*>(font_->GetTable(Tag::loca));
+ glyph_table_ = down_cast<GlyphTable*>(font_->GetTable(Tag::glyf));
+}
+
+CALLER_ATTACH FontInfo* FontSourcedInfoBuilder::GetFontInfo() {
+ CharacterMap* chars_to_glyph_ids = new CharacterMap;
+ bool success = GetCharacterMap(chars_to_glyph_ids);
+ if (!success) {
+ delete chars_to_glyph_ids;
+#if defined (SUBTLY_DEBUG)
+ fprintf(stderr, "Error creating character map.\n");
+#endif
+ return NULL;
+ }
+ GlyphIdSet* resolved_glyph_ids = new GlyphIdSet;
+ success = ResolveCompositeGlyphs(chars_to_glyph_ids, resolved_glyph_ids);
+ if (!success) {
+ delete chars_to_glyph_ids;
+ delete resolved_glyph_ids;
+#if defined (SUBTLY_DEBUG)
+ fprintf(stderr, "Error resolving composite glyphs.\n");
+#endif
+ return NULL;
+ }
+ Ptr<FontInfo> font_info = new FontInfo;
+ font_info->set_chars_to_glyph_ids(chars_to_glyph_ids);
+ font_info->set_resolved_glyph_ids(resolved_glyph_ids);
+ FontIdMap* font_id_map = new FontIdMap;
+ font_id_map->insert(std::make_pair(font_id_, font_));
+ font_info->set_fonts(font_id_map);
+ delete chars_to_glyph_ids;
+ delete resolved_glyph_ids;
+ delete font_id_map;
+ return font_info.Detach();
+}
+
+bool FontSourcedInfoBuilder::GetCharacterMap(CharacterMap* chars_to_glyph_ids) {
+ if (!cmap_ || !chars_to_glyph_ids)
+ return false;
+ chars_to_glyph_ids->clear();
+ CMapTable::CMap::CharacterIterator* character_iterator = cmap_->Iterator();
+ if (!character_iterator)
+ return false;
+ while (character_iterator->HasNext()) {
+ int32_t character = character_iterator->Next();
+ if (!predicate_ || (*predicate_)(character)) {
+ chars_to_glyph_ids->insert
+ (std::make_pair(character,
+ GlyphId(cmap_->GlyphId(character), font_id_)));
+ }
+ }
+ delete character_iterator;
+ return true;
+}
+
+bool
+FontSourcedInfoBuilder::ResolveCompositeGlyphs(CharacterMap* chars_to_glyph_ids,
+ GlyphIdSet* resolved_glyph_ids) {
+ if (!chars_to_glyph_ids || !resolved_glyph_ids)
+ return false;
+ resolved_glyph_ids->clear();
+ resolved_glyph_ids->insert(GlyphId(0, font_id_));
+ IntegerSet* unresolved_glyph_ids = new IntegerSet;
+ // Since composite glyph elements might themselves be composite, we would need
+ // to recursively resolve the elements too. To avoid the recursion we
+ // create two sets, |unresolved_glyph_ids| for the unresolved glyphs,
+ // initially containing all the ids and |resolved_glyph_ids|, initially empty.
+ // We'll remove glyph ids from |unresolved_glyph_ids| until it is empty and,
+ // if the glyph is composite, add its elements to the unresolved set.
+ for (CharacterMap::iterator it = chars_to_glyph_ids->begin(),
+ e = chars_to_glyph_ids->end(); it != e; ++it) {
+ unresolved_glyph_ids->insert(it->second.glyph_id());
+ }
+ // As long as there are unresolved glyph ids.
+ while (!unresolved_glyph_ids->empty()) {
+ // Get the corresponding glyph.
+ int32_t glyph_id = *(unresolved_glyph_ids->begin());
+ unresolved_glyph_ids->erase(unresolved_glyph_ids->begin());
+ if (glyph_id < 0 || glyph_id > loca_table_->num_glyphs()) {
+#if defined (SUBTLY_DEBUG)
+ fprintf(stderr, "%d larger than %d or smaller than 0\n", glyph_id,
+ loca_table_->num_glyphs());
+#endif
+ continue;
+ }
+ int32_t length = loca_table_->GlyphLength(glyph_id);
+ if (length == 0) {
+#if defined (SUBTLY_DEBUG)
+ fprintf(stderr, "Zero length glyph %d\n", glyph_id);
+#endif
+ continue;
+ }
+ int32_t offset = loca_table_->GlyphOffset(glyph_id);
+ GlyphPtr glyph;
+ glyph.Attach(glyph_table_->GetGlyph(offset, length));
+ if (glyph == NULL) {
+#if defined (SUBTLY_DEBUG)
+ fprintf(stderr, "GetGlyph returned NULL for %d\n", glyph_id);
+#endif
+ continue;
+ }
+ // Mark the glyph as resolved.
+ resolved_glyph_ids->insert(GlyphId(glyph_id, font_id_));
+ // If it is composite, add all its components to the unresolved glyph set.
+ if (glyph->GlyphType() == GlyphType::kComposite) {
+ Ptr<GlyphTable::CompositeGlyph> composite_glyph =
+ down_cast<GlyphTable::CompositeGlyph*>(glyph.p_);
+ int32_t num_glyphs = composite_glyph->NumGlyphs();
+ for (int32_t i = 0; i < num_glyphs; ++i) {
+ int32_t glyph_id = composite_glyph->GlyphIndex(i);
+ if (resolved_glyph_ids->find(GlyphId(glyph_id, -1))
+ == resolved_glyph_ids->end()) {
+ unresolved_glyph_ids->insert(glyph_id);
+ }
+ }
+ }
+ }
+ delete unresolved_glyph_ids;
+ return true;
+}
+}
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/font_info.h b/chromium/third_party/sfntly/cpp/src/sample/subtly/font_info.h
new file mode 100644
index 00000000000..6f42d7314b9
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/font_info.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_INFO_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_INFO_H_
+
+#include <map>
+#include <set>
+
+#include "sfntly/font.h"
+#include "sfntly/port/type.h"
+#include "sfntly/port/refcount.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+
+namespace subtly {
+class CharacterPredicate;
+
+typedef int32_t FontId;
+typedef std::map<FontId, sfntly::Ptr<sfntly::Font> > FontIdMap;
+
+// Glyph id pair that contains the loca table glyph id as well as the
+// font id that has the glyph table this glyph belongs to.
+class GlyphId {
+ public:
+ GlyphId(int32_t glyph_id, FontId font_id);
+ ~GlyphId() {}
+
+ bool operator==(const GlyphId& other) const;
+ bool operator<(const GlyphId& other) const;
+
+ int32_t glyph_id() const { return glyph_id_; }
+ void set_glyph_id(const int32_t glyph_id) { glyph_id_ = glyph_id; }
+ FontId font_id() const { return font_id_; }
+ void set_font_id(const FontId font_id) { font_id_ = font_id; }
+
+ private:
+ int32_t glyph_id_;
+ FontId font_id_;
+};
+
+typedef std::map<int32_t, GlyphId> CharacterMap;
+typedef std::set<GlyphId> GlyphIdSet;
+
+// Font information used for FontAssembler in the construction of a new font.
+// Will make copies of character map, glyph id set and font id map.
+class FontInfo : public sfntly::RefCounted<FontInfo> {
+ public:
+ // Empty FontInfo object.
+ FontInfo();
+ // chars_to_glyph_ids maps characters to GlyphIds for CMap construction
+ // resolved_glyph_ids defines GlyphIds which should be in the final font
+ // fonts is a map of font ids to fonts to reference any needed table
+ FontInfo(CharacterMap* chars_to_glyph_ids,
+ GlyphIdSet* resolved_glyph_ids,
+ FontIdMap* fonts);
+ virtual ~FontInfo();
+
+ // Gets the table with the specified tag from the font corresponding to
+ // font_id or NULL if there is no such font/table.
+ // font_id is the id of the font that contains the table
+ // tag identifies the table to be obtained
+ virtual sfntly::FontDataTable* GetTable(FontId font_id, int32_t tag);
+ // Gets the table map of the font whose id is font_id
+ virtual const sfntly::TableMap* GetTableMap(FontId);
+
+ CharacterMap* chars_to_glyph_ids() const { return chars_to_glyph_ids_; }
+ // Takes ownership of the chars_to_glyph_ids CharacterMap.
+ void set_chars_to_glyph_ids(CharacterMap* chars_to_glyph_ids);
+ GlyphIdSet* resolved_glyph_ids() const { return resolved_glyph_ids_; }
+ // Takes ownership of the glyph_ids GlyphIdSet.
+ void set_resolved_glyph_ids(GlyphIdSet* glyph_ids);
+ FontIdMap* fonts() const { return fonts_; }
+ // Takes ownership of the fonts FontIdMap.
+ void set_fonts(FontIdMap* fonts);
+
+ private:
+ CharacterMap* chars_to_glyph_ids_;
+ GlyphIdSet* resolved_glyph_ids_;
+ FontIdMap* fonts_;
+};
+
+// FontSourcedInfoBuilder is used to create a FontInfo object from a Font
+// optionally specifying a CharacterPredicate to filter out some of
+// the font's characters.
+// It does not take ownership or copy the values its constructor receives.
+class FontSourcedInfoBuilder :
+ public sfntly::RefCounted<FontSourcedInfoBuilder> {
+ public:
+ FontSourcedInfoBuilder(sfntly::Font* font, FontId font_id);
+ FontSourcedInfoBuilder(sfntly::Font* font,
+ FontId font_id,
+ CharacterPredicate* predicate);
+ virtual ~FontSourcedInfoBuilder() { }
+
+ virtual CALLER_ATTACH FontInfo* GetFontInfo();
+
+ protected:
+ bool GetCharacterMap(CharacterMap* chars_to_glyph_ids);
+ bool ResolveCompositeGlyphs(CharacterMap* chars_to_glyph_ids,
+ GlyphIdSet* resolved_glyph_ids);
+ void Initialize();
+
+ private:
+ sfntly::Ptr<sfntly::Font> font_;
+ FontId font_id_;
+ CharacterPredicate* predicate_;
+
+ sfntly::Ptr<sfntly::CMapTable::CMap> cmap_;
+ sfntly::Ptr<sfntly::LocaTable> loca_table_;
+ sfntly::Ptr<sfntly::GlyphTable> glyph_table_;
+};
+}
+#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_FONT_INFO_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/merger.cc b/chromium/third_party/sfntly/cpp/src/sample/subtly/merger.cc
new file mode 100644
index 00000000000..7875c2d6b9c
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/merger.cc
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "subtly/merger.h"
+
+#include <stdio.h>
+
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "subtly/character_predicate.h"
+#include "subtly/font_assembler.h"
+#include "subtly/font_info.h"
+#include "subtly/utils.h"
+
+namespace subtly {
+using namespace sfntly;
+
+/******************************************************************************
+ * Merger class
+ ******************************************************************************/
+Merger::Merger(FontArray* fonts) {
+ if (!fonts) {
+ return;
+ }
+ int32_t num_fonts = fonts->size();
+ for (int32_t i = 0; i < num_fonts; ++i) {
+ fonts_.insert(std::make_pair(i, fonts->at(i)));
+ }
+}
+
+CALLER_ATTACH Font* Merger::Merge() {
+ Ptr<FontInfo> merged_info;
+ merged_info.Attach(MergeFontInfos());
+ if (!merged_info) {
+#if defined (SUBTLY_DEBUG)
+ fprintf(stderr, "Could not create merged font info\n");
+#endif
+ return NULL;
+ }
+ Ptr<FontAssembler> font_assembler = new FontAssembler(merged_info);
+ return font_assembler->Assemble();
+}
+
+CALLER_ATTACH FontInfo* Merger::MergeFontInfos() {
+ Ptr<FontInfo> font_info = new FontInfo;
+ font_info->set_fonts(&fonts_);
+ for (FontIdMap::iterator it = fonts_.begin(),
+ e = fonts_.end(); it != e; ++it) {
+ Ptr<FontSourcedInfoBuilder> info_builder =
+ new FontSourcedInfoBuilder(it->second, it->first, NULL);
+ Ptr<FontInfo> current_font_info;
+ current_font_info.Attach(info_builder->GetFontInfo());
+ if (!current_font_info) {
+#if defined (SUBTLY_DEBUG)
+ fprintf(stderr, "Couldn't create font info. "
+ "No subset will be generated.\n");
+#endif
+ return NULL;
+ }
+ font_info->chars_to_glyph_ids()->insert(
+ current_font_info->chars_to_glyph_ids()->begin(),
+ current_font_info->chars_to_glyph_ids()->end());
+ font_info->resolved_glyph_ids()->insert(
+ current_font_info->resolved_glyph_ids()->begin(),
+ current_font_info->resolved_glyph_ids()->end());
+#if defined (SUBTLY_DEBUG)
+ fprintf(stderr, "Counts: chars_to_glyph_ids: %d; resoved_glyph_ids: %d\n",
+ font_info->chars_to_glyph_ids()->size(),
+ font_info->resolved_glyph_ids()->size());
+#endif
+ }
+ return font_info.Detach();
+}
+}
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/merger.h b/chromium/third_party/sfntly/cpp/src/sample/subtly/merger.h
new file mode 100644
index 00000000000..43764a8b6ce
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/merger.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_MERGER_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_MERGER_H_
+
+#include "subtly/character_predicate.h"
+#include "subtly/font_info.h"
+
+namespace sfntly {
+class Font;
+}
+
+namespace subtly {
+// Merges the subsets in the font array into a single font.
+class Merger : public sfntly::RefCounted<Merger> {
+ public:
+ explicit Merger(sfntly::FontArray* fonts);
+ virtual ~Merger() { }
+
+ // Performs merging returning the subsetted font.
+ virtual CALLER_ATTACH sfntly::Font* Merge();
+
+ protected:
+ virtual CALLER_ATTACH FontInfo* MergeFontInfos();
+
+ private:
+ FontIdMap fonts_;
+};
+}
+
+#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_MERGER_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/merger_main.cc b/chromium/third_party/sfntly/cpp/src/sample/subtly/merger_main.cc
new file mode 100644
index 00000000000..a977aa75f87
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/merger_main.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <map>
+#include <utility>
+
+#include "sfntly/font.h"
+#include "subtly/merger.h"
+#include "subtly/stats.h"
+#include "subtly/utils.h"
+
+using namespace subtly;
+
+void PrintUsage(const char* program_name) {
+ fprintf(stdout, "Usage: %s <input_font_file1> <input_font_file2> ..."
+ "<input_font_filen> <output_font_file>\n",
+ program_name);
+}
+
+void CheckLoading(const char* font_path, Font* font) {
+ if (!font || font->num_tables() == 0) {
+ fprintf(stderr, "Could not load font %s. Terminating.\n", font_path);
+ exit(1);
+ }
+}
+
+int main(int argc, const char** argv) {
+ if (argc < 3) {
+ PrintUsage(argv[0]);
+ exit(1);
+ }
+
+ FontArray fonts;
+ for (int32_t i = 1; i < argc - 1; ++i) {
+ Ptr<Font> font;
+ font.Attach(LoadFont(argv[i]));
+ CheckLoading(argv[i], font);
+ fonts.push_back(font);
+ }
+
+ Ptr<Merger> merger = new Merger(&fonts);
+ FontPtr new_font;
+ new_font.Attach(merger->Merge());
+
+ fprintf(stderr, "Serializing font to %s\n", argv[argc - 1]);
+ SerializeFont(argv[argc - 1], new_font);
+ if (!new_font) {
+ fprintf(stdout, "Cannot create merged font.\n");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/stats.cc b/chromium/third_party/sfntly/cpp/src/sample/subtly/stats.cc
new file mode 100644
index 00000000000..769f691e069
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/stats.cc
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+
+#include "sfntly/font.h"
+#include "sfntly/table/table.h"
+#include "sfntly/tag.h"
+#include "subtly/stats.h"
+
+namespace subtly {
+using namespace sfntly;
+
+int32_t TotalFontSize(Font* font) {
+ int32_t size = 0;
+ const TableMap* table_map = font->GetTableMap();
+ for (TableMap::const_iterator it = table_map->begin(),
+ e = table_map->end(); it != e; ++it) {
+ size += it->second->DataLength();
+ }
+ return size;
+}
+
+double TableSizePercent(Font* font, int32_t tag) {
+ TablePtr table = font->GetTable(tag);
+ return static_cast<double>(table->DataLength()) / TotalFontSize(font) * 100;
+}
+
+void PrintComparison(FILE* out, Font* font, Font* new_font) {
+ fprintf(out, "====== Table Comparison (original v. subset) ======\n");
+ const TableMap* tables = font->GetTableMap();
+ for (TableMap::const_iterator it = tables->begin(),
+ e = tables->end(); it != e; ++it) {
+ char *name = TagToString(it->first);
+ int32_t size = it->second->DataLength();
+ fprintf(out, "-- %s: %d (%lf%%) ", name, size,
+ TableSizePercent(font, it->first));
+ delete[] name;
+
+ Ptr<FontDataTable> new_table = new_font->GetTable(it->first);
+ int32_t new_size = 0;
+ double size_percent = 0;
+ if (new_table) {
+ new_size = new_table->DataLength();
+ size_percent = subtly::TableSizePercent(new_font, it->first);
+ }
+
+ if (new_size == size) {
+ fprintf(out, "| same size\n");
+ } else {
+ fprintf(out, "-> %d (%lf%%) | %lf%% of original\n", new_size,
+ size_percent, static_cast<double>(new_size) / size * 100);
+ }
+ }
+}
+
+void PrintStats(FILE* out, Font* font) {
+ fprintf(out, "====== Table Stats ======\n");
+ const TableMap* tables = font->GetTableMap();
+ for (TableMap::const_iterator it = tables->begin(),
+ e = tables->end(); it != e; ++it) {
+ char *name = TagToString(it->first);
+ int32_t size = it->second->DataLength();
+ fprintf(out, "-- %s: %d (%lf%%)\n", name, size,
+ TableSizePercent(font, it->first));
+ delete[] name;
+ }
+}
+}
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/stats.h b/chromium/third_party/sfntly/cpp/src/sample/subtly/stats.h
new file mode 100644
index 00000000000..89ef2aee19e
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/stats.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_STATS_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_STATS_H_
+
+#include <stdio.h>
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+class Font;
+}
+
+namespace subtly {
+using namespace sfntly;
+
+int32_t TotalFontSize(Font* font);
+
+double TableSizePercent(Font* font, int32_t tag);
+
+void PrintComparison(FILE* out, Font* font, Font* new_font);
+
+void PrintStats(FILE* out, Font* font);
+}
+
+#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_STATS_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/subsetter.cc b/chromium/third_party/sfntly/cpp/src/sample/subtly/subsetter.cc
new file mode 100644
index 00000000000..d09627ca353
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/subsetter.cc
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "subtly/subsetter.h"
+
+#include <stdio.h>
+
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/tag.h"
+#include "subtly/character_predicate.h"
+#include "subtly/font_assembler.h"
+#include "subtly/font_info.h"
+#include "subtly/utils.h"
+
+namespace subtly {
+using namespace sfntly;
+
+/******************************************************************************
+ * Subsetter class
+ ******************************************************************************/
+Subsetter::Subsetter(Font* font, CharacterPredicate* predicate)
+ : font_(font),
+ predicate_(predicate) {
+}
+
+Subsetter::Subsetter(const char* font_path, CharacterPredicate* predicate)
+ : predicate_(predicate) {
+ font_.Attach(LoadFont(font_path));
+}
+
+CALLER_ATTACH Font* Subsetter::Subset() {
+ Ptr<FontSourcedInfoBuilder> info_builder =
+ new FontSourcedInfoBuilder(font_, 0, predicate_);
+
+ Ptr<FontInfo> font_info;
+ font_info.Attach(info_builder->GetFontInfo());
+ if (!font_info) {
+#if defined (SUBTLY_DEBUG)
+ fprintf(stderr,
+ "Couldn't create font info. No subset will be generated.\n");
+#endif
+ return NULL;
+ }
+ IntegerSet* table_blacklist = new IntegerSet;
+ table_blacklist->insert(Tag::DSIG);
+ Ptr<FontAssembler> font_assembler = new FontAssembler(font_info,
+ table_blacklist);
+ Ptr<Font> font_subset;
+ font_subset.Attach(font_assembler->Assemble());
+ delete table_blacklist;
+ return font_subset.Detach();
+}
+}
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/subsetter.h b/chromium/third_party/sfntly/cpp/src/sample/subtly/subsetter.h
new file mode 100644
index 00000000000..a93747fafa5
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/subsetter.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_SUBSETTER_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_SUBSETTER_H_
+
+#include "sfntly/font.h"
+// Cannot remove this header due to Ptr<T> instantiation issue
+#include "subtly/character_predicate.h"
+
+namespace subtly {
+// Subsets a given font using a character predicate.
+class Subsetter : public sfntly::RefCounted<Subsetter> {
+ public:
+ Subsetter(sfntly::Font* font, CharacterPredicate* predicate);
+ Subsetter(const char* font_path, CharacterPredicate* predicate);
+ virtual ~Subsetter() { }
+
+ // Performs subsetting returning the subsetted font.
+ virtual CALLER_ATTACH sfntly::Font* Subset();
+
+ private:
+ sfntly::Ptr<sfntly::Font> font_;
+ sfntly::Ptr<CharacterPredicate> predicate_;
+};
+}
+
+#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_SUBSETTER_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/subsetter_main.cc b/chromium/third_party/sfntly/cpp/src/sample/subtly/subsetter_main.cc
new file mode 100644
index 00000000000..d4381486808
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/subsetter_main.cc
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <map>
+#include <utility>
+
+#include "sfntly/font.h"
+#include "subtly/character_predicate.h"
+#include "subtly/stats.h"
+#include "subtly/subsetter.h"
+#include "subtly/utils.h"
+
+using namespace subtly;
+
+void PrintUsage(const char* program_name) {
+ fprintf(stdout, "Usage: %s <input_font_file> <output_font_file>"
+ "<start_char> <end_char>\n", program_name);
+}
+
+int main(int argc, const char** argv) {
+ const char* program_name = argv[0];
+ if (argc < 5) {
+ PrintUsage(program_name);
+ exit(1);
+ }
+
+ const char* input_font_path = argv[1];
+ const char* output_font_path = argv[2];
+ FontPtr font;
+ font.Attach(subtly::LoadFont(input_font_path));
+ if (font->num_tables() == 0) {
+ fprintf(stderr, "Could not load font %s.\n", input_font_path);
+ exit(1);
+ }
+
+ const char* start_char = argv[3];
+ const char* end_char = argv[4];
+ if (start_char[1] != 0) {
+ fprintf(stderr, "Start character %c invalid.\n", start_char[0]);
+ exit(1);
+ }
+ if (end_char[1] != 0) {
+ fprintf(stderr, "Start character %c invalid.\n", end_char[0]);
+ exit(1);
+ }
+ int32_t original_size = TotalFontSize(font);
+
+
+ Ptr<CharacterPredicate> range_predicate =
+ new AcceptRange(start_char[0], end_char[0]);
+ Ptr<Subsetter> subsetter = new Subsetter(font, range_predicate);
+ Ptr<Font> new_font;
+ new_font.Attach(subsetter->Subset());
+ if (!new_font) {
+ fprintf(stdout, "Cannot create subset.\n");
+ return 0;
+ }
+
+ subtly::SerializeFont(output_font_path, new_font);
+ subtly::PrintComparison(stdout, font, new_font);
+ int32_t new_size = TotalFontSize(new_font);
+ fprintf(stdout, "Went from %d to %d: %lf%% of original\n",
+ original_size, new_size,
+ static_cast<double>(new_size) / original_size * 100);
+ return 0;
+}
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/utils.cc b/chromium/third_party/sfntly/cpp/src/sample/subtly/utils.cc
new file mode 100644
index 00000000000..3c204d38146
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/utils.cc
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "subtly/utils.h"
+
+#include "sfntly/data/growable_memory_byte_array.h"
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/port/file_input_stream.h"
+#include "sfntly/port/memory_output_stream.h"
+
+namespace subtly {
+using namespace sfntly;
+
+CALLER_ATTACH Font* LoadFont(const char* font_path) {
+ Ptr<FontFactory> font_factory;
+ font_factory.Attach(FontFactory::GetInstance());
+ FontArray fonts;
+ LoadFonts(font_path, font_factory, &fonts);
+ return fonts[0].Detach();
+}
+
+CALLER_ATTACH Font::Builder* LoadFontBuilder(const char* font_path) {
+ FontFactoryPtr font_factory;
+ font_factory.Attach(FontFactory::GetInstance());
+ FontBuilderArray builders;
+ LoadFontBuilders(font_path, font_factory, &builders);
+ return builders[0].Detach();
+}
+
+void LoadFonts(const char* font_path, FontFactory* factory, FontArray* fonts) {
+ FileInputStream input_stream;
+ input_stream.Open(font_path);
+ factory->LoadFonts(&input_stream, fonts);
+ input_stream.Close();
+}
+
+void LoadFontBuilders(const char* font_path,
+ FontFactory* factory,
+ FontBuilderArray* builders) {
+ FileInputStream input_stream;
+ input_stream.Open(font_path);
+ factory->LoadFontsForBuilding(&input_stream, builders);
+ input_stream.Close();
+}
+
+bool SerializeFont(const char* font_path, Font* font) {
+ if (!font_path)
+ return false;
+ FontFactoryPtr font_factory;
+ font_factory.Attach(FontFactory::GetInstance());
+ return SerializeFont(font_path, font_factory, font);
+}
+
+bool SerializeFont(const char* font_path, FontFactory* factory, Font* font) {
+ if (!font_path || !factory || !font)
+ return false;
+ // Serializing the font to a stream.
+ MemoryOutputStream output_stream;
+ factory->SerializeFont(font, &output_stream);
+ // Serializing the stream to a file.
+ FILE* output_file = NULL;
+#if defined WIN32
+ fopen_s(&output_file, font_path, "wb");
+#else
+ output_file = fopen(font_path, "wb");
+#endif
+ if (output_file == reinterpret_cast<FILE*>(NULL))
+ return false;
+ for (size_t i = 0; i < output_stream.Size(); ++i) {
+ fwrite(&(output_stream.Get()[i]), 1, 1, output_file);
+ }
+ fflush(output_file);
+ fclose(output_file);
+ return true;
+}
+};
diff --git a/chromium/third_party/sfntly/cpp/src/sample/subtly/utils.h b/chromium/third_party/sfntly/cpp/src/sample/subtly/utils.h
new file mode 100644
index 00000000000..ba9f0d4d6af
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sample/subtly/utils.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_UTILS_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_UTILS_H_
+
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+
+namespace subtly {
+CALLER_ATTACH sfntly::Font* LoadFont(const char* font_path);
+CALLER_ATTACH sfntly::Font::Builder* LoadFontBuilder(const char* font_path);
+
+void LoadFonts(const char* font_path, sfntly::FontFactory* factory,
+ sfntly::FontArray* fonts);
+void LoadFontBuilders(const char* font_path,
+ sfntly::FontFactory* factory,
+ sfntly::FontBuilderArray* builders);
+
+bool SerializeFont(const char* font_path, sfntly::Font* font);
+bool SerializeFont(const char* font_path, sfntly::FontFactory* factory,
+ sfntly::Font* font);
+}
+
+#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SAMPLE_SUBTLY_UTILS_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/byte_array.cc b/chromium/third_party/sfntly/cpp/src/sfntly/data/byte_array.cc
new file mode 100644
index 00000000000..915a40c0357
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/byte_array.cc
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/data/byte_array.h"
+
+#include <algorithm>
+
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+
+const int32_t ByteArray::COPY_BUFFER_SIZE = 8192;
+
+ByteArray::~ByteArray() {}
+
+int32_t ByteArray::Length() { return filled_length_; }
+int32_t ByteArray::Size() { return storage_length_; }
+
+int32_t ByteArray::SetFilledLength(int32_t filled_length) {
+ filled_length_ = std::min<int32_t>(filled_length, storage_length_);
+ return filled_length_;
+}
+
+int32_t ByteArray::Get(int32_t index) {
+ return InternalGet(index) & 0xff;
+}
+
+int32_t ByteArray::Get(int32_t index, ByteVector* b) {
+ assert(b);
+ return Get(index, &((*b)[0]), 0, b->size());
+}
+
+int32_t ByteArray::Get(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length) {
+ assert(b);
+ if (index < 0 || index >= filled_length_) {
+ return 0;
+ }
+ int32_t actual_length = std::min<int32_t>(length, filled_length_ - index);
+ return InternalGet(index, b, offset, actual_length);
+}
+
+void ByteArray::Put(int32_t index, byte_t b) {
+ if (index < 0 || index >= Size()) {
+#if defined (SFNTLY_NO_EXCEPTION)
+ return;
+#else
+ throw IndexOutOfBoundException(
+ "Attempt to write outside the bounds of the data");
+#endif
+ }
+ InternalPut(index, b);
+ filled_length_ = std::max<int32_t>(filled_length_, index + 1);
+}
+
+int32_t ByteArray::Put(int index, ByteVector* b) {
+ assert(b);
+ return Put(index, &((*b)[0]), 0, b->size());
+}
+
+int32_t ByteArray::Put(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length) {
+ assert(b);
+ if (index < 0 || index >= Size()) {
+#if defined (SFNTLY_NO_EXCEPTION)
+ return 0;
+#else
+ throw IndexOutOfBoundException(
+ "Attempt to write outside the bounds of the data");
+#endif
+ }
+ int32_t actual_length = std::min<int32_t>(length, Size() - index);
+ int32_t bytes_written = InternalPut(index, b, offset, actual_length);
+ filled_length_ = std::max<int32_t>(filled_length_, index + bytes_written);
+ return bytes_written;
+}
+
+int32_t ByteArray::CopyTo(ByteArray* array) {
+ return CopyTo(array, 0, Length());
+}
+
+int32_t ByteArray::CopyTo(ByteArray* array, int32_t offset, int32_t length) {
+ return CopyTo(0, array, offset, length);
+}
+
+int32_t ByteArray::CopyTo(int32_t dst_offset, ByteArray* array,
+ int32_t src_offset, int32_t length) {
+ assert(array);
+ if (array->Size() < dst_offset + length) { // insufficient space
+ return -1;
+ }
+
+ ByteVector b(COPY_BUFFER_SIZE);
+ int32_t bytes_read = 0;
+ int32_t index = 0;
+ int32_t remaining_length = length;
+ int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
+ while ((bytes_read =
+ Get(index + src_offset, &(b[0]), 0, buffer_length)) > 0) {
+ int bytes_written = array->Put(index + dst_offset, &(b[0]), 0, bytes_read);
+ UNREFERENCED_PARAMETER(bytes_written);
+ index += bytes_read;
+ remaining_length -= bytes_read;
+ buffer_length = std::min<int32_t>(b.size(), remaining_length);
+ }
+ return index;
+}
+
+int32_t ByteArray::CopyTo(OutputStream* os) {
+ return CopyTo(os, 0, Length());
+}
+
+int32_t ByteArray::CopyTo(OutputStream* os, int32_t offset, int32_t length) {
+ ByteVector b(COPY_BUFFER_SIZE);
+ int32_t bytes_read = 0;
+ int32_t index = 0;
+ int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
+ while ((bytes_read = Get(index + offset, &(b[0]), 0, buffer_length)) > 0) {
+ os->Write(&b, 0, bytes_read);
+ index += bytes_read;
+ buffer_length = std::min<int32_t>(b.size(), length - index);
+ }
+ return index;
+}
+
+bool ByteArray::CopyFrom(InputStream* is, int32_t length) {
+ ByteVector b(COPY_BUFFER_SIZE);
+ int32_t bytes_read = 0;
+ int32_t index = 0;
+ int32_t buffer_length = std::min<int32_t>(COPY_BUFFER_SIZE, length);
+ while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
+ if (Put(index, &(b[0]), 0, bytes_read) != bytes_read) {
+#if defined (SFNTLY_NO_EXCEPTION)
+ return 0;
+#else
+ throw IOException("Error writing bytes.");
+#endif
+ }
+ index += bytes_read;
+ length -= bytes_read;
+ buffer_length = std::min<int32_t>(b.size(), length);
+ }
+ return true;
+}
+
+bool ByteArray::CopyFrom(InputStream* is) {
+ ByteVector b(COPY_BUFFER_SIZE);
+ int32_t bytes_read = 0;
+ int32_t index = 0;
+ int32_t buffer_length = COPY_BUFFER_SIZE;
+ while ((bytes_read = is->Read(&b, 0, buffer_length)) > 0) {
+ if (Put(index, &b[0], 0, bytes_read) != bytes_read) {
+#if defined (SFNTLY_NO_EXCEPTION)
+ return 0;
+#else
+ throw IOException("Error writing bytes.");
+#endif
+ }
+ index += bytes_read;
+ }
+ return true;
+}
+
+ByteArray::ByteArray(int32_t filled_length,
+ int32_t storage_length,
+ bool growable) {
+ Init(filled_length, storage_length, growable);
+}
+
+ByteArray::ByteArray(int32_t filled_length, int32_t storage_length) {
+ Init(filled_length, storage_length, false);
+}
+
+void ByteArray::Init(int32_t filled_length,
+ int32_t storage_length,
+ bool growable) {
+ storage_length_ = storage_length;
+ growable_ = growable;
+ SetFilledLength(filled_length);
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/byte_array.h b/chromium/third_party/sfntly/cpp/src/sfntly/data/byte_array.h
new file mode 100644
index 00000000000..70dc92f51a8
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/byte_array.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2011 The sfntly Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_BYTE_ARRAY_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_BYTE_ARRAY_H_
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/port/type.h"
+#include "sfntly/port/input_stream.h"
+#include "sfntly/port/output_stream.h"
+
+namespace sfntly {
+
+// An abstraction to a contiguous array of bytes.
+// C++ port of this class assumes that the data are stored in a linear region
+// like std::vector.
+class ByteArray : virtual public RefCount {
+ public:
+ virtual ~ByteArray();
+
+ // Gets the current filled and readable length of the array.
+ int32_t Length();
+
+ // Gets the maximum size of the array. This is the maximum number of bytes that
+ // the array can hold and all of it may not be filled with data or even fully
+ // allocated yet.
+ int32_t Size();
+
+ // Determines whether or not this array is growable or of fixed size.
+ bool growable() { return growable_; }
+
+ int32_t SetFilledLength(int32_t filled_length);
+
+ // Gets the byte from the given index.
+ // @param index the index into the byte array
+ // @return the byte or -1 if reading beyond the bounds of the data
+ virtual int32_t Get(int32_t index);
+
+ // Gets the bytes from the given index and fill the buffer with them. As many
+ // bytes as will fit into the buffer are read unless that would go past the
+ // end of the array.
+ // @param index the index into the byte array
+ // @param b the buffer to put the bytes read into
+ // @return the number of bytes read from the buffer
+ virtual int32_t Get(int32_t index, ByteVector* b);
+
+ // Gets the bytes from the given index and fill the buffer with them starting
+ // at the offset given. As many bytes as the specified length are read unless
+ // that would go past the end of the array.
+ // @param index the index into the byte array
+ // @param b the buffer to put the bytes read into
+ // @param offset the location in the buffer to start putting the bytes
+ // @param length the number of bytes to put into the buffer
+ // @return the number of bytes read from the buffer
+ virtual int32_t Get(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length);
+
+ // Puts the specified byte into the array at the given index unless that would
+ // be beyond the length of the array and it isn't growable.
+ virtual void Put(int32_t index, byte_t b);
+
+ // Puts the specified bytes into the array at the given index. The entire
+ // buffer is put into the array unless that would extend beyond the length and
+ // the array isn't growable.
+ virtual int32_t Put(int32_t index, ByteVector* b);
+
+ // Puts the specified bytes into the array at the given index. All of the bytes
+ // specified are put into the array unless that would extend beyond the length
+ // and the array isn't growable. The bytes to be put into the array are those
+ // in the buffer from the given offset and for the given length.
+ // @param index the index into the ByteArray
+ // @param b the bytes to put into the array
+ // @param offset the offset in the bytes to start copying from
+ // @param length the number of bytes to copy into the array
+ // @return the number of bytes actually written
+ virtual int32_t Put(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length);
+
+ // Fully copies this ByteArray to another ByteArray to the extent that the
+ // destination array has storage for the data copied.
+ virtual int32_t CopyTo(ByteArray* array);
+
+ // Copies a segment of this ByteArray to another ByteArray.
+ // @param array the destination
+ // @param offset the offset in this ByteArray to start copying from
+ // @param length the maximum length in bytes to copy
+ // @return the number of bytes copied
+ virtual int32_t CopyTo(ByteArray* array, int32_t offset, int32_t length);
+
+ // Copies this ByteArray to another ByteArray.
+ // @param dstOffset the offset in the destination array to start copying to
+ // @param array the destination
+ // @param srcOffset the offset in this ByteArray to start copying from
+ // @param length the maximum length in bytes to copy
+ // @return the number of bytes copied
+ virtual int32_t CopyTo(int32_t dst_offset,
+ ByteArray* array,
+ int32_t src_offset,
+ int32_t length);
+
+ // Copies this ByteArray to an OutputStream.
+ // @param os the destination
+ // @return the number of bytes copied
+ virtual int32_t CopyTo(OutputStream* os);
+
+ // Copies this ByteArray to an OutputStream.
+ // @param os the destination
+ // @param offset
+ // @param length
+ // @return the number of bytes copied
+ virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
+
+ // Copies from the InputStream into this ByteArray.
+ // @param is the source
+ // @param length the number of bytes to copy
+ virtual bool CopyFrom(InputStream* is, int32_t length);
+
+ // Copies everything from the InputStream into this ByteArray.
+ // @param is the source
+ virtual bool CopyFrom(InputStream* is);
+
+ protected:
+ // filledLength the length that is "filled" and readable counting from offset.
+ // storageLength the maximum storage size of the underlying data.
+ // growable is the storage growable - storageLength is the max growable size.
+ ByteArray(int32_t filled_length, int32_t storage_length, bool growable);
+ ByteArray(int32_t filled_length, int32_t storage_length);
+ void Init(int32_t filled_length, int32_t storage_length, bool growable);
+
+ // Internal subclass API
+
+ // Stores the byte at the index given.
+ // @param index the location to store at
+ // @param b the byte to store
+ virtual void InternalPut(int32_t index, byte_t b) = 0;
+
+ // Stores the array of bytes at the given index.
+ // @param index the location to store at
+ // @param b the bytes to store
+ // @param offset the offset to start from in the byte array
+ // @param length the length of the byte array to store from the offset
+ // @return the number of bytes actually stored
+ virtual int32_t InternalPut(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length) = 0;
+
+ // Gets the byte at the index given.
+ // @param index the location to get from
+ // @return the byte stored at the index
+ virtual byte_t InternalGet(int32_t index) = 0;
+
+ // Gets the bytes at the index given of the given length.
+ // @param index the location to start getting from
+ // @param b the array to put the bytes into
+ // @param offset the offset in the array to put the bytes into
+ // @param length the length of bytes to read
+ // @return the number of bytes actually ready
+ virtual int32_t InternalGet(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length) = 0;
+
+ // Close this instance of the ByteArray.
+ virtual void Close() = 0;
+
+ // C++ port only, raw pointer to the first element of storage.
+ virtual byte_t* Begin() = 0;
+
+ // Java toString() not ported.
+
+ static const int32_t COPY_BUFFER_SIZE;
+
+ private:
+ //bool bound_; // unused, comment out
+ int32_t filled_length_;
+ int32_t storage_length_;
+ bool growable_;
+};
+typedef Ptr<ByteArray> ByteArrayPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_BYTE_ARRAY_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/font_data.cc b/chromium/third_party/sfntly/cpp/src/sfntly/data/font_data.cc
new file mode 100644
index 00000000000..d2b95eac1b8
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/font_data.cc
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <limits.h>
+#include <algorithm>
+#include <functional>
+
+#include "sfntly/data/font_data.h"
+
+namespace sfntly {
+
+int32_t FontData::Size() const {
+ return std::min<int32_t>(array_->Size() - bound_offset_, bound_length_);
+}
+
+bool FontData::Bound(int32_t offset, int32_t length) {
+ if (offset + length > Size() || offset < 0 || length < 0)
+ return false;
+
+ bound_offset_ += offset;
+ bound_length_ = length;
+ return true;
+}
+
+bool FontData::Bound(int32_t offset) {
+if (offset > Size() || offset < 0)
+ return false;
+
+ bound_offset_ += offset;
+ return true;
+}
+
+int32_t FontData::Length() const {
+ return std::min<int32_t>(array_->Length() - bound_offset_, bound_length_);
+}
+
+FontData::FontData(ByteArray* ba) {
+ Init(ba);
+}
+
+FontData::FontData(FontData* data, int32_t offset, int32_t length) {
+ Init(data->array_);
+ Bound(data->bound_offset_ + offset, length);
+}
+
+FontData::FontData(FontData* data, int32_t offset) {
+ Init(data->array_);
+ Bound(data->bound_offset_ + offset,
+ (data->bound_length_ == GROWABLE_SIZE)
+ ? GROWABLE_SIZE : data->bound_length_ - offset);
+}
+
+FontData::~FontData() {}
+
+void FontData::Init(ByteArray* ba) {
+ array_ = ba;
+ bound_offset_ = 0;
+ bound_length_ = GROWABLE_SIZE;
+}
+
+int32_t FontData::BoundOffset(int32_t offset) {
+ return offset + bound_offset_;
+}
+
+int32_t FontData::BoundLength(int32_t offset, int32_t length) {
+ return std::min<int32_t>(length, bound_length_ - offset);
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/font_data.h b/chromium/third_party/sfntly/cpp/src/sfntly/data/font_data.h
new file mode 100644
index 00000000000..d02e8b75db2
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/font_data.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_DATA_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_DATA_H_
+
+#include <limits.h>
+
+#include <vector>
+
+#include "sfntly/port/type.h"
+#include "sfntly/data/byte_array.h"
+#include "sfntly/port/refcount.h"
+
+namespace sfntly {
+
+struct DataSize {
+ enum {
+ kBYTE = 1,
+ kCHAR = 1,
+ kUSHORT = 2,
+ kSHORT = 2,
+ kUINT24 = 3,
+ kULONG = 4,
+ kLONG = 4,
+ kFixed = 4,
+ kFUNIT = 4,
+ kFWORD = 2,
+ kUFWORD = 2,
+ kF2DOT14 = 2,
+ kLONGDATETIME = 8,
+ kTag = 4,
+ kGlyphID = 2,
+ kOffset = 2
+ };
+};
+
+class FontData : virtual public RefCount {
+ public:
+ // Gets the maximum size of the FontData. This is the maximum number of bytes
+ // that the font data can hold and all of it may not be filled with data or
+ // even fully allocated yet.
+ // @return the maximum size of this font data
+ virtual int32_t Size() const;
+
+ // Sets limits on the size of the FontData. The FontData is then only
+ // visible within the bounds set.
+ // @param offset the start of the new bounds
+ // @param length the number of bytes in the bounded array
+ // @return true if the bounding range was successful; false otherwise
+ virtual bool Bound(int32_t offset, int32_t length);
+
+ // Sets limits on the size of the FontData. This is a offset bound only so if
+ // the FontData is writable and growable then there is no limit to that growth
+ // from the bounding operation.
+ // @param offset the start of the new bounds which must be within the current
+ // size of the FontData
+ // @return true if the bounding range was successful; false otherwise
+ virtual bool Bound(int32_t offset);
+
+ // Makes a slice of this FontData. The returned slice will share the data with
+ // the original <code>FontData</code>.
+ // @param offset the start of the slice
+ // @param length the number of bytes in the slice
+ // @return a slice of the original FontData
+ virtual CALLER_ATTACH FontData* Slice(int32_t offset, int32_t length) = 0;
+
+ // Makes a bottom bound only slice of this array. The returned slice will
+ // share the data with the original <code>FontData</code>.
+ // @param offset the start of the slice
+ // @return a slice of the original FontData
+ virtual CALLER_ATTACH FontData* Slice(int32_t offset) = 0;
+
+ // Gets the length of the data.
+ virtual int32_t Length() const;
+
+ protected:
+ // Constructor.
+ // @param ba the byte array to use for the backing data
+ explicit FontData(ByteArray* ba);
+
+ // Constructor.
+ // @param data the data to wrap
+ // @param offset the offset to start the wrap from
+ // @param length the length of the data wrapped
+ FontData(FontData* data, int32_t offset, int32_t length);
+
+ // Constructor.
+ // @param data the data to wrap
+ // @param offset the offset to start the wrap from
+ FontData(FontData* data, int32_t offset);
+ virtual ~FontData();
+
+ void Init(ByteArray* ba);
+
+ // Gets the offset in the underlying data taking into account any bounds on
+ // the data.
+ // @param offset the offset to get the bound compensated offset for
+ // @return the bound compensated offset
+ int32_t BoundOffset(int32_t offset);
+
+ // Gets the length in the underlying data taking into account any bounds on
+ // the data.
+ // @param offset the offset that the length is being used at
+ // @param length the length to get the bound compensated length for
+ // @return the bound compensated length
+ int32_t BoundLength(int32_t offset, int32_t length);
+
+ static const int32_t GROWABLE_SIZE = INT_MAX;
+
+ // TODO(arthurhsu): style guide violation: refactor this protected member
+ ByteArrayPtr array_;
+
+ private:
+ int32_t bound_offset_;
+ int32_t bound_length_;
+};
+typedef Ptr<FontData> FontDataPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_DATA_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/font_input_stream.cc b/chromium/third_party/sfntly/cpp/src/sfntly/data/font_input_stream.cc
new file mode 100644
index 00000000000..dcf8be35f9a
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/font_input_stream.cc
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/data/font_input_stream.h"
+
+#include <algorithm>
+
+namespace sfntly {
+
+FontInputStream::FontInputStream(InputStream* is)
+ : stream_(is), position_(0), length_(0), bounded_(false) {
+}
+
+FontInputStream::FontInputStream(InputStream* is, size_t length)
+ : stream_(is), position_(0), length_(length), bounded_(true) {
+}
+
+FontInputStream::~FontInputStream() {
+ // Do not close here, underlying InputStream will close themselves.
+}
+
+int32_t FontInputStream::Available() {
+ if (stream_) {
+ return stream_->Available();
+ }
+ return 0;
+}
+
+void FontInputStream::Close() {
+ if (stream_) {
+ stream_->Close();
+ }
+}
+
+void FontInputStream::Mark(int32_t readlimit) {
+ if (stream_) {
+ stream_->Mark(readlimit);
+ }
+}
+
+bool FontInputStream::MarkSupported() {
+ if (stream_) {
+ return stream_->MarkSupported();
+ }
+ return false;
+}
+
+void FontInputStream::Reset() {
+ if (stream_) {
+ stream_->Reset();
+ }
+}
+
+int32_t FontInputStream::Read() {
+ if (!stream_ || (bounded_ && position_ >= length_)) {
+ return -1;
+ }
+ int32_t b = stream_->Read();
+ if (b >= 0) {
+ position_++;
+ }
+ return b;
+}
+
+int32_t FontInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
+ if (!stream_ || offset < 0 || length < 0 ||
+ (bounded_ && position_ >= length_)) {
+ return -1;
+ }
+ int32_t bytes_to_read =
+ bounded_ ? std::min<int32_t>(length, (int32_t)(length_ - position_)) :
+ length;
+ int32_t bytes_read = stream_->Read(b, offset, bytes_to_read);
+ position_ += bytes_read;
+ return bytes_read;
+}
+
+int32_t FontInputStream::Read(ByteVector* b) {
+ return Read(b, 0, b->size());
+}
+
+int32_t FontInputStream::ReadChar() {
+ return Read();
+}
+
+int32_t FontInputStream::ReadUShort() {
+ return 0xffff & (Read() << 8 | Read());
+}
+
+int32_t FontInputStream::ReadShort() {
+ return ((Read() << 8 | Read()) << 16) >> 16;
+}
+
+int32_t FontInputStream::ReadUInt24() {
+ return 0xffffff & (Read() << 16 | Read() << 8 | Read());
+}
+
+int64_t FontInputStream::ReadULong() {
+ return 0xffffffffL & ReadLong();
+}
+
+int32_t FontInputStream::ReadULongAsInt() {
+ int64_t ulong = ReadULong();
+ return ((int32_t)ulong) & ~0x80000000;
+}
+
+int32_t FontInputStream::ReadLong() {
+ return Read() << 24 | Read() << 16 | Read() << 8 | Read();
+}
+
+int32_t FontInputStream::ReadFixed() {
+ return ReadLong();
+}
+
+int64_t FontInputStream::ReadDateTimeAsLong() {
+ return (int64_t)ReadULong() << 32 | ReadULong();
+}
+
+int64_t FontInputStream::Skip(int64_t n) {
+ if (stream_) {
+ int64_t skipped = stream_->Skip(n);
+ position_ += skipped;
+ return skipped;
+ }
+ return 0;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/font_input_stream.h b/chromium/third_party/sfntly/cpp/src/sfntly/data/font_input_stream.h
new file mode 100644
index 00000000000..9992b0753f6
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/font_input_stream.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_INPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_INPUT_STREAM_H_
+
+#include "sfntly/port/type.h"
+#include "sfntly/port/input_stream.h"
+
+namespace sfntly {
+
+// An input stream for reading font data.
+// The data types used are as listed:
+// BYTE 8-bit unsigned integer.
+// CHAR 8-bit signed integer.
+// USHORT 16-bit unsigned integer.
+// SHORT 16-bit signed integer.
+// UINT24 24-bit unsigned integer.
+// ULONG 32-bit unsigned integer.
+// LONG 32-bit signed integer.
+// Fixed 32-bit signed fixed-point number (16.16)
+// FUNIT Smallest measurable distance in the em space.
+// FWORD 16-bit signed integer (SHORT) that describes a quantity in FUnits.
+// UFWORD 16-bit unsigned integer (USHORT) that describes a quantity in
+// FUnits.
+// F2DOT14 16-bit signed fixed number with the low 14 bits of fraction (2.14)
+// LONGDATETIME Date represented in number of seconds since 12:00 midnight,
+// January 1, 1904. The value is represented as a signed 64-bit
+// integer.
+
+// Note: Original class inherits from Java's FilterOutputStream, which wraps
+// an InputStream within. In C++, we directly do the wrapping without
+// defining another layer of abstraction. The wrapped output stream is
+// *NOT* reference counted (because it's meaningless to ref-count an I/O
+// stream).
+class FontInputStream : public InputStream {
+ public:
+ // Constructor.
+ // @param is input stream to wrap
+ explicit FontInputStream(InputStream* is);
+
+ // Constructor for a bounded font input stream.
+ // @param is input stream to wrap
+ // @param length the maximum length of bytes to read
+ FontInputStream(InputStream* is, size_t length);
+
+ virtual ~FontInputStream();
+
+
+ virtual int32_t Available();
+ virtual void Close();
+ virtual void Mark(int32_t readlimit);
+ virtual bool MarkSupported();
+ virtual void Reset();
+
+ virtual int32_t Read();
+ virtual int32_t Read(ByteVector* buffer);
+ virtual int32_t Read(ByteVector* buffer, int32_t offset, int32_t length);
+
+ // Get the current position in the stream in bytes.
+ // @return the current position in bytes
+ virtual int64_t position() { return position_; }
+
+ virtual int32_t ReadChar();
+ virtual int32_t ReadUShort();
+ virtual int32_t ReadShort();
+ virtual int32_t ReadUInt24();
+ virtual int64_t ReadULong();
+ virtual int32_t ReadULongAsInt();
+ virtual int32_t ReadLong();
+ virtual int32_t ReadFixed();
+ virtual int64_t ReadDateTimeAsLong();
+ virtual int64_t Skip(int64_t n); // n can be negative.
+
+ private:
+ InputStream* stream_;
+ int64_t position_;
+ int64_t length_; // Bound on length of data to read.
+ bool bounded_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_INPUT_STREAM_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/font_output_stream.cc b/chromium/third_party/sfntly/cpp/src/sfntly/data/font_output_stream.cc
new file mode 100644
index 00000000000..3422a22827c
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/font_output_stream.cc
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/data/font_output_stream.h"
+
+#include <algorithm>
+
+namespace sfntly {
+
+FontOutputStream::FontOutputStream(OutputStream* os)
+ : stream_(os),
+ position_(0) {
+}
+
+FontOutputStream::~FontOutputStream() {
+ // Do not close, underlying stream shall clean up themselves.
+}
+
+void FontOutputStream::Write(byte_t b) {
+ if (stream_) {
+ stream_->Write(b);
+ position_++;
+ }
+}
+
+void FontOutputStream::Write(ByteVector* b) {
+ if (b) {
+ Write(b, 0, b->size());
+ position_ += b->size();
+ }
+}
+
+void FontOutputStream::Write(ByteVector* b, int32_t off, int32_t len) {
+ assert(b);
+ assert(stream_);
+ if (off < 0 || len < 0 || off + len < 0 ||
+ static_cast<size_t>(off + len) > b->size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundException();
+#else
+ return;
+#endif
+ }
+
+ stream_->Write(b, off, len);
+ position_ += len;
+}
+
+void FontOutputStream::Write(byte_t* b, int32_t off, int32_t len) {
+ assert(b);
+ assert(stream_);
+ if (off < 0 || len < 0 || off + len < 0) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundException();
+#else
+ return;
+#endif
+ }
+
+ stream_->Write(b, off, len);
+ position_ += len;
+}
+
+void FontOutputStream::WriteChar(byte_t c) {
+ Write(c);
+}
+
+void FontOutputStream::WriteUShort(int32_t us) {
+ Write((byte_t)((us >> 8) & 0xff));
+ Write((byte_t)(us & 0xff));
+}
+
+void FontOutputStream::WriteShort(int32_t s) {
+ WriteUShort(s);
+}
+
+void FontOutputStream::WriteUInt24(int32_t ui) {
+ Write((byte_t)(ui >> 16) & 0xff);
+ Write((byte_t)(ui >> 8) & 0xff);
+ Write((byte_t)ui & 0xff);
+}
+
+void FontOutputStream::WriteULong(int64_t ul) {
+ Write((byte_t)((ul >> 24) & 0xff));
+ Write((byte_t)((ul >> 16) & 0xff));
+ Write((byte_t)((ul >> 8) & 0xff));
+ Write((byte_t)(ul & 0xff));
+}
+
+void FontOutputStream::WriteLong(int64_t l) {
+ WriteULong(l);
+}
+
+void FontOutputStream::WriteFixed(int32_t f) {
+ WriteULong(f);
+}
+
+void FontOutputStream::WriteDateTime(int64_t date) {
+ WriteULong((date >> 32) & 0xffffffff);
+ WriteULong(date & 0xffffffff);
+}
+
+void FontOutputStream::Flush() {
+ if (stream_) {
+ stream_->Flush();
+ }
+}
+
+void FontOutputStream::Close() {
+ if (stream_) {
+ stream_->Flush();
+ stream_->Close();
+ position_ = 0;
+ }
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/font_output_stream.h b/chromium/third_party/sfntly/cpp/src/sfntly/data/font_output_stream.h
new file mode 100644
index 00000000000..fcd48e8aaa8
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/font_output_stream.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_OUTPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_OUTPUT_STREAM_H_
+
+#include "sfntly/port/type.h"
+#include "sfntly/port/output_stream.h"
+
+namespace sfntly {
+
+// An output stream for writing font data.
+// The data types used are as listed:
+// BYTE 8-bit unsigned integer.
+// CHAR 8-bit signed integer.
+// USHORT 16-bit unsigned integer.
+// SHORT 16-bit signed integer.
+// UINT24 24-bit unsigned integer.
+// ULONG 32-bit unsigned integer.
+// LONG 32-bit signed integer.
+// Fixed 32-bit signed fixed-point number (16.16)
+// FUNIT Smallest measurable distance in the em space.
+// FWORD 16-bit signed integer (SHORT) that describes a quantity in FUnits.
+// UFWORD 16-bit unsigned integer (USHORT) that describes a quantity in
+// FUnits.
+// F2DOT14 16-bit signed fixed number with the low 14 bits of fraction (2.14)
+// LONGDATETIME Date represented in number of seconds since 12:00 midnight,
+// January 1, 1904. The value is represented as a signed 64-bit
+// integer.
+
+// Note: The wrapped output stream is *NOT* reference counted (because it's
+// meaningless to ref-count an I/O stream).
+class FontOutputStream : public OutputStream {
+ public:
+ explicit FontOutputStream(OutputStream* os);
+ virtual ~FontOutputStream();
+
+ virtual size_t position() { return position_; }
+
+ virtual void Write(byte_t b);
+ virtual void Write(ByteVector* b);
+ virtual void Write(ByteVector* b, int32_t off, int32_t len);
+ virtual void Write(byte_t* b, int32_t off, int32_t len);
+ virtual void WriteChar(byte_t c);
+ virtual void WriteUShort(int32_t us);
+ virtual void WriteShort(int32_t s);
+ virtual void WriteUInt24(int32_t ui);
+ virtual void WriteULong(int64_t ul);
+ virtual void WriteLong(int64_t l);
+ virtual void WriteFixed(int32_t l);
+ virtual void WriteDateTime(int64_t date);
+
+ // Note: C++ port only.
+ virtual void Flush();
+ virtual void Close();
+
+ private:
+ // Note: we do not use the variable name out as in Java because it has
+ // special meaning in VC++ and will be very confusing.
+ OutputStream* stream_;
+ size_t position_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_FONT_OUTPUT_STREAM_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/growable_memory_byte_array.cc b/chromium/third_party/sfntly/cpp/src/sfntly/data/growable_memory_byte_array.cc
new file mode 100644
index 00000000000..c335614d4de
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/growable_memory_byte_array.cc
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/data/growable_memory_byte_array.h"
+
+#include <limits.h>
+#include <string.h>
+
+#include <algorithm>
+
+namespace sfntly {
+
+GrowableMemoryByteArray::GrowableMemoryByteArray()
+ : ByteArray(0, INT_MAX, true) {
+ // Note: We did not set an initial size of array like Java because STL
+ // implementation will determine the best strategy.
+}
+
+GrowableMemoryByteArray::~GrowableMemoryByteArray() {}
+
+int32_t GrowableMemoryByteArray::CopyTo(OutputStream* os,
+ int32_t offset,
+ int32_t length) {
+ assert(os);
+ os->Write(&b_, offset, length);
+ return length;
+}
+
+void GrowableMemoryByteArray::InternalPut(int32_t index, byte_t b) {
+ if ((size_t)index >= b_.size()) {
+ b_.resize((size_t)(index + 1));
+ }
+ b_[index] = b;
+}
+
+int32_t GrowableMemoryByteArray::InternalPut(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length) {
+ if ((size_t)index + length >= b_.size()) {
+ // Note: We grow one byte more than Java version. VC debuggers shows
+ // data better this way.
+ b_.resize((size_t)(index + length + 1));
+ }
+ std::copy(b + offset, b + offset + length, b_.begin() + index);
+ return length;
+}
+
+byte_t GrowableMemoryByteArray::InternalGet(int32_t index) {
+ return b_[index];
+}
+
+int32_t GrowableMemoryByteArray::InternalGet(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length) {
+ memcpy(b + offset, &(b_[0]) + index, length);
+ return length;
+}
+
+void GrowableMemoryByteArray::Close() {
+ b_.clear();
+}
+
+byte_t* GrowableMemoryByteArray::Begin() {
+ return &(b_[0]);
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/growable_memory_byte_array.h b/chromium/third_party/sfntly/cpp/src/sfntly/data/growable_memory_byte_array.h
new file mode 100644
index 00000000000..8583a0d645f
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/growable_memory_byte_array.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_GROWABLE_MEMORY_BYTE_ARRAY_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_GROWABLE_MEMORY_BYTE_ARRAY_H_
+
+#include "sfntly/data/byte_array.h"
+
+namespace sfntly {
+
+// Note: This is not really a port of Java version. Instead, this wraps a
+// std::vector inside and let it grow by calling resize().
+class GrowableMemoryByteArray : public ByteArray,
+ public RefCounted<GrowableMemoryByteArray> {
+ public:
+ GrowableMemoryByteArray();
+ virtual ~GrowableMemoryByteArray();
+ virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
+
+ // Make gcc -Woverloaded-virtual happy.
+ virtual int32_t CopyTo(ByteArray* array) { return ByteArray::CopyTo(array); }
+ virtual int32_t CopyTo(ByteArray* array, int32_t offset, int32_t length) {
+ return ByteArray::CopyTo(array, offset, length);
+ }
+ virtual int32_t CopyTo(int32_t dst_offset,
+ ByteArray* array,
+ int32_t src_offset,
+ int32_t length) {
+ return ByteArray::CopyTo(dst_offset, array, src_offset, length);
+ }
+ virtual int32_t CopyTo(OutputStream* os) { return ByteArray::CopyTo(os); }
+
+ protected:
+ virtual void InternalPut(int32_t index, byte_t b);
+ virtual int32_t InternalPut(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length);
+ virtual byte_t InternalGet(int32_t index);
+ virtual int32_t InternalGet(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length);
+ virtual void Close();
+ virtual byte_t* Begin();
+
+ private:
+ ByteVector b_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_GROWABLE_MEMORY_BYTE_ARRAY_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/memory_byte_array.cc b/chromium/third_party/sfntly/cpp/src/sfntly/data/memory_byte_array.cc
new file mode 100644
index 00000000000..d6c9c4828d3
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/memory_byte_array.cc
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/data/memory_byte_array.h"
+
+#include <string.h>
+
+namespace sfntly {
+
+MemoryByteArray::MemoryByteArray(int32_t length)
+ : ByteArray(0, length), b_(NULL), allocated_(true) {
+}
+
+MemoryByteArray::MemoryByteArray(byte_t* b, int32_t filled_length)
+ : ByteArray(filled_length, filled_length), b_(b), allocated_(false) {
+ assert(b);
+}
+
+MemoryByteArray::~MemoryByteArray() {
+ Close();
+}
+
+int32_t MemoryByteArray::CopyTo(OutputStream* os,
+ int32_t offset,
+ int32_t length) {
+ assert(os);
+ os->Write(b_, offset, length);
+ return length;
+}
+
+void MemoryByteArray::Init() {
+ if (allocated_ && b_ == NULL) {
+ b_ = new byte_t[Size()];
+ memset(b_, 0, Size());
+ }
+}
+
+void MemoryByteArray::InternalPut(int32_t index, byte_t b) {
+ Init();
+ b_[index] = b;
+}
+
+int32_t MemoryByteArray::InternalPut(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length) {
+ assert(b);
+ Init();
+ memcpy(b_ + index, b + offset, length);
+ return length;
+}
+
+byte_t MemoryByteArray::InternalGet(int32_t index) {
+ Init();
+ return b_[index];
+}
+
+int32_t MemoryByteArray::InternalGet(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length) {
+ assert(b);
+ Init();
+ memcpy(b + offset, b_ + index, length);
+ return length;
+}
+
+void MemoryByteArray::Close() {
+ if (allocated_ && b_) {
+ delete[] b_;
+ }
+ b_ = NULL;
+}
+
+byte_t* MemoryByteArray::Begin() {
+ Init();
+ return b_;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/memory_byte_array.h b/chromium/third_party/sfntly/cpp/src/sfntly/data/memory_byte_array.h
new file mode 100644
index 00000000000..838fd1aca51
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/memory_byte_array.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_MEMORY_BYTE_ARRAY_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_MEMORY_BYTE_ARRAY_H_
+
+#include "sfntly/data/byte_array.h"
+
+namespace sfntly {
+
+class MemoryByteArray : public ByteArray, public RefCounted<MemoryByteArray> {
+ public:
+ // Construct a new MemoryByteArray with a new array of the size given. It is
+ // assumed that none of the array is filled and readable.
+ explicit MemoryByteArray(int32_t length);
+
+ // Note: not implemented due to dangerous operations in constructor.
+ //explicit MemoryByteArray(ByteVector* b);
+
+ // Construct a new MemoryByteArray using byte array.
+ // @param b the byte array that provides the actual storage
+ // @param filled_length the index of the last byte in the array has data
+ // Note: This is different from Java version, it does not take over the
+ // ownership of b. Caller is responsible for handling the lifetime
+ // of b. C++ port also assumes filled_length is buffer_length since
+ // there is not a reliable way to identify the actual size of buffer.
+ MemoryByteArray(byte_t* b, int32_t filled_length);
+
+ virtual ~MemoryByteArray();
+ virtual int32_t CopyTo(OutputStream* os, int32_t offset, int32_t length);
+
+ // Make gcc -Woverloaded-virtual happy.
+ virtual int32_t CopyTo(ByteArray* array) { return ByteArray::CopyTo(array); }
+ virtual int32_t CopyTo(ByteArray* array, int32_t offset, int32_t length) {
+ return ByteArray::CopyTo(array, offset, length);
+ }
+ virtual int32_t CopyTo(int32_t dst_offset,
+ ByteArray* array,
+ int32_t src_offset,
+ int32_t length) {
+ return ByteArray::CopyTo(dst_offset, array, src_offset, length);
+ }
+ virtual int32_t CopyTo(OutputStream* os) { return ByteArray::CopyTo(os); }
+
+ protected:
+ virtual void InternalPut(int32_t index, byte_t b);
+ virtual int32_t InternalPut(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length);
+ virtual byte_t InternalGet(int32_t index);
+ virtual int32_t InternalGet(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length);
+ virtual void Close();
+ virtual byte_t* Begin();
+
+ private:
+ void Init(); // C++ port only, used to allocate memory outside constructor.
+
+ byte_t* b_;
+ bool allocated_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_MEMORY_BYTE_ARRAY_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/readable_font_data.cc b/chromium/third_party/sfntly/cpp/src/sfntly/data/readable_font_data.cc
new file mode 100644
index 00000000000..06d783f2e33
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/readable_font_data.cc
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/data/readable_font_data.h"
+
+#include <stdio.h>
+
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/data/writable_font_data.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+
+ReadableFontData::ReadableFontData(ByteArray* array)
+ : FontData(array),
+ checksum_set_(false),
+ checksum_(0) {
+}
+
+ReadableFontData::~ReadableFontData() {}
+
+// TODO(arthurhsu): re-investigate the memory model of this function. It's
+// not too useful without copying, but it's not performance
+// savvy to do copying.
+CALLER_ATTACH
+ReadableFontData* ReadableFontData::CreateReadableFontData(ByteVector* b) {
+ assert(b);
+ ByteArrayPtr ba = new MemoryByteArray(b->size());
+ ba->Put(0, b);
+ ReadableFontDataPtr wfd = new ReadableFontData(ba);
+ return wfd.Detach();
+}
+
+int64_t ReadableFontData::Checksum() {
+ AutoLock lock(checksum_lock_);
+ if (!checksum_set_) {
+ ComputeChecksum();
+ }
+ return checksum_;
+}
+
+void ReadableFontData::SetCheckSumRanges(const IntegerList& ranges) {
+ checksum_range_ = ranges;
+ checksum_set_ = false; // UNIMPLEMENTED: atomicity
+}
+
+int32_t ReadableFontData::ReadUByte(int32_t index) {
+ int32_t b = array_->Get(BoundOffset(index));
+#if !defined (SFNTLY_NO_EXCEPTION)
+ if (b < 0) {
+ throw IndexOutOfBoundException(
+ "Index attempted to be read from is out of bounds", index);
+ }
+#endif
+ return b;
+}
+
+int32_t ReadableFontData::ReadByte(int32_t index) {
+ int32_t b = array_->Get(BoundOffset(index));
+#if !defined (SFNTLY_NO_EXCEPTION)
+ if (b < 0) {
+ throw IndexOutOfBoundException(
+ "Index attempted to be read from is out of bounds", index);
+ }
+#endif
+ return (b << 24) >> 24;
+}
+
+int32_t ReadableFontData::ReadBytes(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length) {
+ return array_->Get(BoundOffset(index), b, offset, BoundLength(index, length));
+}
+
+int32_t ReadableFontData::ReadChar(int32_t index) {
+ return ReadUByte(index);
+}
+
+int32_t ReadableFontData::ReadUShort(int32_t index) {
+ return 0xffff & (ReadUByte(index) << 8 | ReadUByte(index + 1));
+}
+
+int32_t ReadableFontData::ReadShort(int32_t index) {
+ return ((ReadByte(index) << 8 | ReadUByte(index + 1)) << 16) >> 16;
+}
+
+int32_t ReadableFontData::ReadUInt24(int32_t index) {
+ return 0xffffff & (ReadUByte(index) << 16 |
+ ReadUByte(index + 1) << 8 |
+ ReadUByte(index + 2));
+}
+
+int64_t ReadableFontData::ReadULong(int32_t index) {
+ return 0xffffffffL & (ReadUByte(index) << 24 |
+ ReadUByte(index + 1) << 16 |
+ ReadUByte(index + 2) << 8 |
+ ReadUByte(index + 3));
+}
+
+int32_t ReadableFontData::ReadULongAsInt(int32_t index) {
+ int64_t ulong = ReadULong(index);
+#if !defined (SFNTLY_NO_EXCEPTION)
+ if ((ulong & 0x80000000) == 0x80000000) {
+ throw ArithmeticException("Long value too large to fit into an integer.");
+ }
+#endif
+ return static_cast<int32_t>(ulong);
+}
+
+int64_t ReadableFontData::ReadULongLE(int32_t index) {
+ return 0xffffffffL & (ReadUByte(index) |
+ ReadUByte(index + 1) << 8 |
+ ReadUByte(index + 2) << 16 |
+ ReadUByte(index + 3) << 24);
+}
+
+int32_t ReadableFontData::ReadLong(int32_t index) {
+ return ReadByte(index) << 24 |
+ ReadUByte(index + 1) << 16 |
+ ReadUByte(index + 2) << 8 |
+ ReadUByte(index + 3);
+}
+
+int32_t ReadableFontData::ReadFixed(int32_t index) {
+ return ReadLong(index);
+}
+
+int64_t ReadableFontData::ReadDateTimeAsLong(int32_t index) {
+ return (int64_t)ReadULong(index) << 32 | ReadULong(index + 4);
+}
+
+int32_t ReadableFontData::ReadFWord(int32_t index) {
+ return ReadShort(index);
+}
+
+int32_t ReadableFontData::ReadFUFWord(int32_t index) {
+ return ReadUShort(index);
+}
+
+int32_t ReadableFontData::CopyTo(OutputStream* os) {
+ return array_->CopyTo(os, BoundOffset(0), Length());
+}
+
+int32_t ReadableFontData::CopyTo(WritableFontData* wfd) {
+ return array_->CopyTo(wfd->BoundOffset(0),
+ wfd->array_,
+ BoundOffset(0),
+ Length());
+}
+
+int32_t ReadableFontData::CopyTo(ByteArray* ba) {
+ return array_->CopyTo(ba, BoundOffset(0), Length());
+}
+
+int32_t ReadableFontData::SearchUShort(int32_t start_index,
+ int32_t start_offset,
+ int32_t end_index,
+ int32_t end_offset,
+ int32_t length,
+ int32_t key) {
+ int32_t location = 0;
+ int32_t bottom = 0;
+ int32_t top = length;
+ while (top != bottom) {
+ location = (top + bottom) / 2;
+ int32_t location_start = ReadUShort(start_index + location * start_offset);
+ if (key < location_start) {
+ // location is below current location
+ top = location;
+ } else {
+ // is key below the upper bound?
+ int32_t location_end = ReadUShort(end_index + location * end_offset);
+#if defined (SFNTLY_DEBUG_FONTDATA)
+ fprintf(stderr, "**start: %d; end: %d\n", location_start, location_end);
+#endif
+ if (key <= location_end) {
+ return location;
+ } else {
+ // location is above the current location
+ bottom = location + 1;
+ }
+ }
+ }
+ return -1;
+}
+
+int32_t ReadableFontData::SearchUShort(int32_t start_index,
+ int32_t start_offset,
+ int32_t length,
+ int32_t key) {
+ int32_t location = 0;
+ int32_t bottom = 0;
+ int32_t top = length;
+ while (top != bottom) {
+ location = (top + bottom) / 2;
+ int32_t location_start = ReadUShort(start_index + location * start_offset);
+ if (key < location_start) {
+ // location is below current location
+ top = location;
+ } else if (key > location_start) {
+ // location is above current location
+ bottom = location + 1;
+ } else {
+ return location;
+ }
+ }
+ return -1;
+}
+
+int32_t ReadableFontData::SearchULong(int32_t start_index,
+ int32_t start_offset,
+ int32_t end_index,
+ int32_t end_offset,
+ int32_t length,
+ int32_t key) {
+ int32_t location = 0;
+ int32_t bottom = 0;
+ int32_t top = length;
+ while (top != bottom) {
+ location = (top + bottom) / 2;
+ int32_t location_start = ReadULongAsInt(start_index
+ + location * start_offset);
+ if (key < location_start) {
+ // location is below current location
+ top = location;
+ } else {
+ // is key below the upper bound?
+ int32_t location_end = ReadULongAsInt(end_index + location * end_offset);
+#if defined (SFNTLY_DEBUG_FONTDATA)
+ fprintf(stderr, "**start: %d; end: %d\n", location_start, location_end);
+#endif
+ if (key <= location_end) {
+ return location;
+ } else {
+ // location is above the current location
+ bottom = location + 1;
+ }
+ }
+ }
+ return -1;
+}
+
+CALLER_ATTACH FontData* ReadableFontData::Slice(int32_t offset,
+ int32_t length) {
+ if (offset < 0 || offset + length > Size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundsException(
+ "Attempt to bind data outside of its limits");
+#endif
+ return NULL;
+ }
+ FontDataPtr slice = new ReadableFontData(this, offset, length);
+ return slice.Detach();
+}
+
+CALLER_ATTACH FontData* ReadableFontData::Slice(int32_t offset) {
+ if (offset < 0 || offset > Size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundsException(
+ "Attempt to bind data outside of its limits");
+#endif
+ return NULL;
+ }
+ FontDataPtr slice = new ReadableFontData(this, offset);
+ return slice.Detach();
+}
+
+ReadableFontData::ReadableFontData(ReadableFontData* data, int32_t offset)
+ : FontData(data, offset),
+ checksum_set_(false),
+ checksum_(0) {
+}
+
+ReadableFontData::ReadableFontData(ReadableFontData* data,
+ int32_t offset,
+ int32_t length)
+ : FontData(data, offset, length),
+ checksum_set_(false),
+ checksum_(0) {
+}
+
+void ReadableFontData::ComputeChecksum() {
+ // TODO(arthurhsu): IMPLEMENT: synchronization/atomicity
+ int64_t sum = 0;
+ if (checksum_range_.empty()) {
+ sum = ComputeCheckSum(0, Length());
+ } else {
+ for (uint32_t low_bound_index = 0; low_bound_index < checksum_range_.size();
+ low_bound_index += 2) {
+ int32_t low_bound = checksum_range_[low_bound_index];
+ int32_t high_bound = (low_bound_index == checksum_range_.size() - 1) ?
+ Length() :
+ checksum_range_[low_bound_index + 1];
+ sum += ComputeCheckSum(low_bound, high_bound);
+ }
+ }
+
+ checksum_ = sum & 0xffffffffL;
+ checksum_set_ = true;
+}
+
+int64_t ReadableFontData::ComputeCheckSum(int32_t low_bound,
+ int32_t high_bound) {
+ int64_t sum = 0;
+ // Checksum all whole 4-byte chunks.
+ for (int32_t i = low_bound; i <= high_bound - 4; i += 4) {
+ sum += ReadULong(i);
+ }
+
+ // Add last fragment if not 4-byte multiple
+ int32_t off = high_bound & -4;
+ if (off < high_bound) {
+ int32_t b3 = ReadUByte(off);
+ int32_t b2 = (off + 1 < high_bound) ? ReadUByte(off + 1) : 0;
+ int32_t b1 = (off + 2 < high_bound) ? ReadUByte(off + 2) : 0;
+ int32_t b0 = 0;
+ sum += (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
+ }
+ return sum;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/readable_font_data.h b/chromium/third_party/sfntly/cpp/src/sfntly/data/readable_font_data.h
new file mode 100644
index 00000000000..b43c6260415
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/readable_font_data.h
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_
+
+#include "sfntly/data/font_data.h"
+#include "sfntly/port/lock.h"
+
+namespace sfntly {
+
+class WritableFontData;
+class OutputStream;
+
+// Writable font data wrapper. Supports reading of data primitives in the
+// TrueType / OpenType spec.
+// The data types used are as listed:
+// BYTE 8-bit unsigned integer.
+// CHAR 8-bit signed integer.
+// USHORT 16-bit unsigned integer.
+// SHORT 16-bit signed integer.
+// UINT24 24-bit unsigned integer.
+// ULONG 32-bit unsigned integer.
+// LONG 32-bit signed integer.
+// Fixed 32-bit signed fixed-point number (16.16)
+// FUNIT Smallest measurable distance in the em space.
+// FWORD 16-bit signed integer (SHORT) that describes a quantity in FUnits.
+// UFWORD 16-bit unsigned integer (USHORT) that describes a quantity in
+// FUnits.
+// F2DOT14 16-bit signed fixed number with the low 14 bits of fraction (2.14)
+// LONGDATETIME Date represented in number of seconds since 12:00 midnight,
+// January 1, 1904. The value is represented as a signed 64-bit
+// integer.
+
+class ReadableFontData : public FontData,
+ public RefCounted<ReadableFontData> {
+ public:
+ explicit ReadableFontData(ByteArray* array);
+ virtual ~ReadableFontData();
+
+ static CALLER_ATTACH ReadableFontData* CreateReadableFontData(ByteVector* b);
+
+ // Gets a computed checksum for the data. This checksum uses the OpenType spec
+ // calculation. Every ULong value (32 bit unsigned) in the data is summed and
+ // the resulting value is truncated to 32 bits. If the data length in bytes is
+ // not an integral multiple of 4 then any remaining bytes are treated as the
+ // start of a 4 byte sequence whose remaining bytes are zero.
+ // @return the checksum
+ int64_t Checksum();
+
+ // Sets the bounds to use for computing the checksum. These bounds are in
+ // begin and end pairs. If an odd number is given then the final range is
+ // assumed to extend to the end of the data. The lengths of each range must be
+ // a multiple of 4.
+ // @param ranges the range bounds to use for the checksum
+ void SetCheckSumRanges(const IntegerList& ranges);
+
+ // Read the UBYTE at the given index.
+ // @param index index into the font data
+ // @return the UBYTE; -1 if outside the bounds of the font data
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t ReadUByte(int32_t index);
+
+ // Read the BYTE at the given index.
+ // @param index index into the font data
+ // @return the BYTE
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t ReadByte(int32_t index);
+
+ // Read the bytes at the given index into the array.
+ // @param index index into the font data
+ // @param b the destination for the bytes read
+ // @param offset offset in the byte array to place the bytes
+ // @param length the length of bytes to read
+ // @return the number of bytes actually read; -1 if the index is outside the
+ // bounds of the font data
+ virtual int32_t ReadBytes(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length);
+
+ // Read the CHAR at the given index.
+ // @param index index into the font data
+ // @return the CHAR
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t ReadChar(int32_t index);
+
+ // Read the USHORT at the given index.
+ // @param index index into the font data
+ // @return the USHORT
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t ReadUShort(int32_t index);
+
+ // Read the SHORT at the given index.
+ // @param index index into the font data
+ // @return the SHORT
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t ReadShort(int32_t index);
+
+ // Read the UINT24 at the given index.
+ // @param index index into the font data
+ // @return the UINT24
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t ReadUInt24(int32_t index);
+
+ // Read the ULONG at the given index.
+ // @param index index into the font data
+ // @return the ULONG
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int64_t ReadULong(int32_t index);
+
+ // Read the ULONG at the given index as int32_t.
+ // @param index index into the font data
+ // @return the ULONG
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t ReadULongAsInt(int32_t index);
+
+ // Read the ULONG at the given index, little-endian variant
+ // @param index index into the font data
+ // @return the ULONG
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int64_t ReadULongLE(int32_t index);
+
+ // Read the LONG at the given index.
+ // @param index index into the font data
+ // @return the LONG
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t ReadLong(int32_t index);
+
+ // Read the Fixed at the given index.
+ // @param index index into the font data
+ // @return the Fixed
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t ReadFixed(int32_t index);
+
+ // Read the LONGDATETIME at the given index.
+ // @param index index into the font data
+ // @return the LONGDATETIME
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int64_t ReadDateTimeAsLong(int32_t index);
+
+ // Read the FWORD at the given index.
+ // @param index index into the font data
+ // @return the FWORD
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t ReadFWord(int32_t index);
+
+ // Read the UFWORD at the given index.
+ // @param index index into the font data
+ // @return the UFWORD
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t ReadFUFWord(int32_t index);
+
+ // Note: Not ported because they just throw UnsupportedOperationException()
+ // in Java.
+ /*
+ virtual int32_t ReadFUnit(int32_t index);
+ virtual int64_t ReadF2Dot14(int32_t index);
+ */
+
+ // Copy the FontData to an OutputStream.
+ // @param os the destination
+ // @return number of bytes copied
+ // @throws IOException
+ virtual int32_t CopyTo(OutputStream* os);
+
+ // Copy the FontData to a WritableFontData.
+ // @param wfd the destination
+ // @return number of bytes copied
+ // @throws IOException
+ virtual int32_t CopyTo(WritableFontData* wfd);
+
+ // Make gcc -Woverloaded-virtual happy.
+ virtual int32_t CopyTo(ByteArray* ba);
+
+ // Search for the key value in the range tables provided.
+ // The search looks through the start-end pairs looking for the key value. It
+ // is assumed that the start-end pairs are both represented by UShort values,
+ // ranges do not overlap, and are monotonically increasing.
+ // @param startIndex the position to read the first start value from
+ // @param startOffset the offset between subsequent start values
+ // @param endIndex the position to read the first end value from
+ // @param endOffset the offset between subsequent end values
+ // @param length the number of start-end pairs
+ // @param key the value to search for
+ // @return the index of the start-end pairs in which the key was found; -1
+ // otherwise
+ int32_t SearchUShort(int32_t start_index,
+ int32_t start_offset,
+ int32_t end_index,
+ int32_t end_offset,
+ int32_t length,
+ int32_t key);
+
+ // Search for the key value in the table provided.
+ // The search looks through the values looking for the key value. It is
+ // assumed that the are represented by UShort values and are monotonically
+ // increasing.
+ // @param startIndex the position to read the first start value from
+ // @param startOffset the offset between subsequent start values
+ // @param length the number of start-end pairs
+ // @param key the value to search for
+ // @return the index of the start-end pairs in which the key was found; -1
+ // otherwise
+ int32_t SearchUShort(int32_t start_index,
+ int32_t start_offset,
+ int32_t length,
+ int32_t key);
+
+ // Search for the key value in the range tables provided.
+ // The search looks through the start-end pairs looking for the key value. It
+ // is assumed that the start-end pairs are both represented by ULong values
+ // that can be represented within 31 bits, ranges do not overlap, and are
+ // monotonically increasing.
+ // @param startIndex the position to read the first start value from
+ // @param startOffset the offset between subsequent start values
+ // @param endIndex the position to read the first end value from
+ // @param endOffset the offset between subsequent end values
+ // @param length the number of start-end pairs
+ // @param key the value to search for
+ // @return the index of the start-end pairs in which the key was found; -1
+ // otherwise
+ int32_t SearchULong(int32_t start_index,
+ int32_t start_offset,
+ int32_t end_index,
+ int32_t end_offset,
+ int32_t length,
+ int32_t key);
+
+
+ // TODO(arthurhsu): IMPLEMENT
+ /*
+ virtual int32_t ReadFUnit(int32_t index);
+ virtual int64_t ReadF2Dot14(int32_t index);
+ virtual int64_t ReadLongDateTime(int32_t index);
+ */
+
+ // Makes a slice of this FontData. The returned slice will share the data with
+ // the original FontData.
+ // @param offset the start of the slice
+ // @param length the number of bytes in the slice
+ // @return a slice of the original FontData
+ // Note: C++ polymorphism requires return type to be consistent
+ virtual CALLER_ATTACH FontData* Slice(int32_t offset, int32_t length);
+
+ // Makes a bottom bound only slice of this array. The returned slice will
+ // share the data with the original FontData.
+ // @param offset the start of the slice
+ // @return a slice of the original FontData
+ // Note: C++ polymorphism requires return type to be consistent
+ virtual CALLER_ATTACH FontData* Slice(int32_t offset);
+
+ // Not Ported: toString()
+
+ protected:
+ // Constructor. Creates a bounded wrapper of another ReadableFontData from the
+ // given offset until the end of the original ReadableFontData.
+ // @param data data to wrap
+ // @param offset the start of this data's view of the original data
+ ReadableFontData(ReadableFontData* data, int32_t offset);
+
+ // Constructor. Creates a bounded wrapper of another ReadableFontData from the
+ // given offset until the end of the original ReadableFontData.
+ // @param data data to wrap
+ // @param offset the start of this data's view of the original data
+ // @param length the length of the other FontData to use
+ ReadableFontData(ReadableFontData* data, int32_t offset, int32_t length);
+
+ private:
+ // Compute the checksum for the font data using any ranges set for the
+ // calculation.
+ void ComputeChecksum();
+
+ // Do the actual computation of the checksum for a range using the
+ // TrueType/OpenType checksum algorithm. The range used is from the low bound
+ // to the high bound in steps of four bytes. If any of the bytes within that 4
+ // byte segment are not readable then it will considered a zero for
+ // calculation.
+ // Only called from within a synchronized method so it does not need to be
+ // synchronized itself.
+ // @param lowBound first position to start a 4 byte segment on
+ // @param highBound last possible position to start a 4 byte segment on
+ // @return the checksum for the total range
+ int64_t ComputeCheckSum(int32_t low_bound, int32_t high_bound);
+
+ Lock checksum_lock_;
+ bool checksum_set_;
+ int64_t checksum_;
+ IntegerList checksum_range_;
+};
+typedef Ptr<ReadableFontData> ReadableFontDataPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_READABLE_FONT_DATA_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/writable_font_data.cc b/chromium/third_party/sfntly/cpp/src/sfntly/data/writable_font_data.cc
new file mode 100644
index 00000000000..7f6f72f533e
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/writable_font_data.cc
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/data/writable_font_data.h"
+
+#include "sfntly/data/memory_byte_array.h"
+#include "sfntly/data/growable_memory_byte_array.h"
+
+namespace sfntly {
+
+WritableFontData::WritableFontData(ByteArray* ba) : ReadableFontData(ba) {
+}
+
+WritableFontData::~WritableFontData() {}
+
+// static
+CALLER_ATTACH
+WritableFontData* WritableFontData::CreateWritableFontData(int32_t length) {
+ ByteArrayPtr ba;
+ if (length > 0) {
+ ba = new MemoryByteArray(length);
+ ba->SetFilledLength(length);
+ } else {
+ ba = new GrowableMemoryByteArray();
+ }
+ WritableFontDataPtr wfd = new WritableFontData(ba);
+ return wfd.Detach();
+}
+
+// TODO(arthurhsu): re-investigate the memory model of this function. It's
+// not too useful without copying, but it's not performance
+// savvy to do copying.
+CALLER_ATTACH
+WritableFontData* WritableFontData::CreateWritableFontData(ByteVector* b) {
+ ByteArrayPtr ba = new GrowableMemoryByteArray();
+ ba->Put(0, b);
+ WritableFontDataPtr wfd = new WritableFontData(ba);
+ return wfd.Detach();
+}
+
+int32_t WritableFontData::WriteByte(int32_t index, byte_t b) {
+ array_->Put(BoundOffset(index), b);
+ return 1;
+}
+
+int32_t WritableFontData::WriteBytes(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length) {
+ return array_->Put(BoundOffset(index),
+ b,
+ offset,
+ BoundLength(index, length));
+}
+
+int32_t WritableFontData::WriteBytes(int32_t index, ByteVector* b) {
+ assert(b);
+ return WriteBytes(index, &((*b)[0]), 0, b->size());
+}
+
+int32_t WritableFontData::WriteBytesPad(int32_t index,
+ ByteVector* b,
+ int32_t offset,
+ int32_t length,
+ byte_t pad) {
+ int32_t written =
+ array_->Put(BoundOffset(index),
+ &((*b)[0]),
+ offset,
+ BoundLength(index,
+ std::min<int32_t>(length, b->size() - offset)));
+ written += WritePadding(written + index, length - written, pad);
+ return written;
+}
+
+int32_t WritableFontData::WritePadding(int32_t index, int32_t count) {
+ return WritePadding(index, count, (byte_t)0);
+}
+
+int32_t WritableFontData::WritePadding(int32_t index, int32_t count,
+ byte_t pad) {
+ for (int32_t i = 0; i < count; ++i) {
+ array_->Put(index + i, pad);
+ }
+ return count;
+}
+
+int32_t WritableFontData::WriteChar(int32_t index, byte_t c) {
+ return WriteByte(index, c);
+}
+
+int32_t WritableFontData::WriteUShort(int32_t index, int32_t us) {
+ WriteByte(index, (byte_t)((us >> 8) & 0xff));
+ WriteByte(index + 1, (byte_t)(us & 0xff));
+ return 2;
+}
+
+int32_t WritableFontData::WriteUShortLE(int32_t index, int32_t us) {
+ WriteByte(index, (byte_t)(us & 0xff));
+ WriteByte(index + 1, (byte_t)((us >> 8) & 0xff));
+ return 2;
+}
+
+int32_t WritableFontData::WriteShort(int32_t index, int32_t s) {
+ return WriteUShort(index, s);
+}
+
+int32_t WritableFontData::WriteUInt24(int32_t index, int32_t ui) {
+ WriteByte(index, (byte_t)((ui >> 16) & 0xff));
+ WriteByte(index + 1, (byte_t)((ui >> 8) & 0xff));
+ WriteByte(index + 2, (byte_t)(ui & 0xff));
+ return 3;
+}
+
+int32_t WritableFontData::WriteULong(int32_t index, int64_t ul) {
+ WriteByte(index, (byte_t)((ul >> 24) & 0xff));
+ WriteByte(index + 1, (byte_t)((ul >> 16) & 0xff));
+ WriteByte(index + 2, (byte_t)((ul >> 8) & 0xff));
+ WriteByte(index + 3, (byte_t)(ul & 0xff));
+ return 4;
+}
+
+int32_t WritableFontData::WriteULongLE(int32_t index, int64_t ul) {
+ WriteByte(index, (byte_t)(ul & 0xff));
+ WriteByte(index + 1, (byte_t)((ul >> 8) & 0xff));
+ WriteByte(index + 2, (byte_t)((ul >> 16) & 0xff));
+ WriteByte(index + 3, (byte_t)((ul >> 24) & 0xff));
+ return 4;
+}
+
+int32_t WritableFontData::WriteLong(int32_t index, int64_t l) {
+ return WriteULong(index, l);
+}
+
+int32_t WritableFontData::WriteFixed(int32_t index, int32_t f) {
+ return WriteLong(index, f);
+}
+
+int32_t WritableFontData::WriteDateTime(int32_t index, int64_t date) {
+ WriteULong(index, (date >> 32) & 0xffffffff);
+ WriteULong(index + 4, date & 0xffffffff);
+ return 8;
+}
+
+void WritableFontData::CopyFrom(InputStream* is, int32_t length) {
+ array_->CopyFrom(is, length);
+}
+
+void WritableFontData::CopyFrom(InputStream* is) {
+ array_->CopyFrom(is);
+}
+
+CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset,
+ int32_t length) {
+ if (offset < 0 || offset + length > Size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundsException(
+ "Attempt to bind data outside of its limits");
+#endif
+ return NULL;
+ }
+ FontDataPtr slice = new WritableFontData(this, offset, length);
+ return slice.Detach();
+}
+
+CALLER_ATTACH FontData* WritableFontData::Slice(int32_t offset) {
+ if (offset > Size()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundsException(
+ "Attempt to bind data outside of its limits");
+#endif
+ return NULL;
+ }
+ FontDataPtr slice = new WritableFontData(this, offset);
+ return slice.Detach();
+}
+
+WritableFontData::WritableFontData(WritableFontData* data, int32_t offset)
+ : ReadableFontData(data, offset) {
+}
+
+WritableFontData::WritableFontData(WritableFontData* data,
+ int32_t offset,
+ int32_t length)
+ : ReadableFontData(data, offset, length) {
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/data/writable_font_data.h b/chromium/third_party/sfntly/cpp/src/sfntly/data/writable_font_data.h
new file mode 100644
index 00000000000..d2a049eb55a
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/data/writable_font_data.h
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_DATA_WRITABLE_FONT_DATA_H_
+#define SFNTLY_CPP_SRC_SFNTLY_DATA_WRITABLE_FONT_DATA_H_
+
+#include "sfntly/data/readable_font_data.h"
+
+namespace sfntly {
+
+// Writable font data wrapper. Supports writing of data primitives in the
+// TrueType / OpenType spec.
+class WritableFontData : public ReadableFontData {
+ public:
+ explicit WritableFontData(ByteArray* ba);
+ virtual ~WritableFontData();
+
+ // Constructs a writable font data object. If the length is specified as
+ // positive then a fixed size font data object will be created. If the length
+ // is zero or less then a growable font data object will be created and the
+ // size will be used as an estimate to help in allocating the original space.
+ // @param length if length > 0 create a fixed length font data; otherwise
+ // create a growable font data
+ // @return a new writable font data
+ static CALLER_ATTACH WritableFontData* CreateWritableFontData(int32_t length);
+
+ // Constructs a writable font data object. The new font data object will wrap
+ // the bytes passed in to the factory and it will take make a copy of those
+ // bytes.
+ // @param b the byte vector to wrap
+ // @return a new writable font data
+ static CALLER_ATTACH WritableFontData* CreateWritableFontData(ByteVector* b);
+
+ // Write a byte at the given index.
+ // @param index index into the font data
+ // @param b the byte to write
+ // @return the number of bytes written
+ virtual int32_t WriteByte(int32_t index, byte_t b);
+
+ // Write the bytes from the array.
+ // @param index index into the font data
+ // @param b the source for the bytes to be written
+ // @param offset offset in the byte array
+ // @param length the length of the bytes to be written
+ // @return the number of bytes actually written; -1 if the index is outside
+ // the FontData's range
+ virtual int32_t WriteBytes(int32_t index,
+ byte_t* b,
+ int32_t offset,
+ int32_t length);
+
+ // Write the bytes from the array.
+ // @param index index into the font data
+ // @param b the source for the bytes to be written
+ // @return the number of bytes actually written; -1 if the index is outside
+ // the FontData's range
+ virtual int32_t WriteBytes(int32_t index, ByteVector* b);
+
+ // Write the bytes from the array and pad if necessary.
+ // Write to the length given using the byte array provided and if there are
+ // not enough bytes in the array then pad to the requested length using the
+ // pad byte specified.
+ // @param index index into the font data
+ // @param b the source for the bytes to be written
+ // @param offset offset in the byte array
+ // @param length the length of the bytes to be written
+ // @param pad the padding byte to be used if necessary
+ // @return the number of bytes actually written
+ virtual int32_t WriteBytesPad(int32_t index,
+ ByteVector* b,
+ int32_t offset,
+ int32_t length,
+ byte_t pad);
+
+ // Writes padding to the FontData. The padding byte written is 0x00.
+ // @param index index into the font data
+ // @param count the number of pad bytes to write
+ // @return the number of pad bytes written
+ virtual int32_t WritePadding(int32_t index, int32_t count);
+
+ // Writes padding to the FontData.
+ // @param index index into the font data
+ // @param count the number of pad bytes to write
+ // @param pad the byte value to use as padding
+ // @return the number of pad bytes written
+ virtual int32_t WritePadding(int32_t index, int32_t count, byte_t pad);
+
+ // Write the CHAR at the given index.
+ // @param index index into the font data
+ // @param c the CHAR
+ // @return the number of bytes actually written
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t WriteChar(int32_t index, byte_t c);
+
+ // Write the USHORT at the given index.
+ // @param index index into the font data
+ // @param us the USHORT
+ // @return the number of bytes actually written
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t WriteUShort(int32_t index, int32_t us);
+
+ // Write the USHORT at the given index in little endian format.
+ // @param index index into the font data
+ // @param us the USHORT
+ // @return the number of bytes actually written
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t WriteUShortLE(int32_t index, int32_t us);
+
+ // Write the SHORT at the given index.
+ // @param index index into the font data
+ // @param s the SHORT
+ // @return the number of bytes actually written
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t WriteShort(int32_t index, int32_t s);
+
+ // Write the UINT24 at the given index.
+ // @param index index into the font data
+ // @param ui the UINT24
+ // @return the number of bytes actually written
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t WriteUInt24(int32_t index, int32_t ui);
+
+ // Write the ULONG at the given index.
+ // @param index index into the font data
+ // @param ul the ULONG
+ // @return the number of bytes actually written
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t WriteULong(int32_t index, int64_t ul);
+
+ // Write the ULONG at the given index in little endian format.
+ // @param index index into the font data
+ // @param ul the ULONG
+ // @return the number of bytes actually written
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t WriteULongLE(int32_t index, int64_t ul);
+
+ // Write the LONG at the given index.
+ // @param index index into the font data
+ // @param l the LONG
+ // @return the number of bytes actually written
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t WriteLong(int32_t index, int64_t l);
+
+ // Write the Fixed at the given index.
+ // @param index index into the font data
+ // @param f the Fixed
+ // @return the number of bytes actually written
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t WriteFixed(int32_t index, int32_t f);
+
+ // Write the LONGDATETIME at the given index.
+ // @param index index into the font data
+ // @param date the LONGDATETIME
+ // @return the number of bytes actually written
+ // @throws IndexOutOfBoundsException if index is outside the FontData's range
+ virtual int32_t WriteDateTime(int32_t index, int64_t date);
+
+ // Copy from the InputStream into this FontData.
+ // @param is the source
+ // @param length the number of bytes to copy
+ // @throws IOException
+ virtual void CopyFrom(InputStream* is, int32_t length);
+
+ // Copy everything from the InputStream into this FontData.
+ // @param is the source
+ // @throws IOException
+ virtual void CopyFrom(InputStream* is);
+
+ // Makes a slice of this FontData. The returned slice will share the data with
+ // the original FontData.
+ // @param offset the start of the slice
+ // @param length the number of bytes in the slice
+ // @return a slice of the original FontData
+ virtual CALLER_ATTACH FontData* Slice(int32_t offset, int32_t length);
+
+ // Makes a bottom bound only slice of this array. The returned slice will
+ // share the data with the original FontData.
+ // @param offset the start of the slice
+ // @return a slice of the original FontData
+ virtual CALLER_ATTACH FontData* Slice(int32_t offset);
+
+ private:
+ // Constructor with a lower bound.
+ // @param data other WritableFontData object to share data with
+ // @param offset offset from the other WritableFontData's data
+ WritableFontData(WritableFontData* data, int32_t offset);
+
+ // Constructor with lower bound and a length bound.
+ // @param data other WritableFontData object to share data with
+ // @param offset offset from the other WritableFontData's data
+ // @param length length of other WritableFontData's data to use
+ WritableFontData(WritableFontData* data, int32_t offset, int32_t length);
+};
+typedef Ptr<WritableFontData> WritableFontDataPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_DATA_WRITABLE_FONT_DATA_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/font.cc b/chromium/third_party/sfntly/cpp/src/sfntly/font.cc
new file mode 100644
index 00000000000..347e0c13e97
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/font.cc
@@ -0,0 +1,557 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/font.h"
+
+#include <stdio.h>
+
+#include <functional>
+#include <algorithm>
+#include <map>
+#include <string>
+#include <typeinfo>
+#include <iterator>
+
+#include "sfntly/data/font_input_stream.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/math/fixed1616.h"
+#include "sfntly/math/font_math.h"
+#include "sfntly/port/exception_type.h"
+#include "sfntly/table/core/font_header_table.h"
+#include "sfntly/table/core/horizontal_device_metrics_table.h"
+#include "sfntly/table/core/horizontal_header_table.h"
+#include "sfntly/table/core/horizontal_metrics_table.h"
+#include "sfntly/table/core/maximum_profile_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+#include "sfntly/tag.h"
+
+namespace sfntly {
+
+const int32_t SFNTVERSION_MAJOR = 1;
+const int32_t SFNTVERSION_MINOR = 0;
+
+/******************************************************************************
+ * Font class
+ ******************************************************************************/
+Font::~Font() {}
+
+bool Font::HasTable(int32_t tag) {
+ TableMap::const_iterator result = tables_.find(tag);
+ TableMap::const_iterator end = tables_.end();
+ return (result != end);
+}
+
+Table* Font::GetTable(int32_t tag) {
+ if (!HasTable(tag)) {
+ return NULL;
+ }
+ return tables_[tag];
+}
+
+const TableMap* Font::GetTableMap() {
+ return &tables_;
+}
+
+void Font::Serialize(OutputStream* os, IntegerList* table_ordering) {
+ assert(table_ordering);
+ IntegerList final_table_ordering;
+ GenerateTableOrdering(table_ordering, &final_table_ordering);
+ TableHeaderList table_records;
+ BuildTableHeadersForSerialization(&final_table_ordering, &table_records);
+
+ FontOutputStream fos(os);
+ SerializeHeader(&fos, &table_records);
+ SerializeTables(&fos, &table_records);
+}
+
+Font::Font(int32_t sfnt_version, ByteVector* digest)
+ : sfnt_version_(sfnt_version) {
+ // non-trivial assignments that makes debugging hard if placed in
+ // initialization list
+ digest_ = *digest;
+}
+
+void Font::BuildTableHeadersForSerialization(IntegerList* table_ordering,
+ TableHeaderList* table_headers) {
+ assert(table_headers);
+ assert(table_ordering);
+
+ IntegerList final_table_ordering;
+ GenerateTableOrdering(table_ordering, &final_table_ordering);
+ int32_t table_offset = Offset::kTableRecordBegin + num_tables() *
+ Offset::kTableRecordSize;
+ for (IntegerList::iterator tag = final_table_ordering.begin(),
+ tag_end = final_table_ordering.end();
+ tag != tag_end; ++tag) {
+ if (tables_.find(*tag) == tables_.end()) {
+ continue;
+ }
+ TablePtr table = tables_[*tag];
+ if (table != NULL) {
+ HeaderPtr header =
+ new Header(*tag, table->CalculatedChecksum(), table_offset,
+ table->header()->length());
+ table_headers->push_back(header);
+ table_offset += (table->DataLength() + 3) & ~3;
+ }
+ }
+}
+
+void Font::SerializeHeader(FontOutputStream* fos,
+ TableHeaderList* table_headers) {
+ fos->WriteFixed(sfnt_version_);
+ fos->WriteUShort(table_headers->size());
+ int32_t log2_of_max_power_of_2 = FontMath::Log2(table_headers->size());
+ int32_t search_range = 2 << (log2_of_max_power_of_2 - 1 + 4);
+ fos->WriteUShort(search_range);
+ fos->WriteUShort(log2_of_max_power_of_2);
+ fos->WriteUShort((table_headers->size() * 16) - search_range);
+
+ HeaderTagSortedSet sorted_headers;
+ std::copy(table_headers->begin(),
+ table_headers->end(),
+ std::inserter(sorted_headers, sorted_headers.end()));
+
+ for (HeaderTagSortedSet::iterator record = sorted_headers.begin(),
+ record_end = sorted_headers.end();
+ record != record_end; ++record) {
+ fos->WriteULong((*record)->tag());
+ fos->WriteULong((int32_t)((*record)->checksum()));
+ fos->WriteULong((*record)->offset());
+ fos->WriteULong((*record)->length());
+ }
+}
+
+void Font::SerializeTables(FontOutputStream* fos,
+ TableHeaderList* table_headers) {
+ assert(fos);
+ assert(table_headers);
+ for (TableHeaderList::iterator record = table_headers->begin(),
+ end_of_headers = table_headers->end();
+ record != end_of_headers; ++record) {
+ TablePtr target_table = GetTable((*record)->tag());
+ if (target_table == NULL) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("Table out of sync with font header.");
+#endif
+ return;
+ }
+ int32_t table_size = target_table->Serialize(fos);
+ if (table_size != (*record)->length()) {
+ assert(false);
+ }
+ int32_t filler_size = ((table_size + 3) & ~3) - table_size;
+ for (int32_t i = 0; i < filler_size; ++i) {
+ fos->Write(static_cast<byte_t>(0));
+ }
+ }
+}
+
+void Font::GenerateTableOrdering(IntegerList* default_table_ordering,
+ IntegerList* table_ordering) {
+ assert(default_table_ordering);
+ assert(table_ordering);
+ table_ordering->clear();
+ if (default_table_ordering->empty()) {
+ DefaultTableOrdering(default_table_ordering);
+ }
+
+ typedef std::map<int32_t, bool> Int2Bool;
+ typedef std::pair<int32_t, bool> Int2BoolEntry;
+ Int2Bool tables_in_font;
+ for (TableMap::iterator table = tables_.begin(), table_end = tables_.end();
+ table != table_end; ++table) {
+ tables_in_font.insert(Int2BoolEntry(table->first, false));
+ }
+ for (IntegerList::iterator tag = default_table_ordering->begin(),
+ tag_end = default_table_ordering->end();
+ tag != tag_end; ++tag) {
+ if (HasTable(*tag)) {
+ table_ordering->push_back(*tag);
+ tables_in_font[*tag] = true;
+ }
+ }
+ for (Int2Bool::iterator table = tables_in_font.begin(),
+ table_end = tables_in_font.end();
+ table != table_end; ++table) {
+ if (table->second == false)
+ table_ordering->push_back(table->first);
+ }
+}
+
+void Font::DefaultTableOrdering(IntegerList* default_table_ordering) {
+ assert(default_table_ordering);
+ default_table_ordering->clear();
+ if (HasTable(Tag::CFF)) {
+ default_table_ordering->resize(CFF_TABLE_ORDERING_SIZE);
+ std::copy(CFF_TABLE_ORDERING, CFF_TABLE_ORDERING + CFF_TABLE_ORDERING_SIZE,
+ default_table_ordering->begin());
+ return;
+ }
+ default_table_ordering->resize(TRUE_TYPE_TABLE_ORDERING_SIZE);
+ std::copy(TRUE_TYPE_TABLE_ORDERING,
+ TRUE_TYPE_TABLE_ORDERING + TRUE_TYPE_TABLE_ORDERING_SIZE,
+ default_table_ordering->begin());
+}
+
+/******************************************************************************
+ * Font::Builder class
+ ******************************************************************************/
+Font::Builder::~Builder() {}
+
+CALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(FontFactory* factory,
+ InputStream* is) {
+ FontBuilderPtr builder = new Builder(factory);
+ builder->LoadFont(is);
+ return builder.Detach();
+}
+
+CALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(
+ FontFactory* factory,
+ WritableFontData* wfd,
+ int32_t offset_to_offset_table) {
+ FontBuilderPtr builder = new Builder(factory);
+ builder->LoadFont(wfd, offset_to_offset_table);
+ return builder.Detach();
+}
+
+CALLER_ATTACH Font::Builder* Font::Builder::GetOTFBuilder(
+ FontFactory* factory) {
+ FontBuilderPtr builder = new Builder(factory);
+ return builder.Detach();
+}
+
+bool Font::Builder::ReadyToBuild() {
+ // just read in data with no manipulation
+ if (table_builders_.empty() && !data_blocks_.empty()) {
+ return true;
+ }
+
+ // TODO(stuartg): font level checks - required tables etc?
+ for (TableBuilderMap::iterator table_builder = table_builders_.begin(),
+ table_builder_end = table_builders_.end();
+ table_builder != table_builder_end;
+ ++table_builder) {
+ if (!table_builder->second->ReadyToBuild())
+ return false;
+ }
+ return true;
+}
+
+CALLER_ATTACH Font* Font::Builder::Build() {
+ FontPtr font = new Font(sfnt_version_, &digest_);
+
+ if (!table_builders_.empty()) {
+ // Note: Different from Java. Directly use font->tables_ here to avoid
+ // STL container copying.
+ BuildTablesFromBuilders(font, &table_builders_, &font->tables_);
+ }
+
+ table_builders_.clear();
+ data_blocks_.clear();
+ return font.Detach();
+}
+
+void Font::Builder::SetDigest(ByteVector* digest) {
+ digest_.clear();
+ digest_ = *digest;
+}
+
+void Font::Builder::ClearTableBuilders() {
+ table_builders_.clear();
+}
+
+bool Font::Builder::HasTableBuilder(int32_t tag) {
+ return (table_builders_.find(tag) != table_builders_.end());
+}
+
+Table::Builder* Font::Builder::GetTableBuilder(int32_t tag) {
+ if (HasTableBuilder(tag))
+ return table_builders_[tag];
+ return NULL;
+}
+
+Table::Builder* Font::Builder::NewTableBuilder(int32_t tag) {
+ HeaderPtr header = new Header(tag);
+ TableBuilderPtr builder;
+ builder.Attach(Table::Builder::GetBuilder(header, NULL));
+ table_builders_.insert(TableBuilderEntry(header->tag(), builder));
+ return builder;
+}
+
+Table::Builder* Font::Builder::NewTableBuilder(int32_t tag,
+ ReadableFontData* src_data) {
+ assert(src_data);
+ WritableFontDataPtr data;
+ data.Attach(WritableFontData::CreateWritableFontData(src_data->Length()));
+ // TODO(stuarg): take over original data instead?
+ src_data->CopyTo(data);
+
+ HeaderPtr header = new Header(tag, data->Length());
+ TableBuilderPtr builder;
+ builder.Attach(Table::Builder::GetBuilder(header, data));
+ table_builders_.insert(TableBuilderEntry(tag, builder));
+ return builder;
+}
+
+void Font::Builder::RemoveTableBuilder(int32_t tag) {
+ TableBuilderMap::iterator target = table_builders_.find(tag);
+ if (target != table_builders_.end()) {
+ table_builders_.erase(target);
+ }
+}
+
+Font::Builder::Builder(FontFactory* factory)
+ : factory_(factory),
+ sfnt_version_(Fixed1616::Fixed(SFNTVERSION_MAJOR, SFNTVERSION_MINOR)) {
+}
+
+void Font::Builder::LoadFont(InputStream* is) {
+ // Note: we do not throw exception here for is. This is more of an assertion.
+ assert(is);
+ FontInputStream font_is(is);
+ HeaderOffsetSortedSet records;
+ ReadHeader(&font_is, &records);
+ LoadTableData(&records, &font_is, &data_blocks_);
+ BuildAllTableBuilders(&data_blocks_, &table_builders_);
+ font_is.Close();
+}
+
+void Font::Builder::LoadFont(WritableFontData* wfd,
+ int32_t offset_to_offset_table) {
+ // Note: we do not throw exception here for is. This is more of an assertion.
+ assert(wfd);
+ HeaderOffsetSortedSet records;
+ ReadHeader(wfd, offset_to_offset_table, &records);
+ LoadTableData(&records, wfd, &data_blocks_);
+ BuildAllTableBuilders(&data_blocks_, &table_builders_);
+}
+
+int32_t Font::Builder::SfntWrapperSize() {
+ return Offset::kSfntHeaderSize +
+ (Offset::kTableRecordSize * table_builders_.size());
+}
+
+void Font::Builder::BuildAllTableBuilders(DataBlockMap* table_data,
+ TableBuilderMap* builder_map) {
+ for (DataBlockMap::iterator record = table_data->begin(),
+ record_end = table_data->end();
+ record != record_end; ++record) {
+ TableBuilderPtr builder;
+ builder.Attach(GetTableBuilder(record->first.p_, record->second.p_));
+ builder_map->insert(TableBuilderEntry(record->first->tag(), builder));
+ }
+ InterRelateBuilders(&table_builders_);
+}
+
+CALLER_ATTACH
+Table::Builder* Font::Builder::GetTableBuilder(Header* header,
+ WritableFontData* data) {
+ return Table::Builder::GetBuilder(header, data);
+}
+
+void Font::Builder::BuildTablesFromBuilders(Font* font,
+ TableBuilderMap* builder_map,
+ TableMap* table_map) {
+ UNREFERENCED_PARAMETER(font);
+ InterRelateBuilders(builder_map);
+
+ // Now build all the tables.
+ for (TableBuilderMap::iterator builder = builder_map->begin(),
+ builder_end = builder_map->end();
+ builder != builder_end; ++builder) {
+ TablePtr table;
+ if (builder->second && builder->second->ReadyToBuild()) {
+ table.Attach(down_cast<Table*>(builder->second->Build()));
+ }
+ if (table == NULL) {
+ table_map->clear();
+#if !defined (SFNTLY_NO_EXCEPTION)
+ std::string builder_string = "Unable to build table - ";
+ char* table_name = TagToString(builder->first);
+ builder_string += table_name;
+ delete[] table_name;
+ throw RuntimeException(builder_string.c_str());
+#endif
+ return;
+ }
+ table_map->insert(TableMapEntry(table->header()->tag(), table));
+ }
+}
+
+static Table::Builder* GetBuilder(TableBuilderMap* builder_map, int32_t tag) {
+ if (builder_map) {
+ TableBuilderMap::iterator target = builder_map->find(tag);
+ if (target != builder_map->end()) {
+ return target->second.p_;
+ }
+ }
+
+ return NULL;
+}
+
+void Font::Builder::InterRelateBuilders(TableBuilderMap* builder_map) {
+ Table::Builder* raw_head_builder = GetBuilder(builder_map, Tag::head);
+ FontHeaderTableBuilderPtr header_table_builder;
+ if (raw_head_builder != NULL) {
+ header_table_builder =
+ down_cast<FontHeaderTable::Builder*>(raw_head_builder);
+ }
+
+ Table::Builder* raw_hhea_builder = GetBuilder(builder_map, Tag::hhea);
+ HorizontalHeaderTableBuilderPtr horizontal_header_builder;
+ if (raw_head_builder != NULL) {
+ horizontal_header_builder =
+ down_cast<HorizontalHeaderTable::Builder*>(raw_hhea_builder);
+ }
+
+ Table::Builder* raw_maxp_builder = GetBuilder(builder_map, Tag::maxp);
+ MaximumProfileTableBuilderPtr max_profile_builder;
+ if (raw_maxp_builder != NULL) {
+ max_profile_builder =
+ down_cast<MaximumProfileTable::Builder*>(raw_maxp_builder);
+ }
+
+ Table::Builder* raw_loca_builder = GetBuilder(builder_map, Tag::loca);
+ LocaTableBuilderPtr loca_table_builder;
+ if (raw_loca_builder != NULL) {
+ loca_table_builder = down_cast<LocaTable::Builder*>(raw_loca_builder);
+ }
+
+ Table::Builder* raw_hmtx_builder = GetBuilder(builder_map, Tag::hmtx);
+ HorizontalMetricsTableBuilderPtr horizontal_metrics_builder;
+ if (raw_hmtx_builder != NULL) {
+ horizontal_metrics_builder =
+ down_cast<HorizontalMetricsTable::Builder*>(raw_hmtx_builder);
+ }
+
+#if defined (SFNTLY_EXPERIMENTAL)
+ Table::Builder* raw_hdmx_builder = GetBuilder(builder_map, Tag::hdmx);
+ HorizontalDeviceMetricsTableBuilderPtr hdmx_table_builder;
+ if (raw_hdmx_builder != NULL) {
+ hdmx_table_builder =
+ down_cast<HorizontalDeviceMetricsTable::Builder*>(raw_hdmx_builder);
+ }
+#endif
+
+ // set the inter table data required to build certain tables
+ if (horizontal_metrics_builder != NULL) {
+ if (max_profile_builder != NULL) {
+ horizontal_metrics_builder->SetNumGlyphs(
+ max_profile_builder->NumGlyphs());
+ }
+ if (horizontal_header_builder != NULL) {
+ horizontal_metrics_builder->SetNumberOfHMetrics(
+ horizontal_header_builder->NumberOfHMetrics());
+ }
+ }
+
+ if (loca_table_builder != NULL) {
+ if (max_profile_builder != NULL) {
+ loca_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs());
+ }
+ if (header_table_builder != NULL) {
+ loca_table_builder->set_format_version(
+ header_table_builder->IndexToLocFormat());
+ }
+ }
+
+#if defined (SFNTLY_EXPERIMENTAL)
+ // Note: In C++, hdmx_table_builder can be NULL in a subsetter.
+ if (max_profile_builder != NULL && hdmx_table_builder != NULL) {
+ hdmx_table_builder->SetNumGlyphs(max_profile_builder->NumGlyphs());
+ }
+#endif
+}
+
+void Font::Builder::ReadHeader(FontInputStream* is,
+ HeaderOffsetSortedSet* records) {
+ assert(records);
+ sfnt_version_ = is->ReadFixed();
+ num_tables_ = is->ReadUShort();
+ search_range_ = is->ReadUShort();
+ entry_selector_ = is->ReadUShort();
+ range_shift_ = is->ReadUShort();
+
+ for (int32_t table_number = 0; table_number < num_tables_; ++table_number) {
+ // Need to use temporary vars here. C++ evaluates function parameters from
+ // right to left and thus breaks the order of input stream.
+ int32_t tag = is->ReadULongAsInt();
+ int64_t checksum = is->ReadULong();
+ int32_t offset = is->ReadULongAsInt();
+ int32_t length = is->ReadULongAsInt();
+ HeaderPtr table = new Header(tag, checksum, offset, length);
+ records->insert(table);
+ }
+}
+
+void Font::Builder::ReadHeader(ReadableFontData* fd,
+ int32_t offset,
+ HeaderOffsetSortedSet* records) {
+ assert(records);
+ sfnt_version_ = fd->ReadFixed(offset + Offset::kSfntVersion);
+ num_tables_ = fd->ReadUShort(offset + Offset::kNumTables);
+ search_range_ = fd->ReadUShort(offset + Offset::kSearchRange);
+ entry_selector_ = fd->ReadUShort(offset + Offset::kEntrySelector);
+ range_shift_ = fd->ReadUShort(offset + Offset::kRangeShift);
+
+ int32_t table_offset = offset + Offset::kTableRecordBegin;
+ for (int32_t table_number = 0;
+ table_number < num_tables_;
+ table_number++, table_offset += Offset::kTableRecordSize) {
+ int32_t tag = fd->ReadULongAsInt(table_offset + Offset::kTableTag);
+ int64_t checksum = fd->ReadULong(table_offset + Offset::kTableCheckSum);
+ int32_t offset = fd->ReadULongAsInt(table_offset + Offset::kTableOffset);
+ int32_t length = fd->ReadULongAsInt(table_offset + Offset::kTableLength);
+ HeaderPtr table = new Header(tag, checksum, offset, length);
+ records->insert(table);
+ }
+}
+
+void Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers,
+ FontInputStream* is,
+ DataBlockMap* table_data) {
+ assert(table_data);
+ for (HeaderOffsetSortedSet::iterator table_header = headers->begin(),
+ table_end = headers->end();
+ table_header != table_end;
+ ++table_header) {
+ is->Skip((*table_header)->offset() - is->position());
+ FontInputStream table_is(is, (*table_header)->length());
+ WritableFontDataPtr data;
+ data.Attach(
+ WritableFontData::CreateWritableFontData((*table_header)->length()));
+ data->CopyFrom(&table_is, (*table_header)->length());
+ table_data->insert(DataBlockEntry(*table_header, data));
+ }
+}
+
+void Font::Builder::LoadTableData(HeaderOffsetSortedSet* headers,
+ WritableFontData* fd,
+ DataBlockMap* table_data) {
+ for (HeaderOffsetSortedSet::iterator table_header = headers->begin(),
+ table_end = headers->end();
+ table_header != table_end;
+ ++table_header) {
+ FontDataPtr sliced_data;
+ sliced_data.Attach(
+ fd->Slice((*table_header)->offset(), (*table_header)->length()));
+ WritableFontDataPtr data = down_cast<WritableFontData*>(sliced_data.p_);
+ table_data->insert(DataBlockEntry(*table_header, data));
+ }
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/font.h b/chromium/third_party/sfntly/cpp/src/sfntly/font.h
new file mode 100644
index 00000000000..975e8cc52c9
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/font.h
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_FONT_H_
+#define SFNTLY_CPP_SRC_SFNTLY_FONT_H_
+
+#include <vector>
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/port/type.h"
+#include "sfntly/port/endian.h"
+#include "sfntly/data/font_input_stream.h"
+#include "sfntly/data/font_output_stream.h"
+#include "sfntly/data/writable_font_data.h"
+#include "sfntly/table/table.h"
+
+namespace sfntly {
+
+// Note: following constants are embedded in Font class in Java. They are
+// extracted out for easier reference from other classes. Offset is the
+// one that is kept within class.
+// Platform ids. These are used in a number of places within the font whenever
+// the platform needs to be specified.
+struct PlatformId {
+ enum {
+ kUnknown = -1,
+ kUnicode = 0,
+ kMacintosh = 1,
+ kISO = 2,
+ kWindows = 3,
+ kCustom = 4
+ };
+};
+
+// Unicode encoding ids. These are used in a number of places within the font
+// whenever character encodings need to be specified.
+struct UnicodeEncodingId {
+ enum {
+ kUnknown = -1,
+ kUnicode1_0 = 0,
+ kUnicode1_1 = 1,
+ kISO10646 = 2,
+ kUnicode2_0_BMP = 3,
+ kUnicode2_0 = 4,
+ kUnicodeVariationSequences = 5
+ };
+};
+
+// Windows encoding ids. These are used in a number of places within the font
+// whenever character encodings need to be specified.
+struct WindowsEncodingId {
+ enum {
+ kUnknown = 0xffffffff,
+ kSymbol = 0,
+ kUnicodeUCS2 = 1,
+ kShiftJIS = 2,
+ kPRC = 3,
+ kBig5 = 4,
+ kWansung = 5,
+ kJohab = 6,
+ kUnicodeUCS4 = 10
+ };
+};
+
+// Macintosh encoding ids. These are used in a number of places within the
+// font whenever character encodings need to be specified.
+struct MacintoshEncodingId {
+ // Macintosh Platform Encodings
+ enum {
+ kUnknown = -1,
+ kRoman = 0,
+ kJapanese = 1,
+ kChineseTraditional = 2,
+ kKorean = 3,
+ kArabic = 4,
+ kHebrew = 5,
+ kGreek = 6,
+ kRussian = 7,
+ kRSymbol = 8,
+ kDevanagari = 9,
+ kGurmukhi = 10,
+ kGujarati = 11,
+ kOriya = 12,
+ kBengali = 13,
+ kTamil = 14,
+ kTelugu = 15,
+ kKannada = 16,
+ kMalayalam = 17,
+ kSinhalese = 18,
+ kBurmese = 19,
+ kKhmer = 20,
+ kThai = 21,
+ kLaotian = 22,
+ kGeorgian = 23,
+ kArmenian = 24,
+ kChineseSimplified = 25,
+ kTibetan = 26,
+ kMongolian = 27,
+ kGeez = 28,
+ kSlavic = 29,
+ kVietnamese = 30,
+ kSindhi = 31,
+ kUninterpreted = 32
+ };
+};
+
+class FontFactory;
+
+// An sfnt container font object. This object is immutable and thread safe. To
+// construct one use an instance of Font::Builder.
+class Font : public RefCounted<Font> {
+ public:
+ // A builder for a font object. The builder allows the for the creation of
+ // immutable Font objects. The builder is a one use non-thread safe object and
+ // once the Font object has been created it is no longer usable. To create a
+ // further Font object new builder will be required.
+ class Builder : public RefCounted<Builder> {
+ public:
+ virtual ~Builder();
+
+ static CALLER_ATTACH Builder*
+ GetOTFBuilder(FontFactory* factory, InputStream* is);
+ static CALLER_ATTACH Builder*
+ GetOTFBuilder(FontFactory* factory,
+ WritableFontData* ba,
+ int32_t offset_to_offset_table);
+ static CALLER_ATTACH Builder* GetOTFBuilder(FontFactory* factory);
+
+ // Get the font factory that created this font builder.
+ FontFactory* GetFontFactory() { return factory_; }
+
+ // Is the font ready to build?
+ bool ReadyToBuild();
+
+ // Build the Font. After this call this builder will no longer be usable.
+ CALLER_ATTACH Font* Build();
+
+ // Set a unique fingerprint for the font object.
+ void SetDigest(ByteVector* digest);
+
+ // Clear all table builders.
+ void ClearTableBuilders();
+
+ // Does this font builder have the specified table builder.
+ bool HasTableBuilder(int32_t tag);
+
+ // Get the table builder for the given tag. If there is no builder for that
+ // tag then return a null.
+ Table::Builder* GetTableBuilder(int32_t tag);
+
+ // Creates a new table builder for the table type given by the table id tag.
+ // This new table has been added to the font and will replace any existing
+ // builder for that table.
+ // @return new empty table of the type specified by tag; if tag is not known
+ // then a generic OpenTypeTable is returned
+ virtual Table::Builder* NewTableBuilder(int32_t tag);
+
+ // Creates a new table builder for the table type given by the table id tag.
+ // It makes a copy of the data provided and uses that copy for the table.
+ // This new table has been added to the font and will replace any existing
+ // builder for that table.
+ virtual Table::Builder* NewTableBuilder(int32_t tag,
+ ReadableFontData* src_data);
+
+ // Get a map of the table builders in this font builder accessed by table
+ // tag.
+ virtual TableBuilderMap* table_builders() { return &table_builders_; }
+
+ // Remove the specified table builder from the font builder.
+ // Note: different from Java: we don't return object in removeTableBuilder
+ virtual void RemoveTableBuilder(int32_t tag);
+
+ // Get the number of table builders in the font builder.
+ virtual int32_t number_of_table_builders() {
+ return (int32_t)table_builders_.size();
+ }
+
+ private:
+ explicit Builder(FontFactory* factory);
+ virtual void LoadFont(InputStream* is);
+ virtual void LoadFont(WritableFontData* wfd,
+ int32_t offset_to_offset_table);
+ int32_t SfntWrapperSize();
+ void BuildAllTableBuilders(DataBlockMap* table_data,
+ TableBuilderMap* builder_map);
+ CALLER_ATTACH Table::Builder*
+ GetTableBuilder(Header* header, WritableFontData* data);
+ void BuildTablesFromBuilders(Font* font,
+ TableBuilderMap* builder_map,
+ TableMap* tables);
+ static void InterRelateBuilders(TableBuilderMap* builder_map);
+
+ void ReadHeader(FontInputStream* is,
+ HeaderOffsetSortedSet* records);
+
+ void ReadHeader(ReadableFontData* fd,
+ int32_t offset,
+ HeaderOffsetSortedSet* records);
+
+ void LoadTableData(HeaderOffsetSortedSet* headers,
+ FontInputStream* is,
+ DataBlockMap* table_data);
+
+ void LoadTableData(HeaderOffsetSortedSet* headers,
+ WritableFontData* fd,
+ DataBlockMap* table_data);
+
+ TableBuilderMap table_builders_;
+ FontFactory* factory_; // dumb pointer, avoid circular refcounting
+ int32_t sfnt_version_;
+ int32_t num_tables_;
+ int32_t search_range_;
+ int32_t entry_selector_;
+ int32_t range_shift_;
+ DataBlockMap data_blocks_;
+ ByteVector digest_;
+ };
+
+ virtual ~Font();
+
+ // Gets the sfnt version set in the sfnt wrapper of the font.
+ int32_t sfnt_version() { return sfnt_version_; }
+
+ // Gets a copy of the fonts digest that was created when the font was read. If
+ // no digest was set at creation time then the return result will be null.
+ ByteVector* digest() { return &digest_; }
+
+ // Get the checksum for this font.
+ int64_t checksum() { return checksum_; }
+
+ // Get the number of tables in this font.
+ int32_t num_tables() { return (int32_t)tables_.size(); }
+
+ // Whether the font has a particular table.
+ bool HasTable(int32_t tag);
+
+ // UNIMPLEMENTED: public Iterator<? extends Table> iterator
+
+ // Get the table in this font with the specified id.
+ // @param tag the identifier of the table
+ // @return the table specified if it exists; null otherwise
+ // C++ port: rename table() to GetTable()
+ Table* GetTable(int32_t tag);
+
+ // Get a map of the tables in this font accessed by table tag.
+ // @return an unmodifiable view of the tables in this font
+ // Note: renamed tableMap() to GetTableMap()
+ const TableMap* GetTableMap();
+
+ // UNIMPLEMENTED: toString()
+
+ // Serialize the font to the output stream.
+ // @param os the destination for the font serialization
+ // @param tableOrdering the table ordering to apply
+ void Serialize(OutputStream* os, IntegerList* table_ordering);
+
+ private:
+ // Offsets to specific elements in the underlying data. These offsets are
+ // relative to the start of the table or the start of sub-blocks within the
+ // table.
+ struct Offset {
+ enum {
+ // Offsets within the main directory
+ kSfntVersion = 0,
+ kNumTables = 4,
+ kSearchRange = 6,
+ kEntrySelector = 8,
+ kRangeShift = 10,
+ kTableRecordBegin = 12,
+ kSfntHeaderSize = 12,
+
+ // Offsets within a specific table record
+ kTableTag = 0,
+ kTableCheckSum = 4,
+ kTableOffset = 8,
+ kTableLength = 12,
+ kTableRecordSize = 16
+ };
+ };
+
+ // Note: the two constants are moved to tag.h to avoid VC++ bug.
+// static const int32_t CFF_TABLE_ORDERING[];
+// static const int32_t TRUE_TYPE_TABLE_ORDERING[];
+
+ // Constructor.
+ // @param sfntVersion the sfnt version
+ // @param digest the computed digest for the font; null if digest was not
+ // computed
+ // Note: Current C++ port does not support SHA digest validation.
+ Font(int32_t sfnt_version, ByteVector* digest);
+
+ // Build the table headers to be used for serialization. These headers will be
+ // filled out with the data required for serialization. The headers will be
+ // sorted in the order specified and only those specified will have headers
+ // generated.
+ // @param tableOrdering the tables to generate headers for and the order to
+ // sort them
+ // @return a list of table headers ready for serialization
+ void BuildTableHeadersForSerialization(IntegerList* table_ordering,
+ TableHeaderList* table_headers);
+
+ // Searialize the headers.
+ // @param fos the destination stream for the headers
+ // @param tableHeaders the headers to serialize
+ // @throws IOException
+ void SerializeHeader(FontOutputStream* fos, TableHeaderList* table_headers);
+
+ // Serialize the tables.
+ // @param fos the destination stream for the headers
+ // @param tableHeaders the headers for the tables to serialize
+ // @throws IOException
+ void SerializeTables(FontOutputStream* fos, TableHeaderList* table_headers);
+
+ // Generate the full table ordering to used for serialization. The full
+ // ordering uses the partial ordering as a seed and then adds all remaining
+ // tables in the font in an undefined order.
+ // @param defaultTableOrdering the partial ordering to be used as a seed for
+ // the full ordering
+ // @param (out) table_ordering the full ordering for serialization
+ void GenerateTableOrdering(IntegerList* default_table_ordering,
+ IntegerList* table_ordering);
+
+ // Get the default table ordering based on the type of the font.
+ // @param (out) default_table_ordering the default table ordering
+ void DefaultTableOrdering(IntegerList* default_table_ordering);
+
+ int32_t sfnt_version_;
+ ByteVector digest_;
+ int64_t checksum_;
+ TableMap tables_;
+};
+typedef Ptr<Font> FontPtr;
+typedef std::vector<FontPtr> FontArray;
+typedef Ptr<Font::Builder> FontBuilderPtr;
+typedef std::vector<FontBuilderPtr> FontBuilderArray;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_FONT_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/font_factory.cc b/chromium/third_party/sfntly/cpp/src/sfntly/font_factory.cc
new file mode 100644
index 00000000000..c162a77af34
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/font_factory.cc
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/font_factory.h"
+
+#include <string.h>
+
+#include "sfntly/tag.h"
+
+namespace sfntly {
+
+FontFactory::~FontFactory() {
+}
+
+CALLER_ATTACH FontFactory* FontFactory::GetInstance() {
+ FontFactoryPtr instance = new FontFactory();
+ return instance.Detach();
+}
+
+void FontFactory::FingerprintFont(bool fingerprint) {
+ fingerprint_ = fingerprint;
+}
+
+bool FontFactory::FingerprintFont() {
+ return fingerprint_;
+}
+
+void FontFactory::LoadFonts(InputStream* is, FontArray* output) {
+ assert(output);
+ PushbackInputStream* pbis = down_cast<PushbackInputStream*>(is);
+ if (IsCollection(pbis)) {
+ LoadCollection(pbis, output);
+ return;
+ }
+ FontPtr font;
+ font.Attach(LoadSingleOTF(pbis));
+ if (font) {
+ output->push_back(font);
+ }
+}
+
+void FontFactory::LoadFonts(ByteVector* b, FontArray* output) {
+ WritableFontDataPtr wfd;
+ wfd.Attach(WritableFontData::CreateWritableFontData(b));
+ if (IsCollection(wfd)) {
+ LoadCollection(wfd, output);
+ return;
+ }
+ FontPtr font;
+ font.Attach(LoadSingleOTF(wfd));
+ if (font) {
+ output->push_back(font);
+ }
+}
+
+void FontFactory::LoadFontsForBuilding(InputStream* is,
+ FontBuilderArray* output) {
+ PushbackInputStream* pbis = down_cast<PushbackInputStream*>(is);
+ if (IsCollection(pbis)) {
+ LoadCollectionForBuilding(pbis, output);
+ return;
+ }
+ FontBuilderPtr builder;
+ builder.Attach(LoadSingleOTFForBuilding(pbis));
+ if (builder) {
+ output->push_back(builder);
+ }
+}
+
+void FontFactory::LoadFontsForBuilding(ByteVector* b,
+ FontBuilderArray* output) {
+ WritableFontDataPtr wfd;
+ wfd.Attach(WritableFontData::CreateWritableFontData(b));
+ if (IsCollection(wfd)) {
+ LoadCollectionForBuilding(wfd, output);
+ return;
+ }
+ FontBuilderPtr builder;
+ builder.Attach(LoadSingleOTFForBuilding(wfd, 0));
+ if (builder) {
+ output->push_back(builder);
+ }
+}
+
+void FontFactory::SerializeFont(Font* font, OutputStream* os) {
+ font->Serialize(os, &table_ordering_);
+}
+
+void FontFactory::SetSerializationTableOrdering(
+ const IntegerList& table_ordering) {
+ table_ordering_ = table_ordering;
+}
+
+CALLER_ATTACH Font::Builder* FontFactory::NewFontBuilder() {
+ return Font::Builder::GetOTFBuilder(this);
+}
+
+CALLER_ATTACH Font* FontFactory::LoadSingleOTF(InputStream* is) {
+ FontBuilderPtr builder;
+ builder.Attach(LoadSingleOTFForBuilding(is));
+ return builder->Build();
+}
+
+CALLER_ATTACH Font* FontFactory::LoadSingleOTF(WritableFontData* wfd) {
+ FontBuilderPtr builder;
+ builder.Attach(LoadSingleOTFForBuilding(wfd, 0));
+ return builder->Build();
+}
+
+void FontFactory::LoadCollection(InputStream* is, FontArray* output) {
+ FontBuilderArray ba;
+ LoadCollectionForBuilding(is, &ba);
+ output->reserve(ba.size());
+ for (FontBuilderArray::iterator builder = ba.begin(), builders_end = ba.end();
+ builder != builders_end; ++builder) {
+ FontPtr font;
+ font.Attach((*builder)->Build());
+ output->push_back(font);
+ }
+}
+
+void FontFactory::LoadCollection(WritableFontData* wfd, FontArray* output) {
+ FontBuilderArray builders;
+ LoadCollectionForBuilding(wfd, &builders);
+ output->reserve(builders.size());
+ for (FontBuilderArray::iterator builder = builders.begin(),
+ builders_end = builders.end();
+ builder != builders_end; ++builder) {
+ FontPtr font;
+ font.Attach((*builder)->Build());
+ output->push_back(font);
+ }
+}
+
+CALLER_ATTACH
+Font::Builder* FontFactory::LoadSingleOTFForBuilding(InputStream* is) {
+ // UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream
+ Font::Builder* builder = Font::Builder::GetOTFBuilder(this, is);
+ // UNIMPLEMENTED: setDigest
+ return builder;
+}
+
+CALLER_ATTACH Font::Builder*
+ FontFactory::LoadSingleOTFForBuilding(WritableFontData* wfd,
+ int32_t offset_to_offset_table) {
+ // UNIMPLEMENTED: SHA-1 hash checking via Java DigestStream
+ Font::Builder* builder =
+ Font::Builder::GetOTFBuilder(this, wfd, offset_to_offset_table);
+ // UNIMPLEMENTED: setDigest
+ return builder;
+}
+
+void FontFactory::LoadCollectionForBuilding(InputStream* is,
+ FontBuilderArray* builders) {
+ assert(is);
+ assert(builders);
+ WritableFontDataPtr wfd;
+ wfd.Attach(WritableFontData::CreateWritableFontData(is->Available()));
+ wfd->CopyFrom(is);
+ LoadCollectionForBuilding(wfd, builders);
+}
+
+void FontFactory::LoadCollectionForBuilding(WritableFontData* wfd,
+ FontBuilderArray* builders) {
+ int32_t ttc_tag = wfd->ReadULongAsInt(Offset::kTTCTag);
+ UNREFERENCED_PARAMETER(ttc_tag);
+ int32_t version = wfd->ReadFixed(Offset::kVersion);
+ UNREFERENCED_PARAMETER(version);
+ int32_t num_fonts = wfd->ReadULongAsInt(Offset::kNumFonts);
+
+ builders->reserve(num_fonts);
+ int32_t offset_table_offset = Offset::kOffsetTable;
+ for (int32_t font_number = 0;
+ font_number < num_fonts;
+ font_number++, offset_table_offset += DataSize::kULONG) {
+ int32_t offset = wfd->ReadULongAsInt(offset_table_offset);
+ FontBuilderPtr builder;
+ builder.Attach(LoadSingleOTFForBuilding(wfd, offset));
+ builders->push_back(builder);
+ }
+}
+
+bool FontFactory::IsCollection(PushbackInputStream* pbis) {
+ ByteVector tag(4);
+ pbis->Read(&tag);
+ pbis->Unread(&tag);
+ return Tag::ttcf == GenerateTag(tag[0], tag[1], tag[2], tag[3]);
+}
+
+bool FontFactory::IsCollection(ReadableFontData* rfd) {
+ ByteVector tag(4);
+ rfd->ReadBytes(0, &(tag[0]), 0, tag.size());
+ return Tag::ttcf ==
+ GenerateTag(tag[0], tag[1], tag[2], tag[3]);
+}
+
+FontFactory::FontFactory()
+ : fingerprint_(false) {
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/font_factory.h b/chromium/third_party/sfntly/cpp/src/sfntly/font_factory.h
new file mode 100644
index 00000000000..63deff4abfe
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/font_factory.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_FONT_FACTORY_H_
+#define SFNTLY_CPP_SRC_SFNTLY_FONT_FACTORY_H_
+
+#include <vector>
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/port/type.h"
+#include "sfntly/font.h"
+
+namespace sfntly {
+
+class FontFactory : public RefCounted<FontFactory> {
+ public:
+ virtual ~FontFactory();
+
+ // Factory method for the construction of a font factory.
+ static CALLER_ATTACH FontFactory* GetInstance();
+
+ // Toggle whether fonts that are loaded are fingerprinted with a SHA-1 hash.
+ // If a font is fingerprinted then a SHA-1 hash is generated at load time and
+ // stored in the font. This is useful for uniquely identifying fonts. By
+ // default this is turned on.
+ // @param fingerprint whether fingerprinting should be turned on or off
+ // TODO(arthurhsu): IMPLEMENT: C++ port currently don't do any SHA-1
+ void FingerprintFont(bool fingerprint);
+ bool FingerprintFont();
+
+ // Load the font(s) from the input stream. The current settings on the factory
+ // are used during the loading process. One or more fonts are returned if the
+ // stream contains valid font data. Some font container formats may have more
+ // than one font and in this case multiple font objects will be returned. If
+ // the data in the stream cannot be parsed or is invalid an array of size zero
+ // will be returned.
+ void LoadFonts(InputStream* is, FontArray* output);
+
+ // ByteArray font loading
+ // Load the font(s) from the byte array. The current settings on the factory
+ // are used during the loading process. One or more fonts are returned if the
+ // stream contains valid font data. Some font container formats may have more
+ // than one font and in this case multiple font objects will be returned. If
+ // the data in the stream cannot be parsed or is invalid an array of size zero
+ // will be returned.
+ void LoadFonts(ByteVector* b, FontArray* output);
+
+ // Load the font(s) from the input stream into font builders. The current
+ // settings on the factory are used during the loading process. One or more
+ // font builders are returned if the stream contains valid font data. Some
+ // font container formats may have more than one font and in this case
+ // multiple font builder objects will be returned. If the data in the stream
+ // cannot be parsed or is invalid an array of size zero will be returned.
+ void LoadFontsForBuilding(InputStream* is, FontBuilderArray* output);
+
+ // Load the font(s) from the byte array into font builders. The current
+ // settings on the factory are used during the loading process. One or more
+ // font builders are returned if the stream contains valid font data. Some
+ // font container formats may have more than one font and in this case
+ // multiple font builder objects will be returned. If the data in the stream
+ // cannot be parsed or is invalid an array of size zero will be returned.
+ void LoadFontsForBuilding(ByteVector* b, FontBuilderArray* output);
+
+ // Font serialization
+ // Serialize the font to the output stream.
+ // NOTE: in this port we attempted not to implement I/O stream because dealing
+ // with cross-platform I/O stream itself is big enough as a project.
+ // Byte buffer it is.
+ void SerializeFont(Font* font, OutputStream* os);
+
+ // Set the table ordering to be used in serializing a font. The table ordering
+ // is an ordered list of table ids and tables will be serialized in the order
+ // given. Any tables whose id is not listed in the ordering will be placed in
+ // an unspecified order following those listed.
+ void SetSerializationTableOrdering(const IntegerList& table_ordering);
+
+ // Get an empty font builder for creating a new font from scratch.
+ CALLER_ATTACH Font::Builder* NewFontBuilder();
+
+ private:
+ // Offsets to specific elements in the underlying data. These offsets are
+ // relative to the start of the table or the start of sub-blocks within the
+ // table.
+ struct Offset {
+ enum {
+ // Offsets within the main directory.
+ kTTCTag = 0,
+ kVersion = 4,
+ kNumFonts = 8,
+ kOffsetTable = 12,
+
+ // TTC Version 2.0 extensions.
+ // Offsets from end of OffsetTable.
+ kulDsigTag = 0,
+ kulDsigLength = 4,
+ kulDsigOffset = 8
+ };
+ };
+
+ FontFactory();
+
+ CALLER_ATTACH Font* LoadSingleOTF(InputStream* is);
+ CALLER_ATTACH Font* LoadSingleOTF(WritableFontData* wfd);
+
+ void LoadCollection(InputStream* is, FontArray* output);
+ void LoadCollection(WritableFontData* wfd, FontArray* output);
+
+ CALLER_ATTACH Font::Builder* LoadSingleOTFForBuilding(InputStream* is);
+ CALLER_ATTACH Font::Builder*
+ LoadSingleOTFForBuilding(WritableFontData* wfd,
+ int32_t offset_to_offset_table);
+
+ void LoadCollectionForBuilding(InputStream* is, FontBuilderArray* builders);
+ void LoadCollectionForBuilding(WritableFontData* ba,
+ FontBuilderArray* builders);
+
+ static bool IsCollection(PushbackInputStream* pbis);
+ static bool IsCollection(ReadableFontData* wfd);
+
+ bool fingerprint_;
+ IntegerList table_ordering_;
+};
+typedef Ptr<FontFactory> FontFactoryPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_FONT_FACTORY_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/math/fixed1616.h b/chromium/third_party/sfntly/cpp/src/sfntly/math/fixed1616.h
new file mode 100644
index 00000000000..4abbe180982
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/math/fixed1616.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_MATH_FIXED1616_H_
+#define SFNTLY_CPP_SRC_SFNTLY_MATH_FIXED1616_H_
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+class Fixed1616 {
+ public:
+ static inline int32_t Integral(int32_t fixed) {
+ return (fixed >> 16);
+ }
+
+ static inline int32_t Fractional(int32_t fixed) {
+ return (fixed & 0xffff);
+ }
+
+ static inline int32_t Fixed(int32_t integral, int32_t fractional) {
+ return ((integral & 0xffff) << 16) | (fractional & 0xffff);
+ }
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_MATH_FIXED1616_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/math/font_math.h b/chromium/third_party/sfntly/cpp/src/sfntly/math/font_math.h
new file mode 100644
index 00000000000..f1cd2d2a6f0
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/math/font_math.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_MATH_FONT_MATH_H_
+#define SFNTLY_CPP_SRC_SFNTLY_MATH_FONT_MATH_H_
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+class FontMath {
+ public:
+ static int32_t Log2(int32_t a) {
+ int r = 0; // r will be lg(a)
+ while (a != 0) {
+ a >>= 1;
+ r++;
+ }
+ return r - 1;
+ }
+
+ // Calculates the amount of padding needed. The values provided need to be in
+ // the same units. So, if the size is given as the number of bytes then the
+ // alignment size must also be specified as byte size to align to.
+ // @param size the size of the data that may need padding
+ // @param alignmentSize the number of units to align to
+ // @return the number of units needing to be added for alignment
+ static int32_t PaddingRequired(int32_t size, int32_t alignment_size) {
+ int32_t padding = alignment_size - (size % alignment_size);
+ return padding == alignment_size ? 0 : padding;
+ }
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_MATH_FONT_MATH_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/atomic.h b/chromium/third_party/sfntly/cpp/src/sfntly/port/atomic.h
new file mode 100644
index 00000000000..b381a52af73
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/atomic.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_ATOMIC_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_ATOMIC_H_
+
+#if defined (WIN32)
+
+#include <windows.h>
+
+static inline size_t AtomicIncrement(size_t* address) {
+#if defined (_WIN64)
+ return InterlockedIncrement64(reinterpret_cast<LONGLONG*>(address));
+#else
+ return InterlockedIncrement(reinterpret_cast<LONG*>(address));
+#endif
+}
+
+static inline size_t AtomicDecrement(size_t* address) {
+#if defined (_WIN64)
+ return InterlockedDecrement64(reinterpret_cast<LONGLONG*>(address));
+#else
+ return InterlockedDecrement(reinterpret_cast<LONG*>(address));
+#endif
+}
+
+#elif defined (__APPLE__)
+
+#include <libkern/OSAtomic.h>
+
+static inline size_t AtomicIncrement(size_t* address) {
+ return OSAtomicIncrement32Barrier(reinterpret_cast<int32_t*>(address));
+}
+
+static inline size_t AtomicDecrement(size_t* address) {
+ return OSAtomicDecrement32Barrier(reinterpret_cast<int32_t*>(address));
+}
+
+// Originally we check __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4, however, there are
+// issues that clang not carring over this definition. Therefore we boldly
+// assume it's gcc or gcc-compatible here. Compilation shall still fail since
+// the intrinsics used are GCC-specific.
+
+#else
+
+#include <stddef.h>
+
+static inline size_t AtomicIncrement(size_t* address) {
+ return __sync_add_and_fetch(address, 1);
+}
+
+static inline size_t AtomicDecrement(size_t* address) {
+ return __sync_sub_and_fetch(address, 1);
+}
+
+#endif // WIN32
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_ATOMIC_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/config.h b/chromium/third_party/sfntly/cpp/src/sfntly/port/config.h
new file mode 100644
index 00000000000..0fcdffe7246
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/config.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_CONFIG_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_CONFIG_H_
+
+#if !defined(SFNTLY_BIG_ENDIAN) && !defined(SFNTLY_LITTLE_ENDIAN)
+ #if defined (__ppc__) || defined (__ppc64__)
+ #define SFNTLY_BIG_ENDIAN
+ #else
+ #define SFNTLY_LITTLE_ENDIAN
+ #endif
+#endif
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_CONFIG_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/endian.h b/chromium/third_party/sfntly/cpp/src/sfntly/port/endian.h
new file mode 100644
index 00000000000..db58f0a307a
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/endian.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_ENDIAN_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_ENDIAN_H_
+
+#include "sfntly/port/config.h"
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+static inline uint16_t EndianSwap16(uint16_t value) {
+ return (uint16_t)((value >> 8) | (value << 8));
+}
+
+static inline int32_t EndianSwap32(int32_t value) {
+ return (((value & 0x000000ff) << 24) |
+ ((value & 0x0000ff00) << 8) |
+ ((value & 0x00ff0000) >> 8) |
+ ((value & 0xff000000) >> 24));
+}
+
+static inline uint64_t EndianSwap64(uint64_t value) {
+ return (((value & 0x00000000000000ffLL) << 56) |
+ ((value & 0x000000000000ff00LL) << 40) |
+ ((value & 0x0000000000ff0000LL) << 24) |
+ ((value & 0x00000000ff000000LL) << 8) |
+ ((value & 0x000000ff00000000LL) >> 8) |
+ ((value & 0x0000ff0000000000LL) >> 24) |
+ ((value & 0x00ff000000000000LL) >> 40) |
+ ((value & 0xff00000000000000LL) >> 56));
+}
+
+#ifdef SFNTLY_LITTLE_ENDIAN
+ #define ToBE16(n) EndianSwap16(n)
+ #define ToBE32(n) EndianSwap32(n)
+ #define ToBE64(n) EndianSwap64(n)
+ #define ToLE16(n) (n)
+ #define ToLE32(n) (n)
+ #define ToLE64(n) (n)
+ #define FromBE16(n) EndianSwap16(n)
+ #define FromBE32(n) EndianSwap32(n)
+ #define FromBE64(n) EndianSwap64(n)
+ #define FromLE16(n) (n)
+ #define FromLE32(n) (n)
+ #define FromLE64(n) (n)
+#else // SFNTLY_BIG_ENDIAN
+ #define ToBE16(n) (n)
+ #define ToBE32(n) (n)
+ #define ToBE64(n) (n)
+ #define ToLE16(n) EndianSwap16(n)
+ #define ToLE32(n) EndianSwap32(n)
+ #define ToLE64(n) EndianSwap64(n)
+ #define FromBE16(n) (n)
+ #define FromBE32(n) (n)
+ #define FromBE64(n) (n)
+ #define FromLE16(n) EndianSwap16(n)
+ #define FromLE32(n) EndianSwap32(n)
+ #define FromLE64(n) EndianSwap64(n)
+#endif
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_ENDIAN_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/exception_type.h b/chromium/third_party/sfntly/cpp/src/sfntly/port/exception_type.h
new file mode 100644
index 00000000000..b96efcb6c56
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/exception_type.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Exceptions used in sfntly
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_EXCEPTION_TYPE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_EXCEPTION_TYPE_H_
+
+#if !defined (SFNTLY_NO_EXCEPTION)
+
+#include <exception>
+#include <string>
+#include <sstream>
+
+namespace sfntly {
+
+class Exception : public std::exception {
+ public:
+ Exception() : what_("Unknown exception") {}
+ explicit Exception(const char* message) throw() { SetMessage(message); }
+ virtual ~Exception() throw() {}
+ virtual const char* what() const throw() { return what_.c_str(); }
+
+ protected:
+ void SetMessage(const char* message) throw() {
+ try {
+ what_ = message;
+ } catch (...) {}
+ }
+
+ private:
+ std::string what_;
+};
+
+class IndexOutOfBoundException : public Exception {
+ public:
+ IndexOutOfBoundException() throw() : Exception("Index out of bound") {}
+ explicit IndexOutOfBoundException(const char* message) throw()
+ : Exception(message) {}
+ IndexOutOfBoundException(const char* message, int32_t index) throw() {
+ try {
+ std::ostringstream msg;
+ msg << message;
+ msg << ":";
+ msg << index;
+ SetMessage(msg.str().c_str());
+ } catch (...) {}
+ }
+ virtual ~IndexOutOfBoundException() throw() {}
+};
+
+class IOException : public Exception {
+ public:
+ IOException() throw() : Exception("I/O exception") {}
+ explicit IOException(const char* message) throw() : Exception(message) {}
+ virtual ~IOException() throw() {}
+};
+
+class ArithmeticException : public Exception {
+ public:
+ ArithmeticException() throw() : Exception("Arithmetic exception") {}
+ explicit ArithmeticException(const char* message) throw()
+ : Exception(message) {}
+ virtual ~ArithmeticException() throw() {}
+};
+
+class UnsupportedOperationException : public Exception {
+ public:
+ UnsupportedOperationException() throw() :
+ Exception("Operation not supported") {}
+ explicit UnsupportedOperationException(const char* message) throw()
+ : Exception(message) {}
+ virtual ~UnsupportedOperationException() throw() {}
+};
+
+class RuntimeException : public Exception {
+ public:
+ RuntimeException() throw() : Exception("Runtime exception") {}
+ explicit RuntimeException(const char* message) throw()
+ : Exception(message) {}
+ virtual ~RuntimeException() throw() {}
+};
+
+class NoSuchElementException : public Exception {
+ public:
+ NoSuchElementException() throw() : Exception("No such element") {}
+ explicit NoSuchElementException(const char* message) throw()
+ : Exception(message) {}
+ virtual ~NoSuchElementException() throw() {}
+};
+
+class IllegalArgumentException : public Exception {
+ public:
+ IllegalArgumentException() throw() : Exception("Illegal argument") {}
+ explicit IllegalArgumentException(const char* message) throw()
+ : Exception(message) {}
+ virtual ~IllegalArgumentException() throw() {}
+};
+
+class IllegalStateException : public Exception {
+ public:
+ IllegalStateException() throw() : Exception("Illegal state") {}
+ explicit IllegalStateException(const char* message) throw()
+ : Exception(message) {}
+ virtual ~IllegalStateException() throw() {}
+};
+
+} // namespace sfntly
+
+#endif // #if !defined (SFNTLY_NO_EXCEPTION)
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_EXCEPTION_TYPE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/file_input_stream.cc b/chromium/third_party/sfntly/cpp/src/sfntly/port/file_input_stream.cc
new file mode 100644
index 00000000000..5bcb434af05
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/file_input_stream.cc
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if defined (WIN32)
+#include <windows.h>
+#endif
+
+#include "sfntly/port/file_input_stream.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+
+FileInputStream::FileInputStream()
+ : file_(NULL),
+ position_(0),
+ length_(0) {
+}
+
+FileInputStream::~FileInputStream() {
+ Close();
+}
+
+int32_t FileInputStream::Available() {
+ return length_ - position_;
+}
+
+void FileInputStream::Close() {
+ if (file_) {
+ fclose(file_);
+ length_ = 0;
+ position_ = 0;
+ file_ = NULL;
+ }
+}
+
+void FileInputStream::Mark(int32_t readlimit) {
+ // NOP
+ UNREFERENCED_PARAMETER(readlimit);
+}
+
+bool FileInputStream::MarkSupported() {
+ return false;
+}
+
+int32_t FileInputStream::Read() {
+ if (!file_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("no opened file");
+#endif
+ return 0;
+ }
+ if (feof(file_)) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("eof reached");
+#endif
+ return 0;
+ }
+ byte_t value;
+ size_t length = fread(&value, 1, 1, file_);
+ position_ += length;
+ return value;
+}
+
+int32_t FileInputStream::Read(ByteVector* b) {
+ return Read(b, 0, b->size());
+}
+
+int32_t FileInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
+ assert(b);
+ if (!file_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("no opened file");
+#endif
+ return 0;
+ }
+ if (feof(file_)) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("eof reached");
+#endif
+ return 0;
+ }
+ size_t read_count = std::min<size_t>(length_ - position_, length);
+ if (b->size() < (size_t)(offset + read_count)) {
+ b->resize((size_t)(offset + read_count));
+ }
+ int32_t actual_read = fread(&((*b)[offset]), 1, read_count, file_);
+ position_ += actual_read;
+ return actual_read;
+}
+
+void FileInputStream::Reset() {
+ // NOP
+}
+
+int64_t FileInputStream::Skip(int64_t n) {
+ if (!file_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("no opened file");
+#endif
+ return 0;
+ }
+ int64_t skip_count = 0;
+ if (n < 0) { // move backwards
+ skip_count = std::max<int64_t>(0 - (int64_t)position_, n);
+ position_ -= (size_t)(0 - skip_count);
+ fseek(file_, position_, SEEK_SET);
+ } else {
+ skip_count = std::min<size_t>(length_ - position_, (size_t)n);
+ position_ += (size_t)skip_count;
+ fseek(file_, (size_t)skip_count, SEEK_CUR);
+ }
+ return skip_count;
+}
+
+void FileInputStream::Unread(ByteVector* b) {
+ Unread(b, 0, b->size());
+}
+
+void FileInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) {
+ assert(b);
+ assert(b->size() >= size_t(offset + length));
+ if (!file_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("no opened file");
+#endif
+ return;
+ }
+ size_t unread_count = std::min<size_t>(position_, length);
+ fseek(file_, position_ - unread_count, SEEK_SET);
+ position_ -= unread_count;
+ Read(b, offset, length);
+ fseek(file_, position_ - unread_count, SEEK_SET);
+ position_ -= unread_count;
+}
+
+bool FileInputStream::Open(const char* file_path) {
+ assert(file_path);
+ if (file_) {
+ Close();
+ }
+#if defined (WIN32)
+ fopen_s(&file_, file_path, "rb");
+#else
+ file_ = fopen(file_path, "rb");
+#endif
+ if (file_ == NULL) {
+ return false;
+ }
+
+ fseek(file_, 0, SEEK_END);
+ length_ = ftell(file_);
+ fseek(file_, 0, SEEK_SET);
+ return true;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/file_input_stream.h b/chromium/third_party/sfntly/cpp/src/sfntly/port/file_input_stream.h
new file mode 100644
index 00000000000..cbca25f7e40
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/file_input_stream.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_FILE_INPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_FILE_INPUT_STREAM_H_
+
+#include <stdio.h>
+
+#include "sfntly/port/input_stream.h"
+
+namespace sfntly {
+
+class FileInputStream : public PushbackInputStream {
+ public:
+ FileInputStream();
+ virtual ~FileInputStream();
+
+ // InputStream methods
+ virtual int32_t Available();
+ virtual void Close();
+ virtual void Mark(int32_t readlimit);
+ virtual bool MarkSupported();
+ virtual int32_t Read();
+ virtual int32_t Read(ByteVector* b);
+ virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length);
+ virtual void Reset();
+ virtual int64_t Skip(int64_t n);
+
+ // PushbackInputStream methods
+ virtual void Unread(ByteVector* b);
+ virtual void Unread(ByteVector* b, int32_t offset, int32_t length);
+
+ // Own methods
+ virtual bool Open(const char* file_path);
+
+ private:
+ FILE* file_;
+ size_t position_;
+ size_t length_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_FILE_INPUT_STREAM_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/input_stream.h b/chromium/third_party/sfntly/cpp/src/sfntly/port/input_stream.h
new file mode 100644
index 00000000000..5d24036ea73
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/input_stream.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_INPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_INPUT_STREAM_H_
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+// C++ equivalent to Java's OutputStream class
+class InputStream {
+ public:
+ // Make gcc -Wnon-virtual-dtor happy.
+ virtual ~InputStream() {}
+
+ virtual int32_t Available() = 0;
+ virtual void Close() = 0;
+ virtual void Mark(int32_t readlimit) = 0;
+ virtual bool MarkSupported() = 0;
+ virtual int32_t Read() = 0;
+ virtual int32_t Read(ByteVector* b) = 0;
+ virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length) = 0;
+ virtual void Reset() = 0;
+ virtual int64_t Skip(int64_t n) = 0;
+};
+
+class PushbackInputStream : public InputStream {
+ public:
+ virtual void Unread(ByteVector* b) = 0;
+ virtual void Unread(ByteVector* b, int32_t offset, int32_t length) = 0;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_INPUT_STREAM_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/java_iterator.h b/chromium/third_party/sfntly/cpp/src/sfntly/port/java_iterator.h
new file mode 100644
index 00000000000..0a99bca1d04
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/java_iterator.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_JAVA_ITERATOR_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_JAVA_ITERATOR_H_
+
+#include "sfntly/port/refcount.h"
+
+// Interface of Java iterator.
+// This is a forward read-only iterator that represents java.util.Iterator<E>
+
+namespace sfntly {
+
+template <typename ReturnType, typename ContainerBase>
+class Iterator : public virtual RefCount {
+ public:
+ virtual ~Iterator() {}
+ virtual ContainerBase* container_base() = 0;
+
+ protected:
+ Iterator() {}
+ NO_COPY_AND_ASSIGN(Iterator);
+};
+
+template <typename ReturnType, typename Container,
+ typename ContainerBase = Container>
+class PODIterator : public Iterator<ReturnType, ContainerBase>,
+ public RefCounted< PODIterator<ReturnType, Container> > {
+ public:
+ explicit PODIterator(Container* container) : container_(container) {}
+ virtual ~PODIterator() {}
+ virtual ContainerBase* container_base() {
+ return static_cast<ContainerBase*>(container_);
+ }
+
+ virtual bool HasNext() = 0;
+ virtual ReturnType Next() = 0;
+ virtual void Remove() {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ // Default to no support.
+ throw UnsupportedOperationException();
+#endif
+ }
+
+ protected:
+ Container* container() { return container_; }
+
+ private:
+ Container* container_; // Dumb pointer is used to avoid circular ref-counting
+};
+
+template <typename ReturnType, typename Container,
+ typename ContainerBase = Container>
+class RefIterator : public Iterator<ReturnType, ContainerBase>,
+ public RefCounted< RefIterator<ReturnType, Container> > {
+ public:
+ explicit RefIterator(Container* container) : container_(container) {}
+ virtual ~RefIterator() {}
+ virtual ContainerBase* container_base() {
+ return static_cast<ContainerBase*>(container_);
+ }
+
+ virtual bool HasNext() = 0;
+ CALLER_ATTACH virtual ReturnType* Next() = 0;
+ virtual void Remove() {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ // Default to no support.
+ throw UnsupportedOperationException();
+#endif
+ }
+
+ protected:
+ Container* container() { return container_; }
+
+ private:
+ Container* container_; // Dumb pointer is used to avoid circular ref-counting
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_JAVA_ITERATOR_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/lock.cc b/chromium/third_party/sfntly/cpp/src/sfntly/port/lock.cc
new file mode 100644
index 00000000000..6c0c309a943
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/lock.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/port/lock.h"
+
+namespace sfntly {
+
+#if defined (WIN32)
+
+Lock::Lock() {
+ // The second parameter is the spin count, for short-held locks it avoid the
+ // contending thread from going to sleep which helps performance greatly.
+ ::InitializeCriticalSectionAndSpinCount(&os_lock_, 2000);
+}
+
+Lock::~Lock() {
+ ::DeleteCriticalSection(&os_lock_);
+}
+
+bool Lock::Try() {
+ if (::TryEnterCriticalSection(&os_lock_) != FALSE) {
+ return true;
+ }
+ return false;
+}
+
+void Lock::Acquire() {
+ ::EnterCriticalSection(&os_lock_);
+}
+
+void Lock::Unlock() {
+ ::LeaveCriticalSection(&os_lock_);
+}
+
+#else // We assume it's pthread
+
+Lock::Lock() {
+ pthread_mutex_init(&os_lock_, NULL);
+}
+
+Lock::~Lock() {
+ pthread_mutex_destroy(&os_lock_);
+}
+
+bool Lock::Try() {
+ return (pthread_mutex_trylock(&os_lock_) == 0);
+}
+
+void Lock::Acquire() {
+ pthread_mutex_lock(&os_lock_);
+}
+
+void Lock::Unlock() {
+ pthread_mutex_unlock(&os_lock_);
+}
+
+#endif
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/lock.h b/chromium/third_party/sfntly/cpp/src/sfntly/port/lock.h
new file mode 100644
index 00000000000..b2e29bf64fa
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/lock.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_LOCK_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_LOCK_H_
+
+#if defined (WIN32)
+#include <windows.h>
+#else // Assume pthread.
+#include <pthread.h>
+#include <errno.h>
+#endif
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+#if defined (WIN32)
+ typedef CRITICAL_SECTION OSLockType;
+#else // Assume pthread.
+ typedef pthread_mutex_t OSLockType;
+#endif
+
+class Lock {
+ public:
+ Lock();
+ ~Lock();
+
+ // If the lock is not held, take it and return true. If the lock is already
+ // held by something else, immediately return false.
+ bool Try();
+
+ // Take the lock, blocking until it is available if necessary.
+ void Acquire();
+
+ // Release the lock. This must only be called by the lock's holder: after
+ // a successful call to Try, or a call to Lock.
+ void Unlock();
+
+ private:
+ OSLockType os_lock_;
+ NO_COPY_AND_ASSIGN(Lock);
+};
+
+// A helper class that acquires the given Lock while the AutoLock is in scope.
+class AutoLock {
+ public:
+ explicit AutoLock(Lock& lock) : lock_(lock) {
+ lock_.Acquire();
+ }
+
+ ~AutoLock() {
+ lock_.Unlock();
+ }
+
+ private:
+ Lock& lock_;
+ NO_COPY_AND_ASSIGN(AutoLock);
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_LOCK_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/memory_input_stream.cc b/chromium/third_party/sfntly/cpp/src/sfntly/port/memory_input_stream.cc
new file mode 100755
index 00000000000..56ee81e5dd9
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/memory_input_stream.cc
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if defined (WIN32)
+#include <windows.h>
+#endif
+
+#include <string.h>
+
+#include "sfntly/port/memory_input_stream.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+
+MemoryInputStream::MemoryInputStream()
+ : buffer_(NULL),
+ position_(0),
+ length_(0) {
+}
+
+MemoryInputStream::~MemoryInputStream() {
+ Close();
+}
+
+int32_t MemoryInputStream::Available() {
+ return length_ - position_;
+}
+
+void MemoryInputStream::Close() {
+}
+
+void MemoryInputStream::Mark(int32_t readlimit) {
+ // NOP
+ UNREFERENCED_PARAMETER(readlimit);
+}
+
+bool MemoryInputStream::MarkSupported() {
+ return false;
+}
+
+int32_t MemoryInputStream::Read() {
+ if (!buffer_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("no memory attached");
+#endif
+ return 0;
+ }
+ if (position_ >= length_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("eof reached");
+#endif
+ return 0;
+ }
+ byte_t value = buffer_[position_++];
+ return value;
+}
+
+int32_t MemoryInputStream::Read(ByteVector* b) {
+ return Read(b, 0, b->size());
+}
+
+int32_t MemoryInputStream::Read(ByteVector* b, int32_t offset, int32_t length) {
+ assert(b);
+ if (!buffer_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("no memory attached");
+#endif
+ return 0;
+ }
+ if (position_ >= length_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("eof reached");
+#endif
+ return 0;
+ }
+ size_t read_count = std::min<size_t>(length_ - position_, length);
+ if (b->size() < (size_t)(offset + read_count)) {
+ b->resize((size_t)(offset + read_count));
+ }
+ memcpy(&((*b)[offset]), buffer_ + position_, read_count);
+ position_ += read_count;
+ return read_count;
+}
+
+void MemoryInputStream::Reset() {
+ // NOP
+}
+
+int64_t MemoryInputStream::Skip(int64_t n) {
+ if (!buffer_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("no memory attached");
+#endif
+ return 0;
+ }
+ int64_t skip_count = 0;
+ if (n < 0) { // move backwards
+ skip_count = std::max<int64_t>(0 - (int64_t)position_, n);
+ position_ -= (size_t)(0 - skip_count);
+ } else {
+ skip_count = std::min<size_t>(length_ - position_, (size_t)n);
+ position_ += (size_t)skip_count;
+ }
+ return skip_count;
+}
+
+void MemoryInputStream::Unread(ByteVector* b) {
+ Unread(b, 0, b->size());
+}
+
+void MemoryInputStream::Unread(ByteVector* b, int32_t offset, int32_t length) {
+ assert(b);
+ assert(b->size() >= size_t(offset + length));
+ if (!buffer_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("no memory attached");
+#endif
+ return;
+ }
+ size_t unread_count = std::min<size_t>(position_, length);
+ position_ -= unread_count;
+ Read(b, offset, length);
+ position_ -= unread_count;
+}
+
+bool MemoryInputStream::Attach(const byte_t* buffer, size_t length) {
+ assert(buffer);
+ assert(length);
+ buffer_ = buffer;
+ length_ = length;
+ return true;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/memory_input_stream.h b/chromium/third_party/sfntly/cpp/src/sfntly/port/memory_input_stream.h
new file mode 100755
index 00000000000..bc861c3f132
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/memory_input_stream.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_INPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_INPUT_STREAM_H_
+
+#include <stdio.h>
+
+#include "sfntly/port/input_stream.h"
+
+namespace sfntly {
+
+class MemoryInputStream : public PushbackInputStream {
+ public:
+ MemoryInputStream();
+ virtual ~MemoryInputStream();
+
+ // InputStream methods
+ virtual int32_t Available();
+ virtual void Close();
+ virtual void Mark(int32_t readlimit);
+ virtual bool MarkSupported();
+ virtual int32_t Read();
+ virtual int32_t Read(ByteVector* b);
+ virtual int32_t Read(ByteVector* b, int32_t offset, int32_t length);
+ virtual void Reset();
+ virtual int64_t Skip(int64_t n);
+
+ // PushbackInputStream methods
+ virtual void Unread(ByteVector* b);
+ virtual void Unread(ByteVector* b, int32_t offset, int32_t length);
+
+ // Own methods
+ virtual bool Attach(const byte_t* buffer, size_t length);
+
+ private:
+ const byte_t* buffer_;
+ size_t position_;
+ size_t length_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_INPUT_STREAM_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/memory_output_stream.cc b/chromium/third_party/sfntly/cpp/src/sfntly/port/memory_output_stream.cc
new file mode 100644
index 00000000000..f2ff2e302e9
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/memory_output_stream.cc
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/port/memory_output_stream.h"
+
+namespace sfntly {
+
+MemoryOutputStream::MemoryOutputStream() {
+}
+
+MemoryOutputStream::~MemoryOutputStream() {
+}
+
+void MemoryOutputStream::Write(ByteVector* buffer) {
+ store_.insert(store_.end(), buffer->begin(), buffer->end());
+}
+
+void MemoryOutputStream::Write(ByteVector* buffer,
+ int32_t offset,
+ int32_t length) {
+ assert(buffer);
+ if (offset >= 0 && length > 0) {
+ store_.insert(store_.end(),
+ buffer->begin() + offset,
+ buffer->begin() + offset + length);
+ } else {
+#if !defined(SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundException();
+#endif
+ }
+}
+
+void MemoryOutputStream::Write(byte_t* buffer, int32_t offset, int32_t length) {
+ assert(buffer);
+ if (offset >= 0 && length > 0) {
+ store_.insert(store_.end(), buffer + offset, buffer + offset + length);
+ } else {
+#if !defined(SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundException();
+#endif
+ }
+}
+
+void MemoryOutputStream::Write(byte_t b) {
+ store_.push_back(b);
+}
+
+byte_t* MemoryOutputStream::Get() {
+ if (store_.empty()) {
+ return NULL;
+ }
+ return &(store_[0]);
+}
+
+size_t MemoryOutputStream::Size() {
+ return store_.size();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/memory_output_stream.h b/chromium/third_party/sfntly/cpp/src/sfntly/port/memory_output_stream.h
new file mode 100644
index 00000000000..d1eda7faf87
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/memory_output_stream.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_OUTPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_OUTPUT_STREAM_H_
+
+#include <cstddef>
+#include <vector>
+
+#include "sfntly/port/type.h"
+#include "sfntly/port/output_stream.h"
+
+namespace sfntly {
+
+// OutputStream backed by STL vector
+
+class MemoryOutputStream : public OutputStream {
+ public:
+ MemoryOutputStream();
+ virtual ~MemoryOutputStream();
+
+ virtual void Close() {} // no-op
+ virtual void Flush() {} // no-op
+ virtual void Write(ByteVector* buffer);
+ virtual void Write(ByteVector* buffer, int32_t offset, int32_t length);
+ virtual void Write(byte_t* buffer, int32_t offset, int32_t length);
+ virtual void Write(byte_t b);
+
+ byte_t* Get();
+ size_t Size();
+
+ private:
+ std::vector<byte_t> store_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_MEMORY_OUTPUT_STREAM_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/output_stream.h b/chromium/third_party/sfntly/cpp/src/sfntly/port/output_stream.h
new file mode 100644
index 00000000000..64a602471d5
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/output_stream.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_OUTPUT_STREAM_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_OUTPUT_STREAM_H_
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+// C++ equivalent to Java's OutputStream class
+class OutputStream {
+ public:
+ // Make gcc -Wnon-virtual-dtor happy.
+ virtual ~OutputStream() {}
+
+ virtual void Close() = 0;
+ virtual void Flush() = 0;
+ virtual void Write(ByteVector* buffer) = 0;
+ virtual void Write(byte_t b) = 0;
+
+ // Note: C++ port offered both versions of Write() here. The first one is
+ // better because it does check bounds. The second one is there for
+ // performance concerns.
+ virtual void Write(ByteVector* buffer, int32_t offset, int32_t length) = 0;
+
+ // Note: Caller is responsible for the boundary of buffer.
+ virtual void Write(byte_t* buffer, int32_t offset, int32_t length) = 0;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_OUTPUT_STREAM_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/refcount.h b/chromium/third_party/sfntly/cpp/src/sfntly/port/refcount.h
new file mode 100644
index 00000000000..eed51622d7f
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/refcount.h
@@ -0,0 +1,277 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Object reference count and smart pointer implementation.
+
+// Smart pointer usage in sfntly:
+//
+// sfntly carries a smart pointer implementation like COM. Ref-countable object
+// type inherits from RefCounted<>, which have AddRef and Release just like
+// IUnknown (but no QueryInterface). Use a Ptr<> based smart pointer to hold
+// the object so that the object ref count is handled correctly.
+//
+// class Foo : public RefCounted<Foo> {
+// public:
+// static Foo* CreateInstance() {
+// Ptr<Foo> obj = new Foo(); // ref count = 1
+// return obj.Detach();
+// }
+// };
+// typedef Ptr<Foo> FooPtr; // common short-hand notation
+// FooPtr obj;
+// obj.Attach(Foo::CreatedInstance()); // ref count = 1
+// {
+// FooPtr obj2 = obj; // ref count = 2
+// } // ref count = 1, obj2 out of scope
+// obj.Release(); // ref count = 0, object destroyed
+
+// Notes on usage:
+// 1. Virtual inherit from RefCount interface in base class if smart pointers
+// are going to be defined.
+// 2. All RefCounted objects must be instantiated on the heap. Allocating the
+// object on stack will cause crash.
+// 3. Be careful when you have complex inheritance. For example,
+// class A : public RefCounted<A>;
+// class B : public A, public RefCounted<B>;
+// In this case the smart pointer is pretty dumb and don't count on it to
+// nicely destroy your objects as designed. Try refactor your code like
+// class I; // the common interface and implementations
+// class A : public I, public RefCounted<A>; // A specific implementation
+// class B : public I, public RefCounted<B>; // B specific implementation
+// 4. Smart pointers here are very bad candidates for function parameters. Use
+// dumb pointers in function parameter list.
+// 5. When down_cast is performed on a dangling pointer due to bugs in code,
+// VC++ will generate SEH which is not handled well in VC++ debugger. One
+// can use WinDBG to run it and get the faulting stack.
+// 6. Idioms for heap object as return value
+// Foo* createFoo() { FooPtr obj = new Foo(); return obj.Detach(); }
+// Foo* passthru() { FooPtr obj = createFoo(), return obj; }
+// FooPtr end_scope_pointer;
+// end_scope_pointer.Attach(passThrough);
+// If you are not passing that object back, you are the end of scope.
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_REFCOUNT_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_REFCOUNT_H_
+
+#if !defined (NDEBUG)
+ #define ENABLE_OBJECT_COUNTER
+// #define REF_COUNT_DEBUGGING
+#endif
+
+#if defined (REF_COUNT_DEBUGGING)
+ #include <stdio.h>
+ #include <typeinfo>
+#endif
+
+#include "sfntly/port/atomic.h"
+#include "sfntly/port/type.h"
+
+// Special tag for functions that requires caller to attach instead of using
+// assignment operators.
+#define CALLER_ATTACH
+
+#if defined (REF_COUNT_DEBUGGING)
+ #define DEBUG_OUTPUT(a) \
+ fprintf(stderr, "%s%s:oc=%d,oid=%d,rc=%d\n", a, \
+ typeid(this).name(), object_counter_, object_id_, ref_count_)
+#else
+ #define DEBUG_OUTPUT(a)
+#endif
+
+#if defined (_MSC_VER)
+ // VC 2008/2010 incorrectly gives this warning for pure virtual functions
+ // in virtual inheritance. The only way to get around it is to disable it.
+ #pragma warning(disable:4250)
+#endif
+
+namespace sfntly {
+
+class RefCount {
+ public:
+ // Make gcc -Wnon-virtual-dtor happy.
+ virtual ~RefCount() {}
+
+ virtual size_t AddRef() const = 0;
+ virtual size_t Release() const = 0;
+};
+
+template <typename T>
+class NoAddRefRelease : public T {
+ public:
+ NoAddRefRelease();
+ ~NoAddRefRelease();
+
+ private:
+ virtual size_t AddRef() const = 0;
+ virtual size_t Release() const = 0;
+};
+
+template <typename TDerived>
+class RefCounted : virtual public RefCount {
+ public:
+ RefCounted() : ref_count_(0) {
+#if defined (ENABLE_OBJECT_COUNTER)
+ object_id_ = AtomicIncrement(&next_id_);
+ AtomicIncrement(&object_counter_);
+ DEBUG_OUTPUT("C ");
+#endif
+ }
+ RefCounted(const RefCounted<TDerived>&) : ref_count_(0) {}
+ virtual ~RefCounted() {
+#if defined (ENABLE_OBJECT_COUNTER)
+ AtomicDecrement(&object_counter_);
+ DEBUG_OUTPUT("D ");
+#endif
+ }
+
+ RefCounted<TDerived>& operator=(const RefCounted<TDerived>&) {
+ // Each object maintains own ref count, don't propagate.
+ return *this;
+ }
+
+ virtual size_t AddRef() const {
+ size_t new_count = AtomicIncrement(&ref_count_);
+ DEBUG_OUTPUT("A ");
+ return new_count;
+ }
+
+ virtual size_t Release() const {
+ size_t new_ref_count = AtomicDecrement(&ref_count_);
+ DEBUG_OUTPUT("R ");
+ if (new_ref_count == 0) {
+ // A C-style is used to cast away const-ness and to derived.
+ // lint does not like this but this is how it works.
+ delete (TDerived*)(this);
+ }
+ return new_ref_count;
+ }
+
+ mutable size_t ref_count_; // reference count of current object
+#if defined (ENABLE_OBJECT_COUNTER)
+ static size_t object_counter_;
+ static size_t next_id_;
+ mutable size_t object_id_;
+#endif
+};
+
+#if defined (ENABLE_OBJECT_COUNTER)
+template <typename TDerived> size_t RefCounted<TDerived>::object_counter_ = 0;
+template <typename TDerived> size_t RefCounted<TDerived>::next_id_ = 0;
+#endif
+
+// semi-smart pointer for RefCount derived objects, similar to CComPtr
+template <typename T>
+class Ptr {
+ public:
+ Ptr() : p_(NULL) {
+ }
+
+ // This constructor shall not be explicit.
+ // lint does not like this but this is how it works.
+ Ptr(T* pT) : p_(NULL) {
+ *this = pT;
+ }
+
+ Ptr(const Ptr<T>& p) : p_(NULL) {
+ *this = p;
+ }
+
+ ~Ptr() {
+ Release();
+ }
+
+ T* operator=(T* pT) {
+ if (p_ == pT) {
+ return p_;
+ }
+ if (pT) {
+ RefCount* p = static_cast<RefCount*>(pT);
+ if (p == NULL) {
+ return NULL;
+ }
+ p->AddRef(); // always AddRef() before Release()
+ }
+ Release();
+ p_ = pT;
+ return p_;
+ }
+
+ T* operator=(const Ptr<T>& p) {
+ if (p_ == p.p_) {
+ return p_;
+ }
+ return operator=(p.p_);
+ }
+
+ operator T*&() {
+ return p_;
+ }
+
+ T& operator*() const {
+ return *p_; // It can throw!
+ }
+
+ NoAddRefRelease<T>* operator->() const {
+ return (NoAddRefRelease<T>*)p_; // It can throw!
+ }
+
+ bool operator!() const {
+ return (p_ == NULL);
+ }
+
+ bool operator<(const Ptr<T>& p) const {
+ return (p_ < p.p_);
+ }
+
+ bool operator!=(T* pT) const {
+ return !operator==(pT);
+ }
+
+ bool operator==(T* pT) const {
+ return (p_ == pT);
+ }
+
+ size_t Release() const {
+ size_t ref_count = 0;
+ if (p_) {
+ RefCount* p = static_cast<RefCount*>(p_);
+ if (p) {
+ ref_count = p->Release();
+ }
+ p_ = NULL;
+ }
+ return ref_count;
+ }
+
+ void Attach(T* pT) {
+ if (p_ != pT) {
+ Release();
+ p_ = pT;
+ }
+ }
+
+ T* Detach() {
+ T* pT = p_;
+ p_ = NULL;
+ return pT;
+ }
+
+ mutable T* p_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_REFCOUNT_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/port/type.h b/chromium/third_party/sfntly/cpp/src/sfntly/port/type.h
new file mode 100644
index 00000000000..20a5ba8a892
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/port/type.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_PORT_TYPE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_PORT_TYPE_H_
+
+#include <assert.h>
+
+#if defined (_MSC_VER) && (_MSC_VER < 1600)
+ typedef unsigned char uint8_t;
+ typedef signed char int8_t;
+ typedef unsigned __int16 uint16_t;
+ typedef signed __int16 int16_t;
+ typedef unsigned __int32 uint32_t;
+ typedef signed __int32 int32_t;
+ typedef unsigned __int64 uint64_t;
+ typedef signed __int64 int64_t;
+ // Definitions to avoid ICU redefinition issue
+ #define U_HAVE_INT8_T 1
+ #define U_HAVE_UINT8_T 1
+ #define U_HAVE_INT16_T 1
+ #define U_HAVE_UINT16_T 1
+ #define U_HAVE_INT32_T 1
+ #define U_HAVE_UINT32_T 1
+ #define U_HAVE_INT64_T 1
+ #define U_HAVE_UINT64_T 1
+#else
+ #include <stdint.h>
+#endif
+
+#include <cstddef>
+#include <vector>
+#include <set>
+
+namespace sfntly {
+
+typedef uint8_t byte_t;
+typedef uint16_t word_t;
+typedef uint32_t dword_t;
+typedef uint64_t qword_t;
+
+typedef std::vector<byte_t> ByteVector;
+typedef std::vector<int32_t> IntegerList;
+typedef std::set<int32_t> IntegerSet;
+
+// A macro to disallow the copy constructor and operator= functions.
+// This should be used in the private: declarations for a class.
+#define NO_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&); \
+ void operator=(const TypeName&)
+
+} // namespace sfntly
+
+// Make google3 happy since it prohibits RTTI.
+template<typename To, typename From>
+inline To implicit_cast(From const &f) {
+ return f;
+}
+
+template<typename To, typename From> // use like this: down_cast<T*>(foo);
+inline To down_cast(From* f) { // so we only accept pointers
+ // Ensures that To is a sub-type of From *. This test is here only
+ // for compile-time type checking, and has no overhead in an
+ // optimized build at run-time, as it will be optimized away
+ // completely.
+#if defined (_MSC_VER)
+ #pragma warning(push)
+ #pragma warning(disable:4127) // disable "conditional expression is constant"
+#endif
+ if (false) {
+ implicit_cast<From*, To>(0);
+ }
+#if defined (_MSC_VER)
+ #pragma warning(pop)
+#endif
+
+// The following code is the only place for RTTI. It is done so to allow
+// additional type checking when SFNTLY_TYPE_VERIFICATION is defined.
+#if defined (SFNTLY_TYPE_VERIFICATION)
+ assert(f == NULL || dynamic_cast<To>(f) != NULL);
+#endif
+ return static_cast<To>(f);
+}
+
+#if !defined(WIN32)
+ #define UNREFERENCED_PARAMETER(p) do { (void)p; } while (0)
+#endif
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_PORT_TYPE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc
new file mode 100644
index 00000000000..d853212bbeb
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/big_glyph_metrics.h"
+
+namespace sfntly {
+/******************************************************************************
+ * BigGlyphMetrics class
+ ******************************************************************************/
+BigGlyphMetrics::BigGlyphMetrics(ReadableFontData* data)
+ : GlyphMetrics(data) {
+}
+
+BigGlyphMetrics::~BigGlyphMetrics() {
+}
+
+int32_t BigGlyphMetrics::Height() {
+ return data_->ReadByte(Offset::kHeight);
+}
+
+int32_t BigGlyphMetrics::Width() {
+ return data_->ReadByte(Offset::kWidth);
+}
+
+int32_t BigGlyphMetrics::HoriBearingX() {
+ return data_->ReadByte(Offset::kHoriBearingX);
+}
+
+int32_t BigGlyphMetrics::HoriBearingY() {
+ return data_->ReadByte(Offset::kHoriBearingY);
+}
+
+int32_t BigGlyphMetrics::HoriAdvance() {
+ return data_->ReadByte(Offset::kHoriAdvance);
+}
+
+int32_t BigGlyphMetrics::VertBearingX() {
+ return data_->ReadByte(Offset::kVertBearingX);
+}
+
+int32_t BigGlyphMetrics::VertBearingY() {
+ return data_->ReadByte(Offset::kVertBearingY);
+}
+
+int32_t BigGlyphMetrics::VertAdvance() {
+ return data_->ReadByte(Offset::kVertAdvance);
+}
+
+/******************************************************************************
+ * BigGlyphMetrics::Builder class
+ ******************************************************************************/
+BigGlyphMetrics::Builder::Builder(WritableFontData* data)
+ : GlyphMetrics::Builder(data) {
+}
+
+BigGlyphMetrics::Builder::Builder(ReadableFontData* data)
+ : GlyphMetrics::Builder(data) {
+}
+
+BigGlyphMetrics::Builder::~Builder() {
+}
+
+int32_t BigGlyphMetrics::Builder::Height() {
+ return InternalReadData()->ReadByte(Offset::kHeight);
+}
+
+void BigGlyphMetrics::Builder::SetHeight(byte_t height) {
+ InternalWriteData()->WriteByte(Offset::kHeight, height);
+}
+
+int32_t BigGlyphMetrics::Builder::Width() {
+ return InternalReadData()->ReadByte(Offset::kWidth);
+}
+
+void BigGlyphMetrics::Builder::SetWidth(byte_t width) {
+ InternalWriteData()->WriteByte(Offset::kWidth, width);
+}
+
+int32_t BigGlyphMetrics::Builder::HoriBearingX() {
+ return InternalReadData()->ReadByte(Offset::kHoriBearingX);
+}
+
+void BigGlyphMetrics::Builder::SetHoriBearingX(byte_t bearing) {
+ InternalWriteData()->WriteByte(Offset::kHoriBearingX, bearing);
+}
+
+int32_t BigGlyphMetrics::Builder::HoriBearingY() {
+ return InternalReadData()->ReadByte(Offset::kHoriBearingY);
+}
+
+void BigGlyphMetrics::Builder::SetHoriBearingY(byte_t bearing) {
+ InternalWriteData()->WriteByte(Offset::kHoriBearingY, bearing);
+}
+
+int32_t BigGlyphMetrics::Builder::HoriAdvance() {
+ return InternalReadData()->ReadByte(Offset::kHoriAdvance);
+}
+
+void BigGlyphMetrics::Builder::SetHoriAdvance(byte_t advance) {
+ InternalWriteData()->WriteByte(Offset::kHoriAdvance, advance);
+}
+
+int32_t BigGlyphMetrics::Builder::VertBearingX() {
+ return InternalReadData()->ReadByte(Offset::kVertBearingX);
+}
+
+void BigGlyphMetrics::Builder::SetVertBearingX(byte_t bearing) {
+ InternalWriteData()->WriteByte(Offset::kVertBearingX, bearing);
+}
+
+int32_t BigGlyphMetrics::Builder::VertBearingY() {
+ return InternalReadData()->ReadByte(Offset::kVertBearingY);
+}
+
+void BigGlyphMetrics::Builder::SetVertBearingY(byte_t bearing) {
+ InternalWriteData()->WriteByte(Offset::kVertBearingY, bearing);
+}
+
+int32_t BigGlyphMetrics::Builder::VertAdvance() {
+ return InternalReadData()->ReadByte(Offset::kVertAdvance);
+}
+
+void BigGlyphMetrics::Builder::SetVertAdvance(byte_t advance) {
+ InternalWriteData()->WriteByte(Offset::kVertAdvance, advance);
+}
+
+CALLER_ATTACH FontDataTable*
+ BigGlyphMetrics::Builder::SubBuildTable(ReadableFontData* data) {
+ BigGlyphMetricsPtr output = new BigGlyphMetrics(data);
+ return output.Detach();
+}
+
+void BigGlyphMetrics::Builder::SubDataSet() {
+ // NOP.
+}
+
+int32_t BigGlyphMetrics::Builder::SubDataSizeToSerialize() {
+ return 0;
+}
+
+bool BigGlyphMetrics::Builder::SubReadyToSerialize() {
+ return false;
+}
+
+int32_t BigGlyphMetrics::Builder::SubSerialize(WritableFontData* new_data) {
+ return Data()->CopyTo(new_data);
+}
+
+// static
+CALLER_ATTACH
+BigGlyphMetrics::Builder* BigGlyphMetrics::Builder::CreateBuilder() {
+ WritableFontDataPtr data;
+ data.Attach(WritableFontData::CreateWritableFontData(Offset::kMetricsLength));
+ BigGlyphMetricsBuilderPtr output = new BigGlyphMetrics::Builder(data);
+ return output.Detach();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/big_glyph_metrics.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/big_glyph_metrics.h
new file mode 100644
index 00000000000..a91601c211b
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/big_glyph_metrics.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BIG_GLYPH_METRICS_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BIG_GLYPH_METRICS_H_
+
+#include "sfntly/table/bitmap/glyph_metrics.h"
+
+namespace sfntly {
+
+class BigGlyphMetrics : public GlyphMetrics,
+ public RefCounted<BigGlyphMetrics> {
+ public:
+ struct Offset {
+ enum {
+ kMetricsLength = 8,
+
+ kHeight = 0,
+ kWidth = 1,
+ kHoriBearingX = 2,
+ kHoriBearingY = 3,
+ kHoriAdvance = 4,
+ kVertBearingX = 5,
+ kVertBearingY = 6,
+ kVertAdvance = 7,
+ };
+ };
+
+ class Builder : public GlyphMetrics::Builder,
+ public RefCounted<Builder> {
+ public:
+ // Constructor scope altered to public because C++ does not allow base
+ // class to instantiate derived class with protected constructors.
+ explicit Builder(WritableFontData* data);
+ explicit Builder(ReadableFontData* data);
+
+ virtual ~Builder();
+
+ int32_t Height();
+ void SetHeight(byte_t height);
+ int32_t Width();
+ void SetWidth(byte_t width);
+ int32_t HoriBearingX();
+ void SetHoriBearingX(byte_t bearing);
+ int32_t HoriBearingY();
+ void SetHoriBearingY(byte_t bearing);
+ int32_t HoriAdvance();
+ void SetHoriAdvance(byte_t advance);
+ int32_t VertBearingX();
+ void SetVertBearingX(byte_t bearing);
+ int32_t VertBearingY();
+ void SetVertBearingY(byte_t bearing);
+ int32_t VertAdvance();
+ void SetVertAdvance(byte_t advance);
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ // Static instantiation function.
+ static CALLER_ATTACH Builder* CreateBuilder();
+ };
+
+ explicit BigGlyphMetrics(ReadableFontData* data);
+ virtual ~BigGlyphMetrics();
+
+ int32_t Height();
+ int32_t Width();
+ int32_t HoriBearingX();
+ int32_t HoriBearingY();
+ int32_t HoriAdvance();
+ int32_t VertBearingX();
+ int32_t VertBearingY();
+ int32_t VertAdvance();
+};
+typedef Ptr<BigGlyphMetrics> BigGlyphMetricsPtr;
+typedef Ptr<BigGlyphMetrics::Builder> BigGlyphMetricsBuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BIG_GLYPH_METRICS_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph.cc
new file mode 100644
index 00000000000..334a0c07fb4
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph.cc
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 = the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/bitmap_glyph.h"
+#include "sfntly/table/bitmap/simple_bitmap_glyph.h"
+#include "sfntly/table/bitmap/composite_bitmap_glyph.h"
+
+namespace sfntly {
+/******************************************************************************
+ * BitmapGlyph class
+ ******************************************************************************/
+BitmapGlyph::~BitmapGlyph() {
+}
+
+CALLER_ATTACH BitmapGlyph* BitmapGlyph::CreateGlyph(ReadableFontData* data,
+ int32_t format) {
+ BitmapGlyphPtr glyph;
+ BitmapGlyphBuilderPtr builder;
+ builder.Attach(Builder::CreateGlyphBuilder(data, format));
+ if (builder) {
+ glyph.Attach(down_cast<BitmapGlyph*>(builder->Build()));
+ }
+ return glyph;
+}
+
+BitmapGlyph::BitmapGlyph(ReadableFontData* data, int32_t format)
+ : SubTable(data), format_(format) {
+}
+
+/******************************************************************************
+ * BitmapGlyph::Builder class
+ ******************************************************************************/
+BitmapGlyph::Builder::~Builder() {
+}
+
+CALLER_ATTACH BitmapGlyph::Builder*
+BitmapGlyph::Builder::CreateGlyphBuilder(ReadableFontData* data,
+ int32_t format) {
+ BitmapGlyphBuilderPtr builder;
+ switch (format) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ builder = new SimpleBitmapGlyph::Builder(data, format);
+ break;
+ case 8:
+ case 9:
+ builder = new CompositeBitmapGlyph::Builder(data, format);
+ break;
+ }
+ return builder.Detach();
+}
+
+BitmapGlyph::Builder::Builder(WritableFontData* data, int32_t format)
+ : SubTable::Builder(data), format_(format) {
+}
+
+BitmapGlyph::Builder::Builder(ReadableFontData* data, int32_t format)
+ : SubTable::Builder(data), format_(format) {
+}
+
+CALLER_ATTACH
+FontDataTable* BitmapGlyph::Builder::SubBuildTable(ReadableFontData* data) {
+ UNREFERENCED_PARAMETER(data);
+ return NULL;
+}
+
+void BitmapGlyph::Builder::SubDataSet() {
+ // NOP
+}
+
+int32_t BitmapGlyph::Builder::SubDataSizeToSerialize() {
+ return InternalReadData()->Length();
+}
+
+bool BitmapGlyph::Builder::SubReadyToSerialize() {
+ return true;
+}
+
+int32_t BitmapGlyph::Builder::SubSerialize(WritableFontData* new_data) {
+ return InternalReadData()->CopyTo(new_data);
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph.h
new file mode 100644
index 00000000000..2dd4c3a130c
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 = the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_GLYPH_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_GLYPH_H_
+
+#include <vector>
+#include <map>
+
+#include "sfntly/table/subtable.h"
+
+namespace sfntly {
+
+class BitmapGlyph : public SubTable {
+ public:
+ struct Offset {
+ enum {
+ // header
+ kVersion = 0,
+
+ kSmallGlyphMetricsLength = 5,
+ kBigGlyphMetricsLength = 8,
+ // format 1
+ kGlyphFormat1_imageData = kSmallGlyphMetricsLength,
+
+ // format 2
+ kGlyphFormat2_imageData = kSmallGlyphMetricsLength,
+
+ // format 3
+
+ // format 4
+
+ // format 5
+ kGlyphFormat5_imageData = 0,
+
+ // format 6
+ kGlyphFormat6_imageData = kBigGlyphMetricsLength,
+
+ // format 7
+ kGlyphFormat7_imageData = kBigGlyphMetricsLength,
+
+ // format 8
+ kGlyphFormat8_numComponents = kSmallGlyphMetricsLength + 1,
+ kGlyphFormat8_componentArray = kGlyphFormat8_numComponents +
+ DataSize::kUSHORT,
+
+ // format 9
+ kGlyphFormat9_numComponents = kBigGlyphMetricsLength,
+ kGlyphFormat9_componentArray = kGlyphFormat9_numComponents +
+ DataSize::kUSHORT,
+
+ // ebdtComponent
+ kEbdtComponentLength = DataSize::kUSHORT + 2 * DataSize::kCHAR,
+ kEbdtComponent_glyphCode = 0,
+ kEbdtComponent_xOffset = 2,
+ kEbdtComponent_yOffset = 3,
+ };
+ };
+
+ // TODO(stuartg): builder is not functional at all
+ // - need to add subclasses for each type of bitmap glyph
+ class Builder : public SubTable::Builder {
+ public:
+ virtual ~Builder();
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ int32_t format() { return format_; }
+
+ static CALLER_ATTACH Builder* CreateGlyphBuilder(ReadableFontData* data,
+ int32_t format);
+
+ protected:
+ Builder(WritableFontData* data, int32_t format);
+ Builder(ReadableFontData* data, int32_t format);
+
+ private:
+ int32_t format_;
+ };
+
+ virtual ~BitmapGlyph();
+
+ static CALLER_ATTACH BitmapGlyph* CreateGlyph(ReadableFontData* data,
+ int32_t format);
+ int32_t format() { return format_; }
+
+ // UNIMPLEMENTED: toString()
+
+ protected:
+ BitmapGlyph(ReadableFontData* data, int32_t format);
+
+ private:
+ int32_t format_;
+};
+typedef Ptr<BitmapGlyph> BitmapGlyphPtr;
+typedef Ptr<BitmapGlyph::Builder> BitmapGlyphBuilderPtr;
+typedef std::map<int32_t, BitmapGlyphBuilderPtr> BitmapGlyphBuilderMap;
+typedef std::vector<BitmapGlyphBuilderMap> BitmapGlyphBuilderList;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_GLYPH_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph_info.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph_info.cc
new file mode 100644
index 00000000000..ab9953bc770
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph_info.cc
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/bitmap_glyph_info.h"
+
+namespace sfntly {
+
+BitmapGlyphInfo::BitmapGlyphInfo(int32_t glyph_id,
+ int32_t block_offset,
+ int32_t start_offset,
+ int32_t length,
+ int32_t format)
+ : glyph_id_(glyph_id),
+ relative_(true),
+ block_offset_(block_offset),
+ start_offset_(start_offset),
+ length_(length),
+ format_(format) {
+}
+
+BitmapGlyphInfo::BitmapGlyphInfo(int32_t glyph_id,
+ int32_t start_offset,
+ int32_t length,
+ int32_t format)
+ : glyph_id_(glyph_id),
+ relative_(false),
+ block_offset_(0),
+ start_offset_(start_offset),
+ length_(length),
+ format_(format) {
+}
+
+bool BitmapGlyphInfo::operator==(const BitmapGlyphInfo& rhs) const {
+ return (format_ == rhs.format_ &&
+ glyph_id_ == rhs.glyph_id_ &&
+ length_ == rhs.length_ &&
+ offset() == rhs.offset());
+}
+
+bool BitmapGlyphInfo::operator==(BitmapGlyphInfo* rhs) {
+ if (rhs == NULL) {
+ return this == NULL;
+ }
+ return (format_ == rhs->format() &&
+ glyph_id_ == rhs->glyph_id() &&
+ length_ == rhs->length() &&
+ offset() == rhs->offset());
+}
+
+bool StartOffsetComparator::operator()(BitmapGlyphInfo* lhs,
+ BitmapGlyphInfo* rhs) {
+ return lhs->start_offset() > rhs->start_offset();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph_info.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph_info.h
new file mode 100644
index 00000000000..9921d0d526a
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_glyph_info.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_INFO_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_INFO_H_
+
+#include <vector>
+#include <map>
+
+#include "sfntly/table/subtable.h"
+
+namespace sfntly {
+
+// An immutable class holding bitmap glyph information.
+class BitmapGlyphInfo : public RefCounted<BitmapGlyphInfo> {
+ public:
+ // Constructor for a relative located glyph. The glyph's position in the EBDT
+ // table is a combination of it's block offset and it's own start offset.
+ // @param glyphId the glyph id
+ // @param blockOffset the offset of the block to which the glyph belongs
+ // @param startOffset the offset of the glyph within the block
+ // @param length the byte length
+ // @param format the glyph image format
+ BitmapGlyphInfo(int32_t glyph_id,
+ int32_t block_offset,
+ int32_t start_offset,
+ int32_t length,
+ int32_t format);
+
+ // Constructor for an absolute located glyph. The glyph's position in the EBDT
+ // table is only given by it's own start offset.
+ // @param glyphId the glyph id
+ // @param startOffset the offset of the glyph within the block
+ // @param length the byte length
+ // @param format the glyph image format
+ BitmapGlyphInfo(int32_t glyph_id,
+ int32_t start_offset,
+ int32_t length,
+ int32_t format);
+
+ int32_t glyph_id() const { return glyph_id_; }
+ bool relative() const { return relative_; }
+ int32_t block_offset() const { return block_offset_; }
+ int32_t offset() const { return block_offset() + start_offset(); }
+ int32_t start_offset() const { return start_offset_; }
+ int32_t length() const { return length_; }
+ int32_t format() const { return format_; }
+
+ // UNIMPLEMENTED: hashCode()
+ bool operator==(const BitmapGlyphInfo& rhs) const;
+ bool operator==(BitmapGlyphInfo* rhs);
+
+ private:
+ int32_t glyph_id_;
+ bool relative_;
+ int32_t block_offset_;
+ int32_t start_offset_;
+ int32_t length_;
+ int32_t format_;
+};
+typedef Ptr<BitmapGlyphInfo> BitmapGlyphInfoPtr;
+typedef std::map<int32_t, BitmapGlyphInfoPtr> BitmapGlyphInfoMap;
+typedef std::vector<BitmapGlyphInfoMap> BitmapLocaList;
+
+class StartOffsetComparator {
+ public:
+ bool operator()(BitmapGlyphInfo* lhs, BitmapGlyphInfo* rhs);
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_INFO_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_size_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_size_table.cc
new file mode 100644
index 00000000000..6c7d7315a45
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_size_table.cc
@@ -0,0 +1,604 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 = the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/bitmap_size_table.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sfntly/math/font_math.h"
+#include "sfntly/table/bitmap/eblc_table.h"
+#include "sfntly/table/bitmap/index_sub_table_format1.h"
+#include "sfntly/table/bitmap/index_sub_table_format2.h"
+#include "sfntly/table/bitmap/index_sub_table_format3.h"
+#include "sfntly/table/bitmap/index_sub_table_format4.h"
+#include "sfntly/table/bitmap/index_sub_table_format5.h"
+
+namespace sfntly {
+/******************************************************************************
+ * BitmapSizeTable class
+ ******************************************************************************/
+BitmapSizeTable::~BitmapSizeTable() {
+}
+
+int32_t BitmapSizeTable::IndexSubTableArrayOffset() {
+ return data_->ReadULongAsInt(
+ EblcTable::Offset::kBitmapSizeTable_indexSubTableArrayOffset);
+}
+
+int32_t BitmapSizeTable::IndexTableSize() {
+ return data_->ReadULongAsInt(
+ EblcTable::Offset::kBitmapSizeTable_indexTableSize);
+}
+
+int32_t BitmapSizeTable::NumberOfIndexSubTables() {
+ return NumberOfIndexSubTables(data_, 0);
+}
+
+int32_t BitmapSizeTable::ColorRef() {
+ return data_->ReadULongAsInt(EblcTable::Offset::kBitmapSizeTable_colorRef);
+}
+
+int32_t BitmapSizeTable::StartGlyphIndex() {
+ return data_->ReadUShort(EblcTable::Offset::kBitmapSizeTable_startGlyphIndex);
+}
+
+int32_t BitmapSizeTable::EndGlyphIndex() {
+ return data_->ReadUShort(EblcTable::Offset::kBitmapSizeTable_endGlyphIndex);
+}
+
+int32_t BitmapSizeTable::PpemX() {
+ return data_->ReadByte(EblcTable::Offset::kBitmapSizeTable_ppemX);
+}
+
+int32_t BitmapSizeTable::PpemY() {
+ return data_->ReadByte(EblcTable::Offset::kBitmapSizeTable_ppemY);
+}
+
+int32_t BitmapSizeTable::BitDepth() {
+ return data_->ReadByte(EblcTable::Offset::kBitmapSizeTable_bitDepth);
+}
+
+int32_t BitmapSizeTable::FlagsAsInt() {
+ return data_->ReadChar(EblcTable::Offset::kBitmapSizeTable_flags);
+}
+
+IndexSubTable* BitmapSizeTable::GetIndexSubTable(int32_t index) {
+ IndexSubTableList* subtable_list = GetIndexSubTableList();
+ if (index >= 0 && (size_t)index < subtable_list->size()) {
+ return (*subtable_list)[index];
+ }
+ return NULL;
+}
+
+int32_t BitmapSizeTable::GlyphOffset(int32_t glyph_id) {
+ IndexSubTable* subtable = SearchIndexSubTables(glyph_id);
+ if (subtable == NULL) {
+ return -1;
+ }
+ return subtable->GlyphOffset(glyph_id);
+}
+
+int32_t BitmapSizeTable::GlyphLength(int32_t glyph_id) {
+ IndexSubTable* subtable = SearchIndexSubTables(glyph_id);
+ if (subtable == NULL) {
+ return -1;
+ }
+ return subtable->GlyphLength(glyph_id);
+}
+
+CALLER_ATTACH BitmapGlyphInfo* BitmapSizeTable::GlyphInfo(int32_t glyph_id) {
+ IndexSubTable* sub_table = SearchIndexSubTables(glyph_id);
+ if (sub_table == NULL) {
+ return NULL;
+ }
+ return sub_table->GlyphInfo(glyph_id);
+}
+
+int32_t BitmapSizeTable::GlyphFormat(int32_t glyph_id) {
+ IndexSubTable* subtable = SearchIndexSubTables(glyph_id);
+ if (subtable == NULL) {
+ return -1;
+ }
+ return subtable->image_format();
+}
+
+BitmapSizeTable::BitmapSizeTable(ReadableFontData* data,
+ ReadableFontData* master_data)
+ : SubTable(data, master_data) {
+}
+
+// static
+int32_t BitmapSizeTable::NumberOfIndexSubTables(ReadableFontData* data,
+ int32_t table_offset) {
+ return data->ReadULongAsInt(table_offset +
+ EblcTable::Offset::kBitmapSizeTable_numberOfIndexSubTables);
+}
+
+IndexSubTable* BitmapSizeTable::SearchIndexSubTables(int32_t glyph_id) {
+ // would be faster to binary search but too many size tables don't have
+ // sorted subtables
+#if (SFNTLY_BITMAPSIZE_USE_BINARY_SEARCH)
+ return BinarySearchIndexSubTables(glyph_id);
+#else
+ return LinearSearchIndexSubTables(glyph_id);
+#endif
+}
+
+IndexSubTable* BitmapSizeTable::LinearSearchIndexSubTables(int32_t glyph_id) {
+ IndexSubTableList* subtable_list = GetIndexSubTableList();
+ for (IndexSubTableList::iterator b = subtable_list->begin(),
+ e = subtable_list->end(); b != e; b++) {
+ if ((*b)->first_glyph_index() <= glyph_id &&
+ (*b)->last_glyph_index() >= glyph_id) {
+ return *b;
+ }
+ }
+ return NULL;
+}
+
+IndexSubTable* BitmapSizeTable::BinarySearchIndexSubTables(int32_t glyph_id) {
+ IndexSubTableList* subtable_list = GetIndexSubTableList();
+ int32_t index = 0;
+ int32_t bottom = 0;
+ int32_t top = subtable_list->size();
+ while (top != bottom) {
+ index = (top + bottom) / 2;
+ IndexSubTable* subtable = (*subtable_list)[index];
+ if (glyph_id < subtable->first_glyph_index()) {
+ // Location beow current location
+ top = index;
+ } else {
+ if (glyph_id <= subtable->last_glyph_index()) {
+ return subtable;
+ } else {
+ bottom = index + 1;
+ }
+ }
+ }
+ return NULL;
+}
+
+CALLER_ATTACH
+IndexSubTable* BitmapSizeTable::CreateIndexSubTable(int32_t index) {
+ return IndexSubTable::CreateIndexSubTable(master_read_data(),
+ IndexSubTableArrayOffset(),
+ index);
+}
+
+IndexSubTableList* BitmapSizeTable::GetIndexSubTableList() {
+ AutoLock lock(index_subtables_lock_);
+ if (index_subtables_.empty()) {
+ for (int32_t i = 0; i < NumberOfIndexSubTables(); ++i) {
+ IndexSubTablePtr table;
+ table.Attach(CreateIndexSubTable(i));
+ index_subtables_.push_back(table);
+ }
+ }
+ return &index_subtables_;
+}
+
+/******************************************************************************
+ * BitmapSizeTable::Builder class
+ ******************************************************************************/
+BitmapSizeTable::Builder::~Builder() {
+}
+
+CALLER_ATTACH
+FontDataTable* BitmapSizeTable::Builder::SubBuildTable(ReadableFontData* data) {
+ BitmapSizeTablePtr output = new BitmapSizeTable(data, master_read_data());
+ return output.Detach();
+}
+
+void BitmapSizeTable::Builder::SubDataSet() {
+ Revert();
+}
+
+int32_t BitmapSizeTable::Builder::SubDataSizeToSerialize() {
+ IndexSubTableBuilderList* builders = IndexSubTableBuilders();
+ if (builders->empty()) {
+ return 0;
+ }
+ int32_t size = EblcTable::Offset::kBitmapSizeTableLength;
+ bool variable = false;
+ for (IndexSubTableBuilderList::iterator b = builders->begin(),
+ e = builders->end(); b != e; b++) {
+ size += EblcTable::Offset::kIndexSubTableEntryLength;
+ int32_t sub_table_size = (*b)->SubDataSizeToSerialize();
+ int32_t padding = FontMath::PaddingRequired(abs(sub_table_size),
+ DataSize::kULONG);
+#if defined (SFNTLY_DEBUG_BITMAP)
+ fprintf(stderr, "subtable size=%d\n", sub_table_size);
+#endif
+ variable = (sub_table_size > 0) ? variable : true;
+ size += abs(sub_table_size) + padding;
+ }
+#if defined (SFNTLY_DEBUG_BITMAP)
+ fprintf(stderr, "bitmap table size=%d\n", variable ? -size : size);
+#endif
+ return variable ? -size : size;
+}
+
+bool BitmapSizeTable::Builder::SubReadyToSerialize() {
+ if (IndexSubTableBuilders()->empty()) {
+ return false;
+ }
+ return true;
+}
+
+int32_t BitmapSizeTable::Builder::SubSerialize(WritableFontData* new_data) {
+ SetNumberOfIndexSubTables(IndexSubTableBuilders()->size());
+ int32_t size = InternalReadData()->CopyTo(new_data);
+ return size;
+}
+
+CALLER_ATTACH BitmapSizeTable::Builder*
+BitmapSizeTable::Builder::CreateBuilder(WritableFontData* data,
+ ReadableFontData* master_data) {
+ BitmapSizeTableBuilderPtr output =
+ new BitmapSizeTable::Builder(data, master_data);
+ return output.Detach();
+}
+
+CALLER_ATTACH BitmapSizeTable::Builder*
+BitmapSizeTable::Builder::CreateBuilder(ReadableFontData* data,
+ ReadableFontData* master_data) {
+ BitmapSizeTableBuilderPtr output =
+ new BitmapSizeTable::Builder(data, master_data);
+ return output.Detach();
+}
+
+int32_t BitmapSizeTable::Builder::IndexSubTableArrayOffset() {
+ return InternalReadData()->ReadULongAsInt(
+ EblcTable::Offset::kBitmapSizeTable_indexSubTableArrayOffset);
+}
+
+void BitmapSizeTable::Builder::SetIndexSubTableArrayOffset(int32_t offset) {
+ InternalWriteData()->WriteULong(
+ EblcTable::Offset::kBitmapSizeTable_indexSubTableArrayOffset, offset);
+}
+
+int32_t BitmapSizeTable::Builder::IndexTableSize() {
+ return InternalReadData()->ReadULongAsInt(
+ EblcTable::Offset::kBitmapSizeTable_indexTableSize);
+}
+
+void BitmapSizeTable::Builder::SetIndexTableSize(int32_t size) {
+ InternalWriteData()->WriteULong(
+ EblcTable::Offset::kBitmapSizeTable_indexTableSize, size);
+}
+
+int32_t BitmapSizeTable::Builder::NumberOfIndexSubTables() {
+ return GetIndexSubTableBuilders()->size();
+}
+
+int32_t BitmapSizeTable::Builder::ColorRef() {
+ return InternalReadData()->ReadULongAsInt(
+ EblcTable::Offset::kBitmapSizeTable_colorRef);
+}
+
+int32_t BitmapSizeTable::Builder::StartGlyphIndex() {
+ return InternalReadData()->ReadUShort(
+ EblcTable::Offset::kBitmapSizeTable_startGlyphIndex);
+}
+
+int32_t BitmapSizeTable::Builder::EndGlyphIndex() {
+ return InternalReadData()->ReadUShort(
+ EblcTable::Offset::kBitmapSizeTable_endGlyphIndex);
+}
+
+int32_t BitmapSizeTable::Builder::PpemX() {
+ return InternalReadData()->ReadByte(
+ EblcTable::Offset::kBitmapSizeTable_ppemX);
+}
+
+int32_t BitmapSizeTable::Builder::PpemY() {
+ return InternalReadData()->ReadByte(
+ EblcTable::Offset::kBitmapSizeTable_ppemY);
+}
+
+int32_t BitmapSizeTable::Builder::BitDepth() {
+ return InternalReadData()->ReadByte(
+ EblcTable::Offset::kBitmapSizeTable_bitDepth);
+}
+
+int32_t BitmapSizeTable::Builder::FlagsAsInt() {
+ return InternalReadData()->ReadChar(
+ EblcTable::Offset::kBitmapSizeTable_flags);
+}
+
+IndexSubTable::Builder* BitmapSizeTable::Builder::IndexSubTableBuilder(
+ int32_t index) {
+ IndexSubTableBuilderList* sub_table_list = GetIndexSubTableBuilders();
+ return sub_table_list->at(index);
+}
+
+CALLER_ATTACH BitmapGlyphInfo* BitmapSizeTable::Builder::GlyphInfo(
+ int32_t glyph_id) {
+ IndexSubTable::Builder* sub_table = SearchIndexSubTables(glyph_id);
+ if (sub_table == NULL) {
+ return NULL;
+ }
+ return sub_table->GlyphInfo(glyph_id);
+}
+
+int32_t BitmapSizeTable::Builder::GlyphOffset(int32_t glyph_id) {
+ IndexSubTable::Builder* subtable = SearchIndexSubTables(glyph_id);
+ if (subtable == NULL) {
+ return -1;
+ }
+ return subtable->GlyphOffset(glyph_id);
+}
+
+int32_t BitmapSizeTable::Builder::GlyphLength(int32_t glyph_id) {
+ IndexSubTable::Builder* subtable = SearchIndexSubTables(glyph_id);
+ if (subtable == NULL) {
+ return -1;
+ }
+ return subtable->GlyphLength(glyph_id);
+}
+
+int32_t BitmapSizeTable::Builder::GlyphFormat(int32_t glyph_id) {
+ IndexSubTable::Builder* subtable = SearchIndexSubTables(glyph_id);
+ if (subtable == NULL) {
+ return -1;
+ }
+ return subtable->image_format();
+}
+
+IndexSubTableBuilderList* BitmapSizeTable::Builder::IndexSubTableBuilders() {
+ return GetIndexSubTableBuilders();
+}
+
+CALLER_ATTACH BitmapSizeTable::Builder::BitmapGlyphInfoIterator*
+BitmapSizeTable::Builder::GetIterator() {
+ Ptr<BitmapSizeTable::Builder::BitmapGlyphInfoIterator> output =
+ new BitmapSizeTable::Builder::BitmapGlyphInfoIterator(this);
+ return output.Detach();
+}
+
+void BitmapSizeTable::Builder::GenerateLocaMap(BitmapGlyphInfoMap* output) {
+ assert(output);
+ Ptr<BitmapSizeTable::Builder::BitmapGlyphInfoIterator> it;
+ it.Attach(GetIterator());
+ while (it->HasNext()) {
+ BitmapGlyphInfoPtr info;
+ info.Attach(it->Next());
+ (*output)[info->glyph_id()] = info;
+ }
+}
+
+void BitmapSizeTable::Builder::Revert() {
+ index_sub_tables_.clear();
+ set_model_changed(false);
+}
+
+BitmapSizeTable::Builder::Builder(WritableFontData* data,
+ ReadableFontData* master_data)
+ : SubTable::Builder(data, master_data) {
+}
+
+BitmapSizeTable::Builder::Builder(ReadableFontData* data,
+ ReadableFontData* master_data)
+ : SubTable::Builder(data, master_data) {
+}
+
+void BitmapSizeTable::Builder::SetNumberOfIndexSubTables(int32_t count) {
+ InternalWriteData()->WriteULong(
+ EblcTable::Offset::kBitmapSizeTable_numberOfIndexSubTables, count);
+}
+
+IndexSubTable::Builder* BitmapSizeTable::Builder::SearchIndexSubTables(
+ int32_t glyph_id) {
+ // would be faster to binary search but too many size tables don't have
+ // sorted subtables
+#if (SFNTLY_BITMAPSIZE_USE_BINARY_SEARCH)
+ return BinarySearchIndexSubTables(glyph_id);
+#else
+ return LinearSearchIndexSubTables(glyph_id);
+#endif
+}
+
+IndexSubTable::Builder* BitmapSizeTable::Builder::LinearSearchIndexSubTables(
+ int32_t glyph_id) {
+ IndexSubTableBuilderList* subtable_list = GetIndexSubTableBuilders();
+ for (IndexSubTableBuilderList::iterator b = subtable_list->begin(),
+ e = subtable_list->end();
+ b != e; b++) {
+ if ((*b)->first_glyph_index() <= glyph_id &&
+ (*b)->last_glyph_index() >= glyph_id) {
+ return *b;
+ }
+ }
+ return NULL;
+}
+
+IndexSubTable::Builder* BitmapSizeTable::Builder::BinarySearchIndexSubTables(
+ int32_t glyph_id) {
+ IndexSubTableBuilderList* subtable_list = GetIndexSubTableBuilders();
+ int32_t index = 0;
+ int32_t bottom = 0;
+ int32_t top = subtable_list->size();
+ while (top != bottom) {
+ index = (top + bottom) / 2;
+ IndexSubTable::Builder* subtable = subtable_list->at(index);
+ if (glyph_id < subtable->first_glyph_index()) {
+ // Location beow current location
+ top = index;
+ } else {
+ if (glyph_id <= subtable->last_glyph_index()) {
+ return subtable;
+ } else {
+ bottom = index + 1;
+ }
+ }
+ }
+ return NULL;
+}
+
+IndexSubTableBuilderList* BitmapSizeTable::Builder::GetIndexSubTableBuilders() {
+ if (index_sub_tables_.empty()) {
+ Initialize(InternalReadData());
+ set_model_changed();
+ }
+ return &index_sub_tables_;
+}
+
+void BitmapSizeTable::Builder::Initialize(ReadableFontData* data) {
+ index_sub_tables_.clear();
+ if (data) {
+ int32_t number_of_index_subtables =
+ BitmapSizeTable::NumberOfIndexSubTables(data, 0);
+ index_sub_tables_.resize(number_of_index_subtables);
+ for (int32_t i = 0; i < number_of_index_subtables; ++i) {
+ index_sub_tables_[i].Attach(CreateIndexSubTableBuilder(i));
+ }
+ }
+}
+
+CALLER_ATTACH IndexSubTable::Builder*
+BitmapSizeTable::Builder::CreateIndexSubTableBuilder(int32_t index) {
+ return IndexSubTable::Builder::CreateBuilder(master_read_data(),
+ IndexSubTableArrayOffset(),
+ index);
+}
+
+/******************************************************************************
+ * BitmapSizeTable::Builder::BitmapGlyphInfoIterator class
+ ******************************************************************************/
+BitmapSizeTable::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
+ BitmapSizeTable::Builder* container)
+ : RefIterator<BitmapGlyphInfo, BitmapSizeTable::Builder>(container) {
+ sub_table_iter_ = container->IndexSubTableBuilders()->begin();
+ sub_table_glyph_info_iter_.Attach((*sub_table_iter_)->GetIterator());
+}
+
+bool BitmapSizeTable::Builder::BitmapGlyphInfoIterator::HasNext() {
+ if (sub_table_glyph_info_iter_ && HasNext(sub_table_glyph_info_iter_)) {
+ return true;
+ }
+ while (++sub_table_iter_ != container()->IndexSubTableBuilders()->end()) {
+ sub_table_glyph_info_iter_.Attach((*sub_table_iter_)->GetIterator());
+ if (HasNext(sub_table_glyph_info_iter_)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+CALLER_ATTACH
+BitmapGlyphInfo* BitmapSizeTable::Builder::BitmapGlyphInfoIterator::Next() {
+ if (!HasNext()) {
+ // Note: In C++, we do not throw exception when there's no element.
+ return NULL;
+ }
+ return Next(sub_table_glyph_info_iter_);
+}
+
+bool BitmapSizeTable::Builder::BitmapGlyphInfoIterator::HasNext(
+ BitmapGlyphInfoIter* iterator_base) {
+ if (iterator_base) {
+ switch (iterator_base->container_base()->index_format()) {
+ case 1: {
+ IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator* it =
+ down_cast<IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator*>(
+ iterator_base);
+ return it->HasNext();
+ }
+
+ case 2: {
+ IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator* it =
+ down_cast<IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator*>(
+ iterator_base);
+ return it->HasNext();
+ }
+
+ case 3: {
+ IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator* it =
+ down_cast<IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator*>(
+ iterator_base);
+ return it->HasNext();
+ }
+
+ case 4: {
+ IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator* it =
+ down_cast<IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator*>(
+ iterator_base);
+ return it->HasNext();
+ }
+
+ case 5: {
+ IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator* it =
+ down_cast<IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator*>(
+ iterator_base);
+ return it->HasNext();
+ }
+
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
+CALLER_ATTACH
+BitmapGlyphInfo* BitmapSizeTable::Builder::BitmapGlyphInfoIterator::Next(
+ BitmapGlyphInfoIter* iterator_base) {
+ if (iterator_base) {
+ switch (iterator_base->container_base()->index_format()) {
+ case 1: {
+ IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator* it =
+ down_cast<IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator*>(
+ iterator_base);
+ return it->Next();
+ }
+
+ case 2: {
+ IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator* it =
+ down_cast<IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator*>(
+ iterator_base);
+ return it->Next();
+ }
+
+ case 3: {
+ IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator* it =
+ down_cast<IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator*>(
+ iterator_base);
+ return it->Next();
+ }
+
+ case 4: {
+ IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator* it =
+ down_cast<IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator*>(
+ iterator_base);
+ return it->Next();
+ }
+
+ case 5: {
+ IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator* it =
+ down_cast<IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator*>(
+ iterator_base);
+ return it->Next();
+ }
+
+ default:
+ break;
+ }
+ }
+ return NULL;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_size_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_size_table.h
new file mode 100644
index 00000000000..6733e203042
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/bitmap_size_table.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 = the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_SIZE_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_SIZE_TABLE_H_
+
+#include "sfntly/port/lock.h"
+#include "sfntly/table/bitmap/bitmap_glyph_info.h"
+#include "sfntly/table/bitmap/index_sub_table.h"
+
+namespace sfntly {
+// Binary search would be faster but many fonts have index subtables that
+// aren't sorted.
+// Note: preprocessor define is used to avoid const expression warnings in C++
+// code.
+#define SFNTLY_BITMAPSIZE_USE_BINARY_SEARCH 0
+
+class BitmapSizeTable : public SubTable,
+ public RefCounted<BitmapSizeTable> {
+ public:
+ class Builder : public SubTable::Builder,
+ public RefCounted<Builder> {
+ public:
+ class BitmapGlyphInfoIterator :
+ public RefIterator<BitmapGlyphInfo, Builder> {
+ public:
+ explicit BitmapGlyphInfoIterator(Builder* container);
+ virtual ~BitmapGlyphInfoIterator() {}
+
+ virtual bool HasNext();
+ CALLER_ATTACH virtual BitmapGlyphInfo* Next();
+
+ private:
+ bool HasNext(BitmapGlyphInfoIter* iterator_base);
+ CALLER_ATTACH BitmapGlyphInfo* Next(BitmapGlyphInfoIter* iterator_base);
+
+ IndexSubTableBuilderList::iterator sub_table_iter_;
+ BitmapGlyphInfoIterPtr sub_table_glyph_info_iter_;
+ };
+
+ virtual ~Builder();
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
+ ReadableFontData* master_data);
+ static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
+ ReadableFontData* master_data);
+ // Gets the subtable array offset as set in the original table as read from
+ // the font file. This value cannot be explicitly set and will be generated
+ // during table building.
+ // @return the subtable array offset
+ int32_t IndexSubTableArrayOffset();
+
+ // Sets the subtable array offset. This is used only during the building
+ // process when the objects are being serialized.
+ // @param offset the offset to the index subtable array
+ void SetIndexSubTableArrayOffset(int32_t offset);
+
+ // Gets the subtable array size as set in the original table as read from
+ // the font file. This value cannot be explicitly set and will be generated
+ // during table building.
+ // @return the subtable array size
+ int32_t IndexTableSize();
+
+ // Sets the subtable size. This is used only during the building process
+ // when the objects are being serialized.
+ // @param size the offset to the index subtable array
+ void SetIndexTableSize(int32_t size);
+
+ int32_t NumberOfIndexSubTables();
+ int32_t ColorRef();
+ // TODO(stuartg): SBitLineMetrics hori();
+ // TODO(stuartg): SBitLineMetrics vert();
+ int32_t StartGlyphIndex();
+ int32_t EndGlyphIndex();
+ int32_t PpemX();
+ int32_t PpemY();
+ int32_t BitDepth();
+ int32_t FlagsAsInt();
+
+ IndexSubTable::Builder* IndexSubTableBuilder(int32_t index);
+ CALLER_ATTACH BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
+ int32_t GlyphOffset(int32_t glyph_id);
+ int32_t GlyphLength(int32_t glyph_id);
+ int32_t GlyphFormat(int32_t glyph_id);
+ IndexSubTableBuilderList* IndexSubTableBuilders();
+ // Note: renamed from iterator(), type is the derived type.
+ CALLER_ATTACH BitmapGlyphInfoIterator* GetIterator();
+ void GenerateLocaMap(BitmapGlyphInfoMap* output);
+
+ protected:
+ void Revert();
+
+ private:
+ Builder(WritableFontData* data, ReadableFontData* master_data);
+ Builder(ReadableFontData* data, ReadableFontData* master_data);
+
+ void SetNumberOfIndexSubTables(int32_t count);
+ IndexSubTable::Builder* SearchIndexSubTables(int32_t glyph_id);
+ IndexSubTable::Builder* LinearSearchIndexSubTables(int32_t glyph_id);
+ IndexSubTable::Builder* BinarySearchIndexSubTables(int32_t glyph_id);
+ IndexSubTableBuilderList* GetIndexSubTableBuilders();
+ void Initialize(ReadableFontData* data);
+ CALLER_ATTACH IndexSubTable::Builder* CreateIndexSubTableBuilder(
+ int32_t index);
+
+ IndexSubTableBuilderList index_sub_tables_;
+ };
+
+ virtual ~BitmapSizeTable();
+
+ int32_t IndexSubTableArrayOffset();
+ int32_t IndexTableSize();
+ int32_t NumberOfIndexSubTables();
+ int32_t ColorRef();
+ // TODO(stuartg): SBitLineMetrics hori();
+ // TODO(stuartg): SBitLineMetrics vert();
+ int32_t StartGlyphIndex();
+ int32_t EndGlyphIndex();
+ int32_t PpemX();
+ int32_t PpemY();
+ int32_t BitDepth();
+ int32_t FlagsAsInt();
+
+ // Note: renamed from indexSubTable()
+ IndexSubTable* GetIndexSubTable(int32_t index);
+ int32_t GlyphOffset(int32_t glyph_id);
+ int32_t GlyphLength(int32_t glyph_id);
+ CALLER_ATTACH BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
+ int32_t GlyphFormat(int32_t glyph_id);
+
+ protected:
+ BitmapSizeTable(ReadableFontData* data,
+ ReadableFontData* master_data);
+
+ private:
+ static int32_t NumberOfIndexSubTables(ReadableFontData* data,
+ int32_t table_offset);
+ IndexSubTable* SearchIndexSubTables(int32_t glyph_id);
+ IndexSubTable* LinearSearchIndexSubTables(int32_t glyph_id);
+ IndexSubTable* BinarySearchIndexSubTables(int32_t glyph_id);
+ CALLER_ATTACH IndexSubTable* CreateIndexSubTable(int32_t index);
+ IndexSubTableList* GetIndexSubTableList();
+
+ Lock index_subtables_lock_;
+ IndexSubTableList index_subtables_;
+};
+typedef Ptr<BitmapSizeTable> BitmapSizeTablePtr;
+typedef std::vector<BitmapSizeTablePtr> BitmapSizeTableList;
+typedef Ptr<BitmapSizeTable::Builder> BitmapSizeTableBuilderPtr;
+typedef std::vector<BitmapSizeTableBuilderPtr> BitmapSizeTableBuilderList;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_BITMAP_SIZE_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/composite_bitmap_glyph.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/composite_bitmap_glyph.cc
new file mode 100644
index 00000000000..ae7dc5a7313
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/composite_bitmap_glyph.cc
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 = the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/composite_bitmap_glyph.h"
+
+namespace sfntly {
+/******************************************************************************
+ * CompositeBitmapGlyph class
+ ******************************************************************************/
+CompositeBitmapGlyph::CompositeBitmapGlyph(ReadableFontData* data,
+ int32_t format)
+ : BitmapGlyph(data, format) {
+ Initialize(format);
+}
+
+CompositeBitmapGlyph::~CompositeBitmapGlyph() {
+}
+
+int32_t CompositeBitmapGlyph::NumComponents() {
+ return data_->ReadUShort(num_components_offset_);
+}
+
+CompositeBitmapGlyph::Component CompositeBitmapGlyph::GetComponent(
+ int32_t component_num) const {
+ int32_t component_offset = component_array_offset_ +
+ component_num * Offset::kEbdtComponentLength;
+ return CompositeBitmapGlyph::Component(
+ data_->ReadUShort(component_offset + Offset::kEbdtComponent_glyphCode),
+ data_->ReadChar(component_offset + Offset::kEbdtComponent_xOffset),
+ data_->ReadChar(component_offset + Offset::kEbdtComponent_yOffset));
+}
+
+void CompositeBitmapGlyph::Initialize(int32_t format) {
+ if (format == 8) {
+ num_components_offset_ = Offset::kGlyphFormat8_numComponents;
+ component_array_offset_ = Offset::kGlyphFormat8_componentArray;
+ } else if (format == 9) {
+ num_components_offset_ = Offset::kGlyphFormat9_numComponents;
+ component_array_offset_ = Offset::kGlyphFormat9_componentArray;
+ } else {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IllegalStateException("Attempt to create a Composite Bitmap Glyph "
+ "with a non-composite format.");
+#endif
+ }
+}
+
+/******************************************************************************
+ * CompositeBitmapGlyph::Component class
+ ******************************************************************************/
+CompositeBitmapGlyph::Component::Component(const Component& rhs)
+ : glyph_code_(rhs.glyph_code_),
+ x_offset_(rhs.x_offset_),
+ y_offset_(rhs.y_offset_) {
+}
+
+bool CompositeBitmapGlyph::Component::operator==(
+ const CompositeBitmapGlyph::Component& rhs) {
+ return glyph_code_ == rhs.glyph_code_;
+}
+
+CompositeBitmapGlyph::Component& CompositeBitmapGlyph::Component::operator=(
+ const CompositeBitmapGlyph::Component& rhs) {
+ glyph_code_ = rhs.glyph_code_;
+ x_offset_ = rhs.x_offset_;
+ y_offset_ = rhs.y_offset_;
+ return *this;
+}
+
+CompositeBitmapGlyph::Component::Component(int32_t glyph_code,
+ int32_t x_offset,
+ int32_t y_offset)
+ : glyph_code_(glyph_code), x_offset_(x_offset), y_offset_(y_offset) {
+}
+
+/******************************************************************************
+ * CompositeBitmapGlyph::Builder class
+ ******************************************************************************/
+CompositeBitmapGlyph::Builder::Builder(ReadableFontData* data, int32_t format)
+ : BitmapGlyph::Builder(data, format) {
+}
+
+CompositeBitmapGlyph::Builder::Builder(WritableFontData* data, int32_t format)
+ : BitmapGlyph::Builder(data, format) {
+}
+
+CompositeBitmapGlyph::Builder::~Builder() {
+}
+
+CALLER_ATTACH FontDataTable*
+CompositeBitmapGlyph::Builder::SubBuildTable(ReadableFontData* data) {
+ Ptr<CompositeBitmapGlyph> glyph = new CompositeBitmapGlyph(data, format());
+ return glyph.Detach();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/composite_bitmap_glyph.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/composite_bitmap_glyph.h
new file mode 100644
index 00000000000..897db7e22a7
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/composite_bitmap_glyph.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 = the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_COMPOSITE_BITMAP_GLYPH_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_COMPOSITE_BITMAP_GLYPH_H_
+
+#include "sfntly/table/bitmap/bitmap_glyph.h"
+
+namespace sfntly {
+
+class CompositeBitmapGlyph : public BitmapGlyph,
+ public RefCounted<CompositeBitmapGlyph> {
+ public:
+ class Component {
+ public:
+ Component(const Component& rhs);
+
+ int32_t glyph_code() { return glyph_code_; }
+ int32_t x_offset() { return x_offset_; }
+ int32_t y_offset() { return y_offset_; }
+
+ // UNIMPLEMENTED: int hashCode()
+ bool operator==(const Component& rhs);
+ Component& operator=(const Component& rhs);
+
+ protected:
+ Component(int32_t glyph_code, int32_t x_offset, int32_t y_offset);
+
+ private:
+ int32_t glyph_code_;
+ int32_t x_offset_;
+ int32_t y_offset_;
+
+ friend class CompositeBitmapGlyph;
+ };
+
+ class Builder : public BitmapGlyph::Builder,
+ public RefCounted<Builder> {
+ public:
+ Builder(WritableFontData* data, int32_t format);
+ Builder(ReadableFontData* data, int32_t format);
+ virtual ~Builder();
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ };
+
+ CompositeBitmapGlyph(ReadableFontData* data, int32_t format);
+ virtual ~CompositeBitmapGlyph();
+ int32_t NumComponents();
+ // Note: returned immutable object over stack.
+ Component GetComponent(int32_t component_num) const;
+
+ private:
+ void Initialize(int32_t format);
+
+ int32_t num_components_offset_;
+ int32_t component_array_offset_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_COMPOSITE_BITMAP_GLYPH_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebdt_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebdt_table.cc
new file mode 100644
index 00000000000..eeb1fa06b38
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebdt_table.cc
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/ebdt_table.h"
+
+#include <stdlib.h>
+
+#include "sfntly/table/bitmap/composite_bitmap_glyph.h"
+#include "sfntly/table/bitmap/simple_bitmap_glyph.h"
+
+namespace sfntly {
+/******************************************************************************
+ * EbdtTable class
+ ******************************************************************************/
+EbdtTable::~EbdtTable() {
+}
+
+int32_t EbdtTable::Version() {
+ return data_->ReadFixed(Offset::kVersion);
+}
+
+CALLER_ATTACH
+BitmapGlyph* EbdtTable::Glyph(int32_t offset, int32_t length, int32_t format) {
+ ReadableFontDataPtr glyph_data;
+ glyph_data.Attach(down_cast<ReadableFontData*>(data_->Slice(offset, length)));
+ return BitmapGlyph::CreateGlyph(glyph_data, format);
+}
+
+EbdtTable::EbdtTable(Header* header, ReadableFontData* data)
+ : SubTableContainerTable(header, data) {
+}
+
+/******************************************************************************
+ * EbdtTable::Builder class
+ ******************************************************************************/
+EbdtTable::Builder::Builder(Header* header, WritableFontData* data)
+ : SubTableContainerTable::Builder(header, data) {
+}
+
+EbdtTable::Builder::Builder(Header* header, ReadableFontData* data)
+ : SubTableContainerTable::Builder(header, data) {
+}
+
+EbdtTable::Builder::~Builder() {
+}
+
+CALLER_ATTACH FontDataTable*
+ EbdtTable::Builder::SubBuildTable(ReadableFontData* data) {
+ FontDataTablePtr table = new EbdtTable(header(), data);
+ return table.Detach();
+}
+
+void EbdtTable::Builder::SubDataSet() {
+ Revert();
+}
+
+int32_t EbdtTable::Builder::SubDataSizeToSerialize() {
+ if (glyph_builders_.empty()) {
+ return 0;
+ }
+ bool fixed = true;
+ int32_t size = Offset::kHeaderLength;
+ for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
+ builder_end = glyph_builders_.end();
+ builder_map != builder_end;
+ builder_map++) {
+ for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
+ glyph_entry_end = builder_map->end();
+ glyph_entry != glyph_entry_end;
+ glyph_entry++) {
+ int32_t glyph_size = glyph_entry->second->SubDataSizeToSerialize();
+ size += abs(glyph_size);
+ fixed = (glyph_size <= 0) ? false : fixed;
+ }
+ }
+ return (fixed ? 1 : -1) * size;
+}
+
+bool EbdtTable::Builder::SubReadyToSerialize() {
+ if (glyph_builders_.empty()) {
+ return false;
+ }
+ return true;
+}
+
+int32_t EbdtTable::Builder::SubSerialize(WritableFontData* new_data) {
+ int32_t size = 0;
+ size += new_data->WriteFixed(Offset::kVersion, kVersion);
+ for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
+ builder_end = glyph_builders_.end();
+ builder_map != builder_end;
+ builder_map++) {
+ for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
+ glyph_entry_end = builder_map->end();
+ glyph_entry != glyph_entry_end;
+ glyph_entry++) {
+ WritableFontDataPtr slice;
+ slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
+ size += glyph_entry->second->SubSerialize(slice);
+ }
+ }
+ return size;
+}
+
+void EbdtTable::Builder::SetLoca(BitmapLocaList* loca_list) {
+ assert(loca_list);
+ Revert();
+ glyph_loca_.resize(loca_list->size());
+ std::copy(loca_list->begin(), loca_list->end(), glyph_loca_.begin());
+}
+
+void EbdtTable::Builder::GenerateLocaList(BitmapLocaList* output) {
+ assert(output);
+ output->clear();
+
+ if (glyph_builders_.empty()) {
+ if (glyph_loca_.empty()) {
+ return;
+ }
+ }
+
+ int start_offset = Offset::kHeaderLength;
+ for (BitmapGlyphBuilderList::iterator builder_map = glyph_builders_.begin(),
+ builder_end = glyph_builders_.end();
+ builder_map != builder_end;
+ builder_map++) {
+ BitmapGlyphInfoMap new_loca_map;
+ int32_t glyph_offset = 0;
+ for (BitmapGlyphBuilderMap::iterator glyph_entry = builder_map->begin(),
+ glyph_end = builder_map->end();
+ glyph_entry != glyph_end;
+ glyph_entry++) {
+ BitmapGlyphBuilderPtr builder = glyph_entry->second;
+ int32_t size = builder->SubDataSizeToSerialize();
+ BitmapGlyphInfoPtr info = new BitmapGlyphInfo(glyph_entry->first,
+ start_offset + glyph_offset, size, builder->format());
+ new_loca_map[glyph_entry->first] = info;
+ glyph_offset += size;
+ }
+ start_offset += glyph_offset;
+ output->push_back(new_loca_map);
+ }
+}
+
+BitmapGlyphBuilderList* EbdtTable::Builder::GlyphBuilders() {
+ return GetGlyphBuilders();
+}
+
+void EbdtTable::Builder::SetGlyphBuilders(
+ BitmapGlyphBuilderList* glyph_builders) {
+ glyph_builders_.clear();
+ std::copy(glyph_builders->begin(), glyph_builders->end(),
+ glyph_builders_.begin());
+ set_model_changed();
+}
+
+void EbdtTable::Builder::Revert() {
+ glyph_loca_.clear();
+ glyph_builders_.clear();
+ set_model_changed(false);
+}
+
+CALLER_ATTACH
+EbdtTable::Builder* EbdtTable::Builder::CreateBuilder(Header* header,
+ WritableFontData* data) {
+ Ptr<EbdtTable::Builder> builder;
+ builder = new Builder(header, data);
+ return builder.Detach();
+}
+
+CALLER_ATTACH
+EbdtTable::Builder* EbdtTable::Builder::CreateBuilder(Header* header,
+ ReadableFontData* data) {
+ Ptr<EbdtTable::Builder> builder;
+ builder = new Builder(header, data);
+ return builder.Detach();
+}
+
+BitmapGlyphBuilderList* EbdtTable::Builder::GetGlyphBuilders() {
+ if (glyph_builders_.empty()) {
+ if (glyph_loca_.empty()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IllegalStateException(
+ "Loca values not set - unable to parse glyph data.");
+#endif
+ return NULL;
+ }
+ Initialize(InternalReadData(), &glyph_loca_, &glyph_builders_);
+ set_model_changed();
+ }
+ return &glyph_builders_;
+}
+
+void EbdtTable::Builder::Initialize(ReadableFontData* data,
+ BitmapLocaList* loca_list,
+ BitmapGlyphBuilderList* output) {
+ assert(loca_list);
+ assert(output);
+
+ output->clear();
+ if (data) {
+ for (BitmapLocaList::iterator loca_map = loca_list->begin(),
+ loca_end = loca_list->end();
+ loca_map != loca_end; loca_map++) {
+ BitmapGlyphBuilderMap glyph_builder_map;
+ for (BitmapGlyphInfoMap::iterator entry = loca_map->begin(),
+ entry_end = loca_map->end();
+ entry != entry_end; entry++) {
+ BitmapGlyphInfoPtr info = entry->second;
+ ReadableFontDataPtr slice;
+ slice.Attach(down_cast<ReadableFontData*>(data->Slice(
+ info->offset(), info->length())));
+ BitmapGlyphBuilderPtr glyph_builder;
+ glyph_builder.Attach(BitmapGlyph::Builder::CreateGlyphBuilder(
+ slice, info->format()));
+ glyph_builder_map[entry->first] = glyph_builder;
+ }
+ output->push_back(glyph_builder_map);
+ }
+ }
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebdt_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebdt_table.h
new file mode 100644
index 00000000000..d138c14ca53
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebdt_table.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBDT_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBDT_TABLE_H_
+
+#include "sfntly/table/bitmap/bitmap_glyph.h"
+#include "sfntly/table/bitmap/bitmap_glyph_info.h"
+#include "sfntly/table/subtable_container_table.h"
+
+namespace sfntly {
+
+class EbdtTable : public SubTableContainerTable,
+ public RefCounted<EbdtTable> {
+ public:
+ struct Offset {
+ enum {
+ kVersion = 0,
+ kHeaderLength = DataSize::kFixed,
+ };
+ };
+
+ class Builder : public SubTableContainerTable::Builder,
+ public RefCounted<Builder> {
+ public:
+ // Constructor scope altered to public because C++ does not allow base
+ // class to instantiate derived class with protected constructors.
+ Builder(Header* header, WritableFontData* data);
+ Builder(Header* header, ReadableFontData* data);
+ virtual ~Builder();
+
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual void SubDataSet();
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+ void SetLoca(BitmapLocaList* loca_list);
+ void GenerateLocaList(BitmapLocaList* output);
+
+ // Gets the List of glyph builders for the glyph table builder. These may be
+ // manipulated in any way by the caller and the changes will be reflected in
+ // the final glyph table produced.
+ // If there is no current data for the glyph builder or the glyph builders
+ // have not been previously set then this will return an empty glyph builder
+ // List. If there is current data (i.e. data read from an existing font) and
+ // the loca list has not been set or is null, empty, or invalid, then an
+ // empty glyph builder List will be returned.
+ // @return the list of glyph builders
+ BitmapGlyphBuilderList* GlyphBuilders();
+
+ // Replace the internal glyph builders with the one provided. The provided
+ // list and all contained objects belong to this builder.
+ // This call is only required if the entire set of glyphs in the glyph
+ // table builder are being replaced. If the glyph builder list provided from
+ // the {@link EbdtTable.Builder#glyphBuilders()} is being used and modified
+ // then those changes will already be reflected in the glyph table builder.
+ // @param glyphBuilders the new glyph builders
+ void SetGlyphBuilders(BitmapGlyphBuilderList* glyph_builders);
+
+ void Revert();
+
+ // Create a new builder using the header information and data provided.
+ // @param header the header information
+ // @param data the data holding the table
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ WritableFontData* data);
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ ReadableFontData* data);
+
+ private:
+ BitmapGlyphBuilderList* GetGlyphBuilders();
+ static void Initialize(ReadableFontData* data,
+ BitmapLocaList* loca_list,
+ BitmapGlyphBuilderList* output);
+
+ static const int32_t kVersion = 0x00020000; // TODO(stuartg): const/enum
+ BitmapLocaList glyph_loca_;
+ BitmapGlyphBuilderList glyph_builders_;
+ };
+
+ virtual ~EbdtTable();
+ int32_t Version();
+ CALLER_ATTACH BitmapGlyph* Glyph(int32_t offset,
+ int32_t length,
+ int32_t format);
+ protected:
+ EbdtTable(Header* header, ReadableFontData* data);
+};
+typedef Ptr<EbdtTable> EbdtTablePtr;
+typedef Ptr<EbdtTable::Builder> EbdtTableBuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBDT_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/eblc_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/eblc_table.cc
new file mode 100644
index 00000000000..0ad2764bf6e
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/eblc_table.cc
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sfntly/math/font_math.h"
+
+namespace sfntly {
+/******************************************************************************
+ * EblcTable class
+ ******************************************************************************/
+int32_t EblcTable::Version() {
+ return data_->ReadFixed(Offset::kVersion);
+}
+
+int32_t EblcTable::NumSizes() {
+ return data_->ReadULongAsInt(Offset::kNumSizes);
+}
+
+BitmapSizeTable* EblcTable::GetBitmapSizeTable(int32_t index) {
+ if (index < 0 || index > NumSizes()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundException(
+ "Size table index is outside the range of tables.");
+#endif
+ return NULL;
+ }
+ BitmapSizeTableList* bitmap_size_table_list = GetBitmapSizeTableList();
+ if (bitmap_size_table_list) {
+ return (*bitmap_size_table_list)[index];
+ }
+ return NULL;
+}
+
+EblcTable::EblcTable(Header* header, ReadableFontData* data)
+ : SubTableContainerTable(header, data) {
+}
+
+BitmapSizeTableList* EblcTable::GetBitmapSizeTableList() {
+ AutoLock lock(bitmap_size_table_lock_);
+ if (bitmap_size_table_.empty()) {
+ CreateBitmapSizeTable(data_, NumSizes(), &bitmap_size_table_);
+ }
+ return &bitmap_size_table_;
+}
+
+// static
+void EblcTable::CreateBitmapSizeTable(ReadableFontData* data,
+ int32_t num_sizes,
+ BitmapSizeTableList* output) {
+ assert(data);
+ assert(output);
+ for (int32_t i = 0; i < num_sizes; ++i) {
+ ReadableFontDataPtr new_data;
+ new_data.Attach(down_cast<ReadableFontData*>(
+ data->Slice(Offset::kBitmapSizeTableArrayStart +
+ i * Offset::kBitmapSizeTableLength,
+ Offset::kBitmapSizeTableLength)));
+ BitmapSizeTableBuilderPtr size_builder;
+ size_builder.Attach(
+ BitmapSizeTable::Builder::CreateBuilder(new_data, data));
+ BitmapSizeTablePtr size;
+ size.Attach(down_cast<BitmapSizeTable*>(size_builder->Build()));
+ output->push_back(size);
+ }
+}
+
+/******************************************************************************
+ * EblcTable::Builder class
+ ******************************************************************************/
+EblcTable::Builder::Builder(Header* header, WritableFontData* data)
+ : SubTableContainerTable::Builder(header, data) {
+}
+
+EblcTable::Builder::Builder(Header* header, ReadableFontData* data)
+ : SubTableContainerTable::Builder(header, data) {
+}
+
+EblcTable::Builder::~Builder() {
+}
+
+int32_t EblcTable::Builder::SubSerialize(WritableFontData* new_data) {
+ // header
+ int32_t size = new_data->WriteFixed(0, kVersion);
+ size += new_data->WriteULong(size, size_table_builders_.size());
+
+ // calculate the offsets
+ // offset to the start of the size table array
+ int32_t size_table_start_offset = size;
+ // walking offset in the size table array
+ int32_t size_table_offset = size_table_start_offset;
+ // offset to the start of the whole index subtable block
+ int32_t sub_table_block_start_offset = size_table_offset +
+ size_table_builders_.size() * Offset::kBitmapSizeTableLength;
+ // walking offset in the index subtable
+ // points to the start of the current subtable block
+ int32_t current_sub_table_block_start_offset = sub_table_block_start_offset;
+
+#if defined (SFNTLY_DEBUG_BITMAP)
+ int32_t size_index = 0;
+#endif
+ for (BitmapSizeTableBuilderList::iterator
+ size_builder = size_table_builders_.begin(),
+ size_builder_end = size_table_builders_.end();
+ size_builder != size_builder_end; size_builder++) {
+ (*size_builder)->SetIndexSubTableArrayOffset(
+ current_sub_table_block_start_offset);
+ IndexSubTableBuilderList* index_sub_table_builder_list =
+ (*size_builder)->IndexSubTableBuilders();
+
+ // walking offset within the current subTable array
+ int32_t index_sub_table_array_offset = current_sub_table_block_start_offset;
+ // walking offset within the subTable entries
+ int32_t index_sub_table_offset = index_sub_table_array_offset +
+ index_sub_table_builder_list->size() * Offset::kIndexSubHeaderLength;
+
+#if defined (SFNTLY_DEBUG_BITMAP)
+ fprintf(stderr, "size %d: sizeTable=%x, current subTable Block=%x, ",
+ size_index, size_table_offset,
+ current_sub_table_block_start_offset);
+ fprintf(stderr, "index subTableStart=%x\n", index_sub_table_offset);
+ size_index++;
+ int32_t sub_table_index = 0;
+#endif
+ for (IndexSubTableBuilderList::iterator
+ index_sub_table_builder = index_sub_table_builder_list->begin(),
+ index_sub_table_builder_end = index_sub_table_builder_list->end();
+ index_sub_table_builder != index_sub_table_builder_end;
+ index_sub_table_builder++) {
+#if defined (SFNTLY_DEBUG_BITMAP)
+ fprintf(stderr, "\tsubTableIndex %d: format=%x, ", sub_table_index,
+ (*index_sub_table_builder)->index_format());
+ fprintf(stderr, "indexSubTableArrayOffset=%x, indexSubTableOffset=%x\n",
+ index_sub_table_array_offset, index_sub_table_offset);
+ sub_table_index++;
+#endif
+ // array entry
+ index_sub_table_array_offset += new_data->WriteUShort(
+ index_sub_table_array_offset,
+ (*index_sub_table_builder)->first_glyph_index());
+ index_sub_table_array_offset += new_data->WriteUShort(
+ index_sub_table_array_offset,
+ (*index_sub_table_builder)->last_glyph_index());
+ index_sub_table_array_offset += new_data->WriteULong(
+ index_sub_table_array_offset,
+ index_sub_table_offset - current_sub_table_block_start_offset);
+
+ // index sub table
+ WritableFontDataPtr slice_index_sub_table;
+ slice_index_sub_table.Attach(down_cast<WritableFontData*>(
+ new_data->Slice(index_sub_table_offset)));
+ int32_t current_sub_table_size =
+ (*index_sub_table_builder)->SubSerialize(slice_index_sub_table);
+ int32_t padding = FontMath::PaddingRequired(current_sub_table_size,
+ DataSize::kULONG);
+#if defined (SFNTLY_DEBUG_BITMAP)
+ fprintf(stderr, "\t\tsubTableSize = %x, padding = %x\n",
+ current_sub_table_size, padding);
+#endif
+ index_sub_table_offset += current_sub_table_size;
+ index_sub_table_offset +=
+ new_data->WritePadding(index_sub_table_offset, padding);
+ }
+
+ // serialize size table
+ (*size_builder)->SetIndexTableSize(
+ index_sub_table_offset - current_sub_table_block_start_offset);
+ WritableFontDataPtr slice_size_table;
+ slice_size_table.Attach(down_cast<WritableFontData*>(
+ new_data->Slice(size_table_offset)));
+ size_table_offset += (*size_builder)->SubSerialize(slice_size_table);
+
+ current_sub_table_block_start_offset = index_sub_table_offset;
+ }
+ return size + current_sub_table_block_start_offset;
+}
+
+bool EblcTable::Builder::SubReadyToSerialize() {
+ if (size_table_builders_.empty()) {
+ return false;
+ }
+ for (BitmapSizeTableBuilderList::iterator b = size_table_builders_.begin(),
+ e = size_table_builders_.end();
+ b != e; b++) {
+ if (!(*b)->SubReadyToSerialize()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+int32_t EblcTable::Builder::SubDataSizeToSerialize() {
+ if (size_table_builders_.empty()) {
+ return 0;
+ }
+ int32_t size = Offset::kHeaderLength;
+ bool variable = false;
+#if defined (SFNTLY_DEBUG_BITMAP)
+ size_t size_index = 0;
+#endif
+ for (BitmapSizeTableBuilderList::iterator b = size_table_builders_.begin(),
+ e = size_table_builders_.end();
+ b != e; b++) {
+ int32_t size_builder_size = (*b)->SubDataSizeToSerialize();
+#if defined (SFNTLY_DEBUG_BITMAP)
+ fprintf(stderr, "sizeIndex = %d, sizeBuilderSize=0x%x (%d)\n",
+ size_index++, size_builder_size, size_builder_size);
+#endif
+ variable = size_builder_size > 0 ? variable : true;
+ size += abs(size_builder_size);
+ }
+#if defined (SFNTLY_DEBUG_BITMAP)
+ fprintf(stderr, "eblc size=%d\n", size);
+#endif
+ return variable ? -size : size;
+}
+
+void EblcTable::Builder::SubDataSet() {
+ Revert();
+}
+
+BitmapSizeTableBuilderList* EblcTable::Builder::BitmapSizeBuilders() {
+ return GetSizeList();
+}
+
+void EblcTable::Builder::Revert() {
+ size_table_builders_.clear();
+ set_model_changed(false);
+}
+
+void EblcTable::Builder::GenerateLocaList(BitmapLocaList* output) {
+ assert(output);
+ BitmapSizeTableBuilderList* size_builder_list = GetSizeList();
+ output->clear();
+#if defined (SFNTLY_DEBUG_BITMAP)
+ int32_t size_index = 0;
+#endif
+ for (BitmapSizeTableBuilderList::iterator b = size_builder_list->begin(),
+ e = size_builder_list->end();
+ b != e; b++) {
+#if defined (SFNTLY_DEBUG_BITMAP)
+ fprintf(stderr, "size table = %d\n", size_index++);
+#endif
+ BitmapGlyphInfoMap loca_map;
+ (*b)->GenerateLocaMap(&loca_map);
+ output->push_back(loca_map);
+ }
+}
+
+CALLER_ATTACH
+FontDataTable* EblcTable::Builder::SubBuildTable(ReadableFontData* data) {
+ Ptr<EblcTable> new_table = new EblcTable(header(), data);
+ return new_table.Detach();
+}
+
+// static
+CALLER_ATTACH EblcTable::Builder*
+ EblcTable::Builder::CreateBuilder(Header* header, WritableFontData* data) {
+ Ptr<EblcTable::Builder> new_builder = new EblcTable::Builder(header, data);
+ return new_builder.Detach();
+}
+
+// static
+CALLER_ATTACH EblcTable::Builder*
+ EblcTable::Builder::CreateBuilder(Header* header, ReadableFontData* data) {
+ Ptr<EblcTable::Builder> new_builder = new EblcTable::Builder(header, data);
+ return new_builder.Detach();
+}
+
+BitmapSizeTableBuilderList* EblcTable::Builder::GetSizeList() {
+ if (size_table_builders_.empty()) {
+ Initialize(InternalReadData(), &size_table_builders_);
+ set_model_changed();
+ }
+ return &size_table_builders_;
+}
+
+void EblcTable::Builder::Initialize(ReadableFontData* data,
+ BitmapSizeTableBuilderList* output) {
+ assert(output);
+ if (data) {
+ int32_t num_sizes = data->ReadULongAsInt(Offset::kNumSizes);
+ for (int32_t i = 0; i < num_sizes; ++i) {
+ ReadableFontDataPtr new_data;
+ new_data.Attach(down_cast<ReadableFontData*>(
+ data->Slice(Offset::kBitmapSizeTableArrayStart +
+ i * Offset::kBitmapSizeTableLength,
+ Offset::kBitmapSizeTableLength)));
+ BitmapSizeTableBuilderPtr size_builder;
+ size_builder.Attach(BitmapSizeTable::Builder::CreateBuilder(
+ new_data, data));
+ output->push_back(size_builder);
+ }
+ }
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/eblc_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/eblc_table.h
new file mode 100644
index 00000000000..b04338a93b1
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/eblc_table.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBLC_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBLC_TABLE_H_
+
+#include "sfntly/port/lock.h"
+#include "sfntly/table/bitmap/big_glyph_metrics.h"
+#include "sfntly/table/bitmap/bitmap_glyph.h"
+#include "sfntly/table/bitmap/bitmap_size_table.h"
+#include "sfntly/table/subtable_container_table.h"
+
+namespace sfntly {
+
+class EblcTable : public SubTableContainerTable,
+ public RefCounted<EblcTable> {
+ public:
+ struct Offset {
+ enum {
+ // header
+ kVersion = 0,
+ kNumSizes = 4,
+ kHeaderLength = kNumSizes + DataSize::kULONG,
+
+ // bitmapSizeTable
+ kBitmapSizeTableArrayStart = kHeaderLength,
+ kBitmapSizeTableLength = 48,
+ kBitmapSizeTable_indexSubTableArrayOffset = 0,
+ kBitmapSizeTable_indexTableSize = 4,
+ kBitmapSizeTable_numberOfIndexSubTables = 8,
+ kBitmapSizeTable_colorRef = 12,
+ kBitmapSizeTable_hori = 16,
+ kBitmapSizeTable_vert = 28,
+ kBitmapSizeTable_startGlyphIndex = 40,
+ kBitmapSizeTable_endGlyphIndex = 42,
+ kBitmapSizeTable_ppemX = 44,
+ kBitmapSizeTable_ppemY = 45,
+ kBitmapSizeTable_bitDepth = 46,
+ kBitmapSizeTable_flags = 47,
+
+ // sbitLineMetrics
+ kSbitLineMetricsLength = 12,
+ kSbitLineMetrics_ascender = 0,
+ kSbitLineMetrics_descender = 1,
+ kSbitLineMetrics_widthMax = 2,
+ kSbitLineMetrics_caretSlopeNumerator = 3,
+ kSbitLineMetrics_caretSlopeDenominator = 4,
+ kSbitLineMetrics_caretOffset = 5,
+ kSbitLineMetrics_minOriginSB = 6,
+ kSbitLineMetrics_minAdvanceSB = 7,
+ kSbitLineMetrics_maxBeforeBL = 8,
+ kSbitLineMetrics_minAfterBL = 9,
+ kSbitLineMetrics_pad1 = 10,
+ kSbitLineMetrics_pad2 = 11,
+
+ // indexSubTable
+ kIndexSubTableEntryLength = 8,
+ kIndexSubTableEntry_firstGlyphIndex = 0,
+ kIndexSubTableEntry_lastGlyphIndex = 2,
+ kIndexSubTableEntry_additionalOffsetToIndexSubTable = 4,
+
+ // indexSubHeader
+ kIndexSubHeaderLength = 8,
+ kIndexSubHeader_indexFormat = 0,
+ kIndexSubHeader_imageFormat = 2,
+ kIndexSubHeader_imageDataOffset = 4,
+
+ // indexSubTable - all offset relative to the subtable start
+
+ // indexSubTable1
+ kIndexSubTable1_offsetArray = kIndexSubHeaderLength,
+ kIndexSubTable1_builderDataSize = kIndexSubHeaderLength,
+
+ // kIndexSubTable2
+ kIndexSubTable2Length = kIndexSubHeaderLength +
+ DataSize::kULONG +
+ BitmapGlyph::Offset::kBigGlyphMetricsLength,
+ kIndexSubTable2_imageSize = kIndexSubHeaderLength,
+ kIndexSubTable2_bigGlyphMetrics = kIndexSubTable2_imageSize +
+ DataSize::kULONG,
+ kIndexSubTable2_builderDataSize = kIndexSubTable2_bigGlyphMetrics +
+ BigGlyphMetrics::Offset::kMetricsLength,
+
+ // kIndexSubTable3
+ kIndexSubTable3_offsetArray = kIndexSubHeaderLength,
+ kIndexSubTable3_builderDataSize = kIndexSubTable3_offsetArray,
+
+ // kIndexSubTable4
+ kIndexSubTable4_numGlyphs = kIndexSubHeaderLength,
+ kIndexSubTable4_glyphArray = kIndexSubTable4_numGlyphs +
+ DataSize::kULONG,
+ kIndexSubTable4_codeOffsetPairLength = 2 * DataSize::kUSHORT,
+ kIndexSubTable4_codeOffsetPair_glyphCode = 0,
+ kIndexSubTable4_codeOffsetPair_offset = DataSize::kUSHORT,
+ kIndexSubTable4_builderDataSize = kIndexSubTable4_glyphArray,
+
+ // kIndexSubTable5
+ kIndexSubTable5_imageSize = kIndexSubHeaderLength,
+ kIndexSubTable5_bigGlyphMetrics = kIndexSubTable5_imageSize +
+ DataSize::kULONG,
+ kIndexSubTable5_numGlyphs = kIndexSubTable5_bigGlyphMetrics +
+ BitmapGlyph::Offset::kBigGlyphMetricsLength,
+ kIndexSubTable5_glyphArray = kIndexSubTable5_numGlyphs +
+ DataSize::kULONG,
+ kIndexSubTable5_builderDataSize = kIndexSubTable5_glyphArray,
+
+ // codeOffsetPair
+ kCodeOffsetPairLength = 2 * DataSize::kUSHORT,
+ kCodeOffsetPair_glyphCode = 0,
+ kCodeOffsetPair_offset = DataSize::kUSHORT,
+ };
+ };
+
+ class Builder : public SubTableContainerTable::Builder,
+ public RefCounted<Builder> {
+ public:
+ // Constructor scope altered to public because C++ does not allow base
+ // class to instantiate derived class with protected constructors.
+ Builder(Header* header, WritableFontData* data);
+ Builder(Header* header, ReadableFontData* data);
+ virtual ~Builder();
+
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual void SubDataSet();
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+ BitmapSizeTableBuilderList* BitmapSizeBuilders();
+ void Revert();
+
+ // Generates the loca list for the EBDT table. The list is intended to be
+ // used by the EBDT to allow it to parse the glyph data and generate glyph
+ // objects. After returning from this method the list belongs to the caller.
+ // The list entries are in the same order as the size table builders are at
+ // the time of this call.
+ // @return the list of loca maps with one for each size table builder
+ void GenerateLocaList(BitmapLocaList* output);
+
+ // Create a new builder using the header information and data provided.
+ // @param header the header information
+ // @param data the data holding the table
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ WritableFontData* data);
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ ReadableFontData* data);
+
+ private:
+ BitmapSizeTableBuilderList* GetSizeList();
+ void Initialize(ReadableFontData* data, BitmapSizeTableBuilderList* output);
+
+ static const int32_t kVersion = 0x00020000;
+ BitmapSizeTableBuilderList size_table_builders_;
+ };
+
+ int32_t Version();
+ int32_t NumSizes();
+ // UNIMPLEMENTED: toString()
+
+ BitmapSizeTable* GetBitmapSizeTable(int32_t index);
+
+ static const int32_t NOTDEF = -1;
+
+ protected:
+ EblcTable(Header* header, ReadableFontData* data);
+
+ private:
+ BitmapSizeTableList* GetBitmapSizeTableList();
+
+ static void CreateBitmapSizeTable(ReadableFontData* data,
+ int32_t num_sizes,
+ BitmapSizeTableList* output);
+
+ Lock bitmap_size_table_lock_;
+ BitmapSizeTableList bitmap_size_table_;
+};
+typedef Ptr<EblcTable> EblcTablePtr;
+typedef Ptr<EblcTable::Builder> EblcTableBuilderPtr;
+}
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBLC_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebsc_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebsc_table.cc
new file mode 100644
index 00000000000..458c2d49e83
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebsc_table.cc
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/ebsc_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * EbscTable class
+ ******************************************************************************/
+EbscTable::~EbscTable() {
+}
+
+int32_t EbscTable::Version() {
+ return data_->ReadFixed(Offset::kVersion);
+}
+
+int32_t EbscTable::NumSizes() {
+ return data_->ReadULongAsInt(Offset::kNumSizes);
+}
+
+EbscTable::EbscTable(Header* header, ReadableFontData* data)
+ : Table(header, data) {
+}
+
+/******************************************************************************
+ * EbscTable::BitmapScaleTable class
+ ******************************************************************************/
+EbscTable::BitmapScaleTable::~BitmapScaleTable() {
+}
+
+EbscTable::BitmapScaleTable::BitmapScaleTable(ReadableFontData* data)
+ : SubTable(data) {
+}
+
+int32_t EbscTable::BitmapScaleTable::PpemX() {
+ return data_->ReadByte(Offset::kBitmapScaleTable_ppemX);
+}
+
+int32_t EbscTable::BitmapScaleTable::PpemY() {
+ return data_->ReadByte(Offset::kBitmapScaleTable_ppemY);
+}
+
+int32_t EbscTable::BitmapScaleTable::SubstitutePpemX() {
+ return data_->ReadByte(Offset::kBitmapScaleTable_substitutePpemX);
+}
+
+int32_t EbscTable::BitmapScaleTable::SubstitutePpemY() {
+ return data_->ReadByte(Offset::kBitmapScaleTable_substitutePpemY);
+}
+
+/******************************************************************************
+ * EbscTable::Builder class
+ ******************************************************************************/
+EbscTable::Builder::~Builder() {
+}
+
+CALLER_ATTACH EbscTable::Builder* EbscTable::Builder::CreateBuilder(
+ Header* header, WritableFontData* data) {
+ EbscTableBuilderPtr builder = new EbscTable::Builder(header, data);
+ return builder.Detach();
+}
+
+EbscTable::Builder::Builder(Header* header, WritableFontData* data)
+ : Table::Builder(header, data) {
+}
+
+EbscTable::Builder::Builder(Header* header, ReadableFontData* data)
+ : Table::Builder(header, data) {
+}
+
+CALLER_ATTACH
+FontDataTable* EbscTable::Builder::SubBuildTable(ReadableFontData* data) {
+ EbscTablePtr output = new EbscTable(header(), data);
+ return output.Detach();
+}
+
+void EbscTable::Builder::SubDataSet() {
+ // NOP
+}
+
+int32_t EbscTable::Builder::SubDataSizeToSerialize() {
+ return 0;
+}
+
+bool EbscTable::Builder::SubReadyToSerialize() {
+ return false;
+}
+
+int32_t EbscTable::Builder::SubSerialize(WritableFontData* new_data) {
+ UNREFERENCED_PARAMETER(new_data);
+ return 0;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebsc_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebsc_table.h
new file mode 100644
index 00000000000..b79df380df7
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/ebsc_table.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBSC_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBSC_TABLE_H_
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+namespace sfntly {
+
+class EbscTable : public Table,
+ public RefCounted<EbscTable> {
+ public:
+ struct Offset {
+ enum {
+ // header
+ kVersion = 0,
+ kNumSizes = DataSize::kFixed,
+ kHeaderLength = kNumSizes + DataSize::kULONG,
+ kBitmapScaleTableStart = kHeaderLength,
+
+ // bitmapScaleTable
+ kBitmapScaleTable_hori = 0,
+ kBitmapScaleTable_vert = EblcTable::Offset::kSbitLineMetricsLength,
+ kBitmapScaleTable_ppemX = kBitmapScaleTable_vert +
+ EblcTable::Offset::kSbitLineMetricsLength,
+ kBitmapScaleTable_ppemY = kBitmapScaleTable_ppemX + DataSize::kBYTE,
+ kBitmapScaleTable_substitutePpemX = kBitmapScaleTable_ppemY +
+ DataSize::kBYTE,
+ kBitmapScaleTable_substitutePpemY = kBitmapScaleTable_substitutePpemX +
+ DataSize::kBYTE,
+ kBitmapScaleTableLength = kBitmapScaleTable_substitutePpemY +
+ DataSize::kBYTE,
+ };
+ };
+
+ class BitmapScaleTable : public SubTable,
+ public RefCounted<BitmapScaleTable> {
+ public:
+ virtual ~BitmapScaleTable();
+ int32_t PpemX();
+ int32_t PpemY();
+ int32_t SubstitutePpemX();
+ int32_t SubstitutePpemY();
+
+ protected:
+ // Note: caller to do data->Slice(offset, Offset::kBitmapScaleTableLength)
+ explicit BitmapScaleTable(ReadableFontData* data);
+ };
+
+ // TODO(stuartg): currently the builder just builds from initial data
+ // - need to make fully working but few if any examples to test with
+ class Builder : public Table::Builder,
+ public RefCounted<Builder> {
+ public:
+ virtual ~Builder();
+
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ WritableFontData* data);
+
+ protected:
+ Builder(Header* header, WritableFontData* data);
+ Builder(Header* header, ReadableFontData* data);
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+ };
+
+ virtual ~EbscTable();
+
+ int32_t Version();
+ int32_t NumSizes();
+ // Note: renamed from bitmapScaleTable
+ CALLER_ATTACH BitmapScaleTable* GetBitmapScaleTable(int32_t index);
+
+ private:
+ EbscTable(Header* header, ReadableFontData* data);
+ friend class Builder;
+};
+typedef Ptr<EbscTable> EbscTablePtr;
+typedef Ptr<EbscTable::Builder> EbscTableBuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_EBSC_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/glyph_metrics.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/glyph_metrics.cc
new file mode 100644
index 00000000000..e91eb9921ee
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/glyph_metrics.cc
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/glyph_metrics.h"
+
+namespace sfntly {
+
+GlyphMetrics::~GlyphMetrics() {
+}
+
+GlyphMetrics::GlyphMetrics(ReadableFontData* data)
+ : SubTable(data) {
+}
+
+GlyphMetrics::Builder::~Builder() {
+}
+
+GlyphMetrics::Builder::Builder(WritableFontData* data)
+ : SubTable::Builder(data) {
+}
+
+GlyphMetrics::Builder::Builder(ReadableFontData* data)
+ : SubTable::Builder(data) {
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/glyph_metrics.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/glyph_metrics.h
new file mode 100644
index 00000000000..5f16aaa661d
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/glyph_metrics.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_METRICS_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_METRICS_H_
+
+#include "sfntly/table/subtable.h"
+
+namespace sfntly {
+
+class GlyphMetrics : public SubTable {
+ public:
+ virtual ~GlyphMetrics();
+
+ protected:
+ class Builder : public SubTable::Builder {
+ public:
+ virtual ~Builder();
+
+ protected:
+ explicit Builder(WritableFontData* data);
+ explicit Builder(ReadableFontData* data);
+ };
+
+ explicit GlyphMetrics(ReadableFontData* data);
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_GLYPH_METRICS_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table.cc
new file mode 100644
index 00000000000..5e297845042
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table.cc
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/index_sub_table.h"
+
+#include "sfntly/table/bitmap/eblc_table.h"
+#include "sfntly/table/bitmap/index_sub_table_format1.h"
+#include "sfntly/table/bitmap/index_sub_table_format2.h"
+#include "sfntly/table/bitmap/index_sub_table_format3.h"
+#include "sfntly/table/bitmap/index_sub_table_format4.h"
+#include "sfntly/table/bitmap/index_sub_table_format5.h"
+
+namespace sfntly {
+/******************************************************************************
+ * IndexSubTable class
+ ******************************************************************************/
+CALLER_ATTACH BitmapGlyphInfo* IndexSubTable::GlyphInfo(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return NULL;
+ }
+ if (GlyphStartOffset(glyph_id) == -1) {
+ return NULL;
+ }
+ BitmapGlyphInfoPtr output = new BitmapGlyphInfo(glyph_id,
+ image_data_offset(),
+ GlyphStartOffset(glyph_id),
+ GlyphLength(glyph_id),
+ image_format());
+ return output.Detach();
+}
+
+int32_t IndexSubTable::GlyphOffset(int32_t glyph_id) {
+ int32_t glyph_start_offset = GlyphStartOffset(glyph_id);
+ if (glyph_start_offset == -1) {
+ return -1;
+ }
+ return image_data_offset() + glyph_start_offset;
+}
+
+// static
+CALLER_ATTACH IndexSubTable*
+ IndexSubTable::CreateIndexSubTable(ReadableFontData* data,
+ int32_t offset_to_index_sub_table_array,
+ int32_t array_index) {
+ IndexSubTableBuilderPtr builder;
+ builder.Attach(IndexSubTable::Builder::CreateBuilder(
+ data, offset_to_index_sub_table_array, array_index));
+ return down_cast<IndexSubTable*>(builder->Build());
+}
+
+IndexSubTable::IndexSubTable(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : SubTable(data),
+ first_glyph_index_(first_glyph_index),
+ last_glyph_index_(last_glyph_index) {
+ index_format_ =
+ data_->ReadUShort(EblcTable::Offset::kIndexSubHeader_indexFormat);
+ image_format_ =
+ data_->ReadUShort(EblcTable::Offset::kIndexSubHeader_imageFormat);
+ image_data_offset_ =
+ data_->ReadULongAsInt(EblcTable::Offset::kIndexSubHeader_imageDataOffset);
+}
+
+int32_t IndexSubTable::CheckGlyphRange(int32_t glyph_id) {
+ return CheckGlyphRange(glyph_id, first_glyph_index(), last_glyph_index());
+}
+
+// static
+int32_t IndexSubTable::CheckGlyphRange(int32_t glyph_id,
+ int32_t first_glyph_id,
+ int32_t last_glyph_id) {
+ if (glyph_id < first_glyph_id || glyph_id > last_glyph_id) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundException("Glyph ID is outside of the allowed range.");
+#endif
+ return -1;
+ }
+ return glyph_id - first_glyph_id;
+}
+
+/******************************************************************************
+ * IndexSubTable::Builder class
+ ******************************************************************************/
+IndexSubTable::Builder::~Builder() {
+}
+
+void IndexSubTable::Builder::Revert() {
+ set_model_changed(false);
+ Initialize(InternalReadData());
+}
+
+CALLER_ATTACH BitmapGlyphInfo* IndexSubTable::Builder::GlyphInfo(
+ int32_t glyph_id) {
+ BitmapGlyphInfoPtr glyph_info =
+ new BitmapGlyphInfo(glyph_id,
+ image_data_offset(),
+ GlyphStartOffset(glyph_id),
+ GlyphLength(glyph_id),
+ image_format());
+ return glyph_info.Detach();
+}
+
+int32_t IndexSubTable::Builder::GlyphOffset(int32_t glyph_id) {
+ return image_data_offset() + GlyphStartOffset(glyph_id);
+}
+
+// static
+CALLER_ATTACH IndexSubTable::Builder*
+IndexSubTable::Builder::CreateBuilder(int32_t index_format) {
+ switch (index_format) {
+ case Format::FORMAT_1:
+ return IndexSubTableFormat1::Builder::CreateBuilder();
+ case Format::FORMAT_2:
+ return IndexSubTableFormat2::Builder::CreateBuilder();
+ case Format::FORMAT_3:
+ return IndexSubTableFormat3::Builder::CreateBuilder();
+ case Format::FORMAT_4:
+ return IndexSubTableFormat4::Builder::CreateBuilder();
+ case Format::FORMAT_5:
+ return IndexSubTableFormat5::Builder::CreateBuilder();
+ default:
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IllegalArgumentException("Invalid index subtable format");
+#endif
+ return NULL;
+ }
+}
+
+// static
+CALLER_ATTACH IndexSubTable::Builder*
+IndexSubTable::Builder::CreateBuilder(ReadableFontData* data,
+ int32_t offset_to_index_sub_table_array, int32_t array_index) {
+ int32_t index_sub_table_entry_offset =
+ offset_to_index_sub_table_array +
+ array_index * EblcTable::Offset::kIndexSubTableEntryLength;
+ int32_t first_glyph_index =
+ data->ReadUShort(index_sub_table_entry_offset +
+ EblcTable::Offset::kIndexSubTableEntry_firstGlyphIndex);
+ int32_t last_glyph_index =
+ data->ReadUShort(index_sub_table_entry_offset +
+ EblcTable::Offset::kIndexSubTableEntry_lastGlyphIndex);
+ int32_t additional_offset_to_index_subtable = data->ReadULongAsInt(
+ index_sub_table_entry_offset +
+ EblcTable::Offset::kIndexSubTableEntry_additionalOffsetToIndexSubTable);
+ int32_t index_sub_table_offset = offset_to_index_sub_table_array +
+ additional_offset_to_index_subtable;
+ int32_t index_format = data->ReadUShort(index_sub_table_offset);
+ switch (index_format) {
+ case 1:
+ return IndexSubTableFormat1::Builder::CreateBuilder(
+ data, index_sub_table_offset, first_glyph_index, last_glyph_index);
+ case 2:
+ return IndexSubTableFormat2::Builder::CreateBuilder(
+ data, index_sub_table_offset, first_glyph_index, last_glyph_index);
+ case 3:
+ return IndexSubTableFormat3::Builder::CreateBuilder(
+ data, index_sub_table_offset, first_glyph_index, last_glyph_index);
+ case 4:
+ return IndexSubTableFormat4::Builder::CreateBuilder(
+ data, index_sub_table_offset, first_glyph_index, last_glyph_index);
+ case 5:
+ return IndexSubTableFormat5::Builder::CreateBuilder(
+ data, index_sub_table_offset, first_glyph_index, last_glyph_index);
+ default:
+ // Unknown format and unable to process.
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IllegalArgumentException("Invalid Index Subtable Format");
+#endif
+ break;
+ }
+ return NULL;
+}
+
+CALLER_ATTACH
+FontDataTable* IndexSubTable::Builder::SubBuildTable(ReadableFontData* data) {
+ UNREFERENCED_PARAMETER(data);
+ return NULL;
+}
+
+void IndexSubTable::Builder::SubDataSet() {
+ // NOP
+}
+
+int32_t IndexSubTable::Builder::SubDataSizeToSerialize() {
+ return 0;
+}
+
+bool IndexSubTable::Builder::SubReadyToSerialize() {
+ return false;
+}
+
+int32_t IndexSubTable::Builder::SubSerialize(WritableFontData* new_data) {
+ UNREFERENCED_PARAMETER(new_data);
+ return 0;
+}
+
+IndexSubTable::Builder::Builder(int32_t data_size, int32_t index_format)
+ : SubTable::Builder(data_size),
+ first_glyph_index_(0),
+ last_glyph_index_(0),
+ index_format_(index_format),
+ image_format_(0),
+ image_data_offset_(0) {
+}
+
+IndexSubTable::Builder::Builder(int32_t index_format,
+ int32_t image_format,
+ int32_t image_data_offset,
+ int32_t data_size)
+ : SubTable::Builder(data_size),
+ first_glyph_index_(0),
+ last_glyph_index_(0),
+ index_format_(index_format),
+ image_format_(image_format),
+ image_data_offset_(image_data_offset) {
+}
+
+IndexSubTable::Builder::Builder(WritableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : SubTable::Builder(data),
+ first_glyph_index_(first_glyph_index),
+ last_glyph_index_(last_glyph_index) {
+ Initialize(data);
+}
+
+IndexSubTable::Builder::Builder(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : SubTable::Builder(data),
+ first_glyph_index_(first_glyph_index),
+ last_glyph_index_(last_glyph_index) {
+ Initialize(data);
+}
+
+int32_t IndexSubTable::Builder::CheckGlyphRange(int32_t glyph_id) {
+ return IndexSubTable::CheckGlyphRange(glyph_id,
+ first_glyph_index(),
+ last_glyph_index());
+}
+
+int32_t IndexSubTable::Builder::SerializeIndexSubHeader(
+ WritableFontData* data) {
+ int32_t size =
+ data->WriteUShort(EblcTable::Offset::kIndexSubHeader_indexFormat,
+ index_format());
+ size += data->WriteUShort(EblcTable::Offset::kIndexSubHeader_imageFormat,
+ image_format());
+ size += data->WriteULong(EblcTable::Offset::kIndexSubHeader_imageDataOffset,
+ image_data_offset());
+ return size;
+}
+
+void IndexSubTable::Builder::Initialize(ReadableFontData* data) {
+ index_format_ =
+ data->ReadUShort(EblcTable::Offset::kIndexSubHeader_indexFormat);
+ image_format_ =
+ data->ReadUShort(EblcTable::Offset::kIndexSubHeader_imageFormat);
+ image_data_offset_ =
+ data->ReadULongAsInt(EblcTable::Offset::kIndexSubHeader_imageDataOffset);
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table.h
new file mode 100644
index 00000000000..6d27129ccd3
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_H_
+
+#include <vector>
+
+#include "sfntly/port/java_iterator.h"
+#include "sfntly/table/subtable.h"
+#include "sfntly/table/bitmap/bitmap_glyph_info.h"
+
+namespace sfntly {
+
+class IndexSubTable : public SubTable {
+ public:
+ struct Format {
+ enum {
+ FORMAT_1 = 1,
+ FORMAT_2 = 2,
+ FORMAT_3 = 3,
+ FORMAT_4 = 4,
+ FORMAT_5 = 5,
+ };
+ };
+
+ class Builder : public SubTable::Builder {
+ public:
+ virtual ~Builder();
+
+ void Revert();
+
+ int32_t index_format() { return index_format_; }
+ int32_t first_glyph_index() { return first_glyph_index_; }
+ void set_first_glyph_index(int32_t v) { first_glyph_index_ = v; }
+ int32_t last_glyph_index() { return last_glyph_index_; }
+ void set_last_glyph_index(int32_t v) { last_glyph_index_ = v; }
+ int32_t image_format() { return image_format_; }
+ void set_image_format(int32_t v) { image_format_ = v; }
+ int32_t image_data_offset() { return image_data_offset_; }
+ void set_image_data_offset(int32_t v) { image_data_offset_ = v; }
+
+ virtual int32_t NumGlyphs() = 0;
+
+ // Gets the glyph info for the specified glyph id.
+ // @param glyphId the glyph id to look up
+ // @return the glyph info
+ CALLER_ATTACH virtual BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
+
+ // Gets the full offset of the glyph within the EBDT table.
+ // @param glyphId the glyph id
+ // @return the glyph offset
+ virtual int32_t GlyphOffset(int32_t glyph_id);
+
+ // Gets the offset of the glyph relative to the block for this index
+ // subtable.
+ // @param glyphId the glyph id
+ // @return the glyph offset
+ virtual int32_t GlyphStartOffset(int32_t glyph_id) = 0;
+
+ // Gets the length of the glyph within the EBDT table.
+ // @param glyphId the glyph id
+ // @return the glyph offset
+ virtual int32_t GlyphLength(int32_t glyph_id) = 0;
+
+ // Note: renamed from java iterator()
+ CALLER_ATTACH virtual Iterator<BitmapGlyphInfo, IndexSubTable::Builder>*
+ GetIterator() = 0;
+
+ // Static instantiation function.
+ static CALLER_ATTACH Builder* CreateBuilder(int32_t index_format);
+ static CALLER_ATTACH Builder*
+ CreateBuilder(ReadableFontData* data,
+ int32_t offset_to_index_sub_table_array,
+ int32_t array_index);
+
+ // The following methods will never be called but they need to be here to
+ // allow the BitmapSizeTable to see these methods through an abstract
+ // reference.
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ protected:
+ Builder(int32_t data_size, int32_t index_format);
+ Builder(int32_t index_format,
+ int32_t image_format,
+ int32_t image_data_offset,
+ int32_t data_size);
+ Builder(WritableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ Builder(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+
+ // Checks that the glyph id is within the correct range. If it returns the
+ // offset of the glyph id from the start of the range.
+ // @param glyphId
+ // @return the offset of the glyphId from the start of the glyph range
+ // @throws IndexOutOfBoundsException if the glyph id is not within the
+ // correct range
+ int32_t CheckGlyphRange(int32_t glyph_id);
+ int32_t SerializeIndexSubHeader(WritableFontData* data);
+
+ private:
+ void Initialize(ReadableFontData* data);
+
+ int32_t first_glyph_index_;
+ int32_t last_glyph_index_;
+ int32_t index_format_;
+ int32_t image_format_;
+ int32_t image_data_offset_;
+ };
+
+ int32_t index_format() { return index_format_; }
+ int32_t first_glyph_index() { return first_glyph_index_; }
+ int32_t last_glyph_index() { return last_glyph_index_; }
+ int32_t image_format() { return image_format_; }
+ int32_t image_data_offset() { return image_data_offset_; }
+
+ CALLER_ATTACH BitmapGlyphInfo* GlyphInfo(int32_t glyph_id);
+ virtual int32_t GlyphOffset(int32_t glyph_id);
+ virtual int32_t GlyphStartOffset(int32_t glyph_id) = 0;
+ virtual int32_t GlyphLength(int32_t glyph_id) = 0;
+ virtual int32_t NumGlyphs() = 0;
+
+ static CALLER_ATTACH IndexSubTable*
+ CreateIndexSubTable(ReadableFontData* data,
+ int32_t offset_to_index_sub_table_array,
+ int32_t array_index);
+
+ protected:
+ // Note: the constructor does not implement offset/length form provided in
+ // Java to avoid heavy lifting in constructors. Callers to call
+ // GetDataLength() static method of the derived class to get proper
+ // length and slice ahead.
+ IndexSubTable(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+
+ int32_t CheckGlyphRange(int32_t glyph_id);
+ static int32_t CheckGlyphRange(int32_t glyph_id,
+ int32_t first_glyph_id,
+ int32_t last_glyph_id);
+
+ private:
+ int32_t first_glyph_index_;
+ int32_t last_glyph_index_;
+ int32_t index_format_;
+ int32_t image_format_;
+ int32_t image_data_offset_;
+};
+typedef Ptr<IndexSubTable> IndexSubTablePtr;
+typedef std::vector<IndexSubTablePtr> IndexSubTableList;
+typedef Ptr<IndexSubTable::Builder> IndexSubTableBuilderPtr;
+typedef std::vector<IndexSubTableBuilderPtr> IndexSubTableBuilderList;
+typedef Iterator<BitmapGlyphInfo, IndexSubTable::Builder> BitmapGlyphInfoIter;
+typedef Ptr<BitmapGlyphInfoIter> BitmapGlyphInfoIterPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc
new file mode 100644
index 00000000000..5199e18cb57
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc
@@ -0,0 +1,302 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/index_sub_table_format1.h"
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * IndexSubTableFormat1 class
+ ******************************************************************************/
+// static
+int32_t IndexSubTableFormat1::GetDataLength(ReadableFontData* data,
+ int32_t offset,
+ int32_t first,
+ int32_t last) {
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(offset);
+ return (last - first + 1 + 1) * DataSize::kULONG;
+}
+
+IndexSubTableFormat1::~IndexSubTableFormat1() {
+}
+
+int32_t IndexSubTableFormat1::NumGlyphs() {
+ return last_glyph_index() - first_glyph_index() + 1;
+}
+
+int32_t IndexSubTableFormat1::GlyphStartOffset(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return -1;
+ }
+ return Loca(loca);
+}
+
+int32_t IndexSubTableFormat1::GlyphLength(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return -1;
+ }
+ return Loca(loca + 1) - Loca(loca);
+}
+
+IndexSubTableFormat1::IndexSubTableFormat1(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : IndexSubTable(data, first_glyph_index, last_glyph_index) {
+}
+
+int32_t IndexSubTableFormat1::Loca(int32_t loca) {
+ return image_data_offset() +
+ data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable1_offsetArray +
+ loca * DataSize::kULONG);
+}
+
+/******************************************************************************
+ * IndexSubTableFormat1::Builder class
+ ******************************************************************************/
+IndexSubTableFormat1::Builder::~Builder() {
+}
+
+int32_t IndexSubTableFormat1::Builder::NumGlyphs() {
+ return GetOffsetArray()->size() - 1;
+}
+
+int32_t IndexSubTableFormat1::Builder::GlyphLength(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return 0;
+ }
+ IntegerList* offset_array = GetOffsetArray();
+ return offset_array->at(loca + 1) - offset_array->at(loca);
+}
+
+int32_t IndexSubTableFormat1::Builder::GlyphStartOffset(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return -1;
+ }
+ return GetOffsetArray()->at(loca);
+}
+
+CALLER_ATTACH IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator*
+ IndexSubTableFormat1::Builder::GetIterator() {
+ Ptr<IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator> it =
+ new IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator(this);
+ return it.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat1::Builder*
+IndexSubTableFormat1::Builder::CreateBuilder() {
+ IndexSubTableFormat1BuilderPtr output = new IndexSubTableFormat1::Builder();
+ return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat1::Builder*
+IndexSubTableFormat1::Builder::CreateBuilder(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ int32_t length = Builder::DataLength(data,
+ index_sub_table_offset,
+ first_glyph_index,
+ last_glyph_index);
+ ReadableFontDataPtr new_data;
+ new_data.Attach(down_cast<ReadableFontData*>(
+ data->Slice(index_sub_table_offset, length)));
+ if (new_data == NULL) {
+ return NULL;
+ }
+ IndexSubTableFormat1BuilderPtr output =
+ new IndexSubTableFormat1::Builder(new_data,
+ first_glyph_index,
+ last_glyph_index);
+ return output.Detach();
+}
+
+
+// static
+CALLER_ATTACH IndexSubTableFormat1::Builder*
+IndexSubTableFormat1::Builder::CreateBuilder(WritableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ int32_t length = Builder::DataLength(data,
+ index_sub_table_offset,
+ first_glyph_index,
+ last_glyph_index);
+ WritableFontDataPtr new_data;
+ new_data.Attach(down_cast<WritableFontData*>(
+ data->Slice(index_sub_table_offset, length)));
+ IndexSubTableFormat1BuilderPtr output =
+ new IndexSubTableFormat1::Builder(new_data,
+ first_glyph_index,
+ last_glyph_index);
+ return output.Detach();
+}
+
+CALLER_ATTACH FontDataTable* IndexSubTableFormat1::Builder::SubBuildTable(
+ ReadableFontData* data) {
+ IndexSubTableFormat1Ptr output = new IndexSubTableFormat1(
+ data, first_glyph_index(), last_glyph_index());
+ return output.Detach();
+}
+
+void IndexSubTableFormat1::Builder::SubDataSet() {
+ Revert();
+}
+
+int32_t IndexSubTableFormat1::Builder::SubDataSizeToSerialize() {
+ if (offset_array_.empty()) {
+ return InternalReadData()->Length();
+ }
+ return EblcTable::Offset::kIndexSubHeaderLength +
+ offset_array_.size() * DataSize::kULONG;
+}
+
+bool IndexSubTableFormat1::Builder::SubReadyToSerialize() {
+ if (!offset_array_.empty()) {
+ return true;
+ }
+ return false;
+}
+
+int32_t IndexSubTableFormat1::Builder::SubSerialize(
+ WritableFontData* new_data) {
+ int32_t size = SerializeIndexSubHeader(new_data);
+ if (!model_changed()) {
+ if (InternalReadData() == NULL) {
+ return size;
+ }
+ ReadableFontDataPtr source;
+ WritableFontDataPtr target;
+ source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
+ EblcTable::Offset::kIndexSubTable1_offsetArray)));
+ target.Attach(down_cast<WritableFontData*>(new_data->Slice(
+ EblcTable::Offset::kIndexSubTable1_offsetArray)));
+ size += source->CopyTo(target);
+ } else {
+ for (IntegerList::iterator b = GetOffsetArray()->begin(),
+ e = GetOffsetArray()->end(); b != e; b++) {
+ size += new_data->WriteLong(size, *b);
+ }
+ }
+ return size;
+}
+
+IntegerList* IndexSubTableFormat1::Builder::OffsetArray() {
+ return GetOffsetArray();
+}
+
+void IndexSubTableFormat1::Builder::SetOffsetArray(
+ const IntegerList& offset_array) {
+ offset_array_.clear();
+ offset_array_ = offset_array;
+ set_model_changed();
+}
+
+void IndexSubTableFormat1::Builder::Revert() {
+ offset_array_.clear();
+ IndexSubTable::Builder::Revert();
+}
+
+IndexSubTableFormat1::Builder::Builder()
+ : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable1_builderDataSize,
+ IndexSubTable::Format::FORMAT_1) {
+}
+
+IndexSubTableFormat1::Builder::Builder(WritableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IndexSubTableFormat1::Builder::Builder(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IntegerList* IndexSubTableFormat1::Builder::GetOffsetArray() {
+ if (offset_array_.empty()) {
+ Initialize(InternalReadData());
+ set_model_changed();
+ }
+ return &offset_array_;
+}
+
+void IndexSubTableFormat1::Builder::Initialize(ReadableFontData* data) {
+ offset_array_.clear();
+ if (data) {
+ int32_t num_offsets = (last_glyph_index() - first_glyph_index() + 1) + 1;
+ for (int32_t i = 0; i < num_offsets; ++i) {
+ offset_array_.push_back(data->ReadULongAsInt(
+ EblcTable::Offset::kIndexSubTable1_offsetArray +
+ i * DataSize::kULONG));
+ }
+ }
+}
+
+// static
+int32_t IndexSubTableFormat1::Builder::DataLength(
+ ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(index_sub_table_offset);
+ return EblcTable::Offset::kIndexSubHeaderLength +
+ (last_glyph_index - first_glyph_index + 1 + 1) * DataSize::kULONG;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator class
+ ******************************************************************************/
+IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
+ IndexSubTableFormat1::Builder* container)
+ : RefIterator<BitmapGlyphInfo, IndexSubTableFormat1::Builder,
+ IndexSubTable::Builder>(container) {
+ glyph_id_ = container->first_glyph_index();
+}
+
+bool IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator::HasNext() {
+ if (glyph_id_ <= container()->last_glyph_index()) {
+ return true;
+ }
+ return false;
+}
+
+CALLER_ATTACH BitmapGlyphInfo*
+IndexSubTableFormat1::Builder::BitmapGlyphInfoIterator::Next() {
+ BitmapGlyphInfoPtr output;
+ if (!HasNext()) {
+ // Note: In C++, we do not throw exception when there's no element.
+ return NULL;
+ }
+ output = new BitmapGlyphInfo(glyph_id_,
+ container()->image_data_offset(),
+ container()->GlyphStartOffset(glyph_id_),
+ container()->GlyphLength(glyph_id_),
+ container()->image_format());
+ glyph_id_++;
+ return output.Detach();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format1.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format1.h
new file mode 100644
index 00000000000..33171c15611
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format1.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT1_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT1_H_
+
+#include "sfntly/port/java_iterator.h"
+#include "sfntly/table/bitmap/index_sub_table.h"
+
+namespace sfntly {
+// Format 1 Index Subtable Entry.
+class IndexSubTableFormat1 : public IndexSubTable,
+ public RefCounted<IndexSubTableFormat1> {
+ public:
+ class Builder : public IndexSubTable::Builder,
+ public RefCounted<Builder> {
+ public:
+ class BitmapGlyphInfoIterator
+ : public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
+ public:
+ explicit BitmapGlyphInfoIterator(Builder* container);
+ virtual ~BitmapGlyphInfoIterator() {}
+
+ virtual bool HasNext();
+ CALLER_ATTACH virtual BitmapGlyphInfo* Next();
+
+ private:
+ int32_t glyph_id_;
+ };
+
+ virtual ~Builder();
+ virtual int32_t NumGlyphs();
+ virtual int32_t GlyphLength(int32_t glyph_id);
+ virtual int32_t GlyphStartOffset(int32_t glyph_id);
+ CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ IntegerList* OffsetArray();
+ void SetOffsetArray(const IntegerList& offset_array);
+ CALLER_ATTACH BitmapGlyphInfoIter* Iterator();
+
+ static CALLER_ATTACH Builder* CreateBuilder();
+ static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+
+ protected:
+ void Revert();
+
+ private:
+ Builder();
+ Builder(WritableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ Builder(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ IntegerList* GetOffsetArray();
+ void Initialize(ReadableFontData* data);
+
+ static int32_t DataLength(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+
+ IntegerList offset_array_;
+ };
+
+ virtual ~IndexSubTableFormat1();
+
+ virtual int32_t NumGlyphs();
+ virtual int32_t GlyphStartOffset(int32_t glyph_id);
+ virtual int32_t GlyphLength(int32_t glyph_id);
+
+ static int32_t GetDataLength(ReadableFontData* data,
+ int32_t offset,
+ int32_t first,
+ int32_t last);
+
+ private:
+ IndexSubTableFormat1(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ int32_t Loca(int32_t loca_index);
+
+ friend class Builder;
+};
+typedef Ptr<IndexSubTableFormat1> IndexSubTableFormat1Ptr;
+typedef Ptr<IndexSubTableFormat1::Builder> IndexSubTableFormat1BuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT1_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format2.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format2.cc
new file mode 100644
index 00000000000..ce73e9beec8
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format2.cc
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/index_sub_table_format2.h"
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * IndexSubTableFormat2 class
+ ******************************************************************************/
+IndexSubTableFormat2::~IndexSubTableFormat2() {
+}
+
+int32_t IndexSubTableFormat2::ImageSize() {
+ return data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable2_imageSize);
+}
+
+CALLER_ATTACH BigGlyphMetrics* IndexSubTableFormat2::BigMetrics() {
+ ReadableFontDataPtr slice;
+ slice.Attach(down_cast<ReadableFontData*>(
+ data_->Slice(EblcTable::Offset::kIndexSubTable2_bigGlyphMetrics,
+ BigGlyphMetrics::Offset::kMetricsLength)));
+ BigGlyphMetricsPtr output = new BigGlyphMetrics(slice);
+ return output.Detach();
+}
+
+int32_t IndexSubTableFormat2::NumGlyphs() {
+ return last_glyph_index() - first_glyph_index() + 1;
+}
+
+int32_t IndexSubTableFormat2::GlyphStartOffset(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return -1;
+ }
+ return loca * image_size_;
+}
+
+int32_t IndexSubTableFormat2::GlyphLength(int32_t glyph_id) {
+ if (CheckGlyphRange(glyph_id) == -1) {
+ return 0;
+ }
+ return image_size_;
+}
+
+IndexSubTableFormat2::IndexSubTableFormat2(ReadableFontData* data,
+ int32_t first,
+ int32_t last)
+ : IndexSubTable(data, first, last) {
+ image_size_ =
+ data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable2_imageSize);
+}
+
+/******************************************************************************
+ * IndexSubTableFormat2::Builder class
+ ******************************************************************************/
+IndexSubTableFormat2::Builder::~Builder() {
+}
+
+int32_t IndexSubTableFormat2::Builder::NumGlyphs() {
+ return last_glyph_index() - first_glyph_index() + 1;
+}
+
+int32_t IndexSubTableFormat2::Builder::GlyphStartOffset(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return -1;
+ }
+ return loca * ImageSize();
+}
+
+int32_t IndexSubTableFormat2::Builder::GlyphLength(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return 0;
+ }
+ return ImageSize();
+}
+
+CALLER_ATTACH IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator*
+ IndexSubTableFormat2::Builder::GetIterator() {
+ Ptr<IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator> it =
+ new IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator(this);
+ return it.Detach();
+}
+
+int32_t IndexSubTableFormat2::Builder::ImageSize() {
+ return InternalReadData()->ReadULongAsInt(
+ EblcTable::Offset::kIndexSubTable2_imageSize);
+}
+
+void IndexSubTableFormat2::Builder::SetImageSize(int32_t image_size) {
+ InternalWriteData()->WriteULong(EblcTable::Offset::kIndexSubTable2_imageSize,
+ image_size);
+}
+
+BigGlyphMetrics::Builder* IndexSubTableFormat2::Builder::BigMetrics() {
+ if (metrics_ == NULL) {
+ WritableFontDataPtr data;
+ data.Attach(down_cast<WritableFontData*>(InternalWriteData()->Slice(
+ EblcTable::Offset::kIndexSubTable2_bigGlyphMetrics,
+ BigGlyphMetrics::Offset::kMetricsLength)));
+ metrics_ = new BigGlyphMetrics::Builder(data);
+ }
+ return metrics_;
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat2::Builder*
+IndexSubTableFormat2::Builder::CreateBuilder() {
+ IndexSubTableFormat2BuilderPtr output = new IndexSubTableFormat2::Builder();
+ return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat2::Builder*
+IndexSubTableFormat2::Builder::CreateBuilder(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ int32_t length = Builder::DataLength(data,
+ index_sub_table_offset,
+ first_glyph_index,
+ last_glyph_index);
+ ReadableFontDataPtr new_data;
+ new_data.Attach(down_cast<ReadableFontData*>(
+ data->Slice(index_sub_table_offset, length)));
+ if (new_data == NULL) {
+ return NULL;
+ }
+ IndexSubTableFormat2BuilderPtr output =
+ new IndexSubTableFormat2::Builder(new_data,
+ first_glyph_index,
+ last_glyph_index);
+ return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat2::Builder*
+IndexSubTableFormat2::Builder::CreateBuilder(WritableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ int32_t length = Builder::DataLength(data,
+ index_sub_table_offset,
+ first_glyph_index,
+ last_glyph_index);
+ WritableFontDataPtr new_data;
+ new_data.Attach(down_cast<WritableFontData*>(
+ data->Slice(index_sub_table_offset, length)));
+ IndexSubTableFormat2BuilderPtr output =
+ new IndexSubTableFormat2::Builder(new_data,
+ first_glyph_index,
+ last_glyph_index);
+ return output.Detach();
+}
+
+CALLER_ATTACH FontDataTable* IndexSubTableFormat2::Builder::SubBuildTable(
+ ReadableFontData* data) {
+ IndexSubTableFormat2Ptr output = new IndexSubTableFormat2(
+ data, first_glyph_index(), last_glyph_index());
+ return output.Detach();
+}
+
+void IndexSubTableFormat2::Builder::SubDataSet() {
+ Revert();
+}
+
+int32_t IndexSubTableFormat2::Builder::SubDataSizeToSerialize() {
+ return EblcTable::Offset::kIndexSubTable2Length;
+}
+
+bool IndexSubTableFormat2::Builder::SubReadyToSerialize() {
+ return true;
+}
+
+int32_t IndexSubTableFormat2::Builder::SubSerialize(
+ WritableFontData* new_data) {
+ int32_t size = SerializeIndexSubHeader(new_data);
+ if (metrics_ == NULL) {
+ ReadableFontDataPtr source;
+ WritableFontDataPtr target;
+ source.Attach(down_cast<ReadableFontData*>(
+ InternalReadData()->Slice(size)));
+ target.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
+ size += source->CopyTo(target);
+ } else {
+ WritableFontDataPtr slice;
+ size += new_data->WriteLong(EblcTable::Offset::kIndexSubTable2_imageSize,
+ ImageSize());
+ slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
+ size += metrics_->SubSerialize(slice);
+ }
+ return size;
+}
+
+IndexSubTableFormat2::Builder::Builder()
+ : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable3_builderDataSize,
+ IndexSubTable::Format::FORMAT_2) {
+ metrics_.Attach(BigGlyphMetrics::Builder::CreateBuilder());
+}
+
+IndexSubTableFormat2::Builder::Builder(WritableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IndexSubTableFormat2::Builder::Builder(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+// static
+int32_t IndexSubTableFormat2::Builder::DataLength(
+ ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(index_sub_table_offset);
+ UNREFERENCED_PARAMETER(first_glyph_index);
+ UNREFERENCED_PARAMETER(last_glyph_index);
+ return EblcTable::Offset::kIndexSubTable2Length;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator class
+ ******************************************************************************/
+IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
+ IndexSubTableFormat2::Builder* container)
+ : RefIterator<BitmapGlyphInfo, IndexSubTableFormat2::Builder,
+ IndexSubTable::Builder>(container) {
+ glyph_id_ = container->first_glyph_index();
+}
+
+bool IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::HasNext() {
+ if (glyph_id_ <= container()->last_glyph_index()) {
+ return true;
+ }
+ return false;
+}
+
+CALLER_ATTACH BitmapGlyphInfo*
+IndexSubTableFormat2::Builder::BitmapGlyphInfoIterator::Next() {
+ BitmapGlyphInfoPtr output;
+ if (!HasNext()) {
+ // Note: In C++, we do not throw exception when there's no element.
+ return NULL;
+ }
+ output = new BitmapGlyphInfo(glyph_id_,
+ container()->image_data_offset(),
+ container()->GlyphStartOffset(glyph_id_),
+ container()->GlyphLength(glyph_id_),
+ container()->image_format());
+ glyph_id_++;
+ return output.Detach();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format2.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format2.h
new file mode 100644
index 00000000000..784e8a39fea
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format2.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT2_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT2_H_
+
+#include "sfntly/table/bitmap/index_sub_table.h"
+#include "sfntly/table/bitmap/big_glyph_metrics.h"
+
+namespace sfntly {
+// Format 2 Index Subtable Entry.
+class IndexSubTableFormat2 : public IndexSubTable,
+ public RefCounted<IndexSubTableFormat2> {
+ public:
+ class Builder : public IndexSubTable::Builder,
+ public RefCounted<Builder> {
+ public:
+ class BitmapGlyphInfoIterator
+ : public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
+ public:
+ explicit BitmapGlyphInfoIterator(Builder* container);
+ virtual ~BitmapGlyphInfoIterator() {}
+
+ virtual bool HasNext();
+ CALLER_ATTACH virtual BitmapGlyphInfo* Next();
+
+ private:
+ int32_t glyph_id_;
+ };
+
+ virtual ~Builder();
+ virtual int32_t NumGlyphs();
+ virtual int32_t GlyphStartOffset(int32_t glyph_id);
+ virtual int32_t GlyphLength(int32_t glyph_id);
+ CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ int32_t ImageSize();
+ void SetImageSize(int32_t image_size);
+ BigGlyphMetrics::Builder* BigMetrics();
+
+ static CALLER_ATTACH Builder* CreateBuilder();
+ static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ private:
+ Builder();
+ Builder(WritableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ Builder(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+
+ static int32_t DataLength(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+
+ BigGlyphMetricsBuilderPtr metrics_;
+ };
+
+ virtual ~IndexSubTableFormat2();
+
+ int32_t ImageSize();
+ CALLER_ATTACH BigGlyphMetrics* BigMetrics();
+
+ virtual int32_t NumGlyphs();
+ virtual int32_t GlyphStartOffset(int32_t glyph_id);
+ virtual int32_t GlyphLength(int32_t glyph_id);
+
+ private:
+ IndexSubTableFormat2(ReadableFontData* data, int32_t first, int32_t last);
+
+ int32_t image_size_;
+ friend class Builder;
+};
+typedef Ptr<IndexSubTableFormat2> IndexSubTableFormat2Ptr;
+typedef Ptr<IndexSubTableFormat2::Builder> IndexSubTableFormat2BuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT1_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc
new file mode 100644
index 00000000000..e2679b79a9e
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc
@@ -0,0 +1,298 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/index_sub_table_format3.h"
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * IndexSubTableFormat3 class
+ ******************************************************************************/
+IndexSubTableFormat3::~IndexSubTableFormat3() {
+}
+
+int32_t IndexSubTableFormat3::NumGlyphs() {
+ return last_glyph_index() - first_glyph_index() + 1;
+}
+
+int32_t IndexSubTableFormat3::GlyphStartOffset(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca != -1) {
+ return Loca(loca);
+ }
+ return -1;
+}
+
+int32_t IndexSubTableFormat3::GlyphLength(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca != -1) {
+ return Loca(glyph_id + 1) - Loca(glyph_id);
+ }
+ return 0;
+}
+
+// static
+int32_t IndexSubTableFormat3::GetDataLength(ReadableFontData* data,
+ int32_t offset,
+ int32_t first,
+ int32_t last) {
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(offset);
+ return (last - first + 1 + 1) * DataSize::kUSHORT;
+}
+
+IndexSubTableFormat3::IndexSubTableFormat3(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : IndexSubTable(data, first_glyph_index, last_glyph_index) {
+}
+
+int32_t IndexSubTableFormat3::Loca(int32_t loca) {
+ int32_t read_offset =
+ data_->ReadUShort(EblcTable::Offset::kIndexSubTable3_offsetArray +
+ loca * DataSize::kUSHORT);
+ return read_offset;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat3::Builder class
+ ******************************************************************************/
+IndexSubTableFormat3::Builder::~Builder() {
+}
+
+int32_t IndexSubTableFormat3::Builder::NumGlyphs() {
+ return GetOffsetArray()->size() - 1;
+}
+
+int32_t IndexSubTableFormat3::Builder::GlyphStartOffset(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return -1;
+ }
+ return GetOffsetArray()->at(loca);
+}
+
+int32_t IndexSubTableFormat3::Builder::GlyphLength(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return 0;
+ }
+ IntegerList* offset_array = GetOffsetArray();
+ return offset_array->at(loca + 1) - offset_array->at(loca);
+}
+
+CALLER_ATTACH IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator*
+ IndexSubTableFormat3::Builder::GetIterator() {
+ Ptr<IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator> it =
+ new IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator(this);
+ return it.Detach();
+}
+
+void IndexSubTableFormat3::Builder::Revert() {
+ offset_array_.clear();
+ IndexSubTable::Builder::Revert();
+}
+
+void IndexSubTableFormat3::Builder::SetOffsetArray(
+ const IntegerList& offset_array) {
+ offset_array_.clear();
+ offset_array_ = offset_array;
+ set_model_changed();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat3::Builder*
+IndexSubTableFormat3::Builder::CreateBuilder() {
+ IndexSubTableFormat3BuilderPtr output = new IndexSubTableFormat3::Builder();
+ return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat3::Builder*
+IndexSubTableFormat3::Builder::CreateBuilder(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ int32_t length = Builder::DataLength(data,
+ index_sub_table_offset,
+ first_glyph_index,
+ last_glyph_index);
+ ReadableFontDataPtr new_data;
+ new_data.Attach(down_cast<ReadableFontData*>(
+ data->Slice(index_sub_table_offset, length)));
+ if (new_data == NULL) {
+ return NULL;
+ }
+ IndexSubTableFormat3BuilderPtr output =
+ new IndexSubTableFormat3::Builder(new_data,
+ first_glyph_index,
+ last_glyph_index);
+ return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat3::Builder*
+IndexSubTableFormat3::Builder::CreateBuilder(WritableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ int32_t length = Builder::DataLength(data,
+ index_sub_table_offset,
+ first_glyph_index,
+ last_glyph_index);
+ WritableFontDataPtr new_data;
+ new_data.Attach(down_cast<WritableFontData*>(
+ data->Slice(index_sub_table_offset, length)));
+ IndexSubTableFormat3BuilderPtr output =
+ new IndexSubTableFormat3::Builder(new_data,
+ first_glyph_index,
+ last_glyph_index);
+ return output.Detach();
+}
+
+CALLER_ATTACH FontDataTable* IndexSubTableFormat3::Builder::SubBuildTable(
+ ReadableFontData* data) {
+ IndexSubTableFormat3Ptr output = new IndexSubTableFormat3(
+ data, first_glyph_index(), last_glyph_index());
+ return output.Detach();
+}
+
+void IndexSubTableFormat3::Builder::SubDataSet() {
+ Revert();
+}
+
+int32_t IndexSubTableFormat3::Builder::SubDataSizeToSerialize() {
+ if (offset_array_.empty()) {
+ return InternalReadData()->Length();
+ }
+ return EblcTable::Offset::kIndexSubHeaderLength +
+ offset_array_.size() * DataSize::kULONG;
+}
+
+bool IndexSubTableFormat3::Builder::SubReadyToSerialize() {
+ if (!offset_array_.empty()) {
+ return true;
+ }
+ return false;
+}
+
+int32_t IndexSubTableFormat3::Builder::SubSerialize(
+ WritableFontData* new_data) {
+ int32_t size = SerializeIndexSubHeader(new_data);
+ if (!model_changed()) {
+ if (InternalReadData() == NULL) {
+ return size;
+ }
+ ReadableFontDataPtr source;
+ WritableFontDataPtr target;
+ source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
+ EblcTable::Offset::kIndexSubTable3_offsetArray)));
+ target.Attach(down_cast<WritableFontData*>(new_data->Slice(
+ EblcTable::Offset::kIndexSubTable3_offsetArray)));
+ size += source->CopyTo(target);
+ } else {
+ for (IntegerList::iterator b = GetOffsetArray()->begin(),
+ e = GetOffsetArray()->end(); b != e; b++) {
+ size += new_data->WriteUShort(size, *b);
+ }
+ }
+ return size;
+}
+
+IndexSubTableFormat3::Builder::Builder()
+ : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable3_builderDataSize,
+ IndexSubTable::Format::FORMAT_3) {
+}
+
+IndexSubTableFormat3::Builder::Builder(WritableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IndexSubTableFormat3::Builder::Builder(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IntegerList* IndexSubTableFormat3::Builder::GetOffsetArray() {
+ if (offset_array_.empty()) {
+ Initialize(InternalReadData());
+ set_model_changed();
+ }
+ return &offset_array_;
+}
+
+void IndexSubTableFormat3::Builder::Initialize(ReadableFontData* data) {
+ offset_array_.clear();
+ if (data) {
+ int32_t num_offsets = (last_glyph_index() - first_glyph_index() + 1) + 1;
+ for (int32_t i = 0; i < num_offsets; ++i) {
+ offset_array_.push_back(data->ReadUShort(
+ EblcTable::Offset::kIndexSubTable3_offsetArray +
+ i * DataSize::kUSHORT));
+ }
+ }
+}
+
+// static
+int32_t IndexSubTableFormat3::Builder::DataLength(
+ ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ UNREFERENCED_PARAMETER(data);
+ UNREFERENCED_PARAMETER(index_sub_table_offset);
+ return EblcTable::Offset::kIndexSubHeaderLength +
+ (last_glyph_index - first_glyph_index + 1 + 1) * DataSize::kUSHORT;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator class
+ ******************************************************************************/
+IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
+ IndexSubTableFormat3::Builder* container)
+ : RefIterator<BitmapGlyphInfo, IndexSubTableFormat3::Builder,
+ IndexSubTable::Builder>(container) {
+ glyph_id_ = container->first_glyph_index();
+}
+
+bool IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator::HasNext() {
+ if (glyph_id_ <= container()->last_glyph_index()) {
+ return true;
+ }
+ return false;
+}
+
+CALLER_ATTACH BitmapGlyphInfo*
+IndexSubTableFormat3::Builder::BitmapGlyphInfoIterator::Next() {
+ BitmapGlyphInfoPtr output;
+ if (!HasNext()) {
+ // Note: In C++, we do not throw exception when there's no element.
+ return NULL;
+ }
+ output = new BitmapGlyphInfo(glyph_id_,
+ container()->image_data_offset(),
+ container()->GlyphStartOffset(glyph_id_),
+ container()->GlyphLength(glyph_id_),
+ container()->image_format());
+ glyph_id_++;
+ return output.Detach();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format3.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format3.h
new file mode 100644
index 00000000000..d71f8573cc2
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format3.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT3_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT3_H_
+
+#include "sfntly/table/bitmap/index_sub_table.h"
+
+namespace sfntly {
+// Format 3 Index Subtable Entry.
+class IndexSubTableFormat3 : public IndexSubTable,
+ public RefCounted<IndexSubTableFormat3> {
+ public:
+ class Builder : public IndexSubTable::Builder,
+ public RefCounted<Builder> {
+ public:
+ class BitmapGlyphInfoIterator
+ : public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
+ public:
+ explicit BitmapGlyphInfoIterator(Builder* container);
+ virtual ~BitmapGlyphInfoIterator() {}
+
+ virtual bool HasNext();
+ CALLER_ATTACH virtual BitmapGlyphInfo* Next();
+
+ private:
+ int32_t glyph_id_;
+ };
+
+ virtual ~Builder();
+ virtual int32_t NumGlyphs();
+ virtual int32_t GlyphStartOffset(int32_t glyph_id);
+ virtual int32_t GlyphLength(int32_t glyph_id);
+ CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ void SetOffsetArray(const IntegerList& offset_array);
+
+ static CALLER_ATTACH Builder* CreateBuilder();
+ static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+
+ protected:
+ void Revert();
+
+ private:
+ Builder();
+ Builder(WritableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ Builder(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ IntegerList* GetOffsetArray();
+ void Initialize(ReadableFontData* data);
+
+ static int32_t DataLength(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+
+ IntegerList offset_array_;
+ };
+
+ virtual ~IndexSubTableFormat3();
+
+ virtual int32_t NumGlyphs();
+ virtual int32_t GlyphStartOffset(int32_t glyph_id);
+ virtual int32_t GlyphLength(int32_t glyph_id);
+
+ static int32_t GetDataLength(ReadableFontData* data,
+ int32_t offset,
+ int32_t first,
+ int32_t last);
+
+ private:
+ IndexSubTableFormat3(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ int32_t Loca(int32_t loca_index);
+
+ friend class Builder;
+};
+typedef Ptr<IndexSubTableFormat3> IndexSubTableFormat3Ptr;
+typedef Ptr<IndexSubTableFormat3::Builder> IndexSubTableFormat3BuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT3_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format4.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format4.cc
new file mode 100644
index 00000000000..5baa2a5e86c
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format4.cc
@@ -0,0 +1,384 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/index_sub_table_format4.h"
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * IndexSubTableFormat4 class
+ ******************************************************************************/
+IndexSubTableFormat4::~IndexSubTableFormat4() {
+}
+
+int32_t IndexSubTableFormat4::NumGlyphs() {
+ return IndexSubTableFormat4::NumGlyphs(data_, 0);
+}
+
+int32_t IndexSubTableFormat4::GlyphStartOffset(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return -1;
+ }
+ int32_t pair_index = FindCodeOffsetPair(glyph_id);
+ if (pair_index < 0) {
+ return -1;
+ }
+ return data_->ReadUShort(EblcTable::Offset::kIndexSubTable4_glyphArray +
+ pair_index *
+ EblcTable::Offset::kCodeOffsetPairLength +
+ EblcTable::Offset::kCodeOffsetPair_offset);
+}
+
+int32_t IndexSubTableFormat4::GlyphLength(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return -1;
+ }
+
+ int32_t pair_index = FindCodeOffsetPair(glyph_id);
+ if (pair_index < 0) {
+ return -1;
+ }
+ return data_->ReadUShort(
+ EblcTable::Offset::kIndexSubTable4_glyphArray +
+ (pair_index + 1) * EblcTable::Offset::kCodeOffsetPairLength +
+ EblcTable::Offset::kCodeOffsetPair_offset) -
+ data_->ReadUShort(
+ EblcTable::Offset::kIndexSubTable4_glyphArray +
+ (pair_index) * EblcTable::Offset::kCodeOffsetPairLength +
+ EblcTable::Offset::kCodeOffsetPair_offset);
+}
+
+IndexSubTableFormat4::IndexSubTableFormat4(ReadableFontData* data,
+ int32_t first,
+ int32_t last)
+ : IndexSubTable(data, first, last) {
+}
+
+int32_t IndexSubTableFormat4::FindCodeOffsetPair(int32_t glyph_id) {
+ return data_->SearchUShort(EblcTable::Offset::kIndexSubTable4_glyphArray,
+ EblcTable::Offset::kCodeOffsetPairLength,
+ NumGlyphs(),
+ glyph_id);
+}
+
+int32_t IndexSubTableFormat4::NumGlyphs(ReadableFontData* data,
+ int32_t table_offset) {
+ int32_t num_glyphs = data->ReadULongAsInt(table_offset +
+ EblcTable::Offset::kIndexSubTable4_numGlyphs);
+ return num_glyphs;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat4::CodeOffsetPair related class
+ ******************************************************************************/
+IndexSubTableFormat4::CodeOffsetPair::CodeOffsetPair(int32_t glyph_code,
+ int32_t offset)
+ : glyph_code_(glyph_code), offset_(offset) {
+}
+
+IndexSubTableFormat4::CodeOffsetPairBuilder::CodeOffsetPairBuilder()
+ : CodeOffsetPair(0, 0) {
+}
+
+IndexSubTableFormat4::CodeOffsetPairBuilder::CodeOffsetPairBuilder(
+ int32_t glyph_code, int32_t offset)
+ : CodeOffsetPair(glyph_code, offset) {
+}
+
+bool IndexSubTableFormat4::CodeOffsetPairGlyphCodeComparator::operator()(
+ const CodeOffsetPair& lhs, const CodeOffsetPair& rhs) {
+ return lhs.glyph_code() < rhs.glyph_code();
+}
+
+/******************************************************************************
+ * IndexSubTableFormat4::Builder class
+ ******************************************************************************/
+IndexSubTableFormat4::Builder::~Builder() {
+}
+
+int32_t IndexSubTableFormat4::Builder::NumGlyphs() {
+ return GetOffsetArray()->size() - 1;
+}
+
+int32_t IndexSubTableFormat4::Builder::GlyphLength(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return 0;
+ }
+ int32_t pair_index = FindCodeOffsetPair(glyph_id);
+ if (pair_index == -1) {
+ return 0;
+ }
+ return GetOffsetArray()->at(pair_index + 1).offset() -
+ GetOffsetArray()->at(pair_index).offset();
+}
+
+int32_t IndexSubTableFormat4::Builder::GlyphStartOffset(int32_t glyph_id) {
+ int32_t loca = CheckGlyphRange(glyph_id);
+ if (loca == -1) {
+ return -1;
+ }
+ int32_t pair_index = FindCodeOffsetPair(glyph_id);
+ if (pair_index == -1) {
+ return -1;
+ }
+ return GetOffsetArray()->at(pair_index).offset();
+}
+
+CALLER_ATTACH IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator*
+ IndexSubTableFormat4::Builder::GetIterator() {
+ Ptr<IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator> it =
+ new IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator(this);
+ return it.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat4::Builder*
+IndexSubTableFormat4::Builder::CreateBuilder() {
+ IndexSubTableFormat4BuilderPtr output = new IndexSubTableFormat4::Builder();
+ return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat4::Builder*
+IndexSubTableFormat4::Builder::CreateBuilder(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ int32_t length = Builder::DataLength(data,
+ index_sub_table_offset,
+ first_glyph_index,
+ last_glyph_index);
+ ReadableFontDataPtr new_data;
+ new_data.Attach(down_cast<ReadableFontData*>(
+ data->Slice(index_sub_table_offset, length)));
+ if (new_data == NULL) {
+ return NULL;
+ }
+ IndexSubTableFormat4BuilderPtr output =
+ new IndexSubTableFormat4::Builder(new_data,
+ first_glyph_index,
+ last_glyph_index);
+ return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat4::Builder*
+IndexSubTableFormat4::Builder::CreateBuilder(WritableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ int32_t length = Builder::DataLength(data,
+ index_sub_table_offset,
+ first_glyph_index,
+ last_glyph_index);
+ WritableFontDataPtr new_data;
+ new_data.Attach(down_cast<WritableFontData*>(
+ data->Slice(index_sub_table_offset, length)));
+ IndexSubTableFormat4BuilderPtr output =
+ new IndexSubTableFormat4::Builder(new_data,
+ first_glyph_index,
+ last_glyph_index);
+ return output.Detach();
+}
+
+CALLER_ATTACH FontDataTable* IndexSubTableFormat4::Builder::SubBuildTable(
+ ReadableFontData* data) {
+ IndexSubTableFormat4Ptr output = new IndexSubTableFormat4(
+ data, first_glyph_index(), last_glyph_index());
+ return output.Detach();
+}
+
+void IndexSubTableFormat4::Builder::SubDataSet() {
+ Revert();
+}
+
+int32_t IndexSubTableFormat4::Builder::SubDataSizeToSerialize() {
+ if (offset_pair_array_.empty()) {
+ return InternalReadData()->Length();
+ }
+ return EblcTable::Offset::kIndexSubHeaderLength + DataSize::kULONG +
+ GetOffsetArray()->size() *
+ EblcTable::Offset::kIndexSubTable4_codeOffsetPairLength;
+}
+
+bool IndexSubTableFormat4::Builder::SubReadyToSerialize() {
+ if (!offset_pair_array_.empty()) {
+ return true;
+ }
+ return false;
+}
+
+int32_t IndexSubTableFormat4::Builder::SubSerialize(
+ WritableFontData* new_data) {
+ int32_t size = SerializeIndexSubHeader(new_data);
+ if (!model_changed()) {
+ if (InternalReadData() == NULL) {
+ return size;
+ }
+ ReadableFontDataPtr source;
+ WritableFontDataPtr target;
+ source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
+ EblcTable::Offset::kIndexSubTable4_glyphArray)));
+ target.Attach(down_cast<WritableFontData*>(new_data->Slice(
+ EblcTable::Offset::kIndexSubTable4_glyphArray)));
+ size += source->CopyTo(target);
+ } else {
+ size += new_data->WriteLong(size, offset_pair_array_.size() - 1);
+ for (std::vector<CodeOffsetPairBuilder>::iterator
+ b = GetOffsetArray()->begin(), e = GetOffsetArray()->end();
+ b != e; b++) {
+ size += new_data->WriteUShort(size, b->glyph_code());
+ size += new_data->WriteUShort(size, b->offset());
+ }
+ }
+ return size;
+}
+
+void IndexSubTableFormat4::Builder::Revert() {
+ offset_pair_array_.clear();
+ IndexSubTable::Builder::Revert();
+}
+
+void IndexSubTableFormat4::Builder::SetOffsetArray(
+ const std::vector<CodeOffsetPairBuilder>& pair_array) {
+ offset_pair_array_.clear();
+ offset_pair_array_ = pair_array;
+ set_model_changed();
+}
+
+IndexSubTableFormat4::Builder::Builder()
+ : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable4_builderDataSize,
+ Format::FORMAT_4) {
+}
+
+IndexSubTableFormat4::Builder::Builder(WritableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IndexSubTableFormat4::Builder::Builder(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+std::vector<IndexSubTableFormat4::CodeOffsetPairBuilder>*
+IndexSubTableFormat4::Builder::GetOffsetArray() {
+ if (offset_pair_array_.empty()) {
+ Initialize(InternalReadData());
+ set_model_changed();
+ }
+ return &offset_pair_array_;
+}
+
+void IndexSubTableFormat4::Builder::Initialize(ReadableFontData* data) {
+ offset_pair_array_.clear();
+ if (data) {
+ int32_t num_pairs = IndexSubTableFormat4::NumGlyphs(data, 0) + 1;
+ int32_t offset = EblcTable::Offset::kIndexSubTable4_glyphArray;
+ for (int32_t i = 0; i < num_pairs; ++i) {
+ int32_t glyph_code = data->ReadUShort(offset +
+ EblcTable::Offset::kIndexSubTable4_codeOffsetPair_glyphCode);
+ int32_t glyph_offset = data->ReadUShort(offset +
+ EblcTable::Offset::kIndexSubTable4_codeOffsetPair_offset);
+ offset += EblcTable::Offset::kIndexSubTable4_codeOffsetPairLength;
+ CodeOffsetPairBuilder pair_builder(glyph_code, glyph_offset);
+ offset_pair_array_.push_back(pair_builder);
+ }
+ }
+}
+
+int32_t IndexSubTableFormat4::Builder::FindCodeOffsetPair(int32_t glyph_id) {
+ std::vector<CodeOffsetPairBuilder>* pair_list = GetOffsetArray();
+ int32_t location = 0;
+ int32_t bottom = 0;
+ int32_t top = pair_list->size();
+ while (top != bottom) {
+ location = (top + bottom) / 2;
+ CodeOffsetPairBuilder* pair = &(pair_list->at(location));
+ if (glyph_id < pair->glyph_code()) {
+ // location is below current location
+ top = location;
+ } else if (glyph_id > pair->glyph_code()) {
+ // location is above current location
+ bottom = location + 1;
+ } else {
+ return location;
+ }
+ }
+ return -1;
+}
+
+// static
+int32_t IndexSubTableFormat4::Builder::DataLength(
+ ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ int32_t num_glyphs = IndexSubTableFormat4::NumGlyphs(data,
+ index_sub_table_offset);
+ UNREFERENCED_PARAMETER(first_glyph_index);
+ UNREFERENCED_PARAMETER(last_glyph_index);
+ return EblcTable::Offset::kIndexSubTable4_glyphArray +
+ num_glyphs * EblcTable::Offset::kIndexSubTable4_codeOffsetPair_offset;
+}
+
+
+/******************************************************************************
+ * IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator class
+ ******************************************************************************/
+IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
+ IndexSubTableFormat4::Builder* container)
+ : RefIterator<BitmapGlyphInfo, IndexSubTableFormat4::Builder,
+ IndexSubTable::Builder>(container),
+ code_offset_pair_index_(0) {
+}
+
+bool IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator::HasNext() {
+ if (code_offset_pair_index_ <
+ (int32_t)(container()->GetOffsetArray()->size() - 1)) {
+ return true;
+ }
+ return false;
+}
+
+CALLER_ATTACH BitmapGlyphInfo*
+IndexSubTableFormat4::Builder::BitmapGlyphInfoIterator::Next() {
+ BitmapGlyphInfoPtr output;
+ if (!HasNext()) {
+ // Note: In C++, we do not throw exception when there's no element.
+ return NULL;
+ }
+ std::vector<CodeOffsetPairBuilder>* offset_array =
+ container()->GetOffsetArray();
+ int32_t offset = offset_array->at(code_offset_pair_index_).offset();
+ int32_t next_offset = offset_array->at(code_offset_pair_index_ + 1).offset();
+ int32_t glyph_code = offset_array->at(code_offset_pair_index_).glyph_code();
+ output = new BitmapGlyphInfo(glyph_code,
+ container()->image_data_offset(),
+ offset,
+ next_offset - offset,
+ container()->image_format());
+ code_offset_pair_index_++;
+ return output.Detach();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format4.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format4.h
new file mode 100644
index 00000000000..efd540f1781
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format4.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT4_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT4_H_
+
+#include "sfntly/table/bitmap/index_sub_table.h"
+
+namespace sfntly {
+
+class IndexSubTableFormat4 : public IndexSubTable,
+ public RefCounted<IndexSubTableFormat4> {
+ public:
+ class CodeOffsetPair {
+ public:
+ int32_t glyph_code() const { return glyph_code_; }
+ int32_t offset() const { return offset_; }
+
+ protected:
+ CodeOffsetPair(int32_t glyph_code, int32_t offset);
+
+ // TODO(arthurhsu): C++ style guide prohibits protected members.
+ int32_t glyph_code_;
+ int32_t offset_;
+ };
+
+ class CodeOffsetPairBuilder : public CodeOffsetPair {
+ public:
+ CodeOffsetPairBuilder();
+ CodeOffsetPairBuilder(int32_t glyph_code, int32_t offset);
+ void set_glyph_code(int32_t v) { glyph_code_ = v; }
+ void set_offset(int32_t v) { offset_ = v; }
+ };
+
+ class CodeOffsetPairGlyphCodeComparator {
+ public:
+ bool operator()(const CodeOffsetPair& lhs, const CodeOffsetPair& rhs);
+ };
+
+ class Builder : public IndexSubTable::Builder,
+ public RefCounted<Builder> {
+ public:
+ class BitmapGlyphInfoIterator
+ : public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
+ public:
+ explicit BitmapGlyphInfoIterator(Builder* container);
+ virtual ~BitmapGlyphInfoIterator() {}
+
+ virtual bool HasNext();
+ CALLER_ATTACH virtual BitmapGlyphInfo* Next();
+
+ private:
+ int32_t code_offset_pair_index_;
+ };
+
+ virtual ~Builder();
+ virtual int32_t NumGlyphs();
+ virtual int32_t GlyphLength(int32_t glyph_id);
+ virtual int32_t GlyphStartOffset(int32_t glyph_id);
+ CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ void Revert();
+ void SetOffsetArray(const std::vector<CodeOffsetPairBuilder>& pair_array);
+
+ static CALLER_ATTACH Builder* CreateBuilder();
+ static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ private:
+ Builder();
+ Builder(WritableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ Builder(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ std::vector<CodeOffsetPairBuilder>* GetOffsetArray();
+ void Initialize(ReadableFontData* data);
+ int32_t FindCodeOffsetPair(int32_t glyph_id);
+
+ static int32_t DataLength(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+
+ std::vector<CodeOffsetPairBuilder> offset_pair_array_;
+ };
+
+ virtual ~IndexSubTableFormat4();
+
+ virtual int32_t NumGlyphs();
+ virtual int32_t GlyphStartOffset(int32_t glyph_id);
+ virtual int32_t GlyphLength(int32_t glyph_id);
+
+ private:
+ IndexSubTableFormat4(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+
+ int32_t FindCodeOffsetPair(int32_t glyph_id);
+ static int32_t NumGlyphs(ReadableFontData* data, int32_t table_offset);
+
+ friend class Builder;
+};
+typedef Ptr<IndexSubTableFormat4> IndexSubTableFormat4Ptr;
+typedef Ptr<IndexSubTableFormat4::Builder> IndexSubTableFormat4BuilderPtr;
+typedef std::vector<IndexSubTableFormat4::CodeOffsetPairBuilder>
+ CodeOffsetPairBuilderList;
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT4_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc
new file mode 100644
index 00000000000..0ca21fef59a
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc
@@ -0,0 +1,347 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/index_sub_table_format5.h"
+
+#include <algorithm>
+
+#include "sfntly/table/bitmap/eblc_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * IndexSubTableFormat5 class
+ ******************************************************************************/
+IndexSubTableFormat5::~IndexSubTableFormat5() {
+}
+
+int32_t IndexSubTableFormat5::NumGlyphs() {
+ return NumGlyphs(data_, 0);
+}
+
+int32_t IndexSubTableFormat5::GlyphStartOffset(int32_t glyph_id) {
+ int32_t check = CheckGlyphRange(glyph_id);
+ if (check == -1) {
+ return -1;
+ }
+ int32_t loca = ReadFontData()->SearchUShort(
+ EblcTable::Offset::kIndexSubTable5_glyphArray,
+ DataSize::kUSHORT,
+ NumGlyphs(),
+ glyph_id);
+ if (loca == -1) {
+ return loca;
+ }
+ return loca * ImageSize();
+}
+
+int32_t IndexSubTableFormat5::GlyphLength(int32_t glyph_id) {
+ int32_t check = CheckGlyphRange(glyph_id);
+ if (check == -1) {
+ return 0;
+ }
+ return image_size_;
+}
+
+int32_t IndexSubTableFormat5::ImageSize() {
+ return data_->ReadULongAsInt(EblcTable::Offset::kIndexSubTable5_imageSize);
+}
+
+CALLER_ATTACH BigGlyphMetrics* IndexSubTableFormat5::BigMetrics() {
+ ReadableFontDataPtr data;
+ data.Attach(down_cast<ReadableFontData*>(data_->Slice(
+ EblcTable::Offset::kIndexSubTable5_bigGlyphMetrics,
+ BigGlyphMetrics::Offset::kMetricsLength)));
+ BigGlyphMetricsPtr output = new BigGlyphMetrics(data);
+ return output.Detach();
+}
+
+IndexSubTableFormat5::IndexSubTableFormat5(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : IndexSubTable(data, first_glyph_index, last_glyph_index) {
+ image_size_ = data_->ReadULongAsInt(
+ EblcTable::Offset::kIndexSubTable5_imageSize);
+}
+
+// static
+int32_t IndexSubTableFormat5::NumGlyphs(ReadableFontData* data,
+ int32_t table_offset) {
+ int32_t num_glyphs = data->ReadULongAsInt(table_offset +
+ EblcTable::Offset::kIndexSubTable5_numGlyphs);
+ return num_glyphs;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat5::Builder class
+ ******************************************************************************/
+IndexSubTableFormat5::Builder::~Builder() {
+}
+
+int32_t IndexSubTableFormat5::Builder::NumGlyphs() {
+ return GetGlyphArray()->size();
+}
+
+int32_t IndexSubTableFormat5::Builder::GlyphLength(int32_t glyph_id) {
+ UNREFERENCED_PARAMETER(glyph_id);
+ return ImageSize();
+}
+
+int32_t IndexSubTableFormat5::Builder::GlyphStartOffset(int32_t glyph_id) {
+ int32_t check = CheckGlyphRange(glyph_id);
+ if (check == -1) {
+ return -1;
+ }
+ IntegerList* glyph_array = GetGlyphArray();
+ IntegerList::iterator it = std::find(glyph_array->begin(),
+ glyph_array->end(),
+ glyph_id);
+ if (it == glyph_array->end()) {
+ return -1;
+ }
+ return (it - glyph_array->begin()) * ImageSize();
+}
+
+CALLER_ATTACH IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator*
+ IndexSubTableFormat5::Builder::GetIterator() {
+ Ptr<IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator> it =
+ new IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator(this);
+ return it.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat5::Builder*
+IndexSubTableFormat5::Builder::CreateBuilder() {
+ IndexSubTableFormat5BuilderPtr output = new IndexSubTableFormat5::Builder();
+ return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat5::Builder*
+IndexSubTableFormat5::Builder::CreateBuilder(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ int32_t length = Builder::DataLength(data,
+ index_sub_table_offset,
+ first_glyph_index,
+ last_glyph_index);
+ ReadableFontDataPtr new_data;
+ new_data.Attach(down_cast<ReadableFontData*>(
+ data->Slice(index_sub_table_offset, length)));
+ if (new_data == NULL) {
+ return NULL;
+ }
+ IndexSubTableFormat5BuilderPtr output =
+ new IndexSubTableFormat5::Builder(new_data,
+ first_glyph_index,
+ last_glyph_index);
+ return output.Detach();
+}
+
+// static
+CALLER_ATTACH IndexSubTableFormat5::Builder*
+IndexSubTableFormat5::Builder::CreateBuilder(WritableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ int32_t length = Builder::DataLength(data,
+ index_sub_table_offset,
+ first_glyph_index,
+ last_glyph_index);
+ WritableFontDataPtr new_data;
+ new_data.Attach(down_cast<WritableFontData*>(
+ data->Slice(index_sub_table_offset, length)));
+ IndexSubTableFormat5BuilderPtr output =
+ new IndexSubTableFormat5::Builder(new_data,
+ first_glyph_index,
+ last_glyph_index);
+ return output.Detach();
+}
+
+CALLER_ATTACH FontDataTable* IndexSubTableFormat5::Builder::SubBuildTable(
+ ReadableFontData* data) {
+ IndexSubTableFormat5Ptr output = new IndexSubTableFormat5(
+ data, first_glyph_index(), last_glyph_index());
+ return output.Detach();
+}
+
+void IndexSubTableFormat5::Builder::SubDataSet() {
+ Revert();
+}
+
+int32_t IndexSubTableFormat5::Builder::SubDataSizeToSerialize() {
+ if (glyph_array_.empty()) {
+ return InternalReadData()->Length();
+ }
+ return EblcTable::Offset::kIndexSubTable5_builderDataSize +
+ glyph_array_.size() * DataSize::kUSHORT;
+}
+
+bool IndexSubTableFormat5::Builder::SubReadyToSerialize() {
+ if (!glyph_array_.empty()) {
+ return true;
+ }
+ return false;
+}
+
+int32_t IndexSubTableFormat5::Builder::SubSerialize(
+ WritableFontData* new_data) {
+ int32_t size = SerializeIndexSubHeader(new_data);
+ if (!model_changed()) {
+ ReadableFontDataPtr source;
+ WritableFontDataPtr target;
+ source.Attach(down_cast<ReadableFontData*>(InternalReadData()->Slice(
+ EblcTable::Offset::kIndexSubTable5_imageSize)));
+ target.Attach(down_cast<WritableFontData*>(new_data->Slice(
+ EblcTable::Offset::kIndexSubTable5_imageSize)));
+ size += source->CopyTo(target);
+ } else {
+ size += new_data->WriteULong(EblcTable::Offset::kIndexSubTable5_imageSize,
+ ImageSize());
+ WritableFontDataPtr slice;
+ slice.Attach(down_cast<WritableFontData*>(new_data->Slice(size)));
+ size += BigMetrics()->SubSerialize(slice);
+ size += new_data->WriteULong(size, glyph_array_.size());
+ for (IntegerList::iterator b = glyph_array_.begin(), e = glyph_array_.end();
+ b != e; b++) {
+ size += new_data->WriteUShort(size, *b);
+ }
+ }
+ return size;
+}
+
+int32_t IndexSubTableFormat5::Builder::ImageSize() {
+ return InternalReadData()->ReadULongAsInt(
+ EblcTable::Offset::kIndexSubTable5_imageSize);
+}
+
+void IndexSubTableFormat5::Builder::SetImageSize(int32_t image_size) {
+ InternalWriteData()->WriteULong(
+ EblcTable::Offset::kIndexSubTable5_imageSize, image_size);
+}
+
+BigGlyphMetrics::Builder* IndexSubTableFormat5::Builder::BigMetrics() {
+ if (metrics_ == NULL) {
+ WritableFontDataPtr data;
+ data.Attach(down_cast<WritableFontData*>(InternalWriteData()->Slice(
+ EblcTable::Offset::kIndexSubTable5_bigGlyphMetrics,
+ BigGlyphMetrics::Offset::kMetricsLength)));
+ metrics_ = new BigGlyphMetrics::Builder(data);
+ set_model_changed();
+ }
+ return metrics_;
+}
+
+IntegerList* IndexSubTableFormat5::Builder::GlyphArray() {
+ return GetGlyphArray();
+}
+
+void IndexSubTableFormat5::Builder::SetGlyphArray(const IntegerList& v) {
+ glyph_array_.clear();
+ glyph_array_ = v;
+ set_model_changed();
+}
+
+void IndexSubTableFormat5::Builder::Revert() {
+ glyph_array_.clear();
+ IndexSubTable::Builder::Revert();
+}
+
+IndexSubTableFormat5::Builder::Builder()
+ : IndexSubTable::Builder(EblcTable::Offset::kIndexSubTable5_builderDataSize,
+ IndexSubTable::Format::FORMAT_5) {
+}
+
+IndexSubTableFormat5::Builder::Builder(WritableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IndexSubTableFormat5::Builder::Builder(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index)
+ : IndexSubTable::Builder(data, first_glyph_index, last_glyph_index) {
+}
+
+IntegerList* IndexSubTableFormat5::Builder::GetGlyphArray() {
+ if (glyph_array_.empty()) {
+ Initialize(InternalReadData());
+ set_model_changed();
+ }
+ return &glyph_array_;
+}
+
+void IndexSubTableFormat5::Builder::Initialize(ReadableFontData* data) {
+ glyph_array_.clear();
+ if (data) {
+ int32_t num_glyphs = IndexSubTableFormat5::NumGlyphs(data, 0);
+ for (int32_t i = 0; i < num_glyphs; ++i) {
+ glyph_array_.push_back(data->ReadUShort(
+ EblcTable::Offset::kIndexSubTable5_glyphArray +
+ i * DataSize::kUSHORT));
+ }
+ }
+}
+
+// static
+int32_t IndexSubTableFormat5::Builder::DataLength(
+ ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index) {
+ int32_t num_glyphs = IndexSubTableFormat5::NumGlyphs(data,
+ index_sub_table_offset);
+ UNREFERENCED_PARAMETER(first_glyph_index);
+ UNREFERENCED_PARAMETER(last_glyph_index);
+ return EblcTable::Offset::kIndexSubTable5_glyphArray +
+ num_glyphs * DataSize::kUSHORT;
+}
+
+/******************************************************************************
+ * IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator class
+ ******************************************************************************/
+IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator::BitmapGlyphInfoIterator(
+ IndexSubTableFormat5::Builder* container)
+ : RefIterator<BitmapGlyphInfo, IndexSubTableFormat5::Builder,
+ IndexSubTable::Builder>(container),
+ offset_index_(0) {
+}
+
+bool IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator::HasNext() {
+ if (offset_index_ < (int32_t)(container()->GetGlyphArray()->size())) {
+ return true;
+ }
+ return false;
+}
+
+CALLER_ATTACH BitmapGlyphInfo*
+IndexSubTableFormat5::Builder::BitmapGlyphInfoIterator::Next() {
+ BitmapGlyphInfoPtr output;
+ if (!HasNext()) {
+ // Note: In C++, we do not throw exception when there's no element.
+ return NULL;
+ }
+ output = new BitmapGlyphInfo(container()->GetGlyphArray()->at(offset_index_),
+ container()->image_data_offset(),
+ offset_index_ * container()->ImageSize(),
+ container()->ImageSize(),
+ container()->image_format());
+ offset_index_++;
+ return output.Detach();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format5.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format5.h
new file mode 100644
index 00000000000..a39e88cacaa
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/index_sub_table_format5.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT5_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT5_H_
+
+#include "sfntly/table/bitmap/big_glyph_metrics.h"
+#include "sfntly/table/bitmap/index_sub_table.h"
+
+namespace sfntly {
+
+class IndexSubTableFormat5 : public IndexSubTable,
+ public RefCounted<IndexSubTableFormat5> {
+ public:
+ class Builder : public IndexSubTable::Builder,
+ public RefCounted<Builder> {
+ public:
+ class BitmapGlyphInfoIterator
+ : public RefIterator<BitmapGlyphInfo, Builder, IndexSubTable::Builder> {
+ public:
+ explicit BitmapGlyphInfoIterator(Builder* container);
+ virtual ~BitmapGlyphInfoIterator() {}
+
+ virtual bool HasNext();
+ CALLER_ATTACH virtual BitmapGlyphInfo* Next();
+
+ private:
+ int32_t offset_index_;
+ };
+ virtual ~Builder();
+ virtual int32_t NumGlyphs();
+ virtual int32_t GlyphLength(int32_t glyph_id);
+ virtual int32_t GlyphStartOffset(int32_t glyph_id);
+ CALLER_ATTACH virtual BitmapGlyphInfoIterator* GetIterator();
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ int32_t ImageSize();
+ void SetImageSize(int32_t image_size);
+ BigGlyphMetrics::Builder* BigMetrics();
+ IntegerList* GlyphArray();
+ void SetGlyphArray(const IntegerList& v);
+
+ static CALLER_ATTACH Builder* CreateBuilder();
+ static CALLER_ATTACH Builder* CreateBuilder(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ static CALLER_ATTACH Builder* CreateBuilder(WritableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ protected:
+ void Revert();
+
+ private:
+ Builder();
+ Builder(WritableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+ Builder(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+
+ IntegerList* GetGlyphArray();
+ void Initialize(ReadableFontData* data);
+
+ static int32_t DataLength(ReadableFontData* data,
+ int32_t index_sub_table_offset,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+
+ IntegerList glyph_array_;
+ BigGlyphMetricsBuilderPtr metrics_;
+ };
+ virtual ~IndexSubTableFormat5();
+
+ virtual int32_t NumGlyphs();
+ virtual int32_t GlyphStartOffset(int32_t glyph_id);
+ virtual int32_t GlyphLength(int32_t glyph_id);
+
+ int32_t ImageSize();
+ CALLER_ATTACH BigGlyphMetrics* BigMetrics();
+
+ private:
+ IndexSubTableFormat5(ReadableFontData* data,
+ int32_t first_glyph_index,
+ int32_t last_glyph_index);
+
+ static int32_t NumGlyphs(ReadableFontData* dta, int32_t table_offset);
+
+ int32_t image_size_;
+
+ friend class Builder;
+};
+typedef Ptr<IndexSubTableFormat5> IndexSubTableFormat5Ptr;
+typedef Ptr<IndexSubTableFormat5::Builder> IndexSubTableFormat5BuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_INDEX_SUBTABLE_FORMAT5_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/simple_bitmap_glyph.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/simple_bitmap_glyph.cc
new file mode 100644
index 00000000000..87031a142be
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/simple_bitmap_glyph.cc
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 = the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/simple_bitmap_glyph.h"
+
+namespace sfntly {
+
+SimpleBitmapGlyph::SimpleBitmapGlyph(ReadableFontData* data, int32_t format)
+ : BitmapGlyph(data, format) {
+}
+
+SimpleBitmapGlyph::~SimpleBitmapGlyph() {
+}
+
+SimpleBitmapGlyph::Builder::Builder(ReadableFontData* data, int32_t format)
+ : BitmapGlyph::Builder(data, format) {
+}
+
+SimpleBitmapGlyph::Builder::Builder(WritableFontData* data, int32_t format)
+ : BitmapGlyph::Builder(data, format) {
+}
+
+SimpleBitmapGlyph::Builder::~Builder() {
+}
+
+CALLER_ATTACH FontDataTable*
+SimpleBitmapGlyph::Builder::SubBuildTable(ReadableFontData* data) {
+ Ptr<SimpleBitmapGlyph> glyph = new SimpleBitmapGlyph(data, format());
+ return glyph.Detach();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/simple_bitmap_glyph.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/simple_bitmap_glyph.h
new file mode 100644
index 00000000000..56ede10538b
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/simple_bitmap_glyph.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 = the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SIMPLE_BITMAP_GLYPH_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SIMPLE_BITMAP_GLYPH_H_
+
+#include "sfntly/table/bitmap/bitmap_glyph.h"
+
+namespace sfntly {
+
+class SimpleBitmapGlyph : public BitmapGlyph,
+ public RefCounted<SimpleBitmapGlyph> {
+ public:
+ class Builder : public BitmapGlyph::Builder,
+ public RefCounted<Builder> {
+ public:
+ Builder(WritableFontData* data, int32_t format);
+ Builder(ReadableFontData* data, int32_t format);
+ virtual ~Builder();
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ };
+
+ SimpleBitmapGlyph(ReadableFontData* data, int32_t format);
+ virtual ~SimpleBitmapGlyph();
+};
+typedef Ptr<SimpleBitmapGlyph> SimpleBitmapGlyphPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SIMPLE_BITMAP_GLYPH_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc
new file mode 100644
index 00000000000..0f3c1e91d63
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/bitmap/small_glyph_metrics.h"
+
+namespace sfntly {
+/******************************************************************************
+ * SmallGlyphMetrics class
+ ******************************************************************************/
+SmallGlyphMetrics::SmallGlyphMetrics(ReadableFontData* data)
+ : GlyphMetrics(data) {
+}
+
+SmallGlyphMetrics::~SmallGlyphMetrics() {
+}
+
+int32_t SmallGlyphMetrics::Height() {
+ return data_->ReadByte(Offset::kHeight);
+}
+
+int32_t SmallGlyphMetrics::Width() {
+ return data_->ReadByte(Offset::kWidth);
+}
+
+int32_t SmallGlyphMetrics::BearingX() {
+ return data_->ReadByte(Offset::kBearingX);
+}
+
+int32_t SmallGlyphMetrics::BearingY() {
+ return data_->ReadByte(Offset::kBearingY);
+}
+
+int32_t SmallGlyphMetrics::Advance() {
+ return data_->ReadByte(Offset::kAdvance);
+}
+
+/******************************************************************************
+ * SmallGlyphMetrics::Builder class
+ ******************************************************************************/
+SmallGlyphMetrics::Builder::Builder(WritableFontData* data)
+ : GlyphMetrics::Builder(data) {
+}
+
+SmallGlyphMetrics::Builder::Builder(ReadableFontData* data)
+ : GlyphMetrics::Builder(data) {
+}
+
+SmallGlyphMetrics::Builder::~Builder() {
+}
+
+int32_t SmallGlyphMetrics::Builder::Height() {
+ return InternalReadData()->ReadByte(Offset::kHeight);
+}
+
+void SmallGlyphMetrics::Builder::SetHeight(byte_t height) {
+ InternalWriteData()->WriteByte(Offset::kHeight, height);
+}
+
+int32_t SmallGlyphMetrics::Builder::Width() {
+ return InternalReadData()->ReadByte(Offset::kWidth);
+}
+
+void SmallGlyphMetrics::Builder::SetWidth(byte_t width) {
+ InternalWriteData()->WriteByte(Offset::kWidth, width);
+}
+
+int32_t SmallGlyphMetrics::Builder::BearingX() {
+ return InternalReadData()->ReadByte(Offset::kBearingX);
+}
+
+void SmallGlyphMetrics::Builder::SetBearingX(byte_t bearing) {
+ InternalWriteData()->WriteByte(Offset::kBearingX, bearing);
+}
+
+int32_t SmallGlyphMetrics::Builder::BearingY() {
+ return InternalReadData()->ReadByte(Offset::kBearingY);
+}
+
+void SmallGlyphMetrics::Builder::SetBearingY(byte_t bearing) {
+ InternalWriteData()->WriteByte(Offset::kBearingY, bearing);
+}
+
+int32_t SmallGlyphMetrics::Builder::Advance() {
+ return InternalReadData()->ReadByte(Offset::kAdvance);
+}
+
+void SmallGlyphMetrics::Builder::SetAdvance(byte_t advance) {
+ InternalWriteData()->WriteByte(Offset::kAdvance, advance);
+}
+
+CALLER_ATTACH FontDataTable*
+ SmallGlyphMetrics::Builder::SubBuildTable(ReadableFontData* data) {
+ SmallGlyphMetricsPtr output = new SmallGlyphMetrics(data);
+ return output.Detach();
+}
+
+void SmallGlyphMetrics::Builder::SubDataSet() {
+ // NOP.
+}
+
+int32_t SmallGlyphMetrics::Builder::SubDataSizeToSerialize() {
+ return 0;
+}
+
+bool SmallGlyphMetrics::Builder::SubReadyToSerialize() {
+ return false;
+}
+
+int32_t SmallGlyphMetrics::Builder::SubSerialize(WritableFontData* new_data) {
+ return Data()->CopyTo(new_data);
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/small_glyph_metrics.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/small_glyph_metrics.h
new file mode 100644
index 00000000000..ea13720d8f2
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/bitmap/small_glyph_metrics.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SMALL_GLYPH_METRICS_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SMALL_GLYPH_METRICS_H_
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/table/bitmap/glyph_metrics.h"
+
+namespace sfntly {
+
+class SmallGlyphMetrics : public GlyphMetrics,
+ public RefCounted<SmallGlyphMetrics> {
+ public:
+ struct Offset {
+ enum {
+ kMetricsLength = 5,
+ kHeight = 0,
+ kWidth = 1,
+ kBearingX = 2,
+ kBearingY = 3,
+ kAdvance = 4,
+ };
+ };
+
+ class Builder : public GlyphMetrics::Builder,
+ public RefCounted<Builder> {
+ public:
+ // Constructor scope altered to public because C++ does not allow base
+ // class to instantiate derived class with protected constructors.
+ explicit Builder(WritableFontData* data);
+ explicit Builder(ReadableFontData* data);
+ virtual ~Builder();
+
+ int32_t Height();
+ void SetHeight(byte_t height);
+ int32_t Width();
+ void SetWidth(byte_t width);
+ int32_t BearingX();
+ void SetBearingX(byte_t bearing);
+ int32_t BearingY();
+ void SetBearingY(byte_t bearing);
+ int32_t Advance();
+ void SetAdvance(byte_t advance);
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+ };
+
+ explicit SmallGlyphMetrics(ReadableFontData* data);
+ virtual ~SmallGlyphMetrics();
+
+ int32_t Height();
+ int32_t Width();
+ int32_t BearingX();
+ int32_t BearingY();
+ int32_t Advance();
+};
+typedef Ptr<SmallGlyphMetrics> SmallGlyphMetricsPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BITMAP_SMALL_GLYPH_METRICS_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/byte_array_table_builder.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/byte_array_table_builder.cc
new file mode 100644
index 00000000000..631a05fdd68
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/byte_array_table_builder.cc
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/byte_array_table_builder.h"
+
+namespace sfntly {
+
+ByteArrayTableBuilder::~ByteArrayTableBuilder() {}
+
+int32_t ByteArrayTableBuilder::ByteValue(int32_t index) {
+ ReadableFontDataPtr data = InternalReadData();
+ if (data == NULL) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("No font data for the table");
+#endif
+ return -1;
+ }
+ return data->ReadByte(index);
+}
+
+void ByteArrayTableBuilder::SetByteValue(int32_t index, byte_t b) {
+ WritableFontDataPtr data = InternalWriteData();
+ if (data == NULL) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("No font data for the table");
+#endif
+ return;
+ }
+ data->WriteByte(index, b);
+}
+
+int32_t ByteArrayTableBuilder::ByteCount() {
+ ReadableFontDataPtr data = InternalReadData();
+ if (data == NULL) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("No font data for the table");
+#endif
+ return 0;
+ }
+ return data->Length();
+}
+
+ByteArrayTableBuilder::ByteArrayTableBuilder(Header* header,
+ WritableFontData* data)
+ : TableBasedTableBuilder(header, data) {
+}
+
+ByteArrayTableBuilder::ByteArrayTableBuilder(Header* header,
+ ReadableFontData* data)
+ : TableBasedTableBuilder(header, data) {
+}
+
+ByteArrayTableBuilder::ByteArrayTableBuilder(Header* header)
+ : TableBasedTableBuilder(header) {
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/byte_array_table_builder.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/byte_array_table_builder.h
new file mode 100644
index 00000000000..42d27a8df00
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/byte_array_table_builder.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_BYTE_ARRAY_TABLE_BUILDER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_BYTE_ARRAY_TABLE_BUILDER_H_
+
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+// An abstract builder base for byte array based tables.
+class ByteArrayTableBuilder : public TableBasedTableBuilder {
+ public:
+ virtual ~ByteArrayTableBuilder();
+
+ // Get the byte value at the specified index. The index is relative to the
+ // start of the table.
+ // @param index index relative to the start of the table
+ // @return byte value at the given index
+ virtual int32_t ByteValue(int32_t index);
+
+ // Set the byte value at the specified index. The index is relative to the
+ // start of the table.
+ // @param index index relative to the start of the table
+ // @param b byte value to set
+ virtual void SetByteValue(int32_t index, byte_t b);
+
+ // Get the number of bytes set for this table. It may include padding bytes at
+ // the end.
+ virtual int32_t ByteCount();
+
+ protected:
+ ByteArrayTableBuilder(Header* header, WritableFontData* data);
+ ByteArrayTableBuilder(Header* header, ReadableFontData* data);
+ explicit ByteArrayTableBuilder(Header* header);
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BYTE_ARRAY_TABLE_BUILDER_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/cmap_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/cmap_table.cc
new file mode 100644
index 00000000000..1c83d2e7d0e
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/cmap_table.cc
@@ -0,0 +1,1287 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// type.h needs to be included first because of building issues on Windows
+// Type aliases we delcare are defined in other headers and make the build
+// fail otherwise.
+#include "sfntly/port/type.h"
+#include "sfntly/table/core/cmap_table.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <utility>
+
+#include "sfntly/font.h"
+#include "sfntly/math/font_math.h"
+#include "sfntly/port/endian.h"
+#include "sfntly/port/exception_type.h"
+#include "sfntly/table/core/name_table.h"
+
+namespace sfntly {
+
+const int32_t CMapTable::NOTDEF = 0;
+
+CMapTable::CMapId CMapTable::WINDOWS_BMP = {
+ PlatformId::kWindows,
+ WindowsEncodingId::kUnicodeUCS2
+};
+CMapTable::CMapId CMapTable::WINDOWS_UCS4 = {
+ PlatformId::kWindows,
+ WindowsEncodingId::kUnicodeUCS4
+};
+CMapTable::CMapId CMapTable::MAC_ROMAN = {
+ PlatformId::kWindows,
+ MacintoshEncodingId::kRoman
+};
+
+/******************************************************************************
+ * CMapTable class
+ ******************************************************************************/
+CMapTable::CMapTable(Header* header, ReadableFontData* data)
+ : SubTableContainerTable(header, data) {
+}
+
+CMapTable::~CMapTable() {}
+
+CALLER_ATTACH CMapTable::CMap* CMapTable::GetCMap(const int32_t index) {
+ if (index < 0 || index > NumCMaps()) {
+#ifndef SFNTLY_NO_EXCEPTION
+ throw IndexOutOfBoundException("Requested CMap index is out of bounds.");
+#else
+ return NULL;
+#endif
+ }
+ int32_t platform_id = PlatformId(index);
+ int32_t encoding_id = EncodingId(index);
+ CMapId cmap_id = NewCMapId(platform_id, encoding_id);
+ int32_t offset_ = Offset(index);
+ Ptr<FontDataTable::Builder> cmap_builder =
+ (CMap::Builder::GetBuilder(data_, offset_, cmap_id));
+ if (!cmap_builder) {
+#ifndef SFNTLY_NO_EXCEPTION
+ throw NoSuchElementException("Cannot find builder for requested CMap.");
+#else
+ return NULL;
+#endif
+ }
+ return down_cast<CMapTable::CMap*>(cmap_builder->Build());
+}
+
+CALLER_ATTACH CMapTable::CMap* CMapTable::GetCMap(const int32_t platform_id,
+ const int32_t encoding_id) {
+ return GetCMap(NewCMapId(platform_id, encoding_id));
+}
+
+CALLER_ATTACH CMapTable::CMap*
+CMapTable::GetCMap(const CMapTable::CMapId cmap_id) {
+ CMapIdFilter id_filter(cmap_id);
+ CMapIterator cmap_iterator(this, &id_filter);
+ // There can only be one cmap with a particular CMapId
+ if (cmap_iterator.HasNext()) {
+ Ptr<CMapTable::CMap> cmap;
+ cmap.Attach(cmap_iterator.Next());
+ return cmap.Detach();
+ }
+#ifndef SFNTLY_NO_EXCEPTION
+ throw NoSuchElementException();
+#else
+ return NULL;
+#endif
+}
+
+int32_t CMapTable::Version() {
+ return data_->ReadUShort(Offset::kVersion);
+}
+
+int32_t CMapTable::NumCMaps() {
+ return data_->ReadUShort(Offset::kNumTables);
+}
+
+CMapTable::CMapId CMapTable::GetCMapId(int32_t index) {
+ return NewCMapId(PlatformId(index), EncodingId(index));
+}
+
+int32_t CMapTable::PlatformId(int32_t index) {
+ return data_->ReadUShort(Offset::kEncodingRecordPlatformId +
+ OffsetForEncodingRecord(index));
+}
+
+int32_t CMapTable::EncodingId(int32_t index) {
+ return data_->ReadUShort(Offset::kEncodingRecordEncodingId +
+ OffsetForEncodingRecord(index));
+}
+
+int32_t CMapTable::Offset(int32_t index) {
+ return data_->ReadULongAsInt(Offset::kEncodingRecordOffset +
+ OffsetForEncodingRecord(index));
+}
+
+int32_t CMapTable::OffsetForEncodingRecord(int32_t index) {
+ return Offset::kEncodingRecordStart + index * Offset::kEncodingRecordSize;
+}
+
+CMapTable::CMapId CMapTable::NewCMapId(int32_t platform_id,
+ int32_t encoding_id) {
+ CMapId result;
+ result.platform_id = platform_id;
+ result.encoding_id = encoding_id;
+ return result;
+}
+
+CMapTable::CMapId CMapTable::NewCMapId(const CMapId& obj) {
+ CMapId result;
+ result.platform_id = obj.platform_id;
+ result.encoding_id = obj.encoding_id;
+ return result;
+}
+
+/******************************************************************************
+ * CMapTable::CMapIterator class
+ ******************************************************************************/
+CMapTable::CMapIterator::CMapIterator(CMapTable* table,
+ const CMapFilter* filter)
+ : table_index_(0), filter_(filter), table_(table) {
+}
+
+bool CMapTable::CMapIterator::HasNext() {
+ if (!filter_) {
+ if (table_index_ < table_->NumCMaps()) {
+ return true;
+ }
+ return false;
+ }
+
+ for (; table_index_ < table_->NumCMaps(); ++table_index_) {
+ if (filter_->accept(table_->GetCMapId(table_index_))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+CALLER_ATTACH CMapTable::CMap* CMapTable::CMapIterator::Next() {
+ if (!HasNext()) {
+#ifndef SFNTLY_NO_EXCEPTION
+ throw NoSuchElementException();
+#else
+ return NULL;
+#endif
+ }
+ CMapPtr next_cmap;
+ next_cmap.Attach(table_->GetCMap(table_index_++));
+ if (next_cmap == NULL) {
+#ifndef SFNTLY_NO_EXCEPTION
+ throw NoSuchElementException("Error during the creation of the CMap");
+#else
+ return NULL;
+#endif
+ }
+ return next_cmap.Detach();
+}
+
+/******************************************************************************
+ * CMapTable::CMapId class
+ ******************************************************************************/
+
+/******************************************************************************
+ * CMapTable::CMapIdComparator class
+ ******************************************************************************/
+
+bool CMapTable::CMapIdComparator::operator()(const CMapId& lhs,
+ const CMapId& rhs) const {
+ return ((lhs.platform_id << 8 | lhs.encoding_id) >
+ (rhs.platform_id << 8 | rhs.encoding_id));
+}
+
+/******************************************************************************
+ * CMapTable::CMapIdFilter class
+ ******************************************************************************/
+CMapTable::CMapIdFilter::CMapIdFilter(const CMapId wanted_id)
+ : wanted_id_(wanted_id),
+ comparator_(NULL) {
+}
+
+CMapTable::CMapIdFilter::CMapIdFilter(const CMapId wanted_id,
+ const CMapIdComparator* comparator)
+ : wanted_id_(wanted_id),
+ comparator_(comparator) {
+}
+
+bool CMapTable::CMapIdFilter::accept(const CMapId& cmap_id) const {
+ if (!comparator_)
+ return wanted_id_ == cmap_id;
+ return (*comparator_)(wanted_id_, cmap_id);
+}
+
+/******************************************************************************
+ * CMapTable::CMap class
+ ******************************************************************************/
+CMapTable::CMap::CMap(ReadableFontData* data, int32_t format,
+ const CMapId& cmap_id)
+ : SubTable(data), format_(format), cmap_id_(cmap_id) {
+}
+
+CMapTable::CMap::~CMap() {
+}
+
+/******************************************************************************
+ * CMapTable::CMap::Builder class
+ ******************************************************************************/
+CMapTable::CMap::Builder::~Builder() {
+}
+
+CALLER_ATTACH CMapTable::CMap::Builder*
+ CMapTable::CMap::Builder::GetBuilder(ReadableFontData* data, int32_t offset,
+ const CMapId& cmap_id) {
+ // NOT IMPLEMENTED: Java enum value validation
+ int32_t format = data->ReadUShort(offset);
+ CMapBuilderPtr builder;
+ switch (format) {
+ case CMapFormat::kFormat0:
+ builder.Attach(CMapFormat0::Builder::NewInstance(data, offset, cmap_id));
+ break;
+ case CMapFormat::kFormat2:
+#if defined (SFNTLY_DEBUG_CMAP)
+ fprintf(stderr, "Requesting Format2 builder, but it's unsupported; "
+ "returning NULL\n");
+#endif
+ break;
+ case CMapFormat::kFormat4:
+ builder.Attach(CMapFormat4::Builder::NewInstance(data, offset, cmap_id));
+ break;
+ default:
+#ifdef SFNTLY_DEBUG_CMAP
+ fprintf(stderr, "Unknown builder format requested\n");
+#endif
+ break;
+ }
+ return builder.Detach();
+}
+
+CALLER_ATTACH CMapTable::CMap::Builder*
+CMapTable::CMap::Builder::GetBuilder(int32_t format, const CMapId& cmap_id) {
+ Ptr<CMapTable::CMap::Builder> builder;
+ switch (format) {
+ case CMapFormat::kFormat0:
+ builder.Attach(CMapFormat0::Builder::NewInstance(cmap_id));
+ break;
+ case CMapFormat::kFormat2:
+#if defined (SFNTLY_DEBUG_CMAP)
+ fprintf(stderr, "Requesting Format2 builder, but it's unsupported; "
+ "returning NULL\n");
+#endif
+ break;
+ case CMapFormat::kFormat4:
+ builder.Attach(CMapFormat4::Builder::NewInstance(cmap_id));
+ break;
+ default:
+#ifdef SFNTLY_DEBUG_CMAP
+ fprintf(stderr, "Unknown builder format requested\n");
+#endif
+ break;
+ }
+ return builder.Detach();
+}
+
+CMapTable::CMap::Builder::Builder(ReadableFontData* data,
+ int32_t format,
+ const CMapId& cmap_id)
+ : SubTable::Builder(data),
+ format_(format),
+ cmap_id_(cmap_id),
+ language_(0) {
+}
+
+CMapTable::CMap::Builder::Builder(WritableFontData* data,
+ int32_t format,
+ const CMapId& cmap_id)
+ : SubTable::Builder(data),
+ format_(format),
+ cmap_id_(cmap_id),
+ language_(0) {
+}
+
+int32_t CMapTable::CMap::Builder::SubSerialize(WritableFontData* new_data) {
+ return InternalReadData()->CopyTo(new_data);
+}
+
+bool CMapTable::CMap::Builder::SubReadyToSerialize() {
+ return true;
+}
+
+int32_t CMapTable::CMap::Builder::SubDataSizeToSerialize() {
+ ReadableFontDataPtr read_data = InternalReadData();
+ if (!read_data)
+ return 0;
+ return read_data->Length();
+}
+
+void CMapTable::CMap::Builder::SubDataSet() {
+ // NOP
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat0
+ ******************************************************************************/
+CMapTable::CMapFormat0::~CMapFormat0() {
+}
+
+int32_t CMapTable::CMapFormat0::Language() {
+ return 0;
+}
+
+int32_t CMapTable::CMapFormat0::GlyphId(int32_t character) {
+ if (character < 0 || character > 255) {
+ return CMapTable::NOTDEF;
+ }
+ return data_->ReadUByte(character + Offset::kFormat0GlyphIdArray);
+}
+
+CMapTable::CMapFormat0::CMapFormat0(ReadableFontData* data,
+ const CMapId& cmap_id)
+ : CMap(data, CMapFormat::kFormat0, cmap_id) {
+}
+
+CMapTable::CMap::CharacterIterator* CMapTable::CMapFormat0::Iterator() {
+ return new CMapTable::CMapFormat0::CharacterIterator(0, 0xff);
+}
+
+
+/******************************************************************************
+ * CMapTable::CMapFormat0::CharacterIterator
+ ******************************************************************************/
+CMapTable::CMapFormat0::CharacterIterator::CharacterIterator(int32_t start,
+ int32_t end)
+ : character_(start),
+ max_character_(end) {
+}
+
+CMapTable::CMapFormat0::CharacterIterator::~CharacterIterator() {}
+
+bool CMapTable::CMapFormat0::CharacterIterator::HasNext() {
+ return character_ < max_character_;
+}
+
+int32_t CMapTable::CMapFormat0::CharacterIterator::Next() {
+ if (HasNext())
+ return character_++;
+#ifndef SFNTLY_NO_EXCEPTION
+ throw NoSuchElementException("No more characters to iterate.");
+#endif
+ return -1;
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat0::Builder
+ ******************************************************************************/
+// static
+CALLER_ATTACH CMapTable::CMapFormat0::Builder*
+CMapTable::CMapFormat0::Builder::NewInstance(WritableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id) {
+ WritableFontDataPtr wdata;
+ if (data) {
+ wdata.Attach(down_cast<WritableFontData*>(
+ data->Slice(offset,
+ data->ReadUShort(offset + Offset::kFormat0Length))));
+ }
+ return new Builder(wdata, CMapFormat::kFormat0, cmap_id);
+}
+
+// static
+CALLER_ATTACH CMapTable::CMapFormat0::Builder*
+CMapTable::CMapFormat0::Builder::NewInstance(ReadableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id) {
+ ReadableFontDataPtr rdata;
+ if (data) {
+ rdata.Attach(down_cast<ReadableFontData*>(
+ data->Slice(offset,
+ data->ReadUShort(offset + Offset::kFormat0Length))));
+ }
+ return new Builder(rdata, CMapFormat::kFormat0, cmap_id);
+}
+
+// static
+CALLER_ATTACH CMapTable::CMapFormat0::Builder*
+CMapTable::CMapFormat0::Builder::NewInstance(const CMapId& cmap_id) {
+ return new Builder(cmap_id);
+}
+
+// Always call NewInstance instead of the constructor for creating a new builder
+// object! This refactoring avoids memory leaks when slicing the font data.
+CMapTable::CMapFormat0::Builder::Builder(WritableFontData* data, int32_t offset,
+ const CMapId& cmap_id)
+ : CMapTable::CMap::Builder(data, CMapFormat::kFormat0, cmap_id) {
+ UNREFERENCED_PARAMETER(offset);
+}
+
+CMapTable::CMapFormat0::Builder::Builder(
+ ReadableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id)
+ : CMapTable::CMap::Builder(data, CMapFormat::kFormat0, cmap_id) {
+ UNREFERENCED_PARAMETER(offset);
+}
+
+CMapTable::CMapFormat0::Builder::Builder(const CMapId& cmap_id)
+ : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL),
+ CMapFormat::kFormat0,
+ cmap_id) {
+}
+
+CMapTable::CMapFormat0::Builder::~Builder() {
+}
+
+CALLER_ATTACH FontDataTable*
+ CMapTable::CMapFormat0::Builder::SubBuildTable(ReadableFontData* data) {
+ FontDataTablePtr table = new CMapFormat0(data, cmap_id());
+ return table.Detach();
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat2
+ ******************************************************************************/
+CMapTable::CMapFormat2::~CMapFormat2() {
+}
+
+int32_t CMapTable::CMapFormat2::Language() {
+ return 0;
+}
+
+int32_t CMapTable::CMapFormat2::GlyphId(int32_t character) {
+ if (character > 0xffff) {
+ return CMapTable::NOTDEF;
+ }
+
+ uint32_t c = ToBE32(character);
+ byte_t high_byte = (c >> 8) & 0xff;
+ byte_t low_byte = c & 0xff;
+ int32_t offset = SubHeaderOffset(high_byte);
+
+ if (offset == 0) {
+ low_byte = high_byte;
+ high_byte = 0;
+ }
+
+ int32_t first_code = FirstCode(high_byte);
+ int32_t entry_count = EntryCount(high_byte);
+
+ if (low_byte < first_code || low_byte >= first_code + entry_count) {
+ return CMapTable::NOTDEF;
+ }
+
+ int32_t id_range_offset = IdRangeOffset(high_byte);
+
+ // position of idRangeOffset + value of idRangeOffset + index for low byte
+ // = firstcode
+ int32_t p_location = (offset + Offset::kFormat2SubHeader_idRangeOffset) +
+ id_range_offset +
+ (low_byte - first_code) * DataSize::kUSHORT;
+ int p = data_->ReadUShort(p_location);
+ if (p == 0) {
+ return CMapTable::NOTDEF;
+ }
+
+ if (offset == 0) {
+ return p;
+ }
+ int id_delta = IdDelta(high_byte);
+ return (p + id_delta) % 65536;
+}
+
+int32_t CMapTable::CMapFormat2::BytesConsumed(int32_t character) {
+ uint32_t c = ToBE32(character);
+ int32_t high_byte = (c >> 8) & 0xff;
+ int32_t offset = SubHeaderOffset(high_byte);
+ return (offset == 0) ? 1 : 2;
+}
+
+CMapTable::CMapFormat2::CMapFormat2(ReadableFontData* data,
+ const CMapId& cmap_id)
+ : CMap(data, CMapFormat::kFormat2, cmap_id) {
+}
+
+int32_t CMapTable::CMapFormat2::SubHeaderOffset(int32_t sub_header_index) {
+ return data_->ReadUShort(Offset::kFormat2SubHeaderKeys +
+ sub_header_index * DataSize::kUSHORT);
+}
+
+int32_t CMapTable::CMapFormat2::FirstCode(int32_t sub_header_index) {
+ int32_t sub_header_offset = SubHeaderOffset(sub_header_index);
+ return data_->ReadUShort(sub_header_offset +
+ Offset::kFormat2SubHeaderKeys +
+ Offset::kFormat2SubHeader_firstCode);
+}
+
+int32_t CMapTable::CMapFormat2::EntryCount(int32_t sub_header_index) {
+ int32_t sub_header_offset = SubHeaderOffset(sub_header_index);
+ return data_->ReadUShort(sub_header_offset +
+ Offset::kFormat2SubHeaderKeys +
+ Offset::kFormat2SubHeader_entryCount);
+}
+
+int32_t CMapTable::CMapFormat2::IdRangeOffset(int32_t sub_header_index) {
+ int32_t sub_header_offset = SubHeaderOffset(sub_header_index);
+ return data_->ReadUShort(sub_header_offset +
+ Offset::kFormat2SubHeaderKeys +
+ Offset::kFormat2SubHeader_idRangeOffset);
+}
+
+int32_t CMapTable::CMapFormat2::IdDelta(int32_t sub_header_index) {
+ int32_t sub_header_offset = SubHeaderOffset(sub_header_index);
+ return data_->ReadUShort(sub_header_offset +
+ Offset::kFormat2SubHeaderKeys +
+ Offset::kFormat2SubHeader_idDelta);
+}
+
+CMapTable::CMap::CharacterIterator* CMapTable::CMapFormat2::Iterator() {
+ // UNIMPLEMENTED
+ return NULL;
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat2::Builder
+ ******************************************************************************/
+CMapTable::CMapFormat2::Builder::Builder(WritableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id)
+ : CMapTable::CMap::Builder(data ? down_cast<WritableFontData*>(
+ data->Slice(offset, data->ReadUShort(
+ offset + Offset::kFormat0Length)))
+ : reinterpret_cast<WritableFontData*>(NULL),
+ CMapFormat::kFormat2, cmap_id) {
+ // TODO(arthurhsu): FIXIT: heavy lifting and leak, need fix.
+}
+
+CMapTable::CMapFormat2::Builder::Builder(ReadableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id)
+ : CMapTable::CMap::Builder(data ? down_cast<ReadableFontData*>(
+ data->Slice(offset, data->ReadUShort(
+ offset + Offset::kFormat0Length)))
+ : reinterpret_cast<ReadableFontData*>(NULL),
+ CMapFormat::kFormat2, cmap_id) {
+ // TODO(arthurhsu): FIXIT: heavy lifting and leak, need fix.
+}
+
+CMapTable::CMapFormat2::Builder::~Builder() {
+}
+
+CALLER_ATTACH FontDataTable*
+ CMapTable::CMapFormat2::Builder::SubBuildTable(ReadableFontData* data) {
+ FontDataTablePtr table = new CMapFormat2(data, cmap_id());
+ return table.Detach();
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat4
+ ******************************************************************************/
+CMapTable::CMapFormat4::CMapFormat4(ReadableFontData* data,
+ const CMapId& cmap_id)
+ : CMap(data, CMapFormat::kFormat4, cmap_id),
+ seg_count_(SegCount(data)),
+ start_code_offset_(StartCodeOffset(seg_count_)),
+ id_delta_offset_(IdDeltaOffset(seg_count_)),
+ glyph_id_array_offset_(GlyphIdArrayOffset(seg_count_)) {
+}
+
+CMapTable::CMapFormat4::~CMapFormat4() {
+}
+
+int32_t CMapTable::CMapFormat4::GlyphId(int32_t character) {
+ int32_t segment = data_->SearchUShort(StartCodeOffset(seg_count_),
+ DataSize::kUSHORT,
+ Offset::kFormat4EndCount,
+ DataSize::kUSHORT,
+ seg_count_,
+ character);
+ if (segment == -1) {
+ return CMapTable::NOTDEF;
+ }
+ int32_t start_code = StartCode(segment);
+ return RetrieveGlyphId(segment, start_code, character);
+}
+
+int32_t CMapTable::CMapFormat4::RetrieveGlyphId(int32_t segment,
+ int32_t start_code,
+ int32_t character) {
+ if (character < start_code) {
+ return CMapTable::NOTDEF;
+ }
+ int32_t id_range_offset = IdRangeOffset(segment);
+ if (id_range_offset == 0) {
+ return (character + IdDelta(segment)) % 65536;
+ }
+ return data_->ReadUShort(id_range_offset +
+ IdRangeOffsetLocation(segment) +
+ 2 * (character - start_code));
+}
+
+int32_t CMapTable::CMapFormat4::seg_count() {
+ return seg_count_;
+}
+
+int32_t CMapTable::CMapFormat4::Length() {
+ return Length(data_);
+}
+
+int32_t CMapTable::CMapFormat4::StartCode(int32_t segment) {
+ if (!IsValidIndex(segment)) {
+ return -1;
+ }
+ return StartCode(data_.p_, seg_count_, segment);
+}
+
+// static
+int32_t CMapTable::CMapFormat4::Language(ReadableFontData* data) {
+ int32_t language = data->ReadUShort(Offset::kFormat4Language);
+ return language;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::Length(ReadableFontData* data) {
+ int32_t length = data->ReadUShort(Offset::kFormat4Length);
+ return length;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::SegCount(ReadableFontData* data) {
+ int32_t seg_count = data->ReadUShort(Offset::kFormat4SegCountX2) / 2;
+ return seg_count;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::StartCode(ReadableFontData* data,
+ int32_t seg_count,
+ int32_t index) {
+ int32_t start_code = data->ReadUShort(StartCodeOffset(seg_count) +
+ index * DataSize::kUSHORT);
+ return start_code;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::StartCodeOffset(int32_t seg_count) {
+ int32_t start_code_offset = Offset::kFormat4EndCount +
+ (seg_count + 1) * DataSize::kUSHORT;
+ return start_code_offset;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::EndCode(ReadableFontData* data,
+ int32_t seg_count,
+ int32_t index) {
+ UNREFERENCED_PARAMETER(seg_count);
+ int32_t end_code = data->ReadUShort(Offset::kFormat4EndCount +
+ index * DataSize::kUSHORT);
+ return end_code;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::IdDelta(ReadableFontData* data,
+ int32_t seg_count,
+ int32_t index) {
+ int32_t id_delta = data->ReadUShort(IdDeltaOffset(seg_count) +
+ index * DataSize::kUSHORT);
+ return id_delta;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::IdDeltaOffset(int32_t seg_count) {
+ int32_t id_delta_offset =
+ Offset::kFormat4EndCount + (2 * seg_count + 1) * DataSize::kUSHORT;
+ return id_delta_offset;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::IdRangeOffset(ReadableFontData* data,
+ int32_t seg_count,
+ int32_t index) {
+ int32_t id_range_offset =
+ data->ReadUShort(IdRangeOffsetOffset(seg_count)
+ + index * DataSize::kUSHORT);
+ return id_range_offset;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::IdRangeOffsetOffset(int32_t seg_count) {
+ int32_t id_range_offset_offset =
+ Offset::kFormat4EndCount + (2 * seg_count + 1) * DataSize::kUSHORT +
+ seg_count * DataSize::kSHORT;
+ return id_range_offset_offset;
+}
+
+// static
+int32_t CMapTable::CMapFormat4::GlyphIdArrayOffset(int32_t seg_count) {
+ int32_t glyph_id_array_offset =
+ Offset::kFormat4EndCount + (3 * seg_count + 1) * DataSize::kUSHORT +
+ seg_count * DataSize::kSHORT;
+ return glyph_id_array_offset;
+}
+
+int32_t CMapTable::CMapFormat4::EndCode(int32_t segment) {
+ if (IsValidIndex(segment)) {
+ return EndCode(data_, seg_count_, segment);
+ }
+#if defined (SFNTLY_NO_EXCEPTION)
+ return -1;
+#else
+ throw IllegalArgumentException();
+#endif
+}
+
+bool CMapTable::CMapFormat4::IsValidIndex(int32_t segment) {
+ if (segment < 0 || segment >= seg_count_) {
+#if defined (SFNTLY_NO_EXCEPTION)
+ return false;
+#else
+ throw IllegalArgumentException();
+#endif
+ }
+ return true;
+}
+
+int32_t CMapTable::CMapFormat4::IdDelta(int32_t segment) {
+ if (IsValidIndex(segment))
+ return IdDelta(data_, seg_count_, segment);
+ return -1;
+}
+
+int32_t CMapTable::CMapFormat4::IdRangeOffset(int32_t segment) {
+ if (IsValidIndex(segment))
+ return data_->ReadUShort(IdRangeOffsetLocation(segment));
+ return -1;
+}
+
+int32_t CMapTable::CMapFormat4::IdRangeOffsetLocation(int32_t segment) {
+ if (IsValidIndex(segment))
+ return IdRangeOffsetOffset(seg_count_) + segment * DataSize::kUSHORT;
+ return -1;
+}
+
+int32_t CMapTable::CMapFormat4::GlyphIdArray(int32_t index) {
+ return data_->ReadUShort(glyph_id_array_offset_ + index * DataSize::kUSHORT);
+}
+
+int32_t CMapTable::CMapFormat4::Language() {
+ return Language(data_);
+}
+
+
+CMapTable::CMap::CharacterIterator* CMapTable::CMapFormat4::Iterator() {
+ return new CharacterIterator(this);
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat4::CharacterIterator class
+ ******************************************************************************/
+CMapTable::CMapFormat4::CharacterIterator::CharacterIterator(
+ CMapFormat4* parent)
+ : parent_(parent),
+ segment_index_(0),
+ first_char_in_segment_(-1),
+ last_char_in_segment_(-1),
+ next_char_(-1),
+ next_char_set_(false) {
+}
+
+bool CMapTable::CMapFormat4::CharacterIterator::HasNext() {
+ if (next_char_set_)
+ return true;
+ while (segment_index_ < parent_->seg_count_) {
+ if (first_char_in_segment_ < 0) {
+ first_char_in_segment_ = parent_->StartCode(segment_index_);
+ last_char_in_segment_ = parent_->EndCode(segment_index_);
+ next_char_ = first_char_in_segment_;
+ next_char_set_ = true;
+ return true;
+ }
+ if (next_char_ < last_char_in_segment_) {
+ next_char_++;
+ next_char_set_ = true;
+ return true;
+ }
+ segment_index_++;
+ first_char_in_segment_ = -1;
+ }
+ return false;
+}
+
+int32_t CMapTable::CMapFormat4::CharacterIterator::Next() {
+ if (!next_char_set_) {
+ if (!HasNext()) {
+#if defined (SFNTLY_NO_EXCEPTION)
+ return -1;
+#else
+ throw NoSuchElementException("No more characters to iterate.");
+#endif
+ }
+ }
+ next_char_set_ = false;
+ return next_char_;
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat4::Builder::Segment class
+ ******************************************************************************/
+CMapTable::CMapFormat4::Builder::Segment::Segment() {}
+
+CMapTable::CMapFormat4::Builder::Segment::Segment(Segment* other)
+ : start_count_(other->start_count_),
+ end_count_(other->end_count_),
+ id_delta_(other->id_delta_),
+ id_range_offset_(other->id_range_offset_) {
+}
+
+CMapTable::CMapFormat4::Builder::Segment::Segment(int32_t start_count,
+ int32_t end_count,
+ int32_t id_delta,
+ int32_t id_range_offset)
+ : start_count_(start_count),
+ end_count_(end_count),
+ id_delta_(id_delta),
+ id_range_offset_(id_range_offset) {
+}
+
+CMapTable::CMapFormat4::Builder::Segment::~Segment() {}
+
+int32_t CMapTable::CMapFormat4::Builder::Segment::start_count() {
+ return start_count_;
+}
+
+void
+CMapTable::CMapFormat4::Builder::Segment::set_start_count(int32_t start_count) {
+ start_count_ = start_count;
+}
+
+int32_t CMapTable::CMapFormat4::Builder::Segment::end_count() {
+ return end_count_;
+}
+
+void
+CMapTable::CMapFormat4::Builder::Segment::set_end_count(int32_t end_count) {
+ end_count_ = end_count;
+}
+
+int32_t CMapTable::CMapFormat4::Builder::Segment::id_delta() {
+ return id_delta_;
+}
+
+void
+CMapTable::CMapFormat4::Builder::Segment::set_id_delta(int32_t id_delta) {
+ id_delta_ = id_delta;
+}
+
+int32_t CMapTable::CMapFormat4::Builder::Segment::id_range_offset() {
+ return id_range_offset_;
+}
+
+void
+CMapTable::CMapFormat4::Builder::Segment::
+set_id_range_offset(int32_t id_range_offset) {
+ id_range_offset_ = id_range_offset;
+}
+
+// static
+CALLER_ATTACH SegmentList*
+CMapTable::CMapFormat4::Builder::Segment::DeepCopy(SegmentList* original) {
+ SegmentList* list = new SegmentList;
+ for (SegmentList::iterator it = original->begin(),
+ e = original->end(); it != e; ++it) {
+ list->push_back(*it);
+ }
+ return list;
+}
+
+/******************************************************************************
+ * CMapTable::CMapFormat4::Builder class
+ ******************************************************************************/
+CALLER_ATTACH CMapTable::CMapFormat4::Builder*
+CMapTable::CMapFormat4::Builder::NewInstance(ReadableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id) {
+ ReadableFontDataPtr rdata;
+ if (data) {
+ rdata.Attach
+ (down_cast<ReadableFontData*>
+ (data->Slice(offset,
+ data->ReadUShort(offset + Offset::kFormat4Length))));
+ }
+ return new Builder(rdata, CMapFormat::kFormat4, cmap_id);
+}
+
+CALLER_ATTACH CMapTable::CMapFormat4::Builder*
+CMapTable::CMapFormat4::Builder::NewInstance(WritableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id) {
+ WritableFontDataPtr wdata;
+ if (data) {
+ wdata.Attach
+ (down_cast<WritableFontData*>
+ (data->Slice(offset,
+ data->ReadUShort(offset + Offset::kFormat4Length))));
+ }
+ return new Builder(wdata, CMapFormat::kFormat4, cmap_id);
+}
+
+CALLER_ATTACH CMapTable::CMapFormat4::Builder*
+CMapTable::CMapFormat4::Builder::NewInstance(const CMapId& cmap_id) {
+ return new Builder(cmap_id);
+}
+
+CMapTable::CMapFormat4::Builder::Builder(ReadableFontData* data, int32_t offset,
+ const CMapId& cmap_id)
+ : CMap::Builder(data, CMapFormat::kFormat4, cmap_id) {
+ UNREFERENCED_PARAMETER(offset);
+}
+
+CMapTable::CMapFormat4::Builder::Builder(WritableFontData* data, int32_t offset,
+ const CMapId& cmap_id)
+ : CMap::Builder(data, CMapFormat::kFormat4, cmap_id) {
+ UNREFERENCED_PARAMETER(offset);
+}
+
+CMapTable::CMapFormat4::Builder::Builder(SegmentList* segments,
+ IntegerList* glyph_id_array,
+ const CMapId& cmap_id)
+ : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL),
+ CMapFormat::kFormat4, cmap_id),
+ segments_(segments->begin(), segments->end()),
+ glyph_id_array_(glyph_id_array->begin(), glyph_id_array->end()) {
+ set_model_changed();
+}
+
+CMapTable::CMapFormat4::Builder::Builder(const CMapId& cmap_id)
+ : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL),
+ CMapFormat::kFormat4, cmap_id) {
+}
+
+CMapTable::CMapFormat4::Builder::~Builder() {}
+
+void CMapTable::CMapFormat4::Builder::Initialize(ReadableFontData* data) {
+ if (data == NULL || data->Length() == 0)
+ return;
+
+ // build segments
+ int32_t seg_count = CMapFormat4::SegCount(data);
+ for (int32_t index = 0; index < seg_count; ++index) {
+ Ptr<Segment> segment = new Segment;
+ segment->set_start_count(CMapFormat4::StartCode(data, seg_count, index));
+#if defined SFNTLY_DEBUG_CMAP
+ fprintf(stderr, "Segment %d; start %d\n", index, segment->start_count());
+#endif
+ segment->set_end_count(CMapFormat4::EndCode(data, seg_count, index));
+ segment->set_id_delta(CMapFormat4::IdDelta(data, seg_count, index));
+ segment->set_id_range_offset(CMapFormat4::IdRangeOffset(data,
+ seg_count,
+ index));
+ segments_.push_back(segment);
+ }
+
+ // build glyph id array
+ int32_t glyph_id_array_offset = CMapFormat4::GlyphIdArrayOffset(seg_count);
+ int32_t glyph_id_array_length =
+ (CMapFormat4::Length(data) - glyph_id_array_offset)
+ / DataSize::kUSHORT;
+ fprintf(stderr, "id array size %d\n", glyph_id_array_length);
+ for (int32_t i = 0; i < glyph_id_array_length; i += DataSize::kUSHORT) {
+ glyph_id_array_.push_back(data->ReadUShort(glyph_id_array_offset + i));
+ }
+}
+
+SegmentList* CMapTable::CMapFormat4::Builder::segments() {
+ if (segments_.empty()) {
+ Initialize(InternalReadData());
+ set_model_changed();
+ }
+ return &segments_;
+}
+
+void CMapTable::CMapFormat4::Builder::set_segments(SegmentList* segments) {
+ segments_.assign(segments->begin(), segments->end());
+ set_model_changed();
+}
+
+IntegerList* CMapTable::CMapFormat4::Builder::glyph_id_array() {
+ if (glyph_id_array_.empty()) {
+ Initialize(InternalReadData());
+ set_model_changed();
+ }
+ return &glyph_id_array_;
+}
+
+void CMapTable::CMapFormat4::Builder::
+set_glyph_id_array(IntegerList* glyph_id_array) {
+ glyph_id_array_.assign(glyph_id_array->begin(), glyph_id_array->end());
+ set_model_changed();
+}
+
+CALLER_ATTACH FontDataTable*
+CMapTable::CMapFormat4::Builder::SubBuildTable(ReadableFontData* data) {
+ FontDataTablePtr table = new CMapFormat4(data, cmap_id());
+ return table.Detach();
+}
+
+void CMapTable::CMapFormat4::Builder::SubDataSet() {
+ segments_.clear();
+ glyph_id_array_.clear();
+ set_model_changed();
+}
+
+int32_t CMapTable::CMapFormat4::Builder::SubDataSizeToSerialize() {
+ if (!model_changed()) {
+ return CMap::Builder::SubDataSizeToSerialize();
+ }
+ int32_t size = Offset::kFormat4FixedSize + segments_.size()
+ * (3 * DataSize::kUSHORT + DataSize::kSHORT)
+ + glyph_id_array_.size() * DataSize::kSHORT;
+ return size;
+}
+
+bool CMapTable::CMapFormat4::Builder::SubReadyToSerialize() {
+ if (!model_changed()) {
+ return CMap::Builder::SubReadyToSerialize();
+ }
+ if (!segments()->empty()) {
+ return true;
+ }
+ return false;
+}
+
+int32_t
+CMapTable::CMapFormat4::Builder::SubSerialize(WritableFontData* new_data) {
+ if (!model_changed()) {
+ return CMap::Builder::SubSerialize(new_data);
+ }
+ int32_t index = 0;
+ index += new_data->WriteUShort(index, CMapFormat::kFormat4);
+ index += DataSize::kUSHORT; // length - write this at the end
+ index += new_data->WriteUShort(index, language());
+
+ int32_t seg_count = segments_.size();
+ index += new_data->WriteUShort(index, seg_count * 2);
+ int32_t log2_seg_count = FontMath::Log2(seg_count);
+ int32_t search_range = 1 << (log2_seg_count + 1);
+ index += new_data->WriteUShort(index, search_range);
+ int32_t entry_selector = log2_seg_count;
+ index += new_data->WriteUShort(index, entry_selector);
+ int32_t range_shift = 2 * seg_count - search_range;
+ index += new_data->WriteUShort(index, range_shift);
+
+ for (int32_t i = 0; i < seg_count; ++i) {
+ index += new_data->WriteUShort(index, segments_[i]->end_count());
+ }
+ index += new_data->WriteUShort(index, 0); // reserved ushort
+ for (int32_t i = 0; i < seg_count; ++i) {
+#if defined SFNTLY_DEBUG_CMAP
+ fprintf(stderr, "Segment %d; start %d\n", i, segments_[i]->start_count());
+#endif
+ index += new_data->WriteUShort(index, segments_[i]->start_count());
+ }
+ for (int32_t i = 0; i < seg_count; ++i) {
+ index += new_data->WriteShort(index, segments_[i]->id_delta());
+ }
+ for (int32_t i = 0; i < seg_count; ++i) {
+ index += new_data->WriteUShort(index, segments_[i]->id_range_offset());
+ }
+
+#if defined SFNTLY_DEBUG_CMAP
+ fprintf(stderr, "Glyph id array size %lu\n", glyph_id_array_.size());
+#endif
+ for (size_t i = 0; i < glyph_id_array_.size(); ++i) {
+ index += new_data->WriteUShort(index, glyph_id_array_[i]);
+ }
+
+ new_data->WriteUShort(Offset::kFormat4Length, index);
+ return index;
+}
+
+/******************************************************************************
+ * CMapTable::Builder class
+ ******************************************************************************/
+CMapTable::Builder::Builder(Header* header, WritableFontData* data)
+ : SubTableContainerTable::Builder(header, data), version_(0) {
+}
+
+CMapTable::Builder::Builder(Header* header, ReadableFontData* data)
+ : SubTableContainerTable::Builder(header, data), version_(0) {
+}
+
+CMapTable::Builder::~Builder() {
+}
+
+int32_t CMapTable::Builder::SubSerialize(WritableFontData* new_data) {
+ int32_t size = new_data->WriteUShort(CMapTable::Offset::kVersion,
+ version_);
+ size += new_data->WriteUShort(CMapTable::Offset::kNumTables,
+ GetCMapBuilders()->size());
+
+ int32_t index_offset = size;
+ size += GetCMapBuilders()->size() * CMapTable::Offset::kEncodingRecordSize;
+ for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(),
+ e = GetCMapBuilders()->end(); it != e; ++it) {
+ CMapBuilderPtr b = it->second;
+ // header entry
+ index_offset += new_data->WriteUShort(index_offset, b->platform_id());
+ index_offset += new_data->WriteUShort(index_offset, b->encoding_id());
+ index_offset += new_data->WriteULong(index_offset, size);
+
+ // cmap
+ FontDataPtr slice;
+ slice.Attach(new_data->Slice(size));
+ size += b->SubSerialize(down_cast<WritableFontData*>(slice.p_));
+ }
+ return size;
+}
+
+bool CMapTable::Builder::SubReadyToSerialize() {
+ if (GetCMapBuilders()->empty())
+ return false;
+
+ // check each table
+ for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(),
+ e = GetCMapBuilders()->end(); it != e; ++it) {
+ if (!it->second->SubReadyToSerialize())
+ return false;
+ }
+ return true;
+}
+
+int32_t CMapTable::Builder::SubDataSizeToSerialize() {
+ if (GetCMapBuilders()->empty())
+ return 0;
+
+ bool variable = false;
+ int32_t size = CMapTable::Offset::kEncodingRecordStart +
+ GetCMapBuilders()->size() * CMapTable::Offset::kEncodingRecordSize;
+
+ // calculate size of each table
+ for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(),
+ e = GetCMapBuilders()->end(); it != e; ++it) {
+ int32_t cmap_size = it->second->SubDataSizeToSerialize();
+ size += abs(cmap_size);
+ variable |= cmap_size <= 0;
+ }
+ return variable ? -size : size;
+}
+
+void CMapTable::Builder::SubDataSet() {
+ GetCMapBuilders()->clear();
+ Table::Builder::set_model_changed();
+}
+
+CALLER_ATTACH FontDataTable*
+ CMapTable::Builder::SubBuildTable(ReadableFontData* data) {
+ FontDataTablePtr table = new CMapTable(header(), data);
+ return table.Detach();
+}
+
+CALLER_ATTACH CMapTable::Builder*
+ CMapTable::Builder::CreateBuilder(Header* header,
+ WritableFontData* data) {
+ Ptr<CMapTable::Builder> builder;
+ builder = new CMapTable::Builder(header, data);
+ return builder.Detach();
+}
+
+// static
+CALLER_ATTACH CMapTable::CMap::Builder*
+ CMapTable::Builder::CMapBuilder(ReadableFontData* data, int32_t index) {
+ if (index < 0 || index > NumCMaps(data)) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundException(
+ "CMap table is outside of the bounds of the known tables.");
+#endif
+ return NULL;
+ }
+
+ int32_t platform_id = data->ReadUShort(Offset::kEncodingRecordPlatformId +
+ OffsetForEncodingRecord(index));
+ int32_t encoding_id = data->ReadUShort(Offset::kEncodingRecordEncodingId +
+ OffsetForEncodingRecord(index));
+ int32_t offset = data->ReadULongAsInt(Offset::kEncodingRecordOffset +
+ OffsetForEncodingRecord(index));
+ return CMap::Builder::GetBuilder(data, offset,
+ NewCMapId(platform_id, encoding_id));
+}
+
+// static
+int32_t CMapTable::Builder::NumCMaps(ReadableFontData* data) {
+ if (data == NULL) {
+ return 0;
+ }
+ return data->ReadUShort(Offset::kNumTables);
+}
+
+int32_t CMapTable::Builder::NumCMaps() {
+ return GetCMapBuilders()->size();
+}
+
+void CMapTable::Builder::Initialize(ReadableFontData* data) {
+ int32_t num_cmaps = NumCMaps(data);
+ for (int32_t i = 0; i < num_cmaps; ++i) {
+ CMapTable::CMap::Builder* cmap_builder = CMapBuilder(data, i);
+ if (!cmap_builder)
+ continue;
+ cmap_builders_[cmap_builder->cmap_id()] = cmap_builder;
+ }
+}
+
+CMapTable::CMap::Builder* CMapTable::Builder::NewCMapBuilder(
+ const CMapId& cmap_id,
+ ReadableFontData* data) {
+ Ptr<WritableFontData> wfd;
+ wfd.Attach(WritableFontData::CreateWritableFontData(data->Size()));
+ data->CopyTo(wfd.p_);
+ CMapTable::CMapBuilderPtr builder;
+ builder.Attach(CMap::Builder::GetBuilder(wfd.p_, 0, cmap_id));
+ CMapBuilderMap* cmap_builders = CMapTable::Builder::GetCMapBuilders();
+ cmap_builders->insert(std::make_pair(cmap_id, builder.p_));
+ return builder.Detach();
+}
+
+CMapTable::CMap::Builder*
+CMapTable::Builder::NewCMapBuilder(int32_t format, const CMapId& cmap_id) {
+ Ptr<CMapTable::CMap::Builder> cmap_builder;
+ cmap_builder.Attach(CMap::Builder::GetBuilder(format, cmap_id));
+ CMapBuilderMap* cmap_builders = CMapTable::Builder::GetCMapBuilders();
+ cmap_builders->insert(std::make_pair(cmap_id, cmap_builder.p_));
+ return cmap_builder.Detach();
+}
+
+CMapTable::CMap::Builder*
+CMapTable::Builder::CMapBuilder(const CMapId& cmap_id) {
+ CMapBuilderMap* cmap_builders = this->GetCMapBuilders();
+ CMapBuilderMap::iterator builder = cmap_builders->find(cmap_id);
+ if (builder != cmap_builders->end())
+ return builder->second;
+#ifndef SFNTLY_NO_EXCEPTION
+ throw NoSuchElementException("No builder found for cmap_id");
+#else
+ return NULL;
+#endif
+}
+
+CMapTable::CMapBuilderMap* CMapTable::Builder::GetCMapBuilders() {
+ if (cmap_builders_.empty()) {
+ Initialize(InternalReadData());
+ set_model_changed();
+ }
+ return &cmap_builders_;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/cmap_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/cmap_table.h
new file mode 100644
index 00000000000..b264b074bd9
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/cmap_table.h
@@ -0,0 +1,709 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_
+
+// type.h needs to be included first because of building issues on Windows
+// Type aliases we delcare are defined in other headers and make the build
+// fail otherwise.
+#include "sfntly/port/type.h"
+#include <vector>
+#include <map>
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/table/subtable.h"
+#include "sfntly/table/subtable_container_table.h"
+
+namespace sfntly {
+
+// CMap subtable formats
+struct CMapFormat {
+ enum {
+ kFormat0 = 0,
+ kFormat2 = 2,
+ kFormat4 = 4,
+ kFormat6 = 6,
+ kFormat8 = 8,
+ kFormat10 = 10,
+ kFormat12 = 12,
+ kFormat13 = 13,
+ kFormat14 = 14
+ };
+};
+
+// A CMap table
+class CMapTable : public SubTableContainerTable, public RefCounted<CMapTable> {
+public:
+ // CMapTable::CMapId
+ struct CMapId {
+ int32_t platform_id;
+ int32_t encoding_id;
+ bool operator==(const CMapId& obj) const {
+ return platform_id == obj.platform_id && encoding_id == obj.encoding_id;
+ }
+ };
+ static CMapId WINDOWS_BMP;
+ static CMapId WINDOWS_UCS4;
+ static CMapId MAC_ROMAN;
+
+ // CMapTable::CMapIdComparator
+ class CMapIdComparator {
+ public:
+ bool operator()(const CMapId& lhs, const CMapId& rhs) const;
+ };
+
+ // A filter on cmap
+ // CMapTable::CMapFilter
+ class CMapFilter {
+ public:
+ // Test on whether the cmap is acceptable or not
+ // @param cmap_id the id of the cmap
+ // @return true if the cmap is acceptable; false otherwise
+ virtual bool accept(const CMapId& cmap_id) const = 0;
+ // Make gcc -Wnon-virtual-dtor happy.
+ virtual ~CMapFilter() {}
+ };
+
+ // Filters CMaps by CMapId to implement CMapTable::get()
+ // wanted_id is the CMap we'd like to find.
+ // We compare the current CMap to it either by equality (==) or using a
+ // comparator.
+ // CMapTable::CMapIdFilter
+ class CMapIdFilter : public CMapFilter {
+ public:
+ explicit CMapIdFilter(const CMapId wanted_id);
+ CMapIdFilter(const CMapId wanted_id,
+ const CMapIdComparator* comparator);
+ ~CMapIdFilter() {}
+ virtual bool accept(const CMapId& cmap_id) const;
+ private:
+ CMapIdFilter& operator=(const CMapIdFilter& that);
+ const CMapId wanted_id_;
+ const CMapIdComparator *comparator_;
+ };
+
+ // The abstract base class for all cmaps.
+ //
+ // CMap equality is based on the equality of the (@link {@link CMapId} that
+ // defines the CMap. In the cmap table for a font there can only be one cmap
+ // with a given cmap id (pair of platform and encoding ids) no matter what the
+ // type of the cmap is.
+ //
+ // The cmap offers CharacterIterator to allow iteration over
+ // characters that are mapped by the cmap. This iteration mostly returns the
+ // characters mapped by the cmap. It will return all characters mapped by the
+ // cmap to anything but .notdef <b>but</b> it may return some that are not
+ // mapped or are mapped to .notdef. Various cmap tables provide ranges and
+ // such to describe characters for lookup but without going the full way to
+ // mapping to the glyph id it isn't always possible to tell if a character
+ // will end up with a valid glyph id. So, some of the characters returned from
+ // the Iterator may still end up pointing to the .notdef glyph. However, the
+ // number of such characters should be small in most cases with well designed
+ // cmaps.
+ class Builder;
+ class CMap : public SubTable {
+ public:
+ // CMapTable::CMap::Builder
+ class Builder : public SubTable::Builder {
+ public:
+ virtual ~Builder();
+
+ CALLER_ATTACH static Builder*
+ GetBuilder(ReadableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id);
+ CALLER_ATTACH static Builder*
+ GetBuilder(int32_t format,
+ const CMapId& cmap_id);
+
+ // Note: yes, an object is returned on stack since it's small enough.
+ virtual CMapId cmap_id() { return cmap_id_; }
+ virtual int32_t platform_id() { return cmap_id_.platform_id; }
+ virtual int32_t encoding_id() { return cmap_id_.encoding_id; }
+ virtual int32_t format() { return format_; }
+ virtual int32_t language() { return language_; }
+ virtual void set_language(int32_t language) { language_ = language; }
+
+ protected:
+ Builder(ReadableFontData* data,
+ int32_t format,
+ const CMapId& cmap_id);
+ Builder(WritableFontData* data,
+ int32_t format,
+ const CMapId& cmap_id);
+
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual void SubDataSet();
+
+ private:
+ int32_t format_;
+ CMapId cmap_id_;
+ int32_t language_;
+
+ friend class CMapTable::Builder;
+ };
+ // Abstract CMap character iterator
+ // The fully qualified name is CMapTable::CMap::CharacterIterator
+ class CharacterIterator {
+ public:
+ virtual ~CharacterIterator() {}
+ virtual bool HasNext() = 0;
+ // Returns -1 if there are no more characters to iterate through
+ // and exceptions are turned off
+ virtual int32_t Next() = 0;
+
+ protected:
+ // Use the CMap::Iterator method below instead of directly requesting
+ // a CharacterIterator.
+ CharacterIterator() {}
+ };
+
+ CMap(ReadableFontData* data, int32_t format, const CMapId& cmap_id);
+ virtual ~CMap();
+
+ virtual CMap::CharacterIterator* Iterator() = 0;
+
+ virtual int32_t format() { return format_; }
+ virtual CMapId cmap_id() { return cmap_id_; }
+ virtual int32_t platform_id() { return cmap_id_.platform_id; }
+ virtual int32_t encoding_id() { return cmap_id_.encoding_id; }
+
+ // Get the language of the cmap.
+ //
+ // Note on the language field in 'cmap' subtables: The language field must
+ // be set to zero for all cmap subtables whose platform IDs are other than
+ // Macintosh (platform ID 1). For cmap subtables whose platform IDs are
+ // Macintosh, set this field to the Macintosh language ID of the cmap
+ // subtable plus one, or to zero if the cmap subtable is not
+ // language-specific. For example, a Mac OS Turkish cmap subtable must set
+ // this field to 18, since the Macintosh language ID for Turkish is 17. A
+ // Mac OS Roman cmap subtable must set this field to 0, since Mac OS Roman
+ // is not a language-specific encoding.
+ //
+ // @return the language id
+ virtual int32_t Language() = 0;
+
+ // Gets the glyph id for the character code provided.
+ // The character code provided must be in the encoding used by the cmap
+ // table.
+ virtual int32_t GlyphId(int32_t character) = 0;
+
+ private:
+ int32_t format_;
+ CMapId cmap_id_;
+ };
+ typedef Ptr<CMap> CMapPtr;
+ typedef Ptr<CMap::Builder> CMapBuilderPtr;
+ typedef std::map<CMapId, CMapBuilderPtr, CMapIdComparator> CMapBuilderMap;
+
+ // A cmap format 0 sub table
+ class CMapFormat0 : public CMap, public RefCounted<CMapFormat0> {
+ public:
+ // The fully qualified name is CMapTable::CMapFormat0::Builder
+ class Builder : public CMap::Builder,
+ public RefCounted<Builder> {
+ public:
+ CALLER_ATTACH static Builder* NewInstance(ReadableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id);
+ CALLER_ATTACH static Builder* NewInstance(WritableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id);
+ CALLER_ATTACH static Builder* NewInstance(const CMapId& cmap_id);
+ virtual ~Builder();
+
+ protected:
+ virtual CALLER_ATTACH FontDataTable*
+ SubBuildTable(ReadableFontData* data);
+
+ private:
+ // When creating a new CMapFormat0 Builder, use NewInstance instead of
+ // the constructors! This avoids a memory leak when slicing the FontData.
+ Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id);
+ Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id);
+ Builder(const CMapId& cmap_id);
+ };
+
+ // The fully qualified name is CMapTable::CMapFormat0::CharacterIterator
+ class CharacterIterator : public CMap::CharacterIterator {
+ public:
+ virtual ~CharacterIterator();
+ virtual bool HasNext();
+ virtual int32_t Next();
+
+ private:
+ CharacterIterator(int32_t start, int32_t end);
+ friend class CMapFormat0;
+ int32_t character_, max_character_;
+ };
+
+ virtual ~CMapFormat0();
+ virtual int32_t Language();
+ virtual int32_t GlyphId(int32_t character);
+ CMap::CharacterIterator* Iterator();
+
+ private:
+ CMapFormat0(ReadableFontData* data, const CMapId& cmap_id);
+ };
+
+ // A cmap format 2 sub table
+ // The format 2 cmap is used for multi-byte encodings such as SJIS,
+ // EUC-JP/KR/CN, Big5, etc.
+ class CMapFormat2 : public CMap, public RefCounted<CMapFormat2> {
+ public:
+ // CMapTable::CMapFormat2::Builder
+ class Builder : public CMap::Builder,
+ public RefCounted<Builder> {
+ public:
+ Builder(ReadableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id);
+ Builder(WritableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id);
+ virtual ~Builder();
+
+ protected:
+ virtual CALLER_ATTACH FontDataTable*
+ SubBuildTable(ReadableFontData* data);
+ };
+ // CMapTable::CMapFormat2::CharacterIterator
+ class CharacterIterator : public CMap::CharacterIterator {
+ public:
+ virtual ~CharacterIterator();
+ virtual bool hasNext();
+ virtual int32_t next();
+
+ private:
+ CharacterIterator();
+ };
+
+ virtual int32_t Language();
+ virtual int32_t GlyphId(int32_t character);
+
+ // Returns how many bytes would be consumed by a lookup of this character
+ // with this cmap. This comes about because the cmap format 2 table is
+ // designed around multi-byte encodings such as SJIS, EUC-JP, Big5, etc.
+ // return the number of bytes consumed from this "character" - either 1 or 2
+ virtual int32_t BytesConsumed(int32_t character);
+
+ virtual ~CMapFormat2();
+
+ private:
+ CMapFormat2(ReadableFontData* data, const CMapId& cmap_id);
+
+ int32_t SubHeaderOffset(int32_t sub_header_index);
+ int32_t FirstCode(int32_t sub_header_index);
+ int32_t EntryCount(int32_t sub_header_index);
+ int32_t IdRangeOffset(int32_t sub_header_index);
+ int32_t IdDelta(int32_t sub_header_index);
+ CMap::CharacterIterator* Iterator();
+ };
+
+ // CMapTable::CMapFormat4
+ class CMapFormat4 : public CMap,
+ public RefCounted<CMapFormat4> {
+ public:
+ // CMapTable::CMapFormat4::Builder
+ class Builder : public CMap::Builder,
+ public RefCounted<Builder> {
+ public:
+ // CMapTable::CMapFormat4::Builder::Segment
+ class Segment : public RefCounted<Segment> {
+ public:
+ Segment();
+ explicit Segment(Segment* other);
+ Segment(int32_t start_count,
+ int32_t end_count,
+ int32_t id_delta,
+ int32_t id_range_offset);
+ ~Segment();
+
+ // @return the startCount
+ int32_t start_count();
+ // @param startCount the startCount to set
+ void set_start_count(int32_t start_count);
+ // @return the endCount
+ int32_t end_count();
+ // @param endcount the endCount to set
+ void set_end_count(int32_t end_count);
+ // @return the idDelta
+ int32_t id_delta();
+ // @param idDelta the idDelta to set
+ void set_id_delta(int32_t id_delta);
+ // @return the idRangeOffset
+ int32_t id_range_offset();
+ // @param idRangeOffset the idRangeOffset to set
+ void set_id_range_offset(int32_t id_range_offset);
+
+ static CALLER_ATTACH
+ std::vector<Ptr<Segment> >*
+ DeepCopy(std::vector<Ptr<Segment> >* original);
+
+ private:
+ int32_t start_count_;
+ int32_t end_count_;
+ int32_t id_delta_;
+ int32_t id_range_offset_;
+ };
+ typedef std::vector<Ptr<Segment> > SegmentList;
+
+ static CALLER_ATTACH Builder* NewInstance(WritableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id);
+ static CALLER_ATTACH Builder* NewInstance(ReadableFontData* data,
+ int32_t offset,
+ const CMapId& cmap_id);
+ static CALLER_ATTACH Builder* NewInstance(const CMapId& cmap_id);
+ virtual ~Builder();
+ SegmentList* segments();
+ void set_segments(SegmentList* segments);
+ IntegerList* glyph_id_array();
+ void set_glyph_id_array(IntegerList* glyph_id_array);
+
+ protected:
+ Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id);
+ Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id);
+ Builder(SegmentList* segments, IntegerList* glyph_id_array,
+ const CMapId& cmap_id);
+ explicit Builder(const CMapId& cmap_id);
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(
+ ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ private:
+ void Initialize(ReadableFontData* data);
+
+ SegmentList segments_;
+ IntegerList glyph_id_array_;
+ };
+
+ CMap::CharacterIterator* Iterator();
+ // CMapTable::CMapFormat4::CharacterIterator
+ class CharacterIterator : public CMap::CharacterIterator {
+ public:
+ bool HasNext();
+ int32_t Next();
+ virtual ~CharacterIterator() {}
+
+ private:
+ explicit CharacterIterator(CMapFormat4 *parent);
+ friend CMap::CharacterIterator* CMapFormat4::Iterator();
+
+ CMapFormat4* parent_;
+ int32_t segment_index_;
+ int32_t first_char_in_segment_;
+ int32_t last_char_in_segment_;
+ int32_t next_char_;
+ bool next_char_set_;
+ };
+
+ virtual int32_t GlyphId(int32_t character);
+
+ // Lower level glyph code retrieval that requires processing the Format 4
+ // segments to use.
+ // @param segment the cmap segment
+ // @param startCode the start code for the segment
+ // @param character the character to be looked up
+ // @return the glyph id for the character; CMapTable.NOTDEF if not found
+ int32_t RetrieveGlyphId(int32_t segment,
+ int32_t start_count,
+ int32_t character);
+ virtual int32_t Language();
+
+ // Get the count of the number of segments in this cmap.
+ // @return the number of segments
+ int32_t seg_count();
+ int32_t Length();
+ // Get the start code for a segment.
+ // @param segment the segment in the lookup table
+ // @return the start code for a segment
+ int32_t StartCode(int32_t segment);
+ // Get the end code for a segment.
+ // @param segment the segment in the look up table
+ // @return the end code for the segment
+ int32_t EndCode(int32_t segment);
+ // Get the id delta for a segment
+ // @param segment the segment in the look up table
+ // @return the id delta for the segment
+ int32_t IdDelta(int32_t segment);
+ // Get the id range offset for a segment
+ // @param segment the segment in the look up table
+ // @return the id range offset for the segment
+ int32_t IdRangeOffset(int32_t segment);
+ // Get the location of the id range offset for a segment
+ // @param segment the segment in the look up table
+ // @return the location of the id range offset for the segment
+ int32_t IdRangeOffsetLocation(int32_t segment);
+ // Declared above to allow friending inside CharacterIterator class.
+ // CMap::CharacterIterator* Iterator();
+ virtual ~CMapFormat4();
+
+ protected:
+ CMapFormat4(ReadableFontData* data, const CMapId& cmap_id);
+
+ private:
+ static int32_t Language(ReadableFontData* data);
+ static int32_t Length(ReadableFontData* data);
+ static int32_t SegCount(ReadableFontData* data);
+ static int32_t StartCode(ReadableFontData* data,
+ int32_t seg_count,
+ int32_t index);
+ static int32_t StartCodeOffset(int32_t seg_count);
+ static int32_t EndCode(ReadableFontData* data,
+ int32_t seg_count,
+ int32_t index);
+ static int32_t IdDelta(ReadableFontData* data,
+ int32_t seg_count,
+ int32_t index);
+ static int32_t IdDeltaOffset(int32_t seg_count);
+ static int32_t IdRangeOffset(ReadableFontData* data,
+ int32_t seg_count,
+ int32_t index);
+ static int32_t IdRangeOffsetOffset(int32_t seg_count);
+ static int32_t GlyphIdArrayOffset(int32_t seg_count);
+ // Refactored void to bool to work without exceptions.
+ bool IsValidIndex(int32_t segment);
+ int32_t GlyphIdArray(int32_t index);
+
+ int32_t seg_count_;
+ int32_t start_code_offset_;
+ int32_t id_delta_offset_;
+ int32_t glyph_id_array_offset_;
+ };
+
+ // CMapTable::Builder
+ class Builder : public SubTableContainerTable::Builder,
+ public RefCounted<Builder> {
+ public:
+ // Constructor scope is public because C++ does not allow base class to
+ // instantiate derived class with protected constructors.
+ Builder(Header* header, WritableFontData* data);
+ Builder(Header* header, ReadableFontData* data);
+ virtual ~Builder();
+
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual void SubDataSet();
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ WritableFontData* data);
+
+ CMap::Builder* NewCMapBuilder(const CMapId& cmap_id,
+ ReadableFontData* data);
+ // Create a new empty CMapBuilder of the type specified in the id.
+ CMap::Builder* NewCMapBuilder(int32_t format, const CMapId& cmap_id);
+ CMap::Builder* CMapBuilder(const CMapId& cmap_id);
+
+ int32_t NumCMaps();
+ void SetVersion(int32_t version);
+
+ CMapBuilderMap* GetCMapBuilders();
+
+ protected:
+ static CALLER_ATTACH CMap::Builder* CMapBuilder(ReadableFontData* data,
+ int32_t index);
+
+ private:
+ void Initialize(ReadableFontData* data);
+ static int32_t NumCMaps(ReadableFontData* data);
+
+ int32_t version_;
+ CMapBuilderMap cmap_builders_;
+ };
+ typedef Ptr<Builder> CMapTableBuilderPtr;
+
+ class CMapIterator {
+ public:
+ // If filter is NULL, filter through all tables.
+ CMapIterator(CMapTable* table, const CMapFilter* filter);
+ bool HasNext();
+ CMap* Next();
+
+ private:
+ int32_t table_index_;
+ const CMapFilter* filter_;
+ CMapTable* table_;
+ };
+
+ // Make a CMapId from a platform_id, encoding_id pair
+ static CMapId NewCMapId(int32_t platform_id, int32_t encoding_id);
+ // Make a CMapId from another CMapId
+ static CMapId NewCMapId(const CMapId& obj);
+
+ // Get the CMap with the specified parameters if it exists.
+ // Returns NULL otherwise.
+ CALLER_ATTACH CMap* GetCMap(const int32_t index);
+ CALLER_ATTACH CMap* GetCMap(const int32_t platform_id,
+ const int32_t encoding_id);
+ CALLER_ATTACH CMap* GetCMap(const CMapId GetCMap_id);
+
+ // Get the table version.
+ virtual int32_t Version();
+
+ // Get the number of cmaps within the CMap table.
+ virtual int32_t NumCMaps();
+
+ // Get the cmap id for the cmap with the given index.
+ // Note: yes, an object is returned on stack since it's small enough.
+ // This function is renamed from cmapId to GetCMapId().
+ virtual CMapId GetCMapId(int32_t index);
+
+ virtual int32_t PlatformId(int32_t index);
+ virtual int32_t EncodingId(int32_t index);
+
+ // Get the offset in the table data for the cmap table with the given index.
+ // The offset is from the beginning of the table.
+ virtual int32_t Offset(int32_t index);
+
+ virtual ~CMapTable();
+
+ static const int32_t NOTDEF;
+
+ private:
+ // Offsets to specific elements in the underlying data. These offsets are
+ // relative to the start of the table or the start of sub-blocks within
+ // the table.
+ struct Offset {
+ enum {
+ kVersion = 0,
+ kNumTables = 2,
+ kEncodingRecordStart = 4,
+
+ // offsets relative to the encoding record
+ kEncodingRecordPlatformId = 0,
+ kEncodingRecordEncodingId = 2,
+ kEncodingRecordOffset = 4,
+ kEncodingRecordSize = 8,
+
+ kFormat = 0,
+
+ // Format 0: Byte encoding table
+ kFormat0Format = 0,
+ kFormat0Length = 2,
+ kFormat0Language = 4,
+ kFormat0GlyphIdArray = 6,
+
+ // Format 2: High-byte mapping through table
+ kFormat2Format = 0,
+ kFormat2Length = 2,
+ kFormat2Language = 4,
+ kFormat2SubHeaderKeys = 6,
+ kFormat2SubHeaders = 518,
+ // offset relative to the subHeader structure
+ kFormat2SubHeader_firstCode = 0,
+ kFormat2SubHeader_entryCount = 2,
+ kFormat2SubHeader_idDelta = 4,
+ kFormat2SubHeader_idRangeOffset = 6,
+ kFormat2SubHeader_structLength = 8,
+
+ // Format 4: Segment mapping to delta values
+ kFormat4Format = 0,
+ kFormat4Length = 2,
+ kFormat4Language = 4,
+ kFormat4SegCountX2 = 6,
+ kFormat4SearchRange = 8,
+ kFormat4EntrySelector = 10,
+ kFormat4RangeShift = 12,
+ kFormat4EndCount = 14,
+ kFormat4FixedSize = 16,
+
+ // format 6: Trimmed table mapping
+ kFormat6Format = 0,
+ kFormat6Length = 2,
+ kFormat6Language = 4,
+ kFormat6FirstCode = 6,
+ kFormat6EntryCount = 8,
+ kFormat6GlyphIdArray = 10,
+
+ // Format 8: mixed 16-bit and 32-bit coverage
+ kFormat8Format = 0,
+ kFormat8Length = 4,
+ kFormat8Language = 8,
+ kFormat8Is32 = 12,
+ kFormat8nGroups204 = 8204,
+ kFormat8Groups208 = 8208,
+ // offset relative to the group structure
+ kFormat8Group_startCharCode = 0,
+ kFormat8Group_endCharCode = 4,
+ kFormat8Group_startGlyphId = 8,
+ kFormat8Group_structLength = 12,
+
+ // Format 10: Trimmed array
+ kFormat10Format = 0,
+ kFormat10Length = 4,
+ kFormat10Language = 8,
+ kFormat10StartCharCode = 12,
+ kFormat10NumChars = 16,
+ kFormat10Glyphs0 = 20,
+
+ // Format 12: Segmented coverage
+ kFormat12Format = 0,
+ kFormat12Length = 4,
+ kFormat12Language = 8,
+ kFormat12nGroups = 12,
+ kFormat12Groups = 16,
+ kFormat12Groups_structLength = 12,
+ // offsets within the group structure
+ kFormat12_startCharCode = 0,
+ kFormat12_endCharCode = 4,
+ kFormat12_startGlyphId = 8,
+
+ // Format 13: Last Resort Font
+ kFormat13Format = 0,
+ kFormat13Length = 4,
+ kFormat13Language = 8,
+ kFormat13nGroups = 12,
+ kFormat13Groups = 16,
+ kFormat13Groups_structLength = 12,
+ // offsets within the group structure
+ kFormat13_startCharCode = 0,
+ kFormat13_endCharCode = 4,
+ kFormat13_glyphId = 8,
+
+ // Format 14: Unicode Variation Sequences
+ kFormat14Format = 0,
+ kFormat14Length = 2,
+
+ // TODO(stuartg): finish tables
+ // Default UVS Table
+
+ // Non-default UVS Table
+ kLast = -1
+ };
+ };
+
+ CMapTable(Header* header, ReadableFontData* data);
+
+ // Get the offset in the table data for the encoding record for the cmap with
+ // the given index. The offset is from the beginning of the table.
+ static int32_t OffsetForEncodingRecord(int32_t index);
+};
+typedef std::vector<CMapTable::CMapId> CMapIdList;
+typedef Ptr<CMapTable> CMapTablePtr;
+typedef std::vector<Ptr<CMapTable::CMapFormat4::Builder::Segment> > SegmentList;
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/font_header_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/font_header_table.cc
new file mode 100644
index 00000000000..60015ca9540
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/font_header_table.cc
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/core/font_header_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * FontHeaderTable class
+ ******************************************************************************/
+FontHeaderTable::~FontHeaderTable() {}
+
+int32_t FontHeaderTable::TableVersion() {
+ return data_->ReadFixed(Offset::kTableVersion);
+}
+
+int32_t FontHeaderTable::FontRevision() {
+ return data_->ReadFixed(Offset::kFontRevision);
+}
+
+int64_t FontHeaderTable::ChecksumAdjustment() {
+ return data_->ReadULong(Offset::kCheckSumAdjustment);
+}
+
+int64_t FontHeaderTable::MagicNumber() {
+ return data_->ReadULong(Offset::kMagicNumber);
+}
+
+int32_t FontHeaderTable::FlagsAsInt() {
+ return data_->ReadUShort(Offset::kFlags);
+}
+
+int32_t FontHeaderTable::UnitsPerEm() {
+ return data_->ReadUShort(Offset::kUnitsPerEm);
+}
+
+int64_t FontHeaderTable::Created() {
+ return data_->ReadDateTimeAsLong(Offset::kCreated);
+}
+
+int64_t FontHeaderTable::Modified() {
+ return data_->ReadDateTimeAsLong(Offset::kModified);
+}
+
+int32_t FontHeaderTable::XMin() {
+ return data_->ReadUShort(Offset::kXMin);
+}
+
+int32_t FontHeaderTable::YMin() {
+ return data_->ReadUShort(Offset::kYMin);
+}
+
+int32_t FontHeaderTable::XMax() {
+ return data_->ReadUShort(Offset::kXMax);
+}
+
+int32_t FontHeaderTable::YMax() {
+ return data_->ReadUShort(Offset::kYMax);
+}
+
+int32_t FontHeaderTable::MacStyleAsInt() {
+ return data_->ReadUShort(Offset::kMacStyle);
+}
+
+int32_t FontHeaderTable::LowestRecPPEM() {
+ return data_->ReadUShort(Offset::kLowestRecPPEM);
+}
+
+int32_t FontHeaderTable::FontDirectionHint() {
+ return data_->ReadShort(Offset::kFontDirectionHint);
+}
+
+int32_t FontHeaderTable::IndexToLocFormat() {
+ return data_->ReadShort(Offset::kIndexToLocFormat);
+}
+
+int32_t FontHeaderTable::GlyphDataFormat() {
+ return data_->ReadShort(Offset::kGlyphDataFormat);
+}
+
+FontHeaderTable::FontHeaderTable(Header* header, ReadableFontData* data)
+ : Table(header, data) {
+ IntegerList checksum_ranges;
+ checksum_ranges.push_back(0);
+ checksum_ranges.push_back(Offset::kCheckSumAdjustment);
+ checksum_ranges.push_back(Offset::kMagicNumber);
+ data_->SetCheckSumRanges(checksum_ranges);
+}
+
+/******************************************************************************
+ * FontHeaderTable::Builder class
+ ******************************************************************************/
+FontHeaderTable::Builder::Builder(Header* header, WritableFontData* data)
+ : TableBasedTableBuilder(header, data) {
+}
+
+FontHeaderTable::Builder::Builder(Header* header, ReadableFontData* data)
+ : TableBasedTableBuilder(header, data) {
+}
+
+FontHeaderTable::Builder::~Builder() {}
+
+CALLER_ATTACH FontDataTable* FontHeaderTable::Builder::SubBuildTable(
+ ReadableFontData* data) {
+ FontDataTablePtr table = new FontHeaderTable(header(), data);
+ return table.Detach();
+}
+
+int32_t FontHeaderTable::Builder::TableVersion() {
+ return down_cast<FontHeaderTable*>(GetTable())->TableVersion();
+}
+
+void FontHeaderTable::Builder::SetTableVersion(int32_t version) {
+ InternalWriteData()->WriteFixed(Offset::kTableVersion, version);
+}
+
+int32_t FontHeaderTable::Builder::FontRevision() {
+ return down_cast<FontHeaderTable*>(GetTable())->FontRevision();
+}
+
+void FontHeaderTable::Builder::SetFontRevision(int32_t revision) {
+ InternalWriteData()->WriteFixed(Offset::kFontRevision, revision);
+}
+
+int64_t FontHeaderTable::Builder::ChecksumAdjustment() {
+ return down_cast<FontHeaderTable*>(GetTable())->ChecksumAdjustment();
+}
+
+void FontHeaderTable::Builder::SetChecksumAdjustment(int64_t adjustment) {
+ InternalWriteData()->WriteULong(Offset::kCheckSumAdjustment, adjustment);
+}
+
+int64_t FontHeaderTable::Builder::MagicNumber() {
+ return down_cast<FontHeaderTable*>(GetTable())->MagicNumber();
+}
+
+void FontHeaderTable::Builder::SetMagicNumber(int64_t magic_number) {
+ InternalWriteData()->WriteULong(Offset::kMagicNumber, magic_number);
+}
+
+int32_t FontHeaderTable::Builder::FlagsAsInt() {
+ return down_cast<FontHeaderTable*>(GetTable())->FlagsAsInt();
+}
+
+void FontHeaderTable::Builder::SetFlagsAsInt(int32_t flags) {
+ InternalWriteData()->WriteUShort(Offset::kFlags, flags);
+}
+
+int32_t FontHeaderTable::Builder::UnitsPerEm() {
+ return down_cast<FontHeaderTable*>(GetTable())->UnitsPerEm();
+}
+
+void FontHeaderTable::Builder::SetUnitsPerEm(int32_t units) {
+ InternalWriteData()->WriteUShort(Offset::kUnitsPerEm, units);
+}
+
+int64_t FontHeaderTable::Builder::Created() {
+ return down_cast<FontHeaderTable*>(GetTable())->Created();
+}
+
+void FontHeaderTable::Builder::SetCreated(int64_t date) {
+ InternalWriteData()->WriteDateTime(Offset::kCreated, date);
+}
+
+int64_t FontHeaderTable::Builder::Modified() {
+ return down_cast<FontHeaderTable*>(GetTable())->Modified();
+}
+
+void FontHeaderTable::Builder::SetModified(int64_t date) {
+ InternalWriteData()->WriteDateTime(Offset::kModified, date);
+}
+
+int32_t FontHeaderTable::Builder::XMin() {
+ return down_cast<FontHeaderTable*>(GetTable())->XMin();
+}
+
+void FontHeaderTable::Builder::SetXMin(int32_t xmin) {
+ InternalWriteData()->WriteShort(Offset::kXMin, xmin);
+}
+
+int32_t FontHeaderTable::Builder::YMin() {
+ return down_cast<FontHeaderTable*>(GetTable())->YMin();
+}
+
+void FontHeaderTable::Builder::SetYMin(int32_t ymin) {
+ InternalWriteData()->WriteShort(Offset::kYMin, ymin);
+}
+
+int32_t FontHeaderTable::Builder::XMax() {
+ return down_cast<FontHeaderTable*>(GetTable())->XMax();
+}
+
+void FontHeaderTable::Builder::SetXMax(int32_t xmax) {
+ InternalWriteData()->WriteShort(Offset::kXMax, xmax);
+}
+
+int32_t FontHeaderTable::Builder::YMax() {
+ return down_cast<FontHeaderTable*>(GetTable())->YMax();
+}
+
+void FontHeaderTable::Builder::SetYMax(int32_t ymax) {
+ InternalWriteData()->WriteShort(Offset::kYMax, ymax);
+}
+
+int32_t FontHeaderTable::Builder::MacStyleAsInt() {
+ return down_cast<FontHeaderTable*>(GetTable())->MacStyleAsInt();
+}
+
+void FontHeaderTable::Builder::SetMacStyleAsInt(int32_t style) {
+ InternalWriteData()->WriteUShort(Offset::kMacStyle, style);
+}
+
+int32_t FontHeaderTable::Builder::LowestRecPPEM() {
+ return down_cast<FontHeaderTable*>(GetTable())->LowestRecPPEM();
+}
+
+void FontHeaderTable::Builder::SetLowestRecPPEM(int32_t size) {
+ InternalWriteData()->WriteUShort(Offset::kLowestRecPPEM, size);
+}
+
+int32_t FontHeaderTable::Builder::FontDirectionHint() {
+ return down_cast<FontHeaderTable*>(GetTable())->FontDirectionHint();
+}
+
+void FontHeaderTable::Builder::SetFontDirectionHint(int32_t hint) {
+ InternalWriteData()->WriteShort(Offset::kFontDirectionHint, hint);
+}
+
+int32_t FontHeaderTable::Builder::IndexToLocFormat() {
+ return down_cast<FontHeaderTable*>(GetTable())->IndexToLocFormat();
+}
+
+void FontHeaderTable::Builder::SetIndexToLocFormat(int32_t format) {
+ InternalWriteData()->WriteShort(Offset::kIndexToLocFormat, format);
+}
+
+int32_t FontHeaderTable::Builder::GlyphDataFormat() {
+ return down_cast<FontHeaderTable*>(GetTable())->GlyphDataFormat();
+}
+
+void FontHeaderTable::Builder::SetGlyphDataFormat(int32_t format) {
+ InternalWriteData()->WriteShort(Offset::kGlyphDataFormat, format);
+}
+
+CALLER_ATTACH FontHeaderTable::Builder*
+ FontHeaderTable::Builder::CreateBuilder(Header* header,
+ WritableFontData* data) {
+ Ptr<FontHeaderTable::Builder> builder;
+ builder = new FontHeaderTable::Builder(header, data);
+ return builder.Detach();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/font_header_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/font_header_table.h
new file mode 100644
index 00000000000..841955b4238
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/font_header_table.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_FONT_HEADER_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_FONT_HEADER_TABLE_H_
+
+#include "sfntly/table/table.h"
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+struct IndexToLocFormat {
+ enum {
+ kShortOffset = 0,
+ kLongOffset = 1
+ };
+};
+
+struct FontDirectionHint {
+ enum {
+ kFullyMixed = 0,
+ kOnlyStrongLTR = 1,
+ kStrongLTRAndNeutral = 2,
+ kOnlyStrongRTL = -1,
+ kStrongRTLAndNeutral = -2
+ };
+};
+
+class FontHeaderTable : public Table, public RefCounted<FontHeaderTable> {
+ public:
+ class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
+ public:
+ // Constructor scope altered to public because C++ does not allow base
+ // class to instantiate derived class with protected constructors.
+ Builder(Header* header, WritableFontData* data);
+ Builder(Header* header, ReadableFontData* data);
+ virtual ~Builder();
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+ virtual int32_t TableVersion();
+ virtual void SetTableVersion(int32_t version);
+ virtual int32_t FontRevision();
+ virtual void SetFontRevision(int32_t revision);
+ virtual int64_t ChecksumAdjustment();
+ virtual void SetChecksumAdjustment(int64_t adjustment);
+ virtual int64_t MagicNumber();
+ virtual void SetMagicNumber(int64_t magic_number);
+ virtual int32_t FlagsAsInt();
+ virtual void SetFlagsAsInt(int32_t flags);
+ // TODO(arthurhsu): IMPLEMENT EnumSet<Flags> Flags()
+ // TODO(arthurhsu): IMPLEMENT setFlags(EnumSet<Flags> flags)
+ virtual int32_t UnitsPerEm();
+ virtual void SetUnitsPerEm(int32_t units);
+ virtual int64_t Created();
+ virtual void SetCreated(int64_t date);
+ virtual int64_t Modified();
+ virtual void SetModified(int64_t date);
+ virtual int32_t XMin();
+ virtual void SetXMin(int32_t xmin);
+ virtual int32_t YMin();
+ virtual void SetYMin(int32_t ymin);
+ virtual int32_t XMax();
+ virtual void SetXMax(int32_t xmax);
+ virtual int32_t YMax();
+ virtual void SetYMax(int32_t ymax);
+ virtual int32_t MacStyleAsInt();
+ virtual void SetMacStyleAsInt(int32_t style);
+ // TODO(arthurhsu): IMPLEMENT EnumSet<MacStyle> macStyle()
+ // TODO(arthurhsu): IMPLEMENT setMacStyle(EnumSet<MacStyle> style)
+ virtual int32_t LowestRecPPEM();
+ virtual void SetLowestRecPPEM(int32_t size);
+ virtual int32_t FontDirectionHint();
+ virtual void SetFontDirectionHint(int32_t hint);
+ virtual int32_t IndexToLocFormat();
+ virtual void SetIndexToLocFormat(int32_t format);
+ virtual int32_t GlyphDataFormat();
+ virtual void SetGlyphDataFormat(int32_t format);
+
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ WritableFontData* data);
+ };
+
+ virtual ~FontHeaderTable();
+ int32_t TableVersion();
+ int32_t FontRevision();
+
+ // Get the checksum adjustment. To compute: set it to 0, sum the entire font
+ // as ULONG, then store 0xB1B0AFBA - sum.
+ int64_t ChecksumAdjustment();
+
+ // Get the magic number. Set to 0x5F0F3CF5.
+ int64_t MagicNumber();
+
+ // TODO(arthurhsu): IMPLEMENT: EnumSet<Flags>
+ int32_t FlagsAsInt();
+ // TODO(arthurhsu): IMPLEMENT: Flags() returning EnumSet<Flags>
+
+ int32_t UnitsPerEm();
+
+ // Get the created date. Number of seconds since 12:00 midnight, January 1,
+ // 1904. 64-bit integer.
+ int64_t Created();
+ // Get the modified date. Number of seconds since 12:00 midnight, January 1,
+ // 1904. 64-bit integer.
+ int64_t Modified();
+
+ // Get the x min. For all glyph bounding boxes.
+ int32_t XMin();
+ // Get the y min. For all glyph bounding boxes.
+ int32_t YMin();
+ // Get the x max. For all glyph bounding boxes.
+ int32_t XMax();
+ // Get the y max. For all glyph bounding boxes.
+ int32_t YMax();
+
+ // TODO(arthurhsu): IMPLEMENT: EnumSet<MacStyle>
+ int32_t MacStyleAsInt();
+ // TODO(arthurhsu): IMPLEMENT: macStyle() returning EnumSet<MacStyle>
+
+ int32_t LowestRecPPEM();
+ int32_t FontDirectionHint(); // Note: no AsInt() form, already int
+ int32_t IndexToLocFormat(); // Note: no AsInt() form, already int
+ int32_t GlyphDataFormat();
+
+ private:
+ struct Offset {
+ enum {
+ kTableVersion = 0,
+ kFontRevision = 4,
+ kCheckSumAdjustment = 8,
+ kMagicNumber = 12,
+ kFlags = 16,
+ kUnitsPerEm = 18,
+ kCreated = 20,
+ kModified = 28,
+ kXMin = 36,
+ kYMin = 38,
+ kXMax = 40,
+ kYMax = 42,
+ kMacStyle = 44,
+ kLowestRecPPEM = 46,
+ kFontDirectionHint = 48,
+ kIndexToLocFormat = 50,
+ kGlyphDataFormat = 52
+ };
+ };
+
+ FontHeaderTable(Header* header, ReadableFontData* data);
+};
+typedef Ptr<FontHeaderTable> FontHeaderTablePtr;
+typedef Ptr<FontHeaderTable::Builder> FontHeaderTableBuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_FONT_HEADER_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_device_metrics_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_device_metrics_table.cc
new file mode 100644
index 00000000000..50b0cf579dc
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_device_metrics_table.cc
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/core/horizontal_device_metrics_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * HorizontalDeviceMetricsTable class
+ ******************************************************************************/
+HorizontalDeviceMetricsTable:: ~HorizontalDeviceMetricsTable() {}
+
+int32_t HorizontalDeviceMetricsTable::Version() {
+ return data_->ReadUShort(Offset::kVersion);
+}
+
+int32_t HorizontalDeviceMetricsTable::NumRecords() {
+ return data_->ReadShort(Offset::kNumRecords);
+}
+
+int32_t HorizontalDeviceMetricsTable::RecordSize() {
+ return data_->ReadLong(Offset::kSizeDeviceRecord);
+}
+
+int32_t HorizontalDeviceMetricsTable::PixelSize(int32_t record_index) {
+ if (record_index < 0 || record_index >= NumRecords()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundsException();
+#endif
+ return -1;
+ }
+ return data_->ReadUByte(Offset::kRecords + record_index * RecordSize() +
+ Offset::kDeviceRecordPixelSize);
+}
+
+int32_t HorizontalDeviceMetricsTable::MaxWidth(int32_t record_index) {
+ if (record_index < 0 || record_index >= NumRecords()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundsException();
+#endif
+ return -1;
+ }
+ return data_->ReadUByte(Offset::kRecords + record_index * RecordSize() +
+ Offset::kDeviceRecordMaxWidth);
+}
+
+int32_t HorizontalDeviceMetricsTable::Width(int32_t record_index,
+ int32_t glyph_num) {
+ if (record_index < 0 || record_index >= NumRecords() ||
+ glyph_num < 0 || glyph_num >= num_glyphs_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundsException();
+#endif
+ return -1;
+ }
+ return data_->ReadUByte(Offset::kRecords + record_index * RecordSize() +
+ Offset::kDeviceRecordWidths + glyph_num);
+}
+
+HorizontalDeviceMetricsTable::HorizontalDeviceMetricsTable(
+ Header* header,
+ ReadableFontData* data,
+ int32_t num_glyphs)
+ : Table(header, data), num_glyphs_(num_glyphs) {
+}
+
+/******************************************************************************
+ * HorizontalDeviceMetricsTable::Builder class
+ ******************************************************************************/
+HorizontalDeviceMetricsTable::Builder::Builder(Header* header,
+ WritableFontData* data)
+ : TableBasedTableBuilder(header, data), num_glyphs_(-1) {
+}
+
+HorizontalDeviceMetricsTable::Builder::Builder(Header* header,
+ ReadableFontData* data)
+ : TableBasedTableBuilder(header, data), num_glyphs_(-1) {
+}
+
+HorizontalDeviceMetricsTable::Builder::~Builder() {}
+
+CALLER_ATTACH FontDataTable*
+HorizontalDeviceMetricsTable::Builder::SubBuildTable(ReadableFontData* data) {
+ FontDataTablePtr table = new HorizontalDeviceMetricsTable(header(), data,
+ num_glyphs_);
+ return table.Detach();
+}
+
+void HorizontalDeviceMetricsTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
+ if (num_glyphs < 0) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IllegalArgumentException("Number of glyphs can't be negative.");
+#endif
+ return;
+ }
+ num_glyphs_ = num_glyphs;
+ HorizontalDeviceMetricsTable* table =
+ down_cast<HorizontalDeviceMetricsTable*>(GetTable());
+ if (table) {
+ table->num_glyphs_ = num_glyphs;
+ }
+}
+
+CALLER_ATTACH HorizontalDeviceMetricsTable::Builder*
+HorizontalDeviceMetricsTable::Builder::CreateBuilder(Header* header,
+ WritableFontData* data) {
+ Ptr<HorizontalDeviceMetricsTable::Builder> builder;
+ builder = new HorizontalDeviceMetricsTable::Builder(header, data);
+ return builder.Detach();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_device_metrics_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_device_metrics_table.h
new file mode 100644
index 00000000000..4a27ba0964d
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_device_metrics_table.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_DEVICE_METRICS_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_DEVICE_METRICS_TABLE_H_
+
+#include "sfntly/table/table.h"
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+// A Horizontal Device Metrics table - 'hdmx'
+class HorizontalDeviceMetricsTable
+ : public Table,
+ public RefCounted<HorizontalDeviceMetricsTable> {
+ public:
+ class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
+ public:
+ // Constructor scope altered to public because C++ does not allow base
+ // class to instantiate derived class with protected constructors.
+ Builder(Header* header, WritableFontData* data);
+ Builder(Header* header, ReadableFontData* data);
+ virtual ~Builder();
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ WritableFontData* data);
+
+ void SetNumGlyphs(int32_t num_glyphs);
+
+ private:
+ int32_t num_glyphs_;
+ };
+
+ virtual ~HorizontalDeviceMetricsTable();
+
+ int32_t Version();
+ int32_t NumRecords();
+ int32_t RecordSize();
+ int32_t PixelSize(int32_t record_index);
+ int32_t MaxWidth(int32_t record_index);
+ int32_t Width(int32_t record_index, int32_t glyph_num);
+
+ private:
+ struct Offset {
+ enum {
+ kVersion = 0,
+ kNumRecords = 2,
+ kSizeDeviceRecord = 4,
+ kRecords = 8,
+
+ // Offsets within a device record
+ kDeviceRecordPixelSize = 0,
+ kDeviceRecordMaxWidth = 1,
+ kDeviceRecordWidths = 2,
+ };
+ };
+ HorizontalDeviceMetricsTable(Header* header,
+ ReadableFontData* data,
+ int32_t num_glyphs);
+
+ int32_t num_glyphs_;
+};
+typedef Ptr<HorizontalDeviceMetricsTable> HorizontalDeviceMetricsTablePtr;
+typedef Ptr<HorizontalDeviceMetricsTable::Builder>
+ HorizontalDeviceMetricsTableBuilderPtr;
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_DEVICE_METRICS_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_header_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_header_table.cc
new file mode 100644
index 00000000000..43c20585d3a
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_header_table.cc
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/core/horizontal_header_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * HorizontalHeaderTable class
+ ******************************************************************************/
+HorizontalHeaderTable:: ~HorizontalHeaderTable() {}
+
+int32_t HorizontalHeaderTable::TableVersion() {
+ return data_->ReadFixed(Offset::kVersion);
+}
+
+int32_t HorizontalHeaderTable::Ascender() {
+ return data_->ReadShort(Offset::kAscender);
+}
+
+int32_t HorizontalHeaderTable::Descender() {
+ return data_->ReadShort(Offset::kDescender);
+}
+
+int32_t HorizontalHeaderTable::LineGap() {
+ return data_->ReadShort(Offset::kLineGap);
+}
+
+int32_t HorizontalHeaderTable::AdvanceWidthMax() {
+ return data_->ReadUShort(Offset::kAdvanceWidthMax);
+}
+
+int32_t HorizontalHeaderTable::MinLeftSideBearing() {
+ return data_->ReadShort(Offset::kMinLeftSideBearing);
+}
+
+int32_t HorizontalHeaderTable::MinRightSideBearing() {
+ return data_->ReadShort(Offset::kMinRightSideBearing);
+}
+
+int32_t HorizontalHeaderTable::XMaxExtent() {
+ return data_->ReadShort(Offset::kXMaxExtent);
+}
+
+int32_t HorizontalHeaderTable::CaretSlopeRise() {
+ return data_->ReadShort(Offset::kCaretSlopeRise);
+}
+
+int32_t HorizontalHeaderTable::CaretSlopeRun() {
+ return data_->ReadShort(Offset::kCaretSlopeRun);
+}
+
+int32_t HorizontalHeaderTable::CaretOffset() {
+ return data_->ReadShort(Offset::kCaretOffset);
+}
+
+int32_t HorizontalHeaderTable::MetricDataFormat() {
+ return data_->ReadShort(Offset::kMetricDataFormat);
+}
+
+int32_t HorizontalHeaderTable::NumberOfHMetrics() {
+ return data_->ReadUShort(Offset::kNumberOfHMetrics);
+}
+
+HorizontalHeaderTable:: HorizontalHeaderTable(Header* header,
+ ReadableFontData* data)
+ : Table(header, data) {
+}
+
+/******************************************************************************
+ * HorizontalHeaderTable::Builder class
+ ******************************************************************************/
+HorizontalHeaderTable::Builder::Builder(Header* header, WritableFontData* data)
+ : TableBasedTableBuilder(header, data) {
+}
+
+HorizontalHeaderTable::Builder::Builder(Header* header, ReadableFontData* data)
+ : TableBasedTableBuilder(header, data) {
+}
+
+HorizontalHeaderTable::Builder::~Builder() {}
+
+CALLER_ATTACH FontDataTable*
+ HorizontalHeaderTable::Builder::SubBuildTable(ReadableFontData* data) {
+ FontDataTablePtr table = new HorizontalHeaderTable(header(), data);
+ return table.Detach();
+}
+
+CALLER_ATTACH HorizontalHeaderTable::Builder*
+ HorizontalHeaderTable::Builder::CreateBuilder(Header* header,
+ WritableFontData* data) {
+ Ptr<HorizontalHeaderTable::Builder> builder;
+ builder = new HorizontalHeaderTable::Builder(header, data);
+ return builder.Detach();
+}
+
+int32_t HorizontalHeaderTable::Builder::TableVersion() {
+ return InternalReadData()->ReadFixed(Offset::kVersion);
+}
+
+void HorizontalHeaderTable::Builder::SetTableVersion(int32_t version) {
+ InternalWriteData()->WriteFixed(Offset::kVersion, version);
+}
+
+int32_t HorizontalHeaderTable::Builder::Ascender() {
+ return InternalReadData()->ReadShort(Offset::kAscender);
+}
+
+void HorizontalHeaderTable::Builder::SetAscender(int32_t ascender) {
+ InternalWriteData()->WriteShort(Offset::kVersion, ascender);
+}
+
+int32_t HorizontalHeaderTable::Builder::Descender() {
+ return InternalReadData()->ReadShort(Offset::kDescender);
+}
+
+void HorizontalHeaderTable::Builder::SetDescender(int32_t descender) {
+ InternalWriteData()->WriteShort(Offset::kDescender, descender);
+}
+
+int32_t HorizontalHeaderTable::Builder::LineGap() {
+ return InternalReadData()->ReadShort(Offset::kLineGap);
+}
+
+void HorizontalHeaderTable::Builder::SetLineGap(int32_t line_gap) {
+ InternalWriteData()->WriteShort(Offset::kLineGap, line_gap);
+}
+
+int32_t HorizontalHeaderTable::Builder::AdvanceWidthMax() {
+ return InternalReadData()->ReadUShort(Offset::kAdvanceWidthMax);
+}
+
+void HorizontalHeaderTable::Builder::SetAdvanceWidthMax(int32_t value) {
+ InternalWriteData()->WriteUShort(Offset::kAdvanceWidthMax, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::MinLeftSideBearing() {
+ return InternalReadData()->ReadShort(Offset::kMinLeftSideBearing);
+}
+
+void HorizontalHeaderTable::Builder::SetMinLeftSideBearing(int32_t value) {
+ InternalWriteData()->WriteShort(Offset::kMinLeftSideBearing, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::MinRightSideBearing() {
+ return InternalReadData()->ReadShort(Offset::kMinRightSideBearing);
+}
+
+void HorizontalHeaderTable::Builder::SetMinRightSideBearing(int32_t value) {
+ InternalWriteData()->WriteShort(Offset::kMinRightSideBearing, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::XMaxExtent() {
+ return InternalReadData()->ReadShort(Offset::kXMaxExtent);
+}
+
+void HorizontalHeaderTable::Builder::SetXMaxExtent(int32_t value) {
+ InternalWriteData()->WriteShort(Offset::kXMaxExtent, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::CaretSlopeRise() {
+ return InternalReadData()->ReadUShort(Offset::kCaretSlopeRise);
+}
+
+void HorizontalHeaderTable::Builder::SetCaretSlopeRise(int32_t value) {
+ InternalWriteData()->WriteUShort(Offset::kCaretSlopeRise, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::CaretSlopeRun() {
+ return InternalReadData()->ReadUShort(Offset::kCaretSlopeRun);
+}
+
+void HorizontalHeaderTable::Builder::SetCaretSlopeRun(int32_t value) {
+ InternalWriteData()->WriteUShort(Offset::kCaretSlopeRun, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::CaretOffset() {
+ return InternalReadData()->ReadUShort(Offset::kCaretOffset);
+}
+
+void HorizontalHeaderTable::Builder::SetCaretOffset(int32_t value) {
+ InternalWriteData()->WriteUShort(Offset::kCaretOffset, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::MetricDataFormat() {
+ return InternalReadData()->ReadUShort(Offset::kMetricDataFormat);
+}
+
+void HorizontalHeaderTable::Builder::SetMetricDataFormat(int32_t value) {
+ InternalWriteData()->WriteUShort(Offset::kMetricDataFormat, value);
+}
+
+int32_t HorizontalHeaderTable::Builder::NumberOfHMetrics() {
+ return InternalReadData()->ReadUShort(Offset::kNumberOfHMetrics);
+}
+
+void HorizontalHeaderTable::Builder::SetNumberOfHMetrics(int32_t value) {
+ InternalWriteData()->WriteUShort(Offset::kNumberOfHMetrics, value);
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_header_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_header_table.h
new file mode 100644
index 00000000000..71f30b44756
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_header_table.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_HEADER_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_HEADER_TABLE_H_
+
+#include "sfntly/table/table.h"
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+// A Horizontal Header table - 'hhea'.
+class HorizontalHeaderTable : public Table,
+ public RefCounted<HorizontalHeaderTable> {
+ public:
+ // Builder for a Horizontal Header table - 'hhea'.
+ class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
+ public:
+ // Constructor scope altered to public because C++ does not allow base
+ // class to instantiate derived class with protected constructors.
+ Builder(Header* header, WritableFontData* data);
+ Builder(Header* header, ReadableFontData* data);
+ virtual ~Builder();
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ WritableFontData* data);
+
+ int32_t TableVersion();
+ void SetTableVersion(int32_t version);
+ int32_t Ascender();
+ void SetAscender(int32_t ascender);
+ int32_t Descender();
+ void SetDescender(int32_t descender);
+ int32_t LineGap();
+ void SetLineGap(int32_t line_gap);
+ int32_t AdvanceWidthMax();
+ void SetAdvanceWidthMax(int32_t value);
+ int32_t MinLeftSideBearing();
+ void SetMinLeftSideBearing(int32_t value);
+ int32_t MinRightSideBearing();
+ void SetMinRightSideBearing(int32_t value);
+ int32_t XMaxExtent();
+ void SetXMaxExtent(int32_t value);
+ int32_t CaretSlopeRise();
+ void SetCaretSlopeRise(int32_t value);
+ int32_t CaretSlopeRun();
+ void SetCaretSlopeRun(int32_t value);
+ int32_t CaretOffset();
+ void SetCaretOffset(int32_t value);
+ int32_t MetricDataFormat();
+ void SetMetricDataFormat(int32_t value);
+ int32_t NumberOfHMetrics();
+ void SetNumberOfHMetrics(int32_t value);
+ };
+
+ virtual ~HorizontalHeaderTable();
+ int32_t TableVersion();
+ int32_t Ascender();
+ int32_t Descender();
+ int32_t LineGap();
+ int32_t AdvanceWidthMax();
+ int32_t MinLeftSideBearing();
+ int32_t MinRightSideBearing();
+ int32_t XMaxExtent();
+ int32_t CaretSlopeRise();
+ int32_t CaretSlopeRun();
+ int32_t CaretOffset();
+ int32_t MetricDataFormat();
+ int32_t NumberOfHMetrics();
+
+ private:
+ struct Offset {
+ enum {
+ kVersion = 0,
+ kAscender = 4,
+ kDescender = 6,
+ kLineGap = 8,
+ kAdvanceWidthMax = 10,
+ kMinLeftSideBearing = 12,
+ kMinRightSideBearing = 14,
+ kXMaxExtent = 16,
+ kCaretSlopeRise = 18,
+ kCaretSlopeRun = 20,
+ kCaretOffset = 22,
+ kMetricDataFormat = 32,
+ kNumberOfHMetrics = 34,
+ };
+ };
+
+ HorizontalHeaderTable(Header* header, ReadableFontData* data);
+};
+typedef Ptr<HorizontalHeaderTable> HorizontalHeaderTablePtr;
+typedef Ptr<HorizontalHeaderTable::Builder> HorizontalHeaderTableBuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_HEADER_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_metrics_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_metrics_table.cc
new file mode 100644
index 00000000000..156387daaf2
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_metrics_table.cc
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/core/horizontal_metrics_table.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+/******************************************************************************
+ * HorizontalMetricsTable class
+ ******************************************************************************/
+HorizontalMetricsTable::~HorizontalMetricsTable() {}
+
+int32_t HorizontalMetricsTable::NumberOfHMetrics() {
+ return num_hmetrics_;
+}
+
+int32_t HorizontalMetricsTable::NumberOfLSBs() {
+ return num_glyphs_ - num_hmetrics_;
+}
+
+int32_t HorizontalMetricsTable::HMetricAdvanceWidth(int32_t entry) {
+ if (entry > num_hmetrics_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundException();
+#endif
+ return 0;
+ }
+ int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) +
+ Offset::kHMetricsAdvanceWidth;
+ return data_->ReadUShort(offset);
+}
+
+int32_t HorizontalMetricsTable::HMetricLSB(int32_t entry) {
+ if (entry > num_hmetrics_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundException();
+#endif
+ return 0;
+ }
+ int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) +
+ Offset::kHMetricsLeftSideBearing;
+ return data_->ReadShort(offset);
+}
+
+int32_t HorizontalMetricsTable::LsbTableEntry(int32_t entry) {
+ if (entry > num_hmetrics_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundException();
+#endif
+ return 0;
+ }
+ int32_t offset = Offset::kHMetricsStart + (entry * Offset::kHMetricsSize) +
+ Offset::kLeftSideBearingSize;
+ return data_->ReadShort(offset);
+}
+
+int32_t HorizontalMetricsTable::AdvanceWidth(int32_t glyph_id) {
+ if (glyph_id < num_hmetrics_) {
+ return HMetricAdvanceWidth(glyph_id);
+ }
+ return HMetricAdvanceWidth(glyph_id - num_hmetrics_);
+}
+
+int32_t HorizontalMetricsTable::LeftSideBearing(int32_t glyph_id) {
+ if (glyph_id < num_hmetrics_) {
+ return HMetricLSB(glyph_id);
+ }
+ return LsbTableEntry(glyph_id - num_hmetrics_);
+}
+
+HorizontalMetricsTable::HorizontalMetricsTable(Header* header,
+ ReadableFontData* data,
+ int32_t num_hmetrics,
+ int32_t num_glyphs)
+ : Table(header, data),
+ num_hmetrics_(num_hmetrics),
+ num_glyphs_(num_glyphs) {
+}
+
+/******************************************************************************
+ * HorizontalMetricsTable::Builder class
+ ******************************************************************************/
+HorizontalMetricsTable::Builder::Builder(Header* header, WritableFontData* data)
+ : TableBasedTableBuilder(header, data), num_hmetrics_(-1), num_glyphs_(-1) {
+}
+
+HorizontalMetricsTable::Builder::Builder(Header* header, ReadableFontData* data)
+ : TableBasedTableBuilder(header, data), num_hmetrics_(-1), num_glyphs_(-1) {
+}
+
+HorizontalMetricsTable::Builder::~Builder() {}
+
+CALLER_ATTACH FontDataTable*
+ HorizontalMetricsTable::Builder::SubBuildTable(ReadableFontData* data) {
+ FontDataTablePtr table =
+ new HorizontalMetricsTable(header(), data, num_hmetrics_, num_glyphs_);
+ return table.Detach();
+}
+
+CALLER_ATTACH HorizontalMetricsTable::Builder*
+ HorizontalMetricsTable::Builder::CreateBuilder(Header* header,
+ WritableFontData* data) {
+ Ptr<HorizontalMetricsTable::Builder> builder;
+ builder = new HorizontalMetricsTable::Builder(header, data);
+ return builder.Detach();
+}
+
+void HorizontalMetricsTable::Builder::SetNumberOfHMetrics(
+ int32_t num_hmetrics) {
+ assert(num_hmetrics >= 0);
+ num_hmetrics_ = num_hmetrics;
+ HorizontalMetricsTable* table =
+ down_cast<HorizontalMetricsTable*>(this->GetTable());
+ table->num_hmetrics_ = num_hmetrics;
+}
+
+void HorizontalMetricsTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
+ assert(num_glyphs >= 0);
+ num_glyphs_ = num_glyphs;
+ HorizontalMetricsTable* table =
+ down_cast<HorizontalMetricsTable*>(this->GetTable());
+ table->num_glyphs_ = num_glyphs;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_metrics_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_metrics_table.h
new file mode 100644
index 00000000000..44b51f2d792
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/horizontal_metrics_table.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_METRICS_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_METRICS_TABLE_H_
+
+#include "sfntly/table/table.h"
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+// A Horizontal Metrics table - 'hmtx'.
+class HorizontalMetricsTable : public Table,
+ public RefCounted<HorizontalMetricsTable> {
+ public:
+ // Builder for a Horizontal Metrics Table - 'hmtx'.
+ class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
+ public:
+ // Constructor scope altered to public because C++ does not allow base
+ // class to instantiate derived class with protected constructors.
+ Builder(Header* header, WritableFontData* data);
+ Builder(Header* header, ReadableFontData* data);
+ virtual ~Builder();
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ WritableFontData* data);
+
+ void SetNumberOfHMetrics(int32_t num_hmetrics);
+ void SetNumGlyphs(int32_t num_glyphs);
+
+ private:
+ int32_t num_hmetrics_;
+ int32_t num_glyphs_;
+ };
+
+ virtual ~HorizontalMetricsTable();
+ int32_t NumberOfHMetrics();
+ int32_t NumberOfLSBs();
+ int32_t HMetricAdvanceWidth(int32_t entry);
+ int32_t HMetricLSB(int32_t entry);
+ int32_t LsbTableEntry(int32_t entry);
+ int32_t AdvanceWidth(int32_t glyph_id);
+ int32_t LeftSideBearing(int32_t glyph_id);
+
+ private:
+ struct Offset {
+ enum {
+ // hMetrics
+ kHMetricsStart = 0,
+ kHMetricsSize = 4,
+
+ // Offset within an hMetric
+ kHMetricsAdvanceWidth = 0,
+ kHMetricsLeftSideBearing = 2,
+
+ kLeftSideBearingSize = 2
+ };
+ };
+
+ HorizontalMetricsTable(Header* header,
+ ReadableFontData* data,
+ int32_t num_hmetrics,
+ int32_t num_glyphs);
+
+ int32_t num_hmetrics_;
+ int32_t num_glyphs_;
+};
+typedef Ptr<HorizontalMetricsTable> HorizontalMetricsTablePtr;
+typedef Ptr<HorizontalMetricsTable::Builder> HorizontalMetricsTableBuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_HORIZONTAL_METRICS_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/maximum_profile_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/maximum_profile_table.cc
new file mode 100644
index 00000000000..a8ac3bc93ab
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/maximum_profile_table.cc
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/core/maximum_profile_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * MaximumProfileTable class
+ ******************************************************************************/
+MaximumProfileTable::~MaximumProfileTable() {}
+
+int32_t MaximumProfileTable::TableVersion() {
+ return data_->ReadFixed(Offset::kVersion);
+}
+
+int32_t MaximumProfileTable::NumGlyphs() {
+ return data_->ReadUShort(Offset::kNumGlyphs);
+}
+
+int32_t MaximumProfileTable::MaxPoints() {
+ return data_->ReadUShort(Offset::kMaxPoints);
+}
+
+int32_t MaximumProfileTable::MaxContours() {
+ return data_->ReadUShort(Offset::kMaxContours);
+}
+
+int32_t MaximumProfileTable::MaxCompositePoints() {
+ return data_->ReadUShort(Offset::kMaxCompositePoints);
+}
+
+int32_t MaximumProfileTable::MaxCompositeContours() {
+ return data_->ReadUShort(Offset::kMaxCompositeContours);
+}
+
+int32_t MaximumProfileTable::MaxZones() {
+ return data_->ReadUShort(Offset::kMaxZones);
+}
+
+int32_t MaximumProfileTable::MaxTwilightPoints() {
+ return data_->ReadUShort(Offset::kMaxTwilightPoints);
+}
+
+int32_t MaximumProfileTable::MaxStorage() {
+ return data_->ReadUShort(Offset::kMaxStorage);
+}
+
+int32_t MaximumProfileTable::MaxFunctionDefs() {
+ return data_->ReadUShort(Offset::kMaxFunctionDefs);
+}
+
+int32_t MaximumProfileTable::MaxStackElements() {
+ return data_->ReadUShort(Offset::kMaxStackElements);
+}
+
+int32_t MaximumProfileTable::MaxSizeOfInstructions() {
+ return data_->ReadUShort(Offset::kMaxSizeOfInstructions);
+}
+
+int32_t MaximumProfileTable::MaxComponentElements() {
+ return data_->ReadUShort(Offset::kMaxComponentElements);
+}
+
+int32_t MaximumProfileTable::MaxComponentDepth() {
+ return data_->ReadUShort(Offset::kMaxComponentDepth);
+}
+
+MaximumProfileTable::MaximumProfileTable(Header* header,
+ ReadableFontData* data)
+ : Table(header, data) {
+}
+
+/******************************************************************************
+ * MaximumProfileTable::Builder class
+ ******************************************************************************/
+MaximumProfileTable::Builder::Builder(Header* header, WritableFontData* data)
+ : TableBasedTableBuilder(header, data) {
+}
+
+MaximumProfileTable::Builder::Builder(Header* header, ReadableFontData* data)
+ : TableBasedTableBuilder(header, data) {
+}
+
+MaximumProfileTable::Builder::~Builder() {}
+
+CALLER_ATTACH FontDataTable*
+ MaximumProfileTable::Builder::SubBuildTable(ReadableFontData* data) {
+ FontDataTablePtr table = new MaximumProfileTable(header(), data);
+ return table.Detach();
+}
+
+CALLER_ATTACH MaximumProfileTable::Builder*
+ MaximumProfileTable::Builder::CreateBuilder(Header* header,
+ WritableFontData* data) {
+ Ptr<MaximumProfileTable::Builder> builder;
+ builder = new MaximumProfileTable::Builder(header, data);
+ return builder.Detach();
+}
+
+int32_t MaximumProfileTable::Builder::TableVersion() {
+ return InternalReadData()->ReadUShort(Offset::kVersion);
+}
+
+void MaximumProfileTable::Builder::SetTableVersion(int32_t version) {
+ InternalWriteData()->WriteUShort(Offset::kVersion, version);
+}
+
+int32_t MaximumProfileTable::Builder::NumGlyphs() {
+ return InternalReadData()->ReadUShort(Offset::kNumGlyphs);
+}
+
+void MaximumProfileTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
+ InternalWriteData()->WriteUShort(Offset::kNumGlyphs, num_glyphs);
+}
+
+int32_t MaximumProfileTable::Builder::MaxPoints() {
+ return InternalReadData()->ReadUShort(Offset::kMaxPoints);
+}
+
+void MaximumProfileTable::Builder::SetMaxPoints(int32_t max_points) {
+ InternalWriteData()->WriteUShort(Offset::kMaxPoints, max_points);
+}
+
+int32_t MaximumProfileTable::Builder::MaxContours() {
+ return InternalReadData()->ReadUShort(Offset::kMaxContours);
+}
+
+void MaximumProfileTable::Builder::SetMaxContours(int32_t max_contours) {
+ InternalWriteData()->WriteUShort(Offset::kMaxContours, max_contours);
+}
+
+int32_t MaximumProfileTable::Builder::MaxCompositePoints() {
+ return InternalReadData()->ReadUShort(Offset::kMaxCompositePoints);
+}
+
+void MaximumProfileTable::Builder::SetMaxCompositePoints(
+ int32_t max_composite_points) {
+ InternalWriteData()->WriteUShort(Offset::kMaxCompositePoints,
+ max_composite_points);
+}
+
+int32_t MaximumProfileTable::Builder::MaxCompositeContours() {
+ return InternalReadData()->ReadUShort(Offset::kMaxCompositeContours);
+}
+
+void MaximumProfileTable::Builder::SetMaxCompositeContours(
+ int32_t max_composite_contours) {
+ InternalWriteData()->WriteUShort(Offset::kMaxCompositeContours,
+ max_composite_contours);
+}
+
+int32_t MaximumProfileTable::Builder::MaxZones() {
+ return InternalReadData()->ReadUShort(Offset::kMaxZones);
+}
+
+void MaximumProfileTable::Builder::SetMaxZones(int32_t max_zones) {
+ InternalWriteData()->WriteUShort(Offset::kMaxZones, max_zones);
+}
+
+int32_t MaximumProfileTable::Builder::MaxTwilightPoints() {
+ return InternalReadData()->ReadUShort(Offset::kMaxTwilightPoints);
+}
+
+void MaximumProfileTable::Builder::SetMaxTwilightPoints(
+ int32_t max_twilight_points) {
+ InternalWriteData()->WriteUShort(Offset::kMaxTwilightPoints,
+ max_twilight_points);
+}
+
+int32_t MaximumProfileTable::Builder::MaxStorage() {
+ return InternalReadData()->ReadUShort(Offset::kMaxStorage);
+}
+
+void MaximumProfileTable::Builder::SetMaxStorage(int32_t max_storage) {
+ InternalWriteData()->WriteUShort(Offset::kMaxStorage, max_storage);
+}
+
+int32_t MaximumProfileTable::Builder::MaxFunctionDefs() {
+ return InternalReadData()->ReadUShort(Offset::kMaxFunctionDefs);
+}
+
+void MaximumProfileTable::Builder::SetMaxFunctionDefs(
+ int32_t max_function_defs) {
+ InternalWriteData()->WriteUShort(Offset::kMaxFunctionDefs, max_function_defs);
+}
+
+int32_t MaximumProfileTable::Builder::MaxStackElements() {
+ return InternalReadData()->ReadUShort(Offset::kMaxStackElements);
+}
+
+void MaximumProfileTable::Builder::SetMaxStackElements(
+ int32_t max_stack_elements) {
+ InternalWriteData()->WriteUShort(Offset::kMaxStackElements,
+ max_stack_elements);
+}
+
+int32_t MaximumProfileTable::Builder::MaxSizeOfInstructions() {
+ return InternalReadData()->ReadUShort(Offset::kMaxSizeOfInstructions);
+}
+
+void MaximumProfileTable::Builder::SetMaxSizeOfInstructions(
+ int32_t max_size_of_instructions) {
+ InternalWriteData()->WriteUShort(Offset::kMaxSizeOfInstructions,
+ max_size_of_instructions);
+}
+
+int32_t MaximumProfileTable::Builder::MaxComponentElements() {
+ return InternalReadData()->ReadUShort(Offset::kMaxComponentElements);
+}
+
+void MaximumProfileTable::Builder::SetMaxComponentElements(
+ int32_t max_component_elements) {
+ InternalWriteData()->WriteUShort(Offset::kMaxComponentElements,
+ max_component_elements);
+}
+
+int32_t MaximumProfileTable::Builder::MaxComponentDepth() {
+ return InternalReadData()->ReadUShort(Offset::kMaxComponentDepth);
+}
+
+void MaximumProfileTable::Builder::SetMaxComponentDepth(
+ int32_t max_component_depth) {
+ InternalWriteData()->WriteUShort(Offset::kMaxComponentDepth,
+ max_component_depth);
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/maximum_profile_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/maximum_profile_table.h
new file mode 100644
index 00000000000..e7c5abb3ff4
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/maximum_profile_table.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_MAXIMUM_PROFILE_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_MAXIMUM_PROFILE_TABLE_H_
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/table/table.h"
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+// A Maximum Profile table - 'maxp'.
+class MaximumProfileTable : public Table,
+ public RefCounted<MaximumProfileTable> {
+ public:
+ // Builder for a Maximum Profile table - 'maxp'.
+ class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
+ public:
+ // Constructor scope altered to public because C++ does not allow base
+ // class to instantiate derived class with protected constructors.
+ Builder(Header* header, WritableFontData* data);
+ Builder(Header* header, ReadableFontData* data);
+ virtual ~Builder();
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ WritableFontData* data);
+
+ int32_t TableVersion();
+ void SetTableVersion(int32_t version);
+ int32_t NumGlyphs();
+ void SetNumGlyphs(int32_t num_glyphs);
+ int32_t MaxPoints();
+ void SetMaxPoints(int32_t max_points);
+ int32_t MaxContours();
+ void SetMaxContours(int32_t max_contours);
+ int32_t MaxCompositePoints();
+ void SetMaxCompositePoints(int32_t max_composite_points);
+ int32_t MaxCompositeContours();
+ void SetMaxCompositeContours(int32_t max_composite_contours);
+ int32_t MaxZones();
+ void SetMaxZones(int32_t max_zones);
+ int32_t MaxTwilightPoints();
+ void SetMaxTwilightPoints(int32_t max_twilight_points);
+ int32_t MaxStorage();
+ void SetMaxStorage(int32_t max_storage);
+ int32_t MaxFunctionDefs();
+ void SetMaxFunctionDefs(int32_t max_function_defs);
+ int32_t MaxStackElements();
+ void SetMaxStackElements(int32_t max_stack_elements);
+ int32_t MaxSizeOfInstructions();
+ void SetMaxSizeOfInstructions(int32_t max_size_of_instructions);
+ int32_t MaxComponentElements();
+ void SetMaxComponentElements(int32_t max_component_elements);
+ int32_t MaxComponentDepth();
+ void SetMaxComponentDepth(int32_t max_component_depth);
+ };
+
+ virtual ~MaximumProfileTable();
+ int32_t TableVersion();
+ int32_t NumGlyphs();
+ int32_t MaxPoints();
+ int32_t MaxContours();
+ int32_t MaxCompositePoints();
+ int32_t MaxCompositeContours();
+ int32_t MaxZones();
+ int32_t MaxTwilightPoints();
+ int32_t MaxStorage();
+ int32_t MaxFunctionDefs();
+ int32_t MaxStackElements();
+ int32_t MaxSizeOfInstructions();
+ int32_t MaxComponentElements();
+ int32_t MaxComponentDepth();
+
+ private:
+ struct Offset {
+ enum {
+ // version 0.5 and 1.0
+ kVersion = 0,
+ kNumGlyphs = 4,
+
+ // version 1.0
+ kMaxPoints = 6,
+ kMaxContours = 8,
+ kMaxCompositePoints = 10,
+ kMaxCompositeContours = 12,
+ kMaxZones = 14,
+ kMaxTwilightPoints = 16,
+ kMaxStorage = 18,
+ kMaxFunctionDefs = 20,
+ kMaxInstructionDefs = 22,
+ kMaxStackElements = 24,
+ kMaxSizeOfInstructions = 26,
+ kMaxComponentElements = 28,
+ kMaxComponentDepth = 30,
+ };
+ };
+
+ MaximumProfileTable(Header* header, ReadableFontData* data);
+};
+typedef Ptr<MaximumProfileTable> MaximumProfileTablePtr;
+typedef Ptr<MaximumProfileTable::Builder> MaximumProfileTableBuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_MAXIMUM_PROFILE_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/name_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/name_table.cc
new file mode 100644
index 00000000000..8d2f64f0825
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/name_table.cc
@@ -0,0 +1,723 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/core/name_table.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <unicode/unistr.h>
+
+#include "sfntly/font.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+/******************************************************************************
+ * NameTable::NameEntryId class
+ ******************************************************************************/
+NameTable::NameEntryId::NameEntryId()
+ : platform_id_(0),
+ encoding_id_(0),
+ language_id_(0),
+ name_id_(0) {
+}
+
+NameTable::NameEntryId::NameEntryId(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id)
+ : platform_id_(platform_id),
+ encoding_id_(encoding_id),
+ language_id_(language_id),
+ name_id_(name_id) {
+}
+
+NameTable::NameEntryId::NameEntryId(const NameTable::NameEntryId& rhs) {
+ *this = rhs;
+}
+
+const NameTable::NameEntryId&
+ NameTable::NameEntryId::operator=(const NameTable::NameEntryId& rhs) const {
+ platform_id_ = rhs.platform_id_;
+ encoding_id_ = rhs.encoding_id_;
+ language_id_ = rhs.language_id_;
+ name_id_ = rhs.name_id_;
+ return *this;
+}
+
+bool NameTable::NameEntryId::operator==(const NameEntryId& rhs) const {
+ return platform_id_ == rhs.platform_id_ &&
+ encoding_id_ == rhs.encoding_id_ &&
+ language_id_ == rhs.language_id_ &&
+ name_id_ == rhs.name_id_;
+}
+
+bool NameTable::NameEntryId::operator<(const NameEntryId& rhs) const {
+ if (platform_id_ != rhs.platform_id_) return platform_id_ < rhs.platform_id_;
+ if (encoding_id_ != rhs.encoding_id_) return encoding_id_ < rhs.encoding_id_;
+ if (language_id_ != rhs.language_id_) return language_id_ < rhs.language_id_;
+ return name_id_ < rhs.name_id_;
+}
+
+/******************************************************************************
+ * NameTable::NameEntry class
+ ******************************************************************************/
+NameTable::NameEntry::NameEntry() {
+ Init(0, 0, 0, 0, NULL);
+}
+
+NameTable::NameEntry::NameEntry(const NameEntryId& name_entry_id,
+ const ByteVector& name_bytes) {
+ Init(name_entry_id.platform_id(),
+ name_entry_id.encoding_id(),
+ name_entry_id.language_id(),
+ name_entry_id.name_id(),
+ &name_bytes);
+}
+
+NameTable::NameEntry::NameEntry(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id,
+ const ByteVector& name_bytes) {
+ Init(platform_id, encoding_id, language_id, name_id, &name_bytes);
+}
+
+NameTable::NameEntry::~NameEntry() {}
+
+ByteVector* NameTable::NameEntry::NameAsBytes() {
+ return &name_bytes_;
+}
+
+int32_t NameTable::NameEntry::NameBytesLength() {
+ return name_bytes_.size();
+}
+
+UChar* NameTable::NameEntry::Name() {
+ return NameTable::ConvertFromNameBytes(&name_bytes_,
+ platform_id(),
+ encoding_id());
+}
+
+bool NameTable::NameEntry::operator==(const NameEntry& rhs) const {
+ return (name_entry_id_ == rhs.name_entry_id_ &&
+ name_bytes_ == rhs.name_bytes_);
+}
+
+void NameTable::NameEntry::Init(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id,
+ const ByteVector* name_bytes) {
+ name_entry_id_ = NameEntryId(platform_id, encoding_id, language_id, name_id);
+ if (name_bytes) {
+ name_bytes_ = *name_bytes;
+ } else {
+ name_bytes_.clear();
+ }
+}
+
+/******************************************************************************
+ * NameTable::NameEntryBuilder class
+ ******************************************************************************/
+NameTable::NameEntryBuilder::NameEntryBuilder() {
+ Init(0, 0, 0, 0, NULL);
+}
+
+NameTable::NameEntryBuilder::NameEntryBuilder(const NameEntryId& name_entry_id,
+ const ByteVector& name_bytes) {
+ Init(name_entry_id.platform_id(),
+ name_entry_id.encoding_id(),
+ name_entry_id.language_id(),
+ name_entry_id.name_id(),
+ &name_bytes);
+}
+
+NameTable::NameEntryBuilder::NameEntryBuilder(
+ const NameEntryId& name_entry_id) {
+ Init(name_entry_id.platform_id(),
+ name_entry_id.encoding_id(),
+ name_entry_id.language_id(),
+ name_entry_id.name_id(),
+ NULL);
+}
+
+NameTable::NameEntryBuilder::NameEntryBuilder(NameEntry* b) {
+ Init(b->platform_id(),
+ b->encoding_id(),
+ b->language_id(),
+ b->name_id(),
+ b->NameAsBytes());
+}
+
+NameTable::NameEntryBuilder::~NameEntryBuilder() {}
+
+void NameTable::NameEntryBuilder::SetName(const UChar* name) {
+ if (name == NULL) {
+ name_entry_->name_bytes_.clear();
+ return;
+ }
+ NameTable::ConvertToNameBytes(name,
+ name_entry_->platform_id(),
+ name_entry_->encoding_id(),
+ &name_entry_->name_bytes_);
+}
+
+void NameTable::NameEntryBuilder::SetName(const ByteVector& name_bytes) {
+ name_entry_->name_bytes_.clear();
+ std::copy(name_bytes.begin(),
+ name_bytes.end(),
+ name_entry_->name_bytes_.begin());
+}
+
+void NameTable::NameEntryBuilder::SetName(const ByteVector& name_bytes,
+ int32_t offset,
+ int32_t length) {
+ name_entry_->name_bytes_.clear();
+ std::copy(name_bytes.begin() + offset,
+ name_bytes.begin() + offset + length,
+ name_entry_->name_bytes_.begin());
+}
+
+void NameTable::NameEntryBuilder::Init(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id,
+ const ByteVector* name_bytes) {
+ name_entry_ = new NameEntry();
+ name_entry_->Init(platform_id, encoding_id, language_id, name_id, name_bytes);
+}
+
+/******************************************************************************
+ * NameTable::NameEntryFilterInPlace class (C++ port only)
+ ******************************************************************************/
+NameTable::NameEntryFilterInPlace::NameEntryFilterInPlace(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id)
+ : platform_id_(platform_id),
+ encoding_id_(encoding_id),
+ language_id_(language_id),
+ name_id_(name_id) {
+}
+
+bool NameTable::NameEntryFilterInPlace::Accept(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id) {
+ return (platform_id_ == platform_id &&
+ encoding_id_ == encoding_id &&
+ language_id_ == language_id &&
+ name_id_ == name_id);
+}
+
+/******************************************************************************
+ * NameTable::NameEntryIterator class
+ ******************************************************************************/
+NameTable::NameEntryIterator::NameEntryIterator(NameTable* table)
+ : RefIterator<NameEntry, NameTable>(table),
+ name_index_(0),
+ filter_(NULL) {
+}
+
+NameTable::NameEntryIterator::NameEntryIterator(NameTable* table,
+ NameEntryFilter* filter)
+ : RefIterator<NameEntry, NameTable>(table),
+ name_index_(0),
+ filter_(filter) {
+}
+
+bool NameTable::NameEntryIterator::HasNext() {
+ if (!filter_) {
+ if (name_index_ < container()->NameCount()) {
+ return true;
+ }
+ return false;
+ }
+ for (; name_index_ < container()->NameCount(); ++name_index_) {
+ if (filter_->Accept(container()->PlatformId(name_index_),
+ container()->EncodingId(name_index_),
+ container()->LanguageId(name_index_),
+ container()->NameId(name_index_))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+CALLER_ATTACH NameTable::NameEntry* NameTable::NameEntryIterator::Next() {
+ if (!HasNext())
+ return NULL;
+ return container()->GetNameEntry(name_index_++);
+}
+
+/******************************************************************************
+ * NameTable::Builder class
+ ******************************************************************************/
+NameTable::Builder::Builder(Header* header, WritableFontData* data)
+ : SubTableContainerTable::Builder(header, data) {
+}
+
+NameTable::Builder::Builder(Header* header, ReadableFontData* data)
+ : SubTableContainerTable::Builder(header, data) {
+}
+
+CALLER_ATTACH NameTable::Builder*
+ NameTable::Builder::CreateBuilder(Header* header,
+ WritableFontData* data) {
+ Ptr<NameTable::Builder> builder;
+ builder = new NameTable::Builder(header, data);
+ return builder.Detach();
+}
+
+void NameTable::Builder::RevertNames() {
+ name_entry_map_.clear();
+ set_model_changed(false);
+}
+
+int32_t NameTable::Builder::BuilderCount() {
+ GetNameBuilders(); // Ensure name_entry_map_ is built.
+ return (int32_t)name_entry_map_.size();
+}
+
+bool NameTable::Builder::Has(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id) {
+ NameEntryId probe(platform_id, encoding_id, language_id, name_id);
+ GetNameBuilders(); // Ensure name_entry_map_ is built.
+ return (name_entry_map_.find(probe) != name_entry_map_.end());
+}
+
+CALLER_ATTACH NameTable::NameEntryBuilder*
+ NameTable::Builder::NameBuilder(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id) {
+ NameEntryId probe(platform_id, encoding_id, language_id, name_id);
+ NameEntryBuilderMap builders;
+ GetNameBuilders(); // Ensure name_entry_map_ is built.
+ if (name_entry_map_.find(probe) != name_entry_map_.end()) {
+ return name_entry_map_[probe];
+ }
+ NameEntryBuilderPtr builder = new NameEntryBuilder(probe);
+ name_entry_map_[probe] = builder;
+ return builder.Detach();
+}
+
+bool NameTable::Builder::Remove(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id) {
+ NameEntryId probe(platform_id, encoding_id, language_id, name_id);
+ GetNameBuilders(); // Ensure name_entry_map_ is built.
+ NameEntryBuilderMap::iterator position = name_entry_map_.find(probe);
+ if (position != name_entry_map_.end()) {
+ name_entry_map_.erase(position);
+ return true;
+ }
+ return false;
+}
+
+CALLER_ATTACH FontDataTable*
+ NameTable::Builder::SubBuildTable(ReadableFontData* data) {
+ FontDataTablePtr table = new NameTable(header(), data);
+ return table.Detach();
+}
+
+void NameTable::Builder::SubDataSet() {
+ name_entry_map_.clear();
+ set_model_changed(false);
+}
+
+int32_t NameTable::Builder::SubDataSizeToSerialize() {
+ if (name_entry_map_.empty()) {
+ return 0;
+ }
+
+ int32_t size = NameTable::Offset::kNameRecordStart +
+ name_entry_map_.size() * NameTable::Offset::kNameRecordSize;
+ for (NameEntryBuilderMap::iterator b = name_entry_map_.begin(),
+ end = name_entry_map_.end();
+ b != end; ++b) {
+ NameEntryBuilderPtr p = b->second;
+ NameEntry* entry = p->name_entry();
+ size += entry->NameBytesLength();
+ }
+ return size;
+}
+
+bool NameTable::Builder::SubReadyToSerialize() {
+ return !name_entry_map_.empty();
+}
+
+int32_t NameTable::Builder::SubSerialize(WritableFontData* new_data) {
+ int32_t string_table_start_offset =
+ NameTable::Offset::kNameRecordStart +
+ name_entry_map_.size() * NameTable::Offset::kNameRecordSize;
+
+ // Header
+ new_data->WriteUShort(NameTable::Offset::kFormat, 0);
+ new_data->WriteUShort(NameTable::Offset::kCount, name_entry_map_.size());
+ new_data->WriteUShort(NameTable::Offset::kStringOffset,
+ string_table_start_offset);
+ int32_t name_record_offset = NameTable::Offset::kNameRecordStart;
+ int32_t string_offset = 0;
+ // Note: we offered operator< in NameEntryId, which will be used by std::less,
+ // and therefore our map will act like TreeMap in Java to provide
+ // sorted key set.
+ for (NameEntryBuilderMap::iterator b = name_entry_map_.begin(),
+ end = name_entry_map_.end();
+ b != end; ++b) {
+ new_data->WriteUShort(
+ name_record_offset + NameTable::Offset::kNameRecordPlatformId,
+ b->first.platform_id());
+ new_data->WriteUShort(
+ name_record_offset + NameTable::Offset::kNameRecordEncodingId,
+ b->first.encoding_id());
+ new_data->WriteUShort(
+ name_record_offset + NameTable::Offset::kNameRecordLanguageId,
+ b->first.language_id());
+ new_data->WriteUShort(
+ name_record_offset + NameTable::Offset::kNameRecordNameId,
+ b->first.name_id());
+ NameEntry* builder_entry = b->second->name_entry();
+ new_data->WriteUShort(
+ name_record_offset + NameTable::Offset::kNameRecordStringLength,
+ builder_entry->NameBytesLength());
+ new_data->WriteUShort(
+ name_record_offset + NameTable::Offset::kNameRecordStringOffset,
+ string_offset);
+ name_record_offset += NameTable::Offset::kNameRecordSize;
+ string_offset += new_data->WriteBytes(
+ string_offset + string_table_start_offset,
+ builder_entry->NameAsBytes());
+ }
+
+ return string_offset + string_table_start_offset;
+}
+
+void NameTable::Builder::Initialize(ReadableFontData* data) {
+ if (data) {
+ NameTablePtr table = new NameTable(header(), data);
+ Ptr<NameEntryIterator> name_iter;
+ name_iter.Attach(table->Iterator());
+ while (name_iter->HasNext()) {
+ NameEntryPtr name_entry;
+ name_entry.Attach(name_iter->Next());
+ NameEntryBuilderPtr name_entry_builder = new NameEntryBuilder(name_entry);
+ NameEntry* builder_entry = name_entry_builder->name_entry();
+ NameEntryId probe = builder_entry->name_entry_id();
+ name_entry_map_[probe] = name_entry_builder;
+ }
+ }
+}
+
+NameTable::NameEntryBuilderMap* NameTable::Builder::GetNameBuilders() {
+ if (name_entry_map_.empty()) {
+ Initialize(InternalReadData());
+ }
+ set_model_changed();
+ return &name_entry_map_;
+}
+
+/******************************************************************************
+ * NameTable class
+ ******************************************************************************/
+NameTable::~NameTable() {}
+
+int32_t NameTable::Format() {
+ return data_->ReadUShort(Offset::kFormat);
+}
+
+int32_t NameTable::NameCount() {
+ return data_->ReadUShort(Offset::kCount);
+}
+
+int32_t NameTable::PlatformId(int32_t index) {
+ return data_->ReadUShort(Offset::kNameRecordPlatformId +
+ OffsetForNameRecord(index));
+}
+
+int32_t NameTable::EncodingId(int32_t index) {
+ return data_->ReadUShort(Offset::kNameRecordEncodingId +
+ OffsetForNameRecord(index));
+}
+
+int32_t NameTable::LanguageId(int32_t index) {
+ return data_->ReadUShort(Offset::kNameRecordLanguageId +
+ OffsetForNameRecord(index));
+}
+
+int32_t NameTable::NameId(int32_t index) {
+ return data_->ReadUShort(Offset::kNameRecordNameId +
+ OffsetForNameRecord(index));
+}
+
+void NameTable::NameAsBytes(int32_t index, ByteVector* b) {
+ assert(b);
+ int32_t length = NameLength(index);
+ b->clear();
+ b->resize(length);
+ if (length > 0) {
+ data_->ReadBytes(NameOffset(index), &((*b)[0]), 0, length);
+ }
+}
+
+void NameTable::NameAsBytes(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id,
+ ByteVector* b) {
+ assert(b);
+ NameEntryPtr entry;
+ entry.Attach(GetNameEntry(platform_id, encoding_id, language_id, name_id));
+ if (entry) {
+ ByteVector* name = entry->NameAsBytes();
+ std::copy(name->begin(), name->end(), b->begin());
+ }
+}
+
+UChar* NameTable::Name(int32_t index) {
+ ByteVector b;
+ NameAsBytes(index, &b);
+ return ConvertFromNameBytes(&b, PlatformId(index), EncodingId(index));
+}
+
+UChar* NameTable::Name(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id) {
+ NameEntryPtr entry;
+ entry.Attach(GetNameEntry(platform_id, encoding_id, language_id, name_id));
+ if (entry) {
+ return entry->Name();
+ }
+ return NULL;
+}
+
+CALLER_ATTACH NameTable::NameEntry* NameTable::GetNameEntry(int32_t index) {
+ ByteVector b;
+ NameAsBytes(index, &b);
+ NameEntryPtr instance = new NameEntry(PlatformId(index),
+ EncodingId(index),
+ LanguageId(index),
+ NameId(index), b);
+ return instance.Detach();
+}
+
+CALLER_ATTACH NameTable::NameEntry* NameTable::GetNameEntry(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id) {
+ NameTable::NameEntryFilterInPlace
+ filter(platform_id, encoding_id, language_id, name_id);
+ Ptr<NameTable::NameEntryIterator> name_entry_iter;
+ name_entry_iter.Attach(Iterator(&filter));
+ NameEntryPtr result;
+ if (name_entry_iter->HasNext()) {
+ result = name_entry_iter->Next();
+ }
+ return result;
+}
+
+CALLER_ATTACH NameTable::NameEntryIterator* NameTable::Iterator() {
+ Ptr<NameEntryIterator> output = new NameTable::NameEntryIterator(this);
+ return output.Detach();
+}
+
+CALLER_ATTACH
+NameTable::NameEntryIterator* NameTable::Iterator(NameEntryFilter* filter) {
+ Ptr<NameEntryIterator> output =
+ new NameTable::NameEntryIterator(this, filter);
+ return output.Detach();
+}
+
+NameTable::NameTable(Header* header, ReadableFontData* data)
+ : SubTableContainerTable(header, data) {}
+
+int32_t NameTable::StringOffset() {
+ return data_->ReadUShort(Offset::kStringOffset);
+}
+
+int32_t NameTable::OffsetForNameRecord(int32_t index) {
+ return Offset::kNameRecordStart + index * Offset::kNameRecordSize;
+}
+
+int32_t NameTable::NameLength(int32_t index) {
+ return data_->ReadUShort(Offset::kNameRecordStringLength +
+ OffsetForNameRecord(index));
+}
+
+int32_t NameTable::NameOffset(int32_t index) {
+ return data_->ReadUShort(Offset::kNameRecordStringOffset +
+ OffsetForNameRecord(index)) + StringOffset();
+}
+
+const char* NameTable::GetEncodingName(int32_t platform_id,
+ int32_t encoding_id) {
+ switch (platform_id) {
+ case PlatformId::kUnicode:
+ return "UTF-16BE";
+ case PlatformId::kMacintosh:
+ switch (encoding_id) {
+ case MacintoshEncodingId::kRoman:
+ return "MacRoman";
+ case MacintoshEncodingId::kJapanese:
+ return "Shift-JIS";
+ case MacintoshEncodingId::kChineseTraditional:
+ return "Big5";
+ case MacintoshEncodingId::kKorean:
+ return "EUC-KR";
+ case MacintoshEncodingId::kArabic:
+ return "MacArabic";
+ case MacintoshEncodingId::kHebrew:
+ return "MacHebrew";
+ case MacintoshEncodingId::kGreek:
+ return "MacGreek";
+ case MacintoshEncodingId::kRussian:
+ return "MacCyrillic";
+ case MacintoshEncodingId::kRSymbol:
+ return "MacSymbol";
+ case MacintoshEncodingId::kThai:
+ return "MacThai";
+ case MacintoshEncodingId::kChineseSimplified:
+ return "EUC-CN";
+ default: // Note: unknown/unconfirmed cases are not ported.
+ break;
+ }
+ break;
+ case PlatformId::kISO:
+ break;
+ case PlatformId::kWindows:
+ switch (encoding_id) {
+ case WindowsEncodingId::kSymbol:
+ case WindowsEncodingId::kUnicodeUCS2:
+ return "UTF-16BE";
+ case WindowsEncodingId::kShiftJIS:
+ return "windows-933";
+ case WindowsEncodingId::kPRC:
+ return "windows-936";
+ case WindowsEncodingId::kBig5:
+ return "windows-950";
+ case WindowsEncodingId::kWansung:
+ return "windows-949";
+ case WindowsEncodingId::kJohab:
+ return "ms1361";
+ case WindowsEncodingId::kUnicodeUCS4:
+ return "UCS-4";
+ }
+ break;
+ case PlatformId::kCustom:
+ break;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+UConverter* NameTable::GetCharset(int32_t platform_id, int32_t encoding_id) {
+ UErrorCode error_code = U_ZERO_ERROR;
+ UConverter* conv = ucnv_open(GetEncodingName(platform_id, encoding_id),
+ &error_code);
+ if (U_SUCCESS(error_code)) {
+ return conv;
+ }
+
+ if (conv) {
+ ucnv_close(conv);
+ }
+ return NULL;
+}
+
+void NameTable::ConvertToNameBytes(const UChar* name,
+ int32_t platform_id,
+ int32_t encoding_id,
+ ByteVector* b) {
+ assert(b);
+ assert(name);
+ b->clear();
+ UConverter* cs = GetCharset(platform_id, encoding_id);
+ if (cs == NULL) {
+ return;
+ }
+
+ // Preflight to get buffer size.
+ UErrorCode error_code = U_ZERO_ERROR;
+ int32_t length = ucnv_fromUChars(cs, NULL, 0, name, -1, &error_code);
+ b->resize(length + 4); // The longest termination "\0" is 4 bytes.
+ memset(&((*b)[0]), 0, length + 4);
+ error_code = U_ZERO_ERROR;
+ ucnv_fromUChars(cs,
+ reinterpret_cast<char*>(&((*b)[0])),
+ length + 4,
+ name,
+ -1,
+ &error_code);
+ if (!U_SUCCESS(error_code)) {
+ b->clear();
+ }
+ ucnv_close(cs);
+}
+
+UChar* NameTable::ConvertFromNameBytes(ByteVector* name_bytes,
+ int32_t platform_id,
+ int32_t encoding_id) {
+ if (name_bytes == NULL || name_bytes->size() == 0) {
+ return NULL;
+ }
+ UConverter* cs = GetCharset(platform_id, encoding_id);
+ UErrorCode error_code = U_ZERO_ERROR;
+ if (cs == NULL) {
+ char buffer[11] = {0};
+#if defined (WIN32)
+ _itoa_s(platform_id, buffer, 16);
+#else
+ snprintf(buffer, sizeof(buffer), "%x", platform_id);
+#endif
+ UChar* result = new UChar[12];
+ memset(result, 0, sizeof(UChar) * 12);
+ cs = ucnv_open("utf-8", &error_code);
+ if (U_SUCCESS(error_code)) {
+ ucnv_toUChars(cs, result, 12, buffer, 11, &error_code);
+ ucnv_close(cs);
+ if (U_SUCCESS(error_code)) {
+ return result;
+ }
+ }
+ delete[] result;
+ return NULL;
+ }
+
+ // No preflight needed here, we will be bigger.
+ UChar* output_buffer = new UChar[name_bytes->size() + 1];
+ memset(output_buffer, 0, sizeof(UChar) * (name_bytes->size() + 1));
+ int32_t length = ucnv_toUChars(cs,
+ output_buffer,
+ name_bytes->size(),
+ reinterpret_cast<char*>(&((*name_bytes)[0])),
+ name_bytes->size(),
+ &error_code);
+ ucnv_close(cs);
+ if (length > 0) {
+ return output_buffer;
+ }
+
+ delete[] output_buffer;
+ return NULL;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/name_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/name_table.h
new file mode 100644
index 00000000000..4eaafbbdae2
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/name_table.h
@@ -0,0 +1,743 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_
+
+// Must include this before ICU to avoid stdint redefinition issue.
+#include "sfntly/port/type.h"
+
+#include <unicode/ucnv.h>
+#include <unicode/ustring.h>
+
+#include <map>
+#include <utility>
+
+#include "sfntly/port/java_iterator.h"
+#include "sfntly/table/subtable_container_table.h"
+
+namespace sfntly {
+
+// The following code implements the name table defined in TTF/OTF spec, which
+// can be found at http://www.microsoft.com/typography/otspec/name.htm.
+
+// Name IDs defined in TTF/OTF spec.
+struct NameId {
+ enum {
+ kUnknown = -1,
+ kCopyrightNotice = 0,
+ kFontFamilyName = 1,
+ kFontSubfamilyName = 2,
+ kUniqueFontIdentifier = 3,
+ kFullFontName = 4,
+ kVersionString = 5,
+ kPostscriptName = 6,
+ kTrademark = 7,
+ kManufacturerName = 8,
+ kDesigner = 9,
+ kDescription = 10,
+ kVendorURL = 11,
+ kDesignerURL = 12,
+ kLicenseDescription = 13,
+ kLicenseInfoURL = 14,
+ kReserved15 = 15,
+ kPreferredFamily = 16,
+ kPreferredSubfamily = 17,
+ kCompatibleFullName = 18,
+ kSampleText = 19,
+ kPostscriptCID = 20,
+ kWWSFamilyName = 21,
+ kWWSSubfamilyName = 22
+ };
+};
+
+// Unicode language IDs used in Name Records.
+struct UnicodeLanguageId {
+ enum {
+ kUnknown = -1,
+ kAll = 0
+ };
+};
+
+// Macintosh Language IDs (platform ID = 1)
+struct MacintoshLanguageId {
+ enum {
+ kUnknown = -1,
+ kEnglish = 0,
+ kFrench = 1,
+ kGerman = 2,
+ kItalian = 3,
+ kDutch = 4,
+ kSwedish = 5,
+ kSpanish = 6,
+ kDanish = 7,
+ kPortuguese = 8,
+ kNorwegian = 9,
+ kHebrew = 10,
+ kJapanese = 11,
+ kArabic = 12,
+ kFinnish = 13,
+ kGreek = 14,
+ kIcelandic = 15,
+ kMaltese = 16,
+ kTurkish = 17,
+ kCroatian = 18,
+ kChinese_Traditional = 19,
+ kUrdu = 20,
+ kHindi = 21,
+ kThai = 22,
+ kKorean = 23,
+ kLithuanian = 24,
+ kPolish = 25,
+ kHungarian = 26,
+ kEstonian = 27,
+ kLatvian = 28,
+ kSami = 29,
+ kFaroese = 30,
+ kFarsiPersian = 31,
+ kRussian = 32,
+ kChinese_Simplified = 33,
+ kFlemish = 34,
+ kIrishGaelic = 35,
+ kAlbanian = 36,
+ kRomanian = 37,
+ kCzech = 38,
+ kSlovak = 39,
+ kSlovenian = 40,
+ kYiddish = 41,
+ kSerbian = 42,
+ kMacedonian = 43,
+ kBulgarian = 44,
+ kUkrainian = 45,
+ kByelorussian = 46,
+ kUzbek = 47,
+ kKazakh = 48,
+ kAzerbaijani_Cyrillic = 49,
+ kAzerbaijani_Arabic = 50,
+ kArmenian = 51,
+ kGeorgian = 52,
+ kMoldavian = 53,
+ kKirghiz = 54,
+ kTajiki = 55,
+ kTurkmen = 56,
+ kMongolian_Mongolian = 57,
+ kMongolian_Cyrillic = 58,
+ kPashto = 59,
+ kKurdish = 60,
+ kKashmiri = 61,
+ kSindhi = 62,
+ kTibetan = 63,
+ kNepali = 64,
+ kSanskrit = 65,
+ kMarathi = 66,
+ kBengali = 67,
+ kAssamese = 68,
+ kGujarati = 69,
+ kPunjabi = 70,
+ kOriya = 71,
+ kMalayalam = 72,
+ kKannada = 73,
+ kTamil = 74,
+ kTelugu = 75,
+ kSinhalese = 76,
+ kBurmese = 77,
+ kKhmer = 78,
+ kLao = 79,
+ kVietnamese = 80,
+ kIndonesian = 81,
+ kTagalong = 82,
+ kMalay_Roman = 83,
+ kMalay_Arabic = 84,
+ kAmharic = 85,
+ kTigrinya = 86,
+ kGalla = 87,
+ kSomali = 88,
+ kSwahili = 89,
+ kKinyarwandaRuanda = 90,
+ kRundi = 91,
+ kNyanjaChewa = 92,
+ kMalagasy = 93,
+ kEsperanto = 94,
+ kWelsh = 128,
+ kBasque = 129,
+ kCatalan = 130,
+ kLatin = 131,
+ kQuenchua = 132,
+ kGuarani = 133,
+ kAymara = 134,
+ kTatar = 135,
+ kUighur = 136,
+ kDzongkha = 137,
+ kJavanese_Roman = 138,
+ kSundanese_Roman = 139,
+ kGalician = 140,
+ kAfrikaans = 141,
+ kBreton = 142,
+ kInuktitut = 143,
+ kScottishGaelic = 144,
+ kManxGaelic = 145,
+ kIrishGaelic_WithDotAbove = 146,
+ kTongan = 147,
+ kGreek_Polytonic = 148,
+ kGreenlandic = 149,
+ kAzerbaijani_Roman = 150
+ };
+};
+
+// Windows Language IDs (platformID = 3)
+struct WindowsLanguageId {
+ enum {
+ kUnknown = -1,
+ kAfrikaans_SouthAfrica = 0x0436,
+ kAlbanian_Albania = 0x041C,
+ kAlsatian_France = 0x0484,
+ kAmharic_Ethiopia = 0x045E,
+ kArabic_Algeria = 0x1401,
+ kArabic_Bahrain = 0x3C01,
+ kArabic_Egypt = 0x0C01,
+ kArabic_Iraq = 0x0801,
+ kArabic_Jordan = 0x2C01,
+ kArabic_Kuwait = 0x3401,
+ kArabic_Lebanon = 0x3001,
+ kArabic_Libya = 0x1001,
+ kArabic_Morocco = 0x1801,
+ kArabic_Oman = 0x2001,
+ kArabic_Qatar = 0x4001,
+ kArabic_SaudiArabia = 0x0401,
+ kArabic_Syria = 0x2801,
+ kArabic_Tunisia = 0x1C01,
+ kArabic_UAE = 0x3801,
+ kArabic_Yemen = 0x2401,
+ kArmenian_Armenia = 0x042B,
+ kAssamese_India = 0x044D,
+ kAzeri_Cyrillic_Azerbaijan = 0x082C,
+ kAzeri_Latin_Azerbaijan = 0x042C,
+ kBashkir_Russia = 0x046D,
+ kBasque_Basque = 0x042D,
+ kBelarusian_Belarus = 0x0423,
+ kBengali_Bangladesh = 0x0845,
+ kBengali_India = 0x0445,
+ kBosnian_Cyrillic_BosniaAndHerzegovina = 0x201A,
+ kBosnian_Latin_BosniaAndHerzegovina = 0x141A,
+ kBreton_France = 0x047E,
+ kBulgarian_Bulgaria = 0x0402,
+ kCatalan_Catalan = 0x0403,
+ kChinese_HongKongSAR = 0x0C04,
+ kChinese_MacaoSAR = 0x1404,
+ kChinese_PeoplesRepublicOfChina = 0x0804,
+ kChinese_Singapore = 0x1004,
+ kChinese_Taiwan = 0x0404,
+ kCorsican_France = 0x0483,
+ kCroatian_Croatia = 0x041A,
+ kCroatian_Latin_BosniaAndHerzegovina = 0x101A,
+ kCzech_CzechRepublic = 0x0405,
+ kDanish_Denmark = 0x0406,
+ kDari_Afghanistan = 0x048C,
+ kDivehi_Maldives = 0x0465,
+ kDutch_Belgium = 0x0813,
+ kDutch_Netherlands = 0x0413,
+ kEnglish_Australia = 0x0C09,
+ kEnglish_Belize = 0x2809,
+ kEnglish_Canada = 0x1009,
+ kEnglish_Caribbean = 0x2409,
+ kEnglish_India = 0x4009,
+ kEnglish_Ireland = 0x1809,
+ kEnglish_Jamaica = 0x2009,
+ kEnglish_Malaysia = 0x4409,
+ kEnglish_NewZealand = 0x1409,
+ kEnglish_RepublicOfThePhilippines = 0x3409,
+ kEnglish_Singapore = 0x4809,
+ kEnglish_SouthAfrica = 0x1C09,
+ kEnglish_TrinidadAndTobago = 0x2C09,
+ kEnglish_UnitedKingdom = 0x0809,
+ kEnglish_UnitedStates = 0x0409,
+ kEnglish_Zimbabwe = 0x3009,
+ kEstonian_Estonia = 0x0425,
+ kFaroese_FaroeIslands = 0x0438,
+ kFilipino_Philippines = 0x0464,
+ kFinnish_Finland = 0x040B,
+ kFrench_Belgium = 0x080C,
+ kFrench_Canada = 0x0C0C,
+ kFrench_France = 0x040C,
+ kFrench_Luxembourg = 0x140c,
+ kFrench_PrincipalityOfMonoco = 0x180C,
+ kFrench_Switzerland = 0x100C,
+ kFrisian_Netherlands = 0x0462,
+ kGalician_Galician = 0x0456,
+ kGeorgian_Georgia = 0x0437,
+ kGerman_Austria = 0x0C07,
+ kGerman_Germany = 0x0407,
+ kGerman_Liechtenstein = 0x1407,
+ kGerman_Luxembourg = 0x1007,
+ kGerman_Switzerland = 0x0807,
+ kGreek_Greece = 0x0408,
+ kGreenlandic_Greenland = 0x046F,
+ kGujarati_India = 0x0447,
+ kHausa_Latin_Nigeria = 0x0468,
+ kHebrew_Israel = 0x040D,
+ kHindi_India = 0x0439,
+ kHungarian_Hungary = 0x040E,
+ kIcelandic_Iceland = 0x040F,
+ kIgbo_Nigeria = 0x0470,
+ kIndonesian_Indonesia = 0x0421,
+ kInuktitut_Canada = 0x045D,
+ kInuktitut_Latin_Canada = 0x085D,
+ kIrish_Ireland = 0x083C,
+ kisiXhosa_SouthAfrica = 0x0434,
+ kisiZulu_SouthAfrica = 0x0435,
+ kItalian_Italy = 0x0410,
+ kItalian_Switzerland = 0x0810,
+ kJapanese_Japan = 0x0411,
+ kKannada_India = 0x044B,
+ kKazakh_Kazakhstan = 0x043F,
+ kKhmer_Cambodia = 0x0453,
+ kKiche_Guatemala = 0x0486,
+ kKinyarwanda_Rwanda = 0x0487,
+ kKiswahili_Kenya = 0x0441,
+ kKonkani_India = 0x0457,
+ kKorean_Korea = 0x0412,
+ kKyrgyz_Kyrgyzstan = 0x0440,
+ kLao_LaoPDR = 0x0454,
+ kLatvian_Latvia = 0x0426,
+ kLithuanian_Lithuania = 0x0427,
+ kLowerSorbian_Germany = 0x082E,
+ kLuxembourgish_Luxembourg = 0x046E,
+ kMacedonian_FYROM_FormerYugoslavRepublicOfMacedonia = 0x042F,
+ kMalay_BruneiDarussalam = 0x083E,
+ kMalay_Malaysia = 0x043E,
+ kMalayalam_India = 0x044C,
+ kMaltese_Malta = 0x043A,
+ kMaori_NewZealand = 0x0481,
+ kMapudungun_Chile = 0x047A,
+ kMarathi_India = 0x044E,
+ kMohawk_Mohawk = 0x047C,
+ kMongolian_Cyrillic_Mongolia = 0x0450,
+ kMongolian_Traditional_PeoplesRepublicOfChina = 0x0850,
+ kNepali_Nepal = 0x0461,
+ kNorwegian_Bokmal_Norway = 0x0414,
+ kNorwegian_Nynorsk_Norway = 0x0814,
+ kOccitan_France = 0x0482,
+ kOriya_India = 0x0448,
+ kPashto_Afghanistan = 0x0463,
+ kPolish_Poland = 0x0415,
+ kPortuguese_Brazil = 0x0416,
+ kPortuguese_Portugal = 0x0816,
+ kPunjabi_India = 0x0446,
+ kQuechua_Bolivia = 0x046B,
+ kQuechua_Ecuador = 0x086B,
+ kQuechua_Peru = 0x0C6B,
+ kRomanian_Romania = 0x0418,
+ kRomansh_Switzerland = 0x0417,
+ kRussian_Russia = 0x0419,
+ kSami_Inari_Finland = 0x243B,
+ kSami_Lule_Norway = 0x103B,
+ kSami_Lule_Sweden = 0x143B,
+ kSami_Northern_Finland = 0x0C3B,
+ kSami_Northern_Norway = 0x043B,
+ kSami_Northern_Sweden = 0x083B,
+ kSami_Skolt_Finland = 0x203B,
+ kSami_Southern_Norway = 0x183B,
+ kSami_Southern_Sweden = 0x1C3B,
+ kSanskrit_India = 0x044F,
+ kSerbian_Cyrillic_BosniaAndHerzegovina = 0x1C1A,
+ kSerbian_Cyrillic_Serbia = 0x0C1A,
+ kSerbian_Latin_BosniaAndHerzegovina = 0x181A,
+ kSerbian_Latin_Serbia = 0x081A,
+ kSesothoSaLeboa_SouthAfrica = 0x046C,
+ kSetswana_SouthAfrica = 0x0432,
+ kSinhala_SriLanka = 0x045B,
+ kSlovak_Slovakia = 0x041B,
+ kSlovenian_Slovenia = 0x0424,
+ kSpanish_Argentina = 0x2C0A,
+ kSpanish_Bolivia = 0x400A,
+ kSpanish_Chile = 0x340A,
+ kSpanish_Colombia = 0x240A,
+ kSpanish_CostaRica = 0x140A,
+ kSpanish_DominicanRepublic = 0x1C0A,
+ kSpanish_Ecuador = 0x300A,
+ kSpanish_ElSalvador = 0x440A,
+ kSpanish_Guatemala = 0x100A,
+ kSpanish_Honduras = 0x480A,
+ kSpanish_Mexico = 0x080A,
+ kSpanish_Nicaragua = 0x4C0A,
+ kSpanish_Panama = 0x180A,
+ kSpanish_Paraguay = 0x3C0A,
+ kSpanish_Peru = 0x280A,
+ kSpanish_PuertoRico = 0x500A,
+ kSpanish_ModernSort_Spain = 0x0C0A,
+ kSpanish_TraditionalSort_Spain = 0x040A,
+ kSpanish_UnitedStates = 0x540A,
+ kSpanish_Uruguay = 0x380A,
+ kSpanish_Venezuela = 0x200A,
+ kSweden_Finland = 0x081D,
+ kSwedish_Sweden = 0x041D,
+ kSyriac_Syria = 0x045A,
+ kTajik_Cyrillic_Tajikistan = 0x0428,
+ kTamazight_Latin_Algeria = 0x085F,
+ kTamil_India = 0x0449,
+ kTatar_Russia = 0x0444,
+ kTelugu_India = 0x044A,
+ kThai_Thailand = 0x041E,
+ kTibetan_PRC = 0x0451,
+ kTurkish_Turkey = 0x041F,
+ kTurkmen_Turkmenistan = 0x0442,
+ kUighur_PRC = 0x0480,
+ kUkrainian_Ukraine = 0x0422,
+ kUpperSorbian_Germany = 0x042E,
+ kUrdu_IslamicRepublicOfPakistan = 0x0420,
+ kUzbek_Cyrillic_Uzbekistan = 0x0843,
+ kUzbek_Latin_Uzbekistan = 0x0443,
+ kVietnamese_Vietnam = 0x042A,
+ kWelsh_UnitedKingdom = 0x0452,
+ kWolof_Senegal = 0x0448,
+ kYakut_Russia = 0x0485,
+ kYi_PRC = 0x0478,
+ kYoruba_Nigeria = 0x046A
+ };
+};
+
+class NameTable : public SubTableContainerTable, public RefCounted<NameTable> {
+ public:
+ // Unique identifier for a given name record.
+ class NameEntryId {
+ public:
+ NameEntryId(); // C++ port only, must provide default constructor.
+ NameEntryId(int32_t platform_id, int32_t encoding_id, int32_t language_id,
+ int32_t name_id);
+ NameEntryId(const NameEntryId&);
+ // Make gcc -Wnon-virtual-dtor happy.
+ virtual ~NameEntryId() {}
+
+ int32_t platform_id() const { return platform_id_; }
+ int32_t encoding_id() const { return encoding_id_; }
+ int32_t language_id() const { return language_id_; }
+ int32_t name_id() const { return name_id_; }
+
+ const NameEntryId& operator=(const NameEntryId& rhs) const;
+ bool operator==(const NameEntryId& rhs) const;
+ bool operator<(const NameEntryId& rhs) const;
+
+ // UNIMPLEMENTED: int hashCode()
+ // String toString()
+
+ private:
+ mutable int32_t platform_id_;
+ mutable int32_t encoding_id_;
+ mutable int32_t language_id_;
+ mutable int32_t name_id_;
+ };
+
+ class NameEntryBuilder;
+
+ // Class to represent a name entry in the name table.
+ class NameEntry : public RefCounted<NameEntry> {
+ public:
+ NameEntry();
+ NameEntry(const NameEntryId& name_entry_id, const ByteVector& name_bytes);
+ NameEntry(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id,
+ const ByteVector& name_bytes);
+ virtual ~NameEntry();
+
+ NameEntryId& name_entry_id() { return name_entry_id_; }
+ int32_t platform_id() const { return name_entry_id_.platform_id(); }
+ int32_t encoding_id() const { return name_entry_id_.encoding_id(); }
+ int32_t language_id() const { return name_entry_id_.language_id(); }
+ int32_t name_id() const { return name_entry_id_.name_id(); }
+
+ // Get the bytes for name. Returned pointer is the address of private
+ // member of this class, do not attempt to delete.
+ ByteVector* NameAsBytes();
+
+ // C++ port only: get the length of NameAsBytes.
+ int32_t NameBytesLength();
+
+ // Returns the name in Unicode as UChar array.
+ // Note: ICU UChar* convention requires caller to delete[] it.
+ UChar* Name();
+ bool operator==(const NameEntry& rhs) const;
+
+ // UNIMPLEMENTED: String toString()
+ // int hashCode()
+
+ private:
+ void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id,
+ int32_t name_id, const ByteVector* name_bytes);
+
+ NameEntryId name_entry_id_;
+ ByteVector name_bytes_;
+
+ friend class NameEntryBuilder;
+ };
+
+ // Builder of a name entry.
+ // C++ port: original Java hierarchy inherits from NameEntry. In C++ port, we
+ // opted not doing so to avoid ref count issues and nasty protected members.
+ class NameEntryBuilder : public RefCounted<NameEntryBuilder> {
+ public:
+ NameEntryBuilder();
+ NameEntryBuilder(const NameEntryId& name_entry_id,
+ const ByteVector& name_bytes);
+ explicit NameEntryBuilder(const NameEntryId& name_entry_id);
+ explicit NameEntryBuilder(NameEntry* entry);
+ virtual ~NameEntryBuilder();
+
+ virtual void SetName(const UChar* name);
+ virtual void SetName(const ByteVector& name_bytes);
+ virtual void SetName(const ByteVector& name_bytes,
+ int32_t offset,
+ int32_t length);
+
+ // C++ port only. CALLER_ATTACH is not added because the lifetime shall be
+ // controlled by this class, therefore the caller shall not increase the ref
+ // count.
+ NameEntry* name_entry() { return name_entry_; }
+
+ private:
+ void Init(int32_t platform_id, int32_t encoding_id, int32_t language_id,
+ int32_t name_id, const ByteVector* name_bytes);
+
+ Ptr<NameEntry> name_entry_;
+ };
+ typedef std::map<NameEntryId, Ptr<NameEntryBuilder> > NameEntryBuilderMap;
+
+ // An interface for a filter to use with the name entry iterator. This allows
+ // name entries to be iterated and only those acceptable to the filter will be
+ // returned.
+ class NameEntryFilter {
+ public:
+ virtual bool Accept(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id) = 0;
+ // Make gcc -Wnon-virtual-dtor happy.
+ virtual ~NameEntryFilter() {}
+ };
+
+ // C++ port only: an in-place filter to mimic Java Iterator's filtering.
+ class NameEntryFilterInPlace : public NameEntryFilter {
+ public:
+ NameEntryFilterInPlace(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id);
+ // Make gcc -Wnon-virtual-dtor happy.
+ virtual ~NameEntryFilterInPlace() {}
+
+ virtual bool Accept(int32_t platform_id,
+ int32_t encoding_id,
+ int32_t language_id,
+ int32_t name_id);
+
+ private:
+ int32_t platform_id_;
+ int32_t encoding_id_;
+ int32_t language_id_;
+ int32_t name_id_;
+ };
+
+ class NameEntryIterator : public RefIterator<NameEntry, NameTable> {
+ public:
+ // If filter is NULL, filter through all tables.
+ explicit NameEntryIterator(NameTable* table);
+ NameEntryIterator(NameTable* table, NameEntryFilter* filter);
+ virtual ~NameEntryIterator() {}
+
+ virtual bool HasNext();
+ virtual CALLER_ATTACH NameEntry* Next();
+
+ private:
+ int32_t name_index_;
+ NameEntryFilter* filter_;
+ };
+
+ // The builder to construct name table for outputting.
+ class Builder : public SubTableContainerTable::Builder,
+ public RefCounted<Builder> {
+ public:
+ // Constructor scope altered to public because C++ does not allow base
+ // class to instantiate derived class with protected constructors.
+ Builder(Header* header, WritableFontData* data);
+ Builder(Header* header, ReadableFontData* data);
+
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ WritableFontData* data);
+
+ // Revert the name builders for the name table to the last version that came
+ // from data.
+ void RevertNames();
+
+ // Number of name entry builders contained.
+ int32_t BuilderCount();
+
+ // Note: For C++ port, clear() is not implemented. The clear() function
+ // implies completely remove name entry builders, which is easy in
+ // Java but will take a lot of efforts in C++ to release the builders
+ // nicely and correctly.
+ // TODO(arthurhsu): IMPLEMENT
+ // Clear the name builders for the name table.
+ // void clear();
+
+ // Check the existance of a name entry builder by key.
+ bool Has(int32_t platform_id, int32_t encoding_id, int32_t language_id,
+ int32_t name_id);
+
+ // Get name entry builder by key.
+ CALLER_ATTACH NameEntryBuilder* NameBuilder(int32_t platform_id,
+ int32_t encoding_id, int32_t language_id, int32_t name_id);
+
+ // Remove name entry builder by key.
+ bool Remove(int32_t platform_id, int32_t encoding_id, int32_t language_id,
+ int32_t name_id);
+
+ // FontDataTable::Builder API implementation
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ private:
+ void Initialize(ReadableFontData* data);
+ NameEntryBuilderMap* GetNameBuilders();
+
+ // Note: callers should use the getter funtion provided above to ensure that
+ // this is lazily initialized instead of accessing directly.
+ NameEntryBuilderMap name_entry_map_;
+ };
+
+ /****************************************************************************
+ * public methods of NameTable class
+ ****************************************************************************/
+ virtual ~NameTable();
+
+ // Get the format used in the name table.
+ virtual int32_t Format();
+
+ // Get the number of names in the name table.
+ virtual int32_t NameCount();
+
+ // Get the platform id for the given name record.
+ virtual int32_t PlatformId(int32_t index);
+
+ // Get the encoding id for the given name record.
+ // see MacintoshEncodingId, WindowsEncodingId, UnicodeEncodingId
+ virtual int32_t EncodingId(int32_t index);
+
+ // Get the language id for the given name record.
+ virtual int32_t LanguageId(int32_t index);
+
+ // Get the name id for given name record.
+ virtual int32_t NameId(int32_t index);
+
+ // Get the name as bytes for the specified name. If there is no entry for the
+ // requested name, then empty vector is returned.
+ virtual void NameAsBytes(int32_t index, ByteVector* b);
+ virtual void NameAsBytes(int32_t platform_id, int32_t encoding_id,
+ int32_t language_id, int32_t name_id,
+ ByteVector* b);
+
+ // Get the name as a UChar* for the given name record. If there is no
+ // encoding conversion available for the name record then a best attempt
+ // UChar* will be returned.
+ // Note: ICU UChar* convention requires caller to delete[] it.
+ virtual UChar* Name(int32_t index);
+
+ // Get the name as a UChar* for the specified name. If there is no entry for
+ // the requested name then NULL is returned. If there is no encoding
+ // conversion available for the name then a best attempt UChar* will be
+ // returned.
+ // Note: ICU UChar* convention requires caller to delete[] it.
+ virtual UChar* Name(int32_t platform_id, int32_t encoding_id,
+ int32_t language_id, int32_t name_id);
+
+ // Note: These functions are renamed in C++ port. Their original Java name is
+ // nameEntry().
+ virtual CALLER_ATTACH NameEntry* GetNameEntry(int32_t index);
+ virtual CALLER_ATTACH NameEntry* GetNameEntry(int32_t platform_id,
+ int32_t encoding_id, int32_t language_id, int32_t name_id);
+
+ // Note: Not implemented in C++ port due to complexity and low usage.
+ // virtual void names(std::set<NameEntryPtr>*);
+
+ // Get the iterator to iterate through all name entries.
+ virtual CALLER_ATTACH NameEntryIterator* Iterator();
+ virtual CALLER_ATTACH NameEntryIterator* Iterator(NameEntryFilter* filter);
+
+ private:
+ struct Offset {
+ enum {
+ kFormat = 0,
+ kCount = 2,
+ kStringOffset = 4,
+ kNameRecordStart = 6,
+
+ // Format 1 - offset from the end of the name records
+ kLangTagCount = 0,
+ kLangTagRecord = 2,
+
+ kNameRecordSize = 12,
+ // Name Records
+ kNameRecordPlatformId = 0,
+ kNameRecordEncodingId = 2,
+ kNameRecordLanguageId = 4,
+ kNameRecordNameId = 6,
+ kNameRecordStringLength = 8,
+ kNameRecordStringOffset = 10
+ };
+ };
+
+ // The table shall be constructed using Builder, no direct instantiation.
+ NameTable(Header* header, ReadableFontData* data);
+
+ // Get the offset to the string data in the name table.
+ int32_t StringOffset();
+
+ // Get the offset for the given name record.
+ int32_t OffsetForNameRecord(int32_t index);
+
+ // Get the length of the string data for the given name record.
+ int32_t NameLength(int32_t index);
+
+ // Get the offset of the string data for the given name record.
+ int32_t NameOffset(int32_t index);
+
+ // Note: string literals are returned. Caller shall not attempt to manipulate
+ // the returned pointer.
+ static const char* GetEncodingName(int32_t platform_id, int32_t encoding_id);
+
+ // Note: ICU UConverter* convention requires caller to ucnv_close() it.
+ static UConverter* GetCharset(int32_t platform_id, int32_t encoding_id);
+
+ // Note: Output will be stored in ByteVector* b. Original data in b will be
+ // erased and replaced with converted name bytes.
+ static void ConvertToNameBytes(const UChar* name, int32_t platform_id,
+ int32_t encoding_id, ByteVector* b);
+
+ // Note: ICU UChar* convention requires caller to delete[] it.
+ static UChar* ConvertFromNameBytes(ByteVector* name_bytes,
+ int32_t platform_id, int32_t encoding_id);
+}; // class NameTable
+typedef Ptr<NameTable> NameTablePtr;
+typedef Ptr<NameTable::NameEntry> NameEntryPtr;
+typedef Ptr<NameTable::Builder> NameTableBuilderPtr;
+typedef Ptr<NameTable::NameEntryBuilder> NameEntryBuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_NAME_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/os2_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/os2_table.cc
new file mode 100644
index 00000000000..7ca9d9a4fd1
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/os2_table.cc
@@ -0,0 +1,608 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/core/os2_table.h"
+
+namespace sfntly {
+/******************************************************************************
+ * Constants
+ ******************************************************************************/
+const int64_t CodePageRange::kLatin1_1252 = (int64_t)1 << 0;
+const int64_t CodePageRange::kLatin2_1250 = (int64_t)1 << (int64_t)1;
+const int64_t CodePageRange::kCyrillic_1251 = (int64_t)1 << 2;
+const int64_t CodePageRange::kGreek_1253 = (int64_t)1 << 3;
+const int64_t CodePageRange::kTurkish_1254 = (int64_t)1 << 4;
+const int64_t CodePageRange::kHebrew_1255 = (int64_t)1 << 5;
+const int64_t CodePageRange::kArabic_1256 = (int64_t)1 << 6;
+const int64_t CodePageRange::kWindowsBaltic_1257 = (int64_t)1 << 7;
+const int64_t CodePageRange::kVietnamese_1258 = (int64_t)1 << 8;
+const int64_t CodePageRange::kAlternateANSI9 = (int64_t)1 << 9;
+const int64_t CodePageRange::kAlternateANSI10 = (int64_t)1 << 10;
+const int64_t CodePageRange::kAlternateANSI11 = (int64_t)1 << 11;
+const int64_t CodePageRange::kAlternateANSI12 = (int64_t)1 << 12;
+const int64_t CodePageRange::kAlternateANSI13 = (int64_t)1 << 13;
+const int64_t CodePageRange::kAlternateANSI14 = (int64_t)1 << 14;
+const int64_t CodePageRange::kAlternateANSI15 = (int64_t)1 << 15;
+const int64_t CodePageRange::kThai_874 = (int64_t)1 << 16;
+const int64_t CodePageRange::kJapanJIS_932 = (int64_t)1 << 17;
+const int64_t CodePageRange::kChineseSimplified_936 = (int64_t)1 << 18;
+const int64_t CodePageRange::kKoreanWansung_949 = (int64_t)1 << 19;
+const int64_t CodePageRange::kChineseTraditional_950 = (int64_t)1 << 20;
+const int64_t CodePageRange::kKoreanJohab_1361 = (int64_t)1 << 21;
+const int64_t CodePageRange::kAlternateANSI22 = (int64_t)1 << 22;
+const int64_t CodePageRange::kAlternateANSI23 = (int64_t)1 << 23;
+const int64_t CodePageRange::kAlternateANSI24 = (int64_t)1 << 24;
+const int64_t CodePageRange::kAlternateANSI25 = (int64_t)1 << 25;
+const int64_t CodePageRange::kAlternateANSI26 = (int64_t)1 << 26;
+const int64_t CodePageRange::kAlternateANSI27 = (int64_t)1 << 27;
+const int64_t CodePageRange::kAlternateANSI28 = (int64_t)1 << 28;
+const int64_t CodePageRange::kMacintoshCharacterSet = (int64_t)1 << 29;
+const int64_t CodePageRange::kOEMCharacterSet = (int64_t)1 << 30;
+const int64_t CodePageRange::kSymbolCharacterSet = (int64_t)1 << 31;
+const int64_t CodePageRange::kReservedForOEM32 = (int64_t)1 << 32;
+const int64_t CodePageRange::kReservedForOEM33 = (int64_t)1 << 33;
+const int64_t CodePageRange::kReservedForOEM34 = (int64_t)1 << 34;
+const int64_t CodePageRange::kReservedForOEM35 = (int64_t)1 << 35;
+const int64_t CodePageRange::kReservedForOEM36 = (int64_t)1 << 36;
+const int64_t CodePageRange::kReservedForOEM37 = (int64_t)1 << 37;
+const int64_t CodePageRange::kReservedForOEM38 = (int64_t)1 << 38;
+const int64_t CodePageRange::kReservedForOEM39 = (int64_t)1 << 39;
+const int64_t CodePageRange::kReservedForOEM40 = (int64_t)1 << 40;
+const int64_t CodePageRange::kReservedForOEM41 = (int64_t)1 << 41;
+const int64_t CodePageRange::kReservedForOEM42 = (int64_t)1 << 42;
+const int64_t CodePageRange::kReservedForOEM43 = (int64_t)1 << 43;
+const int64_t CodePageRange::kReservedForOEM44 = (int64_t)1 << 44;
+const int64_t CodePageRange::kReservedForOEM45 = (int64_t)1 << 45;
+const int64_t CodePageRange::kReservedForOEM46 = (int64_t)1 << 46;
+const int64_t CodePageRange::kReservedForOEM47 = (int64_t)1 << 47;
+const int64_t CodePageRange::kIBMGreek_869 = (int64_t)1 << 48;
+const int64_t CodePageRange::kMSDOSRussion_866 = (int64_t)1 << 49;
+const int64_t CodePageRange::kMSDOSNordic_865 = (int64_t)1 << 50;
+const int64_t CodePageRange::kArabic_864 = (int64_t)1 << 51;
+const int64_t CodePageRange::kMSDOSCanadianFrench_863 = (int64_t)1 << 52;
+const int64_t CodePageRange::kHebrew_862 = (int64_t)1 << 53;
+const int64_t CodePageRange::kMSDOSIcelandic_861 = (int64_t)1 << 54;
+const int64_t CodePageRange::kMSDOSPortugese_860 = (int64_t)1 << 55;
+const int64_t CodePageRange::kIBMTurkish_857 = (int64_t)1 << 56;
+const int64_t CodePageRange::kIBMCyrillic_855 = (int64_t)1 << 57;
+const int64_t CodePageRange::kLatin2_852 = (int64_t)1 << 58;
+const int64_t CodePageRange::kMSDOSBaltic_775 = (int64_t)1 << 59;
+const int64_t CodePageRange::kGreek_737 = (int64_t)1 << 60;
+const int64_t CodePageRange::kArabic_708 = (int64_t)1 << 61;
+const int64_t CodePageRange::kLatin1_850 = (int64_t)1 << 62;
+const int64_t CodePageRange::kUS_437 = (int64_t)1 << 63;
+
+/******************************************************************************
+ * struct UnicodeRange
+ ******************************************************************************/
+int32_t UnicodeRange::range(int32_t bit) {
+ if (bit < 0 || bit > kLast) {
+ return -1;
+ }
+ return bit;
+}
+
+/******************************************************************************
+ * class OS2Table
+ ******************************************************************************/
+OS2Table::~OS2Table() {}
+
+int32_t OS2Table::TableVersion() {
+ return data_->ReadUShort(Offset::kVersion);
+}
+
+int32_t OS2Table::XAvgCharWidth() {
+ return data_->ReadShort(Offset::kXAvgCharWidth);
+}
+
+int32_t OS2Table::UsWeightClass() {
+ return data_->ReadUShort(Offset::kUsWeightClass);
+}
+
+int32_t OS2Table::UsWidthClass() {
+ return data_->ReadUShort(Offset::kUsWidthClass);
+}
+
+int32_t OS2Table::FsType() {
+ return data_->ReadUShort(Offset::kFsType);
+}
+
+int32_t OS2Table::YSubscriptXSize() {
+ return data_->ReadShort(Offset::kYSubscriptXSize);
+}
+
+int32_t OS2Table::YSubscriptYSize() {
+ return data_->ReadShort(Offset::kYSubscriptYSize);
+}
+
+int32_t OS2Table::YSubscriptXOffset() {
+ return data_->ReadShort(Offset::kYSubscriptXOffset);
+}
+
+int32_t OS2Table::YSubscriptYOffset() {
+ return data_->ReadShort(Offset::kYSubscriptYOffset);
+}
+
+int32_t OS2Table::YSuperscriptXSize() {
+ return data_->ReadShort(Offset::kYSuperscriptXSize);
+}
+
+int32_t OS2Table::YSuperscriptYSize() {
+ return data_->ReadShort(Offset::kYSuperscriptYSize);
+}
+
+int32_t OS2Table::YSuperscriptXOffset() {
+ return data_->ReadShort(Offset::kYSuperscriptXOffset);
+}
+
+int32_t OS2Table::YSuperscriptYOffset() {
+ return data_->ReadShort(Offset::kYSuperscriptYOffset);
+}
+
+int32_t OS2Table::YStrikeoutSize() {
+ return data_->ReadShort(Offset::kYStrikeoutSize);
+}
+
+int32_t OS2Table::YStrikeoutPosition() {
+ return data_->ReadShort(Offset::kYStrikeoutPosition);
+}
+
+int32_t OS2Table::SFamilyClass() {
+ return data_->ReadShort(Offset::kSFamilyClass);
+}
+
+void OS2Table::Panose(ByteVector* value) {
+ assert(value);
+ value->clear();
+ value->resize(10);
+ data_->ReadBytes(Offset::kPanose, &((*value)[0]), 0, 10);
+}
+
+int64_t OS2Table::UlUnicodeRange1() {
+ return data_->ReadULong(Offset::kUlUnicodeRange1);
+}
+
+int64_t OS2Table::UlUnicodeRange2() {
+ return data_->ReadULong(Offset::kUlUnicodeRange2);
+}
+
+int64_t OS2Table::UlUnicodeRange3() {
+ return data_->ReadULong(Offset::kUlUnicodeRange3);
+}
+
+int64_t OS2Table::UlUnicodeRange4() {
+ return data_->ReadULong(Offset::kUlUnicodeRange4);
+}
+
+void OS2Table::AchVendId(ByteVector* b) {
+ assert(b);
+ b->clear();
+ b->resize(4);
+ data_->ReadBytes(Offset::kAchVendId, &((*b)[0]), 0, 4);
+}
+
+int32_t OS2Table::FsSelection() {
+ return data_->ReadUShort(Offset::kFsSelection);
+}
+
+int32_t OS2Table::UsFirstCharIndex() {
+ return data_->ReadUShort(Offset::kUsFirstCharIndex);
+}
+
+int32_t OS2Table::UsLastCharIndex() {
+ return data_->ReadUShort(Offset::kUsLastCharIndex);
+}
+
+int32_t OS2Table::STypoAscender() {
+ return data_->ReadShort(Offset::kSTypoAscender);
+}
+
+int32_t OS2Table::STypoDescender() {
+ return data_->ReadShort(Offset::kSTypoDescender);
+}
+
+int32_t OS2Table::STypoLineGap() {
+ return data_->ReadShort(Offset::kSTypoLineGap);
+}
+
+int32_t OS2Table::UsWinAscent() {
+ return data_->ReadUShort(Offset::kUsWinAscent);
+}
+
+int32_t OS2Table::UsWinDescent() {
+ return data_->ReadUShort(Offset::kUsWinDescent);
+}
+
+int64_t OS2Table::UlCodePageRange1() {
+ return data_->ReadULong(Offset::kUlCodePageRange1);
+}
+
+int64_t OS2Table::UlCodePageRange2() {
+ return data_->ReadULong(Offset::kUlCodePageRange2);
+}
+
+int32_t OS2Table::SxHeight() {
+ return data_->ReadShort(Offset::kSxHeight);
+}
+
+int32_t OS2Table::SCapHeight() {
+ return data_->ReadShort(Offset::kSCapHeight);
+}
+
+int32_t OS2Table::UsDefaultChar() {
+ return data_->ReadUShort(Offset::kUsDefaultChar);
+}
+
+int32_t OS2Table::UsBreakChar() {
+ return data_->ReadUShort(Offset::kUsBreakChar);
+}
+
+int32_t OS2Table::UsMaxContext() {
+ return data_->ReadUShort(Offset::kUsMaxContext);
+}
+
+OS2Table::OS2Table(Header* header, ReadableFontData* data)
+ : Table(header, data) {
+}
+
+/******************************************************************************
+ * class OS2Table::Builder
+ ******************************************************************************/
+OS2Table::Builder::Builder(Header* header, WritableFontData* data)
+ : TableBasedTableBuilder(header, data) {
+}
+
+OS2Table::Builder::Builder(Header* header, ReadableFontData* data)
+ : TableBasedTableBuilder(header, data) {
+}
+
+OS2Table::Builder::~Builder() {}
+
+CALLER_ATTACH FontDataTable* OS2Table::Builder::SubBuildTable(
+ ReadableFontData* data) {
+ FontDataTablePtr table = new OS2Table(header(), data);
+ return table.Detach();
+}
+
+CALLER_ATTACH OS2Table::Builder*
+ OS2Table::Builder::CreateBuilder(Header* header,
+ WritableFontData* data) {
+ Ptr<OS2Table::Builder> builder;
+ builder = new OS2Table::Builder(header, data);
+ return builder.Detach();
+}
+
+int32_t OS2Table::Builder::TableVersion() {
+ return InternalReadData()->ReadUShort(Offset::kVersion);
+}
+
+void OS2Table::Builder::SetTableVersion(int32_t version) {
+ InternalWriteData()->WriteUShort(Offset::kVersion, version);
+}
+
+int32_t OS2Table::Builder::XAvgCharWidth() {
+ return InternalReadData()->ReadShort(Offset::kXAvgCharWidth);
+}
+
+void OS2Table::Builder::SetXAvgCharWidth(int32_t width) {
+ InternalWriteData()->WriteShort(Offset::kXAvgCharWidth, width);
+}
+
+int32_t OS2Table::Builder::UsWeightClass() {
+ return InternalReadData()->ReadUShort(Offset::kUsWeightClass);
+}
+
+void OS2Table::Builder::SetUsWeightClass(int32_t weight) {
+ InternalWriteData()->WriteUShort(Offset::kUsWeightClass, weight);
+}
+
+int32_t OS2Table::Builder::UsWidthClass() {
+ return InternalReadData()->ReadUShort(Offset::kUsWidthClass);
+}
+
+void OS2Table::Builder::SetUsWidthClass(int32_t width) {
+ InternalWriteData()->WriteUShort(Offset::kUsWidthClass, width);
+}
+
+int32_t OS2Table::Builder::FsType() {
+ return InternalReadData()->ReadUShort(Offset::kFsType);
+}
+
+void OS2Table::Builder::SetFsType(int32_t fs_type) {
+ InternalWriteData()->WriteUShort(Offset::kFsType, fs_type);
+}
+
+int32_t OS2Table::Builder::YSubscriptXSize() {
+ return InternalReadData()->ReadShort(Offset::kYSubscriptXSize);
+}
+
+void OS2Table::Builder::SetYSubscriptXSize(int32_t size) {
+ InternalWriteData()->WriteShort(Offset::kYSubscriptXSize, size);
+}
+
+int32_t OS2Table::Builder::YSubscriptYSize() {
+ return InternalReadData()->ReadShort(Offset::kYSubscriptYSize);
+}
+
+void OS2Table::Builder::SetYSubscriptYSize(int32_t size) {
+ InternalWriteData()->WriteShort(Offset::kYSubscriptYSize, size);
+}
+
+int32_t OS2Table::Builder::YSubscriptXOffset() {
+ return InternalReadData()->ReadShort(Offset::kYSubscriptXOffset);
+}
+
+void OS2Table::Builder::SetYSubscriptXOffset(int32_t offset) {
+ InternalWriteData()->WriteShort(Offset::kYSubscriptXOffset, offset);
+}
+
+int32_t OS2Table::Builder::YSubscriptYOffset() {
+ return InternalReadData()->ReadShort(Offset::kYSubscriptYOffset);
+}
+
+void OS2Table::Builder::SetYSubscriptYOffset(int32_t offset) {
+ InternalWriteData()->WriteShort(Offset::kYSubscriptYOffset, offset);
+}
+
+int32_t OS2Table::Builder::YSuperscriptXSize() {
+ return InternalReadData()->ReadShort(Offset::kYSuperscriptXSize);
+}
+
+void OS2Table::Builder::SetYSuperscriptXSize(int32_t size) {
+ InternalWriteData()->WriteShort(Offset::kYSuperscriptXSize, size);
+}
+
+int32_t OS2Table::Builder::YSuperscriptYSize() {
+ return InternalReadData()->ReadShort(Offset::kYSuperscriptYSize);
+}
+
+void OS2Table::Builder::SetYSuperscriptYSize(int32_t size) {
+ InternalWriteData()->WriteShort(Offset::kYSuperscriptYSize, size);
+}
+
+int32_t OS2Table::Builder::YSuperscriptXOffset() {
+ return InternalReadData()->ReadShort(Offset::kYSuperscriptXOffset);
+}
+
+void OS2Table::Builder::SetYSuperscriptXOffset(int32_t offset) {
+ InternalWriteData()->WriteShort(Offset::kYSuperscriptXOffset, offset);
+}
+
+int32_t OS2Table::Builder::YSuperscriptYOffset() {
+ return InternalReadData()->ReadShort(Offset::kYSuperscriptYOffset);
+}
+
+void OS2Table::Builder::SetYSuperscriptYOffset(int32_t offset) {
+ InternalWriteData()->WriteShort(Offset::kYSuperscriptYOffset, offset);
+}
+
+int32_t OS2Table::Builder::YStrikeoutSize() {
+ return InternalReadData()->ReadShort(Offset::kYStrikeoutSize);
+}
+
+void OS2Table::Builder::SetYStrikeoutSize(int32_t size) {
+ InternalWriteData()->WriteShort(Offset::kYStrikeoutSize, size);
+}
+
+int32_t OS2Table::Builder::YStrikeoutPosition() {
+ return InternalReadData()->ReadShort(Offset::kYStrikeoutPosition);
+}
+
+void OS2Table::Builder::SetYStrikeoutPosition(int32_t position) {
+ InternalWriteData()->WriteShort(Offset::kYStrikeoutPosition, position);
+}
+
+int32_t OS2Table::Builder::SFamilyClass() {
+ return InternalReadData()->ReadShort(Offset::kSFamilyClass);
+}
+
+void OS2Table::Builder::SetSFamilyClass(int32_t family) {
+ InternalWriteData()->WriteShort(Offset::kSFamilyClass, family);
+}
+
+void OS2Table::Builder::Panose(ByteVector* value) {
+ assert(value);
+ value->clear();
+ value->resize(Offset::kPanoseLength);
+ InternalReadData()->ReadBytes(Offset::kPanose,
+ &((*value)[0]),
+ 0,
+ Offset::kPanoseLength);
+}
+
+void OS2Table::Builder::SetPanose(ByteVector* panose) {
+ assert(panose);
+ if (panose->size() != Offset::kPanoseLength) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IllegalArgumentException("Panose bytes must be exactly 10 in length");
+#endif
+ return;
+ }
+ InternalWriteData()->WriteBytes(Offset::kPanose, panose);
+}
+
+int64_t OS2Table::Builder::UlUnicodeRange1() {
+ return InternalReadData()->ReadULong(Offset::kUlUnicodeRange1);
+}
+
+void OS2Table::Builder::SetUlUnicodeRange1(int64_t range) {
+ InternalWriteData()->WriteULong(Offset::kUlUnicodeRange1, range);
+}
+
+int64_t OS2Table::Builder::UlUnicodeRange2() {
+ return InternalReadData()->ReadULong(Offset::kUlUnicodeRange2);
+}
+
+void OS2Table::Builder::SetUlUnicodeRange2(int64_t range) {
+ InternalWriteData()->WriteULong(Offset::kUlUnicodeRange2, range);
+}
+
+int64_t OS2Table::Builder::UlUnicodeRange3() {
+ return InternalReadData()->ReadULong(Offset::kUlUnicodeRange3);
+}
+
+void OS2Table::Builder::SetUlUnicodeRange3(int64_t range) {
+ InternalWriteData()->WriteULong(Offset::kUlUnicodeRange3, range);
+}
+
+int64_t OS2Table::Builder::UlUnicodeRange4() {
+ return InternalReadData()->ReadULong(Offset::kUlUnicodeRange4);
+}
+
+void OS2Table::Builder::SetUlUnicodeRange4(int64_t range) {
+ InternalWriteData()->WriteULong(Offset::kUlUnicodeRange4, range);
+}
+
+void OS2Table::Builder::AchVendId(ByteVector* b) {
+ assert(b);
+ b->clear();
+ b->resize(4);
+ InternalReadData()->ReadBytes(Offset::kAchVendId, &((*b)[0]), 0, 4);
+}
+
+void OS2Table::Builder::SetAchVendId(ByteVector* b) {
+ assert(b);
+ assert(b->size());
+ InternalWriteData()->WriteBytesPad(Offset::kAchVendId,
+ b,
+ 0,
+ std::min<size_t>(
+ (size_t)Offset::kAchVendIdLength,
+ b->size()),
+ static_cast<byte_t>(' '));
+}
+
+int32_t OS2Table::Builder::FsSelection() {
+ return InternalReadData()->ReadUShort(Offset::kFsSelection);
+}
+
+void OS2Table::Builder::SetFsSelection(int32_t fs_selection) {
+ InternalWriteData()->WriteUShort(Offset::kFsSelection, fs_selection);
+}
+
+int32_t OS2Table::Builder::UsFirstCharIndex() {
+ return InternalReadData()->ReadUShort(Offset::kUsFirstCharIndex);
+}
+
+void OS2Table::Builder::SetUsFirstCharIndex(int32_t first_index) {
+ InternalWriteData()->WriteUShort(Offset::kUsFirstCharIndex, first_index);
+}
+
+int32_t OS2Table::Builder::UsLastCharIndex() {
+ return InternalReadData()->ReadUShort(Offset::kUsLastCharIndex);
+}
+
+void OS2Table::Builder::SetUsLastCharIndex(int32_t last_index) {
+ InternalWriteData()->WriteUShort(Offset::kUsLastCharIndex, last_index);
+}
+
+int32_t OS2Table::Builder::STypoAscender() {
+ return InternalReadData()->ReadShort(Offset::kSTypoAscender);
+}
+
+void OS2Table::Builder::SetSTypoAscender(int32_t ascender) {
+ InternalWriteData()->WriteShort(Offset::kSTypoAscender, ascender);
+}
+
+int32_t OS2Table::Builder::STypoDescender() {
+ return InternalReadData()->ReadShort(Offset::kSTypoDescender);
+}
+
+void OS2Table::Builder::SetSTypoDescender(int32_t descender) {
+ InternalWriteData()->WriteShort(Offset::kSTypoDescender, descender);
+}
+
+int32_t OS2Table::Builder::STypoLineGap() {
+ return InternalReadData()->ReadShort(Offset::kSTypoLineGap);
+}
+
+void OS2Table::Builder::SetSTypoLineGap(int32_t line_gap) {
+ InternalWriteData()->WriteShort(Offset::kSTypoLineGap, line_gap);
+}
+
+int32_t OS2Table::Builder::UsWinAscent() {
+ return InternalReadData()->ReadUShort(Offset::kUsWinAscent);
+}
+
+void OS2Table::Builder::SetUsWinAscent(int32_t ascent) {
+ InternalWriteData()->WriteUShort(Offset::kUsWinAscent, ascent);
+}
+
+int32_t OS2Table::Builder::UsWinDescent() {
+ return InternalReadData()->ReadUShort(Offset::kUsWinDescent);
+}
+
+void OS2Table::Builder::SetUsWinDescent(int32_t descent) {
+ InternalWriteData()->WriteUShort(Offset::kUsWinDescent, descent);
+}
+
+int64_t OS2Table::Builder::UlCodePageRange1() {
+ return InternalReadData()->ReadULong(Offset::kUlCodePageRange1);
+}
+
+void OS2Table::Builder::SetUlCodePageRange1(int64_t range) {
+ InternalWriteData()->WriteULong(Offset::kUlCodePageRange1, range);
+}
+
+int64_t OS2Table::Builder::UlCodePageRange2() {
+ return InternalReadData()->ReadULong(Offset::kUlCodePageRange2);
+}
+
+void OS2Table::Builder::SetUlCodePageRange2(int64_t range) {
+ InternalWriteData()->WriteULong(Offset::kUlCodePageRange2, range);
+}
+
+int32_t OS2Table::Builder::SxHeight() {
+ return InternalReadData()->ReadShort(Offset::kSxHeight);
+}
+
+void OS2Table::Builder::SetSxHeight(int32_t height) {
+ InternalWriteData()->WriteShort(Offset::kSxHeight, height);
+}
+
+int32_t OS2Table::Builder::SCapHeight() {
+ return InternalReadData()->ReadShort(Offset::kSCapHeight);
+}
+
+void OS2Table::Builder::SetSCapHeight(int32_t height) {
+ InternalWriteData()->WriteShort(Offset::kSCapHeight, height);
+}
+
+int32_t OS2Table::Builder::UsDefaultChar() {
+ return InternalReadData()->ReadUShort(Offset::kUsDefaultChar);
+}
+
+void OS2Table::Builder::SetUsDefaultChar(int32_t default_char) {
+ InternalWriteData()->WriteUShort(Offset::kUsDefaultChar, default_char);
+}
+
+int32_t OS2Table::Builder::UsBreakChar() {
+ return InternalReadData()->ReadUShort(Offset::kUsBreakChar);
+}
+
+void OS2Table::Builder::SetUsBreakChar(int32_t break_char) {
+ InternalWriteData()->WriteUShort(Offset::kUsBreakChar, break_char);
+}
+
+int32_t OS2Table::Builder::UsMaxContext() {
+ return InternalReadData()->ReadUShort(Offset::kUsMaxContext);
+}
+
+void OS2Table::Builder::SetUsMaxContext(int32_t max_context) {
+ InternalWriteData()->WriteUShort(Offset::kUsMaxContext, max_context);
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/core/os2_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/os2_table.h
new file mode 100644
index 00000000000..00d26d2a3bb
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/core/os2_table.h
@@ -0,0 +1,508 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_OS2_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_OS2_TABLE_H_
+
+#include "sfntly/port/refcount.h"
+#include "sfntly/table/table.h"
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+struct WeightClass {
+ enum {
+ kThin = 100,
+ kExtraLight = 200,
+ kUltraLight = 200,
+ kLight = 300,
+ kNormal = 400,
+ kRegular = 400,
+ kMedium = 500,
+ kSemiBold = 600,
+ kDemiBold = 600,
+ kBold = 700,
+ kExtraBold = 800,
+ kUltraBold = 800,
+ kBlack = 900,
+ kHeavy = 900
+ };
+};
+
+struct WidthClass {
+ enum {
+ kUltraCondensed = 1,
+ kExtraCondensed = 2,
+ kCondensed = 3,
+ kSemiCondensed = 4,
+ kMedium = 5,
+ kNormal = 5,
+ kSemiExpanded = 6,
+ kExpanded = 7,
+ kExtraExpanded = 8,
+ kUltraExpanded = 9
+ };
+};
+
+// Flags to indicate the embedding licensing rights for a font.
+struct EmbeddingFlags {
+ enum {
+ kReserved0 = 1 << 0,
+ kRestrictedLicenseEmbedding = 1 << 1,
+ kPreviewAndPrintEmbedding = 1 << 2,
+ kEditableEmbedding = 1 << 3,
+ kReserved4 = 1 << 4,
+ kReserved5 = 1 << 5,
+ kReserved6 = 1 << 6,
+ kReserved7 = 1 << 7,
+ kNoSubsetting = 1 << 8,
+ kBitmapEmbeddingOnly = 1 << 9,
+ kReserved10 = 1 << 10,
+ kReserved11 = 1 << 11,
+ kReserved12 = 1 << 12,
+ kReserved13 = 1 << 13,
+ kReserved14 = 1 << 14,
+ kReserved15 = 1 << 15
+ };
+};
+
+struct UnicodeRange {
+ enum {
+ // Do NOT reorder. This enum relies on the ordering of the data matching the
+ // ordinal numbers of the properties.
+ kBasicLatin,
+ kLatin1Supplement,
+ kLatinExtendedA,
+ kLatinExtendedB,
+ kIPAExtensions,
+ kSpacingModifierLetters,
+ kCombiningDiacriticalMarks,
+ kGreekAndCoptic,
+ kCoptic,
+ kCyrillic,
+ kArmenian,
+ kHebrew,
+ kVai,
+ kArabic,
+ kNKo,
+ kDevanagari,
+ kBengali,
+ kGurmukhi,
+ kGujarati,
+ kOriya,
+ kTamil,
+ kTelugu,
+ kKannada,
+ kMalayalam,
+ kThai,
+ kLao,
+ kGeorgian,
+ kBalinese,
+ kHangulJamo,
+ kLatinExtendedAdditional,
+ kGreekExtended,
+ kGeneralPunctuation,
+ kSuperscriptsAndSubscripts,
+ kCurrencySymbols,
+ kNumberForms,
+ kArrows,
+ kMathematicalOperators,
+ kMiscTechnical,
+ kControlPictures,
+ kOCR,
+ kEnclosedAlphanumerics,
+ kBoxDrawing,
+ kBlockElements,
+ kGeometricShapes,
+ kMiscSymbols,
+ kDingbats,
+ kCJKSymbolsAndPunctuation,
+ kHiragana,
+ kKatakana,
+ kBopomofo,
+ kHangulCompatibilityJamo,
+ kPhagspa,
+ kEnclosedCJKLettersAndMonths,
+ kCJKCompatibility,
+ kHangulSyllables,
+ kNonPlane0,
+ kPhoenician,
+ kCJKUnifiedIdeographs,
+ kPrivateUseAreaPlane0,
+ kCJKStrokes,
+ kAlphabeticPresentationForms,
+ kArabicPresentationFormsA,
+ kCombiningHalfMarks,
+ kVerticalForms,
+ kSmallFormVariants,
+ kArabicPresentationFormsB,
+ kHalfwidthAndFullwidthForms,
+ kSpecials,
+ kTibetan,
+ kSyriac,
+ kThaana,
+ kSinhala,
+ kMyanmar,
+ kEthiopic,
+ kCherokee,
+ kUnifiedCanadianAboriginalSyllabics,
+ kOgham,
+ kRunic,
+ kKhmer,
+ kMongolian,
+ kBraillePatterns,
+ kYiSyllables,
+ kTagalog,
+ kOldItalic,
+ kGothic,
+ kDeseret,
+ kMusicalSymbols,
+ kMathematicalAlphanumericSymbols,
+ kPrivateUsePlane15And16,
+ kVariationSelectors,
+ kTags,
+ kLimbu,
+ kTaiLe,
+ kNewTaiLue,
+ kBuginese,
+ kGlagolitic,
+ kTifnagh,
+ kYijingHexagramSymbols,
+ kSylotiNagari,
+ kLinearB,
+ kAncientGreekNumbers,
+ kUgaritic,
+ kOldPersian,
+ kShavian,
+ kOsmanya,
+ kCypriotSyllabary,
+ kKharoshthi,
+ kTaiXuanJingSymbols,
+ kCuneiform,
+ kCountingRodNumerals,
+ kSudanese,
+ kLepcha,
+ kOlChiki,
+ kSaurashtra,
+ kKayahLi,
+ kRejang,
+ kCharm,
+ kAncientSymbols,
+ kPhaistosDisc,
+ kCarian,
+ kDominoTiles,
+ kReserved123,
+ kReserved124,
+ kReserved125,
+ kReserved126,
+ kReserved127,
+ kLast = kReserved127
+ };
+
+ int32_t range(int32_t bit);
+ // UNIMPLEMENTED: EnumSet<UnicodeRange> asSet(long range1, long range2,
+ // long range3, long range4)
+ // long[] asArray(EnumSet<UnicodeRange> rangeSet)
+};
+
+struct FsSelection {
+ enum {
+ kITALIC = 1 << 0,
+ kUNDERSCORE = 1 << 1,
+ kNEGATIVE = 1 << 2,
+ kOUTLINED = 1 << 3,
+ kSTRIKEOUT = 1 << 4,
+ kBOLD = 1 << 5,
+ kREGULAR = 1 << 6,
+ kUSE_TYPO_METRICS = 1 << 7,
+ kWWS = 1 << 8,
+ kOBLIQUE = 1 << 9
+ };
+ // UNIMPLEMENTED: EnumSet<FsSelection> asSet(long range1, long range2,
+ // long range3, long range4)
+ // long[] asArray(EnumSet<FsSelection> rangeSet)
+};
+
+// C++ port only: C++ does not support 64-bit enums until C++0x. For better
+// portability, we need to use static const int64_t instead.
+struct CodePageRange {
+ static const int64_t kLatin1_1252;
+ static const int64_t kLatin2_1250;
+ static const int64_t kCyrillic_1251;
+ static const int64_t kGreek_1253;
+ static const int64_t kTurkish_1254;
+ static const int64_t kHebrew_1255;
+ static const int64_t kArabic_1256;
+ static const int64_t kWindowsBaltic_1257;
+ static const int64_t kVietnamese_1258;
+ static const int64_t kAlternateANSI9;
+ static const int64_t kAlternateANSI10;
+ static const int64_t kAlternateANSI11;
+ static const int64_t kAlternateANSI12;
+ static const int64_t kAlternateANSI13;
+ static const int64_t kAlternateANSI14;
+ static const int64_t kAlternateANSI15;
+ static const int64_t kThai_874;
+ static const int64_t kJapanJIS_932;
+ static const int64_t kChineseSimplified_936;
+ static const int64_t kKoreanWansung_949;
+ static const int64_t kChineseTraditional_950;
+ static const int64_t kKoreanJohab_1361;
+ static const int64_t kAlternateANSI22;
+ static const int64_t kAlternateANSI23;
+ static const int64_t kAlternateANSI24;
+ static const int64_t kAlternateANSI25;
+ static const int64_t kAlternateANSI26;
+ static const int64_t kAlternateANSI27;
+ static const int64_t kAlternateANSI28;
+ static const int64_t kMacintoshCharacterSet;
+ static const int64_t kOEMCharacterSet;
+ static const int64_t kSymbolCharacterSet;
+ static const int64_t kReservedForOEM32;
+ static const int64_t kReservedForOEM33;
+ static const int64_t kReservedForOEM34;
+ static const int64_t kReservedForOEM35;
+ static const int64_t kReservedForOEM36;
+ static const int64_t kReservedForOEM37;
+ static const int64_t kReservedForOEM38;
+ static const int64_t kReservedForOEM39;
+ static const int64_t kReservedForOEM40;
+ static const int64_t kReservedForOEM41;
+ static const int64_t kReservedForOEM42;
+ static const int64_t kReservedForOEM43;
+ static const int64_t kReservedForOEM44;
+ static const int64_t kReservedForOEM45;
+ static const int64_t kReservedForOEM46;
+ static const int64_t kReservedForOEM47;
+ static const int64_t kIBMGreek_869;
+ static const int64_t kMSDOSRussion_866;
+ static const int64_t kMSDOSNordic_865;
+ static const int64_t kArabic_864;
+ static const int64_t kMSDOSCanadianFrench_863;
+ static const int64_t kHebrew_862;
+ static const int64_t kMSDOSIcelandic_861;
+ static const int64_t kMSDOSPortugese_860;
+ static const int64_t kIBMTurkish_857;
+ static const int64_t kIBMCyrillic_855;
+ static const int64_t kLatin2_852;
+ static const int64_t kMSDOSBaltic_775;
+ static const int64_t kGreek_737;
+ static const int64_t kArabic_708;
+ static const int64_t kLatin1_850;
+ static const int64_t kUS_437;
+
+ // UNIMPLEMENTED: EnumSet<CodePageRange> asSet(long range1, long range2,
+ // long range3, long range4)
+ // long[] asArray(EnumSet<CodePageRange> rangeSet)
+};
+
+// An OS/2 table - 'OS/2'.
+class OS2Table : public Table, public RefCounted<OS2Table> {
+ public:
+ // A builder for the OS/2 table = 'OS/2'.
+ class Builder : public TableBasedTableBuilder, public RefCounted<Builder> {
+ public:
+ Builder(Header* header, WritableFontData* data);
+ Builder(Header* header, ReadableFontData* data);
+ virtual ~Builder();
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ WritableFontData* data);
+
+ int32_t TableVersion();
+ void SetTableVersion(int32_t version);
+ int32_t XAvgCharWidth();
+ void SetXAvgCharWidth(int32_t width);
+ int32_t UsWeightClass();
+ void SetUsWeightClass(int32_t weight);
+ int32_t UsWidthClass();
+ void SetUsWidthClass(int32_t width);
+ // UNIMPLEMENTED: EnumSet<EmbeddingFlags> fsType()
+ // void setFsType(EnumSeT<EmbeddingFlags> flagSet)
+ int32_t FsType();
+ void SetFsType(int32_t fs_type);
+ int32_t YSubscriptXSize();
+ void SetYSubscriptXSize(int32_t size);
+ int32_t YSubscriptYSize();
+ void SetYSubscriptYSize(int32_t size);
+ int32_t YSubscriptXOffset();
+ void SetYSubscriptXOffset(int32_t offset);
+ int32_t YSubscriptYOffset();
+ void SetYSubscriptYOffset(int32_t offset);
+ int32_t YSuperscriptXSize();
+ void SetYSuperscriptXSize(int32_t size);
+ int32_t YSuperscriptYSize();
+ void SetYSuperscriptYSize(int32_t size);
+ int32_t YSuperscriptXOffset();
+ void SetYSuperscriptXOffset(int32_t offset);
+ int32_t YSuperscriptYOffset();
+ void SetYSuperscriptYOffset(int32_t offset);
+ int32_t YStrikeoutSize();
+ void SetYStrikeoutSize(int32_t size);
+ int32_t YStrikeoutPosition();
+ void SetYStrikeoutPosition(int32_t position);
+ int32_t SFamilyClass();
+ void SetSFamilyClass(int32_t family);
+ void Panose(ByteVector* value);
+ void SetPanose(ByteVector* panose);
+ int64_t UlUnicodeRange1();
+ void SetUlUnicodeRange1(int64_t range);
+ int64_t UlUnicodeRange2();
+ void SetUlUnicodeRange2(int64_t range);
+ int64_t UlUnicodeRange3();
+ void SetUlUnicodeRange3(int64_t range);
+ int64_t UlUnicodeRange4();
+ void SetUlUnicodeRange4(int64_t range);
+ // UNIMPLEMENTED: EnumSet<UnicodeRange> UlUnicodeRange()
+ // setUlUnicodeRange(EnumSet<UnicodeRange> rangeSet)
+ void AchVendId(ByteVector* 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);
+ // UNIMPLEMENTED: public EnumSet<FsSelection> fsSelection()
+ int32_t FsSelection();
+ void SetFsSelection(int32_t fs_selection);
+ int32_t UsFirstCharIndex();
+ void SetUsFirstCharIndex(int32_t first_index);
+ int32_t UsLastCharIndex();
+ void SetUsLastCharIndex(int32_t last_index);
+ int32_t STypoAscender();
+ void SetSTypoAscender(int32_t ascender);
+ int32_t STypoDescender();
+ void SetSTypoDescender(int32_t descender);
+ int32_t STypoLineGap();
+ void SetSTypoLineGap(int32_t line_gap);
+ int32_t UsWinAscent();
+ void SetUsWinAscent(int32_t ascent);
+ int32_t UsWinDescent();
+ void SetUsWinDescent(int32_t descent);
+ int64_t UlCodePageRange1();
+ void SetUlCodePageRange1(int64_t range);
+ int64_t UlCodePageRange2();
+ void SetUlCodePageRange2(int64_t range);
+ // UNIMPLEMENTED: EnumSet<CodePageRange> ulCodePageRange()
+ // void setUlCodePageRange(EnumSet<CodePageRange> rangeSet)
+ int32_t SxHeight();
+ void SetSxHeight(int32_t height);
+ int32_t SCapHeight();
+ void SetSCapHeight(int32_t height);
+ int32_t UsDefaultChar();
+ void SetUsDefaultChar(int32_t default_char);
+ int32_t UsBreakChar();
+ void SetUsBreakChar(int32_t break_char);
+ int32_t UsMaxContext();
+ void SetUsMaxContext(int32_t max_context);
+ };
+
+ ~OS2Table();
+
+ int32_t TableVersion();
+ int32_t XAvgCharWidth();
+ int32_t UsWeightClass();
+ int32_t UsWidthClass();
+ // UNIMPLEMENTED: public EnumSet<EmbeddingFlags> fsType()
+ int32_t FsType();
+ int32_t YSubscriptXSize();
+ int32_t YSubscriptYSize();
+ int32_t YSubscriptXOffset();
+ int32_t YSubscriptYOffset();
+ int32_t YSuperscriptXSize();
+ int32_t YSuperscriptYSize();
+ int32_t YSuperscriptXOffset();
+ int32_t YSuperscriptYOffset();
+ int32_t YStrikeoutSize();
+ int32_t YStrikeoutPosition();
+ int32_t SFamilyClass();
+ void Panose(ByteVector* value);
+ int64_t UlUnicodeRange1();
+ int64_t UlUnicodeRange2();
+ int64_t UlUnicodeRange3();
+ int64_t UlUnicodeRange4();
+ // UNIMPLEMENTED: public EnumSet<UnicodeRange> UlUnicodeRange()
+ void AchVendId(ByteVector* b);
+ // UNIMPLEMENTED: public EnumSet<FsSelection> fsSelection()
+ int32_t FsSelection();
+ int32_t UsFirstCharIndex();
+ int32_t UsLastCharIndex();
+ int32_t STypoAscender();
+ int32_t STypoDescender();
+ int32_t STypoLineGap();
+ int32_t UsWinAscent();
+ int32_t UsWinDescent();
+ int64_t UlCodePageRange1();
+ int64_t UlCodePageRange2();
+ // UNIMPLEMENTED: public EnumSet<CodePageRange> ulCodePageRange()
+ int32_t SxHeight();
+ int32_t SCapHeight();
+ int32_t UsDefaultChar();
+ int32_t UsBreakChar();
+ int32_t UsMaxContext();
+
+ private:
+ struct Offset {
+ enum {
+ kVersion = 0,
+ kXAvgCharWidth = 2,
+ kUsWeightClass = 4,
+ kUsWidthClass = 6,
+ kFsType = 8,
+ kYSubscriptXSize = 10,
+ kYSubscriptYSize = 12,
+ kYSubscriptXOffset = 14,
+ kYSubscriptYOffset = 16,
+ kYSuperscriptXSize = 18,
+ kYSuperscriptYSize = 20,
+ kYSuperscriptXOffset = 22,
+ kYSuperscriptYOffset = 24,
+ kYStrikeoutSize = 26,
+ kYStrikeoutPosition = 28,
+ kSFamilyClass = 30,
+ kPanose = 32,
+ kPanoseLength = 10, // Length of panose bytes.
+ kUlUnicodeRange1 = 42,
+ kUlUnicodeRange2 = 46,
+ kUlUnicodeRange3 = 50,
+ kUlUnicodeRange4 = 54,
+ kAchVendId = 58,
+ kAchVendIdLength = 4, // Length of ach vend id bytes.
+ kFsSelection = 62,
+ kUsFirstCharIndex = 64,
+ kUsLastCharIndex = 66,
+ kSTypoAscender = 68,
+ kSTypoDescender = 70,
+ kSTypoLineGap = 72,
+ kUsWinAscent = 74,
+ kUsWinDescent = 76,
+ kUlCodePageRange1 = 78,
+ kUlCodePageRange2 = 82,
+ kSxHeight = 86,
+ kSCapHeight = 88,
+ kUsDefaultChar = 90,
+ kUsBreakChar = 92,
+ kUsMaxContext = 94
+ };
+ };
+
+ OS2Table(Header* header, ReadableFontData* data);
+};
+typedef Ptr<OS2Table> OS2TablePtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_OS2_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/font_data_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/font_data_table.cc
new file mode 100644
index 00000000000..0e27f7a7717
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/font_data_table.cc
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/font_data_table.h"
+
+#include "sfntly/data/font_output_stream.h"
+
+namespace sfntly {
+
+/******************************************************************************
+ * FontDataTable class
+ ******************************************************************************/
+
+FontDataTable::FontDataTable(ReadableFontData* data) {
+ data_ = data;
+}
+
+FontDataTable::~FontDataTable() {}
+
+ReadableFontData* FontDataTable::ReadFontData() {
+ return data_;
+}
+
+int32_t FontDataTable::DataLength() {
+ return data_->Length();
+}
+
+int32_t FontDataTable::Serialize(OutputStream* os) {
+ return data_->CopyTo(os);
+}
+
+int32_t FontDataTable::Serialize(WritableFontData* data) {
+ return data_->CopyTo(data);
+}
+
+/******************************************************************************
+ * FontDataTable::Builder class
+ ******************************************************************************/
+CALLER_ATTACH WritableFontData* FontDataTable::Builder::Data() {
+ WritableFontDataPtr new_data;
+ if (model_changed_) {
+ if (!SubReadyToSerialize()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("Table not ready to build.");
+#endif
+ return NULL;
+ }
+ int32_t size = SubDataSizeToSerialize();
+ new_data.Attach(WritableFontData::CreateWritableFontData(size));
+ SubSerialize(new_data);
+ } else {
+ ReadableFontDataPtr data = InternalReadData();
+ new_data.Attach(WritableFontData::CreateWritableFontData(
+ data != NULL ? data->Length() : 0));
+ if (data != NULL) {
+ data->CopyTo(new_data);
+ }
+ }
+ return new_data.Detach();
+}
+
+void FontDataTable::Builder::SetData(ReadableFontData* data) {
+ InternalSetData(data, true);
+}
+
+
+CALLER_ATTACH FontDataTable* FontDataTable::Builder::Build() {
+ FontDataTablePtr table; // NULL default table
+ ReadableFontDataPtr data = InternalReadData();
+ if (model_changed_) {
+ // Let subclass serialize from model.
+ if (!SubReadyToSerialize()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IOException("Table not ready to build.");
+#endif
+ return NULL;
+ }
+ int32_t size = SubDataSizeToSerialize();
+ WritableFontDataPtr new_data;
+ new_data.Attach(WritableFontData::CreateWritableFontData(size));
+ SubSerialize(new_data);
+ data = new_data;
+ }
+
+ if (data != NULL) {
+ table = SubBuildTable(data);
+ NotifyPostTableBuild(table);
+ }
+
+ r_data_.Release();
+ w_data_.Release();
+ return table;
+}
+
+bool FontDataTable::Builder::ReadyToBuild() {
+ return true;
+}
+
+ReadableFontData* FontDataTable::Builder::InternalReadData() {
+ return (r_data_ != NULL) ? r_data_.p_ :
+ static_cast<ReadableFontData*>(w_data_.p_);
+}
+
+WritableFontData* FontDataTable::Builder::InternalWriteData() {
+ if (w_data_ == NULL) {
+ WritableFontDataPtr new_data;
+ new_data.Attach(WritableFontData::CreateWritableFontData(
+ r_data_ == NULL ? 0 : r_data_->Length()));
+#if !defined (SFNTLY_NO_EXCEPTION)
+ try {
+#endif
+ if (r_data_) {
+ r_data_->CopyTo(new_data);
+ }
+#if !defined (SFNTLY_NO_EXCEPTION)
+ } catch (IOException& e) {
+ // TODO(stuartg): fix when IOExceptions are cleaned up
+ }
+#endif
+ InternalSetData(new_data, false);
+ }
+ return w_data_.p_;
+}
+
+FontDataTable::Builder::Builder()
+ : model_changed_(false),
+ contained_model_changed_(false),
+ data_changed_(false) {
+}
+
+FontDataTable::Builder::Builder(int32_t data_size)
+ : model_changed_(false),
+ contained_model_changed_(false),
+ data_changed_(false) {
+ w_data_.Attach(WritableFontData::CreateWritableFontData(data_size));
+}
+
+FontDataTable::Builder::Builder(WritableFontData* data)
+ : model_changed_(false),
+ contained_model_changed_(false),
+ data_changed_(false) {
+ w_data_ = data;
+}
+
+FontDataTable::Builder::Builder(ReadableFontData* data)
+ : model_changed_(false),
+ contained_model_changed_(false),
+ data_changed_(false) {
+ r_data_ = data;
+}
+
+FontDataTable::Builder::~Builder() {
+}
+
+void FontDataTable::Builder::NotifyPostTableBuild(FontDataTable* table) {
+ // Default: NOP.
+ UNREFERENCED_PARAMETER(table);
+}
+
+void FontDataTable::Builder::InternalSetData(WritableFontData* data,
+ bool data_changed) {
+ w_data_ = data;
+ r_data_ = NULL;
+ if (data_changed) {
+ data_changed_ = true;
+ SubDataSet();
+ }
+}
+
+void FontDataTable::Builder::InternalSetData(ReadableFontData* data,
+ bool data_changed) {
+ w_data_ = NULL;
+ r_data_ = data;
+ if (data_changed) {
+ data_changed_ = true;
+ SubDataSet();
+ }
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/font_data_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/font_data_table.h
new file mode 100644
index 00000000000..5e437e2f345
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/font_data_table.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_FONT_DATA_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_FONT_DATA_TABLE_H_
+
+#include "sfntly/data/readable_font_data.h"
+#include "sfntly/data/writable_font_data.h"
+#include "sfntly/port/refcount.h"
+
+namespace sfntly {
+
+// An abstract base for any table that contains a FontData. This is the root of
+// the table class hierarchy.
+class FontDataTable : virtual public RefCount {
+ public:
+ // Note: original version is abstract Builder<T extends FontDataTable>
+ // C++ template is not designed that way so plain class is chosen.
+ class Builder : virtual public RefCount {
+ public:
+ // Get a snapshot copy of the internal data of the builder.
+ // This causes any internal data structures to be serialized to a new data
+ // object. This data object belongs to the caller and must be properly
+ // disposed of. No changes are made to the builder and any changes to the
+ // data directly do not affect the internal state. To do that a subsequent
+ // call must be made to {@link #SetData(WritableFontData)}.
+ // @return a copy of the internal data of the builder
+ CALLER_ATTACH WritableFontData* Data();
+ virtual void SetData(ReadableFontData* data);
+
+ // Note: changed from protected to avoid accessibility error in C++
+ virtual CALLER_ATTACH FontDataTable* Build();
+ virtual bool ReadyToBuild();
+
+ ReadableFontData* InternalReadData();
+ WritableFontData* InternalWriteData();
+
+ bool data_changed() { return data_changed_; }
+ bool model_changed() {
+ return current_model_changed() || contained_model_changed();
+ }
+ bool current_model_changed() { return model_changed_; }
+ bool contained_model_changed() { return contained_model_changed_; }
+
+ bool set_model_changed() { return set_model_changed(true); }
+ bool set_model_changed(bool changed) {
+ bool old = model_changed_;
+ model_changed_ = changed;
+ return old;
+ }
+
+ protected:
+ explicit Builder();
+
+ // Construct a FontDataTable.Builder with a WritableFontData backing store
+ // of size given. A positive size will create a fixed size backing store and
+ // a 0 or less size is an estimate for a growable backing store with the
+ // estimate being the absolute of the size.
+ // @param dataSize if positive then a fixed size; if 0 or less then an
+ // estimate for a growable size
+ Builder(int32_t data_size);
+ Builder(WritableFontData* data);
+ Builder(ReadableFontData* data);
+ virtual ~Builder();
+
+ // subclass API
+ virtual void NotifyPostTableBuild(FontDataTable* table);
+ virtual int32_t SubSerialize(WritableFontData* new_data) = 0;
+ virtual bool SubReadyToSerialize() = 0;
+ virtual int32_t SubDataSizeToSerialize() = 0;
+ virtual void SubDataSet() = 0;
+ virtual CALLER_ATTACH FontDataTable*
+ SubBuildTable(ReadableFontData* data) = 0;
+
+ private:
+ void InternalSetData(WritableFontData* data, bool data_changed);
+ void InternalSetData(ReadableFontData* data, bool data_changed);
+
+ WritableFontDataPtr w_data_;
+ ReadableFontDataPtr r_data_;
+ bool model_changed_;
+ bool contained_model_changed_; // may expand to list of submodel states
+ bool data_changed_;
+ };
+
+ explicit FontDataTable(ReadableFontData* data);
+ virtual ~FontDataTable();
+
+ // Get the readable font data for this table.
+ ReadableFontData* ReadFontData();
+
+ // Get the length of the data for this table in bytes. This is the full
+ // allocated length of the data underlying the table and may or may not
+ // include any padding.
+ virtual int32_t DataLength();
+
+ virtual int32_t Serialize(OutputStream* os);
+
+ protected:
+ virtual int32_t Serialize(WritableFontData* data);
+
+ // TODO(arthurhsu): style guide violation: protected member, need refactoring
+ ReadableFontDataPtr data_;
+};
+typedef Ptr<FontDataTable> FontDataTablePtr;
+typedef Ptr<FontDataTable::Builder> FontDataTableBuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_FONT_DATA_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/generic_table_builder.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/generic_table_builder.cc
new file mode 100644
index 00000000000..78e679772c0
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/generic_table_builder.cc
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/generic_table_builder.h"
+
+namespace sfntly {
+
+GenericTableBuilder::~GenericTableBuilder() {}
+
+CALLER_ATTACH
+FontDataTable* GenericTableBuilder::SubBuildTable(ReadableFontData* data) {
+ // Note: In C++ port, we use GenericTable, the ref-counted version of Table
+ UNREFERENCED_PARAMETER(data);
+ Ptr<GenericTable> table = new GenericTable(header(), InternalReadData());
+ return table.Detach();
+}
+
+// static
+CALLER_ATTACH GenericTableBuilder*
+ GenericTableBuilder::CreateBuilder(Header* header, WritableFontData* data) {
+ Ptr<GenericTableBuilder> builder =
+ new GenericTableBuilder(header, data);
+ return builder.Detach();
+}
+
+GenericTableBuilder::GenericTableBuilder(Header* header,
+ WritableFontData* data)
+ : TableBasedTableBuilder(header, data) {
+}
+
+GenericTableBuilder::GenericTableBuilder(Header* header,
+ ReadableFontData* data)
+ : TableBasedTableBuilder(header, data) {
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/generic_table_builder.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/generic_table_builder.h
new file mode 100644
index 00000000000..a100ea072c3
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/generic_table_builder.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_GENERIC_TABLE_BUILDER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_GENERIC_TABLE_BUILDER_H_
+
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+// A table builder to do the minimal table building for an unknown table type.
+class GenericTableBuilder : public TableBasedTableBuilder,
+ public RefCounted<GenericTableBuilder> {
+ public:
+ virtual ~GenericTableBuilder();
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+
+ static CALLER_ATTACH GenericTableBuilder*
+ CreateBuilder(Header* header, WritableFontData* data);
+
+ private:
+ GenericTableBuilder(Header* header, WritableFontData* data);
+ GenericTableBuilder(Header* header, ReadableFontData* data);
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_BYTE_ARRAY_TABLE_BUILDER_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/header.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/header.cc
new file mode 100644
index 00000000000..672ace5749d
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/header.cc
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/header.h"
+
+namespace sfntly {
+
+/******************************************************************************
+ * Header class
+ ******************************************************************************/
+Header::Header(int32_t tag)
+ : tag_(tag),
+ offset_(0),
+ offset_valid_(false),
+ length_(0),
+ length_valid_(false),
+ checksum_(0),
+ checksum_valid_(false) {
+}
+
+Header::Header(int32_t tag, int32_t length)
+ : tag_(tag),
+ offset_(0),
+ offset_valid_(false),
+ length_(length),
+ length_valid_(true),
+ checksum_(0),
+ checksum_valid_(false) {
+}
+
+Header::Header(int32_t tag, int64_t checksum, int32_t offset, int32_t length)
+ : tag_(tag),
+ offset_(offset),
+ offset_valid_(true),
+ length_(length),
+ length_valid_(true),
+ checksum_(checksum),
+ checksum_valid_(true) {
+}
+
+Header::~Header() {}
+
+bool HeaderComparatorByOffset::operator() (const HeaderPtr lhs,
+ const HeaderPtr rhs) {
+ return lhs->offset_ > rhs->offset_;
+}
+
+bool HeaderComparatorByTag::operator() (const HeaderPtr lhs,
+ const HeaderPtr rhs) {
+ return lhs->tag_ > rhs->tag_;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/header.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/header.h
new file mode 100644
index 00000000000..280e556c472
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/header.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_HEADER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_HEADER_H_
+
+#include "sfntly/port/refcount.h"
+
+namespace sfntly {
+
+class Header : public RefCounted<Header> {
+ public:
+ // Make a partial header with only the basic info for an empty new table.
+ explicit Header(int32_t tag);
+
+ // Make a partial header with only the basic info for a new table.
+ Header(int32_t tag, int32_t length);
+
+ // Make a full header as read from an existing font.
+ Header(int32_t tag, int64_t checksum, int32_t offset, int32_t length);
+ virtual ~Header();
+
+ // Get the table tag.
+ int32_t tag() { 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_; }
+
+ // 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_; }
+
+ // 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_; }
+
+ // 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_; }
+
+ // Get the checksum for the table as recorded in the table record header.
+ int64_t checksum() { 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_; }
+
+ // 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_;
+
+ friend class HeaderComparatorByOffset;
+ friend class HeaderComparatorByTag;
+};
+typedef Ptr<Header> HeaderPtr;
+
+class HeaderComparator {
+ public:
+ virtual ~HeaderComparator() {}
+ virtual bool operator()(const HeaderPtr h1,
+ const HeaderPtr h2) = 0;
+};
+
+class HeaderComparatorByOffset : public HeaderComparator {
+ public:
+ virtual ~HeaderComparatorByOffset() {}
+ virtual bool operator()(const HeaderPtr h1,
+ const HeaderPtr h2);
+};
+
+class HeaderComparatorByTag : public HeaderComparator {
+ public:
+ virtual ~HeaderComparatorByTag() {}
+ virtual bool operator()(const HeaderPtr h1,
+ const HeaderPtr h2);
+};
+
+typedef std::set<HeaderPtr, HeaderComparatorByOffset> HeaderOffsetSortedSet;
+typedef std::set<HeaderPtr, HeaderComparatorByTag> HeaderTagSortedSet;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_HEADER_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/subtable.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/subtable.cc
new file mode 100644
index 00000000000..e5b906fd376
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/subtable.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/subtable.h"
+
+namespace sfntly {
+/******************************************************************************
+ * SubTable class
+ ******************************************************************************/
+SubTable::~SubTable() {}
+
+SubTable::SubTable(ReadableFontData* data, ReadableFontData* master_data)
+ : FontDataTable(data), padding_(0) {
+ master_data_ = master_data;
+}
+
+SubTable::SubTable(ReadableFontData* data)
+ : FontDataTable(data), padding_(0) {
+}
+
+/******************************************************************************
+ * SubTable::Builder class
+ ******************************************************************************/
+SubTable::Builder::~Builder() {
+}
+
+SubTable::Builder::Builder(int32_t data_size)
+ : FontDataTable::Builder(data_size) {
+}
+
+SubTable::Builder::Builder(WritableFontData* data,
+ ReadableFontData* master_data)
+ : FontDataTable::Builder(data) {
+ master_data_ = master_data;
+}
+
+SubTable::Builder::Builder(ReadableFontData* data,
+ ReadableFontData* master_data)
+ : FontDataTable::Builder(data) {
+ master_data_ = master_data;
+}
+
+SubTable::Builder::Builder(WritableFontData* data)
+ : FontDataTable::Builder(data) {
+}
+
+SubTable::Builder::Builder(ReadableFontData* data)
+ : FontDataTable::Builder(data) {
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/subtable.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/subtable.h
new file mode 100644
index 00000000000..fa6f4c6bcdb
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/subtable.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_SUBTABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_SUBTABLE_H_
+
+#include "sfntly/table/font_data_table.h"
+
+namespace sfntly {
+
+// An abstract base class for subtables. Subtables are smaller tables nested
+// within other tables and don't have an entry in the main font index. Examples
+// of these are the CMap subtables within CMap table (cmap) or a glyph within
+// the glyph table (glyf).
+class SubTable : public FontDataTable {
+ public:
+ class Builder : public FontDataTable::Builder {
+ public:
+ virtual ~Builder();
+
+ protected:
+ // @param data the data for the subtable being built
+ // @param master_data the data for the full table
+ Builder(int32_t data_size);
+ Builder(WritableFontData* data, ReadableFontData* master_data);
+ Builder(ReadableFontData* data, ReadableFontData* master_data);
+ explicit Builder(WritableFontData* data);
+ explicit Builder(ReadableFontData* data);
+
+ ReadableFontData* master_read_data() { return master_data_; }
+
+ private:
+ ReadableFontDataPtr master_data_;
+ };
+
+ virtual ~SubTable();
+ virtual int32_t Padding() { return padding_; }
+
+ // Sets the amount of padding that is part of the data being used by this
+ // subtable.
+ void set_padding(int32_t padding) { padding_ = padding; }
+
+ protected:
+ SubTable(ReadableFontData* data, ReadableFontData* master_data);
+
+ // Note: constructor refactored in C++ to avoid heavy lifting.
+ // caller need to do data->Slice(offset, length) beforehand.
+ explicit SubTable(ReadableFontData* data);
+
+ ReadableFontData* master_read_data() { return master_data_; }
+
+ private:
+ // The data for the whole table in which this subtable is contained.
+ ReadableFontDataPtr master_data_;
+ int32_t padding_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_SUBTABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/subtable_container_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/subtable_container_table.h
new file mode 100644
index 00000000000..0f099debb4c
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/subtable_container_table.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TYPOGRAPHY_FONT_SFNTLY_SRC_SFNTLY_TABLE_SUBTABLE_CONTAINER_TABLE_H_
+#define TYPOGRAPHY_FONT_SFNTLY_SRC_SFNTLY_TABLE_SUBTABLE_CONTAINER_TABLE_H_
+
+#include "sfntly/table/table.h"
+
+namespace sfntly {
+
+class SubTableContainerTable : public Table {
+ public:
+ class Builder : public Table::Builder {
+ public:
+ Builder(Header* header, WritableFontData* data)
+ : Table::Builder(header, data) {
+ }
+
+ Builder(Header* header, ReadableFontData* data)
+ : Table::Builder(header, data) {
+ }
+
+ virtual ~Builder() {}
+ };
+
+ SubTableContainerTable(Header* header, ReadableFontData* data)
+ : Table(header, data) {
+ }
+
+ virtual ~SubTableContainerTable() {}
+};
+
+} // namespace sfntly
+
+#endif // TYPOGRAPHY_FONT_SFNTLY_SRC_SFNTLY_TABLE_SUBTABLE_CONTAINER_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/table.cc
new file mode 100644
index 00000000000..cf574b838b6
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/table.cc
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// type.h needs to be included first because of building issues on Windows
+// Type aliases we delcare are defined in other headers and make the build
+// fail otherwise.
+#include "sfntly/port/type.h"
+#include "sfntly/table/table.h"
+
+#include "sfntly/font.h"
+#include "sfntly/tag.h"
+#include "sfntly/table/bitmap/ebdt_table.h"
+#include "sfntly/table/bitmap/eblc_table.h"
+#include "sfntly/table/bitmap/ebsc_table.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/table/core/font_header_table.h"
+#include "sfntly/table/core/horizontal_device_metrics_table.h"
+#include "sfntly/table/core/horizontal_header_table.h"
+#include "sfntly/table/core/horizontal_metrics_table.h"
+#include "sfntly/table/core/maximum_profile_table.h"
+#include "sfntly/table/core/name_table.h"
+#include "sfntly/table/core/os2_table.h"
+#include "sfntly/table/generic_table_builder.h"
+#include "sfntly/table/table_based_table_builder.h"
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+
+namespace sfntly {
+
+/******************************************************************************
+ * Table class
+ ******************************************************************************/
+Table::~Table() {}
+
+int64_t Table::CalculatedChecksum() {
+ return data_->Checksum();
+}
+
+void Table::SetFont(Font* font) {
+ font_ = font;
+}
+
+Table::Table(Header* header, ReadableFontData* data)
+ : FontDataTable(data) {
+ header_ = header;
+}
+
+/******************************************************************************
+ * Table::Builder class
+ ******************************************************************************/
+Table::Builder::~Builder() {
+ header_.Release();
+}
+
+void Table::Builder::NotifyPostTableBuild(FontDataTable* table) {
+ if (model_changed() || data_changed()) {
+ Table* derived_table = down_cast<Table*>(table);
+ derived_table->header_ = new Header(header()->tag(),
+ derived_table->DataLength());
+ }
+}
+
+CALLER_ATTACH
+Table::Builder* Table::Builder::GetBuilder(Header* header,
+ WritableFontData* table_data) {
+ int32_t tag = header->tag();
+ Table::Builder* builder_raw = NULL;
+
+ // Note: Tables are commented out when they are not used/ported.
+ // TODO(arthurhsu): IMPLEMENT: finish tables that are not ported.
+ if (tag == Tag::head) {
+ builder_raw = static_cast<Table::Builder*>(
+ FontHeaderTable::Builder::CreateBuilder(header, table_data));
+#if defined (SFNTLY_EXPERIMENTAL)
+ } else if (tag == Tag::cmap) {
+ builder_raw = static_cast<Table::Builder*>(
+ CMapTable::Builder::CreateBuilder(header, table_data));
+#endif // SFNTLY_EXPERIMENTAL
+ } else if (tag == Tag::hhea) {
+ builder_raw = static_cast<Table::Builder*>(
+ HorizontalHeaderTable::Builder::CreateBuilder(header, table_data));
+ } else if (tag == Tag::hmtx) {
+ builder_raw = static_cast<Table::Builder*>(
+ HorizontalMetricsTable::Builder::CreateBuilder(header, table_data));
+ } else if (tag == Tag::maxp) {
+ builder_raw = static_cast<Table::Builder*>(
+ MaximumProfileTable::Builder::CreateBuilder(header, table_data));
+ } else if (tag == Tag::name) {
+ builder_raw = static_cast<Table::Builder*>(
+ NameTable::Builder::CreateBuilder(header, table_data));
+ } else if (tag == Tag::OS_2) {
+ builder_raw = static_cast<Table::Builder*>(
+ OS2Table::Builder::CreateBuilder(header, table_data));
+ }/* else if (tag == Tag::PostScript) {
+ builder_raw = static_cast<Table::Builder*>(
+ PostScriptTable::Builder::CreateBuilder(header, table_data));
+ } else if (tag == Tag::cvt) {
+ builder_raw = static_cast<Table::Builder*>(
+ ControlValueTable::Builder::CreateBuilder(header, table_data));
+ }*/ else if (tag == Tag::glyf) {
+ builder_raw = static_cast<Table::Builder*>(
+ GlyphTable::Builder::CreateBuilder(header, table_data));
+ } else if (tag == Tag::loca) {
+ builder_raw = static_cast<Table::Builder*>(
+ LocaTable::Builder::CreateBuilder(header, table_data));
+ } else if (tag == Tag::EBDT || tag == Tag::bdat) {
+ builder_raw = static_cast<Table::Builder*>(
+ EbdtTable::Builder::CreateBuilder(header, table_data));
+ } else if (tag == Tag::EBLC || tag == Tag::bloc) {
+ builder_raw = static_cast<Table::Builder*>(
+ EblcTable::Builder::CreateBuilder(header, table_data));
+ } else if (tag == Tag::EBSC) {
+ builder_raw = static_cast<Table::Builder*>(
+ EbscTable::Builder::CreateBuilder(header, table_data));
+ } /* else if (tag == Tag::prep) {
+ builder_raw = static_cast<Table::Builder*>(
+ ControlProgramTable::Builder::CreateBuilder(header, table_data));
+ }*/ else if (tag == Tag::bhed) {
+ builder_raw = static_cast<Table::Builder*>(
+ FontHeaderTable::Builder::CreateBuilder(header, table_data));
+#if defined (SFNTLY_EXPERIMENTAL)
+ } else if (tag == Tag::hdmx) {
+ builder_raw = static_cast<Table::Builder*>(
+ HorizontalDeviceMetricsTable::Builder::CreateBuilder(header,
+ table_data));
+#endif // SFNTLY_EXPERIMENTAL
+ } else {
+ builder_raw = static_cast<Table::Builder*>(
+ GenericTableBuilder::CreateBuilder(header, table_data));
+ }
+
+ return builder_raw;
+}
+
+Table::Builder::Builder(Header* header, WritableFontData* data)
+ : FontDataTable::Builder(data) {
+ header_ = header;
+}
+
+Table::Builder::Builder(Header* header, ReadableFontData* data)
+ : FontDataTable::Builder(data) {
+ header_ = header;
+}
+
+Table::Builder::Builder(Header* header) {
+ header_ = header;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/table.h
new file mode 100644
index 00000000000..6ebc22df8ad
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/table.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_TABLE_H_
+
+#include <set>
+#include <map>
+#include <vector>
+#include <utility>
+
+#include "sfntly/port/type.h"
+#include "sfntly/table/font_data_table.h"
+#include "sfntly/table/header.h"
+
+namespace sfntly {
+class Font;
+
+// A concrete implementation of a root level table in the font. This is the base
+// class used for all specific table implementations and is used as the generic
+// table for all tables which have no specific implementations.
+class Table : public FontDataTable {
+ public:
+ // Note: original version is Builder<T extends Table>
+ // C++ template is not designed that way so plain old inheritance is
+ // chosen.
+ class Builder : public FontDataTable::Builder {
+ public:
+ virtual ~Builder();
+ virtual Header* header() { return header_; }
+ virtual void NotifyPostTableBuild(FontDataTable* table);
+
+ // Get a builder for the table type specified by the data in the header.
+ // @param header the header for the table
+ // @param tableData the data to be used to build the table from
+ // @return builder for the table specified
+ static CALLER_ATTACH Builder* GetBuilder(Header* header,
+ WritableFontData* table_data);
+
+ // UNIMPLEMENTED: toString()
+
+ protected:
+ Builder(Header* header, WritableFontData* data);
+ Builder(Header* header, ReadableFontData* data);
+ Builder(Header* header);
+
+ private:
+ Ptr<Header> header_;
+ };
+
+ // Note: GenericTableBuilder moved to table_based_table_builder.h to avoid
+ // circular inclusion.
+
+ virtual ~Table();
+
+ // Get the calculated checksum for the data in the table.
+ virtual int64_t CalculatedChecksum();
+
+ // Get the header for the table.
+ virtual Header* header() { return header_; }
+
+ // Get the tag for the table from the record header.
+ virtual int32_t header_tag() { return header_->tag(); }
+
+ // Get the offset for the table from the record header.
+ virtual int32_t header_offset() { return header_->offset(); }
+
+ // Get the length of the table from the record header.
+ virtual int32_t header_length() { return header_->length(); }
+
+ // Get the checksum for the table from the record header.
+ virtual int64_t header_checksum() { return header_->checksum(); }
+
+ // UNIMPLEMENTED: toString()
+
+ virtual void SetFont(Font* font);
+
+ protected:
+ Table(Header* header, ReadableFontData* data);
+
+ private:
+ Ptr<Header> header_;
+ Ptr<Font> font_;
+};
+
+// C++ port only
+class GenericTable : public Table, public RefCounted<GenericTable> {
+ public:
+ GenericTable(Header* header, ReadableFontData* data) : Table(header, data) {}
+ virtual ~GenericTable() {}
+};
+
+typedef Ptr<Table> TablePtr;
+typedef std::vector<HeaderPtr> TableHeaderList;
+typedef Ptr<Table::Builder> TableBuilderPtr;
+typedef std::map<int32_t, TablePtr> TableMap;
+typedef std::pair<int32_t, TablePtr> TableMapEntry;
+
+typedef std::map<HeaderPtr, WritableFontDataPtr> DataBlockMap;
+typedef std::pair<HeaderPtr, WritableFontDataPtr> DataBlockEntry;
+typedef std::map<int32_t, TableBuilderPtr> TableBuilderMap;
+typedef std::pair<int32_t, TableBuilderPtr> TableBuilderEntry;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/table_based_table_builder.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/table_based_table_builder.cc
new file mode 100644
index 00000000000..b5057046385
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/table_based_table_builder.cc
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/table_based_table_builder.h"
+
+namespace sfntly {
+
+/******************************************************************************
+ * TableBasedTableBuilder class
+ ******************************************************************************/
+TableBasedTableBuilder::~TableBasedTableBuilder() {}
+
+int32_t TableBasedTableBuilder::SubSerialize(WritableFontData* data) {
+ UNREFERENCED_PARAMETER(data);
+ return 0;
+}
+
+bool TableBasedTableBuilder::SubReadyToSerialize() {
+ return false;
+}
+
+int32_t TableBasedTableBuilder::SubDataSizeToSerialize() {
+ return 0;
+}
+
+void TableBasedTableBuilder::SubDataSet() {
+ table_ = NULL;
+}
+
+CALLER_ATTACH FontDataTable* TableBasedTableBuilder::Build() {
+ FontDataTablePtr table = static_cast<FontDataTable*>(GetTable());
+ return table.Detach();
+}
+
+TableBasedTableBuilder::TableBasedTableBuilder(Header* header,
+ WritableFontData* data)
+ : Table::Builder(header, data) {
+}
+
+TableBasedTableBuilder::TableBasedTableBuilder(Header* header,
+ ReadableFontData* data)
+ : Table::Builder(header, data) {
+}
+
+TableBasedTableBuilder::TableBasedTableBuilder(Header* header)
+ : Table::Builder(header) {
+}
+
+Table* TableBasedTableBuilder::GetTable() {
+ if (table_ == NULL) {
+ table_.Attach(down_cast<Table*>(SubBuildTable(InternalReadData())));
+ }
+ return table_;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/table_based_table_builder.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/table_based_table_builder.h
new file mode 100644
index 00000000000..d88eefd11ee
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/table_based_table_builder.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_TABLE_BASED_TABLE_BUILDER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_TABLE_BASED_TABLE_BUILDER_H_
+
+#include "sfntly/table/table.h"
+
+namespace sfntly {
+
+class TableBasedTableBuilder : public Table::Builder {
+ public:
+ virtual ~TableBasedTableBuilder();
+
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual void SubDataSet();
+ virtual CALLER_ATTACH FontDataTable* Build();
+
+ protected:
+ TableBasedTableBuilder(Header* header, WritableFontData* data);
+ TableBasedTableBuilder(Header* header, ReadableFontData* data);
+ explicit TableBasedTableBuilder(Header* header);
+
+ // C++ port: renamed table() to GetTable()
+ virtual Table* GetTable();
+
+ // TODO(arthurhsu): style guide violation: protected member, need refactor
+ TablePtr table_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_TABLE_BASED_TABLE_BUILDER_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/glyph_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/glyph_table.cc
new file mode 100644
index 00000000000..f38fac5c5c4
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/glyph_table.cc
@@ -0,0 +1,679 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/truetype/glyph_table.h"
+
+#include <stdlib.h>
+
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+/******************************************************************************
+ * Constants
+ ******************************************************************************/
+const int32_t GlyphTable::SimpleGlyph::kFLAG_ONCURVE = 1;
+const int32_t GlyphTable::SimpleGlyph::kFLAG_XSHORT = 1 << 1;
+const int32_t GlyphTable::SimpleGlyph::kFLAG_YSHORT = 1 << 2;
+const int32_t GlyphTable::SimpleGlyph::kFLAG_REPEAT = 1 << 3;
+const int32_t GlyphTable::SimpleGlyph::kFLAG_XREPEATSIGN = 1 << 4;
+const int32_t GlyphTable::SimpleGlyph::kFLAG_YREPEATSIGN = 1 << 5;
+
+const int32_t GlyphTable::CompositeGlyph::kFLAG_ARG_1_AND_2_ARE_WORDS = 1 << 0;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_ARGS_ARE_XY_VALUES = 1 << 1;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_ROUND_XY_TO_GRID = 1 << 2;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_A_SCALE = 1 << 3;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_RESERVED = 1 << 4;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_MORE_COMPONENTS = 1 << 5;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_A_TWO_BY_TWO = 1 << 7;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_WE_HAVE_INSTRUCTIONS = 1 << 8;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_USE_MY_METRICS = 1 << 9;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_OVERLAP_COMPOUND = 1 << 10;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_SCALED_COMPONENT_OFFSET = 1 << 11;
+const int32_t GlyphTable::CompositeGlyph::kFLAG_UNSCALED_COMPONENT_OFFSET = 1 << 12;
+
+/******************************************************************************
+ * GlyphTable class
+ ******************************************************************************/
+GlyphTable::~GlyphTable() {
+}
+
+GlyphTable::Glyph* GlyphTable::GetGlyph(int32_t offset, int32_t length) {
+ return GlyphTable::Glyph::GetGlyph(this, this->data_, offset, length);
+}
+
+GlyphTable::GlyphTable(Header* header, ReadableFontData* data)
+ : SubTableContainerTable(header, data) {
+}
+
+/******************************************************************************
+ * GlyphTable::Builder class
+ ******************************************************************************/
+GlyphTable::Builder::Builder(Header* header, ReadableFontData* data)
+ : SubTableContainerTable::Builder(header, data) {
+}
+
+GlyphTable::Builder::~Builder() {
+}
+
+void GlyphTable::Builder::SetLoca(const IntegerList& loca) {
+ loca_ = loca;
+ set_model_changed(false);
+ glyph_builders_.clear();
+}
+
+void GlyphTable::Builder::GenerateLocaList(IntegerList* locas) {
+ assert(locas);
+ GlyphBuilderList* glyph_builders = GetGlyphBuilders();
+ locas->push_back(0);
+ if (glyph_builders->size() == 0) {
+ locas->push_back(0);
+ } else {
+ int32_t total = 0;
+ for (GlyphBuilderList::iterator b = glyph_builders->begin(),
+ b_end = glyph_builders->end();
+ b != b_end; ++b) {
+ int32_t size = (*b)->SubDataSizeToSerialize();
+ locas->push_back(total + size);
+ total += size;
+ }
+ }
+}
+
+CALLER_ATTACH GlyphTable::Builder*
+ GlyphTable::Builder::CreateBuilder(Header* header, WritableFontData* data) {
+ Ptr<GlyphTable::Builder> builder;
+ builder = new GlyphTable::Builder(header, data);
+ return builder.Detach();
+}
+
+GlyphTable::GlyphBuilderList* GlyphTable::Builder::GlyphBuilders() {
+ return GetGlyphBuilders();
+}
+
+void GlyphTable::Builder::SetGlyphBuilders(GlyphBuilderList* glyph_builders) {
+ glyph_builders_ = *glyph_builders;
+ set_model_changed();
+}
+
+CALLER_ATTACH GlyphTable::Glyph::Builder*
+ GlyphTable::Builder::GlyphBuilder(ReadableFontData* data) {
+ return Glyph::Builder::GetBuilder(this, data);
+}
+
+CALLER_ATTACH FontDataTable*
+ GlyphTable::Builder::SubBuildTable(ReadableFontData* data) {
+ FontDataTablePtr table = new GlyphTable(header(), data);
+ return table.Detach();
+}
+
+void GlyphTable::Builder::SubDataSet() {
+ glyph_builders_.clear();
+ set_model_changed(false);
+}
+
+int32_t GlyphTable::Builder::SubDataSizeToSerialize() {
+ if (glyph_builders_.empty())
+ return 0;
+
+ bool variable = false;
+ int32_t size = 0;
+
+ // Calculate size of each table.
+ for (GlyphBuilderList::iterator b = glyph_builders_.begin(),
+ end = glyph_builders_.end(); b != end; ++b) {
+ int32_t glyph_size = (*b)->SubDataSizeToSerialize();
+ size += abs(glyph_size);
+ variable |= glyph_size <= 0;
+ }
+ return variable ? -size : size;
+}
+
+bool GlyphTable::Builder::SubReadyToSerialize() {
+ return !glyph_builders_.empty();
+}
+
+int32_t GlyphTable::Builder::SubSerialize(WritableFontData* new_data) {
+ int32_t size = 0;
+ for (GlyphBuilderList::iterator b = glyph_builders_.begin(),
+ end = glyph_builders_.end(); b != end; ++b) {
+ FontDataPtr data;
+ data.Attach(new_data->Slice(size));
+ size += (*b)->SubSerialize(down_cast<WritableFontData*>(data.p_));
+ }
+ return size;
+}
+
+void GlyphTable::Builder::Initialize(ReadableFontData* data,
+ const IntegerList& loca) {
+ if (data != NULL) {
+ if (loca_.empty()) {
+ return;
+ }
+ int32_t loca_value;
+ int32_t last_loca_value = loca[0];
+ for (size_t i = 1; i < loca.size(); ++i) {
+ loca_value = loca[i];
+ GlyphBuilderPtr builder;
+ builder.Attach(
+ Glyph::Builder::GetBuilder(this,
+ data,
+ last_loca_value /*offset*/,
+ loca_value - last_loca_value /*length*/));
+ glyph_builders_.push_back(builder);
+ last_loca_value = loca_value;
+ }
+ }
+}
+
+GlyphTable::GlyphBuilderList* GlyphTable::Builder::GetGlyphBuilders() {
+ if (glyph_builders_.empty()) {
+ if (InternalReadData() && !loca_.empty()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IllegalStateException(
+ "Loca values not set - unable to parse glyph data.");
+#endif
+ return NULL;
+ }
+ Initialize(InternalReadData(), loca_);
+ set_model_changed();
+ }
+ return &glyph_builders_;
+}
+
+void GlyphTable::Builder::Revert() {
+ glyph_builders_.clear();
+ set_model_changed(false);
+}
+
+/******************************************************************************
+ * GlyphTable::Glyph class
+ ******************************************************************************/
+GlyphTable::Glyph::~Glyph() {}
+
+CALLER_ATTACH GlyphTable::Glyph*
+ GlyphTable::Glyph::GetGlyph(GlyphTable* table,
+ ReadableFontData* data,
+ int32_t offset,
+ int32_t length) {
+ UNREFERENCED_PARAMETER(table);
+ int32_t type = GlyphType(data, offset, length);
+ GlyphPtr glyph;
+
+ ReadableFontDataPtr sliced_data;
+ sliced_data.Attach(down_cast<ReadableFontData*>(data->Slice(offset, length)));
+ if (type == GlyphType::kSimple) {
+ glyph = new SimpleGlyph(sliced_data);
+ } else {
+ glyph = new CompositeGlyph(sliced_data);
+ }
+ return glyph.Detach();
+}
+
+int32_t GlyphTable::Glyph::Padding() {
+ Initialize();
+ return SubTable::Padding();
+}
+
+int32_t GlyphTable::Glyph::GlyphType() {
+ return glyph_type_;
+}
+
+int32_t GlyphTable::Glyph::NumberOfContours() {
+ return number_of_contours_;
+}
+
+int32_t GlyphTable::Glyph::XMin() {
+ return data_->ReadShort(Offset::kXMin);
+}
+
+int32_t GlyphTable::Glyph::XMax() {
+ return data_->ReadShort(Offset::kXMax);
+}
+
+int32_t GlyphTable::Glyph::YMin() {
+ return data_->ReadShort(Offset::kYMin);
+}
+
+int32_t GlyphTable::Glyph::YMax() {
+ return data_->ReadShort(Offset::kYMax);
+}
+
+GlyphTable::Glyph::Glyph(ReadableFontData* data, int32_t glyph_type)
+ : SubTable(data),
+ glyph_type_(glyph_type) {
+ if (data_->Length() == 0) {
+ number_of_contours_ = 0;
+ } else {
+ // -1 if composite
+ number_of_contours_ = data_->ReadShort(Offset::kNumberOfContours);
+ }
+}
+
+int32_t GlyphTable::Glyph::GlyphType(ReadableFontData* data,
+ int32_t offset,
+ int32_t length) {
+ if (length == 0) {
+ return GlyphType::kSimple;
+ }
+ int32_t number_of_contours = data->ReadShort(offset);
+ if (number_of_contours >= 0) {
+ return GlyphType::kSimple;
+ }
+ return GlyphType::kComposite;
+}
+
+/******************************************************************************
+ * GlyphTable::Glyph::Builder class
+ ******************************************************************************/
+GlyphTable::Glyph::Builder::~Builder() {
+}
+
+GlyphTable::Glyph::Builder::Builder(WritableFontData* data)
+ : SubTable::Builder(data) {
+}
+
+GlyphTable::Glyph::Builder::Builder(ReadableFontData* data)
+ : SubTable::Builder(data) {
+}
+
+CALLER_ATTACH GlyphTable::Glyph::Builder*
+ GlyphTable::Glyph::Builder::GetBuilder(
+ GlyphTable::Builder* table_builder,
+ ReadableFontData* data) {
+ return GetBuilder(table_builder, data, 0, data->Length());
+}
+
+CALLER_ATTACH GlyphTable::Glyph::Builder*
+ GlyphTable::Glyph::Builder::GetBuilder(
+ GlyphTable::Builder* table_builder,
+ ReadableFontData* data,
+ int32_t offset,
+ int32_t length) {
+ UNREFERENCED_PARAMETER(table_builder);
+ int32_t type = Glyph::GlyphType(data, offset, length);
+ GlyphBuilderPtr builder;
+ ReadableFontDataPtr sliced_data;
+ sliced_data.Attach(down_cast<ReadableFontData*>(data->Slice(offset, length)));
+ if (type == GlyphType::kSimple) {
+ builder = new SimpleGlyph::SimpleGlyphBuilder(sliced_data);
+ } else {
+ builder = new CompositeGlyph::CompositeGlyphBuilder(sliced_data);
+ }
+ return builder.Detach();
+}
+
+void GlyphTable::Glyph::Builder::SubDataSet() {
+ // NOP
+}
+
+int32_t GlyphTable::Glyph::Builder::SubDataSizeToSerialize() {
+ return InternalReadData()->Length();
+}
+
+bool GlyphTable::Glyph::Builder::SubReadyToSerialize() {
+ return true;
+}
+
+int32_t GlyphTable::Glyph::Builder::SubSerialize(WritableFontData* new_data) {
+ return InternalReadData()->CopyTo(new_data);
+}
+
+/******************************************************************************
+ * GlyphTable::SimpleGlyph
+ ******************************************************************************/
+GlyphTable::SimpleGlyph::SimpleGlyph(ReadableFontData* data)
+ : GlyphTable::Glyph(data, GlyphType::kSimple), initialized_(false) {
+}
+
+GlyphTable::SimpleGlyph::~SimpleGlyph() {
+}
+
+int32_t GlyphTable::SimpleGlyph::InstructionSize() {
+ Initialize();
+ return instruction_size_;
+}
+
+CALLER_ATTACH ReadableFontData* GlyphTable::SimpleGlyph::Instructions() {
+ Initialize();
+ return down_cast<ReadableFontData*>(
+ 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_) {
+ return;
+ }
+
+ if (ReadFontData()->Length() == 0) {
+ instruction_size_ = 0;
+ number_of_points_ = 0;
+ instructions_offset_ = 0;
+ flags_offset_ = 0;
+ x_coordinates_offset_ = 0;
+ y_coordinates_offset_ = 0;
+ return;
+ }
+
+ instruction_size_ = data_->ReadUShort(Offset::kSimpleEndPtsOfCountours +
+ NumberOfContours() * DataSize::kUSHORT);
+ instructions_offset_ = Offset::kSimpleEndPtsOfCountours +
+ (NumberOfContours() + 1) * DataSize::kUSHORT;
+ flags_offset_ = instructions_offset_ + instruction_size_ * DataSize::kBYTE;
+ number_of_points_ = ContourEndPoint(NumberOfContours() - 1) + 1;
+ x_coordinates_.resize(number_of_points_);
+ y_coordinates_.resize(number_of_points_);
+ on_curve_.resize(number_of_points_);
+ ParseData(false);
+ x_coordinates_offset_ = flags_offset_ + flag_byte_count_ * DataSize::kBYTE;
+ y_coordinates_offset_ = x_coordinates_offset_ + x_byte_count_ *
+ DataSize::kBYTE;
+ contour_index_.resize(NumberOfContours() + 1);
+ contour_index_[0] = 0;
+ for (uint32_t contour = 0; contour < contour_index_.size() - 1; ++contour) {
+ contour_index_[contour + 1] = ContourEndPoint(contour) + 1;
+ }
+ ParseData(true);
+ int32_t non_padded_data_length =
+ 5 * DataSize::kSHORT +
+ (NumberOfContours() * DataSize::kUSHORT) +
+ DataSize::kUSHORT +
+ (instruction_size_ * DataSize::kBYTE) +
+ (flag_byte_count_ * DataSize::kBYTE) +
+ (x_byte_count_ * DataSize::kBYTE) +
+ (y_byte_count_ * DataSize::kBYTE);
+ set_padding(DataLength() - non_padded_data_length);
+ initialized_ = true;
+}
+
+void GlyphTable::SimpleGlyph::ParseData(bool fill_arrays) {
+ int32_t flag = 0;
+ int32_t flag_repeat = 0;
+ int32_t flag_index = 0;
+ int32_t x_byte_index = 0;
+ int32_t y_byte_index = 0;
+
+ for (int32_t point_index = 0; point_index < number_of_points_;
+ ++point_index) {
+ // get the flag for the current point
+ if (flag_repeat == 0) {
+ flag = FlagAsInt(flag_index++);
+ if ((flag & kFLAG_REPEAT) == kFLAG_REPEAT) {
+ flag_repeat = FlagAsInt(flag_index++);
+ }
+ } else {
+ flag_repeat--;
+ }
+
+ // on the curve?
+ if (fill_arrays) {
+ on_curve_[point_index] = ((flag & kFLAG_ONCURVE) == kFLAG_ONCURVE);
+ }
+ // get the x coordinate
+ if ((flag & kFLAG_XSHORT) == kFLAG_XSHORT) {
+ // single byte x coord value
+ if (fill_arrays) {
+ x_coordinates_[point_index] =
+ data_->ReadUByte(x_coordinates_offset_ + x_byte_index);
+ x_coordinates_[point_index] *=
+ ((flag & kFLAG_XREPEATSIGN) == kFLAG_XREPEATSIGN) ? 1 : -1;
+ }
+ x_byte_index++;
+ } else {
+ // double byte coord value
+ if (!((flag & kFLAG_XREPEATSIGN) == kFLAG_XREPEATSIGN)) {
+ if (fill_arrays) {
+ x_coordinates_[point_index] =
+ data_->ReadShort(x_coordinates_offset_ + x_byte_index);
+ }
+ x_byte_index += 2;
+ }
+ }
+ if (fill_arrays && point_index > 0) {
+ x_coordinates_[point_index] += x_coordinates_[point_index - 1];
+ }
+
+ // get the y coordinate
+ if ((flag & kFLAG_YSHORT) == kFLAG_YSHORT) {
+ if (fill_arrays) {
+ y_coordinates_[point_index] =
+ data_->ReadUByte(y_coordinates_offset_ + y_byte_index);
+ y_coordinates_[point_index] *=
+ ((flag & kFLAG_YREPEATSIGN) == kFLAG_YREPEATSIGN) ? 1 : -1;
+ }
+ y_byte_index++;
+ } else {
+ if (!((flag & kFLAG_YREPEATSIGN) == kFLAG_YREPEATSIGN)) {
+ if (fill_arrays) {
+ y_coordinates_[point_index] =
+ data_->ReadShort(y_coordinates_offset_ + y_byte_index);
+ }
+ y_byte_index += 2;
+ }
+ }
+ if (fill_arrays && point_index > 0) {
+ y_coordinates_[point_index] += y_coordinates_[point_index - 1];
+ }
+ }
+ flag_byte_count_ = flag_index;
+ x_byte_count_ = x_byte_index;
+ y_byte_count_ = y_byte_index;
+}
+
+int32_t GlyphTable::SimpleGlyph::FlagAsInt(int32_t index) {
+ return data_->ReadUByte(flags_offset_ + index * DataSize::kBYTE);
+}
+
+int32_t GlyphTable::SimpleGlyph::ContourEndPoint(int32_t contour) {
+ return data_->ReadUShort(contour * DataSize::kUSHORT +
+ Offset::kSimpleEndPtsOfCountours);
+}
+
+/******************************************************************************
+ * GlyphTable::SimpleGlyph::Builder
+ ******************************************************************************/
+GlyphTable::SimpleGlyph::SimpleGlyphBuilder::~SimpleGlyphBuilder() {
+}
+
+GlyphTable::SimpleGlyph::SimpleGlyphBuilder::SimpleGlyphBuilder(
+ WritableFontData* data)
+ : Glyph::Builder(data) {
+}
+
+GlyphTable::SimpleGlyph::SimpleGlyphBuilder::SimpleGlyphBuilder(
+ ReadableFontData* data)
+ : Glyph::Builder(data) {
+}
+
+CALLER_ATTACH FontDataTable*
+ GlyphTable::SimpleGlyph::SimpleGlyphBuilder::SubBuildTable(
+ ReadableFontData* data) {
+ FontDataTablePtr table = new SimpleGlyph(data);
+ return table.Detach();
+}
+
+/******************************************************************************
+ * GlyphTable::CompositeGlyph
+ ******************************************************************************/
+GlyphTable::CompositeGlyph::CompositeGlyph(ReadableFontData* data)
+ : GlyphTable::Glyph(data, GlyphType::kComposite),
+ instruction_size_(0),
+ instructions_offset_(0),
+ initialized_(false) {
+ Initialize();
+}
+
+GlyphTable::CompositeGlyph::~CompositeGlyph() {
+}
+
+int32_t GlyphTable::CompositeGlyph::Flags(int32_t contour) {
+ return data_->ReadUShort(contour_index_[contour]);
+}
+
+int32_t GlyphTable::CompositeGlyph::NumGlyphs() {
+ return contour_index_.size();
+}
+
+int32_t GlyphTable::CompositeGlyph::GlyphIndex(int32_t contour) {
+ 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_;
+}
+
+CALLER_ATTACH ReadableFontData* GlyphTable::CompositeGlyph::Instructions() {
+ return down_cast<ReadableFontData*>(
+ data_->Slice(instructions_offset_, InstructionSize()));
+}
+
+void GlyphTable::CompositeGlyph::Initialize() {
+ AutoLock lock(initialization_lock_);
+ if (initialized_) {
+ return;
+ }
+
+ int32_t index = 5 * DataSize::kUSHORT;
+ int32_t flags = kFLAG_MORE_COMPONENTS;
+
+ while ((flags & kFLAG_MORE_COMPONENTS) == kFLAG_MORE_COMPONENTS) {
+ contour_index_.push_back(index);
+ flags = data_->ReadUShort(index);
+ 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;
+ } else {
+ index += 2 * DataSize::kBYTE;
+ }
+ if ((flags & kFLAG_WE_HAVE_A_SCALE) == kFLAG_WE_HAVE_A_SCALE) {
+ index += DataSize::kF2DOT14;
+ } else if ((flags & kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) ==
+ kFLAG_WE_HAVE_AN_X_AND_Y_SCALE) {
+ index += 2 * DataSize::kF2DOT14;
+ } else if ((flags & kFLAG_WE_HAVE_A_TWO_BY_TWO) ==
+ kFLAG_WE_HAVE_A_TWO_BY_TWO) {
+ index += 4 * DataSize::kF2DOT14;
+ }
+ int32_t non_padded_data_length = index;
+ if ((flags & kFLAG_WE_HAVE_INSTRUCTIONS) == kFLAG_WE_HAVE_INSTRUCTIONS) {
+ instruction_size_ = data_->ReadUShort(index);
+ index += DataSize::kUSHORT;
+ instructions_offset_ = index;
+ non_padded_data_length = index + (instruction_size_ * DataSize::kBYTE);
+ }
+ set_padding(DataLength() - non_padded_data_length);
+ }
+
+ initialized_ = true;
+}
+
+/******************************************************************************
+ * GlyphTable::CompositeGlyph::Builder
+ ******************************************************************************/
+GlyphTable::CompositeGlyph::CompositeGlyphBuilder::~CompositeGlyphBuilder() {
+}
+
+GlyphTable::CompositeGlyph::CompositeGlyphBuilder::CompositeGlyphBuilder(
+ WritableFontData* data)
+ : Glyph::Builder(data) {
+}
+
+GlyphTable::CompositeGlyph::CompositeGlyphBuilder::CompositeGlyphBuilder(
+ ReadableFontData* data)
+ : Glyph::Builder(data) {
+}
+
+CALLER_ATTACH FontDataTable*
+ GlyphTable::CompositeGlyph::CompositeGlyphBuilder::SubBuildTable(
+ ReadableFontData* data) {
+ FontDataTablePtr table = new CompositeGlyph(data);
+ return table.Detach();
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/glyph_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/glyph_table.h
new file mode 100644
index 00000000000..4ffddda38ad
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/glyph_table.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_GLYPH_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_GLYPH_TABLE_H_
+
+#include <vector>
+
+#include "sfntly/table/table.h"
+#include "sfntly/table/subtable.h"
+#include "sfntly/table/subtable_container_table.h"
+
+namespace sfntly {
+
+struct GlyphType {
+ enum {
+ kSimple = 0,
+ kComposite = 1
+ };
+};
+
+class GlyphTable : public SubTableContainerTable,
+ public RefCounted<GlyphTable> {
+ public:
+ class Builder;
+ class Glyph : public SubTable {
+ public:
+ // Note: Contour is an empty class for the version ported
+ class Contour {
+ protected:
+ Contour() {}
+ virtual ~Contour() {}
+ };
+
+ class Builder : public SubTable::Builder {
+ public:
+ virtual ~Builder();
+
+ protected:
+ // Incoming table_builder is GlyphTable::Builder*.
+ // Note: constructor refactored in C++ to avoid heavy lifting.
+ // caller need to do data->Slice(offset, length) beforehand.
+ explicit Builder(WritableFontData* data);
+ explicit Builder(ReadableFontData* data);
+
+ static CALLER_ATTACH Builder*
+ GetBuilder(GlyphTable::Builder* table_builder,
+ ReadableFontData* data);
+ static CALLER_ATTACH Builder*
+ GetBuilder(GlyphTable::Builder* table_builder,
+ ReadableFontData* data,
+ int32_t offset,
+ int32_t length);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ private:
+ friend class GlyphTable::Builder;
+ };
+
+ virtual ~Glyph();
+ static CALLER_ATTACH Glyph* GetGlyph(GlyphTable* table,
+ ReadableFontData* data,
+ int32_t offset,
+ int32_t length);
+
+ virtual int32_t Padding();
+ virtual int32_t GlyphType();
+ virtual int32_t NumberOfContours();
+ virtual int32_t XMin();
+ virtual int32_t XMax();
+ virtual int32_t YMin();
+ virtual int32_t YMax();
+
+ virtual int32_t InstructionSize() = 0;
+ virtual ReadableFontData* Instructions() = 0;
+
+ protected:
+ // Note: constructor refactored in C++ to avoid heavy lifting.
+ // caller need to do data->Slice(offset, length) beforehand.
+ Glyph(ReadableFontData* data, int32_t glyph_type);
+ virtual void Initialize() = 0;
+ // Note: Derived class to define initialization_lock_.
+
+ private:
+ static int32_t GlyphType(ReadableFontData* data,
+ int32_t offset,
+ int32_t length);
+
+ int32_t glyph_type_;
+ int32_t number_of_contours_;
+ }; // class GlyphTable::Glyph
+ typedef Ptr<GlyphTable::Glyph::Builder> GlyphBuilderPtr;
+ typedef std::vector<GlyphBuilderPtr> GlyphBuilderList;
+
+ class Builder : public SubTableContainerTable::Builder,
+ public RefCounted<GlyphTable::Builder> {
+ public:
+ // Note: Constructor scope altered to public for base class to instantiate.
+ Builder(Header* header, ReadableFontData* data);
+ virtual ~Builder();
+
+ virtual void SetLoca(const IntegerList& loca);
+ virtual void GenerateLocaList(IntegerList* locas);
+
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ WritableFontData* data);
+
+ // Gets the List of glyph builders for the glyph table builder. These may be
+ // manipulated in any way by the caller and the changes will be reflected in
+ // the final glyph table produced.
+ // If there is no current data for the glyph builder or the glyph builders
+ // have not been previously set then this will return an empty glyph builder
+ // List. If there is current data (i.e. data read from an existing font) and
+ // the <code>loca</code> list has not been set or is null, empty, or
+ // invalid, then an empty glyph builder List will be returned.
+ GlyphBuilderList* GlyphBuilders();
+
+ // Replace the internal glyph builders with the one provided. The provided
+ // list and all contained objects belong to this builder.
+ // This call is only required if the entire set of glyphs in the glyph
+ // table builder are being replaced. If the glyph builder list provided from
+ // the GlyphTable.Builder::GlyphBuilders() is being used and modified
+ // then those changes will already be reflected in the glyph table builder.
+ void SetGlyphBuilders(GlyphBuilderList* glyph_builders);
+
+ // Glyph builder factories
+ CALLER_ATTACH Glyph::Builder* GlyphBuilder(ReadableFontData* data);
+
+ protected: // internal API for building
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ private:
+ void Initialize(ReadableFontData* data, const IntegerList& loca);
+ GlyphBuilderList* GetGlyphBuilders();
+ void Revert();
+
+ GlyphBuilderList glyph_builders_;
+ IntegerList loca_;
+ };
+
+ class SimpleGlyph : public Glyph, public RefCounted<SimpleGlyph> {
+ public:
+ static const int32_t kFLAG_ONCURVE;
+ static const int32_t kFLAG_XSHORT;
+ static const int32_t kFLAG_YSHORT;
+ static const int32_t kFLAG_REPEAT;
+ static const int32_t kFLAG_XREPEATSIGN;
+ static const int32_t kFLAG_YREPEATSIGN;
+
+ class SimpleContour : public Glyph::Contour {
+ protected:
+ SimpleContour() {}
+ virtual ~SimpleContour() {}
+ };
+
+ class SimpleGlyphBuilder : public Glyph::Builder,
+ public RefCounted<SimpleGlyphBuilder> {
+ public:
+ virtual ~SimpleGlyphBuilder();
+
+ protected:
+ // Note: constructor refactored in C++ to avoid heavy lifting.
+ // caller need to do data->Slice(offset, length) beforehand.
+ explicit SimpleGlyphBuilder(WritableFontData* data);
+ explicit SimpleGlyphBuilder(ReadableFontData* data);
+ virtual CALLER_ATTACH FontDataTable*
+ SubBuildTable(ReadableFontData* data);
+
+ private:
+ friend class Glyph::Builder;
+ };
+
+ // Note: constructor refactored in C++ to avoid heavy lifting.
+ // caller need to do data->Slice(offset, length) beforehand.
+ explicit SimpleGlyph(ReadableFontData* data);
+ virtual ~SimpleGlyph();
+
+ virtual int32_t InstructionSize();
+ 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);
+ int32_t ContourEndPoint(int32_t contour);
+
+ bool initialized_;
+ Lock initialization_lock_;
+ int32_t instruction_size_;
+ int32_t number_of_points_;
+
+ // start offsets of the arrays
+ int32_t instructions_offset_;
+ int32_t flags_offset_;
+ int32_t x_coordinates_offset_;
+ int32_t y_coordinates_offset_;
+
+ int32_t flag_byte_count_;
+ int32_t x_byte_count_;
+ int32_t y_byte_count_;
+
+ IntegerList x_coordinates_;
+ IntegerList y_coordinates_;
+ std::vector<bool> on_curve_;
+ IntegerList contour_index_;
+ };
+
+ class CompositeGlyph : public Glyph, public RefCounted<CompositeGlyph> {
+ public:
+ static const int32_t kFLAG_ARG_1_AND_2_ARE_WORDS;
+ static const int32_t kFLAG_ARGS_ARE_XY_VALUES;
+ static const int32_t kFLAG_ROUND_XY_TO_GRID;
+ static const int32_t kFLAG_WE_HAVE_A_SCALE;
+ static const int32_t kFLAG_RESERVED;
+ static const int32_t kFLAG_MORE_COMPONENTS;
+ static const int32_t kFLAG_WE_HAVE_AN_X_AND_Y_SCALE;
+ static const int32_t kFLAG_WE_HAVE_A_TWO_BY_TWO;
+ static const int32_t kFLAG_WE_HAVE_INSTRUCTIONS;
+ static const int32_t kFLAG_USE_MY_METRICS;
+ static const int32_t kFLAG_OVERLAP_COMPOUND;
+ static const int32_t kFLAG_SCALED_COMPONENT_OFFSET;
+ static const int32_t kFLAG_UNSCALED_COMPONENT_OFFSET;
+
+ class CompositeGlyphBuilder : public Glyph::Builder,
+ public RefCounted<CompositeGlyphBuilder> {
+ public:
+ virtual ~CompositeGlyphBuilder();
+
+ protected:
+ // Note: constructor refactored in C++ to avoid heavy lifting.
+ // caller need to do data->Slice(offset, length) beforehand.
+ explicit CompositeGlyphBuilder(WritableFontData* data);
+ explicit CompositeGlyphBuilder(ReadableFontData* data);
+
+ virtual CALLER_ATTACH FontDataTable*
+ SubBuildTable(ReadableFontData* data);
+
+ private:
+ friend class Glyph::Builder;
+ };
+
+ // Note: constructor refactored in C++ to avoid heavy lifting.
+ // caller need to do data->Slice(offset, length) beforehand.
+ explicit CompositeGlyph(ReadableFontData* data);
+ virtual ~CompositeGlyph();
+
+ 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();
+
+ protected:
+ virtual void Initialize();
+
+ private:
+ IntegerList contour_index_;
+ int32_t instruction_size_;
+ int32_t instructions_offset_;
+ bool initialized_;
+ Lock initialization_lock_;
+ };
+
+ virtual ~GlyphTable();
+
+ // C++ port: rename glyph() to GetGlyph().
+ Glyph* GetGlyph(int32_t offset, int32_t length);
+
+ private:
+ struct Offset {
+ enum {
+ // header
+ kNumberOfContours = 0,
+ kXMin = 2,
+ kYMin = 4,
+ kXMax = 6,
+ kYMax = 8,
+
+ // Simple Glyph Description
+ kSimpleEndPtsOfCountours = 10,
+ // offset from the end of the contours array
+ kSimpleInstructionLength = 0,
+ kSimpleInstructions = 2,
+ // flags
+ // xCoordinates
+ // yCoordinates
+
+ // Composite Glyph Description
+ kCompositeFlags = 0,
+ kCompositeGyphIndexWithoutFlag = 0,
+ kCompositeGlyphIndexWithFlag = 2,
+ };
+ };
+
+ GlyphTable(Header* header, ReadableFontData* data);
+};
+typedef Ptr<GlyphTable> GlyphTablePtr;
+typedef Ptr<GlyphTable::Builder> GlyphTableBuilderPtr;
+typedef std::vector<GlyphTableBuilderPtr> GlyphTableBuilderList;
+typedef Ptr<GlyphTable::Glyph> GlyphPtr;
+typedef Ptr<GlyphTable::Glyph::Builder> GlyphBuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_GLYPH_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/loca_table.cc b/chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/loca_table.cc
new file mode 100644
index 00000000000..c692155da8d
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/loca_table.cc
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/table/truetype/loca_table.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+/******************************************************************************
+ * LocaTable class
+ ******************************************************************************/
+LocaTable::~LocaTable() {}
+
+int32_t LocaTable::GlyphOffset(int32_t glyph_id) {
+ if (glyph_id < 0 || glyph_id >= num_glyphs_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundException("Glyph ID is out of bounds.");
+#endif
+ return 0;
+ }
+ return Loca(glyph_id);
+}
+
+int32_t LocaTable::GlyphLength(int32_t glyph_id) {
+ if (glyph_id < 0 || glyph_id >= num_glyphs_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundException("Glyph ID is out of bounds.");
+#endif
+ return 0;
+ }
+ return Loca(glyph_id + 1) - Loca(glyph_id);
+}
+
+int32_t LocaTable::NumLocas() {
+ return num_glyphs_ + 1;
+}
+
+int32_t LocaTable::Loca(int32_t index) {
+ if (index > num_glyphs_) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundException();
+#endif
+ return 0;
+ }
+ if (format_version_ == IndexToLocFormat::kShortOffset) {
+ return 2 * data_->ReadUShort(index * DataSize::kUSHORT);
+ }
+ return data_->ReadULongAsInt(index * DataSize::kULONG);
+}
+
+LocaTable::LocaTable(Header* header,
+ ReadableFontData* data,
+ int32_t format_version,
+ int32_t num_glyphs)
+ : Table(header, data),
+ format_version_(format_version),
+ num_glyphs_(num_glyphs) {
+}
+
+/******************************************************************************
+ * LocaTable::Iterator class
+ ******************************************************************************/
+LocaTable::LocaIterator::LocaIterator(LocaTable* table)
+ : PODIterator<int32_t, LocaTable>(table), index_(-1) {
+}
+
+bool LocaTable::LocaIterator::HasNext() {
+ return index_ <= container()->num_glyphs_;
+}
+
+int32_t LocaTable::LocaIterator::Next() {
+ return container()->Loca(index_++);
+}
+
+/******************************************************************************
+ * LocaTable::Builder class
+ ******************************************************************************/
+LocaTable::Builder::Builder(Header* header, WritableFontData* data)
+ : Table::Builder(header, data),
+ format_version_(IndexToLocFormat::kLongOffset),
+ num_glyphs_(-1) {
+}
+
+LocaTable::Builder::Builder(Header* header, ReadableFontData* data)
+ : Table::Builder(header, data),
+ format_version_(IndexToLocFormat::kLongOffset),
+ num_glyphs_(-1) {
+}
+
+LocaTable::Builder::~Builder() {}
+
+CALLER_ATTACH
+LocaTable::Builder* LocaTable::Builder::CreateBuilder(Header* header,
+ WritableFontData* data) {
+ Ptr<LocaTable::Builder> builder;
+ builder = new LocaTable::Builder(header, data);
+ return builder.Detach();
+}
+
+IntegerList* LocaTable::Builder::LocaList() {
+ return GetLocaList();
+}
+
+void LocaTable::Builder::SetLocaList(IntegerList* list) {
+ loca_.clear();
+ if (list) {
+ loca_ = *list;
+ set_model_changed();
+ }
+}
+
+int32_t LocaTable::Builder::GlyphOffset(int32_t glyph_id) {
+ if (CheckGlyphRange(glyph_id) == -1) {
+ return 0;
+ }
+ return GetLocaList()->at(glyph_id);
+}
+
+int32_t LocaTable::Builder::GlyphLength(int32_t glyph_id) {
+ if (CheckGlyphRange(glyph_id) == -1) {
+ return 0;
+ }
+ return GetLocaList()->at(glyph_id + 1) - GetLocaList()->at(glyph_id);
+}
+
+void LocaTable::Builder::SetNumGlyphs(int32_t num_glyphs) {
+ num_glyphs_ = num_glyphs;
+}
+
+int32_t LocaTable::Builder::NumGlyphs() {
+ return LastGlyphIndex() - 1;
+}
+
+void LocaTable::Builder::Revert() {
+ loca_.clear();
+ set_model_changed(false);
+}
+
+int32_t LocaTable::Builder::NumLocas() {
+ return GetLocaList()->size();
+}
+
+int32_t LocaTable::Builder::Loca(int32_t index) {
+ return GetLocaList()->at(index);
+}
+
+CALLER_ATTACH
+FontDataTable* LocaTable::Builder::SubBuildTable(ReadableFontData* data) {
+ FontDataTablePtr table =
+ new LocaTable(header(), data, format_version_, num_glyphs_);
+ return table.Detach();
+}
+
+void LocaTable::Builder::SubDataSet() {
+ Initialize(InternalReadData());
+}
+
+int32_t LocaTable::Builder::SubDataSizeToSerialize() {
+ if (loca_.empty()) {
+ return 0;
+ }
+ if (format_version_ == IndexToLocFormat::kLongOffset) {
+ return loca_.size() * DataSize::kULONG;
+ }
+ return loca_.size() * DataSize::kUSHORT;
+}
+
+bool LocaTable::Builder::SubReadyToSerialize() {
+ return !loca_.empty();
+}
+
+int32_t LocaTable::Builder::SubSerialize(WritableFontData* new_data) {
+ int32_t size = 0;
+ for (IntegerList::iterator l = loca_.begin(), end = loca_.end();
+ l != end; ++l) {
+ if (format_version_ == IndexToLocFormat::kLongOffset) {
+ size += new_data->WriteULong(size, *l);
+ } else {
+ size += new_data->WriteUShort(size, *l / 2);
+ }
+ }
+ num_glyphs_ = loca_.size() - 1;
+ return size;
+}
+
+void LocaTable::Builder::Initialize(ReadableFontData* data) {
+ ClearLoca(false);
+ if (data) {
+ if (NumGlyphs() < 0) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IllegalStateException("numglyphs not set on LocaTable Builder.");
+#endif
+ return;
+ }
+ LocaTablePtr table =
+ new LocaTable(header(), data, format_version_, num_glyphs_);
+ Ptr<LocaTable::LocaIterator> loca_iter =
+ new LocaTable::LocaIterator(table);
+ while (loca_iter->HasNext()) {
+ loca_.push_back(loca_iter->Next());
+ }
+ }
+}
+
+int32_t LocaTable::Builder::CheckGlyphRange(int32_t glyph_id) {
+ if (glyph_id < 0 || glyph_id > LastGlyphIndex()) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw IndexOutOfBoundsException("Glyph ID is outside of the allowed range");
+#endif
+ return -1;
+ }
+ return glyph_id;
+}
+
+int32_t LocaTable::Builder::LastGlyphIndex() {
+ return !loca_.empty() ? loca_.size() - 2 : num_glyphs_ - 1;
+}
+
+IntegerList* LocaTable::Builder::GetLocaList() {
+ if (loca_.empty()) {
+ Initialize(InternalReadData());
+ set_model_changed();
+ }
+ return &loca_;
+}
+
+void LocaTable::Builder::ClearLoca(bool nullify) {
+ // Note: in C++ port, nullify is not used at all.
+ UNREFERENCED_PARAMETER(nullify);
+ loca_.clear();
+ set_model_changed(false);
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/loca_table.h b/chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/loca_table.h
new file mode 100644
index 00000000000..67c5749b05d
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/table/truetype/loca_table.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_LOCA_TABLE_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_LOCA_TABLE_H_
+
+#include "sfntly/port/java_iterator.h"
+#include "sfntly/table/table.h"
+#include "sfntly/table/core/font_header_table.h"
+
+namespace sfntly {
+
+// A Loca table - 'loca'.
+class LocaTable : public Table, public RefCounted<LocaTable> {
+ public:
+ class LocaIterator : public PODIterator<int32_t, LocaTable> {
+ public:
+ explicit LocaIterator(LocaTable* table);
+ virtual ~LocaIterator() {}
+
+ virtual bool HasNext();
+ virtual int32_t Next();
+
+ private:
+ int32_t index_;
+ };
+
+ class Builder : public Table::Builder, public RefCounted<Builder> {
+ public:
+ // Constructor scope altered to public for base class to instantiate.
+ Builder(Header* header, WritableFontData* data);
+ Builder(Header* header, ReadableFontData* data);
+ virtual ~Builder();
+
+ static CALLER_ATTACH Builder* CreateBuilder(Header* header,
+ WritableFontData* data);
+
+ // Get the format version that will be used when the loca table is
+ // generated.
+ // @return the loca table format version
+ int32_t format_version() { return format_version_; }
+ void set_format_version(int32_t value) { format_version_ = value; }
+
+ // Gets the List of locas for loca table builder. These may be manipulated
+ // in any way by the caller and the changes will be reflected in the final
+ // loca table produced as long as no subsequent call is made to the
+ // 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();
+
+ // 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);
+
+ // 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
+ // for the notdef glyph. The final entry beyond the last glyph id is used to
+ // calculate the size of the last glyph.
+ // @param glyphId the glyph id to get the offset for; must be less than or
+ // equal to one more than the number of glyph ids
+ // @return the offset in the glyph table to the specified glyph id
+ int32_t GlyphOffset(int32_t glyph_id);
+
+ // Get the length of the data in the glyph table for the specified glyph id.
+ int32_t GlyphLength(int32_t glyph_id);
+
+ // Set the number of glyphs.
+ // This method sets the number of glyphs that the builder will attempt to
+ // parse location data for from the raw binary data. This method only needs
+ // to be called (and <b>must</b> be) when the raw data for this builder has
+ // been changed. It does not by itself reset the data or clear any set loca
+ // list.
+ void SetNumGlyphs(int32_t num_glyphs);
+
+ // Get the number of glyphs that this builder has support for.
+ int NumGlyphs();
+
+ // Revert the loca table builder to the state contained in the last raw data
+ // set on the builder. That raw data may be that read from a font file when
+ // the font builder was created, that set by a user of the loca table
+ // builder, or null data if this builder was created as a new empty builder.
+ void Revert();
+
+ // Get the number of locations or locas. This will be one more than the
+ // number of glyphs for this table since the last loca position is used to
+ // indicate the size of the final glyph.
+ int32_t NumLocas();
+
+ // Get the value from the loca table for the index specified. These are the
+ // raw values from the table that are used to compute the offset and size of
+ // a glyph in the glyph table. Valid index values run from 0 to the number
+ // of glyphs in the font.
+ int32_t Loca(int32_t index);
+
+ virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
+ virtual void SubDataSet();
+ virtual int32_t SubDataSizeToSerialize();
+ virtual bool SubReadyToSerialize();
+ virtual int32_t SubSerialize(WritableFontData* new_data);
+
+ private:
+ // Initialize the internal state from the data. Done lazily since in many
+ // cases the builder will be just creating a table object with no parsing
+ // required.
+ // @param data the data to initialize from
+ void Initialize(ReadableFontData* data);
+
+ // Checks that the glyph id is within the correct range.
+ // @return glyph_id if correct, -1 otherwise.
+ int32_t CheckGlyphRange(int32_t glyph_id);
+
+ int32_t LastGlyphIndex();
+
+ // 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();
+
+ void ClearLoca(bool nullify);
+
+ int32_t format_version_; // Note: IndexToLocFormat
+ int32_t num_glyphs_;
+ IntegerList loca_;
+ };
+
+ virtual ~LocaTable();
+
+ int32_t format_version() { return format_version_; }
+ int32_t num_glyphs() { return num_glyphs_; }
+
+ // Return the offset for the given glyph id. Valid glyph ids are from 0 to the
+ // one less than the number of glyphs. The zero entry is the special entry for
+ // the notdef glyph. The final entry beyond the last glyph id is used to
+ // calculate the size of the last glyph.
+ // @param glyphId the glyph id to get the offset for; must be less than or
+ // equal to one more than the number of glyph ids
+ // @return the offset in the glyph table to the specified glyph id
+ int32_t GlyphOffset(int32_t glyph_id);
+
+ // Get the length of the data in the glyph table for the specified glyph id.
+ int32_t GlyphLength(int32_t glyph_id);
+
+ // Get the number of locations or locas. This will be one more than the number
+ // of glyphs for this table since the last loca position is used to indicate
+ // the size of the final glyph.
+ int32_t NumLocas();
+
+ // Get the value from the loca table for the index specified. Valid index
+ // values run from 0 to the number of glyphs in the font.
+ int32_t Loca(int32_t index);
+
+ private:
+ LocaTable(Header* header,
+ ReadableFontData* data,
+ int32_t format_version,
+ int32_t num_glyphs);
+
+ int32_t format_version_; // Note: Java's version, renamed to format_version_
+ int32_t num_glyphs_;
+
+ friend class LocaIterator;
+};
+typedef Ptr<LocaTable> LocaTablePtr;
+typedef Ptr<LocaTable::Builder> LocaTableBuilderPtr;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_TRUETYPE_LOCA_TABLE_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/tag.cc b/chromium/third_party/sfntly/cpp/src/sfntly/tag.cc
new file mode 100644
index 00000000000..c9d8c29878f
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/tag.cc
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/tag.h"
+#include "sfntly/port/endian.h"
+
+// Use a macro instead of GenerateTag() because gcc 4.4.3 creates static
+// initializers in that case.
+#define TAG(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | d);
+
+namespace sfntly {
+
+const int32_t Tag::ttcf = TAG('t', 't', 'c', 'f');
+const int32_t Tag::cmap = TAG('c', 'm', 'a', 'p');
+const int32_t Tag::head = TAG('h', 'e', 'a', 'd');
+const int32_t Tag::hhea = TAG('h', 'h', 'e', 'a');
+const int32_t Tag::hmtx = TAG('h', 'm', 't', 'x');
+const int32_t Tag::maxp = TAG('m', 'a', 'x', 'p');
+const int32_t Tag::name = TAG('n', 'a', 'm', 'e');
+const int32_t Tag::OS_2 = TAG('O', 'S', '/', '2');
+const int32_t Tag::post = TAG('p', 'o', 's', 't');
+const int32_t Tag::cvt = TAG('c', 'v', 't', ' ');
+const int32_t Tag::fpgm = TAG('f', 'p', 'g', 'm');
+const int32_t Tag::glyf = TAG('g', 'l', 'y', 'f');
+const int32_t Tag::loca = TAG('l', 'o', 'c', 'a');
+const int32_t Tag::prep = TAG('p', 'r', 'e', 'p');
+const int32_t Tag::CFF = TAG('C', 'F', 'F', ' ');
+const int32_t Tag::VORG = TAG('V', 'O', 'R', 'G');
+const int32_t Tag::EBDT = TAG('E', 'B', 'D', 'T');
+const int32_t Tag::EBLC = TAG('E', 'B', 'L', 'C');
+const int32_t Tag::EBSC = TAG('E', 'B', 'S', 'C');
+const int32_t Tag::BASE = TAG('B', 'A', 'S', 'E');
+const int32_t Tag::GDEF = TAG('G', 'D', 'E', 'F');
+const int32_t Tag::GPOS = TAG('G', 'P', 'O', 'S');
+const int32_t Tag::GSUB = TAG('G', 'S', 'U', 'B');
+const int32_t Tag::JSTF = TAG('J', 'S', 'T', 'F');
+const int32_t Tag::DSIG = TAG('D', 'S', 'I', 'G');
+const int32_t Tag::gasp = TAG('g', 'a', 's', 'p');
+const int32_t Tag::hdmx = TAG('h', 'd', 'm', 'x');
+const int32_t Tag::kern = TAG('k', 'e', 'r', 'n');
+const int32_t Tag::LTSH = TAG('L', 'T', 'S', 'H');
+const int32_t Tag::PCLT = TAG('P', 'C', 'L', 'T');
+const int32_t Tag::VDMX = TAG('V', 'D', 'M', 'X');
+const int32_t Tag::vhea = TAG('v', 'h', 'e', 'a');
+const int32_t Tag::vmtx = TAG('v', 'm', 't', 'x');
+const int32_t Tag::bsln = TAG('b', 's', 'l', 'n');
+const int32_t Tag::feat = TAG('f', 'e', 'a', 't');
+const int32_t Tag::lcar = TAG('l', 'c', 'a', 'r');
+const int32_t Tag::morx = TAG('m', 'o', 'r', 'x');
+const int32_t Tag::opbd = TAG('o', 'p', 'b', 'd');
+const int32_t Tag::prop = TAG('p', 'r', 'o', 'p');
+const int32_t Tag::Feat = TAG('F', 'e', 'a', 't');
+const int32_t Tag::Glat = TAG('G', 'l', 'a', 't');
+const int32_t Tag::Gloc = TAG('G', 'l', 'o', 'c');
+const int32_t Tag::Sile = TAG('S', 'i', 'l', 'e');
+const int32_t Tag::Silf = TAG('S', 'i', 'l', 'f');
+const int32_t Tag::bhed = TAG('b', 'h', 'e', 'd');
+const int32_t Tag::bdat = TAG('b', 'd', 'a', 't');
+const int32_t Tag::bloc = TAG('b', 'l', 'o', 'c');
+
+const int32_t CFF_TABLE_ORDERING[] = {
+ Tag::head,
+ Tag::hhea,
+ Tag::maxp,
+ Tag::OS_2,
+ Tag::name,
+ Tag::cmap,
+ Tag::post,
+ Tag::CFF };
+const size_t CFF_TABLE_ORDERING_SIZE =
+ sizeof(CFF_TABLE_ORDERING) / sizeof(int32_t);
+
+const int32_t TRUE_TYPE_TABLE_ORDERING[] = {
+ Tag::head,
+ Tag::hhea,
+ Tag::maxp,
+ Tag::OS_2,
+ Tag::hmtx,
+ Tag::LTSH,
+ Tag::VDMX,
+ Tag::hdmx,
+ Tag::cmap,
+ Tag::fpgm,
+ Tag::prep,
+ Tag::cvt,
+ Tag::loca,
+ Tag::glyf,
+ Tag::kern,
+ Tag::name,
+ Tag::post,
+ Tag::gasp,
+ Tag::PCLT,
+ Tag::DSIG };
+const size_t TRUE_TYPE_TABLE_ORDERING_SIZE =
+ sizeof(TRUE_TYPE_TABLE_ORDERING) / sizeof(int32_t);
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/tag.h b/chromium/third_party/sfntly/cpp/src/sfntly/tag.h
new file mode 100644
index 00000000000..0ecbab85b4b
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/tag.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TAG_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TAG_H_
+
+#include <cstddef>
+
+#include "sfntly/port/type.h"
+
+namespace sfntly {
+
+// Font identification tags used for tables, features, etc.
+// Tag names are consistent with the OpenType and sfnt specs.
+struct Tag {
+ static const int32_t ttcf;
+
+ // Table Type Tags
+ // required tables
+ static const int32_t cmap;
+ static const int32_t head;
+ static const int32_t hhea;
+ static const int32_t hmtx;
+ static const int32_t maxp;
+ static const int32_t name;
+ static const int32_t OS_2;
+ static const int32_t post;
+
+ // TrueType outline tables
+ static const int32_t cvt;
+ static const int32_t fpgm;
+ static const int32_t glyf;
+ static const int32_t loca;
+ static const int32_t prep;
+
+ // PostScript outline tables
+ static const int32_t CFF;
+ static const int32_t VORG;
+
+ // opentype bitmap glyph outlines
+ static const int32_t EBDT;
+ static const int32_t EBLC;
+ static const int32_t EBSC;
+
+ // advanced typographic features
+ static const int32_t BASE;
+ static const int32_t GDEF;
+ static const int32_t GPOS;
+ static const int32_t GSUB;
+ static const int32_t JSTF;
+
+ // other
+ static const int32_t DSIG;
+ static const int32_t gasp;
+ static const int32_t hdmx;
+ static const int32_t kern;
+ static const int32_t LTSH;
+ static const int32_t PCLT;
+ static const int32_t VDMX;
+ static const int32_t vhea;
+ static const int32_t vmtx;
+
+ // AAT tables
+ static const int32_t bsln;
+ static const int32_t feat;
+ static const int32_t lcar;
+ static const int32_t morx;
+ static const int32_t opbd;
+ static const int32_t prop;
+
+ // Graphite tables
+ static const int32_t Feat;
+ static const int32_t Glat;
+ static const int32_t Gloc;
+ static const int32_t Sile;
+ static const int32_t Silf;
+
+ // truetype bitmap font tables
+ static const int32_t bhed;
+ static const int32_t bdat;
+ static const int32_t bloc;
+};
+
+// Create integer tag value for human readable tag name.
+inline int32_t GenerateTag(int32_t a, int32_t b, int32_t c, int32_t d) {
+ return (a << 24) | (b << 16) | (c << 8) | d;
+}
+
+// Translate tag to human readable string.
+// The Caller must delete[] the returned value.
+inline char* TagToString(int32_t tag) {
+ char *name = new char[5];
+ name[0] = static_cast<char>((tag & 0xff000000) >> 24);
+ name[1] = static_cast<char>((tag & 0x00ff0000) >> 16);
+ name[2] = static_cast<char>((tag & 0x0000ff00) >> 8);
+ name[3] = static_cast<char>(tag & 0x000000ff);
+ name[4] = 0;
+ return name;
+}
+
+// Note: For Java, these two orderings are in Font class. Moved here to avoid
+// VC++ bug of not populating correct values.
+extern const int32_t CFF_TABLE_ORDERING[];
+extern const size_t CFF_TABLE_ORDERING_SIZE;
+extern const int32_t TRUE_TYPE_TABLE_ORDERING[];
+extern const size_t TRUE_TYPE_TABLE_ORDERING_SIZE;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TAG_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.cc b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.cc
new file mode 100644
index 00000000000..b3d6b07e447
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.cc
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/tools/subsetter/glyph_table_subsetter.h"
+
+#include "sfntly/table/truetype/glyph_table.h"
+#include "sfntly/table/truetype/loca_table.h"
+#include "sfntly/tag.h"
+#include "sfntly/tools/subsetter/subsetter.h"
+#include "sfntly/port/exception_type.h"
+
+namespace sfntly {
+
+const int32_t kGlyphTableSubsetterTags[2] = {Tag::glyf, Tag::loca};
+
+GlyphTableSubsetter::GlyphTableSubsetter()
+ : TableSubsetterImpl(kGlyphTableSubsetterTags, 2) {
+}
+
+GlyphTableSubsetter::~GlyphTableSubsetter() {}
+
+bool GlyphTableSubsetter::Subset(Subsetter* subsetter,
+ Font* font,
+ Font::Builder* font_builder) {
+ assert(font);
+ assert(subsetter);
+ assert(font_builder);
+
+ IntegerList* permutation_table = subsetter->GlyphPermutationTable();
+ if (!permutation_table || permutation_table->empty())
+ return false;
+
+ GlyphTablePtr glyph_table = down_cast<GlyphTable*>(font->GetTable(Tag::glyf));
+ LocaTablePtr loca_table = down_cast<LocaTable*>(font->GetTable(Tag::loca));
+ if (glyph_table == NULL || loca_table == NULL) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw RuntimeException("Font to subset is not valid.");
+#endif
+ return false;
+ }
+
+ GlyphTableBuilderPtr glyph_table_builder =
+ down_cast<GlyphTable::Builder*>
+ (font_builder->NewTableBuilder(Tag::glyf));
+ LocaTableBuilderPtr loca_table_builder =
+ down_cast<LocaTable::Builder*>
+ (font_builder->NewTableBuilder(Tag::loca));
+ if (glyph_table_builder == NULL || loca_table_builder == NULL) {
+#if !defined (SFNTLY_NO_EXCEPTION)
+ throw RuntimeException("Builder for subset is not valid.");
+#endif
+ return false;
+ }
+ GlyphTable::GlyphBuilderList* glyph_builders =
+ glyph_table_builder->GlyphBuilders();
+ for (IntegerList::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);
+ int old_length = loca_table->GlyphLength(*old_glyph_id);
+ GlyphPtr glyph;
+ glyph.Attach(glyph_table->GetGlyph(old_offset, old_length));
+ ReadableFontDataPtr data = glyph->ReadFontData();
+ WritableFontDataPtr copy_data;
+ copy_data.Attach(WritableFontData::CreateWritableFontData(data->Length()));
+ data->CopyTo(copy_data);
+ GlyphBuilderPtr glyph_builder;
+ glyph_builder.Attach(glyph_table_builder->GlyphBuilder(copy_data));
+ glyph_builders->push_back(glyph_builder);
+ }
+ IntegerList loca_list;
+ glyph_table_builder->GenerateLocaList(&loca_list);
+ loca_table_builder->SetLocaList(&loca_list);
+ return true;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.h b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.h
new file mode 100644
index 00000000000..88c704443f6
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/glyph_table_subsetter.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_GLYPH_TABLE_SUBSETTER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_GLYPH_TABLE_SUBSETTER_H_
+
+#include "sfntly/tools/subsetter/table_subsetter_impl.h"
+
+namespace sfntly {
+
+class GlyphTableSubsetter : public TableSubsetterImpl,
+ public RefCounted<GlyphTableSubsetter> {
+ public:
+ GlyphTableSubsetter();
+ virtual ~GlyphTableSubsetter();
+
+ virtual bool Subset(Subsetter* subsetter,
+ Font* font,
+ Font::Builder* font_builder);
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_GLYPH_TABLE_SUBSETTER_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/subsetter.cc b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/subsetter.cc
new file mode 100644
index 00000000000..7d987796b99
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/subsetter.cc
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/tools/subsetter/subsetter.h"
+
+#include <algorithm>
+#include <iterator>
+
+#include "sfntly/tools/subsetter/glyph_table_subsetter.h"
+
+namespace sfntly {
+
+Subsetter::Subsetter(Font* font, FontFactory* font_factory) {
+ font_ = font;
+ font_factory_ = font_factory;
+ TableSubsetterPtr subsetter = new GlyphTableSubsetter();
+ // TODO(arthurhsu): IMPLEMENT: CMap table subsetter
+ table_subsetters_.push_back(subsetter);
+}
+
+Subsetter::~Subsetter() {
+ font_factory_.Release();
+ font_.Release();
+ table_subsetters_.clear();
+}
+
+void Subsetter::SetGlyphs(IntegerList* glyphs) {
+ new_to_old_glyphs_ = *glyphs;
+}
+
+void Subsetter::SetCMaps(CMapIdList* cmap_ids, int32_t number) {
+ UNREFERENCED_PARAMETER(cmap_ids);
+ UNREFERENCED_PARAMETER(number);
+ // TODO(arthurhsu): IMPLEMENT
+}
+
+void Subsetter::SetRemoveTables(IntegerSet* remove_tables) {
+ remove_tables_ = *remove_tables;
+}
+
+CALLER_ATTACH Font::Builder* Subsetter::Subset() {
+ FontBuilderPtr font_builder;
+ font_builder.Attach(font_factory_->NewFontBuilder());
+
+ IntegerSet 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_difference(table_tags.begin(), table_tags.end(),
+ remove_tables_.begin(), remove_tables_.end(),
+ std::inserter(result, result.end()));
+ table_tags = result;
+ }
+ for (TableSubsetterList::iterator
+ table_subsetter = table_subsetters_.begin(),
+ table_subsetter_end = table_subsetters_.end();
+ 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_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(),
+ tag_end = table_tags.end(); tag != tag_end; ++tag) {
+ Table* table = font_->GetTable(*tag);
+ if (table) {
+ font_builder->NewTableBuilder(*tag, table->ReadFontData());
+ }
+ }
+ return font_builder.Detach();
+}
+
+IntegerList* Subsetter::GlyphPermutationTable() {
+ return &new_to_old_glyphs_;
+}
+
+CMapIdList* Subsetter::CMapId() {
+ return &cmap_ids_;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/subsetter.h b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/subsetter.h
new file mode 100644
index 00000000000..85940a79288
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/subsetter.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_SUBSETTER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_SUBSETTER_H_
+
+#include <vector>
+
+#include "sfntly/font.h"
+#include "sfntly/font_factory.h"
+#include "sfntly/table/core/cmap_table.h"
+#include "sfntly/tools/subsetter/table_subsetter.h"
+
+namespace sfntly {
+
+class Subsetter : public RefCounted<Subsetter> {
+ public:
+ Subsetter(Font* font, FontFactory* font_factory);
+ virtual ~Subsetter();
+
+ virtual void SetGlyphs(IntegerList* 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
+ // list should be put into the subsetted font. If there are no matches in the
+ // font for any of the provided cmap ids which would lead to a font with no
+ // cmap then an error will be thrown during subsetting.
+ // The two most common cases would be: <list>
+ // * a list of one or more cmap ids with a count setting of 1
+ // This will use the list of cmap ids as an ordered priority and look for
+ // an available cmap in the font that matches the requests. Only the first
+ // such match will be placed in the subsetted font.
+ // * a list of one or more cmap ids with a count setting equal to the list
+ // length
+ // This will use the list of cmap ids and try to place each one specified
+ // into the subsetted font.
+ // @param cmapIds the cmap ids to use for the subsetted font
+ // @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 CALLER_ATTACH Font::Builder* Subset();
+ virtual IntegerList* GlyphPermutationTable();
+ virtual CMapIdList* CMapId();
+
+ private:
+ FontPtr font_;
+ FontFactoryPtr font_factory_;
+ TableSubsetterList table_subsetters_;
+
+ // Settings from user
+ IntegerSet remove_tables_;
+ IntegerList new_to_old_glyphs_;
+ CMapIdList cmap_ids_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_SUBSETTER_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/table_subsetter.h b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/table_subsetter.h
new file mode 100644
index 00000000000..1336615b07e
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/table_subsetter.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_TABLE_SUBSETTER_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_TABLE_SUBSETTER_H_
+
+#include <vector>
+
+#include "sfntly/font.h"
+
+namespace sfntly {
+
+class Subsetter;
+class TableSubsetter : virtual public RefCount {
+ public:
+ virtual IntegerSet* TagsHandled() = 0;
+ virtual bool TagHandled(int32_t tag) = 0;
+ virtual bool Subset(Subsetter* subsetter, Font* font,
+ Font::Builder* font_builder) = 0;
+};
+typedef Ptr<TableSubsetter> TableSubsetterPtr;
+typedef std::vector<TableSubsetterPtr> TableSubsetterList;
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_TABLE_SUBSETTER_H_
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.cc b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.cc
new file mode 100644
index 00000000000..f239c78e3c2
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.cc
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sfntly/tools/subsetter/table_subsetter_impl.h"
+
+namespace sfntly {
+
+TableSubsetterImpl::TableSubsetterImpl(const int32_t* tags,
+ size_t tags_length) {
+ for (size_t i = 0; i < tags_length; ++i) {
+ tags_.insert(tags[i]);
+ }
+}
+
+TableSubsetterImpl::~TableSubsetterImpl() {}
+
+bool TableSubsetterImpl::TagHandled(int32_t tag) {
+ return tags_.find(tag) != tags_.end();
+}
+
+IntegerSet* TableSubsetterImpl::TagsHandled() {
+ return &tags_;
+}
+
+} // namespace sfntly
diff --git a/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.h b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.h
new file mode 100644
index 00000000000..de0d9a98ca4
--- /dev/null
+++ b/chromium/third_party/sfntly/cpp/src/sfntly/tools/subsetter/table_subsetter_impl.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2011 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_TABLE_SUBSETTER_IMPL_H_
+#define SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_TABLE_SUBSETTER_IMPL_H_
+
+#include "sfntly/tools/subsetter/table_subsetter.h"
+
+namespace sfntly {
+
+class TableSubsetterImpl : public TableSubsetter {
+ public:
+ TableSubsetterImpl(const int32_t* tags, size_t tags_length);
+ virtual ~TableSubsetterImpl();
+ virtual bool TagHandled(int32_t tag);
+ virtual IntegerSet* TagsHandled();
+
+ protected:
+ IntegerSet tags_;
+};
+
+} // namespace sfntly
+
+#endif // SFNTLY_CPP_SRC_SFNTLY_TOOLS_SUBSETTER_TABLE_SUBSETTER_IMPL_H_
diff --git a/chromium/third_party/sfntly/sfntly.gyp b/chromium/third_party/sfntly/sfntly.gyp
new file mode 100644
index 00000000000..f76b8208361
--- /dev/null
+++ b/chromium/third_party/sfntly/sfntly.gyp
@@ -0,0 +1,142 @@
+# Copyright (c) 2011 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'variables': {
+ 'chromium_code': 1,
+ },
+ 'targets': [
+ {
+ 'target_name': 'sfntly',
+ 'type': 'static_library',
+ 'sources': [
+ 'cpp/src/sfntly/data/byte_array.cc',
+ 'cpp/src/sfntly/data/byte_array.h',
+ 'cpp/src/sfntly/data/font_data.cc',
+ 'cpp/src/sfntly/data/font_data.h',
+ 'cpp/src/sfntly/data/font_input_stream.cc',
+ 'cpp/src/sfntly/data/font_input_stream.h',
+ 'cpp/src/sfntly/data/font_output_stream.cc',
+ 'cpp/src/sfntly/data/font_output_stream.h',
+ 'cpp/src/sfntly/data/growable_memory_byte_array.cc',
+ 'cpp/src/sfntly/data/growable_memory_byte_array.h',
+ 'cpp/src/sfntly/data/memory_byte_array.cc',
+ 'cpp/src/sfntly/data/memory_byte_array.h',
+ 'cpp/src/sfntly/data/readable_font_data.cc',
+ 'cpp/src/sfntly/data/readable_font_data.h',
+ 'cpp/src/sfntly/data/writable_font_data.cc',
+ 'cpp/src/sfntly/data/writable_font_data.h',
+ 'cpp/src/sfntly/font.cc',
+ 'cpp/src/sfntly/font.h',
+ 'cpp/src/sfntly/font_factory.cc',
+ 'cpp/src/sfntly/font_factory.h',
+ 'cpp/src/sfntly/math/fixed1616.h',
+ 'cpp/src/sfntly/math/font_math.h',
+ 'cpp/src/sfntly/port/atomic.h',
+ 'cpp/src/sfntly/port/config.h',
+ 'cpp/src/sfntly/port/endian.h',
+ 'cpp/src/sfntly/port/exception_type.h',
+ 'cpp/src/sfntly/port/file_input_stream.cc',
+ 'cpp/src/sfntly/port/file_input_stream.h',
+ 'cpp/src/sfntly/port/input_stream.h',
+ 'cpp/src/sfntly/port/lock.cc',
+ 'cpp/src/sfntly/port/lock.h',
+ 'cpp/src/sfntly/port/memory_input_stream.cc',
+ 'cpp/src/sfntly/port/memory_input_stream.h',
+ 'cpp/src/sfntly/port/memory_output_stream.cc',
+ 'cpp/src/sfntly/port/memory_output_stream.h',
+ 'cpp/src/sfntly/port/output_stream.h',
+ 'cpp/src/sfntly/port/refcount.h',
+ 'cpp/src/sfntly/port/type.h',
+ 'cpp/src/sfntly/table/bitmap/big_glyph_metrics.cc',
+ 'cpp/src/sfntly/table/bitmap/big_glyph_metrics.h',
+ 'cpp/src/sfntly/table/bitmap/bitmap_glyph.cc',
+ 'cpp/src/sfntly/table/bitmap/bitmap_glyph.h',
+ 'cpp/src/sfntly/table/bitmap/bitmap_glyph_info.cc',
+ 'cpp/src/sfntly/table/bitmap/bitmap_glyph_info.h',
+ 'cpp/src/sfntly/table/bitmap/bitmap_size_table.cc',
+ 'cpp/src/sfntly/table/bitmap/bitmap_size_table.h',
+ 'cpp/src/sfntly/table/bitmap/composite_bitmap_glyph.cc',
+ 'cpp/src/sfntly/table/bitmap/composite_bitmap_glyph.h',
+ 'cpp/src/sfntly/table/bitmap/ebdt_table.cc',
+ 'cpp/src/sfntly/table/bitmap/ebdt_table.h',
+ 'cpp/src/sfntly/table/bitmap/eblc_table.cc',
+ 'cpp/src/sfntly/table/bitmap/eblc_table.h',
+ 'cpp/src/sfntly/table/bitmap/ebsc_table.cc',
+ 'cpp/src/sfntly/table/bitmap/ebsc_table.h',
+ 'cpp/src/sfntly/table/bitmap/glyph_metrics.cc',
+ 'cpp/src/sfntly/table/bitmap/glyph_metrics.h',
+ 'cpp/src/sfntly/table/bitmap/index_sub_table.cc',
+ 'cpp/src/sfntly/table/bitmap/index_sub_table.h',
+ 'cpp/src/sfntly/table/bitmap/index_sub_table_format1.cc',
+ 'cpp/src/sfntly/table/bitmap/index_sub_table_format1.h',
+ 'cpp/src/sfntly/table/bitmap/index_sub_table_format2.cc',
+ 'cpp/src/sfntly/table/bitmap/index_sub_table_format2.h',
+ 'cpp/src/sfntly/table/bitmap/index_sub_table_format3.cc',
+ 'cpp/src/sfntly/table/bitmap/index_sub_table_format3.h',
+ 'cpp/src/sfntly/table/bitmap/index_sub_table_format4.cc',
+ 'cpp/src/sfntly/table/bitmap/index_sub_table_format4.h',
+ 'cpp/src/sfntly/table/bitmap/index_sub_table_format5.cc',
+ 'cpp/src/sfntly/table/bitmap/index_sub_table_format5.h',
+ 'cpp/src/sfntly/table/bitmap/simple_bitmap_glyph.cc',
+ 'cpp/src/sfntly/table/bitmap/simple_bitmap_glyph.h',
+ 'cpp/src/sfntly/table/bitmap/small_glyph_metrics.cc',
+ 'cpp/src/sfntly/table/bitmap/small_glyph_metrics.h',
+ 'cpp/src/sfntly/table/byte_array_table_builder.cc',
+ 'cpp/src/sfntly/table/byte_array_table_builder.h',
+ 'cpp/src/sfntly/table/core/cmap_table.cc',
+ 'cpp/src/sfntly/table/core/cmap_table.h',
+ 'cpp/src/sfntly/table/core/font_header_table.cc',
+ 'cpp/src/sfntly/table/core/font_header_table.h',
+ 'cpp/src/sfntly/table/core/horizontal_device_metrics_table.cc',
+ 'cpp/src/sfntly/table/core/horizontal_device_metrics_table.h',
+ 'cpp/src/sfntly/table/core/horizontal_header_table.cc',
+ 'cpp/src/sfntly/table/core/horizontal_header_table.h',
+ 'cpp/src/sfntly/table/core/horizontal_metrics_table.cc',
+ 'cpp/src/sfntly/table/core/horizontal_metrics_table.h',
+ 'cpp/src/sfntly/table/core/maximum_profile_table.cc',
+ 'cpp/src/sfntly/table/core/maximum_profile_table.h',
+ 'cpp/src/sfntly/table/core/name_table.cc',
+ 'cpp/src/sfntly/table/core/name_table.h',
+ 'cpp/src/sfntly/table/core/os2_table.cc',
+ 'cpp/src/sfntly/table/core/os2_table.h',
+ 'cpp/src/sfntly/table/font_data_table.cc',
+ 'cpp/src/sfntly/table/font_data_table.h',
+ 'cpp/src/sfntly/table/generic_table_builder.cc',
+ 'cpp/src/sfntly/table/generic_table_builder.h',
+ 'cpp/src/sfntly/table/header.cc',
+ 'cpp/src/sfntly/table/header.h',
+ 'cpp/src/sfntly/table/subtable.cc',
+ 'cpp/src/sfntly/table/subtable.h',
+ 'cpp/src/sfntly/table/subtable_container_table.h',
+ 'cpp/src/sfntly/table/table.cc',
+ 'cpp/src/sfntly/table/table.h',
+ 'cpp/src/sfntly/table/table_based_table_builder.cc',
+ 'cpp/src/sfntly/table/table_based_table_builder.h',
+ 'cpp/src/sfntly/table/truetype/glyph_table.cc',
+ 'cpp/src/sfntly/table/truetype/glyph_table.h',
+ 'cpp/src/sfntly/table/truetype/loca_table.cc',
+ 'cpp/src/sfntly/table/truetype/loca_table.h',
+ 'cpp/src/sfntly/tag.cc',
+ 'cpp/src/sfntly/tag.h',
+ 'cpp/src/sample/chromium/font_subsetter.cc',
+ 'cpp/src/sample/chromium/font_subsetter.h',
+ 'cpp/src/sample/chromium/subsetter_impl.cc',
+ 'cpp/src/sample/chromium/subsetter_impl.h',
+ ],
+ 'include_dirs': [
+ 'cpp/src', '../..',
+ ],
+ # This macro must be define to suppress the use of exception
+ 'defines': [
+ 'SFNTLY_NO_EXCEPTION',
+ ],
+ 'dependencies' : [
+ '../icu/icu.gyp:icuuc',
+ ],
+ # TODO(jschuh): http://crbug.com/167187
+ 'msvs_disabled_warnings': [ 4267 ],
+ },
+ ]
+}