| /* |
| * Copyright © 2011 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): Behdad Esfahbod |
| */ |
| |
| #ifndef FACE_OPTIONS_HH |
| #define FACE_OPTIONS_HH |
| |
| #include "options.hh" |
| |
| struct face_options_t |
| { |
| ~face_options_t () |
| { |
| g_free (font_file); |
| } |
| |
| void set_face (hb_face_t *face_) |
| { face = face_; } |
| |
| void add_options (option_parser_t *parser); |
| |
| void post_parse (GError **error); |
| |
| static struct cache_t |
| { |
| ~cache_t () |
| { |
| g_free (font_path); |
| hb_blob_destroy (blob); |
| hb_face_destroy (face); |
| } |
| |
| char *font_path = nullptr; |
| hb_blob_t *blob = nullptr; |
| unsigned face_index = (unsigned) -1; |
| hb_face_t *face = nullptr; |
| } cache; |
| |
| char *font_file = nullptr; |
| unsigned face_index = 0; |
| |
| hb_blob_t *blob = nullptr; |
| hb_face_t *face = nullptr; |
| }; |
| |
| |
| face_options_t::cache_t face_options_t::cache {}; |
| |
| void |
| face_options_t::post_parse (GError **error) |
| { |
| if (!font_file) |
| { |
| g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED, |
| "No font file set"); |
| return; |
| } |
| |
| assert (font_file); |
| |
| const char *font_path = font_file; |
| |
| if (0 == strcmp (font_path, "-")) |
| { |
| #if defined(_WIN32) || defined(__CYGWIN__) |
| setmode (fileno (stdin), O_BINARY); |
| font_path = "STDIN"; |
| #else |
| font_path = "/dev/stdin"; |
| #endif |
| } |
| |
| if (!cache.font_path || 0 != strcmp (cache.font_path, font_path)) |
| { |
| hb_blob_destroy (cache.blob); |
| cache.blob = hb_blob_create_from_file_or_fail (font_path); |
| |
| free ((char *) cache.font_path); |
| cache.font_path = g_strdup (font_path); |
| |
| if (!cache.blob) |
| { |
| g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED, |
| "%s: Failed reading file", font_path); |
| return; |
| } |
| |
| hb_face_destroy (cache.face); |
| cache.face = nullptr; |
| cache.face_index = (unsigned) -1; |
| } |
| |
| if (cache.face_index != face_index) |
| { |
| hb_face_destroy (cache.face); |
| cache.face = hb_face_create (cache.blob, face_index); |
| cache.face_index = face_index; |
| } |
| |
| blob = cache.blob; |
| face = cache.face; |
| } |
| |
| void |
| face_options_t::add_options (option_parser_t *parser) |
| { |
| GOptionEntry entries[] = |
| { |
| {"font-file", 0, 0, G_OPTION_ARG_STRING, &this->font_file, "Set font file-name", "filename"}, |
| {"face-index", 'y', 0, G_OPTION_ARG_INT, &this->face_index, "Set face index (default: 0)", "index"}, |
| {nullptr} |
| }; |
| parser->add_group (entries, |
| "face", |
| "Font-face options:", |
| "Options for the font face", |
| this); |
| } |
| |
| #endif |