Compare commits

...

25 Commits

Author SHA1 Message Date
Matthias Clasen
a33cecde95 gtk-demo: Revise the font features demo some more
Make it so that you can tweak ranges.
2017-12-30 18:34:17 -05:00
Matthias Clasen
5625155755 gtk-demo: Revise the font features demo a bit
Add an edit button. Clicking on the label is not very
obvious, and we want to make the label selectable in
the future.
2017-12-30 18:34:17 -05:00
Matthias Clasen
71f2f2be67 font chooser: Show the font name on the tweak page
This was the intention from the start, I just forgot.
2017-12-30 18:34:17 -05:00
Matthias Clasen
1794da485d font chooser: Add scale marks on both size sliders
This was forgotten when we added the second size slider.
2017-12-30 18:34:17 -05:00
Matthias Clasen
15aa0c8ea9 font chooser: Redo the tweaks hookup
Make the font chooser widget export an action that the
dialog can use for the button. This has some advantages:
- we can export not just the toggle state, but also enabled
- we can reuse the same enabled state to make the select
  button insensitive when no font is selected

To determine whether a font is selected, listen to changes
of the list selection. And ensure that the font chooser is
in an initial state when mapped, even if we close the dialog
from the tweak page.
2017-12-30 18:34:17 -05:00
Matthias Clasen
b2c254ea25 gtk-demo: update features and language
Incorporate the font features and language that are
reported by the chooser.
2017-12-30 18:34:17 -05:00
Matthias Clasen
7e2d153a8f font chooser: Add properties for features and language
These can't be returned as part of the font description,
so we need new api for them. For now, this is just readonly
properties. Maybe these should be writable too, eventually.
2017-12-30 18:34:17 -05:00
Matthias Clasen
14dab40bd6 font chooser: Hide the language combo when unneeded
If we have no features, we don't need to select a language.
2017-12-30 18:34:17 -05:00
Matthias Clasen
35a233d9c9 font chooser: Move font variations to the tweaks
This puts everything nicely in the right place.
2017-12-30 18:34:17 -05:00
Matthias Clasen
eecf094924 font chooser: Avoid selection in entries
Its not appropriate here.
2017-12-30 18:34:17 -05:00
Matthias Clasen
756a1a1be9 font chooser: Don't reset features too eagerly
We shouldn't reset the font features when changing the size.
2017-12-30 18:34:17 -05:00
Matthias Clasen
32e7201e47 font chooser: Add a tweak page
Add a button the dialog's header bar that lets us
switch to a second page where we can customize
the selected font.

We show another preview entry and size slider here,
and th font features are now added to this page.
2017-12-30 18:34:17 -05:00
Matthias Clasen
6cb5131717 font chooser: add font features
Allow tweaking font features.
2017-12-30 18:34:17 -05:00
Matthias Clasen
b79634bb9a gtk-demo Populate scripts/langs for font features
We didn't have names for most scripts and languages, and
no translations at all. Copy the necessary code from gtk
here.
2017-12-29 13:22:01 -05:00
Matthias Clasen
829af31a5f gtk-demo: Revise the font features demo
Move the script combo into the features section
where it belongs, improve the labels, and sort it.

Get rid of the double-checkbox-plus-icon thingie
for features. Just use a single, tri-state
checkbutton and only show the features which are
present in the font.
2017-12-29 13:22:01 -05:00
Matthias Clasen
01cf2c2d60 font chooser: Add a monospace filter
Since it is easy to do, why not.
2017-12-29 13:22:01 -05:00
Matthias Clasen
a13eddbf97 font chooser: Add language/script filtering
Allow filtering the list script or language.
This relies on pango api that is not on master
yet.
2017-12-29 13:22:01 -05:00
Matthias Clasen
3903ef546c font button: Remove show-font and show-size
These are now handled in a more systematic fashion
using GtkFontChooserLevel.
2017-12-29 13:22:01 -05:00
Matthias Clasen
9a3e8b7d54 font chooser: introduce font chooser levels
This is a more systematic approach to reducing the
level of detail in the font chooser.
2017-12-29 13:22:00 -05:00
Matthias Clasen
2141ef18ca font chooser: Small revision of the UI
Show only the font names in the list, in their own
font, in order to make the list less noisy.
2017-12-29 13:22:00 -05:00
Matthias Clasen
2fe1e420ac css: Document font-variation-settings 2017-12-29 13:22:00 -05:00
Matthias Clasen
81a3c60e11 font button: Take variations into account
We need to apply variations too, when we are using
the font to render the button label.
2017-12-29 13:20:58 -05:00
Matthias Clasen
aca655169f Implement font-variation-settings
This is a CSS font level 4 property that lets us
use font variation settings from css.
2017-12-29 13:20:58 -05:00
Matthias Clasen
7b971cc1c8 Add a font variations demo
Expand the font features demo to show off font variations.
2017-12-29 13:20:58 -05:00
Matthias Clasen
85c9ffe412 Some initial support for font variations
Make the font chooser show sliders for axes of variable fonts.
Note that we don't have Pango api for some of this, so we are
using freetype and pango-fc apis directly. Therefore, font
variation support will only be available on platforms where
we use these libraries.
2017-12-29 13:20:58 -05:00
37 changed files with 6004 additions and 2013 deletions

View File

@@ -289,3 +289,8 @@
#mesondefine GTK_LIBDIR
#mesondefine GTK_PRINT_BACKENDS
#mesondefine GTK_PRINT_BACKENDS
#mesondefine HAVE_HARFBUZZ
#mesondefine HAVE_PANGOFT

View File

@@ -163,6 +163,7 @@
<file>flowbox.c</file>
<file>foreigndrawing.c</file>
<file>font_features.c</file>
<file>fontplane.c</file>
<file>gestures.c</file>
<file>glarea.c</file>
<file>headerbar.c</file>
@@ -224,6 +225,7 @@
</gresource>
<gresource prefix="/font_features">
<file>font-features.ui</file>
<file>fontplane.c</file>
</gresource>
<gresource prefix="/spinbutton">
<file>spinbutton.ui</file>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

315
demos/gtk-demo/fontplane.c Normal file
View File

@@ -0,0 +1,315 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2012 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "fontplane.h"
#include "gtk.h"
enum {
PROP_0,
PROP_WEIGHT_ADJUSTMENT,
PROP_WIDTH_ADJUSTMENT
};
G_DEFINE_TYPE (GtkFontPlane, gtk_font_plane, GTK_TYPE_WIDGET)
static double
adjustment_get_normalized_value (GtkAdjustment *adj)
{
return (gtk_adjustment_get_value (adj) - gtk_adjustment_get_lower (adj)) /
(gtk_adjustment_get_upper (adj) - gtk_adjustment_get_lower (adj));
}
static void
val_to_xy (GtkFontPlane *plane,
gint *x,
gint *y)
{
gdouble u, v;
gint width, height;
width = gtk_widget_get_allocated_width (GTK_WIDGET (plane));
height = gtk_widget_get_allocated_height (GTK_WIDGET (plane));
u = adjustment_get_normalized_value (plane->width_adj);
v = adjustment_get_normalized_value (plane->weight_adj);
*x = CLAMP (width * u, 0, width - 1);
*y = CLAMP (height * (1 - v), 0, height - 1);
}
static void
plane_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GtkFontPlane *plane = GTK_FONT_PLANE (widget);
gint x, y;
gint width, height;
cairo_t *cr;
val_to_xy (plane, &x, &y);
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
cr = gtk_snapshot_append_cairo (snapshot,
&GRAPHENE_RECT_INIT (0, 0, width, height),
"FontPlane");
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_rectangle (cr, 0, 0, width, height);
cairo_paint (cr);
cairo_move_to (cr, 0, y + 0.5);
cairo_line_to (cr, width, y + 0.5);
cairo_move_to (cr, x + 0.5, 0);
cairo_line_to (cr, x + 0.5, height);
if (gtk_widget_has_visible_focus (widget))
{
cairo_set_line_width (cr, 3.0);
cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.6);
cairo_stroke_preserve (cr);
cairo_set_line_width (cr, 1.0);
cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.8);
cairo_stroke (cr);
}
else
{
cairo_set_line_width (cr, 1.0);
cairo_set_source_rgba (cr, 0.8, 0.8, 0.8, 0.8);
cairo_stroke (cr);
}
cairo_destroy (cr);
}
static void
set_cross_cursor (GtkWidget *widget,
gboolean enabled)
{
if (enabled)
gtk_widget_set_cursor_from_name (widget, "crosshair");
else
gtk_widget_set_cursor (widget, NULL);
}
static void
adj_changed (GtkFontPlane *plane)
{
gtk_widget_queue_draw (GTK_WIDGET (plane));
}
static void
adjustment_set_normalized_value (GtkAdjustment *adj,
double val)
{
gtk_adjustment_set_value (adj,
gtk_adjustment_get_lower (adj) +
val * (gtk_adjustment_get_upper (adj) - gtk_adjustment_get_lower (adj)));
}
static void
update_value (GtkFontPlane *plane,
gint x,
gint y)
{
GtkWidget *widget = GTK_WIDGET (plane);
gdouble u, v;
u = CLAMP (x * (1.0 / gtk_widget_get_allocated_width (widget)), 0, 1);
v = CLAMP (1 - y * (1.0 / gtk_widget_get_allocated_height (widget)), 0, 1);
adjustment_set_normalized_value (plane->width_adj, u);
adjustment_set_normalized_value (plane->weight_adj, v);
gtk_widget_queue_draw (widget);
}
static void
hold_action (GtkGestureLongPress *gesture,
gdouble x,
gdouble y,
GtkFontPlane *plane)
{
gboolean handled;
g_signal_emit_by_name (plane, "popup-menu", &handled);
}
static void
plane_drag_gesture_begin (GtkGestureDrag *gesture,
gdouble start_x,
gdouble start_y,
GtkFontPlane *plane)
{
guint button;
button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
if (button == GDK_BUTTON_SECONDARY)
{
gboolean handled;
g_signal_emit_by_name (plane, "popup-menu", &handled);
}
if (button != GDK_BUTTON_PRIMARY)
{
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
return;
}
set_cross_cursor (GTK_WIDGET (plane), TRUE);
update_value (plane, start_x, start_y);
gtk_widget_grab_focus (GTK_WIDGET (plane));
gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
}
static void
plane_drag_gesture_update (GtkGestureDrag *gesture,
gdouble offset_x,
gdouble offset_y,
GtkFontPlane *plane)
{
gdouble start_x, start_y;
gtk_gesture_drag_get_start_point (GTK_GESTURE_DRAG (gesture),
&start_x, &start_y);
update_value (plane, start_x + offset_x, start_y + offset_y);
}
static void
plane_drag_gesture_end (GtkGestureDrag *gesture,
gdouble offset_x,
gdouble offset_y,
GtkFontPlane *plane)
{
set_cross_cursor (GTK_WIDGET (plane), FALSE);
}
static void
gtk_font_plane_init (GtkFontPlane *plane)
{
gtk_widget_set_has_window (GTK_WIDGET (plane), FALSE);
gtk_widget_set_can_focus (GTK_WIDGET (plane), TRUE);
plane->drag_gesture = gtk_gesture_drag_new (GTK_WIDGET (plane));
g_signal_connect (plane->drag_gesture, "drag-begin",
G_CALLBACK (plane_drag_gesture_begin), plane);
g_signal_connect (plane->drag_gesture, "drag-update",
G_CALLBACK (plane_drag_gesture_update), plane);
g_signal_connect (plane->drag_gesture, "drag-end",
G_CALLBACK (plane_drag_gesture_end), plane);
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (plane->drag_gesture), 0);
plane->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (plane));
g_signal_connect (plane->long_press_gesture, "pressed",
G_CALLBACK (hold_action), plane);
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (plane->long_press_gesture),
TRUE);
}
static void
plane_finalize (GObject *object)
{
GtkFontPlane *plane = GTK_FONT_PLANE (object);
g_clear_object (&plane->weight_adj);
g_clear_object (&plane->width_adj);
g_clear_object (&plane->drag_gesture);
g_clear_object (&plane->long_press_gesture);
G_OBJECT_CLASS (gtk_font_plane_parent_class)->finalize (object);
}
static void
plane_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkFontPlane *plane = GTK_FONT_PLANE (object);
GObject *adjustment;
switch (prop_id)
{
case PROP_WEIGHT_ADJUSTMENT:
adjustment = g_value_get_object (value);
if (adjustment)
{
plane->weight_adj = g_object_ref_sink (adjustment);
g_signal_connect_swapped (adjustment, "value-changed", G_CALLBACK (adj_changed), plane);
}
break;
case PROP_WIDTH_ADJUSTMENT:
adjustment = g_value_get_object (value);
if (adjustment)
{
plane->width_adj = g_object_ref_sink (adjustment);
g_signal_connect_swapped (adjustment, "value-changed", G_CALLBACK (adj_changed), plane);
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_font_plane_class_init (GtkFontPlaneClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->finalize = plane_finalize;
object_class->set_property = plane_set_property;
widget_class->snapshot = plane_snapshot;
g_object_class_install_property (object_class,
PROP_WEIGHT_ADJUSTMENT,
g_param_spec_object ("weight-adjustment",
NULL,
NULL,
GTK_TYPE_ADJUSTMENT,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
PROP_WIDTH_ADJUSTMENT,
g_param_spec_object ("width-adjustment",
NULL,
NULL,
GTK_TYPE_ADJUSTMENT,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY));
}
GtkWidget *
gtk_font_plane_new (GtkAdjustment *weight_adj,
GtkAdjustment *width_adj)
{
return g_object_new (GTK_TYPE_FONT_PLANE,
"weight-adjustment", weight_adj,
"width-adjustment", width_adj,
NULL);
}

View File

@@ -0,0 +1,65 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2012 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GTK_FONT_PLANE_H__
#define __GTK_FONT_PLANE_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GTK_TYPE_FONT_PLANE (gtk_font_plane_get_type ())
#define GTK_FONT_PLANE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FONT_PLANE, GtkFontPlane))
#define GTK_FONT_PLANE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FONT_PLANE, GtkFontPlaneClass))
#define GTK_IS_FONT_PLANE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_COLOR_PLANE))
#define GTK_IS_FONT_PLANE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_COLOR_PLANE))
#define GTK_FONT_PLANE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FONT_PLANE, GtkFontPlaneClass))
typedef struct _GtkFontPlane GtkFontPlane;
typedef struct _GtkFontPlaneClass GtkFontPlaneClass;
struct _GtkFontPlane
{
GtkWidget parent_instance;
GtkAdjustment *weight_adj;
GtkAdjustment *width_adj;
GtkGesture *drag_gesture;
GtkGesture *long_press_gesture;
};
struct _GtkFontPlaneClass
{
GtkWidgetClass parent_class;
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
};
GType gtk_font_plane_get_type (void) G_GNUC_CONST;
GtkWidget * gtk_font_plane_new (GtkAdjustment *width_adj,
GtkAdjustment *weight_adj);
G_END_DECLS
#endif /* __GTK_FONT_PLANE_H__ */

View File

@@ -0,0 +1,233 @@
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <locale.h>
#include <langinfo.h>
#include <sys/stat.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <hb-ot.h>
#include "language-names.h"
#define ISO_CODES_PREFIX "/usr"
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
static GHashTable *language_map;
static char *
get_first_item_in_semicolon_list (const char *list)
{
char **items;
char *item;
items = g_strsplit (list, "; ", 2);
item = g_strdup (items[0]);
g_strfreev (items);
return item;
}
static char *
capitalize_utf8_string (const char *str)
{
char first[8] = { 0 };
if (!str)
return NULL;
g_unichar_to_utf8 (g_unichar_totitle (g_utf8_get_char (str)), first);
return g_strconcat (first, g_utf8_offset_to_pointer (str, 1), NULL);
}
static char *
get_display_name (const char *language)
{
const char *translated;
char *tmp;
char *name;
translated = dgettext ("iso_639", language);
tmp = get_first_item_in_semicolon_list (translated);
name = capitalize_utf8_string (tmp);
g_free (tmp);
return name;
}
static void
languages_parse_start_tag (GMarkupParseContext *ctx,
const char *element_name,
const char **attr_names,
const char **attr_values,
gpointer user_data,
GError **error)
{
const char *ccode_longB;
const char *ccode_longT;
const char *ccode;
const char *ccode_id;
const char *lang_name;
char *display_name;
if (!(g_str_equal (element_name, "iso_639_entry") ||
g_str_equal (element_name, "iso_639_3_entry")) ||
attr_names == NULL ||
attr_values == NULL)
return;
ccode = NULL;
ccode_longB = NULL;
ccode_longT = NULL;
ccode_id = NULL;
lang_name = NULL;
while (*attr_names && *attr_values)
{
if (g_str_equal (*attr_names, "iso_639_1_code"))
{
if (**attr_values)
{
if (strlen (*attr_values) != 2)
return;
ccode = *attr_values;
}
}
else if (g_str_equal (*attr_names, "iso_639_2B_code"))
{
if (**attr_values)
{
if (strlen (*attr_values) != 3)
return;
ccode_longB = *attr_values;
}
}
else if (g_str_equal (*attr_names, "iso_639_2T_code"))
{
if (**attr_values)
{
if (strlen (*attr_values) != 3)
return;
ccode_longT = *attr_values;
}
}
else if (g_str_equal (*attr_names, "id"))
{
if (**attr_values)
{
if (strlen (*attr_values) != 2 &&
strlen (*attr_values) != 3)
return;
ccode_id = *attr_values;
}
}
else if (g_str_equal (*attr_names, "name"))
{
lang_name = *attr_values;
}
++attr_names;
++attr_values;
}
if (lang_name == NULL)
return;
display_name = get_display_name (lang_name);
if (ccode != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode),
g_strdup (display_name));
if (ccode_longB != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode_longB),
g_strdup (display_name));
if (ccode_longT != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode_longT),
g_strdup (display_name));
if (ccode_id != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode_id),
g_strdup (display_name));
g_free (display_name);
}
static void
languages_variant_init (const char *variant)
{
gboolean res;
gsize buf_len;
g_autofree char *buf = NULL;
g_autofree char *filename = NULL;
g_autoptr (GError) error = NULL;
bindtextdomain (variant, ISO_CODES_LOCALESDIR);
bind_textdomain_codeset (variant, "UTF-8");
error = NULL;
filename = g_strconcat (ISO_CODES_DATADIR, "/", variant, ".xml", NULL);
res = g_file_get_contents (filename, &buf, &buf_len, &error);
if (res)
{
g_autoptr (GMarkupParseContext) ctx = NULL;
GMarkupParser parser = { languages_parse_start_tag, NULL, NULL, NULL, NULL };
ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL);
error = NULL;
res = g_markup_parse_context_parse (ctx, buf, buf_len, &error);
if (!res)
g_warning ("Failed to parse '%s': %s\n", filename, error->message);
}
else
g_warning ("Failed to load '%s': %s\n", filename, error->message);
}
static void
languages_init (void)
{
if (language_map)
return;
language_map = g_hash_table_new_full (NULL, NULL, NULL, g_free);
languages_variant_init ("iso_639");
languages_variant_init ("iso_639_3");
}
const char *
get_language_name (PangoLanguage *language)
{
languages_init ();
return (const char *) g_hash_table_lookup (language_map, language);
}
const char *
get_language_name_for_tag (guint32 tag)
{
hb_language_t lang;
const char *s;
lang = hb_ot_tag_to_language (tag);
s = hb_language_to_string (lang);
return get_language_name (pango_language_from_string (s));
}

