hb-subset.cc 3.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 * Copyright © 2010  Behdad Esfahbod
 * Copyright © 2011,2012  Google, Inc.
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Google Author(s): Garret Rieger, Rod Sheeter
 */
27

28
#include <stdio.h>
29

30
#include "main-font-text.hh"
R
Rod Sheeter 已提交
31
#include "hb-subset.h"
32

33 34 35
/*
 * Command line interface to the harfbuzz font subsetter.
 */
36

37 38 39
struct subset_consumer_t
{
  subset_consumer_t (option_parser_t *parser)
B
Behdad Esfahbod 已提交
40
      : failed (false), options (parser), font (nullptr), codepoints (nullptr) {}
41

42 43 44 45
  void init (hb_buffer_t  *buffer_,
             const font_options_t *font_opts)
  {
    font = hb_font_reference (font_opts->get_font ());
46
    codepoints = hb_set_create();
47 48
  }

49 50 51 52 53
  void consume_line (const char   *text,
                     unsigned int  text_len,
                     const char   *text_before,
                     const char   *text_after)
  {
54 55 56 57 58 59 60 61 62
    // text appears to be a g_string when set by --unicodes
    // TODO(Q1) are gunichar and hbcodepoint_t interchangeable?
    // TODO(Q1) does this only get called with at least 1 codepoint?
    gchar *c = (gchar *)text;
    do {
      gunichar cp = g_utf8_get_char(c);
      hb_codepoint_t hb_cp = cp; // TODO(Q1) is this safe?
      hb_set_add(codepoints, hb_cp);
    } while ((c = g_utf8_find_next_char(c, text + text_len)) != nullptr);
63 64
  }

B
Behdad Esfahbod 已提交
65 66
  hb_bool_t
  write_file (const char *output_file, hb_blob_t *blob) {
67
    unsigned int data_length;
R
Rod Sheeter 已提交
68
    const char* data = hb_blob_get_data (blob, &data_length);
69

70
    FILE *fp_out = fopen(output_file, "wb");
71 72
    if (fp_out == nullptr) {
      fprintf(stderr, "Unable to open output file\n");
R
Rod Sheeter 已提交
73
      return false;
G
Garret Rieger 已提交
74
    }
75
    int bytes_written = fwrite(data, 1, data_length, fp_out);
76

B
Behdad Esfahbod 已提交
77 78
    fclose (fp_out);

R
Rod Sheeter 已提交
79 80 81 82
    if (bytes_written == -1) {
      fprintf(stderr, "Unable to write output file\n");
      return false;
    }
83 84
    if ((unsigned int) bytes_written != data_length) {
      fprintf(stderr, "Expected %u bytes written, got %d\n", data_length,
R
Rod Sheeter 已提交
85 86
              bytes_written);
      return false;
B
Behdad Esfahbod 已提交
87
    }
R
Rod Sheeter 已提交
88 89 90 91 92 93 94
    return true;
  }

  void finish (const font_options_t *font_opts)
  {
    // TODO(Q1) check for errors from creates and such
    hb_subset_profile_t *subset_profile = hb_subset_profile_create();
95
    hb_subset_input_t *subset_input = hb_subset_input_create (codepoints);
B
Behdad Esfahbod 已提交
96
    hb_face_t *face = hb_font_get_face (font);
R
Rod Sheeter 已提交
97

98 99 100 101 102 103
    hb_face_t *new_face = hb_subset(face, subset_profile, subset_input);
    hb_blob_t *result = hb_face_reference_blob (new_face);

    failed = !hb_blob_get_length (result);
    if (!failed)
      write_file (options.output_file, result);
104

R
Rod Sheeter 已提交
105 106
    hb_subset_profile_destroy (subset_profile);
    hb_subset_input_destroy (subset_input);
107
    hb_set_destroy (codepoints);
108
    hb_blob_destroy (result);
109
    hb_face_destroy (new_face);
110
    hb_font_destroy (font);
111 112
  }

113 114
  public:
  bool failed;
115

116 117 118
  private:
  output_options_t options;
  hb_font_t *font;
119
  hb_set_t *codepoints;
120
};
121

122 123 124 125 126
int
main (int argc, char **argv)
{
  main_font_text_t<subset_consumer_t, 10, 0> driver;
  return driver.main (argc, argv);
127
}