Compare commits

...

18 Commits

Author SHA1 Message Date
Chun-wei Fan
24d25b0db5 build: Check HarfBuzz has GDI support built in on Windows
We are using APIs from there.  Also enable GDI and DirectWrite if we are
building HarfBuzz as a fallback, and remove an extraneous HarfBuzz dependency
declaration.
2022-07-08 17:14:04 +08:00
Chun-wei Fan
30147b1a99 gtkimcontextime.c: Port to Pango2 APIs
Update the code to use Pango2 APIs, by removing includes to pangowin32, which
is gone, and replacing relevant calls to Pango2 equivilants.

Replace the call to pango_win32_font_logfontw() by retrieving instead the
underlying hb_font_t, and calling hb_uniscribe_font_get_logfontw(), but preedit
fonts are currently not working until a resolution to HarfBuzz issue #3683 can
be found.  Since we are still using Windows IME APIs for input, we need the
HarfBuzz GDI/Uniscribe items to be included in the HarfBuzz builds.
2022-07-08 17:14:04 +08:00
Chun-wei Fan
3979def662 GSK Vulkan: WIP port to Pango2 2022-07-08 17:14:04 +08:00
Chun-wei Fan
71ea2e2ecb gdk/win32: WIP Port to Pango2 2022-07-08 17:13:54 +08:00
Chun-wei Fan
c79b4e2e56 build: Don't try to use pangowin32 in deps
It's no longer there for Pango2.
2022-07-08 11:53:29 +08:00
Matthias Clasen
f7c4b26c59 Make a standalone font explorer
This is the font features demo, broken out as
a standalone application and cleaned up.
2022-07-06 13:45:11 -04:00
Matthias Clasen
a13cfde2a9 fixup clear_template 2022-07-05 20:43:53 -04:00
Emmanuele Bassi
3a5d161b8a Add gtk_widget_clear_template()
The dual of gtk_widget_init_template(), which should be used to clear
the template data associated with a specific GtkWidget type.
2022-07-05 20:43:53 -04:00
Matthias Clasen
baabb57df3 font demo: Keep up with api churn 2022-07-05 14:22:04 -04:00
Matthias Clasen
a69d39d945 fontchooser: Small fixes
Make initial property values match.
2022-07-05 14:22:04 -04:00
Matthias Clasen
646149bc72 Fontchooser: Add palette support
For fonts that have color palettes, optionally
allow the user to select one.

This is behind the new GTK_FONT_CHOOSER_LEVEL_PALETTE
flag. If it is enabled, you can use
gtk_font_chooser_get_palette() to get the
selected palette name.

The testfontchooserdialog test lets you play with
this. Fonts to try tihs with are Amiri Quran Colored
or the Bungee Color family.
2022-07-04 10:37:20 -04:00
Matthias Clasen
b01eb0600c Font demo: Add color palettes 2022-07-04 10:36:52 -04:00
Matthias Clasen
5b92bf51a0 Font demo: Keep a single paragraph
This is currently required for line height to
take effect (we may want to make the leading-trim
changeable).
2022-07-04 10:36:52 -04:00
Matthias Clasen
8ab180b3a9 Port to pango2 api 2022-07-04 10:36:48 -04:00
Matthias Clasen
897195b2f5 Compare family names case-insensitively 2022-07-04 10:36:47 -04:00
Matthias Clasen
d595cc1c55 Use modern C++
This is needed to build HarfBuzz as a subproject.
2022-07-04 10:36:47 -04:00
Matthias Clasen
2841256260 fontchooser: Make size level effective
We were not hiding the size controls on the tweaks
page, which is arguably what should happen when
the size level is disabled.
2022-07-04 10:36:47 -04:00
Matthias Clasen
ff0fec0f7d Beef up testfontchooserdialog
Allow testing levels.
2022-07-04 10:36:47 -04:00
234 changed files with 10747 additions and 4661 deletions

View File

