[util] Add --font-size to hb-shape
Also makes hb-view to use 8 bits of subpixel precision and shape at requested size, instead of always shaping at upem and scaling results.
This commit is contained in:
parent
5789ca69d7
commit
cd4eb96abb
|
@ -110,6 +110,6 @@ struct shape_closure_consumer_t : option_group_t
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
main_font_text_t<shape_closure_consumer_t> driver;
|
main_font_text_t<shape_closure_consumer_t, FONT_SIZE_NONE, 0> driver;
|
||||||
return driver.main (argc, argv);
|
return driver.main (argc, argv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,6 @@ struct output_buffer_t
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
main_font_text_t<shape_consumer_t<output_buffer_t> > driver;
|
main_font_text_t<shape_consumer_t<output_buffer_t>, FONT_SIZE_UPEM, 0> driver;
|
||||||
return driver.main (argc, argv);
|
return driver.main (argc, argv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,12 @@
|
||||||
#include "shape-consumer.hh"
|
#include "shape-consumer.hh"
|
||||||
#include "view-cairo.hh"
|
#include "view-cairo.hh"
|
||||||
|
|
||||||
|
#define DEFAULT_FONT_SIZE 256
|
||||||
|
#define SUBPIXEL_BITS 8
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
main_font_text_t<shape_consumer_t<view_cairo_t> > driver;
|
main_font_text_t<shape_consumer_t<view_cairo_t>, DEFAULT_FONT_SIZE, SUBPIXEL_BITS> driver;
|
||||||
return driver.main (argc, argv);
|
return driver.main (argc, argv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,8 +70,7 @@ void free_ft_library (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_scaled_font_t *
|
cairo_scaled_font_t *
|
||||||
helper_cairo_create_scaled_font (const font_options_t *font_opts,
|
helper_cairo_create_scaled_font (const font_options_t *font_opts)
|
||||||
double font_size)
|
|
||||||
{
|
{
|
||||||
hb_font_t *font = hb_font_reference (font_opts->get_font ());
|
hb_font_t *font = hb_font_reference (font_opts->get_font ());
|
||||||
|
|
||||||
|
@ -105,7 +104,8 @@ helper_cairo_create_scaled_font (const font_options_t *font_opts,
|
||||||
|
|
||||||
cairo_matrix_init_identity (&ctm);
|
cairo_matrix_init_identity (&ctm);
|
||||||
cairo_matrix_init_scale (&font_matrix,
|
cairo_matrix_init_scale (&font_matrix,
|
||||||
font_size, font_size);
|
font_opts->font_size_x,
|
||||||
|
font_opts->font_size_y);
|
||||||
font_options = cairo_font_options_create ();
|
font_options = cairo_font_options_create ();
|
||||||
cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
|
cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
|
||||||
cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
|
cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
|
||||||
|
@ -423,7 +423,7 @@ helper_cairo_line_from_buffer (helper_cairo_line_t *l,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
const char *text,
|
const char *text,
|
||||||
unsigned int text_len,
|
unsigned int text_len,
|
||||||
double scale,
|
int scale_bits,
|
||||||
hb_bool_t utf8_clusters)
|
hb_bool_t utf8_clusters)
|
||||||
{
|
{
|
||||||
memset (l, 0, sizeof (*l));
|
memset (l, 0, sizeof (*l));
|
||||||
|
@ -456,16 +456,16 @@ helper_cairo_line_from_buffer (helper_cairo_line_t *l,
|
||||||
for (i = 0; i < (int) l->num_glyphs; i++)
|
for (i = 0; i < (int) l->num_glyphs; i++)
|
||||||
{
|
{
|
||||||
l->glyphs[i].index = hb_glyph[i].codepoint;
|
l->glyphs[i].index = hb_glyph[i].codepoint;
|
||||||
l->glyphs[i].x = ( hb_position->x_offset + x) * scale;
|
l->glyphs[i].x = scalbn ( hb_position->x_offset + x, scale_bits);
|
||||||
l->glyphs[i].y = (-hb_position->y_offset + y) * scale;
|
l->glyphs[i].y = scalbn (-hb_position->y_offset + y, scale_bits);
|
||||||
x += hb_position->x_advance;
|
x += hb_position->x_advance;
|
||||||
y += -hb_position->y_advance;
|
y += -hb_position->y_advance;
|
||||||
|
|
||||||
hb_position++;
|
hb_position++;
|
||||||
}
|
}
|
||||||
l->glyphs[i].index = -1;
|
l->glyphs[i].index = -1;
|
||||||
l->glyphs[i].x = x * scale;
|
l->glyphs[i].x = scalbn (x, scale_bits);
|
||||||
l->glyphs[i].y = y * scale;
|
l->glyphs[i].y = scalbn (y, scale_bits);
|
||||||
|
|
||||||
if (l->num_clusters) {
|
if (l->num_clusters) {
|
||||||
memset ((void *) l->clusters, 0, l->num_clusters * sizeof (l->clusters[0]));
|
memset ((void *) l->clusters, 0, l->num_clusters * sizeof (l->clusters[0]));
|
||||||
|
|
|
@ -33,8 +33,7 @@
|
||||||
|
|
||||||
|
|
||||||
cairo_scaled_font_t *
|
cairo_scaled_font_t *
|
||||||
helper_cairo_create_scaled_font (const font_options_t *font_opts,
|
helper_cairo_create_scaled_font (const font_options_t *font_opts);
|
||||||
double font_size);
|
|
||||||
|
|
||||||
extern const char *helper_cairo_supported_formats[];
|
extern const char *helper_cairo_supported_formats[];
|
||||||
|
|
||||||
|
@ -76,7 +75,7 @@ helper_cairo_line_from_buffer (helper_cairo_line_t *l,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
const char *text,
|
const char *text,
|
||||||
unsigned int text_len,
|
unsigned int text_len,
|
||||||
double scale,
|
int scale_bits,
|
||||||
hb_bool_t utf8_clusters);
|
hb_bool_t utf8_clusters);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,12 +31,12 @@
|
||||||
|
|
||||||
/* main() body for utilities taking font and processing text.*/
|
/* main() body for utilities taking font and processing text.*/
|
||||||
|
|
||||||
template <typename consumer_t>
|
template <typename consumer_t, int default_font_size, int subpixel_bits>
|
||||||
struct main_font_text_t
|
struct main_font_text_t
|
||||||
{
|
{
|
||||||
main_font_text_t (void)
|
main_font_text_t (void)
|
||||||
: options ("[FONT-FILE] [TEXT]"),
|
: options ("[FONT-FILE] [TEXT]"),
|
||||||
font_opts (&options),
|
font_opts (&options, default_font_size, subpixel_bits),
|
||||||
input (&options),
|
input (&options),
|
||||||
consumer (&options) {}
|
consumer (&options) {}
|
||||||
|
|
||||||
|
|
|
@ -265,7 +265,6 @@ view_options_t::add_options (option_parser_t *parser)
|
||||||
{"foreground", 0, 0, G_OPTION_ARG_STRING, &this->fore, "Set foreground color (default: " DEFAULT_FORE ")", "rrggbb/rrggbbaa"},
|
{"foreground", 0, 0, G_OPTION_ARG_STRING, &this->fore, "Set foreground color (default: " DEFAULT_FORE ")", "rrggbb/rrggbbaa"},
|
||||||
{"line-space", 0, 0, G_OPTION_ARG_DOUBLE, &this->line_space, "Set space between lines (default: 0)", "units"},
|
{"line-space", 0, 0, G_OPTION_ARG_DOUBLE, &this->line_space, "Set space between lines (default: 0)", "units"},
|
||||||
{"margin", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_margin, "Margin around output (default: " G_STRINGIFY(DEFAULT_MARGIN) ")","one to four numbers"},
|
{"margin", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_margin, "Margin around output (default: " G_STRINGIFY(DEFAULT_MARGIN) ")","one to four numbers"},
|
||||||
{"font-size", 0, 0, G_OPTION_ARG_DOUBLE, &this->font_size, "Font size (default: " G_STRINGIFY(DEFAULT_FONT_SIZE) ")","size"},
|
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
parser->add_group (entries,
|
parser->add_group (entries,
|
||||||
|
@ -350,6 +349,28 @@ shape_options_t::add_options (option_parser_t *parser)
|
||||||
this);
|
this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
parse_font_size (const char *name G_GNUC_UNUSED,
|
||||||
|
const char *arg,
|
||||||
|
gpointer data,
|
||||||
|
GError **error G_GNUC_UNUSED)
|
||||||
|
{
|
||||||
|
font_options_t *font_opts = (font_options_t *) data;
|
||||||
|
if (0 == strcmp (arg, "upem"))
|
||||||
|
{
|
||||||
|
font_opts->font_size_y = font_opts->font_size_x = FONT_SIZE_UPEM;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
switch (sscanf (arg, "%lf %lf", &font_opts->font_size_x, &font_opts->font_size_y)) {
|
||||||
|
case 1: font_opts->font_size_y = font_opts->font_size_x;
|
||||||
|
case 2: return true;
|
||||||
|
default:
|
||||||
|
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
|
||||||
|
"%s argument should be one to four space-separated numbers",
|
||||||
|
name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
void
|
void
|
||||||
font_options_t::add_options (option_parser_t *parser)
|
font_options_t::add_options (option_parser_t *parser)
|
||||||
{
|
{
|
||||||
|
@ -370,10 +391,21 @@ font_options_t::add_options (option_parser_t *parser)
|
||||||
parser->free_later (text);
|
parser->free_later (text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *font_size_text;
|
||||||
|
if (default_font_size == FONT_SIZE_UPEM)
|
||||||
|
font_size_text = (char *) "Font size (default: upem)";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
font_size_text = g_strdup_printf ("Font size (default: %d)", default_font_size);
|
||||||
|
parser->free_later (font_size_text);
|
||||||
|
}
|
||||||
|
|
||||||
GOptionEntry entries[] =
|
GOptionEntry entries[] =
|
||||||
{
|
{
|
||||||
{"font-file", 0, 0, G_OPTION_ARG_STRING, &this->font_file, "Set font file-name", "filename"},
|
{"font-file", 0, 0, G_OPTION_ARG_STRING, &this->font_file, "Set font file-name", "filename"},
|
||||||
{"face-index", 0, 0, G_OPTION_ARG_INT, &this->face_index, "Set face index (default: 0)", "index"},
|
{"face-index", 0, 0, G_OPTION_ARG_INT, &this->face_index, "Set face index (default: 0)", "index"},
|
||||||
|
{"font-size", 0, default_font_size ? 0 : G_OPTION_FLAG_HIDDEN,
|
||||||
|
G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_size, font_size_text, "1/2 numbers or 'upem'"},
|
||||||
{"font-funcs", 0, 0, G_OPTION_ARG_STRING, &this->font_funcs, text, "impl"},
|
{"font-funcs", 0, 0, G_OPTION_ARG_STRING, &this->font_funcs, text, "impl"},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
@ -515,8 +547,14 @@ font_options_t::get_font (void) const
|
||||||
|
|
||||||
font = hb_font_create (face);
|
font = hb_font_create (face);
|
||||||
|
|
||||||
unsigned int upem = hb_face_get_upem (face);
|
if (font_size_x == FONT_SIZE_UPEM)
|
||||||
hb_font_set_scale (font, upem, upem);
|
font_size_x = hb_face_get_upem (face);
|
||||||
|
if (font_size_y == FONT_SIZE_UPEM)
|
||||||
|
font_size_y = hb_face_get_upem (face);
|
||||||
|
|
||||||
|
int scale_x = (int) scalbnf (font_size_x, subpixel_bits);
|
||||||
|
int scale_y = (int) scalbnf (font_size_y, subpixel_bits);
|
||||||
|
hb_font_set_scale (font, scale_x, scale_y);
|
||||||
hb_face_destroy (face);
|
hb_face_destroy (face);
|
||||||
|
|
||||||
void (*set_font_funcs) (hb_font_t *) = NULL;
|
void (*set_font_funcs) (hb_font_t *) = NULL;
|
||||||
|
|
|
@ -143,7 +143,8 @@ struct option_parser_t
|
||||||
#define DEFAULT_MARGIN 16
|
#define DEFAULT_MARGIN 16
|
||||||
#define DEFAULT_FORE "#000000"
|
#define DEFAULT_FORE "#000000"
|
||||||
#define DEFAULT_BACK "#FFFFFF"
|
#define DEFAULT_BACK "#FFFFFF"
|
||||||
#define DEFAULT_FONT_SIZE 256
|
#define FONT_SIZE_UPEM 0x7FFFFFFF
|
||||||
|
#define FONT_SIZE_NONE 0
|
||||||
|
|
||||||
struct view_options_t : option_group_t
|
struct view_options_t : option_group_t
|
||||||
{
|
{
|
||||||
|
@ -153,7 +154,6 @@ struct view_options_t : option_group_t
|
||||||
back = DEFAULT_BACK;
|
back = DEFAULT_BACK;
|
||||||
line_space = 0;
|
line_space = 0;
|
||||||
margin.t = margin.r = margin.b = margin.l = DEFAULT_MARGIN;
|
margin.t = margin.r = margin.b = margin.l = DEFAULT_MARGIN;
|
||||||
font_size = DEFAULT_FONT_SIZE;
|
|
||||||
|
|
||||||
add_options (parser);
|
add_options (parser);
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,6 @@ struct view_options_t : option_group_t
|
||||||
struct margin_t {
|
struct margin_t {
|
||||||
double t, r, b, l;
|
double t, r, b, l;
|
||||||
} margin;
|
} margin;
|
||||||
double font_size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -273,9 +272,14 @@ struct shape_options_t : option_group_t
|
||||||
|
|
||||||
struct font_options_t : option_group_t
|
struct font_options_t : option_group_t
|
||||||
{
|
{
|
||||||
font_options_t (option_parser_t *parser) {
|
font_options_t (option_parser_t *parser,
|
||||||
|
int default_font_size_,
|
||||||
|
unsigned int subpixel_bits_) {
|
||||||
|
default_font_size = default_font_size_;
|
||||||
|
subpixel_bits = subpixel_bits_;
|
||||||
font_file = NULL;
|
font_file = NULL;
|
||||||
face_index = 0;
|
face_index = 0;
|
||||||
|
font_size_x = font_size_y = default_font_size;
|
||||||
font_funcs = NULL;
|
font_funcs = NULL;
|
||||||
|
|
||||||
font = NULL;
|
font = NULL;
|
||||||
|
@ -292,6 +296,10 @@ struct font_options_t : option_group_t
|
||||||
|
|
||||||
const char *font_file;
|
const char *font_file;
|
||||||
int face_index;
|
int face_index;
|
||||||
|
int default_font_size;
|
||||||
|
unsigned int subpixel_bits;
|
||||||
|
mutable double font_size_x;
|
||||||
|
mutable double font_size_y;
|
||||||
const char *font_funcs;
|
const char *font_funcs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -54,7 +54,7 @@ view_cairo_t::get_surface_size (cairo_scaled_font_t *scaled_font,
|
||||||
void
|
void
|
||||||
view_cairo_t::render (const font_options_t *font_opts)
|
view_cairo_t::render (const font_options_t *font_opts)
|
||||||
{
|
{
|
||||||
cairo_scaled_font_t *scaled_font = helper_cairo_create_scaled_font (font_opts, view_options.font_size);
|
cairo_scaled_font_t *scaled_font = helper_cairo_create_scaled_font (font_opts);
|
||||||
double w, h;
|
double w, h;
|
||||||
get_surface_size (scaled_font, &w, &h);
|
get_surface_size (scaled_font, &w, &h);
|
||||||
cairo_t *cr = helper_cairo_create_context (w, h, &view_options, &output_options);
|
cairo_t *cr = helper_cairo_create_context (w, h, &view_options, &output_options);
|
||||||
|
|
|
@ -37,7 +37,7 @@ struct view_cairo_t
|
||||||
: output_options (parser, helper_cairo_supported_formats),
|
: output_options (parser, helper_cairo_supported_formats),
|
||||||
view_options (parser),
|
view_options (parser),
|
||||||
direction (HB_DIRECTION_INVALID),
|
direction (HB_DIRECTION_INVALID),
|
||||||
lines (0), scale (1.0) {}
|
lines (0), scale_bits (0) {}
|
||||||
~view_cairo_t (void) {
|
~view_cairo_t (void) {
|
||||||
if (debug)
|
if (debug)
|
||||||
cairo_debug_reset_static_data ();
|
cairo_debug_reset_static_data ();
|
||||||
|
@ -46,7 +46,7 @@ struct view_cairo_t
|
||||||
void init (const font_options_t *font_opts)
|
void init (const font_options_t *font_opts)
|
||||||
{
|
{
|
||||||
lines = g_array_new (false, false, sizeof (helper_cairo_line_t));
|
lines = g_array_new (false, false, sizeof (helper_cairo_line_t));
|
||||||
scale = double (view_options.font_size) / hb_face_get_upem (hb_font_get_face (font_opts->get_font ()));
|
scale_bits = -font_opts->subpixel_bits;
|
||||||
}
|
}
|
||||||
void new_line (void)
|
void new_line (void)
|
||||||
{
|
{
|
||||||
|
@ -71,7 +71,7 @@ struct view_cairo_t
|
||||||
{
|
{
|
||||||
direction = hb_buffer_get_direction (buffer);
|
direction = hb_buffer_get_direction (buffer);
|
||||||
helper_cairo_line_t l;
|
helper_cairo_line_t l;
|
||||||
helper_cairo_line_from_buffer (&l, buffer, text, text_len, scale, utf8_clusters);
|
helper_cairo_line_from_buffer (&l, buffer, text, text_len, scale_bits, utf8_clusters);
|
||||||
g_array_append_val (lines, l);
|
g_array_append_val (lines, l);
|
||||||
}
|
}
|
||||||
void finish (const font_options_t *font_opts)
|
void finish (const font_options_t *font_opts)
|
||||||
|
@ -100,7 +100,7 @@ struct view_cairo_t
|
||||||
|
|
||||||
hb_direction_t direction; // Remove this, make segment_properties accessible
|
hb_direction_t direction; // Remove this, make segment_properties accessible
|
||||||
GArray *lines;
|
GArray *lines;
|
||||||
double scale;
|
int scale_bits;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue