Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/harfbuzz/util/font-options.hh @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 * Copyright © 2011 Google, Inc. | |
| 3 * | |
| 4 * This is part of HarfBuzz, a text shaping library. | |
| 5 * | |
| 6 * Permission is hereby granted, without written agreement and without | |
| 7 * license or royalty fees, to use, copy, modify, and distribute this | |
| 8 * software and its documentation for any purpose, provided that the | |
| 9 * above copyright notice and the following two paragraphs appear in | |
| 10 * all copies of this software. | |
| 11 * | |
| 12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR | |
| 13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES | |
| 14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN | |
| 15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH | |
| 16 * DAMAGE. | |
| 17 * | |
| 18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, | |
| 19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
| 20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | |
| 21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO | |
| 22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | |
| 23 * | |
| 24 * Google Author(s): Behdad Esfahbod | |
| 25 */ | |
| 26 | |
| 27 #ifndef FONT_OPTIONS_HH | |
| 28 #define FONT_OPTIONS_HH | |
| 29 | |
| 30 #include "face-options.hh" | |
| 31 | |
| 32 #ifdef HAVE_FREETYPE | |
| 33 #include <hb-ft.h> | |
| 34 #endif | |
| 35 #include <hb-ot.h> | |
| 36 | |
| 37 #define FONT_SIZE_UPEM 0x7FFFFFFF | |
| 38 #define FONT_SIZE_NONE 0 | |
| 39 | |
| 40 extern const unsigned DEFAULT_FONT_SIZE; | |
| 41 extern const unsigned SUBPIXEL_BITS; | |
| 42 | |
| 43 struct font_options_t : face_options_t | |
| 44 { | |
| 45 ~font_options_t () | |
| 46 { | |
| 47 #ifndef HB_NO_VAR | |
| 48 free (variations); | |
| 49 #endif | |
| 50 g_free (font_funcs); | |
| 51 hb_font_destroy (font); | |
| 52 } | |
| 53 | |
| 54 void add_options (option_parser_t *parser); | |
| 55 | |
| 56 void post_parse (GError **error); | |
| 57 | |
| 58 hb_bool_t sub_font = false; | |
| 59 #ifndef HB_NO_VAR | |
| 60 hb_variation_t *variations = nullptr; | |
| 61 unsigned int num_variations = 0; | |
| 62 #endif | |
| 63 int x_ppem = 0; | |
| 64 int y_ppem = 0; | |
| 65 double ptem = 0.; | |
| 66 double slant = 0.; | |
| 67 unsigned int subpixel_bits = SUBPIXEL_BITS; | |
| 68 mutable double font_size_x = DEFAULT_FONT_SIZE; | |
| 69 mutable double font_size_y = DEFAULT_FONT_SIZE; | |
| 70 char *font_funcs = nullptr; | |
| 71 int ft_load_flags = 2; | |
| 72 | |
| 73 hb_font_t *font = nullptr; | |
| 74 }; | |
| 75 | |
| 76 | |
| 77 static struct supported_font_funcs_t { | |
| 78 char name[4]; | |
| 79 void (*func) (hb_font_t *); | |
| 80 } supported_font_funcs[] = | |
| 81 { | |
| 82 {"ot", hb_ot_font_set_funcs}, | |
| 83 #ifdef HAVE_FREETYPE | |
| 84 {"ft", hb_ft_font_set_funcs}, | |
| 85 #endif | |
| 86 }; | |
| 87 | |
| 88 | |
| 89 void | |
| 90 font_options_t::post_parse (GError **error) | |
| 91 { | |
| 92 assert (!font); | |
| 93 font = hb_font_create (face); | |
| 94 | |
| 95 if (font_size_x == FONT_SIZE_UPEM) | |
| 96 font_size_x = hb_face_get_upem (face); | |
| 97 if (font_size_y == FONT_SIZE_UPEM) | |
| 98 font_size_y = hb_face_get_upem (face); | |
| 99 | |
| 100 hb_font_set_ppem (font, x_ppem, y_ppem); | |
| 101 hb_font_set_ptem (font, ptem); | |
| 102 | |
| 103 hb_font_set_synthetic_slant (font, slant); | |
| 104 | |
| 105 int scale_x = (int) scalbnf (font_size_x, subpixel_bits); | |
| 106 int scale_y = (int) scalbnf (font_size_y, subpixel_bits); | |
| 107 hb_font_set_scale (font, scale_x, scale_y); | |
| 108 | |
| 109 #ifndef HB_NO_VAR | |
| 110 hb_font_set_variations (font, variations, num_variations); | |
| 111 #endif | |
| 112 | |
| 113 void (*set_font_funcs) (hb_font_t *) = nullptr; | |
| 114 if (!font_funcs) | |
| 115 { | |
| 116 set_font_funcs = supported_font_funcs[0].func; | |
| 117 } | |
| 118 else | |
| 119 { | |
| 120 for (unsigned int i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++) | |
| 121 if (0 == g_ascii_strcasecmp (font_funcs, supported_font_funcs[i].name)) | |
| 122 { | |
| 123 set_font_funcs = supported_font_funcs[i].func; | |
| 124 break; | |
| 125 } | |
| 126 if (!set_font_funcs) | |
| 127 { | |
| 128 GString *s = g_string_new (nullptr); | |
| 129 for (unsigned int i = 0; i < ARRAY_LENGTH (supported_font_funcs); i++) | |
| 130 { | |
| 131 if (i) | |
| 132 g_string_append_c (s, '/'); | |
| 133 g_string_append (s, supported_font_funcs[i].name); | |
| 134 } | |
| 135 g_string_append_c (s, '\n'); | |
| 136 char *p = g_string_free (s, FALSE); | |
| 137 g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, | |
| 138 "Unknown font function implementation `%s'; supported values are: %s; default is %s", | |
| 139 font_funcs, | |
| 140 p, | |
| 141 supported_font_funcs[0].name); | |
| 142 free (p); | |
| 143 return; | |
| 144 } | |
| 145 } | |
| 146 set_font_funcs (font); | |
| 147 #ifdef HAVE_FREETYPE | |
| 148 hb_ft_font_set_load_flags (font, ft_load_flags); | |
| 149 #endif | |
| 150 | |
| 151 if (sub_font) | |
| 152 { | |
| 153 hb_font_t *old_font = font; | |
| 154 font = hb_font_create_sub_font (old_font); | |
| 155 hb_font_set_scale (old_font, scale_x * 2, scale_y * 2); | |
| 156 hb_font_destroy (old_font); | |
| 157 } | |
| 158 } | |
| 159 | |
| 160 | |
| 161 #ifndef HB_NO_VAR | |
| 162 static gboolean | |
| 163 parse_variations (const char *name G_GNUC_UNUSED, | |
| 164 const char *arg, | |
| 165 gpointer data, | |
| 166 GError **error G_GNUC_UNUSED) | |
| 167 { | |
| 168 font_options_t *font_opts = (font_options_t *) data; | |
| 169 char *s = (char *) arg; | |
| 170 char *p; | |
| 171 | |
| 172 font_opts->num_variations = 0; | |
| 173 g_free (font_opts->variations); | |
| 174 font_opts->variations = nullptr; | |
| 175 | |
| 176 if (!*s) | |
| 177 return true; | |
| 178 | |
| 179 /* count the variations first, so we can allocate memory */ | |
| 180 p = s; | |
| 181 do { | |
| 182 font_opts->num_variations++; | |
| 183 p = strpbrk (p, ", "); | |
| 184 if (p) | |
| 185 p++; | |
| 186 } while (p); | |
| 187 | |
| 188 font_opts->variations = (hb_variation_t *) calloc (font_opts->num_variations, sizeof (*font_opts->variations)); | |
| 189 if (!font_opts->variations) | |
| 190 return false; | |
| 191 | |
| 192 /* now do the actual parsing */ | |
| 193 p = s; | |
| 194 font_opts->num_variations = 0; | |
| 195 while (p && *p) { | |
| 196 char *end = strpbrk (p, ", "); | |
| 197 if (hb_variation_from_string (p, end ? end - p : -1, &font_opts->variations[font_opts->num_variations])) | |
| 198 font_opts->num_variations++; | |
| 199 p = end ? end + 1 : nullptr; | |
| 200 } | |
| 201 | |
| 202 return true; | |
| 203 } | |
| 204 #endif | |
| 205 | |
| 206 static gboolean | |
| 207 parse_font_size (const char *name G_GNUC_UNUSED, | |
| 208 const char *arg, | |
| 209 gpointer data, | |
| 210 GError **error G_GNUC_UNUSED) | |
| 211 { | |
| 212 font_options_t *font_opts = (font_options_t *) data; | |
| 213 if (0 == strcmp (arg, "upem")) | |
| 214 { | |
| 215 font_opts->font_size_y = font_opts->font_size_x = FONT_SIZE_UPEM; | |
| 216 return true; | |
| 217 } | |
| 218 switch (sscanf (arg, "%lf%*[ ,]%lf", &font_opts->font_size_x, &font_opts->font_size_y)) { | |
| 219 case 1: font_opts->font_size_y = font_opts->font_size_x; HB_FALLTHROUGH; | |
| 220 case 2: return true; | |
| 221 default: | |
| 222 g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, | |
| 223 "%s argument should be one or two space-separated numbers", | |
| 224 name); | |
| 225 return false; | |
| 226 } | |
| 227 } | |
| 228 | |
| 229 static gboolean | |
| 230 parse_font_ppem (const char *name G_GNUC_UNUSED, | |
| 231 const char *arg, | |
| 232 gpointer data, | |
| 233 GError **error G_GNUC_UNUSED) | |
| 234 { | |
| 235 font_options_t *font_opts = (font_options_t *) data; | |
| 236 switch (sscanf (arg, "%d%*[ ,]%d", &font_opts->x_ppem, &font_opts->y_ppem)) { | |
| 237 case 1: font_opts->y_ppem = font_opts->x_ppem; HB_FALLTHROUGH; | |
| 238 case 2: return true; | |
| 239 default: | |
| 240 g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, | |
| 241 "%s argument should be one or two space-separated numbers", | |
| 242 name); | |
| 243 return false; | |
| 244 } | |
| 245 } | |
| 246 | |
| 247 void | |
| 248 font_options_t::add_options (option_parser_t *parser) | |
| 249 { | |
| 250 face_options_t::add_options (parser); | |
| 251 | |
| 252 char *text = nullptr; | |
| 253 | |
| 254 { | |
| 255 static_assert ((ARRAY_LENGTH_CONST (supported_font_funcs) > 0), | |
| 256 "No supported font-funcs found."); | |
| 257 GString *s = g_string_new (nullptr); | |
| 258 g_string_printf (s, "Set font functions implementation to use (default: %s)\n\n Supported font function implementations are: %s", | |
| 259 supported_font_funcs[0].name, | |
| 260 supported_font_funcs[0].name); | |
| 261 for (unsigned int i = 1; i < ARRAY_LENGTH (supported_font_funcs); i++) | |
| 262 { | |
| 263 g_string_append_c (s, '/'); | |
| 264 g_string_append (s, supported_font_funcs[i].name); | |
| 265 } | |
| 266 text = g_string_free (s, FALSE); | |
| 267 parser->free_later (text); | |
| 268 } | |
| 269 | |
| 270 char *font_size_text; | |
| 271 if (DEFAULT_FONT_SIZE == FONT_SIZE_UPEM) | |
| 272 font_size_text = (char *) "Font size (default: upem)"; | |
| 273 else | |
| 274 { | |
| 275 font_size_text = g_strdup_printf ("Font size (default: %d)", DEFAULT_FONT_SIZE); | |
| 276 parser->free_later (font_size_text); | |
| 277 } | |
| 278 | |
| 279 int font_size_flags = DEFAULT_FONT_SIZE == FONT_SIZE_NONE ? G_OPTION_FLAG_HIDDEN : 0; | |
| 280 GOptionEntry entries[] = | |
| 281 { | |
| 282 {"font-size", 0, font_size_flags, | |
| 283 G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_size, font_size_text, "1/2 integers or 'upem'"}, | |
| 284 {"font-ppem", 0, font_size_flags, | |
| 285 G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_ppem, "Set x,y pixels per EM (default: 0; disabled)", "1/2 integers"}, | |
| 286 {"font-ptem", 0, 0, | |
| 287 G_OPTION_ARG_DOUBLE, &this->ptem, "Set font point-size (default: 0; disabled)", "point-size"}, | |
| 288 {"font-slant", 0, 0, | |
| 289 G_OPTION_ARG_DOUBLE, &this->slant, "Set synthetic slant (default: 0)", "slant ratio; eg. 0.2"}, | |
| 290 {"font-funcs", 0, 0, G_OPTION_ARG_STRING, &this->font_funcs, text, "impl"}, | |
| 291 {"sub-font", 0, G_OPTION_FLAG_HIDDEN, | |
| 292 G_OPTION_ARG_NONE, &this->sub_font, "Create a sub-font (default: false)", "boolean"}, | |
| 293 {"ft-load-flags", 0, 0, G_OPTION_ARG_INT, &this->ft_load_flags, "Set FreeType load-flags (default: 2)", "integer"}, | |
| 294 {nullptr} | |
| 295 }; | |
| 296 parser->add_group (entries, | |
| 297 "font", | |
| 298 "Font-instance options:", | |
| 299 "Options for the font instance", | |
| 300 this, | |
| 301 false /* We add below. */); | |
| 302 | |
| 303 #ifndef HB_NO_VAR | |
| 304 const gchar *variations_help = "Comma-separated list of font variations\n" | |
| 305 "\n" | |
| 306 " Variations are set globally. The format for specifying variation settings\n" | |
| 307 " follows. All valid CSS font-variation-settings values other than 'normal'\n" | |
| 308 " and 'inherited' are also accepted, though, not documented below.\n" | |
| 309 "\n" | |
| 310 " The format is a tag, optionally followed by an equals sign, followed by a\n" | |
| 311 " number. For example:\n" | |
| 312 "\n" | |
| 313 " \"wght=500\"\n" | |
| 314 " \"slnt=-7.5\""; | |
| 315 | |
| 316 GOptionEntry entries2[] = | |
| 317 { | |
| 318 {"variations", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_variations, variations_help, "list"}, | |
| 319 {nullptr} | |
| 320 }; | |
| 321 parser->add_group (entries2, | |
| 322 "variations", | |
| 323 "Variations options:", | |
| 324 "Options for font variations used", | |
| 325 this); | |
| 326 #endif | |
| 327 } | |
| 328 | |
| 329 #endif |