@@ -28,7 +28,7 @@ pacman --noconfirm -S --needed \
mingw-w64-$MSYS2_ARCH-graphene \
mingw-w64-$MSYS2_ARCH-json-glib \
mingw-w64-$MSYS2_ARCH-libepoxy \
mingw-w64-$MSYS2_ARCH-pango \
mingw-w64-$MSYS2_ARCH-pango2 \
mingw-w64-$MSYS2_ARCH-fribidi \
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
mingw-w64-$MSYS2_ARCH-shared-mime-info \

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,287 @@
#include "fontcolors.h"
#include "rangeedit.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
enum {
PROP_FONT_DESC = 1,
PROP_PALETTE,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _FontColors
{
GtkWidget parent;
GtkGrid *label;
GtkGrid *grid;
Pango2FontDescription *font_desc;
GSimpleAction *reset_action;
gboolean has_colors;
char *palette;
GtkCheckButton *default_check;
};
struct _FontColorsClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (FontColors, font_colors, GTK_TYPE_WIDGET);
static Pango2Font *
get_font (FontColors *self)
{
Pango2Context *context;
context = gtk_widget_get_pango_context (GTK_WIDGET (self));
return pango2_context_load_font (context, self->font_desc);
}
static void
palette_changed (GtkCheckButton *button,
FontColors *self)
{
g_free (self->palette);
self->palette = g_strdup ((const char *) g_object_get_data (G_OBJECT (button), "palette"));
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PALETTE]);
}
static void
update_colors (FontColors *self)
{
Pango2Font *font;
hb_font_t *hb_font;
hb_face_t *hb_face;
GtkWidget *child;
GtkWidget *check;
unsigned int n_colors;
hb_color_t *colors;
GtkWidget *box;
g_object_ref (self->label);
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self->grid))))
gtk_grid_remove (self->grid, child);
gtk_grid_attach (self->grid, GTK_WIDGET (self->label), 0, -4, 2, 1);
g_object_unref (self->label);
self->default_check = NULL;
font = get_font (self);
hb_font = pango2_font_get_hb_font (font);
hb_face = hb_font_get_face (hb_font);
self->has_colors = hb_ot_color_has_palettes (hb_face);
gtk_widget_set_visible (GTK_WIDGET (self), self->has_colors);
if (!self->has_colors)
{
g_simple_action_set_enabled (self->reset_action, FALSE);
return;
}
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
gtk_grid_attach (self->grid, box, 0, -3, 2, 1);
check = gtk_check_button_new_with_label ("Default");
g_object_set_data (G_OBJECT (check), "palette", (gpointer)"default");
if (g_strcmp0 ("default", self->palette) == 0)
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
gtk_box_append (GTK_BOX (box), check);
self->default_check = GTK_CHECK_BUTTON (check);
check = gtk_check_button_new_with_label ("Light");
g_object_set_data (G_OBJECT (check), "palette", (gpointer)"light");
if (g_strcmp0 ("light", self->palette) == 0)
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
gtk_check_button_set_group (GTK_CHECK_BUTTON (check), self->default_check);
gtk_box_append (GTK_BOX (box), check);
check = gtk_check_button_new_with_label ("Dark");
g_object_set_data (G_OBJECT (check), "palette", (gpointer)"dark");
if (g_strcmp0 ("dark", self->palette) == 0)
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
gtk_check_button_set_group (GTK_CHECK_BUTTON (check), self->default_check);
gtk_box_append (GTK_BOX (box), check);
for (int i = 0; i < hb_ot_color_palette_get_count (hb_face); i++)
{
char *id = g_strdup_printf ("palette%d", i);
char *label = g_strdup_printf ("Palette %d", i);
GtkWidget *palette;
check = gtk_check_button_new_with_label (label);
g_object_set_data_full (G_OBJECT (check), "palette", id, g_free);
if (g_strcmp0 (id, self->palette) == 0)
gtk_check_button_set_active (GTK_CHECK_BUTTON (check), TRUE);
g_signal_connect (check, "toggled", G_CALLBACK (palette_changed), self);
gtk_check_button_set_group (GTK_CHECK_BUTTON (check), self->default_check);
gtk_grid_attach (self->grid, check, 0, i, 1, 1);
n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, NULL, NULL);
colors = g_new (hb_color_t, n_colors);
n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, &n_colors, colors);
palette = gtk_grid_new ();
gtk_widget_set_valign (palette, GTK_ALIGN_CENTER);
gtk_grid_attach (self->grid, palette, 1, i, 1, 1);
/* HACK - defeat first-child/last-child theming */
gtk_grid_attach (GTK_GRID (palette), gtk_picture_new (), -1, 0, 1, 1);
for (int k = 0; k < n_colors; k++)
{
GtkWidget *swatch;
swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
"rgba", &(GdkRGBA){ hb_color_get_red (colors[k])/255.,
hb_color_get_green (colors[k])/255.,
hb_color_get_blue (colors[k])/255.,
hb_color_get_alpha (colors[k])/255.},
"selectable", FALSE,
"has-menu", FALSE,
"can-drag", FALSE,
"width-request", 16,
"height-request", 16,
NULL);
gtk_grid_attach (GTK_GRID (palette), swatch, k % 6, k / 6, 1, 1);
}
/* HACK - defeat first-child/last-child theming */
gtk_grid_attach (GTK_GRID (palette), gtk_picture_new (), 6, 0, 1, 1);
}
}
static void
reset (GSimpleAction *action,
GVariant *parameter,
FontColors *self)
{
g_free (self->palette);
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
if (self->has_colors)
gtk_check_button_set_active (self->default_check, TRUE);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_PALETTE]);
g_simple_action_set_enabled (self->reset_action, FALSE);
}
static void
font_colors_init (FontColors *self)
{
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
gtk_widget_init_template (GTK_WIDGET (self));
self->reset_action = g_simple_action_new ("reset", NULL);
g_simple_action_set_enabled (self->reset_action, FALSE);
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
}
static void
font_colors_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), FONT_COLORS_TYPE);
G_OBJECT_CLASS (font_colors_parent_class)->dispose (object);
}
static void
font_colors_finalize (GObject *object)
{
FontColors *self = FONT_COLORS (object);
g_clear_pointer (&self->font_desc, pango2_font_description_free);
g_free (self->palette);
G_OBJECT_CLASS (font_colors_parent_class)->finalize (object);
}
static void
font_colors_set_property (GObject *object,
unsigned int prop_id,
const GValue *value,
GParamSpec *pspec)
{
FontColors *self = FONT_COLORS (object);
switch (prop_id)
{
case PROP_FONT_DESC:
pango2_font_description_free (self->font_desc);
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
update_colors (self);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_colors_get_property (GObject *object,
unsigned int prop_id,
GValue *value,
GParamSpec *pspec)
{
FontColors *self = FONT_COLORS (object);
switch (prop_id)
{
case PROP_PALETTE:
g_value_set_string (value, self->palette);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_colors_class_init (FontColorsClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = font_colors_dispose;
object_class->finalize = font_colors_finalize;
object_class->get_property = font_colors_get_property;
object_class->set_property = font_colors_set_property;
properties[PROP_FONT_DESC] =
g_param_spec_boxed ("font-desc", "", "",
PANGO2_TYPE_FONT_DESCRIPTION,
G_PARAM_WRITABLE);
properties[PROP_PALETTE] =
g_param_spec_string ("palette", "", "",
PANGO2_COLOR_PALETTE_DEFAULT,
G_PARAM_READABLE);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/fontcolors.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontColors, grid);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontColors, label);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontcolors");
}
FontColors *
font_colors_new (void)
{
return g_object_new (FONT_COLORS_TYPE, NULL);
}
GAction *
font_colors_get_reset_action (FontColors *self)
{
return G_ACTION (self->reset_action);
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include <gtk/gtk.h>
#define FONT_COLORS_TYPE (font_colors_get_type ())
#define FONT_COLORS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_COLORS_TYPE, FontColors))
typedef struct _FontColors FontColors;
typedef struct _FontColorsClass FontColorsClass;
GType font_colors_get_type (void);
FontColors * font_colors_new (void);
GAction * font_colors_get_reset_action (FontColors *self);

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FontColors" parent="GtkWidget">
<property name="layout-manager"><object class="GtkBinLayout"/></property>
<child>
<object class="GtkGrid" id="grid">
<child>
<object class="GtkLabel" id="label">
<property name="label" translatable="yes">Colors</property>
<property name="margin-bottom">10</property>
<property name="xalign">0</property>
<style>
<class name="heading"/>
</style>
<layout>
<property name="row">-2</property>
<property name="column">0</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -0,0 +1,271 @@
#include "fontcontrols.h"
#include "rangeedit.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
enum {
PROP_SIZE = 1,
PROP_LETTERSPACING,
PROP_LINE_HEIGHT,
PROP_FOREGROUND,
PROP_BACKGROUND,
PROP_DISABLE_SIZE,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _FontControls
{
GtkWidget parent;
GtkAdjustment *size_adjustment;
GtkAdjustment *letterspacing_adjustment;
GtkAdjustment *line_height_adjustment;
GtkColorButton *foreground;
GtkColorButton *background;
GSimpleAction *reset_action;
gboolean disable_size;
};
struct _FontControlsClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(FontControls, font_controls, GTK_TYPE_WIDGET);
static void
size_changed (GtkAdjustment *adjustment,
FontControls *self)
{
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SIZE]);
g_simple_action_set_enabled (self->reset_action, TRUE);
}
static void
letterspacing_changed (GtkAdjustment *adjustment,
FontControls *self)
{
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LETTERSPACING]);
g_simple_action_set_enabled (self->reset_action, TRUE);
}
static void
line_height_changed (GtkAdjustment *adjustment,
FontControls *self)
{
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LINE_HEIGHT]);
g_simple_action_set_enabled (self->reset_action, TRUE);
}
static void
color_set (GtkColorButton *button,
GParamSpec *pspec,
FontControls *self)
{
if (button == self->foreground)
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FOREGROUND]);
else
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_BACKGROUND]);
g_simple_action_set_enabled (self->reset_action, TRUE);
}
static void
swap_colors (GtkButton *button,
FontControls *self)
{
GdkRGBA fg;
GdkRGBA bg;
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->foreground), &fg);
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->background), &bg);
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->foreground), &bg);
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->background), &fg);
}
static void
reset (GSimpleAction *action,
GVariant *parameter,
FontControls *self)
{
gtk_adjustment_set_value (self->size_adjustment, 12.);
gtk_adjustment_set_value (self->letterspacing_adjustment, 0.);
gtk_adjustment_set_value (self->line_height_adjustment, 1.);
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->foreground), &(GdkRGBA){0., 0., 0., 1.0 });
gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (self->background), &(GdkRGBA){1., 1., 1., 1.0 });
g_simple_action_set_enabled (self->reset_action, FALSE);
}
static void
font_controls_init (FontControls *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
self->reset_action = g_simple_action_new ("reset", NULL);
g_simple_action_set_enabled (self->reset_action, FALSE);
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
}
static void
font_controls_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), FONT_CONTROLS_TYPE);
G_OBJECT_CLASS (font_controls_parent_class)->dispose (object);
}
static void
font_controls_finalize (GObject *object)
{
//FontControls *self = FONT_CONTROLS (object);
G_OBJECT_CLASS (font_controls_parent_class)->finalize (object);
}
static void
font_controls_set_property (GObject *object,
unsigned int prop_id,
const GValue *value,
GParamSpec *pspec)
{
FontControls *self = FONT_CONTROLS (object);
switch (prop_id)
{
case PROP_SIZE:
gtk_adjustment_set_value (self->size_adjustment, g_value_get_float (value));
break;
case PROP_DISABLE_SIZE:
self->disable_size = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_controls_get_property (GObject *object,
unsigned int prop_id,
GValue *value,
GParamSpec *pspec)
{
FontControls *self = FONT_CONTROLS (object);
switch (prop_id)
{
case PROP_SIZE:
g_value_set_float (value, gtk_adjustment_get_value (self->size_adjustment));
break;
case PROP_LETTERSPACING:
g_value_set_int (value, (int) gtk_adjustment_get_value (self->letterspacing_adjustment));
break;
case PROP_LINE_HEIGHT:
g_value_set_float (value, gtk_adjustment_get_value (self->line_height_adjustment));
break;
case PROP_FOREGROUND:
{
GdkRGBA rgba;
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->foreground), &rgba);
g_value_set_boxed (value, &rgba);
}
break;
case PROP_BACKGROUND:
{
GdkRGBA rgba;
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (self->background), &rgba);
g_value_set_boxed (value, &rgba);
}
break;
case PROP_DISABLE_SIZE:
g_value_set_boolean (value, self->disable_size);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_controls_class_init (FontControlsClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
g_type_ensure (RANGE_EDIT_TYPE);
object_class->dispose = font_controls_dispose;
object_class->finalize = font_controls_finalize;
object_class->get_property = font_controls_get_property;
object_class->set_property = font_controls_set_property;
properties[PROP_SIZE] =
g_param_spec_float ("size", "", "",
0., 100., 12.,
G_PARAM_READABLE);
properties[PROP_LETTERSPACING] =
g_param_spec_int ("letterspacing", "", "",
-G_MAXINT, G_MAXINT, 0,
G_PARAM_READABLE);
properties[PROP_LINE_HEIGHT] =
g_param_spec_float ("line-height", "", "",
0., 100., 1.,
G_PARAM_READABLE);
properties[PROP_FOREGROUND] =
g_param_spec_boxed ("foreground", "", "",
GDK_TYPE_RGBA,
G_PARAM_READABLE);
properties[PROP_BACKGROUND] =
g_param_spec_boxed ("background", "", "",
GDK_TYPE_RGBA,
G_PARAM_READABLE);
properties[PROP_DISABLE_SIZE] =
g_param_spec_boolean ("disable-size", "", "",
FALSE,
G_PARAM_READWRITE);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/fontcontrols.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, size_adjustment);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, letterspacing_adjustment);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, line_height_adjustment);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, foreground);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontControls, background);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), size_changed);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), letterspacing_changed);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), line_height_changed);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), color_set);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), swap_colors);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontcontrols");
}
FontControls *
font_controls_new (void)
{
return g_object_new (FONT_CONTROLS_TYPE, NULL);
}
GAction *
font_controls_get_reset_action (FontControls *self)
{
return G_ACTION (self->reset_action);
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include <gtk/gtk.h>
#define FONT_CONTROLS_TYPE (font_controls_get_type ())
#define FONT_CONTROLS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_CONTROLS_TYPE, FontControls))
typedef struct _FontControls FontControls;
typedef struct _FontControlsClass FontControlsClass;
GType font_controls_get_type (void);
FontControls * font_controls_new (void);
GAction * font_controls_get_reset_action (FontControls *self);

View File

@@ -0,0 +1,175 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FontControls" parent="GtkWidget">
<property name="layout-manager"><object class="GtkGridLayout"/></property>
<child>
<object class="GtkLabel">
<property name="sensitive" bind-source="FontControls" bind-property="disable-size" bind-flags="invert-boolean"/>
<property name="label">Size</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="RangeEdit">
<property name="sensitive" bind-source="FontControls" bind-property="disable-size" bind-flags="invert-boolean"/>
<property name="hexpand">1</property>
<property name="width-request">160</property>
<property name="valign">baseline</property>
<property name="adjustment">
<object class="GtkAdjustment" id="size_adjustment">
<property name="lower">7</property>
<property name="upper">100</property>
<property name="value">14</property>
<property name="step_increment">0.5</property>
<property name="page_increment">10</property>
<signal name="value-changed" handler="size_changed"/>
</object>
</property>
<property name="default-value">12</property>
<property name="n-chars">5</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Letterspacing</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="RangeEdit">
<property name="hexpand">1</property>
<property name="width-request">160</property>
<property name="valign">baseline</property>
<property name="adjustment">
<object class="GtkAdjustment" id="letterspacing_adjustment">
<property name="lower">-1024</property>
<property name="upper">8192</property>
<property name="value">0</property>
<property name="step_increment">1</property>
<property name="page_increment">512</property>
<signal name="value-changed" handler="letterspacing_changed"/>
</object>
</property>
<property name="default-value">0</property>
<property name="n-chars">5</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Line Height</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="RangeEdit">
<property name="hexpand">1</property>
<property name="width-request">160</property>
<property name="valign">baseline</property>
<property name="adjustment">
<object class="GtkAdjustment" id="line_height_adjustment">
<property name="lower">0.75</property>
<property name="upper">2.5</property>
<property name="value">1.0</property>
<property name="step_increment">0.1</property>
<property name="page_increment">1</property>
<signal name="value-changed" handler="line_height_changed"/>
</object>
</property>
<property name="default-value">1</property>
<property name="n-chars">5</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Foreground</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkColorButton" id="foreground">
<property name="rgba">black</property>
<signal name="notify::rgba" handler="color_set"/>
<layout>
<property name="column">1</property>
<property name="row">3</property>
</layout>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="label">Background</property>
<property name="xalign">0</property>
<property name="valign">baseline</property>
<layout>
<property name="column">0</property>
<property name="row">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkColorButton" id="background">
<property name="rgba">white</property>
<signal name="notify::rgba" handler="color_set"/>
<layout>
<property name="column">1</property>
<property name="row">4</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="icon-name">object-flip-vertical-symbolic</property>
<property name="halign">start</property>
<property name="valign">center</property>
<style>
<class name="circular"/>
</style>
<signal name="clicked" handler="swap_colors"/>
<layout>
<property name="column">2</property>
<property name="row">3</property>
<property name="row-span">2</property>
</layout>
</object>
</child>
</template>
</interface>

View File

@@ -0,0 +1,20 @@
box.sidebar {
padding: 20px;
border-spacing: 20px;
}
fontcontrols {
border-spacing: 10px;
}
fontvariations > grid {
border-spacing: 10px;
}
fontcolors > grid {
border-spacing: 10px;
}
samplechooser {
border-spacing: 10px;
}
fontview {
padding: 10px;
border-spacing: 10px;
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gtk/fontexplorer">
<file preprocess="xml-stripblanks">fontexplorerwin.ui</file>
<file preprocess="xml-stripblanks">fontview.ui</file>
<file preprocess="xml-stripblanks">fontcontrols.ui</file>
<file preprocess="xml-stripblanks">samplechooser.ui</file>
<file preprocess="xml-stripblanks">fontcolors.ui</file>
<file preprocess="xml-stripblanks">fontfeatures.ui</file>
<file preprocess="xml-stripblanks">fontvariations.ui</file>
<file preprocess="xml-stripblanks">rangeedit.ui</file>
<file>fontexplorer.css</file>
</gresource>
</gresources>

View File

@@ -0,0 +1,165 @@
#include "config.h"
#include <gtk/gtk.h>
#include "fontexplorerapp.h"
#include "fontexplorerwin.h"
#include "demo_conf.h"
struct _FontExplorerApp
{
GtkApplication parent;
};
struct _FontExplorerAppClass
{
GtkApplicationClass parent_class;
};
G_DEFINE_TYPE(FontExplorerApp, font_explorer_app, GTK_TYPE_APPLICATION);
static void
font_explorer_app_init (FontExplorerApp *app)
{
}
static void
quit_activated (GSimpleAction *action,
GVariant *parameter,
gpointer app)
{
g_application_quit (G_APPLICATION (app));
}
static void
inspector_activated (GSimpleAction *action,
GVariant *parameter,
gpointer app)
{
gtk_window_set_interactive_debugging (TRUE);
}
static void
about_activated (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GtkApplication *app = user_data;
const char *authors[] = {
"The GTK Team",
NULL
};
char *icon_theme;
char *version;
GString *s;
char *os_name;
char *os_version;
g_object_get (gtk_settings_get_default (),
"gtk-icon-theme-name", &icon_theme,
NULL);
s = g_string_new ("");
os_name = g_get_os_info (G_OS_INFO_KEY_NAME);
os_version = g_get_os_info (G_OS_INFO_KEY_VERSION_ID);
if (os_name && os_version)
g_string_append_printf (s, "OS\t%s %s\n\n", os_name, os_version);
g_string_append (s, "System libraries\n");
g_string_append_printf (s, "\tGLib\t%d.%d.%d\n",
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (s, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());
g_string_append_printf (s, "\nIcon theme\n\t%s", icon_theme);
version = g_strdup_printf ("%s%s%s\nRunning against GTK %d.%d.%d",
PACKAGE_VERSION,
g_strcmp0 (PROFILE, "devel") == 0 ? "-" : "",
g_strcmp0 (PROFILE, "devel") == 0 ? VCS_TAG : "",
gtk_get_major_version (),
gtk_get_minor_version (),
gtk_get_micro_version ());
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
"program-name", g_strcmp0 (PROFILE, "devel") == 0
? "GTK Font Explorer (Development)"
: "GTK Font Explorer",
"version", version,
"copyright", "©1997—2021 The GTK Team",
"license-type", GTK_LICENSE_LGPL_2_1,
"website", "http://www.gtk.org",
"comments", "Program to explore font features",
"authors", authors,
"logo-icon-name", "org.gtk.FontExplorer",
"title", "About GTK Font Explorer",
"system-information", s->str,
NULL);
g_string_free (s, TRUE);
g_free (version);
g_free (icon_theme);
g_free (os_name);
g_free (os_version);
}
static GActionEntry app_entries[] =
{
{ "quit", quit_activated, NULL, NULL, NULL },
{ "inspector", inspector_activated, NULL, NULL, NULL },
{ "about", about_activated, NULL, NULL, NULL }
};
static void
font_explorer_app_startup (GApplication *app)
{
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
GtkCssProvider *provider;
G_APPLICATION_CLASS (font_explorer_app_parent_class)->startup (app);
g_action_map_add_action_entries (G_ACTION_MAP (app),
app_entries, G_N_ELEMENTS (app_entries),
app);
gtk_application_set_accels_for_action (GTK_APPLICATION (app),
"app.quit",
quit_accels);
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider, "/org/gtk/fontexplorer/fontexplorer.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
static void
font_explorer_app_activate (GApplication *app)
{
FontExplorerWindow *win;
win = font_explorer_window_new (FONT_EXPLORER_APP (app));
if (g_strcmp0 (PROFILE, "devel") == 0)
gtk_widget_add_css_class (GTK_WIDGET (win), "devel");
gtk_window_present (GTK_WINDOW (win));
}
static void
font_explorer_app_class_init (FontExplorerAppClass *class)
{
G_APPLICATION_CLASS (class)->startup = font_explorer_app_startup;
G_APPLICATION_CLASS (class)->activate = font_explorer_app_activate;
}
FontExplorerApp *
font_explorer_app_new (void)
{
return g_object_new (FONT_EXPLORER_APP_TYPE,
"application-id", "org.gtk.FontExplorer",
NULL);
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include <gtk/gtk.h>
#define FONT_EXPLORER_APP_TYPE (font_explorer_app_get_type ())
#define FONT_EXPLORER_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_EXPLORER_APP_TYPE, FontExplorerApp))
typedef struct _FontExplorerApp FontExplorerApp;
typedef struct _FontExplorerAppClass FontExplorerAppClass;
GType font_explorer_app_get_type (void);
FontExplorerApp * font_explorer_app_new (void);

View File

@@ -0,0 +1,131 @@
#include "fontexplorerapp.h"
#include "fontexplorerwin.h"
#include "fontview.h"
#include "fontcontrols.h"
#include "samplechooser.h"
#include "fontcolors.h"
#include "fontfeatures.h"
#include "fontvariations.h"
#include <gtk/gtk.h>
#include <string.h>
struct _FontExplorerWindow
{
GtkApplicationWindow parent;
GtkFontButton *fontbutton;
FontControls *controls;
FontFeatures *features;
FontVariations *variations;
FontColors *colors;
FontView *view;
};
struct _FontExplorerWindowClass
{
GtkApplicationWindowClass parent_class;
};
G_DEFINE_TYPE(FontExplorerWindow, font_explorer_window, GTK_TYPE_APPLICATION_WINDOW);
static void
reset (GSimpleAction *action,
GVariant *parameter,
FontExplorerWindow *win)
{
g_action_activate (font_controls_get_reset_action (win->controls), NULL);
g_action_activate (font_features_get_reset_action (win->features), NULL);
g_action_activate (font_variations_get_reset_action (win->variations), NULL);
g_action_activate (font_colors_get_reset_action (win->colors), NULL);
}
static void
update_reset (GSimpleAction *action,
GParamSpec *pspec,
FontExplorerWindow *win)
{
gboolean enabled;
GAction *reset_action;
enabled = g_action_get_enabled (font_controls_get_reset_action (win->controls)) ||
g_action_get_enabled (font_features_get_reset_action (win->features)) ||
g_action_get_enabled (font_variations_get_reset_action (win->variations)) ||
g_action_get_enabled (font_colors_get_reset_action (win->colors));
reset_action = g_action_map_lookup_action (G_ACTION_MAP (win), "reset");
g_simple_action_set_enabled (G_SIMPLE_ACTION (reset_action), enabled);
}
static void
font_explorer_window_init (FontExplorerWindow *win)
{
GSimpleAction *reset_action;
gtk_widget_init_template (GTK_WIDGET (win));
reset_action = g_simple_action_new ("reset", NULL);
g_signal_connect (reset_action, "activate", G_CALLBACK (reset), win);
g_signal_connect (font_controls_get_reset_action (win->controls),
"notify::enabled", G_CALLBACK (update_reset), win);
g_signal_connect (font_variations_get_reset_action (win->variations),
"notify::enabled", G_CALLBACK (update_reset), win);
g_signal_connect (font_colors_get_reset_action (win->colors),
"notify::enabled", G_CALLBACK (update_reset), win);
g_signal_connect (font_features_get_reset_action (win->features),
"notify::enabled", G_CALLBACK (update_reset), win);
g_action_map_add_action (G_ACTION_MAP (win), G_ACTION (reset_action));
update_reset (NULL, NULL, win);
}
static void
font_explorer_window_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), FONT_EXPLORER_WINDOW_TYPE);
G_OBJECT_CLASS (font_explorer_window_parent_class)->dispose (object);
}
static void
font_explorer_window_finalize (GObject *object)
{
// FontExplorerWindow *win = FONT_EXPLORER_WINDOW (object);
G_OBJECT_CLASS (font_explorer_window_parent_class)->finalize (object);
}
static void
font_explorer_window_class_init (FontExplorerWindowClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
g_type_ensure (FONT_VIEW_TYPE);
g_type_ensure (FONT_CONTROLS_TYPE);
g_type_ensure (SAMPLE_CHOOSER_TYPE);
g_type_ensure (FONT_VARIATIONS_TYPE);
g_type_ensure (FONT_COLORS_TYPE);
g_type_ensure (FONT_FEATURES_TYPE);
object_class->dispose = font_explorer_window_dispose;
object_class->finalize = font_explorer_window_finalize;
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/fontexplorerwin.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, fontbutton);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, controls);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, variations);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, colors);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, features);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, view);
}
FontExplorerWindow *
font_explorer_window_new (FontExplorerApp *app)
{
return g_object_new (FONT_EXPLORER_WINDOW_TYPE, "application", app, NULL);
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include <gtk/gtk.h>
#include "fontexplorerapp.h"
#define FONT_EXPLORER_WINDOW_TYPE (font_explorer_window_get_type ())
#define FONT_EXPLORER_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_EXPLORER_WINDOW_TYPE, FontExplorerWindow))
typedef struct _FontExplorerWindow FontExplorerWindow;
typedef struct _FontExplorerWindowClass FontExplorerWindowClass;
GType font_explorer_window_get_type (void);
FontExplorerWindow * font_explorer_window_new (FontExplorerApp *app);

View File

@@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="gear_menu">
<section>
<item>
<attribute name="label" translatable="yes">_Inspector</attribute>
<attribute name="action">app.inspector</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_About GTK Font Explorer</attribute>
<attribute name="action">app.about</attribute>
</item>
</section>
</menu>
<template class="FontExplorerWindow" parent="GtkApplicationWindow">
<property name="title" translatable="yes">Font Explorer</property>
<property name="default-width">1024</property>
<property name="default-height">768</property>
<child type="titlebar">
<object class="GtkHeaderBar">
<child>
<object class="GtkButton" id="reset">
<property name="receives-default">1</property>
<property name="tooltip-text">Reset</property>
<property name="icon-name">view-refresh-symbolic</property>
<property name="action-name">win.reset</property>
</object>
</child>
<child type="end">
<object class="GtkMenuButton" id="gear_menu_button">
<property name="focus-on-click">0</property>
<property name="valign">center</property>
<property name="menu-model">gear_menu</property>
<property name="icon-name">open-menu-symbolic</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<style>
<class name="sidebar"/>
</style>
<child>
<object class="GtkFontButton" id="fontbutton">
<property name="level">family|style</property>
</object>
</child>
<child>
<object class="FontControls" id="controls">
<property name="disable-size" bind-source="view" bind-property="ignore-size" bind-flags="sync-create"/>
</object>
</child>
<child>
<object class="SampleChooser" id="samplechooser"/>
</child>
<child>
<object class="FontVariations" id="variations">
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
</object>
</child>
<child>
<object class="FontFeatures" id="features">
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
<property name="language" bind-source="fontbutton" bind-flags="sync-create"/>
</object>
</child>
<child>
<object class="FontColors" id="colors">
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="FontView" id="view">
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
<property name="size" bind-source="controls" bind-flags="sync-create"/>
<property name="letterspacing" bind-source="controls" bind-flags="sync-create"/>
<property name="line-height" bind-source="controls" bind-flags="sync-create"/>
<property name="foreground" bind-source="controls" bind-flags="sync-create"/>
<property name="background" bind-source="controls" bind-flags="sync-create"/>
<property name="sample-text" bind-source="samplechooser" bind-flags="sync-create"/>
<property name="features" bind-source="features" bind-flags="sync-create"/>
<property name="variations" bind-source="variations" bind-flags="sync-create"/>
<property name="palette" bind-source="colors" bind-flags="sync-create"/>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -0,0 +1,727 @@
#include "fontfeatures.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
#include <glib/gi18n.h>
#include "open-type-layout.h"
#include "language-names.h"
enum {
PROP_FONT_DESC = 1,
PROP_LANGUAGE,
PROP_FEATURES,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
typedef struct {
unsigned int tag;
const char *name;
GtkWidget *feat;
} FeatureItem;
struct _FontFeatures
{
GtkWidget parent;
GtkGrid *label;
GtkGrid *grid;
Pango2FontDescription *font_desc;
GSimpleAction *reset_action;
Pango2Language *lang;
GList *feature_items;
};
struct _FontFeaturesClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(FontFeatures, font_features, GTK_TYPE_WIDGET);
static Pango2Font *
get_font (FontFeatures *self)
{
Pango2Context *context;
context = gtk_widget_get_pango_context (GTK_WIDGET (self));
return pango2_context_load_font (context, self->font_desc);
}
static gboolean
is_ssNN (const char *buf)
{
return g_str_has_prefix (buf, "ss") && g_ascii_isdigit (buf[2]) && g_ascii_isdigit (buf[3]);
}
static gboolean
is_cvNN (const char *buf)
{
return g_str_has_prefix (buf, "cv") && g_ascii_isdigit (buf[2]) && g_ascii_isdigit (buf[3]);
}
static char *
get_feature_display_name (unsigned int tag)
{
int i;
static char buf[5] = { 0, };
if (tag == HB_TAG ('x', 'x', 'x', 'x'))
return g_strdup (_("Default"));
hb_tag_to_string (tag, buf);
if (is_ssNN (buf))
{
int num = (buf[2] - '0') * 10 + (buf[3] - '0');
return g_strdup_printf (g_dpgettext2 (NULL, "OpenType layout", "Stylistic Set %d"), num);
}
else if (is_cvNN (buf))
{
int num = (buf[2] - '0') * 10 + (buf[3] - '0');
return g_strdup_printf (g_dpgettext2 (NULL, "OpenType layout", "Character Variant %d"), num);
}
for (i = 0; i < G_N_ELEMENTS (open_type_layout_features); i++)
{
if (tag == open_type_layout_features[i].tag)
return g_strdup (g_dpgettext2 (NULL, "OpenType layout", open_type_layout_features[i].name));
}
g_warning ("unknown OpenType layout feature tag: %s", buf);
return g_strdup (buf);
}
static void
update_feature_label (FontFeatures *self,
FeatureItem *item,
hb_font_t *hb_font,
hb_tag_t script_tag,
hb_tag_t lang_tag)
{
hb_face_t *hb_face;
unsigned int script_index, lang_index, feature_index;
hb_ot_name_id_t id;
unsigned int len;
char *label;
char name[5] = { 0, };
hb_face = hb_font_get_face (hb_font);
hb_tag_to_string (item->tag, name);
if (!is_ssNN (name) && !is_cvNN (name))
return;
hb_ot_layout_table_find_script (hb_face, HB_OT_TAG_GSUB, script_tag, &script_index);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
hb_ot_layout_script_find_language (hb_face, HB_OT_TAG_GSUB, script_index, lang_tag, &lang_index);
G_GNUC_END_IGNORE_DEPRECATIONS
if (hb_ot_layout_language_find_feature (hb_face, HB_OT_TAG_GSUB, script_index, lang_index, item->tag, &feature_index) &&
hb_ot_layout_feature_get_name_ids (hb_face, HB_OT_TAG_GSUB, feature_index, &id, NULL, NULL, NULL, NULL))
{
len = hb_ot_name_get_utf8 (hb_face, id, HB_LANGUAGE_INVALID, NULL, NULL);
len++;
label = g_new (char, len);
hb_ot_name_get_utf8 (hb_face, id, HB_LANGUAGE_INVALID, &len, label);
gtk_check_button_set_label (GTK_CHECK_BUTTON (item->feat), label);
g_free (label);
}
else
{
label = get_feature_display_name (item->tag);
gtk_check_button_set_label (GTK_CHECK_BUTTON (item->feat), label);
g_free (label);
}
}
static void
set_inconsistent (GtkCheckButton *button,
gboolean inconsistent)
{
gtk_check_button_set_inconsistent (GTK_CHECK_BUTTON (button), inconsistent);
gtk_widget_set_opacity (gtk_widget_get_first_child (GTK_WIDGET (button)), inconsistent ? 0.0 : 1.0);
}
static void
find_language_and_script (FontFeatures *self,
hb_face_t *hb_face,
hb_tag_t *lang_tag,
hb_tag_t *script_tag)
{
int i, j, k;
hb_tag_t scripts[80];
unsigned int n_scripts;
unsigned int count;
hb_tag_t table[2] = { HB_OT_TAG_GSUB, HB_OT_TAG_GPOS };
hb_language_t lang;
const char *langname, *p;
langname = pango2_language_to_string (self->lang);
p = strchr (langname, '-');
lang = hb_language_from_string (langname, p ? p - langname : -1);
n_scripts = 0;
for (i = 0; i < 2; i++)
{
count = G_N_ELEMENTS (scripts);
hb_ot_layout_table_get_script_tags (hb_face, table[i], n_scripts, &count, scripts);
n_scripts += count;
}
for (j = 0; j < n_scripts; j++)
{
hb_tag_t languages[80];
unsigned int n_languages;
n_languages = 0;
for (i = 0; i < 2; i++)
{
count = G_N_ELEMENTS (languages);
hb_ot_layout_script_get_language_tags (hb_face, table[i], j, n_languages, &count, languages);
n_languages += count;
}
for (k = 0; k < n_languages; k++)
{
if (lang == hb_ot_tag_to_language (languages[k]))
{
*script_tag = scripts[j];
*lang_tag = languages[k];
return;
}
}
}
*lang_tag = HB_OT_TAG_DEFAULT_LANGUAGE;
*script_tag = HB_OT_TAG_DEFAULT_SCRIPT;
}
static void
hide_feature_maybe (FeatureItem *item,
gboolean has_feature)
{
gtk_widget_set_visible (item->feat, has_feature);
if (has_feature)
gtk_widget_set_visible (gtk_widget_get_parent (item->feat), TRUE);
}
/* Make features insensitive if the font/langsys does not have them,
* and reset all others to their initial value
*/
static void
update_features (FontFeatures *self)
{
guint script_index, lang_index;
hb_tag_t lang_tag;
hb_tag_t script_tag;
Pango2Font *font;
hb_font_t *hb_font;
hb_face_t *hb_face;
font = get_font (self);
hb_font = pango2_font_get_hb_font (font);
hb_face = hb_font_get_face (hb_font);
{
hb_tag_t table[2] = { HB_OT_TAG_GSUB, HB_OT_TAG_GPOS };
hb_tag_t features[256];
unsigned int count;
unsigned int n_features = 0;
find_language_and_script (self, hb_face, &lang_tag, &script_tag);
/* Collect all features */
for (int i = 0; i < 2; i++)
{
hb_ot_layout_table_find_script (hb_face,
table[i],
script_tag,
&script_index);
hb_ot_layout_script_select_language (hb_face,
table[i],
script_index,
1,
&lang_tag,
&lang_index);
count = G_N_ELEMENTS (features);
hb_ot_layout_language_get_feature_tags (hb_face,
table[i],
script_index,
lang_index,
n_features,
&count,
features);
n_features += count;
}
/* Update all the features */
for (GList *l = self->feature_items; l; l = l->next)
{
FeatureItem *item = l->data;
gboolean has_feature = FALSE;
for (int j = 0; j < n_features; j++)
{
if (item->tag == features[j])
{
has_feature = TRUE;
break;
}
}
update_feature_label (self, item, hb_font, script_tag, lang_tag);
hide_feature_maybe (item, has_feature);
if (GTK_IS_CHECK_BUTTON (item->feat))
{
GtkWidget *def = GTK_WIDGET (g_object_get_data (G_OBJECT (item->feat), "default"));
if (def)
{
gtk_widget_show (def);
gtk_widget_show (gtk_widget_get_parent (def));
gtk_check_button_set_active (GTK_CHECK_BUTTON (def), TRUE);
}
else
set_inconsistent (GTK_CHECK_BUTTON (item->feat), TRUE);
}
}
}
/* Hide empty groups */
for (GList *l = self->feature_items; l; l = l->next)
{
FeatureItem *item = l->data;
GtkWidget *box;
box = gtk_widget_get_parent (item->feat);
if (gtk_widget_get_visible (box))
{
GtkWidget *c;
int count;
count = 0;
for (c = gtk_widget_get_first_child (box); c; c = gtk_widget_get_next_sibling (c))
{
if (gtk_widget_get_visible (c))
count++;
}
if (count == 1)
gtk_widget_hide (box);
else if (count == 2 &&
item->tag == HB_TAG ('x', 'x', 'x', 'x'))
gtk_widget_hide (box);
}
}
}
static void
script_changed (GtkComboBox *combo,
FontFeatures *self)
{
update_features (self);
}
static char *
get_features (FontFeatures *self)
{
GString *s;
char buf[128];
s = g_string_new ("");
for (GList *l = self->feature_items; l; l = l->next)
{
FeatureItem *item = l->data;
if (!gtk_widget_is_sensitive (item->feat))
continue;
if (GTK_IS_CHECK_BUTTON (item->feat) && g_object_get_data (G_OBJECT (item->feat), "default"))
{
if (gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat)) &&
item->tag != HB_TAG ('x', 'x', 'x', 'x'))
{
hb_feature_to_string (&(hb_feature_t) { item->tag, 1, 0, -1 }, buf, sizeof (buf));
if (s->len > 0)
g_string_append_c (s, ',');
g_string_append (s, buf);
}
}
else if (GTK_IS_CHECK_BUTTON (item->feat))
{
guint32 value;
if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (item->feat)))
continue;
value = gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat));
hb_feature_to_string (&(hb_feature_t) { item->tag, value, 0, -1 }, buf, sizeof (buf));
if (s->len > 0)
g_string_append_c (s, ',');
g_string_append (s, buf);
}
}
return g_string_free (s, FALSE);
}
static void
update_display (FontFeatures *self)
{
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FEATURES]);
g_simple_action_set_enabled (self->reset_action, TRUE);
}
static GtkWidget *
make_title_label (const char *title)
{
GtkWidget *label;
label = gtk_label_new (title);
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_widget_set_halign (label, GTK_ALIGN_START);
g_object_set (label, "margin-top", 10, "margin-bottom", 10, NULL);
gtk_widget_add_css_class (label, "heading");
return label;
}
static void
feat_toggled_cb (GtkCheckButton *check_button,
gpointer data)
{
set_inconsistent (check_button, FALSE);
}
static void
feat_pressed (GtkGestureClick *gesture,
int n_press,
double x,
double y,
GtkWidget *feat)
{
const guint button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
if (button == GDK_BUTTON_PRIMARY)
{
g_signal_handlers_block_by_func (feat, feat_pressed, NULL);
if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat)))
{
set_inconsistent (GTK_CHECK_BUTTON (feat), FALSE);
gtk_check_button_set_active (GTK_CHECK_BUTTON (feat), TRUE);
}
g_signal_handlers_unblock_by_func (feat, feat_pressed, NULL);
}
else if (button == GDK_BUTTON_SECONDARY)
{
gboolean inconsistent = gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat));
set_inconsistent (GTK_CHECK_BUTTON (feat), !inconsistent);
}
}
static void
add_check_group (FontFeatures *self,
const char *title,
const char **tags,
unsigned int n_tags,
int row)
{
GtkWidget *group;
int i;
group = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_halign (group, GTK_ALIGN_START);
gtk_box_append (GTK_BOX (group), make_title_label (title));
for (i = 0; i < n_tags; i++)
{
unsigned int tag;
GtkWidget *feat;
FeatureItem *item;
GtkGesture *gesture;
char *name;
tag = hb_tag_from_string (tags[i], -1);
name = get_feature_display_name (tag);
feat = gtk_check_button_new_with_label (name);
g_free (name);
set_inconsistent (GTK_CHECK_BUTTON (feat), TRUE);
g_signal_connect_swapped (feat, "notify::active", G_CALLBACK (update_display), self);
g_signal_connect_swapped (feat, "notify::inconsistent", G_CALLBACK (update_display), self);
g_signal_connect (feat, "toggled", G_CALLBACK (feat_toggled_cb), NULL);
gesture = gtk_gesture_click_new ();
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
g_signal_connect (gesture, "pressed", G_CALLBACK (feat_pressed), feat);
gtk_widget_add_controller (feat, GTK_EVENT_CONTROLLER (gesture));
gtk_box_append (GTK_BOX (group), feat);
item = g_new (FeatureItem, 1);
item->name = tags[i];
item->tag = tag;
item->feat = feat;
self->feature_items = g_list_prepend (self->feature_items, item);
}
gtk_grid_attach (self->grid, group, 0, row, 2, 1);
}
static void
add_radio_group (FontFeatures *self,
const char *title,
const char **tags,
unsigned int n_tags,
int row)
{
GtkWidget *group;
int i;
GtkWidget *group_button = NULL;
group = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_halign (group, GTK_ALIGN_START);
gtk_box_append (GTK_BOX (group), make_title_label (title));
for (i = 0; i < n_tags; i++)
{
unsigned int tag;
GtkWidget *feat;
FeatureItem *item;
char *name;
tag = hb_tag_from_string (tags[i], -1);
name = get_feature_display_name (tag);
feat = gtk_check_button_new_with_label (name ? name : _("Default"));
g_free (name);
if (group_button == NULL)
group_button = feat;
else
gtk_check_button_set_group (GTK_CHECK_BUTTON (feat), GTK_CHECK_BUTTON (group_button));
g_signal_connect_swapped (feat, "notify::active", G_CALLBACK (update_display), self);
g_object_set_data (G_OBJECT (feat), "default", group_button);
gtk_box_append (GTK_BOX (group), feat);
item = g_new (FeatureItem, 1);
item->name = tags[i];
item->tag = tag;
item->feat = feat;
self->feature_items = g_list_prepend (self->feature_items, item);
}
gtk_grid_attach (self->grid, group, 0, row, 2, 1);
}
static void
setup_features (FontFeatures *self)
{
const char *kerning[] = { "kern" };
const char *ligatures[] = { "liga", "dlig", "hlig", "clig", "rlig" };
const char *letter_case[] = {
"smcp", "c2sc", "pcap", "c2pc", "unic", "cpsp", "case"
};
const char *number_case[] = { "xxxx", "lnum", "onum" };
const char *number_spacing[] = { "xxxx", "pnum", "tnum" };
const char *fractions[] = { "xxxx", "frac", "afrc" };
const char *num_extras[] = { "zero", "nalt", "sinf" };
const char *char_alt[] = {
"swsh", "cswh", "locl", "calt", "falt", "hist",
"salt", "jalt", "titl", "rand", "subs", "sups",
"ordn", "ltra", "ltrm", "rtla", "rtlm", "rclt"
};
const char *pos_alt[] = {
"init", "medi", "med2", "fina", "fin2", "fin3", "isol"
};
const char *width_var[] = {
"fwid", "hwid", "halt", "pwid", "palt", "twid", "qwid"
};
const char *style_alt[] = {
"ss01", "ss02", "ss03", "ss04", "ss05", "ss06",
"ss07", "ss08", "ss09", "ss10", "ss11", "ss12",
"ss13", "ss14", "ss15", "ss16", "ss17", "ss18",
"ss19", "ss20"
};
const char *char_var[] = {
"cv01", "cv02", "cv03", "cv04", "cv05", "cv06",
"cv07", "cv08", "cv09", "cv10", "cv11", "cv12",
"cv13", "cv14", "cv15", "cv16", "cv17", "cv18",
"cv19", "cv20"
};
const char *math[] = { "dtls", "flac", "mgrk", "ssty" };
const char *bounds[] = { "opbd", "lfbd", "rtbd" };
int row = 0;
add_check_group (self, _("Kerning"), kerning, G_N_ELEMENTS (kerning), row++);
add_check_group (self, _("Ligatures"), ligatures, G_N_ELEMENTS (ligatures), row++);
add_check_group (self, _("Letter Case"), letter_case, G_N_ELEMENTS (letter_case), row++);
add_radio_group (self, _("Number Case"), number_case, G_N_ELEMENTS (number_case), row++);
add_radio_group (self, _("Number Spacing"), number_spacing, G_N_ELEMENTS (number_spacing), row++);
add_radio_group (self, _("Fractions"), fractions, G_N_ELEMENTS (fractions), row++);
add_check_group (self, _("Numeric Extras"), num_extras, G_N_ELEMENTS (num_extras), row++);
add_check_group (self, _("Character Alternatives"), char_alt, G_N_ELEMENTS (char_alt), row++);
add_check_group (self, _("Positional Alternatives"), pos_alt, G_N_ELEMENTS (pos_alt), row++);
add_check_group (self, _("Width Variants"), width_var, G_N_ELEMENTS (width_var), row++);
add_check_group (self, _("Alternative Stylistic Sets"), style_alt, G_N_ELEMENTS (style_alt), row++);
add_check_group (self, _("Character Variants"), char_var, G_N_ELEMENTS (char_var), row++);
add_check_group (self, _("Mathematical"), math, G_N_ELEMENTS (math), row++);
add_check_group (self, _("Optical Bounds"), bounds, G_N_ELEMENTS (bounds), row++);
self->feature_items = g_list_reverse (self->feature_items);
}
static void
reset (GSimpleAction *action,
GVariant *parameter,
FontFeatures *self)
{
update_features (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FEATURES]);
g_simple_action_set_enabled (self->reset_action, FALSE);
}
static void
font_features_init (FontFeatures *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
self->font_desc = pango2_font_description_from_string ("sans 12");
self->lang = pango2_language_get_default ();
setup_features (self);
self->reset_action = g_simple_action_new ("reset", NULL);
g_simple_action_set_enabled (self->reset_action, FALSE);
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
}
static void
font_features_dispose (GObject *object)
{
FontFeatures *self = FONT_FEATURES (object);
gtk_widget_clear_template (GTK_WIDGET (object), FONT_FEATURES_TYPE);
g_list_free_full (self->feature_items, g_free);
G_OBJECT_CLASS (font_features_parent_class)->dispose (object);
}
static void
font_features_finalize (GObject *object)
{
FontFeatures *self = FONT_FEATURES (object);
g_clear_pointer (&self->font_desc, pango2_font_description_free);
G_OBJECT_CLASS (font_features_parent_class)->finalize (object);
}
static void
font_features_set_property (GObject *object,
unsigned int prop_id,
const GValue *value,
GParamSpec *pspec)
{
FontFeatures *self = FONT_FEATURES (object);
switch (prop_id)
{
case PROP_FONT_DESC:
pango2_font_description_free (self->font_desc);
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
update_features (self);
break;
case PROP_LANGUAGE:
self->lang = pango2_language_from_string (g_value_get_string (value));
update_features (self);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_features_get_property (GObject *object,
unsigned int prop_id,
GValue *value,
GParamSpec *pspec)
{
FontFeatures *self = FONT_FEATURES (object);
switch (prop_id)
{
case PROP_FEATURES:
g_value_take_string (value, get_features (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_features_class_init (FontFeaturesClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = font_features_dispose;
object_class->finalize = font_features_finalize;
object_class->get_property = font_features_get_property;
object_class->set_property = font_features_set_property;
properties[PROP_FONT_DESC] =
g_param_spec_boxed ("font-desc", "", "",
PANGO2_TYPE_FONT_DESCRIPTION,
G_PARAM_WRITABLE);
properties[PROP_LANGUAGE] =
g_param_spec_string ("language", "", "",
"en",
G_PARAM_WRITABLE);
properties[PROP_FEATURES] =
g_param_spec_string ("features", "", "",
"",
G_PARAM_READABLE);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/fontfeatures.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontFeatures, grid);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontFeatures, label);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), script_changed);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontfeatures");
}
FontFeatures *
font_features_new (void)
{
return g_object_new (FONT_FEATURES_TYPE, NULL);
}
GAction *
font_features_get_reset_action (FontFeatures *self)
{
return G_ACTION (self->reset_action);
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include <gtk/gtk.h>
#define FONT_FEATURES_TYPE (font_features_get_type ())
#define FONT_FEATURES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_FEATURES_TYPE, FontFeatures))
typedef struct _FontFeatures FontFeatures;
typedef struct _FontFeaturesClass FontFeaturesClass;
GType font_features_get_type (void);
FontFeatures * font_features_new (void);
GAction * font_features_get_reset_action (FontFeatures *self);

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FontFeatures" parent="GtkWidget">
<property name="layout-manager"><object class="GtkBinLayout"/></property>
<child>
<object class="GtkGrid" id="grid">
<child>
<object class="GtkLabel" id="label">
<property name="label" translatable="yes">Features</property>
<property name="margin-bottom">10</property>
<property name="xalign">0</property>
<style>
<class name="heading"/>
</style>
<layout>
<property name="row">-1</property>
<property name="column">0</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -0,0 +1,488 @@
#include "fontvariations.h"
#include "rangeedit.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
enum {
PROP_FONT_DESC = 1,
PROP_VARIATIONS,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _FontVariations
{
GtkWidget parent;
GtkGrid *label;
GtkGrid *grid;
Pango2FontDescription *font_desc;
GSimpleAction *reset_action;
gboolean has_variations;
GtkWidget *instance_combo;
GHashTable *axes;
GHashTable *instances;
};
struct _FontVariationsClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(FontVariations, font_variations, GTK_TYPE_WIDGET);
static Pango2Font *
get_font (FontVariations *self)
{
Pango2Context *context;
context = gtk_widget_get_pango_context (GTK_WIDGET (self));
return pango2_context_load_font (context, self->font_desc);
}
typedef struct {
guint32 tag;
GtkAdjustment *adjustment;
double default_value;
} Axis;
static guint
axes_hash (gconstpointer v)
{
const Axis *p = v;
return p->tag;
}
static gboolean
axes_equal (gconstpointer v1, gconstpointer v2)
{
const Axis *p1 = v1;
const Axis *p2 = v2;
return p1->tag == p2->tag;
}
static void
unset_instance (GtkAdjustment *adjustment,
FontVariations *self)
{
if (self->instance_combo)
gtk_combo_box_set_active (GTK_COMBO_BOX (self->instance_combo), 0);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
g_simple_action_set_enabled (self->reset_action, TRUE);
}
static void
add_axis (FontVariations *self,
hb_face_t *hb_face,
hb_ot_var_axis_info_t *ax,
int i)
{
GtkWidget *axis_label;
GtkWidget *axis_scale;
GtkAdjustment *adjustment;
Axis *axis;
char name[20];
unsigned int name_len = 20;
hb_ot_name_get_utf8 (hb_face, ax->name_id, HB_LANGUAGE_INVALID, &name_len, name);
axis_label = gtk_label_new (name);
gtk_widget_set_halign (axis_label, GTK_ALIGN_START);
gtk_widget_set_valign (axis_label, GTK_ALIGN_BASELINE);
gtk_grid_attach (self->grid, axis_label, 0, i, 1, 1);
adjustment = gtk_adjustment_new (ax->default_value, ax->min_value, ax->max_value,
1.0, 10.0, 0.0);
axis_scale = g_object_new (RANGE_EDIT_TYPE,
"adjustment", adjustment,
"default-value", ax->default_value,
"n-chars", 5,
"hexpand", TRUE,
"halign", GTK_ALIGN_FILL,
"valign", GTK_ALIGN_BASELINE,
NULL);
gtk_grid_attach (self->grid, axis_scale, 1, i, 1, 1);
axis = g_new0 (Axis, 1);
axis->tag = ax->tag;
axis->adjustment = adjustment;
axis->default_value = ax->default_value;
g_hash_table_add (self->axes, axis);
g_signal_connect (adjustment, "value-changed", G_CALLBACK (unset_instance), self);
}
typedef struct {
char *name;
unsigned int index;
} Instance;
static guint
instance_hash (gconstpointer v)
{
const Instance *p = v;
return g_str_hash (p->name);
}
static gboolean
instance_equal (gconstpointer v1, gconstpointer v2)
{
const Instance *p1 = v1;
const Instance *p2 = v2;
return g_str_equal (p1->name, p2->name);
}
static void
free_instance (gpointer data)
{
Instance *instance = data;
g_free (instance->name);
g_free (instance);
}
static void
add_instance (FontVariations *self,
hb_face_t *face,
unsigned int index,
GtkWidget *combo,
int pos)
{
Instance *instance;
hb_ot_name_id_t name_id;
char name[20];
unsigned int name_len = 20;
instance = g_new0 (Instance, 1);
name_id = hb_ot_var_named_instance_get_subfamily_name_id (face, index);
hb_ot_name_get_utf8 (face, name_id, HB_LANGUAGE_INVALID, &name_len, name);
instance->name = g_strdup (name);
instance->index = index;
g_hash_table_add (self->instances, instance);
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), instance->name);
}
static void
instance_changed (GtkComboBox *combo,
FontVariations *self)
{
char *text;
Instance *instance;
Instance ikey;
int i;
unsigned int coords_length;
float *coords = NULL;
hb_ot_var_axis_info_t *ai = NULL;
unsigned int n_axes;
Pango2Font *font = NULL;
hb_font_t *hb_font;
hb_face_t *hb_face;
text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo));
if (text[0] == '\0')
goto out;
ikey.name = text;
instance = g_hash_table_lookup (self->instances, &ikey);
if (!instance)
{
g_print ("did not find instance %s\n", text);
goto out;
}
font = get_font (self);
hb_font = pango2_font_get_hb_font (font);
hb_face = hb_font_get_face (hb_font);
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
ai = g_new (hb_ot_var_axis_info_t, n_axes);
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, ai);
coords = g_new (float, n_axes);
hb_ot_var_named_instance_get_design_coords (hb_face,
instance->index,
&coords_length,
coords);
for (i = 0; i < n_axes; i++)
{
Axis *axis;
Axis akey;
double value;
value = coords[ai[i].axis_index];
akey.tag = ai[i].tag;
axis = g_hash_table_lookup (self->axes, &akey);
if (axis)
{
g_signal_handlers_block_by_func (axis->adjustment, unset_instance, self);
gtk_adjustment_set_value (axis->adjustment, value);
g_signal_handlers_unblock_by_func (axis->adjustment, unset_instance, self);
}
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
g_simple_action_set_enabled (self->reset_action, TRUE);
out:
g_free (text);
g_clear_object (&font);
g_free (ai);
g_free (coords);
}
static void
update_variations (FontVariations *self)
{
GtkWidget *child;
Pango2Font *font;
hb_font_t *hb_font;
hb_face_t *hb_face;
unsigned int n_axes;
hb_ot_var_axis_info_t *ai = NULL;
int i;
font = get_font (self);
hb_font = pango2_font_get_hb_font (font);
hb_face = hb_font_get_face (hb_font);
g_object_ref (self->label);
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self->grid))))
gtk_grid_remove (self->grid, child);
gtk_grid_attach (self->grid, GTK_WIDGET (self->label), 0, -2, 2, 1);
g_object_unref (self->label);
self->instance_combo = NULL;
g_hash_table_remove_all (self->axes);
g_hash_table_remove_all (self->instances);
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
self->has_variations = n_axes > 0;
gtk_widget_set_visible (GTK_WIDGET (self), self->has_variations);
if (!self->has_variations)
{
g_simple_action_set_enabled (self->reset_action, FALSE);
return;
}
if (hb_ot_var_get_named_instance_count (hb_face) > 0)
{
GtkWidget *label;
GtkWidget *combo;
label = gtk_label_new ("Instance");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_BASELINE);
gtk_grid_attach (self->grid, label, 0, -1, 1, 1);
combo = gtk_combo_box_text_new ();
gtk_widget_set_halign (combo, GTK_ALIGN_START);
gtk_widget_set_valign (combo, GTK_ALIGN_BASELINE);
gtk_widget_set_hexpand (combo, TRUE);
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "");
for (i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
add_instance (self, hb_face, i, combo, i);
gtk_grid_attach (GTK_GRID (self->grid), combo, 1, -1, 1, 1);
g_signal_connect (combo, "changed", G_CALLBACK (instance_changed), self);
self->instance_combo = combo;
}
ai = g_new (hb_ot_var_axis_info_t, n_axes);
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, ai);
for (i = 0; i < n_axes; i++)
add_axis (self, hb_face, &ai[i], i);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
g_clear_object (&font);
g_free (ai);
}
static char *
get_variations (FontVariations *self)
{
GHashTableIter iter;
Axis *axis;
char buf[G_ASCII_DTOSTR_BUF_SIZE];
const char *sep = "";
GString *s;
if (!self->has_variations)
return g_strdup ("");
s = g_string_new ("");
g_hash_table_iter_init (&iter, self->axes);
while (g_hash_table_iter_next (&iter, (gpointer *)NULL, (gpointer *)&axis))
{
char tag[5];
double value;
hb_tag_to_string (axis->tag, tag);
tag[4] = '\0';
value = gtk_adjustment_get_value (axis->adjustment);
g_string_append_printf (s, "%s%s=%s", sep, tag, g_ascii_dtostr (buf, sizeof (buf), value));
sep = ",";
}
return g_string_free (s, FALSE);
}
static void
reset (GSimpleAction *action,
GVariant *parameter,
FontVariations *self)
{
GHashTableIter iter;
Axis *axis;
if (self->instance_combo)
gtk_combo_box_set_active (GTK_COMBO_BOX (self->instance_combo), 0);
g_hash_table_iter_init (&iter, self->axes);
while (g_hash_table_iter_next (&iter, (gpointer *)NULL, (gpointer *)&axis))
{
g_signal_handlers_block_by_func (axis->adjustment, unset_instance, self);
gtk_adjustment_set_value (axis->adjustment, axis->default_value);
g_signal_handlers_unblock_by_func (axis->adjustment, unset_instance, self);
}
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VARIATIONS]);
g_simple_action_set_enabled (self->reset_action, FALSE);
}
static void
font_variations_init (FontVariations *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
self->reset_action = g_simple_action_new ("reset", NULL);
g_simple_action_set_enabled (self->reset_action, FALSE);
g_signal_connect (self->reset_action, "activate", G_CALLBACK (reset), self);
self->instances = g_hash_table_new_full (instance_hash, instance_equal,
NULL, free_instance);
self->axes = g_hash_table_new_full (axes_hash, axes_equal,
NULL, g_free);
}
static void
font_variations_dispose (GObject *object)
{
FontVariations *self = FONT_VARIATIONS (object);
gtk_widget_clear_template (GTK_WIDGET (object), FONT_VARIATIONS_TYPE);
g_hash_table_unref (self->instances);
g_hash_table_unref (self->axes);
G_OBJECT_CLASS (font_variations_parent_class)->dispose (object);
}
static void
font_variations_finalize (GObject *object)
{
FontVariations *self = FONT_VARIATIONS (object);
g_clear_pointer (&self->font_desc, pango2_font_description_free);
G_OBJECT_CLASS (font_variations_parent_class)->finalize (object);
}
static void
font_variations_set_property (GObject *object,
unsigned int prop_id,
const GValue *value,
GParamSpec *pspec)
{
FontVariations *self = FONT_VARIATIONS (object);
switch (prop_id)
{
case PROP_FONT_DESC:
pango2_font_description_free (self->font_desc);
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
update_variations (self);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_variations_get_property (GObject *object,
unsigned int prop_id,
GValue *value,
GParamSpec *pspec)
{
FontVariations *self = FONT_VARIATIONS (object);
switch (prop_id)
{
case PROP_VARIATIONS:
g_value_take_string (value, get_variations (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_variations_class_init (FontVariationsClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = font_variations_dispose;
object_class->finalize = font_variations_finalize;
object_class->get_property = font_variations_get_property;
object_class->set_property = font_variations_set_property;
properties[PROP_FONT_DESC] =
g_param_spec_boxed ("font-desc", "", "",
PANGO2_TYPE_FONT_DESCRIPTION,
G_PARAM_WRITABLE);
properties[PROP_VARIATIONS] =
g_param_spec_string ("variations", "", "",
"",
G_PARAM_READABLE);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/fontvariations.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontVariations, grid);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontVariations, label);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontvariations");
}
FontVariations *
font_variations_new (void)
{
return g_object_new (FONT_VARIATIONS_TYPE, NULL);
}
GAction *
font_variations_get_reset_action (FontVariations *self)
{
return G_ACTION (self->reset_action);
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include <gtk/gtk.h>
#define FONT_VARIATIONS_TYPE (font_variations_get_type ())
#define FONT_VARIATIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_VARIATIONS_TYPE, FontVariations))
typedef struct _FontVariations FontVariations;
typedef struct _FontVariationsClass FontVariationsClass;
GType font_variations_get_type (void);
FontVariations * font_variations_new (void);
GAction * font_variations_get_reset_action (FontVariations *self);

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FontVariations" parent="GtkWidget">
<property name="layout-manager"><object class="GtkBinLayout"/></property>
<child>
<object class="GtkGrid" id="grid">
<child>
<object class="GtkLabel" id="label">
<property name="label" translatable="yes">Variations</property>
<property name="margin-bottom">10</property>
<property name="xalign">0</property>
<style>
<class name="heading"/>
</style>
<layout>
<property name="row">-2</property>
<property name="column">0</property>
<property name="column-span">2</property>
</layout>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -0,0 +1,413 @@
#include "fontview.h"
#include <gtk/gtk.h>
enum {
PROP_FONT_DESC = 1,
PROP_SIZE,
PROP_LETTERSPACING,
PROP_LINE_HEIGHT,
PROP_FOREGROUND,
PROP_BACKGROUND,
PROP_VARIATIONS,
PROP_FEATURES,
PROP_PALETTE,
PROP_SAMPLE_TEXT,
PROP_IGNORE_SIZE,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _FontView
{
GtkWidget parent;
GtkStack *stack;
GtkTextView *edit;
GtkLabel *content;
GtkScrolledWindow *swin;
Pango2FontDescription *font_desc;
float size;
char *variations;
char *features;
char *palette;
int letterspacing;
float line_height;
GdkRGBA foreground;
GdkRGBA background;
GtkCssProvider *bg_provider;
char *sample_text;
gboolean do_waterfall;
};
struct _FontViewClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(FontView, font_view, GTK_TYPE_WIDGET);
static void
font_view_init (FontView *self)
{
self->font_desc = pango2_font_description_from_string ("sans 12");
self->size = 12.;
self->letterspacing = 0;
self->line_height = 1.;
self->variations = g_strdup ("");
self->features = g_strdup ("");
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
self->foreground = (GdkRGBA){0., 0., 0., 1. };
self->background = (GdkRGBA){1., 1., 1., 1. };
self->sample_text = g_strdup ("Some sample text is better than other sample text");
gtk_widget_set_layout_manager (GTK_WIDGET (self),
gtk_box_layout_new (GTK_ORIENTATION_VERTICAL));
gtk_widget_init_template (GTK_WIDGET (self));
self->bg_provider = gtk_css_provider_new ();
gtk_style_context_add_provider (gtk_widget_get_style_context (GTK_WIDGET (self->content)),
GTK_STYLE_PROVIDER (self->bg_provider), 800);
}
static void
font_view_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), FONT_VIEW_TYPE);
G_OBJECT_CLASS (font_view_parent_class)->dispose (object);
}
static void
font_view_finalize (GObject *object)
{
FontView *self = FONT_VIEW (object);
pango2_font_description_free (self->font_desc);
g_free (self->variations);
g_free (self->features);
g_free (self->palette);
G_OBJECT_CLASS (font_view_parent_class)->finalize (object);
}
static void
update_view (FontView *self)
{
Pango2FontDescription *desc;
Pango2AttrList *attrs;
char *fg, *bg, *css;
desc = pango2_font_description_copy_static (self->font_desc);
pango2_font_description_set_size (desc, 12 * PANGO2_SCALE);
pango2_font_description_set_variations (desc, self->variations);
attrs = pango2_attr_list_new ();
pango2_attr_list_insert (attrs, pango2_attr_font_desc_new (desc));
pango2_attr_list_insert (attrs, pango2_attr_size_new (self->size * PANGO2_SCALE));
pango2_attr_list_insert (attrs, pango2_attr_letter_spacing_new (self->letterspacing));
pango2_attr_list_insert (attrs, pango2_attr_line_height_new (self->line_height));
pango2_attr_list_insert (attrs, pango2_attr_foreground_new (&(Pango2Color){65535 * self->foreground.red,
65535 * self->foreground.green,
65535 * self->foreground.blue,
65535 * self->foreground.alpha}));
pango2_attr_list_insert (attrs, pango2_attr_font_features_new (self->features));
pango2_attr_list_insert (attrs, pango2_attr_palette_new (self->palette));
pango2_font_description_free (desc);
gtk_scrolled_window_set_policy (self->swin,
self->do_waterfall ? GTK_POLICY_AUTOMATIC : GTK_POLICY_NEVER,
GTK_POLICY_AUTOMATIC);
gtk_label_set_wrap (self->content, !self->do_waterfall);
if (self->do_waterfall)
{
GString *str;
int sizes[] = { 7, 8, 9, 10, 12, 14, 16, 20, 24, 30, 40, 50, 60, 70, 90 };
int start, text_len;
str = g_string_new ("");
start = 0;
text_len = strlen (self->sample_text);
for (int i = 0; i < G_N_ELEMENTS (sizes); i++)
{
Pango2Attribute *attr;
g_string_append (str, self->sample_text);
g_string_append (str, ""); /* Unicode line separator */
attr = pango2_attr_size_new (sizes[i] * PANGO2_SCALE);
pango2_attribute_set_range (attr, start, start + text_len);
pango2_attr_list_insert (attrs, attr);
start += text_len + strlen ("");
}
gtk_label_set_text (self->content, str->str);
gtk_label_set_attributes (self->content, attrs);
g_string_free (str, TRUE);
}
else
{
gtk_label_set_label (self->content, self->sample_text);
gtk_label_set_attributes (self->content, attrs);
}
pango2_attr_list_unref (attrs);
fg = gdk_rgba_to_string (&self->foreground);
bg = gdk_rgba_to_string (&self->background);
css = g_strdup_printf (".view_background { caret-color: %s; background-color: %s; }", fg, bg);
gtk_css_provider_load_from_data (self->bg_provider, css, strlen (css));
g_free (css);
g_free (fg);
g_free (bg);
}
static void
toggle_edit (GtkToggleButton *button,
FontView *self)
{
GtkTextBuffer *buffer;
buffer = gtk_text_view_get_buffer (self->edit);
if (gtk_toggle_button_get_active (button))
{
gtk_text_buffer_set_text (buffer, self->sample_text, -1);
gtk_stack_set_visible_child_name (self->stack, "edit");
gtk_widget_grab_focus (GTK_WIDGET (self->edit));
}
else
{
GtkTextIter start, end;
g_free (self->sample_text);
gtk_text_buffer_get_bounds (buffer, &start, &end);
self->sample_text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
update_view (self);
gtk_stack_set_visible_child_name (self->stack, "content");
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
}
}
static void
waterfall_changed (GtkToggleButton *button,
GParamSpec *pspec,
FontView *self)
{
self->do_waterfall = gtk_toggle_button_get_active (button);
update_view (self);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_IGNORE_SIZE]);
}
static void
font_view_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
FontView *self = FONT_VIEW (object);
switch (prop_id)
{
case PROP_FONT_DESC:
pango2_font_description_free (self->font_desc);
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
break;
case PROP_SIZE:
self->size = g_value_get_float (value);
break;
case PROP_LETTERSPACING:
self->letterspacing = g_value_get_int (value);
break;
case PROP_LINE_HEIGHT:
self->line_height = g_value_get_float (value);
break;
case PROP_FOREGROUND:
self->foreground = *(GdkRGBA *)g_value_get_boxed (value);
break;
case PROP_BACKGROUND:
self->background = *(GdkRGBA *)g_value_get_boxed (value);
break;
case PROP_VARIATIONS:
g_free (self->variations);
self->variations = g_strdup (g_value_get_string (value));
break;
case PROP_FEATURES:
g_free (self->features);
self->features = g_strdup (g_value_get_string (value));
break;
case PROP_PALETTE:
g_free (self->palette);
self->palette = g_strdup (g_value_get_string (value));
break;
case PROP_SAMPLE_TEXT:
g_free (self->sample_text);
self->sample_text = g_strdup (g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
update_view (self);
}
static void
font_view_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
FontView *self = FONT_VIEW (object);
switch (prop_id)
{
case PROP_FONT_DESC:
g_value_set_boxed (value, self->font_desc);
break;
case PROP_SIZE:
g_value_set_float (value, self->size);
break;
case PROP_LETTERSPACING:
g_value_set_int (value, self->letterspacing);
break;
case PROP_LINE_HEIGHT:
g_value_set_float (value, self->line_height);
break;
case PROP_FOREGROUND:
g_value_set_boxed (value, &self->foreground);
break;
case PROP_BACKGROUND:
g_value_set_boxed (value, &self->background);
break;
case PROP_VARIATIONS:
g_value_set_string (value, self->variations);
break;
case PROP_FEATURES:
g_value_set_string (value, self->features);
break;
case PROP_PALETTE:
g_value_set_string (value, self->palette);
break;
case PROP_SAMPLE_TEXT:
g_value_set_string (value, self->sample_text);
break;
case PROP_IGNORE_SIZE:
g_value_set_boolean (value, self->do_waterfall);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_view_class_init (FontViewClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = font_view_dispose;
object_class->finalize = font_view_finalize;
object_class->get_property = font_view_get_property;
object_class->set_property = font_view_set_property;
properties[PROP_FONT_DESC] =
g_param_spec_boxed ("font-desc", "", "",
PANGO2_TYPE_FONT_DESCRIPTION,
G_PARAM_READWRITE);
properties[PROP_SIZE] =
g_param_spec_float ("size", "", "",
0., 100., 12.,
G_PARAM_READWRITE);
properties[PROP_LETTERSPACING] =
g_param_spec_int ("letterspacing", "", "",
-G_MAXINT, G_MAXINT, 0,
G_PARAM_READWRITE);
properties[PROP_LINE_HEIGHT] =
g_param_spec_float ("line-height", "", "",
0., 100., 1.,
G_PARAM_READWRITE);
properties[PROP_FOREGROUND] =
g_param_spec_boxed ("foreground", "", "",
GDK_TYPE_RGBA,
G_PARAM_READWRITE);
properties[PROP_BACKGROUND] =
g_param_spec_boxed ("background", "", "",
GDK_TYPE_RGBA,
G_PARAM_READWRITE);
properties[PROP_VARIATIONS] =
g_param_spec_string ("variations", "", "",
"",
G_PARAM_READWRITE);
properties[PROP_FEATURES] =
g_param_spec_string ("features", "", "",
"",
G_PARAM_READWRITE);
properties[PROP_PALETTE] =
g_param_spec_string ("palette", "", "",
PANGO2_COLOR_PALETTE_DEFAULT,
G_PARAM_READWRITE);
properties[PROP_SAMPLE_TEXT] =
g_param_spec_string ("sample-text", "", "",
"",
G_PARAM_READWRITE);
properties[PROP_IGNORE_SIZE] =
g_param_spec_boolean ("ignore-size", "", "",
FALSE,
G_PARAM_READWRITE);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/fontview.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontView, swin);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontView, content);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontView, stack);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontView, edit);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), toggle_edit);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), waterfall_changed);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "fontview");
}
FontView *
font_view_new (void)
{
return g_object_new (FONT_VIEW_TYPE, NULL);
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include <gtk/gtk.h>
#define FONT_VIEW_TYPE (font_view_get_type ())
#define FONT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FONT_VIEW_TYPE, FontView))
typedef struct _FontView FontView;
typedef struct _FontViewClass FontViewClass;
GType font_view_get_type (void);
FontView * font_view_new (void);

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="FontView" parent="GtkWidget">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<style>
<class name="view"/>
</style>
<child>
<object class="GtkStack" id="stack">
<child>
<object class="GtkStackPage">
<property name="name">content</property>
<property name="child">
<object class="GtkScrolledWindow" id="swin">
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<child>
<object class="GtkLabel" id="content">
<property name="label">ContentContent</property>
<property name="wrap">1</property>
<property name="wrap-mode">word-char</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="halign">fill</property>
<property name="valign">fill</property>
<style>
<class name="view_background"/>
</style>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">edit</property>
<property name="child">
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<child>
<object class="GtkTextView" id="edit">
<property name="wrap-mode">word-char</property>
</object>
</child>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<child>
<object class="GtkBox">
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkToggleButton" id="plain_toggle">
<property name="label" translatable="yes">Plain</property>
<property name="active">1</property>
</object>
</child>
<child>
<object class="GtkToggleButton" id="waterfall_toggle">
<property name="label" translatable="yes">Waterfall</property>
<property name="group">plain_toggle</property>
<signal name="notify::active" handler="waterfall_changed"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToggleButton">
<property name="icon-name">document-edit-symbolic</property>
<property name="tooltip-text" translatable="yes">Edit the sample</property>
<property name="halign">end</property>
<property name="valign">end</property>
<property name="hexpand">1</property>
<signal name="clicked" handler="toggle_edit"/>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -0,0 +1,336 @@
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <errno.h>
#include <locale.h>
#include <sys/stat.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <hb-ot.h>
#include "language-names.h"
#ifdef G_OS_WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#ifndef ISO_CODES_PREFIX
#define ISO_CODES_PREFIX "/usr"
#endif
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
#endif
static GHashTable *language_map;
#ifdef G_OS_WIN32
/* if we are using native Windows use native Windows API for language names */
static BOOL CALLBACK
get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
{
wchar_t *langname_w = NULL;
wchar_t locale_abbrev_w[9];
gchar *langname, *locale_abbrev, *locale, *p;
gint i;
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
GHashTable *ht_scripts_langs = (GHashTable *) param;
Pango2Language *lang;
gint langname_size, locale_abbrev_size;
langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0);
if (langname_size == 0)
return FALSE;
langname_w = g_new0 (wchar_t, langname_size);
if (langname_size == 0)
return FALSE;
GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, langname_size);
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
p = strchr (locale, '-');
lang = pango2_language_from_string (locale);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
/*
* Track 3+-letter ISO639-2/3 language codes as well (these have a max length of 9 including terminating NUL)
* ISO639-2: iso639_lctypes[0] = LOCALE_SISO639LANGNAME
* ISO639-3: iso639_lctypes[1] = LOCALE_SISO639LANGNAME2
*/
for (i = 0; i < 2; i++)
{
locale_abbrev_size = GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, 0);
if (locale_abbrev_size > 0)
{
GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size);
locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL);
lang = pango2_language_from_string (locale_abbrev);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
g_free (locale_abbrev);
}
}
g_free (locale);
g_free (langname_w);
return TRUE;
}
#else /* non-Windows */
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;
const char *long_names[] = {
"Dogri",
"Greek, Modern",
"Interlingua",
"Konkani",
"Tonga",
"Turkish, Ottoman",
};
int i;
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);
/* Fix up some egregious names */
for (i = 0; i < G_N_ELEMENTS (long_names); i++)
{
if (g_str_has_prefix (display_name, long_names[i]))
display_name[strlen (long_names[i])] = '\0';
}
if (ccode != NULL)
g_hash_table_insert (language_map,
pango2_language_from_string (ccode),
g_strdup (display_name));
if (ccode_longB != NULL)
g_hash_table_insert (language_map,
pango2_language_from_string (ccode_longB),
g_strdup (display_name));
if (ccode_longT != NULL)
g_hash_table_insert (language_map,
pango2_language_from_string (ccode_longT),
g_strdup (display_name));
if (ccode_id != NULL)
g_hash_table_insert (language_map,
pango2_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;
char *buf;
char *filename;
GError *error;
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)
{
GMarkupParseContext *ctx = NULL;
GMarkupParser parser = { languages_parse_start_tag, NULL, NULL, NULL, NULL };
ctx = g_markup_parse_context_new (&parser, 0, NULL, NULL);
res = g_markup_parse_context_parse (ctx, buf, buf_len, &error);
g_free (ctx);
if (!res)
{
g_warning ("Failed to parse '%s': %s\n", filename, error->message);
g_error_free (error);
}
}
else
{
g_warning ("Failed to load '%s': %s\n", filename, error->message);
g_error_free (error);
}
g_free (filename);
g_free (buf);
}
#endif
static void
languages_init (void)
{
if (language_map)
return;
language_map = g_hash_table_new_full (NULL, NULL, NULL, g_free);
#ifdef G_OS_WIN32
g_return_if_fail (EnumSystemLocalesEx (&get_win32_all_locales_scripts, LOCALE_ALL, (LPARAM) language_map, NULL));
#else
languages_variant_init ("iso_639");
languages_variant_init ("iso_639_3");
#endif
}
const char *
get_language_name (Pango2Language *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 (pango2_language_from_string (s));
}

View File

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

View File

@@ -0,0 +1,8 @@
#include <gtk/gtk.h>
#include <fontexplorerapp.h>
int
main (int argc, char *argv[])
{
return g_application_run (G_APPLICATION (font_explorer_app_new ()), argc, argv);
}

View File

@@ -0,0 +1,27 @@
fontexplorer_sources = [
'main.c',
'fontexplorerapp.c',
'fontexplorerwin.c',
'fontcontrols.c',
'samplechooser.c',
'fontcolors.c',
'fontfeatures.c',
'fontvariations.c',
'fontview.c',
'rangeedit.c',
'language-names.c',
]
fontexplorer_resources = gnome.compile_resources('fontexplorer_resources',
'fontexplorer.gresource.xml',
source_dir: '.',
)
executable('gtk4-font-explorer',
sources: [fontexplorer_sources, fontexplorer_resources],
c_args: common_cflags,
dependencies: [ libgtk_dep, demo_conf_h ],
include_directories: confinc,
link_args: extra_demo_ldflags,
install: true,
)

View File

@@ -0,0 +1,173 @@
#include "rangeedit.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
enum {
PROP_ADJUSTMENT = 1,
PROP_DEFAULT_VALUE,
PROP_N_CHARS,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _RangeEdit
{
GtkWidget parent;
GtkAdjustment *adjustment;
GtkScale *scale;
GtkEntry *entry;
double default_value;
int n_chars;
};
struct _RangeEditClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (RangeEdit, range_edit, GTK_TYPE_WIDGET);
static void
range_edit_init (RangeEdit *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
}
static void
range_edit_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), RANGE_EDIT_TYPE);
G_OBJECT_CLASS (range_edit_parent_class)->dispose (object);
}
static void
range_edit_get_property (GObject *object,
unsigned int prop_id,
GValue *value,
GParamSpec *pspec)
{
RangeEdit *self = RANGE_EDIT (object);
switch (prop_id)
{
case PROP_ADJUSTMENT:
g_value_set_object (value, self->adjustment);
break;
case PROP_DEFAULT_VALUE:
g_value_set_double (value, self->default_value);
break;
case PROP_N_CHARS:
g_value_set_int (value, self->n_chars);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
adjustment_changed (GtkAdjustment *adjustment,
RangeEdit *self)
{
char *str;
str = g_strdup_printf ("%.1f", gtk_adjustment_get_value (adjustment));
gtk_editable_set_text (GTK_EDITABLE (self->entry), str);
g_free (str);
}
static void
range_edit_set_property (GObject *object,
unsigned int prop_id,
const GValue *value,
GParamSpec *pspec)
{
RangeEdit *self = RANGE_EDIT (object);
switch (prop_id)
{
case PROP_ADJUSTMENT:
g_set_object (&self->adjustment, g_value_get_object (value));
g_signal_connect (self->adjustment, "value-changed", G_CALLBACK (adjustment_changed), self);
adjustment_changed (self->adjustment, self);
break;
case PROP_DEFAULT_VALUE:
self->default_value = g_value_get_double (value);
break;
case PROP_N_CHARS:
self->n_chars = g_value_get_int (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
range_edit_constructed (GObject *object)
{
RangeEdit *self = RANGE_EDIT (object);
gtk_scale_add_mark (self->scale, self->default_value, GTK_POS_TOP, NULL);
}
static void
entry_activated (GtkEntry *entry,
RangeEdit *self)
{
double value;
char *err = NULL;
value = g_strtod (gtk_editable_get_text (GTK_EDITABLE (entry)), &err);
if (err != NULL)
gtk_adjustment_set_value (self->adjustment, value);
}
static void
range_edit_class_init (RangeEditClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = range_edit_dispose;
object_class->get_property = range_edit_get_property;
object_class->set_property = range_edit_set_property;
object_class->constructed = range_edit_constructed;
properties[PROP_ADJUSTMENT] =
g_param_spec_object ("adjustment", "", "",
GTK_TYPE_ADJUSTMENT,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
properties[PROP_DEFAULT_VALUE] =
g_param_spec_double ("default-value", "", "",
-G_MAXDOUBLE, G_MAXDOUBLE, 0.,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
properties[PROP_N_CHARS] =
g_param_spec_int ("n-chars", "", "",
0, G_MAXINT, 10,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/rangeedit.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), RangeEdit, scale);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), RangeEdit, entry);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), entry_activated);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "rangeedit");
}
RangeEdit *
range_edit_new (void)
{
return g_object_new (RANGE_EDIT_TYPE, NULL);
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include <gtk/gtk.h>
#define RANGE_EDIT_TYPE (range_edit_get_type ())
#define RANGE_EDIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RANGE_EDIT_TYPE, RangeEdit))
typedef struct _RangeEdit RangeEdit;
typedef struct _RangeEditClass RangeEditClass;
GType range_edit_get_type (void);
RangeEdit * range_edit_new (void);

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="RangeEdit" parent="GtkWidget">
<property name="layout-manager">
<object class="GtkBoxLayout">
<property name="spacing">10</property>
</object>
</property>
<child>
<object class="GtkScale" id="scale">
<property name="orientation">horizontal</property>
<property name="hexpand">1</property>
<property name="adjustment" bind-source="RangeEdit" bind-flags="sync-create"/>
</object>
</child>
<child>
<object class="GtkEntry" id="entry">
<property name="width-chars" bind-source="RangeEdit" bind-property="n-chars" bind-flags="sync-create"/>
<property name="max-width-chars" bind-source="RangeEdit" bind-property="n-chars" bind-flags="sync-create"/>
<signal name="activate" handler="entry_activated"/>
</object>
</child>
</template>
</interface>

View File

@@ -0,0 +1,162 @@
#include "samplechooser.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
enum {
PROP_SAMPLE_TEXT = 1,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _SampleChooser
{
GtkWidget parent;
int sample;
const char *sample_text;
};
struct _SampleChooserClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(SampleChooser, sample_chooser, GTK_TYPE_WIDGET);
static const char *pangrams[] = {
"The quick brown fox jumps over the lazy dog.",
"Waltz, bad nymph, for quick jigs vex.",
"Quick zephyrs blow, vexing daft Jim.",
"Crazy Fredrick bought many very exquisite opal jewels.",
"Jaded zombies acted quaintly but kept driving their oxen forward.",
};
static const char *paragraphs[] = {
"Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.",
" Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!",
"Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός",
};
static const char *alphabets[] = {
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"0123456789",
"!@#$%^&*()?",
};
static const char *titles[] = {
"From My Cold Dead Hands",
"From Afar Upon the Back of a Tiger",
"Spontaneous Apple Creation",
"Big Bizness (Screwed & Chopped)",
"Pizza Shop Extended",
"Good News & Bad News",
};
static void
next_pangram (GtkButton *button,
SampleChooser *self)
{
self->sample++;
self->sample_text = pangrams[self->sample % G_N_ELEMENTS (pangrams)];
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
}
static void
next_paragraph (GtkButton *button,
SampleChooser *self)
{
self->sample++;
self->sample_text = paragraphs[self->sample % G_N_ELEMENTS (paragraphs)];
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
}
static void
next_alphabet (GtkButton *button,
SampleChooser *self)
{
self->sample++;
self->sample_text = alphabets[self->sample % G_N_ELEMENTS (alphabets)];
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
}
static void
next_title (GtkButton *button,
SampleChooser *self)
{
self->sample++;
self->sample_text = titles[self->sample % G_N_ELEMENTS (titles)];
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
}
static void
sample_chooser_init (SampleChooser *self)
{
self->sample_text = "Boring sample text";
gtk_widget_init_template (GTK_WIDGET (self));
}
static void
sample_chooser_dispose (GObject *object)
{
GtkWidget *child;
gtk_widget_clear_template (GTK_WIDGET (object), SAMPLE_CHOOSER_TYPE);
while ((child = gtk_widget_get_first_child (GTK_WIDGET (object))) != NULL)
gtk_widget_unparent (child);
G_OBJECT_CLASS (sample_chooser_parent_class)->dispose (object);
}
static void
sample_chooser_get_property (GObject *object,
unsigned int prop_id,
GValue *value,
GParamSpec *pspec)
{
SampleChooser *self = SAMPLE_CHOOSER (object);
switch (prop_id)
{
case PROP_SAMPLE_TEXT:
g_value_set_string (value, self->sample_text);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sample_chooser_class_init (SampleChooserClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = sample_chooser_dispose;
object_class->get_property = sample_chooser_get_property;
properties[PROP_SAMPLE_TEXT] =
g_param_spec_string ("sample-text", "", "",
"",
G_PARAM_READABLE);
g_object_class_install_properties (G_OBJECT_CLASS (class), NUM_PROPERTIES, properties);
gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (class),
"/org/gtk/fontexplorer/samplechooser.ui");
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_pangram);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_paragraph);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_alphabet);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), next_title);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "samplechooser");
}
SampleChooser *
sample_chooser_new (void)
{
return g_object_new (SAMPLE_CHOOSER_TYPE, NULL);
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include <gtk/gtk.h>
#define SAMPLE_CHOOSER_TYPE (sample_chooser_get_type ())
#define SAMPLE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SAMPLE_CHOOSER_TYPE, SampleChooser))
typedef struct _SampleChooser SampleChooser;
typedef struct _SampleChooserClass SampleChooserClass;
GType sample_chooser_get_type (void);
SampleChooser * sample_chooser_new (void);

View File

@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="SampleChooser" parent="GtkWidget">
<property name="layout-manager"><object class="GtkGridLayout"/></property>
<child>
<object class="GtkButton">
<property name="label">Pangram</property>
<signal name="clicked" handler="next_pangram"/>
<layout>
<property name="row">0</property>
<property name="column">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Paragraph</property>
<signal name="clicked" handler="next_paragraph"/>
<layout>
<property name="row">0</property>
<property name="column">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Alphabet</property>
<signal name="clicked" handler="next_alphabet"/>
<layout>
<property name="row">1</property>
<property name="column">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label">Title</property>
<signal name="clicked" handler="next_title"/>
<layout>
<property name="row">1</property>
<property name="column">1</property>
</layout>
</object>
</child>
</template>
</interface>

View File

@@ -260,12 +260,13 @@ mask_entry_set_background (MaskEntry *entry)
{
if (!g_regex_match_simple (entry->mask, gtk_editable_get_text (GTK_EDITABLE (entry)), 0, 0))
{
PangoAttrList *attrs;
Pango2AttrList *attrs;
Pango2Color color = { 65535, 32767, 32767, 65535 };
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_foreground_new (65535, 32767, 32767));
attrs = pango2_attr_list_new ();
pango2_attr_list_insert (attrs, pango2_attr_foreground_new (&color));
gtk_entry_set_attributes (GTK_ENTRY (entry), attrs);
pango_attr_list_unref (attrs);
pango2_attr_list_unref (attrs);
return;
}
}