View File

@@ -0,0 +1,13 @@
#ifndef LANGUAGE_NAMES_H
#define LANGUAGE_NAMES_H
#include <pango/pango.h>
G_BEGIN_DECLS
const char * get_language_name (PangoLanguage *language);
const char * get_language_name_for_tag (guint32 tag);
G_END_DECLS
#endif

View File

@@ -94,7 +94,7 @@ gtkdemo_resources = gnome.compile_resources('gtkdemo_resources',
source_dir: '.')
executable('gtk4-demo',
'main.c', 'gtkfishbowl.c', demos, demos_h, gtkdemo_resources,
'main.c', 'gtkfishbowl.c', 'fontplane.c', 'script-names.c', 'language-names.c', demos, demos_h, gtkdemo_resources,
c_args: gtkdemo_args,
dependencies: gtkdemo_deps,
include_directories: confinc,

View File

@@ -0,0 +1,155 @@
/* Registered OpenType layout tags, see
* https://www.microsoft.com/typography/otspec/featuretags.htm
*/
typedef struct {
unsigned int tag;
const char *name;
} NamedTag;
#define MAKE_TAG(a,b,c,d) (unsigned int)(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
static NamedTag open_type_layout_features[] = {
{ MAKE_TAG('a','a','l','t'), NC_("OpenType layout", "Access All Alternates") },
{ MAKE_TAG('a','b','v','f'), NC_("OpenType layout", "Above-base Forms") },
{ MAKE_TAG('a','b','v','m'), NC_("OpenType layout", "Above-base Mark Positioning") },
{ MAKE_TAG('a','b','v','s'), NC_("OpenType layout", "Above-base Substitutions") },
{ MAKE_TAG('a','f','r','c'), NC_("OpenType layout", "Alternative Fractions") },
{ MAKE_TAG('a','k','h','n'), NC_("OpenType layout", "Akhands") },
{ MAKE_TAG('b','l','w','f'), NC_("OpenType layout", "Below-base Forms") },
{ MAKE_TAG('b','l','w','m'), NC_("OpenType layout", "Below-base Mark Positioning") },
{ MAKE_TAG('b','l','w','s'), NC_("OpenType layout", "Below-base Substitutions") },
{ MAKE_TAG('c','a','l','t'), NC_("OpenType layout", "Contextual Alternates") },
{ MAKE_TAG('c','a','s','e'), NC_("OpenType layout", "Case-Sensitive Forms") },
{ MAKE_TAG('c','c','m','p'), NC_("OpenType layout", "Glyph Composition / Decomposition") },
{ MAKE_TAG('c','f','a','r'), NC_("OpenType layout", "Conjunct Form After Ro") },
{ MAKE_TAG('c','j','c','t'), NC_("OpenType layout", "Conjunct Forms") },
{ MAKE_TAG('c','l','i','g'), NC_("OpenType layout", "Contextual Ligatures") },
{ MAKE_TAG('c','p','c','t'), NC_("OpenType layout", "Centered CJK Punctuation") },
{ MAKE_TAG('c','p','s','p'), NC_("OpenType layout", "Capital Spacing") },
{ MAKE_TAG('c','s','w','h'), NC_("OpenType layout", "Contextual Swash") },
{ MAKE_TAG('c','u','r','s'), NC_("OpenType layout", "Cursive Positioning") },
{ MAKE_TAG('c','2','p','c'), NC_("OpenType layout", "Petite Capitals From Capitals") },
{ MAKE_TAG('c','2','s','c'), NC_("OpenType layout", "Small Capitals From Capitals") },
{ MAKE_TAG('d','i','s','t'), NC_("OpenType layout", "Distances") },
{ MAKE_TAG('d','l','i','g'), NC_("OpenType layout", "Discretionary Ligatures") },
{ MAKE_TAG('d','n','o','m'), NC_("OpenType layout", "Denominators") },
{ MAKE_TAG('d','t','l','s'), NC_("OpenType layout", "Dotless Forms") },
{ MAKE_TAG('e','x','p','t'), NC_("OpenType layout", "Expert Forms") },
{ MAKE_TAG('f','a','l','t'), NC_("OpenType layout", "Final Glyph on Line Alternates") },
{ MAKE_TAG('f','i','n','2'), NC_("OpenType layout", "Terminal Forms #2") },
{ MAKE_TAG('f','i','n','3'), NC_("OpenType layout", "Terminal Forms #3") },
{ MAKE_TAG('f','i','n','a'), NC_("OpenType layout", "Terminal Forms") },
{ MAKE_TAG('f','l','a','c'), NC_("OpenType layout", "Flattened accent forms") },
{ MAKE_TAG('f','r','a','c'), NC_("OpenType layout", "Fractions") },
{ MAKE_TAG('f','w','i','d'), NC_("OpenType layout", "Full Widths") },
{ MAKE_TAG('h','a','l','f'), NC_("OpenType layout", "Half Forms") },
{ MAKE_TAG('h','a','l','n'), NC_("OpenType layout", "Halant Forms") },
{ MAKE_TAG('h','a','l','t'), NC_("OpenType layout", "Alternate Half Widths") },
{ MAKE_TAG('h','i','s','t'), NC_("OpenType layout", "Historical Forms") },
{ MAKE_TAG('h','k','n','a'), NC_("OpenType layout", "Horizontal Kana Alternates") },
{ MAKE_TAG('h','l','i','g'), NC_("OpenType layout", "Historical Ligatures") },
{ MAKE_TAG('h','n','g','l'), NC_("OpenType layout", "Hangul") },
{ MAKE_TAG('h','o','j','o'), NC_("OpenType layout", "Hojo Kanji Forms") },
{ MAKE_TAG('h','w','i','d'), NC_("OpenType layout", "Half Widths") },
{ MAKE_TAG('i','n','i','t'), NC_("OpenType layout", "Initial Forms") },
{ MAKE_TAG('i','s','o','l'), NC_("OpenType layout", "Isolated Forms") },
{ MAKE_TAG('i','t','a','l'), NC_("OpenType layout", "Italics") },
{ MAKE_TAG('j','a','l','t'), NC_("OpenType layout", "Justification Alternates") },
{ MAKE_TAG('j','p','7','8'), NC_("OpenType layout", "JIS78 Forms") },
{ MAKE_TAG('j','p','8','3'), NC_("OpenType layout", "JIS83 Forms") },
{ MAKE_TAG('j','p','9','0'), NC_("OpenType layout", "JIS90 Forms") },
{ MAKE_TAG('j','p','0','4'), NC_("OpenType layout", "JIS2004 Forms") },
{ MAKE_TAG('k','e','r','n'), NC_("OpenType layout", "Kerning") },
{ MAKE_TAG('l','f','b','d'), NC_("OpenType layout", "Left Bounds") },
{ MAKE_TAG('l','i','g','a'), NC_("OpenType layout", "Standard Ligatures") },
{ MAKE_TAG('l','j','m','o'), NC_("OpenType layout", "Leading Jamo Forms") },
{ MAKE_TAG('l','n','u','m'), NC_("OpenType layout", "Lining Figures") },
{ MAKE_TAG('l','o','c','l'), NC_("OpenType layout", "Localized Forms") },
{ MAKE_TAG('l','t','r','a'), NC_("OpenType layout", "Left-to-right alternates") },
{ MAKE_TAG('l','t','r','m'), NC_("OpenType layout", "Left-to-right mirrored forms") },
{ MAKE_TAG('m','a','r','k'), NC_("OpenType layout", "Mark Positioning") },
{ MAKE_TAG('m','e','d','2'), NC_("OpenType layout", "Medial Forms #2") },
{ MAKE_TAG('m','e','d','i'), NC_("OpenType layout", "Medial Forms") },
{ MAKE_TAG('m','g','r','k'), NC_("OpenType layout", "Mathematical Greek") },
{ MAKE_TAG('m','k','m','k'), NC_("OpenType layout", "Mark to Mark Positioning") },
{ MAKE_TAG('m','s','e','t'), NC_("OpenType layout", "Mark Positioning via Substitution") },
{ MAKE_TAG('n','a','l','t'), NC_("OpenType layout", "Alternate Annotation Forms") },
{ MAKE_TAG('n','l','c','k'), NC_("OpenType layout", "NLC Kanji Forms") },
{ MAKE_TAG('n','u','k','t'), NC_("OpenType layout", "Nukta Forms") },
{ MAKE_TAG('n','u','m','r'), NC_("OpenType layout", "Numerators") },
{ MAKE_TAG('o','n','u','m'), NC_("OpenType layout", "Oldstyle Figures") },
{ MAKE_TAG('o','p','b','d'), NC_("OpenType layout", "Optical Bounds") },
{ MAKE_TAG('o','r','d','n'), NC_("OpenType layout", "Ordinals") },
{ MAKE_TAG('o','r','n','m'), NC_("OpenType layout", "Ornaments") },
{ MAKE_TAG('p','a','l','t'), NC_("OpenType layout", "Proportional Alternate Widths") },
{ MAKE_TAG('p','c','a','p'), NC_("OpenType layout", "Petite Capitals") },
{ MAKE_TAG('p','k','n','a'), NC_("OpenType layout", "Proportional Kana") },
{ MAKE_TAG('p','n','u','m'), NC_("OpenType layout", "Proportional Figures") },
{ MAKE_TAG('p','r','e','f'), NC_("OpenType layout", "Pre-Base Forms") },
{ MAKE_TAG('p','r','e','s'), NC_("OpenType layout", "Pre-base Substitutions") },
{ MAKE_TAG('p','s','t','f'), NC_("OpenType layout", "Post-base Forms") },
{ MAKE_TAG('p','s','t','s'), NC_("OpenType layout", "Post-base Substitutions") },
{ MAKE_TAG('p','w','i','d'), NC_("OpenType layout", "Proportional Widths") },
{ MAKE_TAG('q','w','i','d'), NC_("OpenType layout", "Quarter Widths") },
{ MAKE_TAG('r','a','n','d'), NC_("OpenType layout", "Randomize") },
{ MAKE_TAG('r','c','l','t'), NC_("OpenType layout", "Required Contextual Alternates") },
{ MAKE_TAG('r','k','r','f'), NC_("OpenType layout", "Rakar Forms") },
{ MAKE_TAG('r','l','i','g'), NC_("OpenType layout", "Required Ligatures") },
{ MAKE_TAG('r','p','h','f'), NC_("OpenType layout", "Reph Forms") },
{ MAKE_TAG('r','t','b','d'), NC_("OpenType layout", "Right Bounds") },
{ MAKE_TAG('r','t','l','a'), NC_("OpenType layout", "Right-to-left alternates") },
{ MAKE_TAG('r','t','l','m'), NC_("OpenType layout", "Right-to-left mirrored forms") },
{ MAKE_TAG('r','u','b','y'), NC_("OpenType layout", "Ruby Notation Forms") },
{ MAKE_TAG('r','v','r','n'), NC_("OpenType layout", "Required Variation Alternates") },
{ MAKE_TAG('s','a','l','t'), NC_("OpenType layout", "Stylistic Alternates") },
{ MAKE_TAG('s','i','n','f'), NC_("OpenType layout", "Scientific Inferiors") },
{ MAKE_TAG('s','i','z','e'), NC_("OpenType layout", "Optical size") },
{ MAKE_TAG('s','m','c','p'), NC_("OpenType layout", "Small Capitals") },
{ MAKE_TAG('s','m','p','l'), NC_("OpenType layout", "Simplified Forms") },
{ MAKE_TAG('s','s','0','1'), NC_("OpenType layout", "Stylistic Set 1") },
{ MAKE_TAG('s','s','0','2'), NC_("OpenType layout", "Stylistic Set 2") },
{ MAKE_TAG('s','s','0','3'), NC_("OpenType layout", "Stylistic Set 3") },
{ MAKE_TAG('s','s','0','4'), NC_("OpenType layout", "Stylistic Set 4") },
{ MAKE_TAG('s','s','0','5'), NC_("OpenType layout", "Stylistic Set 5") },
{ MAKE_TAG('s','s','0','6'), NC_("OpenType layout", "Stylistic Set 6") },
{ MAKE_TAG('s','s','0','7'), NC_("OpenType layout", "Stylistic Set 7") },
{ MAKE_TAG('s','s','0','8'), NC_("OpenType layout", "Stylistic Set 8") },
{ MAKE_TAG('s','s','0','9'), NC_("OpenType layout", "Stylistic Set 9") },
{ MAKE_TAG('s','s','1','0'), NC_("OpenType layout", "Stylistic Set 10") },
{ MAKE_TAG('s','s','1','1'), NC_("OpenType layout", "Stylistic Set 11") },
{ MAKE_TAG('s','s','1','2'), NC_("OpenType layout", "Stylistic Set 12") },
{ MAKE_TAG('s','s','1','3'), NC_("OpenType layout", "Stylistic Set 13") },
{ MAKE_TAG('s','s','1','4'), NC_("OpenType layout", "Stylistic Set 14") },
{ MAKE_TAG('s','s','1','5'), NC_("OpenType layout", "Stylistic Set 15") },
{ MAKE_TAG('s','s','1','6'), NC_("OpenType layout", "Stylistic Set 16") },
{ MAKE_TAG('s','s','1','7'), NC_("OpenType layout", "Stylistic Set 17") },
{ MAKE_TAG('s','s','1','8'), NC_("OpenType layout", "Stylistic Set 18") },
{ MAKE_TAG('s','s','1','9'), NC_("OpenType layout", "Stylistic Set 19") },
{ MAKE_TAG('s','s','2','0'), NC_("OpenType layout", "Stylistic Set 20") },
{ MAKE_TAG('s','s','t','y'), NC_("OpenType layout", "Math script style alternates") },
{ MAKE_TAG('s','t','c','h'), NC_("OpenType layout", "Stretching Glyph Decomposition") },
{ MAKE_TAG('s','u','b','s'), NC_("OpenType layout", "Subscript") },
{ MAKE_TAG('s','u','p','s'), NC_("OpenType layout", "Superscript") },
{ MAKE_TAG('s','w','s','h'), NC_("OpenType layout", "Swash") },
{ MAKE_TAG('t','i','t','l'), NC_("OpenType layout", "Titling") },
{ MAKE_TAG('t','j','m','o'), NC_("OpenType layout", "Trailing Jamo Forms") },
{ MAKE_TAG('t','n','a','m'), NC_("OpenType layout", "Traditional Name Forms") },
{ MAKE_TAG('t','n','u','m'), NC_("OpenType layout", "Tabular Figures") },
{ MAKE_TAG('t','r','a','d'), NC_("OpenType layout", "Traditional Forms") },
{ MAKE_TAG('t','w','i','d'), NC_("OpenType layout", "Third Widths") },
{ MAKE_TAG('u','n','i','c'), NC_("OpenType layout", "Unicase") },
{ MAKE_TAG('v','a','l','t'), NC_("OpenType layout", "Alternate Vertical Metrics") },
{ MAKE_TAG('v','a','t','u'), NC_("OpenType layout", "Vattu Variants") },
{ MAKE_TAG('v','e','r','t'), NC_("OpenType layout", "Vertical Writing") },
{ MAKE_TAG('v','h','a','l'), NC_("OpenType layout", "Alternate Vertical Half Metrics") },
{ MAKE_TAG('v','j','m','o'), NC_("OpenType layout", "Vowel Jamo Forms") },
{ MAKE_TAG('v','k','n','a'), NC_("OpenType layout", "Vertical Kana Alternates") },
{ MAKE_TAG('v','k','r','n'), NC_("OpenType layout", "Vertical Kerning") },
{ MAKE_TAG('v','p','a','l'), NC_("OpenType layout", "Proportional Alternate Vertical Metrics") },
{ MAKE_TAG('v','r','t','2'), NC_("OpenType layout", "Vertical Alternates and Rotation") },
{ MAKE_TAG('v','r','t','r'), NC_("OpenType layout", "Vertical Alternates for Rotation") },
{ MAKE_TAG('z','e','r','o'), NC_("OpenType layout", "Slashed Zero") },
};
#undef MAKE_TAG

View File

@@ -0,0 +1,184 @@
#include "config.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <hb-ot.h>
#include "script-names.h"
static struct {
GUnicodeScript script;
hb_script_t hb_script;
const char *name;
} scripts[] =
{
{ G_UNICODE_SCRIPT_COMMON, HB_SCRIPT_COMMON, NULL },
{ G_UNICODE_SCRIPT_INHERITED, HB_SCRIPT_INHERITED, NULL },
{ G_UNICODE_SCRIPT_ARABIC, HB_SCRIPT_ARABIC, NC_("Script", "Arabic") },
{ G_UNICODE_SCRIPT_ARMENIAN, HB_SCRIPT_ARMENIAN, NC_("Script", "Armenian") },
{ G_UNICODE_SCRIPT_BENGALI, HB_SCRIPT_BENGALI, NC_("Script", "Bengali") },
{ G_UNICODE_SCRIPT_BOPOMOFO, HB_SCRIPT_BOPOMOFO, NC_("Script", "Bopomofo") },
{ G_UNICODE_SCRIPT_CHEROKEE, HB_SCRIPT_CHEROKEE, NC_("Script", "Cherokee") },
{ G_UNICODE_SCRIPT_COPTIC, HB_SCRIPT_COPTIC, NC_("Script", "Coptic") },
{ G_UNICODE_SCRIPT_CYRILLIC, HB_SCRIPT_CYRILLIC, NC_("Script", "Cyrillic") },
{ G_UNICODE_SCRIPT_DESERET, HB_SCRIPT_DESERET, NC_("Script", "Deseret") },
{ G_UNICODE_SCRIPT_DEVANAGARI, HB_SCRIPT_DEVANAGARI, NC_("Script", "Devanagari") },
{ G_UNICODE_SCRIPT_ETHIOPIC, HB_SCRIPT_ETHIOPIC, NC_("Script", "Ethiopic") },
{ G_UNICODE_SCRIPT_GEORGIAN, HB_SCRIPT_GEORGIAN, NC_("Script", "Georgian") },
{ G_UNICODE_SCRIPT_GOTHIC, HB_SCRIPT_GOTHIC, NC_("Script", "Gothic") },
{ G_UNICODE_SCRIPT_GREEK, HB_SCRIPT_GREEK, NC_("Script", "Greek") },
{ G_UNICODE_SCRIPT_GUJARATI, HB_SCRIPT_GUJARATI, NC_("Script", "Gujarati") },
{ G_UNICODE_SCRIPT_GURMUKHI, HB_SCRIPT_GURMUKHI, NC_("Script", "Gurmukhi") },
{ G_UNICODE_SCRIPT_HAN, HB_SCRIPT_HAN, NC_("Script", "Han") },
{ G_UNICODE_SCRIPT_HANGUL, HB_SCRIPT_HANGUL, NC_("Script", "Hangul") },
{ G_UNICODE_SCRIPT_HEBREW, HB_SCRIPT_HEBREW, NC_("Script", "Hebrew") },
{ G_UNICODE_SCRIPT_HIRAGANA, HB_SCRIPT_HIRAGANA, NC_("Script", "Hiragana") },
{ G_UNICODE_SCRIPT_KANNADA, HB_SCRIPT_KANNADA, NC_("Script", "Kannada") },
{ G_UNICODE_SCRIPT_KATAKANA, HB_SCRIPT_KATAKANA, NC_("Script", "Katakana") },
{ G_UNICODE_SCRIPT_KHMER, HB_SCRIPT_KHMER, NC_("Script", "Khmer") },
{ G_UNICODE_SCRIPT_LAO, HB_SCRIPT_LAO, NC_("Script", "Lao") },
{ G_UNICODE_SCRIPT_LATIN, HB_SCRIPT_LATIN, NC_("Script", "Latin") },
{ G_UNICODE_SCRIPT_MALAYALAM, HB_SCRIPT_MALAYALAM, NC_("Script", "Malayalam") },
{ G_UNICODE_SCRIPT_MONGOLIAN, HB_SCRIPT_MONGOLIAN, NC_("Script", "Mongolian") },
{ G_UNICODE_SCRIPT_MYANMAR, HB_SCRIPT_MYANMAR, NC_("Script", "Myanmar") },
{ G_UNICODE_SCRIPT_OGHAM, HB_SCRIPT_OGHAM, NC_("Script", "Ogham") },
{ G_UNICODE_SCRIPT_OLD_ITALIC, HB_SCRIPT_OLD_ITALIC, NC_("Script", "Old Italic") },
{ G_UNICODE_SCRIPT_ORIYA, HB_SCRIPT_ORIYA, NC_("Script", "Oriya") },
{ G_UNICODE_SCRIPT_RUNIC, HB_SCRIPT_RUNIC, NC_("Script", "Runic") },
{ G_UNICODE_SCRIPT_SINHALA, HB_SCRIPT_SINHALA, NC_("Script", "Sinhala") },
{ G_UNICODE_SCRIPT_SYRIAC, HB_SCRIPT_SYRIAC, NC_("Script", "Syriac") },
{ G_UNICODE_SCRIPT_TAMIL, HB_SCRIPT_TAMIL, NC_("Script", "Tamil") },
{ G_UNICODE_SCRIPT_TELUGU, HB_SCRIPT_TELUGU, NC_("Script", "Telugu") },
{ G_UNICODE_SCRIPT_THAANA, HB_SCRIPT_THAANA, NC_("Script", "Thaana") },
{ G_UNICODE_SCRIPT_THAI, HB_SCRIPT_THAI, NC_("Script", "Thai") },
{ G_UNICODE_SCRIPT_TIBETAN, HB_SCRIPT_TIBETAN, NC_("Script", "Tibetan") },
{ G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, HB_SCRIPT_CANADIAN_ABORIGINAL, NC_("Script", "Canadian Aboriginal") },
{ G_UNICODE_SCRIPT_YI, HB_SCRIPT_YI, NC_("Script", "Yi") },
{ G_UNICODE_SCRIPT_TAGALOG, HB_SCRIPT_TAGALOG, NC_("Script", "Tagalog") },
{ G_UNICODE_SCRIPT_HANUNOO, HB_SCRIPT_HANUNOO, NC_("Script", "Hanunoo") },
{ G_UNICODE_SCRIPT_BUHID, HB_SCRIPT_BUHID, NC_("Script", "Buhid") },
{ G_UNICODE_SCRIPT_TAGBANWA, HB_SCRIPT_TAGBANWA, NC_("Script", "Tagbanwa") },
{ G_UNICODE_SCRIPT_BRAILLE, HB_SCRIPT_BRAILLE, NC_("Script", "Braille") },
{ G_UNICODE_SCRIPT_CYPRIOT, HB_SCRIPT_CYPRIOT, NC_("Script", "Cypriot") },
{ G_UNICODE_SCRIPT_LIMBU, HB_SCRIPT_LIMBU, NC_("Script", "Limbu") },
{ G_UNICODE_SCRIPT_OSMANYA, HB_SCRIPT_OSMANYA, NC_("Script", "Osmanya") },
{ G_UNICODE_SCRIPT_SHAVIAN, HB_SCRIPT_SHAVIAN, NC_("Script", "Shavian") },
{ G_UNICODE_SCRIPT_LINEAR_B, HB_SCRIPT_LINEAR_B, NC_("Script", "Linear B") },
{ G_UNICODE_SCRIPT_TAI_LE, HB_SCRIPT_TAI_LE, NC_("Script", "Tai Le") },
{ G_UNICODE_SCRIPT_UGARITIC, HB_SCRIPT_UGARITIC, NC_("Script", "Ugaritic") },
{ G_UNICODE_SCRIPT_NEW_TAI_LUE, HB_SCRIPT_NEW_TAI_LUE, NC_("Script", "New Tai Lue") },
{ G_UNICODE_SCRIPT_BUGINESE, HB_SCRIPT_BUGINESE, NC_("Script", "Buginese") },
{ G_UNICODE_SCRIPT_GLAGOLITIC, HB_SCRIPT_GLAGOLITIC, NC_("Script", "Glagolitic") },
{ G_UNICODE_SCRIPT_TIFINAGH, HB_SCRIPT_TIFINAGH, NC_("Script", "Tifinagh") },
{ G_UNICODE_SCRIPT_SYLOTI_NAGRI, HB_SCRIPT_SYLOTI_NAGRI, NC_("Script", "Syloti Nagri") },
{ G_UNICODE_SCRIPT_OLD_PERSIAN, HB_SCRIPT_OLD_PERSIAN, NC_("Script", "Old Persian") },
{ G_UNICODE_SCRIPT_KHAROSHTHI, HB_SCRIPT_KHAROSHTHI, NC_("Script", "Kharoshthi") },
{ G_UNICODE_SCRIPT_UNKNOWN, HB_SCRIPT_UNKNOWN, NC_("Script", "Unknown") },
{ G_UNICODE_SCRIPT_BALINESE, HB_SCRIPT_BALINESE, NC_("Script", "Balinese") },
{ G_UNICODE_SCRIPT_CUNEIFORM, HB_SCRIPT_CUNEIFORM, NC_("Script", "Cuneiform") },
{ G_UNICODE_SCRIPT_PHOENICIAN, HB_SCRIPT_PHOENICIAN, NC_("Script", "Phoenician") },
{ G_UNICODE_SCRIPT_PHAGS_PA, HB_SCRIPT_PHAGS_PA, NC_("Script", "Phags-pa") },
{ G_UNICODE_SCRIPT_NKO, HB_SCRIPT_NKO, NC_("Script", "N'Ko") },
{ G_UNICODE_SCRIPT_KAYAH_LI, HB_SCRIPT_KAYAH_LI, NC_("Script", "Kayah Li") },
{ G_UNICODE_SCRIPT_LEPCHA, HB_SCRIPT_LEPCHA, NC_("Script", "Lepcha") },
{ G_UNICODE_SCRIPT_REJANG, HB_SCRIPT_REJANG, NC_("Script", "Rejang") },
{ G_UNICODE_SCRIPT_SUNDANESE, HB_SCRIPT_SUNDANESE, NC_("Script", "Sundanese") },
{ G_UNICODE_SCRIPT_SAURASHTRA, HB_SCRIPT_SAURASHTRA, NC_("Script", "Saurashtra") },
{ G_UNICODE_SCRIPT_CHAM, HB_SCRIPT_CHAM, NC_("Script", "Cham") },
{ G_UNICODE_SCRIPT_OL_CHIKI, HB_SCRIPT_OL_CHIKI, NC_("Script", "Ol Chiki") },
{ G_UNICODE_SCRIPT_VAI, HB_SCRIPT_VAI, NC_("Script", "Vai") },
{ G_UNICODE_SCRIPT_CARIAN, HB_SCRIPT_CARIAN, NC_("Script", "Carian") },
{ G_UNICODE_SCRIPT_LYCIAN, HB_SCRIPT_LYCIAN, NC_("Script", "Lycian") },
{ G_UNICODE_SCRIPT_LYDIAN, HB_SCRIPT_LYDIAN, NC_("Script", "Lydian") },
{ G_UNICODE_SCRIPT_AVESTAN, HB_SCRIPT_AVESTAN, NC_("Script", "Avestan") },
{ G_UNICODE_SCRIPT_BAMUM, HB_SCRIPT_BAMUM, NC_("Script", "Bamum") },
{ G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS, HB_SCRIPT_EGYPTIAN_HIEROGLYPHS, NC_("Script", "Egyptian Hieroglpyhs") },
{ G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC, HB_SCRIPT_IMPERIAL_ARAMAIC, NC_("Script", "Imperial Aramaic") },
{ G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI, HB_SCRIPT_INSCRIPTIONAL_PAHLAVI, NC_("Script", "Inscriptional Pahlavi") },
{ G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN, HB_SCRIPT_INSCRIPTIONAL_PARTHIAN, NC_("Script", "Inscriptional Parthian") },
{ G_UNICODE_SCRIPT_JAVANESE, HB_SCRIPT_JAVANESE, NC_("Script", "Javanese") },
{ G_UNICODE_SCRIPT_KAITHI, HB_SCRIPT_KAITHI, NC_("Script", "Kaithi") },
{ G_UNICODE_SCRIPT_LISU, HB_SCRIPT_LISU, NC_("Script", "Lisu") },
{ G_UNICODE_SCRIPT_MEETEI_MAYEK, HB_SCRIPT_MEETEI_MAYEK, NC_("Script", "Meetei Mayek") },
{ G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN, HB_SCRIPT_OLD_SOUTH_ARABIAN, NC_("Script", "Old South Arabian") },
{ G_UNICODE_SCRIPT_OLD_TURKIC, HB_SCRIPT_OLD_TURKIC, NC_("Script", "Old Turkic") },
{ G_UNICODE_SCRIPT_SAMARITAN, HB_SCRIPT_SAMARITAN, NC_("Script", "Samaritan") },
{ G_UNICODE_SCRIPT_TAI_THAM, HB_SCRIPT_TAI_THAM, NC_("Script", "Tai Tham") },
{ G_UNICODE_SCRIPT_TAI_VIET, HB_SCRIPT_TAI_VIET, NC_("Script", "Tai Viet") },
{ G_UNICODE_SCRIPT_BATAK, HB_SCRIPT_BATAK, NC_("Script", "Batak") },
{ G_UNICODE_SCRIPT_BRAHMI, HB_SCRIPT_BRAHMI, NC_("Script", "Brahmi") },
{ G_UNICODE_SCRIPT_MANDAIC, HB_SCRIPT_MANDAIC, NC_("Script", "Mandaic") },
{ G_UNICODE_SCRIPT_CHAKMA, HB_SCRIPT_CHAKMA, NC_("Script", "Chakma") },
{ G_UNICODE_SCRIPT_MEROITIC_CURSIVE, HB_SCRIPT_MEROITIC_CURSIVE, NC_("Script", "Meroitic Cursive") },
{ G_UNICODE_SCRIPT_MEROITIC_HIEROGLYPHS, HB_SCRIPT_MEROITIC_HIEROGLYPHS, NC_("Script", "Meroitic Hieroglyphs") },
{ G_UNICODE_SCRIPT_MIAO, HB_SCRIPT_MIAO, NC_("Script", "Miao") },
{ G_UNICODE_SCRIPT_SHARADA, HB_SCRIPT_SHARADA, NC_("Script", "Sharada") },
{ G_UNICODE_SCRIPT_SORA_SOMPENG, HB_SCRIPT_SORA_SOMPENG, NC_("Script", "Sora Sompeng") },
{ G_UNICODE_SCRIPT_TAKRI, HB_SCRIPT_TAKRI, NC_("Script", "Takri") },
{ G_UNICODE_SCRIPT_BASSA_VAH, HB_SCRIPT_BASSA_VAH, NC_("Script", "Bassa") },
{ G_UNICODE_SCRIPT_CAUCASIAN_ALBANIAN, HB_SCRIPT_CAUCASIAN_ALBANIAN, NC_("Script", "Caucasian Albanian") },
{ G_UNICODE_SCRIPT_DUPLOYAN, HB_SCRIPT_DUPLOYAN, NC_("Script", "Duployan") },
{ G_UNICODE_SCRIPT_ELBASAN, HB_SCRIPT_ELBASAN, NC_("Script", "Elbasan") },
{ G_UNICODE_SCRIPT_GRANTHA, HB_SCRIPT_GRANTHA, NC_("Script", "Grantha") },
{ G_UNICODE_SCRIPT_KHOJKI, HB_SCRIPT_KHOJKI, NC_("Script", "Kjohki") },
{ G_UNICODE_SCRIPT_KHUDAWADI, HB_SCRIPT_KHUDAWADI, NC_("Script", "Khudawadi, Sindhi") },
{ G_UNICODE_SCRIPT_LINEAR_A, HB_SCRIPT_LINEAR_A, NC_("Script", "Linear A") },
{ G_UNICODE_SCRIPT_MAHAJANI, HB_SCRIPT_MAHAJANI, NC_("Script", "Mahajani") },
{ G_UNICODE_SCRIPT_MANICHAEAN, HB_SCRIPT_MANICHAEAN, NC_("Script", "Manichaean") },
{ G_UNICODE_SCRIPT_MENDE_KIKAKUI, HB_SCRIPT_MENDE_KIKAKUI, NC_("Script", "Mende Kikakui") },
{ G_UNICODE_SCRIPT_MODI, HB_SCRIPT_MODI, NC_("Script", "Modi") },
{ G_UNICODE_SCRIPT_MRO, HB_SCRIPT_MRO, NC_("Script", "Mro") },
{ G_UNICODE_SCRIPT_NABATAEAN, HB_SCRIPT_NABATAEAN, NC_("Script", "Nabataean") },
{ G_UNICODE_SCRIPT_OLD_NORTH_ARABIAN, HB_SCRIPT_OLD_NORTH_ARABIAN, NC_("Script", "Old North Arabian") },
{ G_UNICODE_SCRIPT_OLD_PERMIC, HB_SCRIPT_OLD_PERMIC, NC_("Script", "Old Permic") },
{ G_UNICODE_SCRIPT_PAHAWH_HMONG, HB_SCRIPT_PAHAWH_HMONG, NC_("Script", "Pahawh Hmong") },
{ G_UNICODE_SCRIPT_PALMYRENE, HB_SCRIPT_PALMYRENE, NC_("Script", "Palmyrene") },
{ G_UNICODE_SCRIPT_PAU_CIN_HAU, HB_SCRIPT_PAU_CIN_HAU, NC_("Script", "Pau Cin Hau") },
{ G_UNICODE_SCRIPT_PSALTER_PAHLAVI, HB_SCRIPT_PSALTER_PAHLAVI, NC_("Script", "Psalter Pahlavi") },
{ G_UNICODE_SCRIPT_SIDDHAM, HB_SCRIPT_SIDDHAM, NC_("Script", "Siddham") },
{ G_UNICODE_SCRIPT_TIRHUTA, HB_SCRIPT_TIRHUTA, NC_("Script", "Tirhuta") },
{ G_UNICODE_SCRIPT_WARANG_CITI, HB_SCRIPT_WARANG_CITI, NC_("Script", "Warang Citi") },
{ G_UNICODE_SCRIPT_AHOM, HB_SCRIPT_AHOM, NC_("Script", "Ahom") },
{ G_UNICODE_SCRIPT_ANATOLIAN_HIEROGLYPHS, HB_SCRIPT_ANATOLIAN_HIEROGLYPHS, NC_("Script", "Anatolian Hieroglyphs") },
{ G_UNICODE_SCRIPT_HATRAN, HB_SCRIPT_HATRAN, NC_("Script", "Hatran") },
{ G_UNICODE_SCRIPT_MULTANI, HB_SCRIPT_MULTANI, NC_("Script", "Multani") },
{ G_UNICODE_SCRIPT_OLD_HUNGARIAN, HB_SCRIPT_OLD_HUNGARIAN, NC_("Script", "Old Hungarian") },
{ G_UNICODE_SCRIPT_SIGNWRITING, HB_SCRIPT_SIGNWRITING, NC_("Script", "Signwriting") },
{ G_UNICODE_SCRIPT_ADLAM, HB_SCRIPT_ADLAM, NC_("Script", "Adlam") },
{ G_UNICODE_SCRIPT_BHAIKSUKI, HB_SCRIPT_BHAIKSUKI, NC_("Script", "Bhaiksuki") },
{ G_UNICODE_SCRIPT_MARCHEN, HB_SCRIPT_MARCHEN, NC_("Script", "Marchen") },
{ G_UNICODE_SCRIPT_NEWA, HB_SCRIPT_NEWA, NC_("Script", "Newa") },
{ G_UNICODE_SCRIPT_OSAGE, HB_SCRIPT_OSAGE, NC_("Script", "Osage") },
{ G_UNICODE_SCRIPT_TANGUT, HB_SCRIPT_TANGUT, NC_("Script", "Tangut") },
{ G_UNICODE_SCRIPT_MASARAM_GONDI, HB_SCRIPT_INVALID, NC_("Script", "Masaram Gondi") },
{ G_UNICODE_SCRIPT_NUSHU, HB_SCRIPT_INVALID, NC_("Script", "Nushu") },
{ G_UNICODE_SCRIPT_SOYOMBO, HB_SCRIPT_INVALID, NC_("Script", "Soyombo") },
{ G_UNICODE_SCRIPT_ZANABAZAR_SQUARE, HB_SCRIPT_INVALID, NC_("Script", "Zanabazar Square") },
};
const char *
get_script_name (GUnicodeScript script)
{
int i;
for (i = 0; i < G_N_ELEMENTS (scripts); i++)
{
if (scripts[i].script == script)
return g_dpgettext2 (GETTEXT_PACKAGE, "Script", scripts[i].name);
}
return NULL;
}
const char *
get_script_name_for_tag (guint32 tag)
{
int i;
for (i = 0; i < G_N_ELEMENTS (scripts); i++)
{
if (scripts[i].hb_script == hb_script_from_iso15924_tag (tag))
return g_dpgettext2 (GETTEXT_PACKAGE, "Script", scripts[i].name);
}
return NULL;
}

View File

@@ -0,0 +1,13 @@
#ifndef SCRIPT_NAMES_H
#define SCRIPT_NAMES_H
#include <glib.h>
G_BEGIN_DECLS
const char * get_script_name (GUnicodeScript script);
const char * get_script_name_for_tag (guint32 tag);
G_END_DECLS
#endif

View File

@@ -322,6 +322,15 @@ We use <literallayout> for syntax productions, and each line is put in a <code>
<entry><ulink url="https://www.w3.org/TR/css3-fonts/#font-feature-settings-prop">CSS3</ulink></entry>
<entry></entry>
</row>
<row>
<entry><phrase role="nowrap">font-variation-settings</phrase></entry>
<entry><code>normal | [ 〈string〉〈number〉]&num;</code></entry>
<entry>normal</entry>
<entry></entry>
<entry></entry>
<entry><ulink url="https://www.w3.org/TR/css-fonts-4/#font-variation-settings-def">CSS4</ulink></entry>
<entry></entry>
</row>
</tbody>
</tgroup>
<tgroup cols="5">

View File

@@ -1276,10 +1276,6 @@ gtk_font_button_new
gtk_font_button_new_with_font
gtk_font_button_set_font_name
gtk_font_button_get_font_name
gtk_font_button_set_show_style
gtk_font_button_get_show_style
gtk_font_button_set_show_size
gtk_font_button_get_show_size
gtk_font_button_set_use_font
gtk_font_button_get_use_font
gtk_font_button_set_use_size
@@ -1313,6 +1309,9 @@ gtk_font_chooser_get_preview_text
gtk_font_chooser_set_preview_text
gtk_font_chooser_get_show_preview_entry
gtk_font_chooser_set_show_preview_entry
GtkFontChooserLevel
gtk_font_chooser_get_level
gtk_font_chooser_set_level
GtkFontFilterFunc
gtk_font_chooser_set_filter_func
gtk_font_chooser_set_font_map

View File

@@ -0,0 +1,294 @@
/* GTK - The GIMP Toolkit
* Copyright (C) 2017 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Matthias Clasen
*/
#include "config.h"
#include "gtkcssparserprivate.h"
#include "gtkcssnumbervalueprivate.h"
#include "gtkcssfontvariationsvalueprivate.h"
struct _GtkCssValue {
GTK_CSS_VALUE_BASE
GHashTable *axes;
};
static GtkCssValue *default_font_variations;
static GtkCssValue *gtk_css_font_variations_value_new_empty (void);
static void
gtk_css_font_variations_value_add_axis (GtkCssValue *value,
const char *name,
GtkCssValue *coord)
{
g_hash_table_insert (value->axes, g_strdup (name), coord);
}
static void
gtk_css_value_font_variations_free (GtkCssValue *value)
{
g_hash_table_unref (value->axes);
g_slice_free (GtkCssValue, value);
}
static GtkCssValue *
gtk_css_value_font_variations_compute (GtkCssValue *specified,
guint property_id,
GtkStyleProvider *provider,
GtkCssStyle *style,
GtkCssStyle *parent_style)
{
GHashTableIter iter;
gpointer name, coord;
GtkCssValue *computed_coord;
GtkCssValue *result;
gboolean changes = FALSE;
result = gtk_css_font_variations_value_new_empty ();
g_hash_table_iter_init (&iter, specified->axes);
while (g_hash_table_iter_next (&iter, &name, &coord))
{
computed_coord = _gtk_css_value_compute (coord, property_id, provider, style, parent_style);
changes |= computed_coord != coord;
gtk_css_font_variations_value_add_axis (result, name, computed_coord);
}
if (!changes)
{
_gtk_css_value_unref (result);
result = _gtk_css_value_ref (specified);
}
return result;
}
static gboolean
gtk_css_value_font_variations_equal (const GtkCssValue *value1,
const GtkCssValue *value2)
{
gpointer name, coord1, coord2;
GHashTableIter iter;
if (g_hash_table_size (value1->axes) != g_hash_table_size (value2->axes))
return FALSE;
g_hash_table_iter_init (&iter, value1->axes);
while (g_hash_table_iter_next (&iter, &name, &coord1))
{
coord2 = g_hash_table_lookup (value2->axes, name);
if (coord2 == NULL)
return FALSE;
if (!_gtk_css_value_equal (coord1, coord2))
return FALSE;
}
return TRUE;
}
static GtkCssValue *
gtk_css_value_font_variations_transition (GtkCssValue *start,
GtkCssValue *end,
guint property_id,
double progress)
{
const char *name;
GtkCssValue *start_coord, *end_coord;
GHashTableIter iter;
GtkCssValue *result, *transition;
/* XXX: For value that are only in start or end but not both,
* we don't transition but just keep the value.
* That causes an abrupt transition to the new value at the end.
*/
result = gtk_css_font_variations_value_new_empty ();
g_hash_table_iter_init (&iter, start->axes);
while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&start_coord))
{
end_coord = g_hash_table_lookup (end->axes, name);
if (end_coord == NULL)
transition = _gtk_css_value_ref (start_coord);
else
transition = _gtk_css_value_transition (start_coord, end_coord, property_id, progress);
gtk_css_font_variations_value_add_axis (result, name, transition);
}
g_hash_table_iter_init (&iter, end->axes);
while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&end_coord))
{
start_coord = g_hash_table_lookup (start->axes, name);
if (start_coord != NULL)
continue;
gtk_css_font_variations_value_add_axis (result, name, _gtk_css_value_ref (end_coord));
}
return result;
}
static void
gtk_css_value_font_variations_print (const GtkCssValue *value,
GString *string)
{
GHashTableIter iter;
const char *name;
GtkCssValue *coord;
gboolean first = TRUE;
if (value == default_font_variations)
{
g_string_append (string, "normal");
return;
}
g_hash_table_iter_init (&iter, value->axes);
while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&coord))
{
if (first)
first = FALSE;
else
g_string_append (string, ", ");
g_string_append_printf (string, "\"%s\" ", name);
_gtk_css_value_print (coord, string);
}
}
static const GtkCssValueClass GTK_CSS_VALUE_FONT_VARIATIONS = {
gtk_css_value_font_variations_free,
gtk_css_value_font_variations_compute,
gtk_css_value_font_variations_equal,
gtk_css_value_font_variations_transition,
gtk_css_value_font_variations_print
};
static GtkCssValue *
gtk_css_font_variations_value_new_empty (void)
{
GtkCssValue *result;
result = _gtk_css_value_new (GtkCssValue, &GTK_CSS_VALUE_FONT_VARIATIONS);
result->axes = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free,
(GDestroyNotify) _gtk_css_value_unref);
return result;
}
GtkCssValue *
gtk_css_font_variations_value_new_default (void)
{
if (default_font_variations == NULL)
default_font_variations = gtk_css_font_variations_value_new_empty ();
return _gtk_css_value_ref (default_font_variations);
}
static gboolean
is_valid_opentype_tag (const char *s)
{
if (strlen (s) != 4)
return FALSE;
if (s[0] < 0x20 || s[0] > 0x7e ||
s[1] < 0x20 || s[1] > 0x7e ||
s[2] < 0x20 || s[2] > 0x7e ||
s[3] < 0x20 || s[3] > 0x7e)
return FALSE;
return TRUE;
}
GtkCssValue *
gtk_css_font_variations_value_parse (GtkCssParser *parser)
{
GtkCssValue *result, *coord;
char *name;
if (_gtk_css_parser_try (parser, "normal", TRUE))
return gtk_css_font_variations_value_new_default ();
result = gtk_css_font_variations_value_new_empty ();
do {
_gtk_css_parser_skip_whitespace (parser);
name = _gtk_css_parser_read_string (parser);
if (name == NULL)
{
_gtk_css_value_unref (result);
return NULL;
}
if (!is_valid_opentype_tag (name))
{
_gtk_css_parser_error (parser, "Not a valid OpenType tag.");
g_free (name);
_gtk_css_value_unref (result);
return NULL;
}
coord = _gtk_css_number_value_parse (parser, GTK_CSS_PARSE_NUMBER);
if (coord == NULL)
{
g_free (name);
_gtk_css_value_unref (result);
return NULL;
}
gtk_css_font_variations_value_add_axis (result, name, coord);
g_free (name);
} while (_gtk_css_parser_try (parser, ",", TRUE));
return result;
}
char *
gtk_css_font_variations_value_get_variations (GtkCssValue *value)
{
GtkCssValue *coord;
GHashTableIter iter;
gboolean first = TRUE;
const char *name;
GString *string;
g_return_val_if_fail (value->class == &GTK_CSS_VALUE_FONT_VARIATIONS, NULL);
if (value == default_font_variations)
return NULL;
string = g_string_new ("");
g_hash_table_iter_init (&iter, value->axes);
while (g_hash_table_iter_next (&iter, (gpointer *)&name, (gpointer *)&coord))
{
if (first)
first = FALSE;
else
g_string_append (string, ",");
g_string_append_printf (string, "%s=%g", name,
_gtk_css_number_value_get (coord, 100));
}
return g_string_free (string, FALSE);
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright © 2017 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Matthias Clasen
*/
#ifndef __GTK_CSS_FONT_VARIATIONS_VALUE_PRIVATE_H__
#define __GTK_CSS_FONT_VARIATIONS_PRIVATE_H__
#include "gtkcssparserprivate.h"
#include "gtkcssvalueprivate.h"
G_BEGIN_DECLS
GtkCssValue * gtk_css_font_variations_value_new_default (void);
GtkCssValue * gtk_css_font_variations_value_parse (GtkCssParser *parser);
char * gtk_css_font_variations_value_get_variations (GtkCssValue *value);
G_END_DECLS
#endif /* __GTK_CSS_FONT_VARIATIONS_VALUE_PRIVATE_H__ */

View File

@@ -59,6 +59,7 @@
#include "gtkcssshadowsvalueprivate.h"
#include "gtkcssstringvalueprivate.h"
#include "gtkcsstransformvalueprivate.h"
#include "gtkcssfontvariationsvalueprivate.h"
#include "gtktypebuiltins.h"
/*** REGISTRATION ***/
@@ -664,6 +665,13 @@ parse_font_feature_settings (GtkCssStyleProperty *property,
return gtk_css_font_features_value_parse (parser);
}
static GtkCssValue *
parse_font_variation_settings (GtkCssStyleProperty *property,
GtkCssParser *parser)
{
return gtk_css_font_variations_value_parse (parser);
}
static GtkCssValue *
box_shadow_value_parse (GtkCssStyleProperty *property,
GtkCssParser *parser)
@@ -1816,4 +1824,12 @@ _gtk_css_style_property_init_properties (void)
parse_font_feature_settings,
NULL,
gtk_css_font_features_value_new_default ());
gtk_css_style_property_register ("font-variation-settings",
GTK_CSS_PROPERTY_FONT_VARIATION_SETTINGS,
G_TYPE_NONE,
GTK_STYLE_PROPERTY_INHERIT | GTK_STYLE_PROPERTY_ANIMATED,
GTK_CSS_AFFECTS_TEXT_ATTRS | GTK_CSS_AFFECTS_TEXT_SIZE,
parse_font_variation_settings,
NULL,
gtk_css_font_variations_value_new_default ());
}

