| /* |
| * 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; |
| } |