View File

@@ -84,11 +84,11 @@ do_css_basics (GtkWidget *do_widget)
text = gtk_text_buffer_new (NULL);
gtk_text_buffer_create_tag (text,
"warning",
"underline", PANGO_UNDERLINE_SINGLE,
"underline", PANGO2_LINE_STYLE_SOLID,
NULL);
gtk_text_buffer_create_tag (text,
"error",
"underline", PANGO_UNDERLINE_ERROR,
"underline", PANGO2_LINE_STYLE_DOTTED,
NULL);
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());

View File

@@ -122,11 +122,11 @@ do_css_multiplebgs (GtkWidget *do_widget)
text = gtk_text_buffer_new (NULL);
gtk_text_buffer_create_tag (text,
"warning",
"underline", PANGO_UNDERLINE_SINGLE,
"underline", PANGO2_LINE_STYLE_SOLID,
NULL);
gtk_text_buffer_create_tag (text,
"error",
"underline", PANGO_UNDERLINE_ERROR,
"underline", PANGO2_LINE_STYLE_DOTTED,
NULL);
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());

View File

@@ -93,11 +93,11 @@ do_css_pixbufs (GtkWidget *do_widget)
text = gtk_text_buffer_new (NULL);
gtk_text_buffer_create_tag (text,
"warning",
"underline", PANGO_UNDERLINE_SINGLE,
"underline", PANGO2_LINE_STYLE_SOLID,
NULL);
gtk_text_buffer_create_tag (text,
"error",
"underline", PANGO_UNDERLINE_ERROR,
"underline", PANGO2_LINE_STYLE_DOTTED,
NULL);
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());

View File

@@ -111,11 +111,11 @@ do_css_shadows (GtkWidget *do_widget)
text = gtk_text_buffer_new (NULL);
gtk_text_buffer_create_tag (text,
"warning",
"underline", PANGO_UNDERLINE_SINGLE,
"underline", PANGO2_LINE_STYLE_SOLID,
NULL);
gtk_text_buffer_create_tag (text,
"error",
"underline", PANGO_UNDERLINE_ERROR,
"underline", PANGO2_LINE_STYLE_DOTTED,
NULL);
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());

View File

@@ -263,7 +263,7 @@ drop_down_new_from_strings (const char *const *titles,
static char *
get_family_name (gpointer item)
{
return g_strdup (pango_font_family_get_name (PANGO_FONT_FAMILY (item)));
return g_strdup (pango2_font_family_get_name (PANGO2_FONT_FAMILY (item)));
}
static char *
@@ -326,8 +326,8 @@ bind_highlight_item (GtkSignalListItemFactory *factory,
{
MatchObject *obj;
GtkWidget *label;
PangoAttrList *attrs;
PangoAttribute *attr;
Pango2AttrList *attrs;
Pango2Attribute *attr;
const char *str;
obj = MATCH_OBJECT (gtk_list_item_get_item (item));
@@ -336,13 +336,14 @@ bind_highlight_item (GtkSignalListItemFactory *factory,
str = match_object_get_string (obj);
gtk_label_set_label (GTK_LABEL (label), str);
attrs = pango_attr_list_new ();
attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
attr->start_index = match_object_get_match_start (obj);
attr->end_index = match_object_get_match_end (obj);
pango_attr_list_insert (attrs, attr);
attrs = pango2_attr_list_new ();
attr = pango2_attr_weight_new (PANGO2_WEIGHT_BOLD);
pango2_attribute_set_range (attr,
match_object_get_match_start (obj),
match_object_get_match_end (obj));
pango2_attr_list_insert (attrs, attr);
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs);
pango2_attr_list_unref (attrs);
}
static void
@@ -434,7 +435,7 @@ do_dropdown (GtkWidget *do_widget)
button = gtk_drop_down_new (NULL, NULL);
model = G_LIST_MODEL (pango_cairo_font_map_get_default ());
model = G_LIST_MODEL (pango2_font_map_get_default ());
gtk_drop_down_set_model (GTK_DROP_DOWN (button), model);
gtk_drop_down_set_selected (GTK_DROP_DOWN (button), 0);

View File

@@ -35,9 +35,10 @@ typedef struct {
typedef struct {
unsigned int start;
unsigned int end;
PangoFontDescription *desc;
Pango2FontDescription *desc;
char *features;
PangoLanguage *language;
char *palette;
Pango2Language *language;
} Range;
typedef struct {
@@ -58,6 +59,8 @@ typedef struct {
GtkWidget *script_lang;
GtkWidget *feature_list;
GtkWidget *variations_grid;
GtkWidget *colors_grid;
GtkWidget *first_palette;
GtkWidget *instance_combo;
GtkWidget *stack;
GtkWidget *entry;
@@ -81,6 +84,7 @@ typedef struct {
GtkWidget *swin;
GtkCssProvider *provider;
int sample;
int palette;
} FontFeaturesDemo;
static void
@@ -202,12 +206,12 @@ font_features_reset_basic (void)
static void
update_basic (void)
{
PangoFontDescription *desc;
Pango2FontDescription *desc;
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (demo->font));
gtk_adjustment_set_value (demo->size_adjustment,
pango_font_description_get_size (desc) / (double) PANGO_SCALE);
pango2_font_description_get_size (desc) / (double) PANGO2_SCALE);
}
static void add_font_variations (GString *s);
@@ -218,8 +222,9 @@ free_range (gpointer data)
Range *range = data;
if (range->desc)
pango_font_description_free (range->desc);
pango2_font_description_free (range->desc);
g_free (range->features);
g_free (range->palette);
g_free (range);
}
@@ -244,9 +249,10 @@ compare_range (gconstpointer a, gconstpointer b)
static void
ensure_range (unsigned int start,
unsigned int end,
PangoFontDescription *desc,
Pango2FontDescription *desc,
const char *features,
PangoLanguage *language)
const char *palette,
Pango2Language *language)
{
GList *l;
Range *range;
@@ -270,11 +276,12 @@ ensure_range (unsigned int start,
set:
if (range->desc)
pango_font_description_free (range->desc);
pango2_font_description_free (range->desc);
if (desc)
range->desc = pango_font_description_copy (desc);
range->desc = pango2_font_description_copy (desc);
g_free (range->features);
range->features = g_strdup (features);
range->palette = g_strdup (palette);
range->language = language;
}
@@ -473,19 +480,20 @@ update_display (void)
gboolean has_feature;
GtkTreeIter iter;
GtkTreeModel *model;
PangoFontDescription *desc;
Pango2FontDescription *desc;
GList *l;
PangoAttrList *attrs;
PangoAttribute *attr;
Pango2AttrList *attrs;
Pango2Attribute *attr;
int ins, bound;
guint start, end;
PangoLanguage *lang;
Pango2Language *lang;
char *font_desc;
char *features;
double value;
int text_len;
gboolean do_waterfall;
GString *waterfall;
char *palette;
{
GtkTextBuffer *buffer;
@@ -503,8 +511,8 @@ update_display (void)
if (do_waterfall)
{
start = PANGO_ATTR_INDEX_FROM_TEXT_BEGINNING;
end = PANGO_ATTR_INDEX_TO_TEXT_END;
start = PANGO2_ATTR_INDEX_FROM_TEXT_BEGINNING;
end = PANGO2_ATTR_INDEX_TO_TEXT_END;
}
else if (gtk_label_get_selection_bounds (GTK_LABEL (demo->the_label), &ins, &bound))
{
@@ -513,24 +521,24 @@ update_display (void)
}
else
{
start = PANGO_ATTR_INDEX_FROM_TEXT_BEGINNING;
end = PANGO_ATTR_INDEX_TO_TEXT_END;
start = PANGO2_ATTR_INDEX_FROM_TEXT_BEGINNING;
end = PANGO2_ATTR_INDEX_TO_TEXT_END;
}
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (demo->font));
value = gtk_adjustment_get_value (demo->size_adjustment);
pango_font_description_set_size (desc, value * PANGO_SCALE);
pango2_font_description_set_size (desc, value * PANGO2_SCALE);
s = g_string_new ("");
add_font_variations (s);
if (s->len > 0)
{
pango_font_description_set_variations (desc, s->str);
pango2_font_description_set_variations (desc, s->str);
g_string_free (s, TRUE);
}
font_desc = pango_font_description_to_string (desc);
font_desc = pango2_font_description_to_string (desc);
s = g_string_new ("");
@@ -575,6 +583,8 @@ update_display (void)
features = g_string_free (s, FALSE);
palette = g_strdup_printf ("palette%d", demo->palette);
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (demo->script_lang), &iter))
{
hb_tag_t lang_tag;
@@ -582,27 +592,25 @@ update_display (void)
model = gtk_combo_box_get_model (GTK_COMBO_BOX (demo->script_lang));
gtk_tree_model_get (model, &iter, 3, &lang_tag, -1);
lang = pango_language_from_string (hb_language_to_string (hb_ot_tag_to_language (lang_tag)));
lang = pango2_language_from_string (hb_language_to_string (hb_ot_tag_to_language (lang_tag)));
}
else
lang = NULL;
attrs = pango_attr_list_new ();
attrs = pango2_attr_list_new ();
if (gtk_adjustment_get_value (demo->letterspacing_adjustment) != 0.)
{
attr = pango_attr_letter_spacing_new (gtk_adjustment_get_value (demo->letterspacing_adjustment));
attr->start_index = start;
attr->end_index = end;
pango_attr_list_insert (attrs, attr);
attr = pango2_attr_letter_spacing_new (gtk_adjustment_get_value (demo->letterspacing_adjustment));
pango2_attribute_set_range (attr, start, end);
pango2_attr_list_insert (attrs, attr);
}
if (gtk_adjustment_get_value (demo->line_height_adjustment) != 1.)
{
attr = pango_attr_line_height_new (gtk_adjustment_get_value (demo->line_height_adjustment));
attr->start_index = start;
attr->end_index = end;
pango_attr_list_insert (attrs, attr);
attr = pango2_attr_line_height_new (gtk_adjustment_get_value (demo->line_height_adjustment));
pango2_attribute_set_range (attr, start, end);
pango2_attr_list_insert (attrs, attr);
}
{
@@ -610,16 +618,12 @@ update_display (void)
char *fg, *bg, *css;
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (demo->foreground), &rgba);
attr = pango_attr_foreground_new (65535 * rgba.red,
65535 * rgba.green,
65535 * rgba.blue);
attr->start_index = start;
attr->end_index = end;
pango_attr_list_insert (attrs, attr);
attr = pango_attr_foreground_alpha_new (65535 * rgba.alpha);
attr->start_index = start;
attr->end_index = end;
pango_attr_list_insert (attrs, attr);
attr = pango2_attr_foreground_new (&(Pango2Color){ 65535 * rgba.red,
65535 * rgba.green,
65535 * rgba.blue,
65535 * rgba.alpha });
pango2_attribute_set_range (attr, start, end);
pango2_attr_list_insert (attrs, attr);
fg = gdk_rgba_to_string (&rgba);
gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (demo->background), &rgba);
@@ -633,37 +637,40 @@ update_display (void)
if (do_waterfall)
{
attr = pango_attr_font_desc_new (desc);
pango_attr_list_insert (attrs, attr);
attr = pango_attr_font_features_new (features);
pango_attr_list_insert (attrs, attr);
attr = pango_attr_language_new (lang);
pango_attr_list_insert (attrs, attr);
attr = pango2_attr_font_desc_new (desc);
pango2_attr_list_insert (attrs, attr);
attr = pango2_attr_font_features_new (features);
pango2_attr_list_insert (attrs, attr);
attr = pango2_attr_palette_new (palette);
pango2_attr_list_insert (attrs, attr);
attr = pango2_attr_language_new (lang);
pango2_attr_list_insert (attrs, attr);
}
else
{
ensure_range (start, end, desc, features, lang);
ensure_range (start, end, desc, features, palette, lang);
for (l = demo->ranges; l; l = l->next)
{
Range *range = l->data;
attr = pango_attr_font_desc_new (range->desc);
attr->start_index = range->start;
attr->end_index = range->end;
pango_attr_list_insert (attrs, attr);
attr = pango2_attr_font_desc_new (range->desc);
pango2_attribute_set_range (attr, range->start, range->end);
pango2_attr_list_insert (attrs, attr);
attr = pango_attr_font_features_new (range->features);
attr->start_index = range->start;
attr->end_index = range->end;
pango_attr_list_insert (attrs, attr);
attr = pango2_attr_font_features_new (range->features);
pango2_attribute_set_range (attr, range->start, range->end);
pango2_attr_list_insert (attrs, attr);
attr = pango2_attr_palette_new (range->palette);
pango2_attribute_set_range (attr, range->start, range->end);
pango2_attr_list_insert (attrs, attr);
if (range->language)
{
attr = pango_attr_language_new (range->language);
attr->start_index = range->start;
attr->end_index = range->end;
pango_attr_list_insert (attrs, attr);
attr = pango2_attr_language_new (range->language);
pango2_attribute_set_range (attr, range->start, range->end);
pango2_attr_list_insert (attrs, attr);
}
}
}
@@ -679,14 +686,13 @@ update_display (void)
for (int i = 0; i < G_N_ELEMENTS (sizes); i++)
{
g_string_append (waterfall, text);
g_string_append_c (waterfall, '\n');
g_string_append (waterfall, ""); /* Unicode line separator */
attr = pango_attr_size_new (sizes[i] * PANGO_SCALE);
attr->start_index = start;
attr->end_index = start + text_len;
pango_attr_list_insert (attrs, attr);
attr = pango2_attr_size_new (sizes[i] * PANGO2_SCALE);
pango2_attribute_set_range (attr, start, start + text_len);
pango2_attr_list_insert (attrs, attr);
start += text_len + 1;
start += text_len + strlen ("");
}
gtk_label_set_text (GTK_LABEL (demo->the_label), waterfall->str);
g_string_free (waterfall, TRUE);
@@ -697,22 +703,23 @@ update_display (void)
gtk_label_set_attributes (GTK_LABEL (demo->the_label), attrs);
g_free (font_desc);
pango_font_description_free (desc);
pango2_font_description_free (desc);
g_free (features);
pango_attr_list_unref (attrs);
g_free (palette);
pango2_attr_list_unref (attrs);
g_free (text);
}
static PangoFont *
static Pango2Font *
get_pango_font (void)
{
PangoFontDescription *desc;
PangoContext *context;
Pango2FontDescription *desc;
Pango2Context *context;
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (demo->font));
context = gtk_widget_get_pango_context (demo->font);
return pango_context_load_font (context, desc);
return pango2_context_load_font (context, desc);
}
typedef struct {
@@ -765,7 +772,7 @@ update_script_combo (void)
GtkListStore *store;
hb_font_t *hb_font;
int i, j, k;
PangoFont *pango_font;
Pango2Font *pango_font;
GHashTable *tags;
GHashTableIter iter;
TagPair *pair;
@@ -785,7 +792,7 @@ update_script_combo (void)
store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
pango_font = get_pango_font ();
hb_font = pango_font_get_hb_font (pango_font);
hb_font = pango2_font_get_hb_font (pango_font);
tags = g_hash_table_new_full (tag_pair_hash, tag_pair_equal, g_free, NULL);
@@ -908,7 +915,7 @@ update_features (void)
GtkTreeIter iter;
guint script_index, lang_index;
hb_tag_t lang_tag;
PangoFont *pango_font;
Pango2Font *pango_font;
hb_font_t *hb_font;
GList *l;
@@ -947,8 +954,19 @@ update_features (void)
gtk_check_button_set_active (GTK_CHECK_BUTTON (item->feat), TRUE);
}
/* set feature presence checks from the font features */
if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (demo->script_lang), &iter))
return;
model = gtk_combo_box_get_model (GTK_COMBO_BOX (demo->script_lang));
gtk_tree_model_get (model, &iter,
1, &script_index,
2, &lang_index,
-1);
pango_font = get_pango_font ();
hb_font = pango_font_get_hb_font (pango_font);
hb_font = pango2_font_get_hb_font (pango_font);
if (hb_font)
{
@@ -1176,6 +1194,8 @@ ease_out_cubic (double t)
return p * p * p + 1;
}
static const guint64 period = G_TIME_SPAN_SECOND * 3;
static gboolean
animate_axis (GtkWidget *widget,
GdkFrameClock *frame_clock,
@@ -1187,13 +1207,13 @@ animate_axis (GtkWidget *widget,
now = g_get_monotonic_time ();
if (now >= axis->start_time + G_TIME_SPAN_SECOND)
if (now >= axis->start_time + period)
{
axis->start_time += G_TIME_SPAN_SECOND;
axis->start_time += period;
axis->increasing = !axis->increasing;
}
value = (now - axis->start_time) / (double) G_TIME_SPAN_SECOND;
value = (now - axis->start_time) / (double) period;
value = ease_out_cubic (value);
@@ -1230,7 +1250,7 @@ start_or_stop_axis_animation (GtkButton *button,
lower = gtk_adjustment_get_lower (axis->adjustment);
upper = gtk_adjustment_get_upper (axis->adjustment);
value = value / (upper - lower);
axis->start_time = g_get_monotonic_time () - value * G_TIME_SPAN_SECOND;
axis->start_time = g_get_monotonic_time () - value * period;
axis->increasing = TRUE;
}
}
@@ -1361,7 +1381,7 @@ instance_changed (GtkComboBox *combo)
float *coords = NULL;
hb_ot_var_axis_info_t *ai = NULL;
unsigned int n_axes;
PangoFont *pango_font = NULL;
Pango2Font *pango_font = NULL;
hb_font_t *hb_font;
hb_face_t *hb_face;
@@ -1378,7 +1398,7 @@ instance_changed (GtkComboBox *combo)
}
pango_font = get_pango_font ();
hb_font = pango_font_get_hb_font (pango_font);
hb_font = pango2_font_get_hb_font (pango_font);
hb_face = hb_font_get_face (hb_font);
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
@@ -1479,10 +1499,10 @@ denorm_coord (hb_ot_var_axis_info_t *axis, int coord)
}
static void
update_font_variations (void)
update_variations (void)
{
GtkWidget *child;
PangoFont *pango_font = NULL;
Pango2Font *pango_font = NULL;
hb_font_t *hb_font;
hb_face_t *hb_face;
unsigned int n_axes;
@@ -1501,7 +1521,7 @@ update_font_variations (void)
g_hash_table_remove_all (demo->instances);
pango_font = get_pango_font ();
hb_font = pango_font_get_hb_font (pango_font);
hb_font = pango2_font_get_hb_font (pango_font);
hb_face = hb_font_get_face (hb_font);
n_axes = hb_ot_var_get_axis_infos (hb_face, 0, NULL, NULL);
@@ -1561,13 +1581,125 @@ done:
g_free (design_coords);
}
static void
palette_changed (GtkCheckButton *button)
{
demo->palette = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (button), "palette"));
update_display ();
}
static void
update_colors (void)
{
Pango2Font *pango_font = NULL;
hb_font_t *hb_font;
hb_face_t *hb_face;
GtkWidget *child;
while ((child = gtk_widget_get_first_child (demo->colors_grid)))
gtk_grid_remove (GTK_GRID (demo->colors_grid), child);
pango_font = get_pango_font ();
hb_font = pango2_font_get_hb_font (pango_font);
hb_face = hb_font_get_face (hb_font);
if (hb_ot_color_has_palettes (hb_face))
{
demo->first_palette = NULL;
for (unsigned int i = 0; i < hb_ot_color_palette_get_count (hb_face); i++)
{
hb_ot_name_id_t name_id;
char *name;
unsigned int n_colors;
hb_color_t *colors;
GtkWidget *palette;
GtkWidget *swatch;
hb_ot_color_palette_flags_t flags;
const char *str;
GtkWidget *toggle;
name_id = hb_ot_color_palette_get_name_id (hb_face, i);
if (name_id != HB_OT_NAME_ID_INVALID)
{
unsigned int len;
char buf[80];
len = sizeof (buf);
hb_ot_name_get_utf8 (hb_face, name_id, HB_LANGUAGE_INVALID, &len, buf);
name = g_strdup (buf);
}
else
name = g_strdup_printf ("Palette %d", i);
toggle = gtk_check_button_new_with_label (name);
if (i == demo->palette)
gtk_check_button_set_active (GTK_CHECK_BUTTON (toggle), TRUE);
g_object_set_data (G_OBJECT (toggle), "palette", GUINT_TO_POINTER (i));
g_signal_connect (toggle, "toggled", G_CALLBACK (palette_changed), NULL);
if (demo->first_palette)
gtk_check_button_set_group (GTK_CHECK_BUTTON (toggle), GTK_CHECK_BUTTON (demo->first_palette));
else
demo->first_palette = toggle;
g_free (name);
gtk_grid_attach (GTK_GRID (demo->colors_grid), toggle, 0, i, 1, 1);
flags = hb_ot_color_palette_get_flags (hb_face, i);
if ((flags & (HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND |
HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND)) ==
(HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND |
HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND))
str = "(light, dark)";
else if (flags & HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND)
str = "(light)";
else if (flags & HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND)
str = "(dark)";
else
str = NULL;
if (str)
gtk_grid_attach (GTK_GRID (demo->colors_grid), gtk_label_new (str), 1, i, 1, 1);
n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, NULL, NULL);
colors = g_new (hb_color_t, n_colors);
n_colors = hb_ot_color_palette_get_colors (hb_face, i, 0, &n_colors, colors);
palette = gtk_grid_new ();
gtk_grid_attach (GTK_GRID (demo->colors_grid), palette, 2, i, 1, 1);
for (int k = 0; k < n_colors; k++)
{
swatch = g_object_new (g_type_from_name ("GtkColorSwatch"),
"rgba", &(GdkRGBA){ hb_color_get_red (colors[k])/255.,
hb_color_get_green (colors[k])/255.,
hb_color_get_blue (colors[k])/255.,
hb_color_get_alpha (colors[k])/255.},
"width-request", 16,
"height-request", 16,
NULL);
gtk_grid_attach (GTK_GRID (palette), swatch, k % 8, k / 8, 1, 1);
}
}
}
}
static void
font_features_reset_colors (void)
{
gtk_check_button_set_active (GTK_CHECK_BUTTON (demo->first_palette), TRUE);
}
static void
font_features_font_changed (void)
{
update_basic ();
update_script_combo ();
update_features ();
update_font_variations ();
update_variations ();
update_colors ();
}
static void
@@ -1704,6 +1836,7 @@ do_font_features (GtkWidget *do_widget)
gtk_builder_cscope_add_callback (scope, font_features_reset_basic);
gtk_builder_cscope_add_callback (scope, font_features_reset_features);
gtk_builder_cscope_add_callback (scope, font_features_reset_variations);
gtk_builder_cscope_add_callback (scope, font_features_reset_colors);
gtk_builder_cscope_add_callback (scope, font_features_toggle_plain);
gtk_builder_cscope_add_callback (scope, font_features_toggle_edit);
gtk_builder_cscope_add_callback (scope, font_features_stop_edit);
@@ -1742,6 +1875,8 @@ do_font_features (GtkWidget *do_widget)
demo->foreground = GTK_WIDGET (gtk_builder_get_object (builder, "foreground"));
demo->background = GTK_WIDGET (gtk_builder_get_object (builder, "background"));
demo->swin = GTK_WIDGET (gtk_builder_get_object (builder, "swin"));
demo->variations_grid = GTK_WIDGET (gtk_builder_get_object (builder, "variations_grid"));
demo->colors_grid = GTK_WIDGET (gtk_builder_get_object (builder, "colors_grid"));
demo->provider = gtk_css_provider_new ();
gtk_style_context_add_provider (gtk_widget_get_style_context (demo->swin),
@@ -1796,7 +1931,6 @@ do_font_features (GtkWidget *do_widget)
(const char *[]){ "opbd", "lfbd", "rtbd", NULL });
demo->feature_items = g_list_reverse (demo->feature_items);
demo->variations_grid = GTK_WIDGET (gtk_builder_get_object (builder, "variations_grid"));
if (demo->instances == NULL)
demo->instances = g_hash_table_new_full (instance_hash, instance_equal, NULL, free_instance);
else