View File

@@ -245,6 +245,7 @@ enum { /*< skip >*/
GTK_CSS_PROPERTY_CARET_COLOR,
GTK_CSS_PROPERTY_SECONDARY_CARET_COLOR,
GTK_CSS_PROPERTY_FONT_FEATURE_SETTINGS,
GTK_CSS_PROPERTY_FONT_VARIATION_SETTINGS,
/* add more */
GTK_CSS_PROPERTY_N_PROPERTIES
};

View File

@@ -70,8 +70,6 @@ struct _GtkFontButtonPrivate
guint use_font : 1;
guint use_size : 1;
guint show_style : 1;
guint show_size : 1;
guint show_preview_entry : 1;
GtkWidget *button;
@@ -90,6 +88,8 @@ struct _GtkFontButtonPrivate
gpointer font_filter_data;
GDestroyNotify font_filter_data_destroy;
GtkCssProvider *provider;
GtkFontChooserLevel level;
};
/* Signals */
@@ -104,9 +104,7 @@ enum
PROP_0,
PROP_TITLE,
PROP_USE_FONT,
PROP_USE_SIZE,
PROP_SHOW_STYLE,
PROP_SHOW_SIZE
PROP_USE_SIZE
};
/* Prototypes */
@@ -137,6 +135,10 @@ static void gtk_font_button_update_font_info (GtkFontButton *gfs);
static void gtk_font_button_set_font_name (GtkFontButton *button,
const char *fontname);
static const char *gtk_font_button_get_font_name (GtkFontButton *button);
static void gtk_font_button_set_level (GtkFontButton *font_button,
GtkFontChooserLevel level);
static char *gtk_font_button_get_font_features (GtkFontButton *button);
static char *gtk_font_button_get_language (GtkFontButton *button);
static guint font_button_signals[LAST_SIGNAL] = { 0 };
@@ -543,39 +545,6 @@ gtk_font_button_class_init (GtkFontButtonClass *klass)
FALSE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
/**
* GtkFontButton:show-style:
*
* If this property is set to %TRUE, the name of the selected font style
* will be shown in the label. For a more WYSIWYG way to show the selected
* style, see the ::use-font property.
*
* Since: 2.4
*/
g_object_class_install_property (gobject_class,
PROP_SHOW_STYLE,
g_param_spec_boolean ("show-style",
P_("Show style"),
P_("Whether the selected font style is shown in the label"),
TRUE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
/**
* GtkFontButton:show-size:
*
* If this property is set to %TRUE, the selected font size will be shown
* in the label. For a more WYSIWYG way to show the selected size, see the
* ::use-size property.
*
* Since: 2.4
*/
g_object_class_install_property (gobject_class,
PROP_SHOW_SIZE,
g_param_spec_boolean ("show-size",
P_("Show size"),
P_("Whether selected font size is shown in the label"),
TRUE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
/**
* GtkFontButton::font-set:
* @widget: the object which received the signal.
@@ -633,8 +602,6 @@ gtk_font_button_init (GtkFontButton *font_button)
/* Initialize fields */
font_button->priv->use_font = FALSE;
font_button->priv->use_size = FALSE;
font_button->priv->show_style = TRUE;
font_button->priv->show_size = TRUE;
font_button->priv->show_preview_entry = TRUE;
font_button->priv->font_dialog = NULL;
font_button->priv->font_family = NULL;
@@ -693,6 +660,9 @@ gtk_font_button_set_property (GObject *object,
case GTK_FONT_CHOOSER_PROP_FONT_DESC:
gtk_font_button_take_font_desc (font_button, g_value_dup_boxed (value));
break;
case GTK_FONT_CHOOSER_PROP_LEVEL:
gtk_font_button_set_level (font_button, g_value_get_enum (value));
break;
case GTK_FONT_CHOOSER_PROP_FONT:
gtk_font_button_set_font_name (font_button, g_value_get_string (value));
break;
@@ -702,12 +672,6 @@ gtk_font_button_set_property (GObject *object,
case PROP_USE_SIZE:
gtk_font_button_set_use_size (font_button, g_value_get_boolean (value));
break;
case PROP_SHOW_STYLE:
gtk_font_button_set_show_style (font_button, g_value_get_boolean (value));
break;
case PROP_SHOW_SIZE:
gtk_font_button_set_show_size (font_button, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -721,6 +685,7 @@ gtk_font_button_get_property (GObject *object,
GParamSpec *pspec)
{
GtkFontButton *font_button = GTK_FONT_BUTTON (object);
GtkFontButtonPrivate *priv = font_button->priv;
switch (param_id)
{
@@ -736,21 +701,24 @@ gtk_font_button_get_property (GObject *object,
case GTK_FONT_CHOOSER_PROP_FONT_DESC:
g_value_set_boxed (value, gtk_font_button_get_font_desc (font_button));
break;
case GTK_FONT_CHOOSER_PROP_LEVEL:
g_value_set_enum (value, priv->level);
break;
case GTK_FONT_CHOOSER_PROP_FONT:
g_value_set_string (value, gtk_font_button_get_font_name (font_button));
break;
case GTK_FONT_CHOOSER_PROP_FONT_FEATURES:
g_value_take_string (value, gtk_font_button_get_font_features (font_button));
break;
case GTK_FONT_CHOOSER_PROP_LANGUAGE:
g_value_take_string (value, gtk_font_button_get_language (font_button));
break;
case PROP_USE_FONT:
g_value_set_boolean (value, gtk_font_button_get_use_font (font_button));
break;
case PROP_USE_SIZE:
g_value_set_boolean (value, gtk_font_button_get_use_size (font_button));
break;
case PROP_SHOW_STYLE:
g_value_set_boolean (value, gtk_font_button_get_show_style (font_button));
break;
case PROP_SHOW_SIZE:
g_value_set_boolean (value, gtk_font_button_get_show_size (font_button));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -924,101 +892,6 @@ gtk_font_button_set_use_size (GtkFontButton *font_button,
}
}
/**
* gtk_font_button_get_show_style:
* @font_button: a #GtkFontButton
*
* Returns whether the name of the font style will be shown in the label.
*
* Returns: whether the font style will be shown in the label.
*
* Since: 2.4
**/
gboolean
gtk_font_button_get_show_style (GtkFontButton *font_button)
{
g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
return font_button->priv->show_style;
}
/**
* gtk_font_button_set_show_style:
* @font_button: a #GtkFontButton
* @show_style: %TRUE if font style should be displayed in label.
*
* If @show_style is %TRUE, the font style will be displayed along with name of the selected font.
*
* Since: 2.4
*/
void
gtk_font_button_set_show_style (GtkFontButton *font_button,
gboolean show_style)
{
g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
show_style = (show_style != FALSE);
if (font_button->priv->show_style != show_style)
{
font_button->priv->show_style = show_style;
gtk_font_button_update_font_info (font_button);
g_object_notify (G_OBJECT (font_button), "show-style");
}
}
/**
* gtk_font_button_get_show_size:
* @font_button: a #GtkFontButton
*
* Returns whether the font size will be shown in the label.
*
* Returns: whether the font size will be shown in the label.
*
* Since: 2.4
**/
gboolean
gtk_font_button_get_show_size (GtkFontButton *font_button)
{
g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
return font_button->priv->show_size;
}
/**
* gtk_font_button_set_show_size:
* @font_button: a #GtkFontButton
* @show_size: %TRUE if font size should be displayed in dialog.
*
* If @show_size is %TRUE, the font size will be displayed along with the name of the selected font.
*
* Since: 2.4
*/
void
gtk_font_button_set_show_size (GtkFontButton *font_button,
gboolean show_size)
{
g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
show_size = (show_size != FALSE);
if (font_button->priv->show_size != show_size)
{
font_button->priv->show_size = show_size;
if (font_button->priv->show_size)
gtk_widget_show (font_button->priv->font_size_box);
else
gtk_widget_hide (font_button->priv->font_size_box);
gtk_font_button_update_font_info (font_button);
g_object_notify (G_OBJECT (font_button), "show-size");
}
}
static const gchar *
gtk_font_button_get_font_name (GtkFontButton *font_button)
{
@@ -1056,7 +929,9 @@ gtk_font_button_clicked (GtkButton *button,
if (priv->font_map)
gtk_font_chooser_set_font_map (font_dialog, priv->font_map);
gtk_font_chooser_set_show_preview_entry (font_dialog, priv->show_preview_entry);
gtk_font_chooser_set_level (GTK_FONT_CHOOSER (font_dialog), priv->level);
if (priv->preview_text)
{
@@ -1163,6 +1038,62 @@ dialog_destroy (GtkWidget *widget,
font_button->priv->font_dialog = NULL;
}
static void
add_css_variations (GString *s,
const char *variations)
{
const char *p;
const char *sep = "";
if (variations == NULL || variations[0] == '\0')
{
g_string_append (s, "normal");
return;
}
p = variations;
while (p && *p)
{
const char *start;
const char *end, *end2;
double value;
char name[5];
while (g_ascii_isspace (*p)) p++;
start = p;
end = strchr (p, ',');
if (end && (end - p < 6))
goto skip;
name[0] = p[0];
name[1] = p[1];
name[2] = p[2];
name[3] = p[3];
name[4] = '\0';
p += 4;
while (g_ascii_isspace (*p)) p++;
if (*p == '=') p++;
if (p - start < 5)
goto skip;
value = g_ascii_strtod (p, (char **) &end2);
while (end2 && g_ascii_isspace (*end2)) end2++;
if (end2 && (*end2 != ',' && *end2 != '\0'))
goto skip;
g_string_append_printf (s, "%s\"%s\" %g", sep, name, value);
sep = ", ";
skip:
p = end ? end + 1 : NULL;
}
}
static gchar *
pango_font_description_to_css (PangoFontDescription *desc)
{
@@ -1284,7 +1215,17 @@ pango_font_description_to_css (PangoFontDescription *desc)
}
if (set & PANGO_FONT_MASK_SIZE)
{
g_string_append_printf (s, "font-size: %dpt", pango_font_description_get_size (desc) / PANGO_SCALE);
g_string_append_printf (s, "font-size: %dpt; ", pango_font_description_get_size (desc) / PANGO_SCALE);
}
if (set & PANGO_FONT_MASK_VARIATIONS)
{
const char *variations;
g_string_append (s, "font-variation-settings: ");
variations = pango_font_description_get_variations (desc);
add_css_variations (s, variations);
g_string_append (s, "; ");
}
g_string_append (s, "}");
@@ -1351,25 +1292,71 @@ gtk_font_button_update_font_info (GtkFontButton *font_button)
else
face_name = "";
if (priv->show_style)
family_style = g_strconcat (fam_name, " ", face_name, NULL);
else
if (priv->level == GTK_FONT_CHOOSER_LEVEL_FAMILY)
family_style = g_strdup (fam_name);
else
family_style = g_strconcat (fam_name, " ", face_name, NULL);
gtk_label_set_text (GTK_LABEL (font_button->priv->font_label), family_style);
g_free (family_style);
if (font_button->priv->show_size)
if (priv->level == GTK_FONT_CHOOSER_LEVEL_FONT)
{
/* mirror Pango, which doesn't translate this either */
gchar *size = g_strdup_printf ("%2.4g%s",
pango_font_description_get_size (priv->font_desc) / (double)PANGO_SCALE,
pango_font_description_get_size_is_absolute (priv->font_desc) ? "px" : "");
gtk_label_set_text (GTK_LABEL (font_button->priv->size_label), size);
g_free (size);
gtk_widget_show (font_button->priv->font_size_box);
}
else
gtk_widget_hide (font_button->priv->font_size_box);
gtk_font_button_label_use_font (font_button);
}
}
static void
gtk_font_button_set_level (GtkFontButton *button,
GtkFontChooserLevel level)
{
GtkFontButtonPrivate *priv = button->priv;
if (priv->level == level)
return;
priv->level = level;
if (priv->font_dialog)
gtk_font_chooser_set_level (GTK_FONT_CHOOSER (priv->font_dialog), level);
gtk_font_button_update_font_info (button);
g_object_notify (G_OBJECT (button), "level");
}
static char *
gtk_font_button_get_font_features (GtkFontButton *button)
{
GtkFontButtonPrivate *priv = button->priv;
if (priv->font_dialog)
return gtk_font_chooser_get_font_features (GTK_FONT_CHOOSER (priv->font_dialog));
return NULL;
}
static char *
gtk_font_button_get_language (GtkFontButton *button)
{
GtkFontButtonPrivate *priv = button->priv;
if (priv->font_dialog)
return gtk_font_chooser_get_language (GTK_FONT_CHOOSER (priv->font_dialog));
return NULL;
}

View File

@@ -92,16 +92,6 @@ gboolean gtk_font_button_get_use_size (GtkFontButton *font_button
GDK_AVAILABLE_IN_ALL
void gtk_font_button_set_use_size (GtkFontButton *font_button,
gboolean use_size);
GDK_AVAILABLE_IN_ALL
gboolean gtk_font_button_get_show_style (GtkFontButton *font_button);
GDK_AVAILABLE_IN_ALL
void gtk_font_button_set_show_style (GtkFontButton *font_button,
gboolean show_style);
GDK_AVAILABLE_IN_ALL
gboolean gtk_font_button_get_show_size (GtkFontButton *font_button);
GDK_AVAILABLE_IN_ALL
void gtk_font_button_set_show_size (GtkFontButton *font_button,
gboolean show_size);
G_END_DECLS

View File

@@ -79,6 +79,22 @@ gtk_font_chooser_default_init (GtkFontChooserInterface *iface)
PANGO_TYPE_FONT_DESCRIPTION,
GTK_PARAM_READWRITE));
g_object_interface_install_property
(iface,
g_param_spec_string ("font-features",
P_("Font features"),
P_("Font features as a string"),
"",
GTK_PARAM_READABLE));
g_object_interface_install_property
(iface,
g_param_spec_string ("language",
P_("Language"),
P_("Language for which features have been selected"),
"",
GTK_PARAM_READABLE));
/**
* GtkFontChooser:preview-text:
*
@@ -105,6 +121,22 @@ gtk_font_chooser_default_init (GtkFontChooserInterface *iface)
TRUE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
/**
* GtkFontChooser:level:
*
* The level of granularity to offer for selecting fonts.
*
* Since: 3.94
*/
g_object_interface_install_property
(iface,
g_param_spec_enum ("level",
P_("Selection level"),
P_("Whether to select family, face or font"),
GTK_TYPE_FONT_CHOOSER_LEVEL,
GTK_FONT_CHOOSER_LEVEL_FONT,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
/**
* GtkFontChooser::font-activated:
* @self: the object which received the signal
@@ -481,3 +513,67 @@ gtk_font_chooser_get_font_map (GtkFontChooser *fontchooser)
return fontmap;
}
/**
* gtk_font_chooser_set_level:
* @fontchooser: a #GtkFontChooser
* @level: the desired level of granularity
*
* Sets the desired level of granularity for selecting fonts.
*
* Since: 3.94
*/
void
gtk_font_chooser_set_level (GtkFontChooser *fontchooser,
GtkFontChooserLevel level)
{
g_return_if_fail (GTK_IS_FONT_CHOOSER (fontchooser));
g_object_set (fontchooser, "level", level, NULL);
}
/**
* gtk_font_chooser_get_level:
* @fontchooser: a #GtkFontChooser
*
* Returns the current level of granularity for selecting fonts.
*
* Returns: the current granularity level
* Since: 3.94
*/
GtkFontChooserLevel
gtk_font_chooser_get_level (GtkFontChooser *fontchooser)
{
GtkFontChooserLevel level;
g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), 0);
g_object_get (fontchooser, "level", &level, NULL);
return level;
}
char *
gtk_font_chooser_get_font_features (GtkFontChooser *fontchooser)
{
char *text;
g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
g_object_get (fontchooser, "font-features", &text, NULL);
return text;
}
char *
gtk_font_chooser_get_language (GtkFontChooser *fontchooser)
{
char *text;
g_return_val_if_fail (GTK_IS_FONT_CHOOSER (fontchooser), NULL);
g_object_get (fontchooser, "language", &text, NULL);
return text;
}

View File

@@ -44,6 +44,24 @@ typedef gboolean (*GtkFontFilterFunc) (const PangoFontFamily *family,
const PangoFontFace *face,
gpointer data);
/**
* GtkFontChooserLevel:
* @GTK_FONT_CHOOSER_LEVEL_FONT: Select an individual
* font, including a size. An example would be: "Arial Bold 11"
* @GTK_FONT_CHOOSER_LEVEL_FACE: Select a font face,
* without a size. An example would be: "Arial Bold"
* @GTK_FONT_CHOOSER_LEVEL_FAMILY: Select a font family, without
* specifying the face. An example would be: "Arial"
*
* This enumeration specifies the granularity of font selection
* that is desired in a font chooser.
*/
typedef enum {
GTK_FONT_CHOOSER_LEVEL_FONT,
GTK_FONT_CHOOSER_LEVEL_FACE,
GTK_FONT_CHOOSER_LEVEL_FAMILY
} GtkFontChooserLevel;
#define GTK_TYPE_FONT_CHOOSER (gtk_font_chooser_get_type ())
#define GTK_FONT_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_FONT_CHOOSER, GtkFontChooser))
#define GTK_IS_FONT_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_FONT_CHOOSER))
@@ -122,6 +140,16 @@ void gtk_font_chooser_set_font_map (GtkFontChooser *fo
PangoFontMap *fontmap);
GDK_AVAILABLE_IN_3_18
PangoFontMap * gtk_font_chooser_get_font_map (GtkFontChooser *fontchooser);
GDK_AVAILABLE_IN_3_94
void gtk_font_chooser_set_level (GtkFontChooser *fontchooser,
GtkFontChooserLevel level);
GDK_AVAILABLE_IN_3_94
GtkFontChooserLevel
gtk_font_chooser_get_level (GtkFontChooser *fontchooser);
GDK_AVAILABLE_IN_3_94
char * gtk_font_chooser_get_font_features (GtkFontChooser *fontchooser);
GDK_AVAILABLE_IN_3_94
char * gtk_font_chooser_get_language (GtkFontChooser *fontchooser);
G_END_DECLS

View File

@@ -36,6 +36,9 @@
#include "gtkwidget.h"
#include "gtksettings.h"
#include "gtkdialogprivate.h"
#include "gtktogglebutton.h"
#include "gtkheaderbar.h"
#include "gtkactionable.h"
struct _GtkFontChooserDialogPrivate
{
@@ -43,6 +46,7 @@ struct _GtkFontChooserDialogPrivate
GtkWidget *select_button;
GtkWidget *cancel_button;
GtkWidget *tweak_button;
};
/**
@@ -136,6 +140,49 @@ gtk_font_chooser_dialog_key_press_event (GtkWidget *dialog,
return handled;
}
static void
setup_tweak_button (GtkFontChooserDialog *dialog)
{
gboolean use_header;
if (dialog->priv->tweak_button)
return;
g_object_get (dialog, "use-header-bar", &use_header, NULL);
if (use_header)
{
GtkWidget *button;
GtkWidget *header;
GSimpleActionGroup *actions;
actions = g_simple_action_group_new ();
g_action_map_add_action (G_ACTION_MAP (actions), gtk_font_chooser_widget_get_tweak_action (dialog->priv->fontchooser));
gtk_widget_insert_action_group (GTK_WIDGET (dialog), "font", actions);
g_object_unref (actions);
button = gtk_toggle_button_new ();
gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "font.tweak");
gtk_widget_set_focus_on_click (button, FALSE);
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
gtk_button_set_icon_name (GTK_BUTTON (button), "emblem-system-symbolic");
header = gtk_dialog_get_header_bar (GTK_DIALOG (dialog));
gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button);
dialog->priv->tweak_button = button;
}
}
static void
gtk_font_chooser_dialog_map (GtkWidget *widget)
{
GtkFontChooserDialog *dialog = GTK_FONT_CHOOSER_DIALOG (widget);
setup_tweak_button (dialog);
GTK_WIDGET_CLASS (gtk_font_chooser_dialog_parent_class)->map (widget);
}
static void
gtk_font_chooser_dialog_class_init (GtkFontChooserDialogClass *klass)
{
@@ -146,15 +193,20 @@ gtk_font_chooser_dialog_class_init (GtkFontChooserDialogClass *klass)
gobject_class->set_property = gtk_font_chooser_dialog_set_property;
widget_class->key_press_event = gtk_font_chooser_dialog_key_press_event;
widget_class->map = gtk_font_chooser_dialog_map;
_gtk_font_chooser_install_properties (gobject_class);
widget_class->key_press_event = gtk_font_chooser_dialog_key_press_event;
/* Bind class to template
*/
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gtk/libgtk/ui/gtkfontchooserdialog.ui");
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserDialog, fontchooser);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserDialog, select_button);
gtk_widget_class_bind_template_child_private (widget_class, GtkFontChooserDialog, cancel_button);
gtk_widget_class_bind_template_callback (widget_class, font_activated_cb);
}
@@ -169,11 +221,14 @@ gtk_font_chooser_dialog_init (GtkFontChooserDialog *fontchooserdiag)
gtk_widget_init_template (GTK_WIDGET (fontchooserdiag));
gtk_dialog_set_use_header_bar_from_setting (GTK_DIALOG (fontchooserdiag));
priv->select_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (fontchooserdiag), GTK_RESPONSE_OK);
priv->cancel_button = gtk_dialog_get_widget_for_response (GTK_DIALOG (fontchooserdiag), GTK_RESPONSE_CANCEL);
_gtk_font_chooser_set_delegate (GTK_FONT_CHOOSER (fontchooserdiag),
GTK_FONT_CHOOSER (priv->fontchooser));
g_object_bind_property (gtk_font_chooser_widget_get_tweak_action (priv->fontchooser),
"enabled",
priv->select_button,
"sensitive",
G_BINDING_SYNC_CREATE);
}
/**

View File

@@ -134,6 +134,15 @@ _gtk_font_chooser_install_properties (GObjectClass *klass)
g_object_class_override_property (klass,
GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY,
"show-preview-entry");
g_object_class_override_property (klass,
GTK_FONT_CHOOSER_PROP_FONT_FEATURES,
"font-features");
g_object_class_override_property (klass,
GTK_FONT_CHOOSER_PROP_LANGUAGE,
"language");
g_object_class_override_property (klass,
GTK_FONT_CHOOSER_PROP_LEVEL,
"level");
}
/**

View File

@@ -37,6 +37,9 @@ typedef enum {
GTK_FONT_CHOOSER_PROP_FONT_DESC,
GTK_FONT_CHOOSER_PROP_PREVIEW_TEXT,
GTK_FONT_CHOOSER_PROP_SHOW_PREVIEW_ENTRY,
GTK_FONT_CHOOSER_PROP_LEVEL,
GTK_FONT_CHOOSER_PROP_FONT_FEATURES,
GTK_FONT_CHOOSER_PROP_LANGUAGE,
GTK_FONT_CHOOSER_PROP_LAST
} GtkFontChooserProp;

File diff suppressed because it is too large Load Diff

View File

@@ -25,6 +25,8 @@ G_BEGIN_DECLS
gboolean gtk_font_chooser_widget_handle_event (GtkWidget *widget,
GdkEventKey *event);
GAction *gtk_font_chooser_widget_get_tweak_action (GtkWidget *fontchooser);
G_END_DECLS
#endif /* __GTK_FONT_CHOOSER_WIDGET_PRIVATE_H__ */

View File

@@ -76,6 +76,7 @@
#include "gtkdebugupdatesprivate.h"
#include "gsk/gskdebugprivate.h"
#include "gtkeventcontrollerlegacyprivate.h"
#include "gtkcssfontvariationsvalueprivate.h"
#include "inspector/window.h"
@@ -8597,15 +8598,23 @@ update_pango_context (GtkWidget *widget,
GtkStyleContext *style_context;
GtkSettings *settings;
cairo_font_options_t *font_options;
GtkCssValue *value;
char *variations;
style_context = _gtk_widget_get_style_context (widget);
gtk_style_context_get (style_context,
"font", &font_desc,
NULL);
value = _gtk_style_context_peek_property (_gtk_widget_get_style_context (widget), GTK_CSS_PROPERTY_FONT_VARIATION_SETTINGS);
variations = gtk_css_font_variations_value_get_variations (value);
pango_font_description_set_variations (font_desc, variations);
pango_context_set_font_description (context, font_desc);
pango_font_description_free (font_desc);
g_free (variations);
pango_context_set_base_dir (context,
_gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR ?

233
gtk/language-names.c Normal file
View File

@@ -0,0 +1,233 @@
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <locale.h>
#include <langinfo.h>
#include <sys/stat.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <hb-ot.h>
#include "language-names.h"
#define ISO_CODES_PREFIX "/usr"
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
static GHashTable *language_map;
static char *
get_first_item_in_semicolon_list (const char *list)
{
char **items;
char *item;
items = g_strsplit (list, "; ", 2);
item = g_strdup (items[0]);
g_strfreev (items);
return item;
}
static char *
capitalize_utf8_string (const char *str)
{
char first[8] = { 0 };
if (!str)
return NULL;
g_unichar_to_utf8 (g_unichar_totitle (g_utf8_get_char (str)), first);
return g_strconcat (first, g_utf8_offset_to_pointer (str, 1), NULL);
}
static char *
get_display_name (const char *language)
{
const char *translated;
char *tmp;
char *name;
translated = dgettext ("iso_639", language);
tmp = get_first_item_in_semicolon_list (translated);
name = capitalize_utf8_string (tmp);
g_free (tmp);
return name;
}
static void
languages_parse_start_tag (GMarkupParseContext *ctx,
const char *element_name,
const char **attr_names,
const char **attr_values,
gpointer user_data,
GError **error)
{
const char *ccode_longB;
const char *ccode_longT;
const char *ccode;
const char *ccode_id;
const char *lang_name;
char *display_name;
if (!(g_str_equal (element_name, "iso_639_entry") ||
g_str_equal (element_name, "iso_639_3_entry")) ||
attr_names == NULL ||
attr_values == NULL)
return;
ccode = NULL;
ccode_longB = NULL;
ccode_longT = NULL;
ccode_id = NULL;
lang_name = NULL;
while (*attr_names && *attr_values)
{
if (g_str_equal (*attr_names, "iso_639_1_code"))
{
if (**attr_values)
{
if (strlen (*attr_values) != 2)
return;
ccode = *attr_values;
}
}
else if (g_str_equal (*attr_names, "iso_639_2B_code"))
{
if (**attr_values)
{
if (strlen (*attr_values) != 3)
return;
ccode_longB = *attr_values;
}
}
else if (g_str_equal (*attr_names, "iso_639_2T_code"))
{
if (**attr_values)
{
if (strlen (*attr_values) != 3)
return;
ccode_longT = *attr_values;
}
}
else if (g_str_equal (*attr_names, "id"))
{
if (**attr_values)
{
if (strlen (*attr_values) != 2 &&
strlen (*attr_values) != 3)
return;
ccode_id = *attr_values;
}
}
else if (g_str_equal (*attr_names, "name"))
{
lang_name = *attr_values;
}
++attr_names;
++attr_values;
}
if (lang_name == NULL)
return;
display_name = get_display_name (lang_name);
if (ccode != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode),
g_strdup (display_name));
if (ccode_longB != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode_longB),
g_strdup (display_name));
if (ccode_longT != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode_longT),
g_strdup (display_name));
if (ccode_id != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode_id),
g_strdup (display_name));
g_free (display_name);
}
static void
languages_variant_init (const char *variant)
{
gboolean res;
gsize buf_len;
g_autofree char *buf = NULL;
g_autofree char *filename = NULL;
g_autoptr (GError) error = NULL;
bindtextdomain (variant, ISO_CODES_LOCALESDIR);
bind_textdomain_codeset (variant, "UTF-8");
error = NULL;
filename = g_strconcat (ISO_CODES_DATADIR, "/", variant, ".xml", NULL);
res = g_file_get_contents (filename, &buf, &buf_len, &error);
if (res)
{
g_autoptr (GMarkupParseContext) ctx = NULL;
GMarkupParser parser = { languages_parse_start_tag, NULL, NULL, NULL, NULL };
ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL);
error = NULL;
res = g_markup_parse_context_parse (ctx, buf, buf_len, &error);
if (!res)
g_warning ("Failed to parse '%s': %s\n", filename, error->message);
}
else
g_warning ("Failed to load '%s': %s\n", filename, error->message);
}
static void
languages_init (void)
{
if (language_map)
return;
language_map = g_hash_table_new_full (NULL, NULL, NULL, g_free);
languages_variant_init ("iso_639");
languages_variant_init ("iso_639_3");
}
const char *
get_language_name (PangoLanguage *language)
{
languages_init ();
return (const char *) g_hash_table_lookup (language_map, language);
}
const char *
get_language_name_for_tag (guint32 tag)
{
hb_language_t lang;
const char *s;
lang = hb_ot_tag_to_language (tag);
s = hb_language_to_string (lang);
return get_language_name (pango_language_from_string (s));
}

13
gtk/language-names.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef LANGUAGE_NAMES_H
#define LANGUAGE_NAMES_H
#include <pango/pango.h>
G_BEGIN_DECLS
const char * get_language_name (PangoLanguage *language);
const char * get_language_name_for_tag (guint32 tag);
G_END_DECLS
#endif

View File

@@ -5,6 +5,8 @@ subdir('inspector')
gtk_public_sources = files([
'fallback-c89.c',
'fnmatch.c',
'language-names.c',
'script-names.c',
'gdkpixbufutils.c',
'gtkaboutdialog.c',
'gtkaccelgroup.c',
@@ -86,6 +88,7 @@ gtk_public_sources = files([
'gtkcssenumvalue.c',
'gtkcssfiltervalue.c',
'gtkcssfontfeaturesvalue.c',
'gtkcssfontvariationsvalue.c',
'gtkcssiconthemevalue.c',
'gtkcssimage.c',
'gtkcssimagebuiltin.c',
@@ -824,6 +827,10 @@ gtk_deps = [
graphene_dep,
]
if harfbuzz_dep.found() and pangoft_dep.found()
gtk_deps += [ harfbuzz_dep, ]
endif
if x11_enabled
x11_data_prefix = dependency('x11').get_pkgconfig_variable('prefix')

155
gtk/open-type-layout.h Normal file
View File

@@ -0,0 +1,155 @@
/* Registered OpenType layout tags, see
* https://www.microsoft.com/typography/otspec/featuretags.htm
*/
typedef struct {
unsigned int tag;
const char *name;
} NamedTag;
#define MAKE_TAG(a,b,c,d) (unsigned int)(((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
static NamedTag open_type_layout_features[] = {
{ MAKE_TAG('a','a','l','t'), NC_("OpenType layout", "Access All Alternates") },
{ MAKE_TAG('a','b','v','f'), NC_("OpenType layout", "Above-base Forms") },
{ MAKE_TAG('a','b','v','m'), NC_("OpenType layout", "Above-base Mark Positioning") },
{ MAKE_TAG('a','b','v','s'), NC_("OpenType layout", "Above-base Substitutions") },
{ MAKE_TAG('a','f','r','c'), NC_("OpenType layout", "Alternative Fractions") },
{ MAKE_TAG('a','k','h','n'), NC_("OpenType layout", "Akhands") },
{ MAKE_TAG('b','l','w','f'), NC_("OpenType layout", "Below-base Forms") },
{ MAKE_TAG('b','l','w','m'), NC_("OpenType layout", "Below-base Mark Positioning") },
{ MAKE_TAG('b','l','w','s'), NC_("OpenType layout", "Below-base Substitutions") },
{ MAKE_TAG('c','a','l','t'), NC_("OpenType layout", "Contextual Alternates") },
{ MAKE_TAG('c','a','s','e'), NC_("OpenType layout", "Case-Sensitive Forms") },
{ MAKE_TAG('c','c','m','p'), NC_("OpenType layout", "Glyph Composition / Decomposition") },
{ MAKE_TAG('c','f','a','r'), NC_("OpenType layout", "Conjunct Form After Ro") },
{ MAKE_TAG('c','j','c','t'), NC_("OpenType layout", "Conjunct Forms") },
{ MAKE_TAG('c','l','i','g'), NC_("OpenType layout", "Contextual Ligatures") },
{ MAKE_TAG('c','p','c','t'), NC_("OpenType layout", "Centered CJK Punctuation") },
{ MAKE_TAG('c','p','s','p'), NC_("OpenType layout", "Capital Spacing") },
{ MAKE_TAG('c','s','w','h'), NC_("OpenType layout", "Contextual Swash") },
{ MAKE_TAG('c','u','r','s'), NC_("OpenType layout", "Cursive Positioning") },
{ MAKE_TAG('c','2','p','c'), NC_("OpenType layout", "Petite Capitals From Capitals") },
{ MAKE_TAG('c','2','s','c'), NC_("OpenType layout", "Small Capitals From Capitals") },
{ MAKE_TAG('d','i','s','t'), NC_("OpenType layout", "Distances") },
{ MAKE_TAG('d','l','i','g'), NC_("OpenType layout", "Discretionary Ligatures") },
{ MAKE_TAG('d','n','o','m'), NC_("OpenType layout", "Denominators") },
{ MAKE_TAG('d','t','l','s'), NC_("OpenType layout", "Dotless Forms") },
{ MAKE_TAG('e','x','p','t'), NC_("OpenType layout", "Expert Forms") },
{ MAKE_TAG('f','a','l','t'), NC_("OpenType layout", "Final Glyph on Line Alternates") },
{ MAKE_TAG('f','i','n','2'), NC_("OpenType layout", "Terminal Forms #2") },
{ MAKE_TAG('f','i','n','3'), NC_("OpenType layout", "Terminal Forms #3") },
{ MAKE_TAG('f','i','n','a'), NC_("OpenType layout", "Terminal Forms") },
{ MAKE_TAG('f','l','a','c'), NC_("OpenType layout", "Flattened accent forms") },
{ MAKE_TAG('f','r','a','c'), NC_("OpenType layout", "Fractions") },
{ MAKE_TAG('f','w','i','d'), NC_("OpenType layout", "Full Widths") },
{ MAKE_TAG('h','a','l','f'), NC_("OpenType layout", "Half Forms") },
{ MAKE_TAG('h','a','l','n'), NC_("OpenType layout", "Halant Forms") },
{ MAKE_TAG('h','a','l','t'), NC_("OpenType layout", "Alternate Half Widths") },
{ MAKE_TAG('h','i','s','t'), NC_("OpenType layout", "Historical Forms") },
{ MAKE_TAG('h','k','n','a'), NC_("OpenType layout", "Horizontal Kana Alternates") },
{ MAKE_TAG('h','l','i','g'), NC_("OpenType layout", "Historical Ligatures") },
{ MAKE_TAG('h','n','g','l'), NC_("OpenType layout", "Hangul") },
{ MAKE_TAG('h','o','j','o'), NC_("OpenType layout", "Hojo Kanji Forms") },
{ MAKE_TAG('h','w','i','d'), NC_("OpenType layout", "Half Widths") },
{ MAKE_TAG('i','n','i','t'), NC_("OpenType layout", "Initial Forms") },
{ MAKE_TAG('i','s','o','l'), NC_("OpenType layout", "Isolated Forms") },
{ MAKE_TAG('i','t','a','l'), NC_("OpenType layout", "Italics") },
{ MAKE_TAG('j','a','l','t'), NC_("OpenType layout", "Justification Alternates") },
{ MAKE_TAG('j','p','7','8'), NC_("OpenType layout", "JIS78 Forms") },
{ MAKE_TAG('j','p','8','3'), NC_("OpenType layout", "JIS83 Forms") },
{ MAKE_TAG('j','p','9','0'), NC_("OpenType layout", "JIS90 Forms") },
{ MAKE_TAG('j','p','0','4'), NC_("OpenType layout", "JIS2004 Forms") },
{ MAKE_TAG('k','e','r','n'), NC_("OpenType layout", "Kerning") },
{ MAKE_TAG('l','f','b','d'), NC_("OpenType layout", "Left Bounds") },
{ MAKE_TAG('l','i','g','a'), NC_("OpenType layout", "Standard Ligatures") },
{ MAKE_TAG('l','j','m','o'), NC_("OpenType layout", "Leading Jamo Forms") },
{ MAKE_TAG('l','n','u','m'), NC_("OpenType layout", "Lining Figures") },
{ MAKE_TAG('l','o','c','l'), NC_("OpenType layout", "Localized Forms") },
{ MAKE_TAG('l','t','r','a'), NC_("OpenType layout", "Left-to-right alternates") },
{ MAKE_TAG('l','t','r','m'), NC_("OpenType layout", "Left-to-right mirrored forms") },
{ MAKE_TAG('m','a','r','k'), NC_("OpenType layout", "Mark Positioning") },
{ MAKE_TAG('m','e','d','2'), NC_("OpenType layout", "Medial Forms #2") },
{ MAKE_TAG('m','e','d','i'), NC_("OpenType layout", "Medial Forms") },
{ MAKE_TAG('m','g','r','k'), NC_("OpenType layout", "Mathematical Greek") },
{ MAKE_TAG('m','k','m','k'), NC_("OpenType layout", "Mark to Mark Positioning") },
{ MAKE_TAG('m','s','e','t'), NC_("OpenType layout", "Mark Positioning via Substitution") },
{ MAKE_TAG('n','a','l','t'), NC_("OpenType layout", "Alternate Annotation Forms") },
{ MAKE_TAG('n','l','c','k'), NC_("OpenType layout", "NLC Kanji Forms") },
{ MAKE_TAG('n','u','k','t'), NC_("OpenType layout", "Nukta Forms") },
{ MAKE_TAG('n','u','m','r'), NC_("OpenType layout", "Numerators") },
{ MAKE_TAG('o','n','u','m'), NC_("OpenType layout", "Oldstyle Figures") },
{ MAKE_TAG('o','p','b','d'), NC_("OpenType layout", "Optical Bounds") },
{ MAKE_TAG('o','r','d','n'), NC_("OpenType layout", "Ordinals") },
{ MAKE_TAG('o','r','n','m'), NC_("OpenType layout", "Ornaments") },
{ MAKE_TAG('p','a','l','t'), NC_("OpenType layout", "Proportional Alternate Widths") },
{ MAKE_TAG('p','c','a','p'), NC_("OpenType layout", "Petite Capitals") },
{ MAKE_TAG('p','k','n','a'), NC_("OpenType layout", "Proportional Kana") },
{ MAKE_TAG('p','n','u','m'), NC_("OpenType layout", "Proportional Figures") },
{ MAKE_TAG('p','r','e','f'), NC_("OpenType layout", "Pre-Base Forms") },
{ MAKE_TAG('p','r','e','s'), NC_("OpenType layout", "Pre-base Substitutions") },
{ MAKE_TAG('p','s','t','f'), NC_("OpenType layout", "Post-base Forms") },
{ MAKE_TAG('p','s','t','s'), NC_("OpenType layout", "Post-base Substitutions") },
{ MAKE_TAG('p','w','i','d'), NC_("OpenType layout", "Proportional Widths") },
{ MAKE_TAG('q','w','i','d'), NC_("OpenType layout", "Quarter Widths") },
{ MAKE_TAG('r','a','n','d'), NC_("OpenType layout", "Randomize") },
{ MAKE_TAG('r','c','l','t'), NC_("OpenType layout", "Required Contextual Alternates") },
{ MAKE_TAG('r','k','r','f'), NC_("OpenType layout", "Rakar Forms") },
{ MAKE_TAG('r','l','i','g'), NC_("OpenType layout", "Required Ligatures") },
{ MAKE_TAG('r','p','h','f'), NC_("OpenType layout", "Reph Forms") },
{ MAKE_TAG('r','t','b','d'), NC_("OpenType layout", "Right Bounds") },
{ MAKE_TAG('r','t','l','a'), NC_("OpenType layout", "Right-to-left alternates") },
{ MAKE_TAG('r','t','l','m'), NC_("OpenType layout", "Right-to-left mirrored forms") },
{ MAKE_TAG('r','u','b','y'), NC_("OpenType layout", "Ruby Notation Forms") },
{ MAKE_TAG('r','v','r','n'), NC_("OpenType layout", "Required Variation Alternates") },
{ MAKE_TAG('s','a','l','t'), NC_("OpenType layout", "Stylistic Alternates") },
{ MAKE_TAG('s','i','n','f'), NC_("OpenType layout", "Scientific Inferiors") },
{ MAKE_TAG('s','i','z','e'), NC_("OpenType layout", "Optical size") },
{ MAKE_TAG('s','m','c','p'), NC_("OpenType layout", "Small Capitals") },
{ MAKE_TAG('s','m','p','l'), NC_("OpenType layout", "Simplified Forms") },
{ MAKE_TAG('s','s','0','1'), NC_("OpenType layout", "Stylistic Set 1") },
{ MAKE_TAG('s','s','0','2'), NC_("OpenType layout", "Stylistic Set 2") },
{ MAKE_TAG('s','s','0','3'), NC_("OpenType layout", "Stylistic Set 3") },
{ MAKE_TAG('s','s','0','4'), NC_("OpenType layout", "Stylistic Set 4") },
{ MAKE_TAG('s','s','0','5'), NC_("OpenType layout", "Stylistic Set 5") },
{ MAKE_TAG('s','s','0','6'), NC_("OpenType layout", "Stylistic Set 6") },
{ MAKE_TAG('s','s','0','7'), NC_("OpenType layout", "Stylistic Set 7") },
{ MAKE_TAG('s','s','0','8'), NC_("OpenType layout", "Stylistic Set 8") },
{ MAKE_TAG('s','s','0','9'), NC_("OpenType layout", "Stylistic Set 9") },
{ MAKE_TAG('s','s','1','0'), NC_("OpenType layout", "Stylistic Set 10") },
{ MAKE_TAG('s','s','1','1'), NC_("OpenType layout", "Stylistic Set 11") },
{ MAKE_TAG('s','s','1','2'), NC_("OpenType layout", "Stylistic Set 12") },
{ MAKE_TAG('s','s','1','3'), NC_("OpenType layout", "Stylistic Set 13") },
{ MAKE_TAG('s','s','1','4'), NC_("OpenType layout", "Stylistic Set 14") },
{ MAKE_TAG('s','s','1','5'), NC_("OpenType layout", "Stylistic Set 15") },
{ MAKE_TAG('s','s','1','6'), NC_("OpenType layout", "Stylistic Set 16") },
{ MAKE_TAG('s','s','1','7'), NC_("OpenType layout", "Stylistic Set 17") },
{ MAKE_TAG('s','s','1','8'), NC_("OpenType layout", "Stylistic Set 18") },
{ MAKE_TAG('s','s','1','9'), NC_("OpenType layout", "Stylistic Set 19") },
{ MAKE_TAG('s','s','2','0'), NC_("OpenType layout", "Stylistic Set 20") },
{ MAKE_TAG('s','s','t','y'), NC_("OpenType layout", "Math script style alternates") },
{ MAKE_TAG('s','t','c','h'), NC_("OpenType layout", "Stretching Glyph Decomposition") },
{ MAKE_TAG('s','u','b','s'), NC_("OpenType layout", "Subscript") },
{ MAKE_TAG('s','u','p','s'), NC_("OpenType layout", "Superscript") },
{ MAKE_TAG('s','w','s','h'), NC_("OpenType layout", "Swash") },
{ MAKE_TAG('t','i','t','l'), NC_("OpenType layout", "Titling") },
{ MAKE_TAG('t','j','m','o'), NC_("OpenType layout", "Trailing Jamo Forms") },
{ MAKE_TAG('t','n','a','m'), NC_("OpenType layout", "Traditional Name Forms") },
{ MAKE_TAG('t','n','u','m'), NC_("OpenType layout", "Tabular Figures") },
{ MAKE_TAG('t','r','a','d'), NC_("OpenType layout", "Traditional Forms") },
{ MAKE_TAG('t','w','i','d'), NC_("OpenType layout", "Third Widths") },
{ MAKE_TAG('u','n','i','c'), NC_("OpenType layout", "Unicase") },
{ MAKE_TAG('v','a','l','t'), NC_("OpenType layout", "Alternate Vertical Metrics") },
{ MAKE_TAG('v','a','t','u'), NC_("OpenType layout", "Vattu Variants") },
{ MAKE_TAG('v','e','r','t'), NC_("OpenType layout", "Vertical Writing") },
{ MAKE_TAG('v','h','a','l'), NC_("OpenType layout", "Alternate Vertical Half Metrics") },
{ MAKE_TAG('v','j','m','o'), NC_("OpenType layout", "Vowel Jamo Forms") },
{ MAKE_TAG('v','k','n','a'), NC_("OpenType layout", "Vertical Kana Alternates") },
{ MAKE_TAG('v','k','r','n'), NC_("OpenType layout", "Vertical Kerning") },
{ MAKE_TAG('v','p','a','l'), NC_("OpenType layout", "Proportional Alternate Vertical Metrics") },
{ MAKE_TAG('v','r','t','2'), NC_("OpenType layout", "Vertical Alternates and Rotation") },
{ MAKE_TAG('v','r','t','r'), NC_("OpenType layout", "Vertical Alternates for Rotation") },
{ MAKE_TAG('z','e','r','o'), NC_("OpenType layout", "Slashed Zero") },
};
#undef MAKE_TAG

184
gtk/script-names.c Normal file
View File

@@ -0,0 +1,184 @@
#include "config.h"
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <hb-ot.h>
#include "script-names.h"
static struct {
GUnicodeScript script;
hb_script_t hb_script;
const char *name;
} scripts[] =
{
{ G_UNICODE_SCRIPT_COMMON, HB_SCRIPT_COMMON, NULL },
{ G_UNICODE_SCRIPT_INHERITED, HB_SCRIPT_INHERITED, NULL },
{ G_UNICODE_SCRIPT_ARABIC, HB_SCRIPT_ARABIC, NC_("Script", "Arabic") },
{ G_UNICODE_SCRIPT_ARMENIAN, HB_SCRIPT_ARMENIAN, NC_("Script", "Armenian") },
{ G_UNICODE_SCRIPT_BENGALI, HB_SCRIPT_BENGALI, NC_("Script", "Bengali") },
{ G_UNICODE_SCRIPT_BOPOMOFO, HB_SCRIPT_BOPOMOFO, NC_("Script", "Bopomofo") },
{ G_UNICODE_SCRIPT_CHEROKEE, HB_SCRIPT_CHEROKEE, NC_("Script", "Cherokee") },
{ G_UNICODE_SCRIPT_COPTIC, HB_SCRIPT_COPTIC, NC_("Script", "Coptic") },
{ G_UNICODE_SCRIPT_CYRILLIC, HB_SCRIPT_CYRILLIC, NC_("Script", "Cyrillic") },
{ G_UNICODE_SCRIPT_DESERET, HB_SCRIPT_DESERET, NC_("Script", "Deseret") },
{ G_UNICODE_SCRIPT_DEVANAGARI, HB_SCRIPT_DEVANAGARI, NC_("Script", "Devanagari") },
{ G_UNICODE_SCRIPT_ETHIOPIC, HB_SCRIPT_ETHIOPIC, NC_("Script", "Ethiopic") },
{ G_UNICODE_SCRIPT_GEORGIAN, HB_SCRIPT_GEORGIAN, NC_("Script", "Georgian") },
{ G_UNICODE_SCRIPT_GOTHIC, HB_SCRIPT_GOTHIC, NC_("Script", "Gothic") },
{ G_UNICODE_SCRIPT_GREEK, HB_SCRIPT_GREEK, NC_("Script", "Greek") },
{ G_UNICODE_SCRIPT_GUJARATI, HB_SCRIPT_GUJARATI, NC_("Script", "Gujarati") },
{ G_UNICODE_SCRIPT_GURMUKHI, HB_SCRIPT_GURMUKHI, NC_("Script", "Gurmukhi") },
{ G_UNICODE_SCRIPT_HAN, HB_SCRIPT_HAN, NC_("Script", "Han") },
{ G_UNICODE_SCRIPT_HANGUL, HB_SCRIPT_HANGUL, NC_("Script", "Hangul") },
{ G_UNICODE_SCRIPT_HEBREW, HB_SCRIPT_HEBREW, NC_("Script", "Hebrew") },
{ G_UNICODE_SCRIPT_HIRAGANA, HB_SCRIPT_HIRAGANA, NC_("Script", "Hiragana") },
{ G_UNICODE_SCRIPT_KANNADA, HB_SCRIPT_KANNADA, NC_("Script", "Kannada") },
{ G_UNICODE_SCRIPT_KATAKANA, HB_SCRIPT_KATAKANA, NC_("Script", "Katakana") },
{ G_UNICODE_SCRIPT_KHMER, HB_SCRIPT_KHMER, NC_("Script", "Khmer") },
{ G_UNICODE_SCRIPT_LAO, HB_SCRIPT_LAO, NC_("Script", "Lao") },
{ G_UNICODE_SCRIPT_LATIN, HB_SCRIPT_LATIN, NC_("Script", "Latin") },
{ G_UNICODE_SCRIPT_MALAYALAM, HB_SCRIPT_MALAYALAM, NC_("Script", "Malayalam") },
{ G_UNICODE_SCRIPT_MONGOLIAN, HB_SCRIPT_MONGOLIAN, NC_("Script", "Mongolian") },
{ G_UNICODE_SCRIPT_MYANMAR, HB_SCRIPT_MYANMAR, NC_("Script", "Myanmar") },
{ G_UNICODE_SCRIPT_OGHAM, HB_SCRIPT_OGHAM, NC_("Script", "Ogham") },
{ G_UNICODE_SCRIPT_OLD_ITALIC, HB_SCRIPT_OLD_ITALIC, NC_("Script", "Old Italic") },
{ G_UNICODE_SCRIPT_ORIYA, HB_SCRIPT_ORIYA, NC_("Script", "Oriya") },
{ G_UNICODE_SCRIPT_RUNIC, HB_SCRIPT_RUNIC, NC_("Script", "Runic") },
{ G_UNICODE_SCRIPT_SINHALA, HB_SCRIPT_SINHALA, NC_("Script", "Sinhala") },
{ G_UNICODE_SCRIPT_SYRIAC, HB_SCRIPT_SYRIAC, NC_("Script", "Syriac") },
{ G_UNICODE_SCRIPT_TAMIL, HB_SCRIPT_TAMIL, NC_("Script", "Tamil") },
{ G_UNICODE_SCRIPT_TELUGU, HB_SCRIPT_TELUGU, NC_("Script", "Telugu") },
{ G_UNICODE_SCRIPT_THAANA, HB_SCRIPT_THAANA, NC_("Script", "Thaana") },
{ G_UNICODE_SCRIPT_THAI, HB_SCRIPT_THAI, NC_("Script", "Thai") },
{ G_UNICODE_SCRIPT_TIBETAN, HB_SCRIPT_TIBETAN, NC_("Script", "Tibetan") },
{ G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, HB_SCRIPT_CANADIAN_ABORIGINAL, NC_("Script", "Canadian Aboriginal") },
{ G_UNICODE_SCRIPT_YI, HB_SCRIPT_YI, NC_("Script", "Yi") },
{ G_UNICODE_SCRIPT_TAGALOG, HB_SCRIPT_TAGALOG, NC_("Script", "Tagalog") },
{ G_UNICODE_SCRIPT_HANUNOO, HB_SCRIPT_HANUNOO, NC_("Script", "Hanunoo") },
{ G_UNICODE_SCRIPT_BUHID, HB_SCRIPT_BUHID, NC_("Script", "Buhid") },
{ G_UNICODE_SCRIPT_TAGBANWA, HB_SCRIPT_TAGBANWA, NC_("Script", "Tagbanwa") },
{ G_UNICODE_SCRIPT_BRAILLE, HB_SCRIPT_BRAILLE, NC_("Script", "Braille") },
{ G_UNICODE_SCRIPT_CYPRIOT, HB_SCRIPT_CYPRIOT, NC_("Script", "Cypriot") },
{ G_UNICODE_SCRIPT_LIMBU, HB_SCRIPT_LIMBU, NC_("Script", "Limbu") },
{ G_UNICODE_SCRIPT_OSMANYA, HB_SCRIPT_OSMANYA, NC_("Script", "Osmanya") },
{ G_UNICODE_SCRIPT_SHAVIAN, HB_SCRIPT_SHAVIAN, NC_("Script", "Shavian") },
{ G_UNICODE_SCRIPT_LINEAR_B, HB_SCRIPT_LINEAR_B, NC_("Script", "Linear B") },
{ G_UNICODE_SCRIPT_TAI_LE, HB_SCRIPT_TAI_LE, NC_("Script", "Tai Le") },
{ G_UNICODE_SCRIPT_UGARITIC, HB_SCRIPT_UGARITIC, NC_("Script", "Ugaritic") },
{ G_UNICODE_SCRIPT_NEW_TAI_LUE, HB_SCRIPT_NEW_TAI_LUE, NC_("Script", "New Tai Lue") },
{ G_UNICODE_SCRIPT_BUGINESE, HB_SCRIPT_BUGINESE, NC_("Script", "Buginese") },
{ G_UNICODE_SCRIPT_GLAGOLITIC, HB_SCRIPT_GLAGOLITIC, NC_("Script", "Glagolitic") },
{ G_UNICODE_SCRIPT_TIFINAGH, HB_SCRIPT_TIFINAGH, NC_("Script", "Tifinagh") },
{ G_UNICODE_SCRIPT_SYLOTI_NAGRI, HB_SCRIPT_SYLOTI_NAGRI, NC_("Script", "Syloti Nagri") },
{ G_UNICODE_SCRIPT_OLD_PERSIAN, HB_SCRIPT_OLD_PERSIAN, NC_("Script", "Old Persian") },
{ G_UNICODE_SCRIPT_KHAROSHTHI, HB_SCRIPT_KHAROSHTHI, NC_("Script", "Kharoshthi") },
{ G_UNICODE_SCRIPT_UNKNOWN, HB_SCRIPT_UNKNOWN, NC_("Script", "Unknown") },
{ G_UNICODE_SCRIPT_BALINESE, HB_SCRIPT_BALINESE, NC_("Script", "Balinese") },
{ G_UNICODE_SCRIPT_CUNEIFORM, HB_SCRIPT_CUNEIFORM, NC_("Script", "Cuneiform") },
{ G_UNICODE_SCRIPT_PHOENICIAN, HB_SCRIPT_PHOENICIAN, NC_("Script", "Phoenician") },
{ G_UNICODE_SCRIPT_PHAGS_PA, HB_SCRIPT_PHAGS_PA, NC_("Script", "Phags-pa") },
{ G_UNICODE_SCRIPT_NKO, HB_SCRIPT_NKO, NC_("Script", "N'Ko") },
{ G_UNICODE_SCRIPT_KAYAH_LI, HB_SCRIPT_KAYAH_LI, NC_("Script", "Kayah Li") },
{ G_UNICODE_SCRIPT_LEPCHA, HB_SCRIPT_LEPCHA, NC_("Script", "Lepcha") },
{ G_UNICODE_SCRIPT_REJANG, HB_SCRIPT_REJANG, NC_("Script", "Rejang") },
{ G_UNICODE_SCRIPT_SUNDANESE, HB_SCRIPT_SUNDANESE, NC_("Script", "Sundanese") },
{ G_UNICODE_SCRIPT_SAURASHTRA, HB_SCRIPT_SAURASHTRA, NC_("Script", "Saurashtra") },
{ G_UNICODE_SCRIPT_CHAM, HB_SCRIPT_CHAM, NC_("Script", "Cham") },
{ G_UNICODE_SCRIPT_OL_CHIKI, HB_SCRIPT_OL_CHIKI, NC_("Script", "Ol Chiki") },
{ G_UNICODE_SCRIPT_VAI, HB_SCRIPT_VAI, NC_("Script", "Vai") },
{ G_UNICODE_SCRIPT_CARIAN, HB_SCRIPT_CARIAN, NC_("Script", "Carian") },
{ G_UNICODE_SCRIPT_LYCIAN, HB_SCRIPT_LYCIAN, NC_("Script", "Lycian") },
{ G_UNICODE_SCRIPT_LYDIAN, HB_SCRIPT_LYDIAN, NC_("Script", "Lydian") },
{ G_UNICODE_SCRIPT_AVESTAN, HB_SCRIPT_AVESTAN, NC_("Script", "Avestan") },
{ G_UNICODE_SCRIPT_BAMUM, HB_SCRIPT_BAMUM, NC_("Script", "Bamum") },
{ G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS, HB_SCRIPT_EGYPTIAN_HIEROGLYPHS, NC_("Script", "Egyptian Hieroglpyhs") },
{ G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC, HB_SCRIPT_IMPERIAL_ARAMAIC, NC_("Script", "Imperial Aramaic") },
{ G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI, HB_SCRIPT_INSCRIPTIONAL_PAHLAVI, NC_("Script", "Inscriptional Pahlavi") },
{ G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN, HB_SCRIPT_INSCRIPTIONAL_PARTHIAN, NC_("Script", "Inscriptional Parthian") },
{ G_UNICODE_SCRIPT_JAVANESE, HB_SCRIPT_JAVANESE, NC_("Script", "Javanese") },
{ G_UNICODE_SCRIPT_KAITHI, HB_SCRIPT_KAITHI, NC_("Script", "Kaithi") },
{ G_UNICODE_SCRIPT_LISU, HB_SCRIPT_LISU, NC_("Script", "Lisu") },
{ G_UNICODE_SCRIPT_MEETEI_MAYEK, HB_SCRIPT_MEETEI_MAYEK, NC_("Script", "Meetei Mayek") },
{ G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN, HB_SCRIPT_OLD_SOUTH_ARABIAN, NC_("Script", "Old South Arabian") },
{ G_UNICODE_SCRIPT_OLD_TURKIC, HB_SCRIPT_OLD_TURKIC, NC_("Script", "Old Turkic") },
{ G_UNICODE_SCRIPT_SAMARITAN, HB_SCRIPT_SAMARITAN, NC_("Script", "Samaritan") },
{ G_UNICODE_SCRIPT_TAI_THAM, HB_SCRIPT_TAI_THAM, NC_("Script", "Tai Tham") },
{ G_UNICODE_SCRIPT_TAI_VIET, HB_SCRIPT_TAI_VIET, NC_("Script", "Tai Viet") },
{ G_UNICODE_SCRIPT_BATAK, HB_SCRIPT_BATAK, NC_("Script", "Batak") },
{ G_UNICODE_SCRIPT_BRAHMI, HB_SCRIPT_BRAHMI, NC_("Script", "Brahmi") },
{ G_UNICODE_SCRIPT_MANDAIC, HB_SCRIPT_MANDAIC, NC_("Script", "Mandaic") },
{ G_UNICODE_SCRIPT_CHAKMA, HB_SCRIPT_CHAKMA, NC_("Script", "Chakma") },
{ G_UNICODE_SCRIPT_MEROITIC_CURSIVE, HB_SCRIPT_MEROITIC_CURSIVE, NC_("Script", "Meroitic Cursive") },
{ G_UNICODE_SCRIPT_MEROITIC_HIEROGLYPHS, HB_SCRIPT_MEROITIC_HIEROGLYPHS, NC_("Script", "Meroitic Hieroglyphs") },
{ G_UNICODE_SCRIPT_MIAO, HB_SCRIPT_MIAO, NC_("Script", "Miao") },
{ G_UNICODE_SCRIPT_SHARADA, HB_SCRIPT_SHARADA, NC_("Script", "Sharada") },
{ G_UNICODE_SCRIPT_SORA_SOMPENG, HB_SCRIPT_SORA_SOMPENG, NC_("Script", "Sora Sompeng") },
{ G_UNICODE_SCRIPT_TAKRI, HB_SCRIPT_TAKRI, NC_("Script", "Takri") },
{ G_UNICODE_SCRIPT_BASSA_VAH, HB_SCRIPT_BASSA_VAH, NC_("Script", "Bassa") },
{ G_UNICODE_SCRIPT_CAUCASIAN_ALBANIAN, HB_SCRIPT_CAUCASIAN_ALBANIAN, NC_("Script", "Caucasian Albanian") },
{ G_UNICODE_SCRIPT_DUPLOYAN, HB_SCRIPT_DUPLOYAN, NC_("Script", "Duployan") },
{ G_UNICODE_SCRIPT_ELBASAN, HB_SCRIPT_ELBASAN, NC_("Script", "Elbasan") },
{ G_UNICODE_SCRIPT_GRANTHA, HB_SCRIPT_GRANTHA, NC_("Script", "Grantha") },
{ G_UNICODE_SCRIPT_KHOJKI, HB_SCRIPT_KHOJKI, NC_("Script", "Kjohki") },
{ G_UNICODE_SCRIPT_KHUDAWADI, HB_SCRIPT_KHUDAWADI, NC_("Script", "Khudawadi, Sindhi") },
{ G_UNICODE_SCRIPT_LINEAR_A, HB_SCRIPT_LINEAR_A, NC_("Script", "Linear A") },
{ G_UNICODE_SCRIPT_MAHAJANI, HB_SCRIPT_MAHAJANI, NC_("Script", "Mahajani") },
{ G_UNICODE_SCRIPT_MANICHAEAN, HB_SCRIPT_MANICHAEAN, NC_("Script", "Manichaean") },
{ G_UNICODE_SCRIPT_MENDE_KIKAKUI, HB_SCRIPT_MENDE_KIKAKUI, NC_("Script", "Mende Kikakui") },
{ G_UNICODE_SCRIPT_MODI, HB_SCRIPT_MODI, NC_("Script", "Modi") },
{ G_UNICODE_SCRIPT_MRO, HB_SCRIPT_MRO, NC_("Script", "Mro") },
{ G_UNICODE_SCRIPT_NABATAEAN, HB_SCRIPT_NABATAEAN, NC_("Script", "Nabataean") },
{ G_UNICODE_SCRIPT_OLD_NORTH_ARABIAN, HB_SCRIPT_OLD_NORTH_ARABIAN, NC_("Script", "Old North Arabian") },
{ G_UNICODE_SCRIPT_OLD_PERMIC, HB_SCRIPT_OLD_PERMIC, NC_("Script", "Old Permic") },
{ G_UNICODE_SCRIPT_PAHAWH_HMONG, HB_SCRIPT_PAHAWH_HMONG, NC_("Script", "Pahawh Hmong") },
{ G_UNICODE_SCRIPT_PALMYRENE, HB_SCRIPT_PALMYRENE, NC_("Script", "Palmyrene") },
{ G_UNICODE_SCRIPT_PAU_CIN_HAU, HB_SCRIPT_PAU_CIN_HAU, NC_("Script", "Pau Cin Hau") },
{ G_UNICODE_SCRIPT_PSALTER_PAHLAVI, HB_SCRIPT_PSALTER_PAHLAVI, NC_("Script", "Psalter Pahlavi") },
{ G_UNICODE_SCRIPT_SIDDHAM, HB_SCRIPT_SIDDHAM, NC_("Script", "Siddham") },
{ G_UNICODE_SCRIPT_TIRHUTA, HB_SCRIPT_TIRHUTA, NC_("Script", "Tirhuta") },
{ G_UNICODE_SCRIPT_WARANG_CITI, HB_SCRIPT_WARANG_CITI, NC_("Script", "Warang Citi") },
{ G_UNICODE_SCRIPT_AHOM, HB_SCRIPT_AHOM, NC_("Script", "Ahom") },
{ G_UNICODE_SCRIPT_ANATOLIAN_HIEROGLYPHS, HB_SCRIPT_ANATOLIAN_HIEROGLYPHS, NC_("Script", "Anatolian Hieroglyphs") },
{ G_UNICODE_SCRIPT_HATRAN, HB_SCRIPT_HATRAN, NC_("Script", "Hatran") },
{ G_UNICODE_SCRIPT_MULTANI, HB_SCRIPT_MULTANI, NC_("Script", "Multani") },
{ G_UNICODE_SCRIPT_OLD_HUNGARIAN, HB_SCRIPT_OLD_HUNGARIAN, NC_("Script", "Old Hungarian") },
{ G_UNICODE_SCRIPT_SIGNWRITING, HB_SCRIPT_SIGNWRITING, NC_("Script", "Signwriting") },
{ G_UNICODE_SCRIPT_ADLAM, HB_SCRIPT_ADLAM, NC_("Script", "Adlam") },
{ G_UNICODE_SCRIPT_BHAIKSUKI, HB_SCRIPT_BHAIKSUKI, NC_("Script", "Bhaiksuki") },
{ G_UNICODE_SCRIPT_MARCHEN, HB_SCRIPT_MARCHEN, NC_("Script", "Marchen") },
{ G_UNICODE_SCRIPT_NEWA, HB_SCRIPT_NEWA, NC_("Script", "Newa") },
{ G_UNICODE_SCRIPT_OSAGE, HB_SCRIPT_OSAGE, NC_("Script", "Osage") },
{ G_UNICODE_SCRIPT_TANGUT, HB_SCRIPT_TANGUT, NC_("Script", "Tangut") },
{ G_UNICODE_SCRIPT_MASARAM_GONDI, HB_SCRIPT_INVALID, NC_("Script", "Masaram Gondi") },
{ G_UNICODE_SCRIPT_NUSHU, HB_SCRIPT_INVALID, NC_("Script", "Nushu") },
{ G_UNICODE_SCRIPT_SOYOMBO, HB_SCRIPT_INVALID, NC_("Script", "Soyombo") },
{ G_UNICODE_SCRIPT_ZANABAZAR_SQUARE, HB_SCRIPT_INVALID, NC_("Script", "Zanabazar Square") },
};
const char *
get_script_name (GUnicodeScript script)
{
int i;
for (i = 0; i < G_N_ELEMENTS (scripts); i++)
{
if (scripts[i].script == script)
return g_dpgettext2 (GETTEXT_PACKAGE, "Script", scripts[i].name);
}
return NULL;
}
const char *
get_script_name_for_tag (guint32 tag)
{
int i;
for (i = 0; i < G_N_ELEMENTS (scripts); i++)
{
if (scripts[i].hb_script == hb_script_from_iso15924_tag (tag))
return g_dpgettext2 (GETTEXT_PACKAGE, "Script", scripts[i].name);
}
return NULL;
}

13
gtk/script-names.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef SCRIPT_NAMES_H
#define SCRIPT_NAMES_H
#include <glib.h>
G_BEGIN_DECLS
const char * get_script_name (GUnicodeScript script);
const char * get_script_name_for_tag (guint32 tag);
G_END_DECLS
#endif

View File

@@ -27,7 +27,7 @@
</object>
</child>
<child type="action">
<object class="GtkButton" id="ok_button">
<object class="GtkButton" id="select_button">
<property name="label" translatable="yes">_Select</property>
<property name="use-underline">1</property>
<property name="can-default">1</property>
@@ -35,7 +35,7 @@
</child>
<action-widgets>
<action-widget response="cancel">cancel_button</action-widget>
<action-widget response="ok" default="true">ok_button</action-widget>
<action-widget response="ok" default="true">select_button</action-widget>
</action-widgets>
</template>
</interface>

View File

@@ -32,164 +32,299 @@
</object>
<template class="GtkFontChooserWidget" parent="GtkWidget">
<child>
<object class="GtkGrid" id="grid">
<property name="row-spacing">6</property>
<property name="column-spacing">6</property>
<object class="GtkStack" id="stack">
<child>
<object class="GtkSearchEntry" id="search_entry">
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="activates-default">1</property>
<property name="primary-icon-name">edit-find-symbolic</property>
<property name="primary-icon-activatable">0</property>
<property name="secondary-icon-activatable">0</property>
<property name="primary-icon-sensitive">0</property>
<property name="secondary-icon-sensitive">0</property>
<property name="placeholder-text" translatable="yes">Search font name</property>
<signal name="search-changed" handler="text_changed_cb" swapped="no"/>
<signal name="stop-search" handler="stop_search_cb" swapped="no"/>
<object class="GtkGrid" id="grid">
<property name="row-spacing">6</property>
<property name="column-spacing">6</property>
<child>
<object class="GtkBox">
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkSearchEntry" id="search_entry">
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="activates-default">1</property>
<property name="primary-icon-name">edit-find-symbolic</property>
<property name="primary-icon-activatable">0</property>
<property name="secondary-icon-activatable">0</property>
<property name="primary-icon-sensitive">0</property>
<property name="secondary-icon-sensitive">0</property>
<property name="placeholder-text" translatable="yes">Search font name</property>
<signal name="search-changed" handler="text_changed_cb" swapped="no"/>
<signal name="stop-search" handler="stop_search_cb" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuButton" id="filter_button">
<property name="popover">filter_popover</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkStack" id="list_stack">
<child>
<object class="GtkGrid" id="font_grid">
<property name="row-spacing">6</property>
<property name="column-spacing">6</property>
<child>
<object class="GtkScrolledWindow" id="list_scrolled_window">
<property name="width-request">400</property>
<property name="height-request">300</property>
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="hscrollbar-policy">never</property>
<property name="shadow-type">etched-in</property>
<child>
<object class="GtkTreeView" id="family_face_list">
<property name="can-focus">1</property>
<property name="model">filter_model</property>
<property name="headers-visible">0</property>
<property name="enable-search">0</property>
<property name="fixed-height-mode">1</property>
<signal name="cursor-changed" handler="cursor_changed_cb" swapped="no"/>
<signal name="row-activated" handler="row_activated_cb" swapped="no"/>
<signal name="style-updated" handler="gtk_font_chooser_widget_set_cell_size" object="GtkFontChooserWidget" after="yes" swapped="yes"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1">
<property name="mode">browse</property>
<signal name="changed" handler="selection_changed"/>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="family_face_column">
<property name="sizing">fixed</property>
<property name="title" translatable="yes">Font Family</property>
<child>
<object class="GtkCellRendererText" id="family_face_cell">
<property name="ellipsize">end</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
<property name="width">3</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="preview">
<property name="can-focus">1</property>
<property name="placeholder-text" translatable="yes">Preview text</property>
<signal name="scroll-event" handler="resize_by_scroll_cb" swapped="no"/>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="width">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="size_label">
<property name="label" translatable="yes">Size</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkScale" id="size_slider">
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="adjustment">slider_adjustment</property>
<property name="draw-value">0</property>
<property name="round-digits">0</property>
<signal name="scroll-event" handler="resize_by_scroll_cb" swapped="no"/>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="size_spin">
<property name="can-focus">1</property>
<property name="adjustment">spin_adjustment</property>
<signal name="output" handler="output_cb"/>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">3</property>
</packing>
</child>
</object>
<packing>
<property name="name">list</property>
</packing>
</child>
<child>
<object class="GtkGrid">
<property name="row-spacing">12</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<style>
<class name="dim-label"/>
</style>
<child>
<object class="GtkImage">
<property name="gicon">fonticon</property>
<property name="pixel-size">64</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">No Fonts Found</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.2"/>
</attributes>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">empty</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
<property name="width">2</property>
<property name="name">list</property>
</packing>
</child>
<child>
<object class="GtkStack" id="list_stack">
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkGrid">
<property name="row-spacing">6</property>
<property name="column-spacing">6</property>
<object class="GtkLabel" id="font_name_label">
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="ellipsize">end</property>
<property name="xalign">0</property>
</object>
</child>
<child>
<object class="GtkEntry" id="preview2">
<property name="can-focus">1</property>
<property name="placeholder-text" translatable="yes">Preview text</property>
<property name="text" bind-source="preview" bind-property="text" bind-flags="bidirectional"/>
<property name="attributes" bind-source="preview" bind-property="attributes" bind-flags="bidirectional"/>
<signal name="scroll-event" handler="resize_by_scroll_cb" swapped="no"/>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="shadow-type">in</property>
<property name="vexpand">1</property>
<style>
<class name="view"/>
</style>
<child>
<object class="GtkScrolledWindow" id="list_scrolled_window">
<property name="width-request">400</property>
<property name="height-request">300</property>
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="hscrollbar-policy">never</property>
<property name="shadow-type">etched-in</property>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<property name="margin">12</property>
<child>
<object class="GtkTreeView" id="family_face_list">
<property name="can-focus">1</property>
<property name="model">filter_model</property>
<property name="headers-visible">0</property>
<property name="enable-search">0</property>
<property name="fixed-height-mode">1</property>
<signal name="cursor-changed" handler="cursor_changed_cb" swapped="no"/>
<signal name="row-activated" handler="row_activated_cb" swapped="no"/>
<signal name="style-updated" handler="gtk_font_chooser_widget_set_cell_size" object="GtkFontChooserWidget" after="yes" swapped="yes"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1">
<property name="mode">browse</property>
<object class="GtkGrid" id="axis_grid">
<property name="row-spacing">6</property>
<property name="column-spacing">12</property>
<child>
<object class="GtkLabel" id="size_label2">
<property name="label" translatable="yes">Size</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkTreeViewColumn" id="family_face_column">
<property name="sizing">fixed</property>
<property name="title" translatable="yes">Font Family</property>
<object class="GtkScale" id="size_slider2">
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="adjustment">slider_adjustment</property>
<property name="draw-value">0</property>
<property name="round-digits">0</property>
<signal name="scroll-event" handler="resize_by_scroll_cb" swapped="no"/>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="size_spin2">
<property name="can-focus">1</property>
<property name="adjustment">spin_adjustment</property>
<signal name="output" handler="output_cb"/>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">0</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="feature_box">
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<child>
<object class="GtkComboBox" id="feature_language_combo">
<property name="halign">start</property>
<property name="margin-top">10</property>
<signal name="changed" handler="update_language" swapped="yes"/>
<child>
<object class="GtkCellRendererText" id="family_face_cell">
<property name="ellipsize">end</property>
</object>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="preview">
<property name="can-focus">1</property>
<property name="placeholder-text" translatable="yes">Preview text</property>
<signal name="scroll-event" handler="resize_by_scroll_cb" swapped="no"/>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkScale" id="size_slider">
<property name="can-focus">1</property>
<property name="hexpand">1</property>
<property name="adjustment">slider_adjustment</property>
<property name="draw-value">0</property>
<property name="round-digits">0</property>
<signal name="scroll-event" handler="resize_by_scroll_cb" swapped="no"/>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="size_spin">
<property name="can-focus">1</property>
<property name="adjustment">spin_adjustment</property>
<signal name="output" handler="output_cb"/>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</packing>
</child>
</object>
<packing>
<property name="name">list</property>
</packing>
</child>
<child>
<object class="GtkGrid">
<property name="row-spacing">12</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">center</property>
<property name="valign">center</property>
<style>
<class name="dim-label"/>
</style>
<child>
<object class="GtkImage">
<property name="gicon">fonticon</property>
<property name="pixel-size">64</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">No Fonts Found</property>
<attributes>
<attribute name="weight" value="bold"/>
<attribute name="scale" value="1.2"/>
</attributes>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
</object>
<packing>
<property name="name">empty</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
<property name="width">2</property>
<property name="name">tweaks</property>
</packing>
</child>
</object>
@@ -199,4 +334,154 @@
<property name="names">font-x-generic-symbolic
emblem-documents-symbolic</property>
</object>
<object class="GtkPopover" id="filter_popover">
<property name="width-request">300</property>
<signal name="notify::visible" handler="popover_notify"/>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="margin">20</property>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Script</property>
<property name="xalign">0</property>
<property name="margin-bottom">10</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="script_filter_button">
<signal name="clicked" handler="script_filter_button_clicked"/>
<child>
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkLabel" id="script_filter_button_label">
<property name="xalign">0</property>
<property name="max-width-chars">25</property>
<property name="label" translatable="yes">Any script</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkImage">
<property name="icon-name">pan-down-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkRevealer" id="script_filter_revealer">
<property name="margin-bottom">20</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">10</property>
<child>
<object class="GtkSearchEntry" id="script_filter_entry">
<property name="placeholder-text" translatable="yes">Search…</property>
<signal name="search-changed" handler="script_filter_changed" swapped="yes"/>
<signal name="stop-search" handler="script_filter_stop" swapped="yes"/>
<signal name="activate" handler="script_filter_activated" swapped="yes"/>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="shadow-type">in</property>
<property name="hscrollbar-policy">never</property>
<property name="propagate-natural-height">1</property>
<property name="max-content-height">200</property>
<child>
<object class="GtkListBox" id="script_list">
<property name="selection-mode">none</property>
<signal name="row-activated" handler="script_row_activated"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Language</property>
<property name="xalign">0</property>
<property name="margin-bottom">10</property>
<style>
<class name="dim-label"/>
</style>
</object>
</child>
<child>
<object class="GtkButton" id="language_filter_button">
<signal name="clicked" handler="language_filter_button_clicked"/>
<child>
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkLabel" id="language_filter_button_label">
<property name="xalign">0</property>
<property name="max-width-chars">25</property>
<property name="label" translatable="yes">Any language</property>
<property name="hexpand">1</property>
</object>
</child>
<child>
<object class="GtkImage">
<property name="icon-name">pan-down-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkRevealer" id="language_filter_revealer">
<property name="margin-bottom">20</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">10</property>
<child>
<object class="GtkSearchEntry" id="language_filter_entry">
<property name="placeholder-text" translatable="yes">Search…</property>
<signal name="search-changed" handler="language_filter_changed" swapped="yes"/>
<signal name="stop-search" handler="language_filter_stop" swapped="yes"/>
<signal name="activate" handler="language_filter_activated" swapped="yes"/>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="shadow-type">in</property>
<property name="hscrollbar-policy">never</property>
<property name="propagate-natural-height">1</property>
<property name="max-content-height">200</property>
<child>
<object class="GtkListBox" id="language_list">
<property name="selection-mode">none</property>
<signal name="row-activated" handler="language_row_activated"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkCheckButton" id="monospace_filter_check">
<property name="label" translatable="yes">Only monospace</property>
<signal name="notify::active" handler="gtk_font_chooser_widget_refilter_font_list" swapped="yes"/>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -346,6 +346,9 @@ else
platform_gio_dep = giounix_dep
endif
cdata.set('HAVE_HARFBUZZ', harfbuzz_dep.found())
cdata.set('HAVE_PANGOFT', pangoft_dep.found())
backend_immodules = []
pc_gdk_extra_libs = []