Home | History | Annotate | Download | only in chromium
      1 /*
      2  * Copyright 2011 Google Inc. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <stdio.h>
     18 
     19 #include <vector>
     20 #include <string>
     21 #include <sstream>
     22 
     23 #include "sfntly/port/type.h"
     24 #include "font_subsetter.h"
     25 
     26 template <typename T>
     27 class HexTo {
     28  public:
     29   explicit HexTo(const char* in) {
     30     std::stringstream ss;
     31     ss << std::hex << in;
     32     ss >> value_;
     33   }
     34   operator T() const { return value_; }
     35 
     36  private:
     37   T value_;
     38 };
     39 
     40 bool LoadFile(const char* input_file_path, sfntly::ByteVector* input_buffer) {
     41   assert(input_file_path);
     42   assert(input_buffer);
     43 
     44   FILE* input_file = NULL;
     45 #if defined WIN32
     46   fopen_s(&input_file, input_file_path, "rb");
     47 #else
     48   input_file = fopen(input_file_path, "rb");
     49 #endif
     50   if (input_file == NULL) {
     51     return false;
     52   }
     53   fseek(input_file, 0, SEEK_END);
     54   size_t file_size = ftell(input_file);
     55   fseek(input_file, 0, SEEK_SET);
     56   input_buffer->resize(file_size);
     57   size_t bytes_read = fread(&((*input_buffer)[0]), 1, file_size, input_file);
     58   fclose(input_file);
     59   return bytes_read == file_size;
     60 }
     61 
     62 bool SaveFile(const char* output_file_path, const unsigned char* output_buffer,
     63               int buffer_length) {
     64   int byte_count = 0;
     65   if (buffer_length > 0) {
     66     FILE* output_file = NULL;
     67 #if defined WIN32
     68     fopen_s(&output_file, output_file_path, "wb");
     69 #else
     70     output_file = fopen(output_file_path, "wb");
     71 #endif
     72     if (output_file) {
     73       byte_count = fwrite(output_buffer, 1, buffer_length, output_file);
     74       fflush(output_file);
     75       fclose(output_file);
     76     }
     77     return buffer_length == byte_count;
     78   }
     79   return false;
     80 }
     81 
     82 bool StringToGlyphId(const char* input, std::vector<unsigned int>* glyph_ids) {
     83   assert(input);
     84   std::string hex_csv = input;
     85   size_t start = 0;
     86   size_t end = hex_csv.find_first_of(",");
     87   while (end != std::string::npos) {
     88     glyph_ids->push_back(
     89         HexTo<unsigned int>(hex_csv.substr(start, end - start).c_str()));
     90     start = end + 1;
     91     end = hex_csv.find_first_of(",", start);
     92   }
     93   glyph_ids->push_back(HexTo<unsigned int>(hex_csv.substr(start).c_str()));
     94   return glyph_ids->size() > 0;
     95 }
     96 
     97 int main(int argc, char** argv) {
     98   if (argc < 5) {
     99     fprintf(stderr,
    100         "Usage: %s <input path> <output path> <font name> <glyph ids>\n",
    101         argv[0]);
    102     fprintf(stderr, "\tGlyph ids are comma separated hex values\n");
    103     fprintf(stderr, "\te.g. 20,1a,3b,4f\n");
    104     return 0;
    105   }
    106 
    107   sfntly::ByteVector input_buffer;
    108   if (!LoadFile(argv[1], &input_buffer)) {
    109     fprintf(stderr, "ERROR: unable to load font file %s\n", argv[1]);
    110     return 0;
    111   }
    112 
    113   std::vector<unsigned int> glyph_ids;
    114   if (!StringToGlyphId(argv[4], &glyph_ids)) {
    115     fprintf(stderr, "ERROR: unable to parse input glyph id\n");
    116     return 0;
    117   }
    118 
    119   unsigned char* output_buffer = NULL;
    120   int output_length =
    121       SfntlyWrapper::SubsetFont(argv[3],
    122                                 &(input_buffer[0]),
    123                                 input_buffer.size(),
    124                                 &(glyph_ids[0]),
    125                                 glyph_ids.size(),
    126                                 &output_buffer);
    127 
    128   int result = SaveFile(argv[2], output_buffer, output_length) ? 1 : 0;
    129   delete[] output_buffer;
    130   return result;
    131 }
    132