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