91 {
92 if (argc != 3) {
94 return -1;
95 }
96 std::string output_file_path(
argv[1]);
97 std::string input_file_path(
argv[2]);
98 std::cout << "Using output file: " << output_file_path << std::endl;
99 std::cout << "Using source file: " << input_file_path << std::endl;
100
102 hb_blob_create_from_file(input_file_path.c_str()));
103 if (!hb_blob_get_length(font_blob.get())) {
104 std::cerr << "Failed to load input font " << input_file_path
105 << "; aborting. This error indicates that the font is invalid or "
106 "the current version of Harfbuzz is unable to process it."
107 << std::endl;
108 return -1;
109 }
110
112 if (font_face.get() == hb_face_get_empty()) {
113 std::cerr << "Failed to load input font face " << input_file_path
114 << "; aborting. This error indicates that the font is invalid or "
115 "the current version of Harfbuzz is unable to process it."
116 << std::endl;
117 return -1;
118 }
119
121 {
122 hb_set_t* desired_codepoints = hb_subset_input_unicode_set(input.get());
124 hb_face_collect_unicodes(font_face.get(), actual_codepoints.get());
125 std::string raw_codepoint;
126 while (std::cin >> raw_codepoint) {
127 bool optional = false;
128 auto codepoint =
130 if (!codepoint) {
131 std::cerr << "Invalid codepoint for " << raw_codepoint << "; exiting."
132 << std::endl;
133 return -1;
134 }
135
136 if (!hb_set_has(actual_codepoints.get(), codepoint)) {
137 if (optional) {
138
139 continue;
140 }
141
142 std::cerr << "Codepoint " << raw_codepoint
143 << " not found in font, aborting." << std::endl;
144 return -1;
145 }
146 hb_set_add(desired_codepoints, codepoint);
147 }
148 if (hb_set_is_empty(desired_codepoints)) {
149 std::cerr << "No codepoints specified, exiting." << std::endl;
150 return -1;
151 }
152 }
153
156
157 if (!new_face || new_face.get() == hb_face_get_empty()) {
158 std::cerr
159 << "Failed to subset font; aborting. This error normally indicates "
160 "the current version of Harfbuzz is unable to process it."
161 << std::endl;
162 return -1;
163 }
164
166 if (!hb_blob_get_length(
result.get())) {
167 std::cerr << "Failed get new font bytes; aborting. This error may indicate "
168 "low availability of memory or a bug in Harfbuzz."
169 << std::endl;
170 return -1;
171 }
172
173 unsigned int data_length;
174 const char*
data = hb_blob_get_data(
result.get(), &data_length);
175
176 std::ofstream output_font_file;
177 output_font_file.open(output_file_path,
179 if (!output_font_file.is_open()) {
180 std::cerr << "Failed to open output file '" << output_file_path
181 << "'. The parent directory may not exist, or the user does not "
182 "have permission to create this file."
183 << std::endl;
184 return -1;
185 }
186 output_font_file.write(
data, data_length);
187 output_font_file.flush();
188 output_font_file.close();
189
190 std::cout << "Wrote " << data_length << " bytes to " << output_file_path
191 << std::endl;
192 return 0;
193}
std::unique_ptr< hb_subset_input_t, hb_subset_input_deleter > HbSubsetInputPtr
std::unique_ptr< hb_blob_t, hb_blob_deleter > HbBlobPtr
std::unique_ptr< hb_face_t, hb_face_deleter > HbFacePtr
std::unique_ptr< hb_set_t, hb_set_deleter > HbSetPtr
SIN Vec< N, float > trunc(const Vec< N, float > &x)
static HarfbuzzWrappers::HbFacePtr Make(hb_face_t *face, T input)
std::shared_ptr< const fml::Mapping > data
hb_codepoint_t ParseCodepoint(std::string_view arg, bool &optional)