View File

@@ -38,6 +38,7 @@
<signal name="clicked" handler="font_features_reset_basic" swapped="no"/>
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
<signal name="clicked" handler="font_features_reset_variations" swapped="no"/>
<signal name="clicked" handler="font_features_reset_colors" swapped="no"/>
</object>
</child>
</object>
@@ -296,6 +297,27 @@
</child>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel">
<property name="label" translatable="yes">Color Palettes</property>
<property name="xalign">0</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<style>
<class name="title-4"/>
</style>
</object>
</child>
<child>
<object class="GtkGrid" id="colors_grid">
<property name="column-spacing">10</property>
<property name="row-spacing">10</property>
</object>
</child>
</object>
</child>
</object>
</child>
<style>

View File

@@ -19,7 +19,7 @@
*/
static void
insert_tags_for_attributes (GtkTextBuffer *buffer,
PangoAttrIterator *iter,
Pango2AttrIterator *iter,
GtkTextIter *start,
GtkTextIter *end)
{
@@ -27,13 +27,12 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
GSList *attrs, *l;
GtkTextTag *tag;
char name[256];
float fg_alpha, bg_alpha;
table = gtk_text_buffer_get_tag_table (buffer);
#define LANGUAGE_ATTR(attr_name) \
{ \
const char *language = pango_language_to_string (((PangoAttrLanguage*)attr)->value); \
const char *language = pango2_language_to_string (pango2_attribute_get_language (attr)); \
g_snprintf (name, 256, "language=%s", language); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
@@ -48,7 +47,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
#define STRING_ATTR(attr_name) \
{ \
const char *string = ((PangoAttrString*)attr)->value; \
const char *string = pango2_attribute_get_string (attr); \
g_snprintf (name, 256, #attr_name "=%s", string); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
@@ -63,7 +62,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
#define INT_ATTR(attr_name) \
{ \
int value = ((PangoAttrInt*)attr)->value; \
int value = pango2_attribute_get_int (attr); \
g_snprintf (name, 256, #attr_name "=%d", value); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
@@ -78,8 +77,8 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
#define FONT_ATTR(attr_name) \
{ \
PangoFontDescription *desc = ((PangoAttrFontDesc*)attr)->desc; \
char *str = pango_font_description_to_string (desc); \
Pango2FontDescription *desc = pango2_attribute_get_font_desc (attr); \
char *str = pango2_font_description_to_string (desc); \
g_snprintf (name, 256, "font-desc=%s", str); \
g_free (str); \
tag = gtk_text_tag_table_lookup (table, name); \
@@ -95,7 +94,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
#define FLOAT_ATTR(attr_name) \
{ \
float value = ((PangoAttrFloat*)attr)->value; \
float value = pango2_attribute_get_float (attr); \
g_snprintf (name, 256, #attr_name "=%g", value); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
@@ -108,15 +107,14 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
#define RGBA_ATTR(attr_name, alpha_value) \
#define RGBA_ATTR(attr_name) \
{ \
PangoColor *color; \
Pango2Color *color = pango2_attribute_get_color (attr); \
GdkRGBA rgba; \
color = &((PangoAttrColor*)attr)->color; \
rgba.red = color->red / 65535.; \
rgba.green = color->green / 65535.; \
rgba.blue = color->blue / 65535.; \
rgba.alpha = alpha_value; \
rgba.alpha = color->alpha / 65535.; \
char *str = gdk_rgba_to_string (&rgba); \
g_snprintf (name, 256, #attr_name "=%s", str); \
g_free (str); \
@@ -144,173 +142,157 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
fg_alpha = bg_alpha = 1.;
attrs = pango_attr_iterator_get_attrs (iter);
attrs = pango2_attr_iterator_get_attrs (iter);
for (l = attrs; l; l = l->next)
{
PangoAttribute *attr = l->data;
Pango2Attribute *attr = l->data;
switch ((int)attr->klass->type)
switch (pango2_attribute_type (attr))
{
case PANGO_ATTR_FOREGROUND_ALPHA:
fg_alpha = ((PangoAttrInt*)attr)->value / 65535.;
break;
case PANGO_ATTR_BACKGROUND_ALPHA:
bg_alpha = ((PangoAttrInt*)attr)->value / 65535.;
break;
default:
break;
}
}
for (l = attrs; l; l = l->next)
{
PangoAttribute *attr = l->data;
switch (attr->klass->type)
{
case PANGO_ATTR_LANGUAGE:
case PANGO2_ATTR_LANGUAGE:
LANGUAGE_ATTR (language);
break;
case PANGO_ATTR_FAMILY:
case PANGO2_ATTR_FAMILY:
STRING_ATTR (family);
break;
case PANGO_ATTR_STYLE:
case PANGO2_ATTR_STYLE:
INT_ATTR (style);
break;
case PANGO_ATTR_WEIGHT:
case PANGO2_ATTR_WEIGHT:
INT_ATTR (weight);
break;
case PANGO_ATTR_VARIANT:
case PANGO2_ATTR_VARIANT:
INT_ATTR (variant);
break;
case PANGO_ATTR_STRETCH:
case PANGO2_ATTR_STRETCH:
INT_ATTR (stretch);
break;
case PANGO_ATTR_SIZE:
case PANGO2_ATTR_SIZE:
INT_ATTR (size);
break;
case PANGO_ATTR_FONT_DESC:
case PANGO2_ATTR_FONT_DESC:
FONT_ATTR (font-desc);
break;
case PANGO_ATTR_FOREGROUND:
RGBA_ATTR (foreground_rgba, fg_alpha);
case PANGO2_ATTR_FOREGROUND:
RGBA_ATTR (foreground_rgba);
break;
case PANGO_ATTR_BACKGROUND:
RGBA_ATTR (background_rgba, bg_alpha);
case PANGO2_ATTR_BACKGROUND:
RGBA_ATTR (background_rgba);
break;
case PANGO_ATTR_UNDERLINE:
case PANGO2_ATTR_UNDERLINE:
INT_ATTR (underline);
break;
case PANGO_ATTR_UNDERLINE_COLOR:
RGBA_ATTR (underline_rgba, fg_alpha);
case PANGO2_ATTR_UNDERLINE_COLOR:
RGBA_ATTR (underline_rgba);
break;
case PANGO_ATTR_OVERLINE:
case PANGO2_ATTR_OVERLINE:
INT_ATTR (overline);
break;
case PANGO_ATTR_OVERLINE_COLOR:
RGBA_ATTR (overline_rgba, fg_alpha);
case PANGO2_ATTR_OVERLINE_COLOR:
RGBA_ATTR (overline_rgba);
break;
case PANGO_ATTR_STRIKETHROUGH:
case PANGO2_ATTR_STRIKETHROUGH:
INT_ATTR (strikethrough);
break;
case PANGO_ATTR_STRIKETHROUGH_COLOR:
RGBA_ATTR (strikethrough_rgba, fg_alpha);
case PANGO2_ATTR_STRIKETHROUGH_COLOR:
RGBA_ATTR (strikethrough_rgba);
break;
case PANGO_ATTR_RISE:
case PANGO2_ATTR_RISE:
INT_ATTR (rise);
break;
case PANGO_ATTR_SCALE:
case PANGO2_ATTR_SCALE:
FLOAT_ATTR (scale);
break;
case PANGO_ATTR_FALLBACK:
case PANGO2_ATTR_FALLBACK:
INT_ATTR (fallback);
break;
case PANGO_ATTR_LETTER_SPACING:
case PANGO2_ATTR_LETTER_SPACING:
INT_ATTR (letter_spacing);
break;
case PANGO_ATTR_FONT_FEATURES:
case PANGO2_ATTR_FONT_FEATURES:
STRING_ATTR (font_features);
break;
case PANGO_ATTR_ALLOW_BREAKS:
case PANGO2_ATTR_ALLOW_BREAKS:
INT_ATTR (allow_breaks);
break;
case PANGO_ATTR_SHOW:
case PANGO2_ATTR_SHOW:
INT_ATTR (show_spaces);
break;
case PANGO_ATTR_INSERT_HYPHENS:
case PANGO2_ATTR_INSERT_HYPHENS:
INT_ATTR (insert_hyphens);
break;
case PANGO_ATTR_LINE_HEIGHT:
case PANGO2_ATTR_LINE_HEIGHT:
FLOAT_ATTR (line_height);
break;
case PANGO_ATTR_ABSOLUTE_LINE_HEIGHT:
case PANGO2_ATTR_ABSOLUTE_LINE_HEIGHT:
break;
case PANGO_ATTR_WORD:
case PANGO2_ATTR_LINE_SPACING:
INT_ATTR (pixels_inside_wrap);
break;
case PANGO2_ATTR_WORD:
VOID_ATTR (word);
break;
case PANGO_ATTR_SENTENCE:
case PANGO2_ATTR_SENTENCE:
VOID_ATTR (sentence);
break;
case PANGO_ATTR_BASELINE_SHIFT:
case PANGO2_ATTR_PARAGRAPH:
VOID_ATTR (paragraph);
break;
case PANGO2_ATTR_BASELINE_SHIFT:
INT_ATTR (baseline_shift);
break;
case PANGO_ATTR_FONT_SCALE:
case PANGO2_ATTR_FONT_SCALE:
INT_ATTR (font_scale);
break;
case PANGO_ATTR_SHAPE:
case PANGO_ATTR_ABSOLUTE_SIZE:
case PANGO_ATTR_GRAVITY:
case PANGO_ATTR_GRAVITY_HINT:
case PANGO_ATTR_FOREGROUND_ALPHA:
case PANGO_ATTR_BACKGROUND_ALPHA:
case PANGO2_ATTR_ABSOLUTE_SIZE:
case PANGO2_ATTR_GRAVITY:
case PANGO2_ATTR_GRAVITY_HINT:
break;
case PANGO_ATTR_TEXT_TRANSFORM:
case PANGO2_ATTR_TEXT_TRANSFORM:
INT_ATTR (text_transform);
break;
case PANGO_ATTR_INVALID:
case PANGO2_ATTR_INVALID:
default:
g_assert_not_reached ();
break;
}
}
g_slist_free_full (attrs, (GDestroyNotify)pango_attribute_destroy);
g_slist_free_full (attrs, (GDestroyNotify)pango2_attribute_destroy);
#undef LANGUAGE_ATTR
#undef STRING_ATTR
@@ -329,9 +311,9 @@ typedef struct
GtkTextBuffer *buffer;
GtkTextIter iter;
GtkTextMark *mark;
PangoAttrList *attributes;
Pango2AttrList *attributes;
char *text;
PangoAttrIterator *attr;
Pango2AttrIterator *attr;
} MarkupData;
static void
@@ -340,8 +322,8 @@ free_markup_data (MarkupData *mdata)
g_free (mdata->markup);
g_clear_pointer (&mdata->parser, g_markup_parse_context_free);
gtk_text_buffer_delete_mark (mdata->buffer, mdata->mark);
g_clear_pointer (&mdata->attr, pango_attr_iterator_destroy);
g_clear_pointer (&mdata->attributes, pango_attr_list_unref);
g_clear_pointer (&mdata->attr, pango2_attr_iterator_destroy);
g_clear_pointer (&mdata->attributes, pango2_attr_list_unref);
g_free (mdata->text);
g_object_unref (mdata->buffer);
g_free (mdata);
@@ -367,7 +349,7 @@ insert_markup_idle (gpointer data)
return G_SOURCE_REMOVE;
}
pango_attr_iterator_range (mdata->attr, &start, &end);
pango2_attr_iterator_range (mdata->attr, &start, &end);
if (end == G_MAXINT) /* last chunk */
end = start - 1; /* resulting in -1 to be passed to _insert */
@@ -380,7 +362,7 @@ insert_markup_idle (gpointer data)
gtk_text_buffer_get_iter_at_mark (mdata->buffer, &mdata->iter, mdata->mark);
}
while (pango_attr_iterator_next (mdata->attr));
while (pango2_attr_iterator_next (mdata->attr));
free_markup_data (mdata);
return G_SOURCE_REMOVE;
@@ -416,7 +398,7 @@ parse_markup_idle (gpointer data)
mdata->pos += 4096;
} while (mdata->pos < mdata->len);
if (!pango_markup_parser_finish (mdata->parser,
if (!pango2_markup_parser_finish (mdata->parser,
&mdata->attributes,
&mdata->text,
NULL,
@@ -435,7 +417,7 @@ parse_markup_idle (gpointer data)
return G_SOURCE_REMOVE;
}
mdata->attr = pango_attr_list_get_iterator (mdata->attributes);
mdata->attr = pango2_attr_list_get_iterator (mdata->attributes);
insert_markup_idle (data);
return G_SOURCE_REMOVE;
@@ -461,7 +443,7 @@ insert_markup (GtkTextBuffer *buffer,
data->markup = markup;
data->len = len;
data->parser = pango_markup_parser_new (0);
data->parser = pango2_markup_parser_new (0);
data->pos = 0;
/* create mark with right gravity */

View File

@@ -25,7 +25,7 @@ static GtkWidget *show_extents = NULL;
static GtkWidget *show_pixels = NULL;
static GtkWidget *show_outlines = NULL;
static PangoContext *context;
static Pango2Context *context;
static int scale = 7;
static double pixel_alpha = 1.0;
@@ -35,9 +35,9 @@ static void
update_image (void)
{
const char *text;
PangoFontDescription *desc;
PangoLayout *layout;
PangoRectangle ink, logical;
Pango2FontDescription *desc;
Pango2Layout *layout;
Pango2Rectangle ink, logical;
int baseline;
cairo_surface_t *surface;
cairo_t *cr;
@@ -56,7 +56,7 @@ update_image (void)
text = gtk_editable_get_text (GTK_EDITABLE (entry));
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font_button));
fopt = cairo_font_options_copy (pango_cairo_context_get_font_options (context));
fopt = cairo_font_options_copy (pango2_cairo_context_get_font_options (context));
hint = gtk_combo_box_get_active_id (GTK_COMBO_BOX (hinting));
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
@@ -85,20 +85,20 @@ update_image (void)
antialias = CAIRO_ANTIALIAS_NONE;
cairo_font_options_set_antialias (fopt, antialias);
pango_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
pango_cairo_context_set_font_options (context, fopt);
pango2_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
pango2_cairo_context_set_font_options (context, fopt);
cairo_font_options_destroy (fopt);
pango_context_changed (context);
pango2_context_changed (context);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (text_radio)))
{
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, text, -1);
pango_layout_get_extents (layout, &ink, &logical);
baseline = pango_layout_get_baseline (layout);
layout = pango2_layout_new (context);
pango2_layout_set_font_description (layout, desc);
pango2_layout_set_text (layout, text, -1);
pango2_lines_get_extents (pango2_layout_get_lines (layout), &ink, &logical);
baseline = pango2_lines_get_baseline (pango2_layout_get_lines (layout));
pango_extents_to_pixels (&ink, NULL);
pango2_extents_to_pixels (&ink, NULL);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ink.width + 20, ink.height + 20);
cr = cairo_create (surface);
@@ -108,9 +108,9 @@ update_image (void)
cairo_set_source_rgba (cr, 0, 0, 0, pixel_alpha);
cairo_move_to (cr, 10, 10);
pango_cairo_show_layout (cr, layout);
pango2_cairo_show_layout (cr, layout);
pango_cairo_layout_path (cr, layout);
pango2_cairo_layout_path (cr, layout);
path = cairo_copy_path (cr);
cairo_destroy (cr);
@@ -154,15 +154,15 @@ update_image (void)
cairo_set_source_rgb (cr, 0, 0, 1);
cairo_rectangle (cr,
scale * (10 + pango_units_to_double (logical.x)) - 0.5,
scale * (10 + pango_units_to_double (logical.y)) - 0.5,
scale * pango_units_to_double (logical.width) + 1,
scale * pango_units_to_double (logical.height) + 1);
scale * (10 + pango2_units_to_double (logical.x)) - 0.5,
scale * (10 + pango2_units_to_double (logical.y)) - 0.5,
scale * pango2_units_to_double (logical.width) + 1,
scale * pango2_units_to_double (logical.height) + 1);
cairo_stroke (cr);
cairo_move_to (cr, scale * (10 + pango_units_to_double (logical.x)) - 0.5,
scale * (10 + pango_units_to_double (baseline)) - 0.5);
cairo_line_to (cr, scale * (10 + pango_units_to_double (logical.x + logical.width)) + 1,
scale * (10 + pango_units_to_double (baseline)) - 0.5);
cairo_move_to (cr, scale * (10 + pango2_units_to_double (logical.x)) - 0.5,
scale * (10 + pango2_units_to_double (baseline)) - 0.5);
cairo_line_to (cr, scale * (10 + pango2_units_to_double (logical.x + logical.width)) + 1,
scale * (10 + pango2_units_to_double (baseline)) - 0.5);
cairo_stroke (cr);
cairo_set_source_rgb (cr, 1, 0, 0);
cairo_rectangle (cr,
@@ -206,9 +206,10 @@ update_image (void)
}
else
{
PangoLayoutIter *iter;
PangoLayoutRun *run;
PangoGlyphInfo *g;
Pango2LineIter *iter;
Pango2Run *run;
Pango2GlyphString *glyphs;
Pango2GlyphInfo *g;
int i, j;
GString *str;
gunichar ch;
@@ -226,43 +227,44 @@ update_image (void)
g_string_append_unichar (str, 0x200c);
}
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, str->str, -1);
layout = pango2_layout_new (context);
pango2_layout_set_font_description (layout, desc);
pango2_layout_set_text (layout, str->str, -1);
g_string_free (str, TRUE);
pango_layout_get_extents (layout, &ink, &logical);
pango_extents_to_pixels (&logical, NULL);
pango2_lines_get_extents (pango2_layout_get_lines (layout), &ink, &logical);
pango2_extents_to_pixels (&logical, NULL);
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, logical.width * 3 / 2, 4*logical.height);
cr = cairo_create (surface);
cairo_set_source_rgb (cr, 1, 1, 1);
cairo_paint (cr);
iter = pango_layout_get_iter (layout);
run = pango_layout_iter_get_run (iter);
iter = pango2_layout_get_iter (layout);
run = pango2_line_iter_get_run (iter);
glyphs = pango2_run_get_glyphs (run);
cairo_set_source_rgb (cr, 0, 0, 0);
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[2*i]);
g->geometry.width = PANGO_UNITS_ROUND (g->geometry.width * 3 / 2);
g = &(glyphs->glyphs[2*i]);
g->geometry.width = PANGO2_UNITS_ROUND (g->geometry.width * 3 / 2);
}
for (j = 0; j < 4; j++)
{
for (i = 0; i < 4; i++)
{
g = &(run->glyphs->glyphs[2*i]);
g->geometry.x_offset = i * (PANGO_SCALE / 4);
g->geometry.y_offset = j * (PANGO_SCALE / 4);
g = &(glyphs->glyphs[2*i]);
g->geometry.x_offset = i * (PANGO2_SCALE / 4);
g->geometry.y_offset = j * (PANGO2_SCALE / 4);
}
cairo_move_to (cr, 0, j * logical.height);
pango_cairo_show_layout (cr, layout);
pango2_cairo_show_layout (cr, layout);
}
cairo_destroy (cr);
pango_layout_iter_free (iter);
pango2_line_iter_free (iter);
g_object_unref (layout);
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
@@ -275,7 +277,7 @@ update_image (void)
g_object_unref (pixbuf2);
pango_font_description_free (desc);
pango2_font_description_free (desc);
}
static gboolean fading = FALSE;

View File

@@ -29,7 +29,7 @@ insert_link (GtkTextBuffer *buffer,
tag = gtk_text_buffer_create_tag (buffer, NULL,
"foreground", "blue",
"underline", PANGO_UNDERLINE_SINGLE,
"underline", PANGO2_LINE_STYLE_SOLID,
NULL);
g_object_set_data (G_OBJECT (tag), "page", GINT_TO_POINTER (page));
gtk_text_buffer_insert_with_tags (buffer, iter, text, -1, tag, NULL);
@@ -72,8 +72,8 @@ show_page (GtkTextView *text_view,
buffer = gtk_text_view_get_buffer (text_view);
bold = gtk_text_buffer_create_tag (buffer, NULL,
"weight", PANGO_WEIGHT_BOLD,
"scale", PANGO_SCALE_X_LARGE,
"weight", PANGO2_WEIGHT_BOLD,
"scale", PANGO2_SCALE_X_LARGE,
NULL);
mono = gtk_text_buffer_create_tag (buffer, NULL,
"family", "monospace",

View File

@@ -123,11 +123,11 @@ populate_emoji_text (void)
for (int i = 0; i < 500; i++)
{
if (i % 2)
g_string_append (s, "<span underline=\"single\" underline_color=\"red\">x</span>");
g_string_append (s, "<span underline=\"solid\" underline_color=\"red\">x</span>");
for (int j = 0; j < 30; j++)
{
g_string_append (s, "💓");
g_string_append (s, "<span underline=\"single\" underline_color=\"red\">x</span>");
g_string_append (s, "<span underline=\"solid\" underline_color=\"red\">x</span>");
}
g_string_append (s, "\n");
}

View File

@@ -44,7 +44,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
gint i;
const LCTYPE iso639_lctypes[] = { LOCALE_SISO639LANGNAME, LOCALE_SISO639LANGNAME2 };
GHashTable *ht_scripts_langs = (GHashTable *) param;
PangoLanguage *lang;
Pango2Language *lang;
gint langname_size, locale_abbrev_size;
langname_size = GetLocaleInfoEx (locale_w, LOCALE_SLOCALIZEDDISPLAYNAME, langname_w, 0);
@@ -60,7 +60,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
langname = g_utf16_to_utf8 (langname_w, -1, NULL, NULL, NULL);
locale = g_utf16_to_utf8 (locale_w, -1, NULL, NULL, NULL);
p = strchr (locale, '-');
lang = pango_language_from_string (locale);
lang = pango2_language_from_string (locale);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
@@ -77,7 +77,7 @@ get_win32_all_locales_scripts (LPWSTR locale_w, DWORD flags, LPARAM param)
GetLocaleInfoEx (locale_w, iso639_lctypes[i], locale_abbrev_w, locale_abbrev_size);
locale_abbrev = g_utf16_to_utf8 (locale_abbrev_w, -1, NULL, NULL, NULL);
lang = pango_language_from_string (locale_abbrev);
lang = pango2_language_from_string (locale_abbrev);
if (g_hash_table_lookup (ht_scripts_langs, lang) == NULL)
g_hash_table_insert (ht_scripts_langs, lang, langname);
@@ -218,22 +218,22 @@ languages_parse_start_tag (GMarkupParseContext *ctx,
if (ccode != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode),
pango2_language_from_string (ccode),
g_strdup (display_name));
if (ccode_longB != NULL)
g_hash_table_insert (language_map,
pango_language_from_string (ccode_longB),
pango2_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),
pango2_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),
pango2_language_from_string (ccode_id),
g_strdup (display_name));
g_free (display_name);
@@ -295,7 +295,7 @@ languages_init (void)
}
const char *
get_language_name (PangoLanguage *language)
get_language_name (Pango2Language *language)
{
languages_init ();
@@ -311,5 +311,5 @@ get_language_name_for_tag (guint32 tag)
lang = hb_ot_tag_to_language (tag);
s = hb_language_to_string (lang);
return get_language_name (pango_language_from_string (s));
return get_language_name (pango2_language_from_string (s));
}

View File

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

View File

@@ -72,7 +72,7 @@ do_links (GtkWidget *do_widget)
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
gtk_label_set_max_width_chars (GTK_LABEL (label), 40);
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD);
gtk_label_set_wrap_mode (GTK_LABEL (label), PANGO2_WRAP_WORD);
g_signal_connect (label, "activate-link", G_CALLBACK (activate_link), NULL);
gtk_widget_set_margin_start (label, 20);
gtk_widget_set_margin_end (label, 20);

View File

@@ -758,15 +758,15 @@ setup_number_item (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
GtkWidget *label;
PangoAttrList *attrs;
Pango2AttrList *attrs;
label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (label), 1);
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum"));
attrs = pango2_attr_list_new ();
pango2_attr_list_insert (attrs, pango2_attr_font_features_new ("tnum"));
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs);
pango2_attr_list_unref (attrs);
gtk_list_item_set_child (item, label);
}
@@ -862,7 +862,7 @@ do_listview_colors (GtkWidget *do_widget)
GtkExpression *expression;
GtkWidget *button;
GtkWidget *label;
PangoAttrList *attrs;
Pango2AttrList *attrs;
char *string;
guint len;
GtkWidget *selection_view;
@@ -990,10 +990,10 @@ do_listview_colors (GtkWidget *do_widget)
gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button);
label = gtk_label_new ("0 /");
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum"));
attrs = pango2_attr_list_new ();
pango2_attr_list_insert (attrs, pango2_attr_font_features_new ("tnum"));
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs);
pango2_attr_list_unref (attrs);
string = g_strdup_printf ("%'u", 4096);
len = g_utf8_strlen (string, -1);
g_free (string);

View File

@@ -123,7 +123,7 @@ setup_ellipsizing_label (GtkSignalListItemFactory *factory,
GtkWidget *label;
label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO2_ELLIPSIZE_END);
gtk_label_set_width_chars (GTK_LABEL (label), 20);
gtk_list_item_set_child (GTK_LIST_ITEM (listitem), label);
}

View File

@@ -190,8 +190,8 @@ activate_about (GSimpleAction *action,
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (s, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),

View File

@@ -7,9 +7,9 @@ Text weights: <span weight="thin">thin</span> <span weight="light">light</span>
Text <span color="gray">c<span color="green">o</span>l<span color="tomato">o</span>rs</span> and <span background="pink">backgrounds</span>
Colorful <span underline="low" underline-color="blue"><span underline="double" underline-color="red">under</span>lines</span> and <span background="pink"><span underline="error">mo</span><span underline="error" underline-color="green">re</span></span>
Colorful <span underline_position="under" underline-color="blue"><span underline="double" underline-color="red">under</span>lines</span> and <span background="pink"><span underline="wavy">mo</span><span underline="wavy" underline-color="green">re</span></span>
Colorful <span strikethrough="true" strikethrough-color="magenta">strikethroughs</span> and <span overline="single" overline_color="green">overlines</span>
Colorful <span strikethrough="solid" strikethrough-color="magenta">strikethroughs</span> and <span overline="solid" overline_color="green">overlines</span>
Superscripts and subscripts: 𝜀<span rise="-6000" size="x-small" font_desc="italic">0</span> = 𝜔<span rise="8000" size="smaller">𝜔<span rise="14000" size="smaller">𝜔<span rise="20000">.<span rise="23000">.<span rise="26000">.</span></span></span></span></span>
@@ -19,7 +19,7 @@ OpenType font features: <span font_desc="sans regular" font_features="dlig=0">fe
Shortcuts: <tt>Monospace</tt> <b>Bold</b> <i>Italic</i> <big>Big</big> <small>Small</small> <u>Underlined</u> <s>Strikethrough</s> Super<sup>script</sup> Sub<sub>script</sub>
hy­phen­ation al­go­rithm is a <span allow_breaks="false" style="italic">set of rules</span>, espe­ci­ally one co­di­fied for im­ple­men­tation in a com­pu­ter pro­gram, that de­ci­des at which points a word can be bro­ken over two lines with a hy­phen. For ex­am­ple, a hy­phen­ation al­go­rithm might de­cide that im­peach­ment can be broken as impeach‧ment or im‧peachment but not impe‧achment.
A hy­phen­ation al­go­rithm is a <span allow_breaks="false" style="italic">set of rules</span>, espe­ci­ally one co­di­fied for im­ple­men­tation in a com­pu­ter pro­gram, that de­ci­des at which points a word can be bro­ken over two lines with a hy­phen. For ex­am­ple, a hy­phen­ation al­go­rithm might de­cide that im­peach­ment can be broken as impeach‧ment or im‧peachment but not impe‧achment.
<span insert_hyphens="false">one/two three/four five/six seven/eight nine/ten</span>

View File

@@ -75,7 +75,7 @@ demos = files([
'printing.c',
'read_more.c',
'revealer.c',
'rotated_text.c',
#'rotated_text.c', FIXME
'scale.c',
'search_entry.c',
'search_entry2.c',

View File

@@ -11,8 +11,8 @@
#include <gtk/gtk.h>
static gboolean
filter_font_cb (const PangoFontFamily *family,
const PangoFontFace *face,
filter_font_cb (const Pango2FontFamily *family,
const Pango2FontFace *face,
gpointer data)
{
const char *alias_families[] = {
@@ -26,9 +26,15 @@ filter_font_cb (const PangoFontFamily *family,
};
const char *family_name;
family_name = pango_font_family_get_name (PANGO_FONT_FAMILY (family));
family_name = pango2_font_family_get_name ((Pango2FontFamily *)family);
return g_strv_contains (alias_families, family_name);
for (int i = 0; alias_families[i]; i++)
{
if (g_ascii_strcasecmp (alias_families[i], family_name) == 0)
return TRUE;
}
return FALSE;
}
#define COLOR(r,g,b) { r/255., g/255., b/255., 1.0 }

View File

@@ -59,11 +59,11 @@ draw_page (GtkPrintOperation *operation,
{
PrintData *data = (PrintData *)user_data;
cairo_t *cr;
PangoLayout *layout;
int text_width, text_height;
Pango2Layout *layout;
Pango2Rectangle ext;
double width;
int line, i;
PangoFontDescription *desc;
Pango2FontDescription *desc;
char *page_str;
cr = gtk_print_context_get_cairo_context (context);
@@ -80,47 +80,50 @@ draw_page (GtkPrintOperation *operation,
layout = gtk_print_context_create_pango_layout (context);
desc = pango_font_description_from_string ("sans 14");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
desc = pango2_font_description_from_string ("sans 14");
pango2_layout_set_font_description (layout, desc);
pango2_font_description_free (desc);
pango_layout_set_text (layout, data->resourcename, -1);
pango_layout_get_pixel_size (layout, &text_width, &text_height);
pango2_layout_set_text (layout, data->resourcename, -1);
pango2_lines_get_extents (pango2_layout_get_lines (layout), NULL, &ext);
pango2_extents_to_pixels (&ext, NULL);
if (text_width > width)
if (ext.width > width)
{
pango_layout_set_width (layout, width);
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_START);
pango_layout_get_pixel_size (layout, &text_width, &text_height);
pango2_layout_set_width (layout, width);
pango2_layout_set_ellipsize (layout, PANGO2_ELLIPSIZE_START);
pango2_lines_get_extents (pango2_layout_get_lines (layout), NULL, &ext);
pango2_extents_to_pixels (&ext, NULL);
}
cairo_move_to (cr, (width - text_width) / 2, (HEADER_HEIGHT - text_height) / 2);
pango_cairo_show_layout (cr, layout);
cairo_move_to (cr, (width - ext.width) / 2, (HEADER_HEIGHT - ext.height) / 2);
pango2_cairo_show_layout (cr, layout);
page_str = g_strdup_printf ("%d/%d", page_nr + 1, data->num_pages);
pango_layout_set_text (layout, page_str, -1);
pango2_layout_set_text (layout, page_str, -1);
g_free (page_str);
pango_layout_set_width (layout, -1);
pango_layout_get_pixel_size (layout, &text_width, &text_height);
cairo_move_to (cr, width - text_width - 4, (HEADER_HEIGHT - text_height) / 2);
pango_cairo_show_layout (cr, layout);
pango2_layout_set_width (layout, -1);
pango2_lines_get_extents (pango2_layout_get_lines (layout), NULL, &ext);
pango2_extents_to_pixels (&ext, NULL);
cairo_move_to (cr, width - ext.width - 4, (HEADER_HEIGHT - ext.height) / 2);
pango2_cairo_show_layout (cr, layout);
g_object_unref (layout);
layout = gtk_print_context_create_pango_layout (context);
desc = pango_font_description_from_string ("monospace");
pango_font_description_set_size (desc, data->font_size * PANGO_SCALE);
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
desc = pango2_font_description_from_string ("monospace");
pango2_font_description_set_size (desc, data->font_size * PANGO2_SCALE);
pango2_layout_set_font_description (layout, desc);
pango2_font_description_free (desc);
cairo_move_to (cr, 0, HEADER_HEIGHT + HEADER_GAP);
line = page_nr * data->lines_per_page;
for (i = 0; i < data->lines_per_page && line < data->num_lines; i++)
{
pango_layout_set_text (layout, data->lines[line], -1);
pango_cairo_show_layout (cr, layout);
pango2_layout_set_text (layout, data->lines[line], -1);
pango2_cairo_show_layout (cr, layout);
cairo_rel_move_to (cr, 0, data->font_size);
line++;
}

View File

@@ -1,9 +1,9 @@
/* Pango/Rotated Text
/* Pango2/Rotated Text
*
* This demo shows how to use PangoCairo to draw rotated and transformed
* This demo shows how to use Pango2Cairo to draw rotated and transformed
* text. The right pane shows a rotated GtkLabel widget.
*
* In both cases, a custom PangoCairo shape renderer is installed to draw
* In both cases, a custom Pango2Cairo shape renderer is installed to draw
* a red heart using cairo drawing operations instead of the Unicode heart
* character.
*/
@@ -14,75 +14,118 @@
#define HEART "♥"
const char text[] = "I ♥ GTK";
static void
fancy_shape_renderer (cairo_t *cr,
PangoAttrShape *attr,
gboolean do_path,
gpointer data)
static gboolean
glyph_cb (Pango2UserFace *face,
hb_codepoint_t unicode,
hb_codepoint_t *glyph,
gpointer data)
{
double x, y;
cairo_get_current_point (cr, &x, &y);
cairo_translate (cr, x, y);
cairo_scale (cr,
(double) attr->ink_rect.width / PANGO_SCALE,
(double) attr->ink_rect.height / PANGO_SCALE);
if (GPOINTER_TO_UINT (attr->data) == 0x2665) /* U+2665 BLACK HEART SUIT */
if (unicode == 0x2665)
{
*glyph = 0x2665;
return TRUE;
}
return FALSE;
}
static gboolean
glyph_info_cb (Pango2UserFace *face,
int size,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
hb_position_t *h_advance,
hb_position_t *v_advance,
gboolean *is_color,
gpointer user_data)
{
if (glyph == 0x2665)
{
extents->x_bearing = 0;
extents->y_bearing = size;
extents->width = size;
extents->height = - size;
*h_advance = size;
*v_advance = size;
*is_color = TRUE;
return TRUE;
}
return FALSE;
}
static gboolean
font_info_cb (Pango2UserFace *face,
int size,
hb_font_extents_t *extents,
gpointer user_data)
{
extents->ascender = size;
extents->descender = 0;
extents->line_gap = 0;
return TRUE;
}
static gboolean
render_cb (Pango2UserFace *face,
int size,
hb_codepoint_t glyph,
gpointer user_data,
const char *backend_id,
gpointer backend_data)
{
cairo_t *cr;
if (strcmp (backend_id, "cairo") != 0)
{
g_warning ("Unsupported Pango2Renderer backend %s", backend_id);
return FALSE;
}
cr = backend_data;
if (glyph == 0x2665)
{
cairo_set_source_rgb (cr, 1., 0., 0.);
cairo_move_to (cr, .5, .0);
cairo_line_to (cr, .9, -.4);
cairo_curve_to (cr, 1.1, -.8, .5, -.9, .5, -.5);
cairo_curve_to (cr, .5, -.9, -.1, -.8, .1, -.4);
cairo_close_path (cr);
cairo_fill (cr);
return TRUE;
}
if (!do_path)
{
cairo_set_source_rgb (cr, 1., 0., 0.);
cairo_fill (cr);
}
return FALSE;
}
static PangoAttrList *
create_fancy_attr_list_for_layout (PangoLayout *layout)
static void
setup_fontmap (void)
{
PangoAttrList *attrs;
PangoFontMetrics *metrics;
int ascent;
PangoRectangle ink_rect, logical_rect;
const char *p;
Pango2FontMap *fontmap = pango2_font_map_get_default ();
Pango2FontDescription *desc;
Pango2UserFace *face;
/* Get font metrics and prepare fancy shape size */
metrics = pango_context_get_metrics (pango_layout_get_context (layout),
pango_layout_get_font_description (layout),
NULL);
ascent = pango_font_metrics_get_ascent (metrics);
logical_rect.x = 0;
logical_rect.width = ascent;
logical_rect.y = -ascent;
logical_rect.height = ascent;
ink_rect = logical_rect;
pango_font_metrics_unref (metrics);
desc = pango2_font_description_new ();
pango2_font_description_set_family (desc, "Bullets");
/* Set fancy shape attributes for all hearts */
attrs = pango_attr_list_new ();
for (p = text; (p = strstr (p, HEART)); p += strlen (HEART))
{
PangoAttribute *attr;
/* Create our fancy user font, "Bullets Black" */
face = pango2_user_face_new (font_info_cb,
glyph_cb,
glyph_info_cb,
NULL,
render_cb,
NULL, NULL, "Black", desc);
attr = pango_attr_shape_new_with_data (&ink_rect,
&logical_rect,
GUINT_TO_POINTER (g_utf8_get_char (p)),
NULL, NULL);
/* And add it to the default fontmap */
pango2_font_map_add_face (fontmap, PANGO2_FONT_FACE (face));
attr->start_index = p - text;
attr->end_index = attr->start_index + strlen (HEART);
pango_attr_list_insert (attrs, attr);
}
return attrs;
pango2_font_description_free (desc);
}
static void
@@ -94,16 +137,12 @@ rotated_text_draw (GtkDrawingArea *da,
{
#define RADIUS 150
#define N_WORDS 5
#define FONT "Serif 18"
PangoContext *context;
PangoLayout *layout;
PangoFontDescription *desc;
#define FONT "Bullets 18"
Pango2Context *context;
Pango2Layout *layout;
Pango2FontDescription *desc;
cairo_pattern_t *pattern;
PangoAttrList *attrs;
double device_radius;
int i;
@@ -123,40 +162,34 @@ rotated_text_draw (GtkDrawingArea *da,
cairo_pattern_add_color_stop_rgb (pattern, 1., .0, .0, .5);
cairo_set_source (cr, pattern);
/* Create a PangoContext and set up our shape renderer */
/* Create a Pango2Context and set up our shape renderer */
context = gtk_widget_create_pango_context (GTK_WIDGET (da));
pango_cairo_context_set_shape_renderer (context,
fancy_shape_renderer,
NULL, NULL);
/* Create a PangoLayout, set the text, font, and attributes */
layout = pango_layout_new (context);
pango_layout_set_text (layout, text, -1);
desc = pango_font_description_from_string (FONT);
pango_layout_set_font_description (layout, desc);
attrs = create_fancy_attr_list_for_layout (layout);
pango_layout_set_attributes (layout, attrs);
pango_attr_list_unref (attrs);
/* Create a Pango2Layout, set the text, font, and attributes */
layout = pango2_layout_new (context);
pango2_layout_set_text (layout, text, -1);
desc = pango2_font_description_from_string (FONT);
pango2_layout_set_font_description (layout, desc);
/* Draw the layout N_WORDS times in a circle */
for (i = 0; i < N_WORDS; i++)
{
int layout_width, layout_height;
Pango2Rectangle ext;
/* Inform Pango to re-layout the text with the new transformation matrix */
pango_cairo_update_layout (cr, layout);
/* Inform Pango2 to re-layout the text with the new transformation matrix */
pango2_cairo_update_layout (cr, layout);
pango_layout_get_pixel_size (layout, &layout_width, &layout_height);
cairo_move_to (cr, - layout_width / 2, - RADIUS * .9);
pango_cairo_show_layout (cr, layout);
pango2_lines_get_extents (pango2_layout_get_lines (layout), NULL, &ext);
pango2_extents_to_pixels (&ext, NULL);
cairo_move_to (cr, - ext.width / 2, - RADIUS * .9);
pango2_cairo_show_layout (cr, layout);
/* Rotate for the next turn */
cairo_rotate (cr, G_PI*2 / N_WORDS);
}
/* free the objects we created */
pango_font_description_free (desc);
pango2_font_description_free (desc);
g_object_unref (layout);
g_object_unref (context);
cairo_pattern_destroy (pattern);
@@ -172,8 +205,10 @@ do_rotated_text (GtkWidget *do_widget)
GtkWidget *box;
GtkWidget *drawing_area;
GtkWidget *label;
PangoLayout *layout;
PangoAttrList *attrs;
Pango2Attribute *attr;
Pango2AttrList *attrs;
setup_fontmap ();
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
@@ -197,16 +232,12 @@ do_rotated_text (GtkWidget *do_widget)
/* And a label */
label = gtk_label_new (text);
gtk_box_append (GTK_BOX (box), label);
/* Set up fancy stuff on the label */
layout = gtk_label_get_layout (GTK_LABEL (label));
pango_cairo_context_set_shape_renderer (pango_layout_get_context (layout),
fancy_shape_renderer,
NULL, NULL);
attrs = create_fancy_attr_list_for_layout (layout);
attrs = pango2_attr_list_new ();
attr = pango2_attr_font_desc_new (pango2_font_description_from_string (FONT));
pango2_attr_list_insert (attrs, attr);
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs);
pango2_attr_list_unref (attrs);
gtk_box_append (GTK_BOX (box), label);
}
if (!gtk_widget_get_visible (window))

View File

@@ -21,7 +21,7 @@ do_tabs (GtkWidget *do_widget)
GtkWidget *view;
GtkWidget *sw;
GtkTextBuffer *buffer;
PangoTabArray *tabs;
Pango2TabArray *tabs;
window = gtk_window_new ();
gtk_window_set_title (GTK_WINDOW (window), "Tabs");
@@ -38,13 +38,13 @@ do_tabs (GtkWidget *do_widget)
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 20);
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view), 20);
tabs = pango_tab_array_new (3, TRUE);
pango_tab_array_set_tab (tabs, 0, PANGO_TAB_LEFT, 0);
pango_tab_array_set_tab (tabs, 1, PANGO_TAB_DECIMAL, 150);
pango_tab_array_set_decimal_point (tabs, 1, '.');
pango_tab_array_set_tab (tabs, 2, PANGO_TAB_RIGHT, 290);
tabs = pango2_tab_array_new (3, TRUE);
pango2_tab_array_set_tab (tabs, 0, PANGO2_TAB_LEFT, 0);
pango2_tab_array_set_tab (tabs, 1, PANGO2_TAB_DECIMAL, 150);
pango2_tab_array_set_decimal_point (tabs, 1, '.');
pango2_tab_array_set_tab (tabs, 2, PANGO2_TAB_RIGHT, 290);
gtk_text_view_set_tabs (GTK_TEXT_VIEW (view), tabs);
pango_tab_array_free (tabs);
pango2_tab_array_free (tabs);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
gtk_text_buffer_set_text (buffer, "one\t2.0\tthree\nfour\t5.555\tsix\nseven\t88.88\tnine", -1);

View File

@@ -1,6 +1,6 @@
/* Pango/Text Mask
*
* This demo shows how to use PangoCairo to draw text with more than
* This demo shows how to use Pango to draw text with more than
* just a single color.
*/
@@ -15,18 +15,18 @@ draw_text (GtkDrawingArea *da,
gpointer data)
{
cairo_pattern_t *pattern;
PangoLayout *layout;
PangoFontDescription *desc;
Pango2Layout *layout;
Pango2FontDescription *desc;
cairo_save (cr);
layout = gtk_widget_create_pango_layout (GTK_WIDGET (da), "Pango power!\nPango power!\nPango power!");
desc = pango_font_description_from_string ("sans bold 34");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
desc = pango2_font_description_from_string ("sans bold 34");
pango2_layout_set_font_description (layout, desc);
pango2_font_description_free (desc);
cairo_move_to (cr, 30, 20);
pango_cairo_layout_path (cr, layout);
pango2_cairo_layout_path (cr, layout);
g_object_unref (layout);
pattern = cairo_pattern_create_linear (0.0, 0.0, width, height);

View File

@@ -36,25 +36,25 @@ create_tags (GtkTextBuffer *buffer)
*/
gtk_text_buffer_create_tag (buffer, "heading",
"weight", PANGO_WEIGHT_BOLD,
"size", 15 * PANGO_SCALE,
"weight", PANGO2_WEIGHT_BOLD,
"size", 15 * PANGO2_SCALE,
NULL);
gtk_text_buffer_create_tag (buffer, "italic",
"style", PANGO_STYLE_ITALIC, NULL);
"style", PANGO2_STYLE_ITALIC, NULL);
gtk_text_buffer_create_tag (buffer, "bold",
"weight", PANGO_WEIGHT_BOLD, NULL);
"weight", PANGO2_WEIGHT_BOLD, NULL);
gtk_text_buffer_create_tag (buffer, "big",
/* points times the PANGO_SCALE factor */
"size", 20 * PANGO_SCALE, NULL);
/* points times the PANGO2_SCALE factor */
"size", 20 * PANGO2_SCALE, NULL);
gtk_text_buffer_create_tag (buffer, "xx-small",
"scale", PANGO_SCALE_XX_SMALL, NULL);
"scale", PANGO2_SCALE_XX_SMALL, NULL);
gtk_text_buffer_create_tag (buffer, "x-large",
"scale", PANGO_SCALE_X_LARGE, NULL);
"scale", PANGO2_SCALE_X_LARGE, NULL);
gtk_text_buffer_create_tag (buffer, "monospace",
"family", "monospace", NULL);
@@ -100,19 +100,19 @@ create_tags (GtkTextBuffer *buffer)
"strikethrough", TRUE, NULL);
gtk_text_buffer_create_tag (buffer, "underline",
"underline", PANGO_UNDERLINE_SINGLE, NULL);
"underline", PANGO2_LINE_STYLE_SOLID, NULL);
gtk_text_buffer_create_tag (buffer, "double_underline",
"underline", PANGO_UNDERLINE_DOUBLE, NULL);
"underline", PANGO2_LINE_STYLE_DOUBLE, NULL);
gtk_text_buffer_create_tag (buffer, "superscript",
"rise", 10 * PANGO_SCALE, /* 10 pixels */
"size", 8 * PANGO_SCALE, /* 8 points */
"rise", 10 * PANGO2_SCALE, /* 10 pixels */
"size", 8 * PANGO2_SCALE, /* 8 points */
NULL);
gtk_text_buffer_create_tag (buffer, "subscript",
"rise", -10 * PANGO_SCALE, /* 10 pixels */
"size", 8 * PANGO_SCALE, /* 8 points */
"rise", -10 * PANGO2_SCALE, /* 10 pixels */
"size", 8 * PANGO2_SCALE, /* 8 points */
NULL);
gtk_text_buffer_create_tag (buffer, "rtl_quote",

View File

@@ -70,8 +70,8 @@ about_activated (GSimpleAction *action,
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (s, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),

View File

@@ -22,3 +22,4 @@ subdir('icon-browser')
subdir('node-editor')
subdir('widget-factory')
subdir('print-editor')
subdir('font-explorer')

View File

@@ -77,8 +77,8 @@ activate_about (GSimpleAction *action,
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (s, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),

View File

@@ -365,13 +365,13 @@ static void
load_error (NodeEditorWindow *self,
const char *error_message)
{
PangoLayout *layout;
Pango2Layout *layout;
GtkSnapshot *snapshot;
GskRenderNode *node;
GBytes *bytes;
layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), error_message);
pango_layout_set_width (layout, 300 * PANGO_SCALE);
pango2_layout_set_width (layout, 300 * PANGO2_SCALE);
snapshot = gtk_snapshot_new ();
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA) { 0.7, 0.13, 0.13, 1.0 });
node = gtk_snapshot_free_to_node (snapshot);
@@ -1060,7 +1060,7 @@ node_editor_window_init (NodeEditorWindow *self)
gtk_text_tag_table_add (self->tag_table,
g_object_new (GTK_TYPE_TEXT_TAG,
"name", "error",
"underline", PANGO_UNDERLINE_ERROR,
"underline", PANGO2_LINE_STYLE_DOTTED,
NULL));
gtk_text_tag_table_add (self->tag_table,
g_object_new (GTK_TYPE_TEXT_TAG,

View File

@@ -1,6 +1,6 @@
#include <config.h>
#include <math.h>
#include <pango/pangocairo.h>
#include <pango2/pangocairo.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
@@ -200,7 +200,7 @@ save_file (GFile *save_filename)
typedef struct {
char *text;
PangoLayout *layout;
Pango2Layout *layout;
GList *page_breaks;
GtkWidget *font_button;
char *font;
@@ -211,39 +211,41 @@ begin_print (GtkPrintOperation *operation,
GtkPrintContext *context,
PrintData *print_data)
{
PangoFontDescription *desc;
PangoLayoutLine *layout_line;
Pango2FontDescription *desc;
Pango2Lines *lines;
Pango2Line *line;
double width, height;
double page_height;
GList *page_breaks;
int num_lines;
int line;
int i;
width = gtk_print_context_get_width (context);
height = gtk_print_context_get_height (context);
print_data->layout = gtk_print_context_create_pango_layout (context);
desc = pango_font_description_from_string (print_data->font);
pango_layout_set_font_description (print_data->layout, desc);
pango_font_description_free (desc);
desc = pango2_font_description_from_string (print_data->font);
pango2_layout_set_font_description (print_data->layout, desc);
pango2_font_description_free (desc);
pango_layout_set_width (print_data->layout, width * PANGO_SCALE);
pango2_layout_set_width (print_data->layout, width * PANGO2_SCALE);
pango_layout_set_text (print_data->layout, print_data->text, -1);
pango2_layout_set_text (print_data->layout, print_data->text, -1);
num_lines = pango_layout_get_line_count (print_data->layout);
lines = pango2_layout_get_lines (print_data->layout);
num_lines = pango2_lines_get_line_count (lines);
page_breaks = NULL;
page_height = 0;
for (line = 0; line < num_lines; line++)
for (i = 0; i < num_lines; i++)
{
PangoRectangle ink_rect, logical_rect;
Pango2Rectangle logical_rect;
double line_height;
layout_line = pango_layout_get_line (print_data->layout, line);
pango_layout_line_get_extents (layout_line, &ink_rect, &logical_rect);
line = pango2_lines_get_lines (lines)[i];
pango2_line_get_extents (line, NULL, &logical_rect);
line_height = logical_rect.height / 1024.0;
@@ -271,7 +273,7 @@ draw_page (GtkPrintOperation *operation,
cairo_t *cr;
GList *pagebreak;
int start, end, i;
PangoLayoutIter *iter;
Pango2LineIter *iter;
double start_pos;
if (page_nr == 0)
@@ -284,7 +286,7 @@ draw_page (GtkPrintOperation *operation,
pagebreak = g_list_nth (print_data->page_breaks, page_nr);
if (pagebreak == NULL)
end = pango_layout_get_line_count (print_data->layout);
end = pango2_lines_get_line_count (pango2_layout_get_lines (print_data->layout));
else
end = GPOINTER_TO_INT (pagebreak->data);
@@ -294,33 +296,33 @@ draw_page (GtkPrintOperation *operation,
i = 0;
start_pos = 0;
iter = pango_layout_get_iter (print_data->layout);
iter = pango2_layout_get_iter (print_data->layout);
do
{
PangoRectangle logical_rect;
PangoLayoutLine *line;
int baseline;
Pango2Rectangle logical_rect;
Pango2Line *line;
int baseline;
if (i >= start)
{
line = pango_layout_iter_get_line (iter);
line = pango2_line_iter_get_line (iter);
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango_layout_iter_get_baseline (iter);
pango2_line_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango2_line_iter_get_line_baseline (iter);
if (i == start)
start_pos = logical_rect.y / 1024.0;
cairo_move_to (cr, logical_rect.x / 1024.0, baseline / 1024.0 - start_pos);
pango_cairo_show_layout_line (cr, line);
pango2_cairo_show_line (cr, line);
}
i++;
}
while (i < end &&
pango_layout_iter_next_line (iter));
pango2_line_iter_next_line (iter));
pango_layout_iter_free (iter);
pango2_line_iter_free (iter);
}
static void
@@ -626,8 +628,8 @@ activate_about (GSimpleAction *action,
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (sysinfo, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (sysinfo, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (sysinfo, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),

View File

@@ -296,8 +296,8 @@ activate_about (GSimpleAction *action,
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (s, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),

View File

@@ -90,10 +90,10 @@ _gdk_broadway_display_get_keymap (GdkDisplay *display)
return broadway_display->keymap;
}
static PangoDirection
static Pango2Direction
gdk_broadway_keymap_get_direction (GdkKeymap *keymap)
{
return PANGO_DIRECTION_NEUTRAL;
return PANGO2_DIRECTION_NEUTRAL;
}
static gboolean

View File

@@ -28,8 +28,8 @@ gboolean gdk_should_use_portal (void);
const char * gdk_get_startup_notification_id (void);
PangoDirection gdk_unichar_direction (gunichar ch) G_GNUC_CONST;
PangoDirection gdk_find_base_dir (const char *text,
Pango2Direction gdk_unichar_direction (gunichar ch) G_GNUC_CONST;
Pango2Direction gdk_find_base_dir (const char *text,
int len);
typedef struct

View File

@@ -370,7 +370,7 @@ gdk_should_use_portal (void)
return FALSE;
}
PangoDirection
Pango2Direction
gdk_unichar_direction (gunichar ch)
{
FriBidiCharType fribidi_ch_type;
@@ -380,21 +380,21 @@ gdk_unichar_direction (gunichar ch)
fribidi_ch_type = fribidi_get_bidi_type (ch);
if (!FRIBIDI_IS_STRONG (fribidi_ch_type))
return PANGO_DIRECTION_NEUTRAL;
return PANGO2_DIRECTION_NEUTRAL;
else if (FRIBIDI_IS_RTL (fribidi_ch_type))
return PANGO_DIRECTION_RTL;
return PANGO2_DIRECTION_RTL;
else
return PANGO_DIRECTION_LTR;
return PANGO2_DIRECTION_LTR;
}
PangoDirection
Pango2Direction
gdk_find_base_dir (const char *text,
int length)
{
PangoDirection dir = PANGO_DIRECTION_NEUTRAL;
Pango2Direction dir = PANGO2_DIRECTION_NEUTRAL;
const char *p;
g_return_val_if_fail (text != NULL || length == 0, PANGO_DIRECTION_NEUTRAL);
g_return_val_if_fail (text != NULL || length == 0, PANGO2_DIRECTION_NEUTRAL);
p = text;
while ((length < 0 || p < text + length) && *p)
@@ -403,7 +403,7 @@ gdk_find_base_dir (const char *text,
dir = gdk_unichar_direction (wc);
if (dir != PANGO_DIRECTION_NEUTRAL)
if (dir != PANGO2_DIRECTION_NEUTRAL)
break;
p = g_utf8_next_char (p);

View File

@@ -25,7 +25,7 @@
#include <gdk/gdkversionmacros.h>
#include <gdk/gdkrgba.h>
#include <gdk/gdkpixbuf.h>
#include <pango/pangocairo.h>
#include <pango2/pangocairo.h>
G_BEGIN_DECLS

View File

@@ -229,7 +229,7 @@ gdk_device_class_init (GdkDeviceClass *klass)
*/
device_props[PROP_DIRECTION] =
g_param_spec_enum ("direction", NULL, NULL,
PANGO_TYPE_DIRECTION, PANGO_DIRECTION_NEUTRAL,
PANGO2_TYPE_DIRECTION, PANGO2_DIRECTION_NEUTRAL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
/**
@@ -1309,13 +1309,13 @@ gdk_device_get_modifier_state (GdkDevice *device)
* This is only relevant for keyboard devices.
*
* The direction of a layout is the direction of the majority
* of its symbols. See [func@Pango.unichar_direction].
* of its symbols. See [func@Pango2.unichar_direction].
*
* Returns: %PANGO_DIRECTION_LTR or %PANGO_DIRECTION_RTL
* if it can determine the direction. %PANGO_DIRECTION_NEUTRAL
* otherwise
*/
PangoDirection
Pango2Direction
gdk_device_get_direction (GdkDevice *device)
{
GdkKeymap *keymap = gdk_display_get_keymap (device->display);
@@ -1323,7 +1323,7 @@ gdk_device_get_direction (GdkDevice *device)
if (device->source == GDK_SOURCE_KEYBOARD)
return gdk_keymap_get_direction (keymap);
return PANGO_DIRECTION_NEUTRAL;
return PANGO2_DIRECTION_NEUTRAL;
}
/**

View File

@@ -109,7 +109,7 @@ guint gdk_device_get_num_touches (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
GdkModifierType gdk_device_get_modifier_state (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
PangoDirection gdk_device_get_direction (GdkDevice *device);
Pango2Direction gdk_device_get_direction (GdkDevice *device);
GDK_AVAILABLE_IN_ALL
gboolean gdk_device_has_bidi_layouts (GdkDevice *device);
GDK_AVAILABLE_IN_ALL

View File

@@ -309,14 +309,14 @@ gdk_keyval_is_lower (guint keyval)
* The direction of a layout is the direction of the majority of its
* symbols. See pango_unichar_direction().
*
* Returns: %PANGO_DIRECTION_LTR or %PANGO_DIRECTION_RTL
* if it can determine the direction. %PANGO_DIRECTION_NEUTRAL
* Returns: %PANGO2_DIRECTION_LTR or %PANGO2_DIRECTION_RTL
* if it can determine the direction. %PANGO2_DIRECTION_NEUTRAL
* otherwise.
*/
PangoDirection
Pango2Direction
gdk_keymap_get_direction (GdkKeymap *keymap)
{
g_return_val_if_fail (GDK_IS_KEYMAP (keymap), PANGO_DIRECTION_LTR);
g_return_val_if_fail (GDK_IS_KEYMAP (keymap), PANGO2_DIRECTION_LTR);
return GDK_KEYMAP_GET_CLASS (keymap)->get_direction (keymap);
}

View File

@@ -38,7 +38,7 @@ struct _GdkKeymapClass
{
GObjectClass parent_class;
PangoDirection (* get_direction) (GdkKeymap *keymap);
Pango2Direction (* get_direction) (GdkKeymap *keymap);
gboolean (* have_bidi_layouts) (GdkKeymap *keymap);
gboolean (* get_caps_lock_state) (GdkKeymap *keymap);
gboolean (* get_num_lock_state) (GdkKeymap *keymap);
@@ -111,7 +111,7 @@ gboolean gdk_keymap_get_entries_for_keycode (GdkKeymap *keymap,
guint **keyvals,
int *n_entries);
PangoDirection gdk_keymap_get_direction (GdkKeymap *keymap);
Pango2Direction gdk_keymap_get_direction (GdkKeymap *keymap);
gboolean gdk_keymap_have_bidi_layouts (GdkKeymap *keymap);
gboolean gdk_keymap_get_caps_lock_state (GdkKeymap *keymap);
gboolean gdk_keymap_get_num_lock_state (GdkKeymap *keymap);

View File

@@ -22,7 +22,7 @@
#include "gdkintl.h"
#include <math.h>
#include <pango/pangocairo.h>
#include <pango2/pangocairo.h>
/* Get a clip region to draw only part of a layout. index_ranges
@@ -30,25 +30,29 @@
* region which contains the given ranges, i.e. if you draw with the
* region as clip, only the given ranges are drawn.
*/
static cairo_region_t*
layout_iter_get_line_clip_region (PangoLayoutIter *iter,
int x_origin,
int y_origin,
const int *index_ranges,
int n_ranges)
static cairo_region_t *
layout_iter_get_line_clip_region (Pango2LineIter *iter,
int x_origin,
int y_origin,
const int *index_ranges,
int n_ranges)
{
PangoLayoutLine *line;
Pango2Lines *lines;
Pango2Line *line;
cairo_region_t *clip_region;
PangoRectangle logical_rect;
Pango2Rectangle logical_rect;
int baseline;
int i;
int start_index, length;
line = pango_layout_iter_get_line_readonly (iter);
lines = pango2_line_iter_get_lines (iter);
line = pango2_line_iter_get_line (iter);
pango2_line_get_text (line, &start_index, &length);
clip_region = cairo_region_create ();
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango_layout_iter_get_baseline (iter);
pango2_line_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango2_line_iter_get_line_baseline (iter);
i = 0;
while (i < n_ranges)
@@ -57,27 +61,27 @@ layout_iter_get_line_clip_region (PangoLayoutIter *iter,
int n_pixel_ranges = 0;
int j;
/* Note that get_x_ranges returns layout coordinates
*/
if (index_ranges[i*2+1] >= pango_layout_line_get_start_index (line) &&
index_ranges[i*2] < pango_layout_line_get_start_index (line) + pango_layout_line_get_length (line))
pango_layout_line_get_x_ranges (line,
index_ranges[i*2],
index_ranges[i*2+1],
&pixel_ranges, &n_pixel_ranges);
/* Note that get_x_ranges returns layout coordinates */
if (index_ranges[i*2+1] >= pango2_line_get_start_index (line) &&
index_ranges[i*2] < pango2_line_get_start_index (line) + pango2_line_get_length (line))
pango2_lines_get_x_ranges (lines,
line,
NULL, index_ranges[i*2],
NULL, index_ranges[i*2+1],
&pixel_ranges, &n_pixel_ranges);
for (j = 0; j < n_pixel_ranges; j++)
{
GdkRectangle rect;
int x_off, y_off;
int x_off, y_off;
x_off = PANGO_PIXELS (pixel_ranges[2*j] - logical_rect.x);
y_off = PANGO_PIXELS (baseline - logical_rect.y);
x_off = PANGO2_PIXELS (pixel_ranges[2*j] - logical_rect.x);
y_off = PANGO2_PIXELS (baseline - logical_rect.y);
rect.x = x_origin + x_off;
rect.y = y_origin - y_off;
rect.width = PANGO_PIXELS (pixel_ranges[2*j + 1] - logical_rect.x) - x_off;
rect.height = PANGO_PIXELS (baseline - logical_rect.y + logical_rect.height) - y_off;
rect.width = PANGO2_PIXELS (pixel_ranges[2*j + 1] - logical_rect.x) - x_off;
rect.height = PANGO2_PIXELS (baseline - logical_rect.y + logical_rect.height) - y_off;
cairo_region_union_rectangle (clip_region, &rect);
}
@@ -89,59 +93,8 @@ layout_iter_get_line_clip_region (PangoLayoutIter *iter,
}
/**
* gdk_pango_layout_line_get_clip_region: (skip)
* @line: a `PangoLayoutLine`
* @x_origin: X pixel where you intend to draw the layout line with this clip
* @y_origin: baseline pixel where you intend to draw the layout line with this clip
* @index_ranges: (array): array of byte indexes into the layout, where even
* members of array are start indexes and odd elements are end indexes
* @n_ranges: number of ranges in @index_ranges, i.e. half the size of @index_ranges
*
* Obtains a clip region which contains the areas where the given
* ranges of text would be drawn.
*
* @x_origin and @y_origin are the top left position of the layout.
* @index_ranges should contain ranges of bytes in the layouts text.
* The clip region will include space to the left or right of the line
* (to the layout bounding box) if you have indexes above or below the
* indexes contained inside the line. This is to draw the selection all
* the way to the side of the layout. However, the clip region is in line
* coordinates, not layout coordinates.
*
* Note that the regions returned correspond to logical extents of the text
* ranges, not ink extents. So the drawn line may in fact touch areas out of
* the clip region. The clip region is mainly useful for highlightling parts
* of text, such as when text is selected.
*
* Returns: a clip region containing the given ranges
*/
cairo_region_t*
gdk_pango_layout_line_get_clip_region (PangoLayoutLine *line,
int x_origin,
int y_origin,
const int *index_ranges,
int n_ranges)
{
cairo_region_t *clip_region;
PangoLayoutIter *iter;
g_return_val_if_fail (line != NULL, NULL);
g_return_val_if_fail (index_ranges != NULL, NULL);
iter = pango_layout_get_iter (line->layout);
while (pango_layout_iter_get_line_readonly (iter) != line)
pango_layout_iter_next_line (iter);
clip_region = layout_iter_get_line_clip_region(iter, x_origin, y_origin, index_ranges, n_ranges);
pango_layout_iter_free (iter);
return clip_region;
}
/**
* gdk_pango_layout_get_clip_region: (skip)
* @layout: a `PangoLayout`
* gdk_pango2_layout_get_clip_region: (skip)
* @layout: a `Pango2Layout`
* @x_origin: X pixel where you intend to draw the layout with this clip
* @y_origin: Y pixel where you intend to draw the layout with this clip
* @index_ranges: array of byte indexes into the layout, where even members of array are start indexes and odd elements are end indexes
@@ -160,44 +113,44 @@ gdk_pango_layout_line_get_clip_region (PangoLayoutLine *line,
*
* Returns: a clip region containing the given ranges
*/
cairo_region_t*
gdk_pango_layout_get_clip_region (PangoLayout *layout,
cairo_region_t *
gdk_pango_layout_get_clip_region (Pango2Layout *layout,
int x_origin,
int y_origin,
const int *index_ranges,
int n_ranges)
{
PangoLayoutIter *iter;
Pango2LineIter *iter;
cairo_region_t *clip_region;
g_return_val_if_fail (PANGO_IS_LAYOUT (layout), NULL);
g_return_val_if_fail (PANGO2_IS_LAYOUT (layout), NULL);
g_return_val_if_fail (index_ranges != NULL, NULL);
clip_region = cairo_region_create ();
iter = pango_layout_get_iter (layout);
iter = pango2_layout_get_iter (layout);
do
{
PangoRectangle logical_rect;
Pango2Rectangle logical_rect;
cairo_region_t *line_region;
int baseline;
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango_layout_iter_get_baseline (iter);
pango2_line_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango2_line_iter_get_line_baseline (iter);
line_region = layout_iter_get_line_clip_region(iter,
x_origin + PANGO_PIXELS (logical_rect.x),
y_origin + PANGO_PIXELS (baseline),
index_ranges,
n_ranges);
line_region = layout_iter_get_line_clip_region (iter,
x_origin + PANGO2_PIXELS (logical_rect.x),
y_origin + PANGO2_PIXELS (baseline),
index_ranges,
n_ranges);
cairo_region_union (clip_region, line_region);
cairo_region_destroy (line_region);
}
while (pango_layout_iter_next_line (iter));
while (pango2_line_iter_next_line (iter));
pango_layout_iter_free (iter);
pango2_line_iter_free (iter);
return clip_region;
}

View File

@@ -1,5 +1,5 @@
/* GDK - The GIMP Drawing Kit
* Copyright (C) 2000 Red Hat, Inc.
* Copyright (C) 2000 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
@@ -27,24 +27,12 @@
G_BEGIN_DECLS
/* Get a clip region to draw only part of a layout or
* line. index_ranges contains alternating range starts/stops. The
* region is the region which contains the given ranges, i.e. if you
* draw with the region as clip, only the given ranges are drawn.
*/
GDK_AVAILABLE_IN_ALL
cairo_region_t *gdk_pango_layout_line_get_clip_region (PangoLayoutLine *line,
int x_origin,
int y_origin,
const int *index_ranges,
int n_ranges);
GDK_AVAILABLE_IN_ALL
cairo_region_t *gdk_pango_layout_get_clip_region (PangoLayout *layout,
int x_origin,
int y_origin,
const int *index_ranges,
int n_ranges);
cairo_region_t *gdk_pango_layout_get_clip_region (Pango2Layout *layout,
int x_origin,
int y_origin,
const int *index_ranges,
int n_ranges);
G_END_DECLS

View File

@@ -223,20 +223,19 @@ gdk_rgba_parse (GdkRGBA *rgba,
}
else
{
PangoColor pango_color;
guint16 alpha;
Pango2Color pango_color;
/* Resort on PangoColor for rgb.txt color
/* Resort on Pango2Color for rgb.txt color
* map and '#' prefixed colors
*/
if (pango_color_parse_with_alpha (&pango_color, &alpha, str))
if (pango2_color_parse (&pango_color, str))
{
if (rgba)
{
rgba->red = pango_color.red / 65535.;
rgba->green = pango_color.green / 65535.;
rgba->blue = pango_color.blue / 65535.;
rgba->alpha = alpha / 65535.;
rgba->alpha = pango_color.alpha / 65535.;
}
return TRUE;

View File

@@ -35,7 +35,7 @@
#include <glib-object.h>
#include <gio/gio.h>
#include <cairo.h>
#include <pango/pango.h>
#include <pango2/pango.h>
/* The system specific file gdkconfig.h contains such configuration
* settings that are needed not only when compiling GDK (or GTK)

View File

@@ -380,7 +380,7 @@ gdk_macos_keymap_update (GdkMacosKeymap *self)
g_signal_emit_by_name (self, "keys-changed");
}
static PangoDirection
static Pango2Direction
gdk_macos_keymap_get_direction (GdkKeymap *keymap)
{
return PANGO_DIRECTION_NEUTRAL;

View File

@@ -1925,7 +1925,7 @@ keyboard_handle_keymap (void *data,
uint32_t size)
{
GdkWaylandSeat *seat = data;
PangoDirection direction;
Pango2Direction direction;
gboolean bidi;
gboolean caps_lock;
gboolean num_lock;
@@ -2297,7 +2297,7 @@ keyboard_handle_modifiers (void *data,
GdkWaylandSeat *seat = data;
GdkKeymap *keymap;
struct xkb_state *xkb_state;
PangoDirection direction;
Pango2Direction direction;
gboolean bidi;
gboolean caps_lock;
gboolean num_lock;

View File

@@ -51,7 +51,7 @@ struct _GdkWaylandKeymap
struct xkb_keymap *xkb_keymap;
struct xkb_state *xkb_state;
PangoDirection *direction;
Pango2Direction *direction;
gboolean bidi;
};
@@ -80,7 +80,7 @@ gdk_wayland_keymap_finalize (GObject *object)
G_OBJECT_CLASS (_gdk_wayland_keymap_parent_class)->finalize (object);
}
static PangoDirection
static Pango2Direction
gdk_wayland_keymap_get_direction (GdkKeymap *keymap)
{
GdkWaylandKeymap *keymap_wayland = GDK_WAYLAND_KEYMAP (keymap);
@@ -92,7 +92,7 @@ gdk_wayland_keymap_get_direction (GdkKeymap *keymap)
return keymap_wayland->direction[i];
}
return PANGO_DIRECTION_NEUTRAL;
return PANGO2_DIRECTION_NEUTRAL;
}
static gboolean
@@ -399,7 +399,7 @@ update_direction (GdkWaylandKeymap *keymap)
num_layouts = xkb_keymap_num_layouts (keymap->xkb_keymap);
keymap->direction = g_renew (PangoDirection, keymap->direction, num_layouts);
keymap->direction = g_renew (Pango2Direction, keymap->direction, num_layouts);
rtl = g_newa (int, num_layouts);
for (i = 0; i < num_layouts; i++)
rtl[i] = 0;
@@ -421,22 +421,20 @@ update_direction (GdkWaylandKeymap *keymap)
num_syms = xkb_keymap_key_get_syms_by_level (keymap->xkb_keymap, key, layout, 0, &syms);
for (sym = 0; sym < num_syms; sym++)
{
PangoDirection dir;
Pango2Direction dir;
dir = gdk_unichar_direction (xkb_keysym_to_utf32 (syms[sym]));
switch (dir)
{
case PANGO_DIRECTION_RTL:
case PANGO2_DIRECTION_RTL:
rtl[layout]++;
break;
case PANGO_DIRECTION_LTR:
case PANGO2_DIRECTION_LTR:
rtl[layout]--;
break;
case PANGO_DIRECTION_TTB_LTR:
case PANGO_DIRECTION_TTB_RTL:
case PANGO_DIRECTION_WEAK_LTR:
case PANGO_DIRECTION_WEAK_RTL:
case PANGO_DIRECTION_NEUTRAL:
case PANGO2_DIRECTION_WEAK_LTR:
case PANGO2_DIRECTION_WEAK_RTL:
case PANGO2_DIRECTION_NEUTRAL:
default:
break;
}
@@ -449,12 +447,12 @@ update_direction (GdkWaylandKeymap *keymap)
{
if (rtl[i] > 0)
{
keymap->direction[i] = PANGO_DIRECTION_RTL;
keymap->direction[i] = PANGO2_DIRECTION_RTL;
have_rtl = TRUE;
}
else
{
keymap->direction[i] = PANGO_DIRECTION_LTR;
keymap->direction[i] = PANGO2_DIRECTION_LTR;
have_ltr = TRUE;
}
}

View File

@@ -720,7 +720,7 @@ _gdk_win32_keymap_get_mod_mask (GdkWin32Keymap *keymap)
return mod_bits_to_gdk_mod_mask (mod_bits);
}
static PangoDirection
static Pango2Direction
get_hkl_direction (HKL hkl)
{
switch (PRIMARYLANGID (LOWORD ((DWORD) (gintptr) hkl)))
@@ -732,20 +732,20 @@ get_hkl_direction (HKL hkl)
#endif
case LANG_FARSI:
/* Others? */
return PANGO_DIRECTION_RTL;
return PANGO2_DIRECTION_RTL;
default:
return PANGO_DIRECTION_LTR;
return PANGO2_DIRECTION_LTR;
}
}
static PangoDirection
static Pango2Direction
gdk_win32_keymap_get_direction (GdkKeymap *gdk_keymap)
{
GdkWin32Keymap *keymap;
HKL active_hkl;
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), PANGO_DIRECTION_LTR);
g_return_val_if_fail (GDK_IS_KEYMAP (gdk_keymap), PANGO2_DIRECTION_LTR);
keymap = GDK_WIN32_KEYMAP (gdk_keymap);
@@ -777,7 +777,7 @@ gdk_win32_keymap_have_bidi_layouts (GdkKeymap *gdk_keymap)
for (group = 0; group < keymap->layout_handles->len; group++)
{
if (get_hkl_direction (g_array_index (keymap->layout_handles, HKL,
group)) == PANGO_DIRECTION_RTL)
group)) == PANGO2_DIRECTION_RTL)
have_rtl = TRUE;
else
have_ltr = TRUE;

View File

@@ -27,7 +27,7 @@
#include <string.h>
#include <stdlib.h>
#include <glib/gprintf.h>
#include <pango/pangowin32.h>
#include <pango2/pangodwrite-fontmap.h>
#include "gdkdisplayprivate.h"
#include "gdkprivate-win32.h"
@@ -37,7 +37,7 @@ static char *
_get_system_font_name (HDC hdc)
{
NONCLIENTMETRICSW ncm;
PangoFontDescription *font_desc;
Pango2FontDescription *font_desc;
char *result, *font_desc_string;
int logpixelsy;
int font_size;
@@ -47,9 +47,9 @@ _get_system_font_name (HDC hdc)
return NULL;
logpixelsy = GetDeviceCaps (hdc, LOGPIXELSY);
font_desc = pango_win32_font_description_from_logfontw (&ncm.lfMessageFont);
font_desc_string = pango_font_description_to_string (font_desc);
pango_font_description_free (font_desc);
font_desc = pango2_direct_write_get_font_description_from_logfontw (&ncm.lfMessageFont, NULL);
font_desc_string = pango2_font_description_to_string (font_desc);
pango2_font_description_free (font_desc);
/* https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/ns-wingdi-taglogfonta */
font_size = -MulDiv (ncm.lfMessageFont.lfHeight, 72, logpixelsy);
@@ -192,15 +192,6 @@ _gdk_win32_get_setting (const char *name,
if (font_name)
{
/* The pango font fallback list got fixed during 1.43, before that
* using anything but "Segoe UI" would lead to a poor glyph coverage */
if (pango_version_check (1, 43, 0) != NULL &&
g_ascii_strncasecmp (font_name, "Segoe UI", strlen ("Segoe UI")) != 0)
{
g_free (font_name);
return FALSE;
}
GDK_NOTE(MISC, g_print("gdk_screen_get_setting(\"%s\") : %s\n", name, font_name));
g_value_take_string (value, font_name);
return TRUE;

View File

@@ -54,7 +54,6 @@ if have_egl
endif
gdk_win32_deps = [
pangowin32_dep, # FIXME
cc.find_library('hid'),
]

View File

@@ -55,7 +55,7 @@ typedef struct _DirectionCacheEntry DirectionCacheEntry;
struct _DirectionCacheEntry
{
guint serial;
PangoDirection direction;
Pango2Direction direction;
Atom group_atom;
};
@@ -73,7 +73,7 @@ struct _GdkX11Keymap
GdkModifierType num_lock_mask;
GdkModifierType scroll_lock_mask;
GdkModifierType modmap[8];
PangoDirection current_direction;
Pango2Direction current_direction;
guint have_direction : 1;
guint have_lock_state : 1;
guint caps_lock_state : 1;
@@ -470,7 +470,7 @@ get_keymap (GdkX11Keymap *keymap_x11)
}
#ifdef HAVE_XKB
static PangoDirection
static Pango2Direction
get_direction (XkbDescRec *xkb,
int group)
{
@@ -482,33 +482,31 @@ get_direction (XkbDescRec *xkb,
{
int level = 0;
KeySym sym = XkbKeySymEntry (xkb, code, level, group);
PangoDirection dir = gdk_unichar_direction (gdk_keyval_to_unicode (sym));
Pango2Direction dir = gdk_unichar_direction (gdk_keyval_to_unicode (sym));
switch (dir)
{
case PANGO_DIRECTION_RTL:
case PANGO2_DIRECTION_RTL:
rtl_minus_ltr++;
break;
case PANGO_DIRECTION_LTR:
case PANGO2_DIRECTION_LTR:
rtl_minus_ltr--;
break;
case PANGO_DIRECTION_TTB_LTR:
case PANGO_DIRECTION_TTB_RTL:
case PANGO_DIRECTION_WEAK_LTR:
case PANGO_DIRECTION_WEAK_RTL:
case PANGO_DIRECTION_NEUTRAL:
case PANGO2_DIRECTION_WEAK_LTR:
case PANGO2_DIRECTION_WEAK_RTL:
case PANGO2_DIRECTION_NEUTRAL:
default:
break;
}
}
if (rtl_minus_ltr > 0)
return PANGO_DIRECTION_RTL;
return PANGO2_DIRECTION_RTL;
else
return PANGO_DIRECTION_LTR;
return PANGO2_DIRECTION_LTR;
}
static PangoDirection
static Pango2Direction
get_direction_from_cache (GdkX11Keymap *keymap_x11,
XkbDescPtr xkb,
int group)
@@ -518,7 +516,7 @@ get_direction_from_cache (GdkX11Keymap *keymap_x11,
gboolean cache_hit = FALSE;
DirectionCacheEntry *cache = keymap_x11->group_direction_cache;
PangoDirection direction = PANGO_DIRECTION_NEUTRAL;
Pango2Direction direction = PANGO2_DIRECTION_NEUTRAL;
int i;
if (keymap_x11->have_direction)
@@ -588,7 +586,7 @@ update_direction (GdkX11Keymap *keymap_x11,
XkbDescPtr xkb = get_xkb (keymap_x11);
Atom group_atom;
gboolean had_direction;
PangoDirection old_direction;
Pango2Direction old_direction;
had_direction = keymap_x11->have_direction;
old_direction = keymap_x11->current_direction;
@@ -721,7 +719,7 @@ _gdk_x11_keymap_keys_changed (GdkDisplay *display)
g_signal_emit_by_name (display_x11->keymap, "keys_changed", 0);
}
static PangoDirection
static Pango2Direction
gdk_x11_keymap_get_direction (GdkKeymap *keymap)
{
#ifdef HAVE_XKB
@@ -746,7 +744,7 @@ gdk_x11_keymap_get_direction (GdkKeymap *keymap)
}
else
#endif /* HAVE_XKB */
return PANGO_DIRECTION_NEUTRAL;
return PANGO2_DIRECTION_NEUTRAL;
}
static gboolean
@@ -765,7 +763,7 @@ gdk_x11_keymap_have_bidi_layouts (GdkKeymap *keymap)
for (i = 0; i < num_groups; i++)
{
if (get_direction_from_cache (keymap_x11, xkb, i) == PANGO_DIRECTION_RTL)
if (get_direction_from_cache (keymap_x11, xkb, i) == PANGO2_DIRECTION_RTL)
have_rtl_keyboard = TRUE;
else
have_ltr_keyboard = TRUE;

View File

@@ -188,7 +188,7 @@ init_xft_settings (GdkX11Screen *x11_screen)
if (!get_double_default (x11_screen, "dpi", &dpi_double))
dpi_double = 96.0;
x11_screen->xft_dpi = (int)(0.5 + PANGO_SCALE * dpi_double);
x11_screen->xft_dpi = (int)(0.5 + PANGO2_SCALE * dpi_double);
}
gboolean

View File

@@ -55,6 +55,7 @@ gsk_gl_glyph_key_hash (gconstpointer data)
*/
return GPOINTER_TO_UINT (key->font) ^
key->palette ^
key->glyph ^
(key->xshift << 24) ^
(key->yshift << 26) ^
@@ -215,8 +216,8 @@ render_glyph (cairo_surface_t *surface,
const GskGLGlyphValue *value)
{
cairo_t *cr;
PangoGlyphString glyph_string;
PangoGlyphInfo glyph_info;
Pango2GlyphString glyph_string;
Pango2GlyphInfo glyph_info;
g_assert (surface != NULL);
@@ -231,7 +232,7 @@ render_glyph (cairo_surface_t *surface,
glyph_string.num_glyphs = 1;
glyph_string.glyphs = &glyph_info;
pango_cairo_show_glyph_string (cr, key->font, &glyph_string);
pango2_cairo_show_color_glyph_string (cr, key->font, key->palette, &glyph_string);
cairo_destroy (cr);
cairo_surface_flush (surface);
@@ -323,7 +324,7 @@ gsk_gl_glyph_library_add (GskGLGlyphLibrary *self,
const GskGLGlyphValue **out_value)
{
GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self;
PangoRectangle ink_rect;
Pango2Rectangle ink_rect;
GskGLGlyphValue *value;
int width;
int height;
@@ -334,8 +335,8 @@ gsk_gl_glyph_library_add (GskGLGlyphLibrary *self,
g_assert (key != NULL);
g_assert (out_value != NULL);
pango_font_get_glyph_extents (key->font, key->glyph, &ink_rect, NULL);
pango_extents_to_pixels (&ink_rect, NULL);
pango2_font_get_glyph_extents (key->font, key->glyph, &ink_rect, NULL);
pango2_extents_to_pixels (&ink_rect, NULL);
ink_rect.x -= 1;
ink_rect.width += 2;

View File

@@ -21,7 +21,7 @@
#ifndef __GSK_GL_GLYPH_LIBRARY_PRIVATE_H__
#define __GSK_GL_GLYPH_LIBRARY_PRIVATE_H__
#include <pango/pango.h>
#include <pango2/pango.h>
#include "gskgltexturelibraryprivate.h"
@@ -31,8 +31,9 @@ G_BEGIN_DECLS
typedef struct _GskGLGlyphKey
{
PangoFont *font;
PangoGlyph glyph;
Pango2Font *font;
GQuark palette;
Pango2Glyph glyph;
guint xshift : 2;
guint yshift : 2;
guint scale : 28; /* times 1024 */
@@ -41,13 +42,13 @@ typedef struct _GskGLGlyphKey
typedef struct _GskGLGlyphValue
{
GskGLTextureAtlasEntry entry;
PangoRectangle ink_rect;
Pango2Rectangle ink_rect;
} GskGLGlyphValue;
#if GLIB_SIZEOF_VOID_P == 8
G_STATIC_ASSERT (sizeof (GskGLGlyphKey) == 16);
G_STATIC_ASSERT (sizeof (GskGLGlyphKey) == 24);
#elif GLIB_SIZEOF_VOID_P == 4
G_STATIC_ASSERT (sizeof (GskGLGlyphKey) == 12);
G_STATIC_ASSERT (sizeof (GskGLGlyphKey) == 16);
#endif
G_DECLARE_FINAL_TYPE (GskGLGlyphLibrary, gsk_gl_glyph_library, GSK, GL_GLYPH_LIBRARY, GskGLTextureLibrary)

View File

@@ -21,7 +21,7 @@
#ifndef __GSK_GL_ICON_LIBRARY_PRIVATE_H__
#define __GSK_GL_ICON_LIBRARY_PRIVATE_H__
#include <pango/pango.h>
#include <pango2/pango.h>
#include "gskgltexturelibraryprivate.h"

View File

@@ -2935,8 +2935,9 @@ gsk_gl_render_job_visit_text_node (GskGLRenderJob *job,
const GdkRGBA *color,
gboolean force_color)
{
const PangoFont *font = gsk_text_node_get_font (node);
const PangoGlyphInfo *glyphs = gsk_text_node_get_glyphs (node, NULL);
const Pango2Font *font = gsk_text_node_get_font (node);
GQuark palette = gsk_text_node_get_palette (node);
const Pango2GlyphInfo *glyphs = gsk_text_node_get_glyphs (node, NULL);
const graphene_point_t *offset = gsk_text_node_get_offset (node);
float text_scale = MAX (job->scale_x, job->scale_y); /* TODO: Fix for uneven scales? */
guint num_glyphs = gsk_text_node_get_num_glyphs (node);
@@ -2952,7 +2953,7 @@ gsk_gl_render_job_visit_text_node (GskGLRenderJob *job,
guint16 nc[4] = { FP16_MINUS_ONE, FP16_MINUS_ONE, FP16_MINUS_ONE, FP16_MINUS_ONE };
guint16 cc[4];
const guint16 *c;
const PangoGlyphInfo *gi;
const Pango2GlyphInfo *gi;
guint i;
int yshift;
float ypos;
@@ -2966,7 +2967,8 @@ gsk_gl_render_job_visit_text_node (GskGLRenderJob *job,
rgba_to_half (color, cc);
lookup.font = (PangoFont *)font;
lookup.font = (Pango2Font *)font;
lookup.palette = palette;
lookup.scale = (guint) (text_scale * 1024);
yshift = compute_phase_and_pos (y, &ypos);
@@ -2996,12 +2998,12 @@ gsk_gl_render_job_visit_text_node (GskGLRenderJob *job,
else
c = cc;
cx = (float)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
cx = (float)(x_position + gi->geometry.x_offset) / PANGO2_SCALE;
lookup.xshift = compute_phase_and_pos (x + cx, &cx);
if G_UNLIKELY (gi->geometry.y_offset != 0)
{
cy = (float)(gi->geometry.y_offset) / PANGO_SCALE;
cy = (float)(gi->geometry.y_offset) / PANGO2_SCALE;
lookup.yshift = compute_phase_and_pos (y + cy, &cy);
}
else

View File

@@ -17,17 +17,17 @@ gsk_ensure_resources (void)
}
int
pango_glyph_string_num_glyphs (PangoGlyphString *glyphs)
pango_glyph_string_num_glyphs (Pango2GlyphString *glyphs)
{
int i, count;
count = 0;
for (i = 0; i < glyphs->num_glyphs; i++)
{
PangoGlyphInfo *gi = &glyphs->glyphs[i];
if (gi->glyph != PANGO_GLYPH_EMPTY)
Pango2GlyphInfo *gi = &glyphs->glyphs[i];
if (gi->glyph != PANGO2_GLYPH_EMPTY)
{
if (!(gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG))
if (!(gi->glyph & PANGO2_GLYPH_UNKNOWN_FLAG))
count++;
}
}

View File

@@ -2,13 +2,13 @@
#define __GSK_PRIVATE_H__
#include <glib.h>
#include <pango/pango.h>
#include <pango2/pango.h>
G_BEGIN_DECLS
void gsk_ensure_resources (void);
int pango_glyph_string_num_glyphs (PangoGlyphString *glyphs) G_GNUC_PURE;
int pango_glyph_string_num_glyphs (Pango2GlyphString *glyphs) G_GNUC_PURE;
typedef struct _GskVulkanRender GskVulkanRender;
typedef struct _GskVulkanRenderPass GskVulkanRenderPass;

View File

@@ -488,20 +488,23 @@ float gsk_cross_fade_node_get_progress (const GskRender
GDK_AVAILABLE_IN_ALL
GType gsk_text_node_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
GskRenderNode * gsk_text_node_new (PangoFont *font,
PangoGlyphString *glyphs,
const GdkRGBA *color,
const graphene_point_t *offset);
GskRenderNode * gsk_text_node_new (Pango2Font *font,
Pango2GlyphString *glyphs,
GQuark palette,
const GdkRGBA *color,
const graphene_point_t *offset);
GDK_AVAILABLE_IN_ALL
PangoFont * gsk_text_node_get_font (const GskRenderNode *node) G_GNUC_PURE;
Pango2Font * gsk_text_node_get_font (const GskRenderNode *node) G_GNUC_PURE;
GDK_AVAILABLE_IN_4_2
gboolean gsk_text_node_has_color_glyphs (const GskRenderNode *node) G_GNUC_PURE;
GDK_AVAILABLE_IN_ALL
guint gsk_text_node_get_num_glyphs (const GskRenderNode *node) G_GNUC_PURE;
GDK_AVAILABLE_IN_ALL
const PangoGlyphInfo *gsk_text_node_get_glyphs (const GskRenderNode *node,
const Pango2GlyphInfo *gsk_text_node_get_glyphs (const GskRenderNode *node,
guint *n_glyphs) G_GNUC_PURE;
GDK_AVAILABLE_IN_ALL
GQuark gsk_text_node_get_palette (const GskRenderNode *node) G_GNUC_PURE;
GDK_AVAILABLE_IN_ALL
const GdkRGBA * gsk_text_node_get_color (const GskRenderNode *node) G_GNUC_PURE;
GDK_AVAILABLE_IN_ALL
const graphene_point_t *gsk_text_node_get_offset (const GskRenderNode *node) G_GNUC_PURE;

View File

@@ -4406,14 +4406,15 @@ struct _GskTextNode
{
GskRenderNode render_node;
PangoFont *font;
Pango2Font *font;
gboolean has_color_glyphs;
GQuark palette;
GdkRGBA color;
graphene_point_t offset;
Pango2GlyphInfo *glyphs;
guint num_glyphs;
PangoGlyphInfo *glyphs;
};
static void
@@ -4433,7 +4434,7 @@ gsk_text_node_draw (GskRenderNode *node,
cairo_t *cr)
{
GskTextNode *self = (GskTextNode *) node;
PangoGlyphString glyphs;
Pango2GlyphString glyphs;
glyphs.num_glyphs = self->num_glyphs;
glyphs.glyphs = self->glyphs;
@@ -4443,7 +4444,7 @@ gsk_text_node_draw (GskRenderNode *node,
gdk_cairo_set_source_rgba (cr, &self->color);
cairo_translate (cr, self->offset.x, self->offset.y);
pango_cairo_show_glyph_string (cr, self->font, &glyphs);
pango2_cairo_show_color_glyph_string (cr, self->font, self->palette, &glyphs);
cairo_restore (cr);
}
@@ -4457,6 +4458,7 @@ gsk_text_node_diff (GskRenderNode *node1,
GskTextNode *self2 = (GskTextNode *) node2;
if (self1->font == self2->font &&
self1->palette == self2->palette &&
gdk_rgba_equal (&self1->color, &self2->color) &&
graphene_point_equal (&self1->offset, &self2->offset) &&
self1->num_glyphs == self2->num_glyphs)
@@ -4465,8 +4467,8 @@ gsk_text_node_diff (GskRenderNode *node1,
for (i = 0; i < self1->num_glyphs; i++)
{
PangoGlyphInfo *info1 = &self1->glyphs[i];
PangoGlyphInfo *info2 = &self2->glyphs[i];
Pango2GlyphInfo *info1 = &self1->glyphs[i];
Pango2GlyphInfo *info2 = &self2->glyphs[i];
if (info1->glyph == info2->glyph &&
info1->geometry.width == info2->geometry.width &&
@@ -4488,8 +4490,9 @@ gsk_text_node_diff (GskRenderNode *node1,
/**
* gsk_text_node_new:
* @font: the `PangoFont` containing the glyphs
* @glyphs: the `PangoGlyphString` to render
* @font: the `Pango2Font` containing the glyphs
* @glyphs: the `Pango2GlyphString` to render
* @palette: the palette to use, as quark
* @color: the foreground color to render with
* @offset: offset of the baseline
*
@@ -4501,19 +4504,20 @@ gsk_text_node_diff (GskRenderNode *node1,
* Returns: (nullable) (transfer full) (type GskTextNode): a new `GskRenderNode`
*/
GskRenderNode *
gsk_text_node_new (PangoFont *font,
PangoGlyphString *glyphs,
gsk_text_node_new (Pango2Font *font,
Pango2GlyphString *glyphs,
GQuark palette,
const GdkRGBA *color,
const graphene_point_t *offset)
{
GskTextNode *self;
GskRenderNode *node;
PangoRectangle ink_rect;
PangoGlyphInfo *glyph_infos;
Pango2Rectangle ink_rect;
Pango2GlyphInfo *glyph_infos;
int n;
pango_glyph_string_extents (glyphs, font, &ink_rect, NULL);
pango_extents_to_pixels (&ink_rect, NULL);
pango2_glyph_string_extents (glyphs, font, &ink_rect, NULL);
pango2_extents_to_pixels (&ink_rect, NULL);
/* Don't create nodes with empty bounds */
if (ink_rect.width == 0 || ink_rect.height == 0)
@@ -4527,14 +4531,15 @@ gsk_text_node_new (PangoFont *font,
self->color = *color;
self->offset = *offset;
self->has_color_glyphs = FALSE;
self->palette = palette;
glyph_infos = g_malloc_n (glyphs->num_glyphs, sizeof (PangoGlyphInfo));
glyph_infos = g_malloc_n (glyphs->num_glyphs, sizeof (Pango2GlyphInfo));
n = 0;
for (int i = 0; i < glyphs->num_glyphs; i++)
{
/* skip empty glyphs */
if (glyphs->glyphs[i].glyph == PANGO_GLYPH_EMPTY)
if (glyphs->glyphs[i].glyph == PANGO2_GLYPH_EMPTY)
continue;
glyph_infos[n] = glyphs->glyphs[i];
@@ -4581,7 +4586,7 @@ gsk_text_node_get_color (const GskRenderNode *node)
*
* Returns: (transfer none): the font
*/
PangoFont *
Pango2Font *
gsk_text_node_get_font (const GskRenderNode *node)
{
const GskTextNode *self = (const GskTextNode *) node;
@@ -4607,6 +4612,14 @@ gsk_text_node_has_color_glyphs (const GskRenderNode *node)
return self->has_color_glyphs;
}
GQuark
gsk_text_node_get_palette (const GskRenderNode *node)
{
const GskTextNode *self = (const GskTextNode *) node;
return self->palette;
}
/**
* gsk_text_node_get_num_glyphs:
* @node: (type GskTextNode): a text `GskRenderNode`
@@ -4632,7 +4645,7 @@ gsk_text_node_get_num_glyphs (const GskRenderNode *node)
*
* Returns: (transfer none) (array length=n_glyphs): the glyph information
*/
const PangoGlyphInfo *
const Pango2GlyphInfo *
gsk_text_node_get_glyphs (const GskRenderNode *node,
guint *n_glyphs)
{

View File

@@ -641,20 +641,17 @@ parse_blend_mode (GtkCssParser *parser,
return FALSE;
}
static PangoFont *
static Pango2Font *
font_from_string (const char *string)
{
PangoFontDescription *desc;
PangoFontMap *font_map;
PangoContext *context;
PangoFont *font;
Pango2FontDescription *desc;
Pango2Context *context;
Pango2Font *font;
desc = pango_font_description_from_string (string);
font_map = pango_cairo_font_map_get_default ();
context = pango_font_map_create_context (font_map);
font = pango_font_map_load_font (font_map, context, desc);
pango_font_description_free (desc);
desc = pango2_font_description_from_string (string);
context = pango2_context_new ();
font = pango2_context_load_font (context, desc);
pango2_font_description_free (desc);
g_object_unref (context);
return font;
@@ -664,62 +661,61 @@ font_from_string (const char *string)
#define MAX_ASCII_GLYPH 127 /* exclusive */
#define N_ASCII_GLYPHS (MAX_ASCII_GLYPH - MIN_ASCII_GLYPH)
static PangoGlyphString *
create_ascii_glyphs (PangoFont *font)
static Pango2GlyphString *
create_ascii_glyphs (Pango2Font *font)
{
PangoLanguage *language = pango_language_from_string ("en_US"); /* just pick one */
PangoCoverage *coverage;
PangoAnalysis not_a_hack = {
.shape_engine = NULL, /* unused */
.lang_engine = NULL, /* unused by pango_shape() */
.font = font,
.level = 0,
.gravity = PANGO_GRAVITY_SOUTH,
.flags = 0,
.script = PANGO_SCRIPT_COMMON,
.language = language,
.extra_attrs = NULL
};
PangoGlyphString *result, *glyph_string;
Pango2Context *context;
Pango2FontDescription *desc;
Pango2GlyphString *result, *glyph_string;
guint i;
coverage = pango_font_get_coverage (font, language);
for (i = MIN_ASCII_GLYPH; i < MAX_ASCII_GLYPH; i++)
{
if (!pango_coverage_get (coverage, i))
if (!pango2_font_face_has_char (pango2_font_get_face (font), i))
break;
}
pango_coverage_unref (coverage);
if (i < MAX_ASCII_GLYPH)
return NULL;
result = pango_glyph_string_new ();
pango_glyph_string_set_size (result, N_ASCII_GLYPHS);
glyph_string = pango_glyph_string_new ();
desc = pango2_font_describe (font);
context = pango2_context_new ();
pango2_context_set_font_description (context, desc);
pango2_font_description_free (desc);
result = pango2_glyph_string_new ();
pango2_glyph_string_set_size (result, N_ASCII_GLYPHS);
glyph_string = pango2_glyph_string_new ();
for (i = MIN_ASCII_GLYPH; i < MAX_ASCII_GLYPH; i++)
{
const char text[2] = { i, 0 };
PangoShapeFlags flags = 0;
GList *items;
Pango2Item *item;
Pango2ShapeFlags flags;
items = pango2_itemize (context, PANGO2_DIRECTION_LTR, text, 0, 1, NULL);
item = items->data;
if (cairo_version () < CAIRO_VERSION_ENCODE (1, 17, 4))
flags = PANGO_SHAPE_ROUND_POSITIONS;
flags = PANGO2_SHAPE_ROUND_POSITIONS;
pango_shape_with_flags (text, 1,
text, 1,
&not_a_hack,
glyph_string,
flags);
pango2_shape_item (item, text, 1, NULL, glyph_string, flags);
g_list_free_full (items, (GDestroyNotify) pango2_item_free);
if (glyph_string->num_glyphs != 1)
{
pango_glyph_string_free (glyph_string);
pango_glyph_string_free (result);
pango2_glyph_string_free (glyph_string);
pango2_glyph_string_free (result);
g_object_unref (context);
return NULL;
}
result->glyphs[i - MIN_ASCII_GLYPH] = glyph_string->glyphs[0];
}
pango_glyph_string_free (glyph_string);
pango2_glyph_string_free (glyph_string);
g_object_unref (context);
return result;
}
@@ -728,7 +724,7 @@ static gboolean
parse_font (GtkCssParser *parser,
gpointer out_font)
{
PangoFont *font;
Pango2Font *font;
char *s;
s = gtk_css_parser_consume_string (parser);
@@ -742,7 +738,7 @@ parse_font (GtkCssParser *parser,
return FALSE;
}
*((PangoFont**)out_font) = font;
*((Pango2Font**)out_font) = font;
g_free (s);
@@ -752,20 +748,20 @@ parse_font (GtkCssParser *parser,
static void
clear_font (gpointer inout_font)
{
g_clear_object ((PangoFont **) inout_font);
g_clear_object ((Pango2Font **) inout_font);
}
static gboolean
parse_glyphs (GtkCssParser *parser,
gpointer out_glyphs)
{
PangoGlyphString *glyph_string;
Pango2GlyphString *glyph_string;
glyph_string = pango_glyph_string_new ();
glyph_string = pango2_glyph_string_new ();
do
{
PangoGlyphInfo gi = { 0, { 0, 0, 0}, { 1 } };
Pango2GlyphInfo gi = { 0, { 0, 0, 0}, { 1 } };
double d, d2;
int i;
@@ -779,8 +775,8 @@ parse_glyphs (GtkCssParser *parser,
{
gtk_css_parser_error_value (parser, "Unsupported character %d in string", i);
}
gi.glyph = PANGO_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH + s[i];
pango_glyph_string_set_size (glyph_string, glyph_string->num_glyphs + 1);
gi.glyph = PANGO2_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH + s[i];
pango2_glyph_string_set_size (glyph_string, glyph_string->num_glyphs + 1);
glyph_string->glyphs[glyph_string->num_glyphs - 1] = gi;
}
@@ -791,22 +787,22 @@ parse_glyphs (GtkCssParser *parser,
if (!gtk_css_parser_consume_integer (parser, &i) ||
!gtk_css_parser_consume_number (parser, &d))
{
pango_glyph_string_free (glyph_string);
pango2_glyph_string_free (glyph_string);
return FALSE;
}
gi.glyph = i;
gi.geometry.width = (int) (d * PANGO_SCALE);
gi.geometry.width = (int) (d * PANGO2_SCALE);
if (gtk_css_parser_has_number (parser))
{
if (!gtk_css_parser_consume_number (parser, &d) ||
!gtk_css_parser_consume_number (parser, &d2))
{
pango_glyph_string_free (glyph_string);
pango2_glyph_string_free (glyph_string);
return FALSE;
}
gi.geometry.x_offset = (int) (d * PANGO_SCALE);
gi.geometry.y_offset = (int) (d2 * PANGO_SCALE);
gi.geometry.x_offset = (int) (d * PANGO2_SCALE);
gi.geometry.y_offset = (int) (d2 * PANGO2_SCALE);
if (gtk_css_parser_try_ident (parser, "same-cluster"))
gi.attr.is_cluster_start = 0;
@@ -819,13 +815,13 @@ parse_glyphs (GtkCssParser *parser,
gi.attr.is_color = 0;
}
pango_glyph_string_set_size (glyph_string, glyph_string->num_glyphs + 1);
pango2_glyph_string_set_size (glyph_string, glyph_string->num_glyphs + 1);
glyph_string->glyphs[glyph_string->num_glyphs - 1] = gi;
}
}
while (gtk_css_parser_try_token (parser, GTK_CSS_TOKEN_COMMA));
*((PangoGlyphString **)out_glyphs) = glyph_string;
*((Pango2GlyphString **)out_glyphs) = glyph_string;
return TRUE;
}
@@ -833,7 +829,7 @@ parse_glyphs (GtkCssParser *parser,
static void
clear_glyphs (gpointer inout_glyphs)
{
g_clear_pointer ((PangoGlyphString **) inout_glyphs, pango_glyph_string_free);
g_clear_pointer ((Pango2GlyphString **) inout_glyphs, pango2_glyph_string_free);
}
static gboolean
@@ -1616,21 +1612,21 @@ parse_repeat_node (GtkCssParser *parser)
}
static gboolean
unpack_glyphs (PangoFont *font,
PangoGlyphString *glyphs)
unpack_glyphs (Pango2Font *font,
Pango2GlyphString *glyphs)
{
PangoGlyphString *ascii = NULL;
Pango2GlyphString *ascii = NULL;
guint i;
for (i = 0; i < glyphs->num_glyphs; i++)
{
PangoGlyph glyph = glyphs->glyphs[i].glyph;
Pango2Glyph glyph = glyphs->glyphs[i].glyph;
if (glyph < PANGO_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH ||
glyph >= PANGO_GLYPH_INVALID_INPUT)
if (glyph < PANGO2_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH ||
glyph >= PANGO2_GLYPH_INVALID_INPUT)
continue;
glyph = glyph - (PANGO_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH) - MIN_ASCII_GLYPH;
glyph = glyph - (PANGO2_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH) - MIN_ASCII_GLYPH;
if (ascii == NULL)
{
@@ -1643,7 +1639,7 @@ unpack_glyphs (PangoFont *font,
glyphs->glyphs[i].geometry.width = ascii->glyphs[glyph].geometry.width;
}
g_clear_pointer (&ascii, pango_glyph_string_free);
g_clear_pointer (&ascii, pango2_glyph_string_free);
return TRUE;
}
@@ -1651,15 +1647,17 @@ unpack_glyphs (PangoFont *font,
static GskRenderNode *
parse_text_node (GtkCssParser *parser)
{
PangoFont *font = NULL;
Pango2Font *font = NULL;
graphene_point_t offset = GRAPHENE_POINT_INIT (0, 0);
GdkRGBA color = GDK_RGBA("000000");
PangoGlyphString *glyphs = NULL;
Pango2GlyphString *glyphs = NULL;
char *palette = NULL;
const Declaration declarations[] = {
{ "font", parse_font, clear_font, &font },
{ "offset", parse_point, NULL, &offset },
{ "color", parse_color, NULL, &color },
{ "glyphs", parse_glyphs, clear_glyphs, &glyphs }
{ "glyphs", parse_glyphs, clear_glyphs, &glyphs },
{ "palette", parse_string, clear_string, &palette },
};
GskRenderNode *result;
@@ -1671,17 +1669,20 @@ parse_text_node (GtkCssParser *parser)
g_assert (font);
}
if (palette == NULL)
palette = g_strdup ("default");
if (!glyphs)
{
const char *text = "Hello";
PangoGlyphInfo gi = { 0, { 0, 0, 0}, { 1 } };
Pango2GlyphInfo gi = { 0, { 0, 0, 0}, { 1 } };
guint i;
glyphs = pango_glyph_string_new ();
pango_glyph_string_set_size (glyphs, strlen (text));
glyphs = pango2_glyph_string_new ();
pango2_glyph_string_set_size (glyphs, strlen (text));
for (i = 0; i < strlen (text); i++)
{
gi.glyph = PANGO_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH + text[i];
gi.glyph = PANGO2_GLYPH_INVALID_INPUT - MAX_ASCII_GLYPH + text[i];
glyphs->glyphs[i] = gi;
}
}
@@ -1693,7 +1694,7 @@ parse_text_node (GtkCssParser *parser)
}
else
{
result = gsk_text_node_new (font, glyphs, &color, &offset);
result = gsk_text_node_new (font, glyphs, g_quark_from_string (palette), &color, &offset);
if (result == NULL)
{
gtk_css_parser_error_value (parser, "Glyphs result in empty text");
@@ -1701,7 +1702,7 @@ parse_text_node (GtkCssParser *parser)
}
g_object_unref (font);
pango_glyph_string_free (glyphs);
pango2_glyph_string_free (glyphs);
/* return anything, whatever, just not NULL */
if (result == NULL)
@@ -2329,11 +2330,11 @@ gsk_text_node_serialize_glyphs (GskRenderNode *node,
GString *p)
{
const guint n_glyphs = gsk_text_node_get_num_glyphs (node);
const PangoGlyphInfo *glyphs = gsk_text_node_get_glyphs (node, NULL);
PangoFont *font = gsk_text_node_get_font (node);
const Pango2GlyphInfo *glyphs = gsk_text_node_get_glyphs (node, NULL);
Pango2Font *font = gsk_text_node_get_font (node);
GString *str;
guint i, j;
PangoGlyphString *ascii;
Pango2GlyphString *ascii;
ascii = create_ascii_glyphs (font);
str = g_string_new ("");
@@ -2377,16 +2378,16 @@ gsk_text_node_serialize_glyphs (GskRenderNode *node,
}
g_string_append_printf (p, "%u ", glyphs[i].glyph);
string_append_double (p, (double) glyphs[i].geometry.width / PANGO_SCALE);
string_append_double (p, (double) glyphs[i].geometry.width / PANGO2_SCALE);
if (!glyphs[i].attr.is_cluster_start ||
glyphs[i].attr.is_color ||
glyphs[i].geometry.x_offset != 0 ||
glyphs[i].geometry.y_offset != 0)
{
g_string_append (p, " ");
string_append_double (p, (double) glyphs[i].geometry.x_offset / PANGO_SCALE);
string_append_double (p, (double) glyphs[i].geometry.x_offset / PANGO2_SCALE);
g_string_append (p, " ");
string_append_double (p, (double) glyphs[i].geometry.y_offset / PANGO_SCALE);
string_append_double (p, (double) glyphs[i].geometry.y_offset / PANGO2_SCALE);
if (!glyphs[i].attr.is_cluster_start)
g_string_append (p, " same-cluster");
if (!glyphs[i].attr.is_color)
@@ -2402,7 +2403,7 @@ gsk_text_node_serialize_glyphs (GskRenderNode *node,
g_string_free (str, TRUE);
if (ascii)
pango_glyph_string_free (ascii);
pango2_glyph_string_free (ascii);
}
static void
@@ -2761,9 +2762,10 @@ render_node_print (Printer *p,
{
const graphene_point_t *offset = gsk_text_node_get_offset (node);
const GdkRGBA *color = gsk_text_node_get_color (node);
PangoFont *font = gsk_text_node_get_font (node);
PangoFontDescription *desc;
Pango2Font *font = gsk_text_node_get_font (node);
Pango2FontDescription *desc;
char *font_name;
const char *palette = g_quark_to_string (gsk_text_node_get_palette (node));
start_node (p, "text");
@@ -2771,11 +2773,11 @@ render_node_print (Printer *p,
append_rgba_param (p, "color", color);
_indent (p);
desc = pango_font_describe (font);
font_name = pango_font_description_to_string (desc);
desc = pango2_font_describe (font);
font_name = pango2_font_description_to_string (desc);
g_string_append_printf (p->str, "font: \"%s\";\n", font_name);
g_free (font_name);
pango_font_description_free (desc);
pango2_font_description_free (desc);
_indent (p);
g_string_append (p->str, "glyphs: ");
@@ -2788,6 +2790,9 @@ render_node_print (Printer *p,
if (!graphene_point_equal (offset, graphene_point_zero ()))
append_point_param (p, "offset", offset);
if (strcmp (palette, "default") != 0)
append_string_param (p, "palette", palette);
end_node (p);
}
break;

View File

@@ -97,9 +97,9 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
guchar *data,
GskVulkanRenderer *renderer,
const graphene_rect_t *rect,
PangoFont *font,
Pango2Font *font,
guint total_glyphs,
const PangoGlyphInfo *glyphs,
const Pango2GlyphInfo *glyphs,
const graphene_point_t *offset,
guint start_glyph,
guint num_glyphs,
@@ -115,12 +115,12 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline *
for (; i < total_glyphs && count < num_glyphs; i++)
{
const PangoGlyphInfo *gi = &glyphs[i];
const Pango2GlyphInfo *gi = &glyphs[i];
if (gi->glyph != PANGO_GLYPH_EMPTY)
if (gi->glyph != PANGO2_GLYPH_EMPTY)
{
double cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = gi->geometry.y_offset / PANGO_SCALE;
double cx = (x_position + gi->geometry.x_offset) / PANGO2_SCALE;
double cy = gi->geometry.y_offset / PANGO2_SCALE;
GskVulkanColorTextInstance *instance = &instances[count];
GskVulkanCachedGlyph *glyph;

View File

@@ -25,9 +25,9 @@ void gsk_vulkan_color_text_pipeline_collect_vertex_data (Gs
guchar *data,
GskVulkanRenderer *renderer,
const graphene_rect_t *rect,
PangoFont *font,
Pango2Font *font,
guint total_glyphs,
const PangoGlyphInfo *glyphs,
const Pango2GlyphInfo *glyphs,
const graphene_point_t *offset,
guint start_glyph,
guint num_glyphs,

View File

@@ -113,8 +113,8 @@ gsk_vulkan_glyph_cache_class_init (GskVulkanGlyphCacheClass *klass)
}
typedef struct {
PangoFont *font;
PangoGlyph glyph;
Pango2Font *font;
Pango2Glyph glyph;
guint xshift;
guint yshift;
guint scale; /* times 1024 */
@@ -257,8 +257,8 @@ render_glyph (Atlas *atlas,
GskVulkanCachedGlyph *value = glyph->value;
cairo_surface_t *surface;
cairo_t *cr;
PangoGlyphString glyphs;
PangoGlyphInfo gi;
Pango2GlyphString glyphs;
Pango2GlyphInfo gi;
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
value->draw_width * key->scale / 1024,
@@ -270,7 +270,7 @@ render_glyph (Atlas *atlas,
gi.glyph = key->glyph;
gi.geometry.width = value->draw_width * 1024;
if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
if (key->glyph & PANGO2_GLYPH_UNKNOWN_FLAG)
gi.geometry.x_offset = key->xshift * 256;
else
gi.geometry.x_offset = key->xshift * 256 - value->draw_x * 1024;
@@ -279,7 +279,7 @@ render_glyph (Atlas *atlas,
glyphs.num_glyphs = 1;
glyphs.glyphs = &gi;
pango_cairo_show_glyph_string (cr, key->font, &glyphs);
pango2_cairo_show_glyph_string (cr, key->font, &glyphs);
cairo_destroy (cr);
@@ -332,13 +332,13 @@ gsk_vulkan_glyph_cache_new (GskRenderer *renderer,
return cache;
}
#define PHASE(x) ((x % PANGO_SCALE) * 4 / PANGO_SCALE)
#define PHASE(x) ((x % PANGO2_SCALE) * 4 / PANGO2_SCALE)
GskVulkanCachedGlyph *
gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
gboolean create,
PangoFont *font,
PangoGlyph glyph,
Pango2Font *font,
Pango2Glyph glyph,
int x,
int y,
float scale)
@@ -373,13 +373,13 @@ gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
if (create && value == NULL)
{
GlyphCacheKey *key;
PangoRectangle ink_rect;
Pango2Rectangle ink_rect;
key = g_new (GlyphCacheKey, 1);
value = g_new0 (GskVulkanCachedGlyph, 1);
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
pango_extents_to_pixels (&ink_rect, NULL);
pango2_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
pango2_extents_to_pixels (&ink_rect, NULL);
value->draw_x = ink_rect.x;
value->draw_y = ink_rect.y;

View File

@@ -1,7 +1,7 @@
#ifndef __GSK_VULKAN_GLYPH_CACHE_PRIVATE_H__
#define __GSK_VULKAN_GLYPH_CACHE_PRIVATE_H__
#include <pango/pango.h>
#include <pango2/pango.h>
#include "gskvulkanrendererprivate.h"
#include "gskvulkanimageprivate.h"
@@ -20,8 +20,8 @@ GskVulkanImage * gsk_vulkan_glyph_cache_get_glyph_image (GskVulkanGlyphCache
GskVulkanCachedGlyph *gsk_vulkan_glyph_cache_lookup (GskVulkanGlyphCache *cache,
gboolean create,
PangoFont *font,
PangoGlyph glyph,
Pango2Font *font,
Pango2Glyph glyph,
int x,
int y,

View File

@@ -378,8 +378,8 @@ gsk_vulkan_renderer_ref_glyph_image (GskVulkanRenderer *self,
guint
gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
PangoFont *font,
PangoGlyph glyph,
Pango2Font *font,
Pango2Glyph glyph,
int x,
int y,
float scale)
@@ -389,8 +389,8 @@ gsk_vulkan_renderer_cache_glyph (GskVulkanRenderer *self,
GskVulkanCachedGlyph *
gsk_vulkan_renderer_get_cached_glyph (GskVulkanRenderer *self,
PangoFont *font,
PangoGlyph glyph,
Pango2Font *font,
Pango2Glyph glyph,
int x,
int y,
float scale)

Some files were not shown because too many files have changed in this diff Show More