Compare commits

..

3 Commits

Author SHA1 Message Date
Matthias Clasen
10d075ee47 Steal enough Weston test code to show a yuv surface
This isn't mean to be mergable. It is just a quick hack
to get a yuv surface onscreen. It only runs under weston
atm, since mutter does not support yuv yet.
2022-06-08 15:36:11 -04:00
Matthias Clasen
9ec662dbba Flesh this out a bit 2022-06-08 14:53:34 -04:00
Matthias Clasen
5b6297e00f Add a quick subsurface test
Add a subsurface to a GTK toplevel,
and paint it green.
2022-06-08 14:53:34 -04:00
344 changed files with 10800 additions and 23336 deletions

View File

@@ -346,7 +346,6 @@ reference:
- _reference
publish-docs:
image: fedora:latest
stage: publish
needs: ['reference']
script:

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-pango2 \
mingw-w64-$MSYS2_ARCH-pango \
mingw-w64-$MSYS2_ARCH-fribidi \
mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \
mingw-w64-$MSYS2_ARCH-shared-mime-info \

View File

@@ -1,303 +0,0 @@
#include "fontcolors.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
#include "rangeedit.h"
enum {
PROP_FONT_MAP = 1,
PROP_FONT_DESC,
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;
Pango2FontMap *font_map;
};
struct _FontColorsClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE (FontColors, font_colors, GTK_TYPE_WIDGET);
static Pango2Font *
get_font (FontColors *self)
{
Pango2Context *context;
Pango2Font *font;
context = pango2_context_new_with_font_map (self->font_map);
font = pango2_context_load_font (context, self->font_desc);
g_object_unref (context);
return font;
}
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->font_map = g_object_ref (pango2_font_map_get_default ());
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_clear_object (&self->font_map);
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_MAP:
g_set_object (&self->font_map, g_value_get_object (value));
break;
case PROP_FONT_DESC:
pango2_font_description_free (self->font_desc);
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
update_colors (self);
}
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_MAP] =
g_param_spec_object ("font-map", "", "",
PANGO2_TYPE_FONT_MAP,
G_PARAM_READWRITE);
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");
}
GAction *
font_colors_get_reset_action (FontColors *self)
{
return G_ACTION (self->reset_action);
}

View File

@@ -1,15 +0,0 @@
#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);
GAction * font_colors_get_reset_action (FontColors *self);

View File

@@ -1,25 +0,0 @@
<?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

@@ -1,257 +0,0 @@
#include "fontcontrols.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
#include "rangeedit.h"
enum {
PROP_SIZE = 1,
PROP_LETTERSPACING,
PROP_LINE_HEIGHT,
PROP_FOREGROUND,
PROP_BACKGROUND,
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;
};
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;
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;
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);
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

@@ -1,16 +0,0 @@
#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

@@ -1,173 +0,0 @@
<?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="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="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

@@ -1,43 +0,0 @@
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;
}
plainview .content {
padding: 20px;
}
waterfallview .content {
padding: 20px;
}
styleview .content {
padding: 20px;
}
glyphsview .content {
padding: 20px;
}
infoview .content {
padding: 20px;
border-spacing: 10px;
}
gridview > child {
padding: 0;
}
glyphview {
padding: 0;
border: 0.6px solid gray;
}
.viewcontrols {
padding: 20px;
border-spacing: 10px;
}

View File

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

View File

@@ -1,186 +0,0 @@
#include "config.h"
#include "fontexplorerapp.h"
#include <gtk/gtk.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_open (GApplication *app,
GFile **files,
int n_files,
const char *hint)
{
FontExplorerWindow *win;
int i;
for (i = 0; i < n_files; i++)
{
win = font_explorer_window_new (FONT_EXPLORER_APP (app));
font_explorer_window_load (win, files[i]);
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;
G_APPLICATION_CLASS (class)->open = font_explorer_app_open;
}
FontExplorerApp *
font_explorer_app_new (void)
{
return g_object_new (FONT_EXPLORER_APP_TYPE,
"application-id", "org.gtk.FontExplorer",
"flags", G_APPLICATION_HANDLES_OPEN,
NULL);
}

View File

@@ -1,15 +0,0 @@
#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

@@ -1,269 +0,0 @@
#include "fontexplorerwin.h"
#include <gtk/gtk.h>
#include <string.h>
#include "fontcolors.h"
#include "fontcontrols.h"
#include "fontexplorerapp.h"
#include "fontfeatures.h"
#include "fontvariations.h"
#include "glyphsview.h"
#include "infoview.h"
#include "plainview.h"
#include "samplechooser.h"
#include "sampleeditor.h"
#include "styleview.h"
#include "waterfallview.h"
struct _FontExplorerWindow
{
GtkApplicationWindow parent;
Pango2FontMap *font_map;
GtkFontButton *fontbutton;
GtkLabel *path;
FontControls *controls;
FontFeatures *features;
FontVariations *variations;
FontColors *colors;
GtkStack *stack;
GtkToggleButton *plain_toggle;
GtkToggleButton *waterfall_toggle;
GtkToggleButton *style_toggle;
GtkToggleButton *glyphs_toggle;
GtkToggleButton *info_toggle;
GtkToggleButton *edit_toggle;
};
struct _FontExplorerWindowClass
{
GtkApplicationWindowClass parent_class;
};
enum {
PROP_FONT_MAP = 1,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
G_DEFINE_TYPE(FontExplorerWindow, font_explorer_window, GTK_TYPE_APPLICATION_WINDOW);
static void
reset (GSimpleAction *action,
GVariant *parameter,
FontExplorerWindow *self)
{
g_action_activate (font_controls_get_reset_action (self->controls), NULL);
g_action_activate (font_features_get_reset_action (self->features), NULL);
g_action_activate (font_variations_get_reset_action (self->variations), NULL);
g_action_activate (font_colors_get_reset_action (self->colors), NULL);
}
static void
update_reset (GSimpleAction *action,
GParamSpec *pspec,
FontExplorerWindow *self)
{
gboolean enabled;
GAction *reset_action;
enabled = g_action_get_enabled (font_controls_get_reset_action (self->controls)) ||
g_action_get_enabled (font_features_get_reset_action (self->features)) ||
g_action_get_enabled (font_variations_get_reset_action (self->variations)) ||
g_action_get_enabled (font_colors_get_reset_action (self->colors));
reset_action = g_action_map_lookup_action (G_ACTION_MAP (self), "reset");
g_simple_action_set_enabled (G_SIMPLE_ACTION (reset_action), enabled);
}
static void
font_explorer_window_init (FontExplorerWindow *self)
{
GSimpleAction *reset_action;
self->font_map = g_object_ref (pango2_font_map_get_default ());
gtk_widget_init_template (GTK_WIDGET (self));
reset_action = g_simple_action_new ("reset", NULL);
g_signal_connect (reset_action, "activate", G_CALLBACK (reset), self);
g_signal_connect (font_controls_get_reset_action (self->controls),
"notify::enabled", G_CALLBACK (update_reset), self);
g_signal_connect (font_variations_get_reset_action (self->variations),
"notify::enabled", G_CALLBACK (update_reset), self);
g_signal_connect (font_colors_get_reset_action (self->colors),
"notify::enabled", G_CALLBACK (update_reset), self);
g_signal_connect (font_features_get_reset_action (self->features),
"notify::enabled", G_CALLBACK (update_reset), self);
g_action_map_add_action (G_ACTION_MAP (self), G_ACTION (reset_action));
update_reset (NULL, NULL, self);
}
static void
update_view (GtkToggleButton *button,
FontExplorerWindow *self)
{
if (gtk_toggle_button_get_active (self->edit_toggle))
gtk_stack_set_visible_child_name (self->stack, "edit");
else if (gtk_toggle_button_get_active (self->plain_toggle))
gtk_stack_set_visible_child_name (self->stack, "plain");
else if (gtk_toggle_button_get_active (self->waterfall_toggle))
gtk_stack_set_visible_child_name (self->stack, "waterfall");
else if (gtk_toggle_button_get_active (self->style_toggle))
gtk_stack_set_visible_child_name (self->stack, "style");
else if (gtk_toggle_button_get_active (self->glyphs_toggle))
gtk_stack_set_visible_child_name (self->stack, "glyphs");
else if (gtk_toggle_button_get_active (self->info_toggle))
gtk_stack_set_visible_child_name (self->stack, "info");
}
static void
font_explorer_window_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
FontExplorerWindow *self = FONT_EXPLORER_WINDOW (object);
switch (prop_id)
{
case PROP_FONT_MAP:
g_set_object (&self->font_map, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
font_explorer_window_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
FontExplorerWindow *self = FONT_EXPLORER_WINDOW (object);
switch (prop_id)
{
case PROP_FONT_MAP:
g_value_set_object (value, self->font_map);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
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 *self = FONT_EXPLORER_WINDOW (object);
g_clear_object (&self->font_map);
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_COLORS_TYPE);
g_type_ensure (FONT_CONTROLS_TYPE);
g_type_ensure (FONT_FEATURES_TYPE);
g_type_ensure (FONT_VARIATIONS_TYPE);
g_type_ensure (GLYPHS_VIEW_TYPE);
g_type_ensure (INFO_VIEW_TYPE);
g_type_ensure (PLAIN_VIEW_TYPE);
g_type_ensure (SAMPLE_CHOOSER_TYPE);
g_type_ensure (SAMPLE_EDITOR_TYPE);
g_type_ensure (STYLE_VIEW_TYPE);
g_type_ensure (WATERFALL_VIEW_TYPE);
object_class->set_property = font_explorer_window_set_property;
object_class->get_property = font_explorer_window_get_property;
object_class->dispose = font_explorer_window_dispose;
object_class->finalize = font_explorer_window_finalize;
properties[PROP_FONT_MAP] =
g_param_spec_object ("font-map", "", "",
PANGO2_TYPE_FONT_MAP,
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/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, path);
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, stack);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, plain_toggle);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, waterfall_toggle);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, style_toggle);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, glyphs_toggle);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, info_toggle);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), FontExplorerWindow, edit_toggle);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), update_view);
}
FontExplorerWindow *
font_explorer_window_new (FontExplorerApp *app)
{
return g_object_new (FONT_EXPLORER_WINDOW_TYPE, "application", app, NULL);
}
void
font_explorer_window_load (FontExplorerWindow *self,
GFile *file)
{
const char *path;
Pango2FontMap *map;
Pango2HbFace *face;
Pango2FontDescription *desc;
char *basename;
path = g_file_peek_path (file);
basename = g_path_get_basename (path);
face = pango2_hb_face_new_from_file (path, 0, -2, NULL, NULL);
desc = pango2_font_face_describe (PANGO2_FONT_FACE (face));
map = pango2_font_map_new ();
pango2_font_map_add_face (map, PANGO2_FONT_FACE (face));
pango2_font_map_set_fallback (map, pango2_font_map_get_default ());
g_set_object (&self->font_map, map);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FONT_MAP]);
g_object_unref (map);
gtk_font_chooser_set_font_desc (GTK_FONT_CHOOSER (self->fontbutton), desc);
gtk_widget_hide (GTK_WIDGET (self->fontbutton));
gtk_widget_show (GTK_WIDGET (self->path));
gtk_label_set_label (self->path, basename);
pango2_font_description_free (desc);
g_free (basename);
}

View File

@@ -1,18 +0,0 @@
#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);
void font_explorer_window_load (FontExplorerWindow *self,
GFile *file);

View File

@@ -1,252 +0,0 @@
<?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="title">
<object class="GtkBox">
<property name="orientation">horizontal</property>
<style>
<class name="linked"/>
</style>
<child>
<object class="GtkToggleButton" id="plain_toggle">
<property name="label">Plain</property>
<property name="active">1</property>
<signal name="toggled" handler="update_view"/>
</object>
</child>
<child>
<object class="GtkToggleButton" id="waterfall_toggle">
<property name="label">Waterfall</property>
<property name="group">plain_toggle</property>
<signal name="toggled" handler="update_view"/>
</object>
</child>
<child>
<object class="GtkToggleButton" id="style_toggle">
<property name="label">Styles</property>
<property name="group">plain_toggle</property>
<property name="sensitive" bind-source="styleview" bind-property="has-styles" bind-flags="sync-create"/>
<signal name="toggled" handler="update_view"/>
</object>
</child>
<child>
<object class="GtkToggleButton" id="glyphs_toggle">
<property name="label">Glyphs</property>
<property name="group">plain_toggle</property>
<signal name="toggled" handler="update_view"/>
</object>
</child>
<child>
<object class="GtkToggleButton" id="info_toggle">
<property name="label">Info</property>
<property name="group">plain_toggle</property>
<signal name="toggled" handler="update_view"/>
</object>
</child>
</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>
<child type="end">
<object class="GtkToggleButton" id="edit_toggle">
<property name="hexpand">1</property>
<property name="halign">end</property>
<property name="icon-name">document-edit-symbolic</property>
<property name="tooltip-text" translatable="yes">Edit the sample</property>
<signal name="toggled" handler="update_view"/>
</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="GtkLabel" id="path">
<property name="visible">0</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child>
<object class="FontControls" id="controls">
</object>
</child>
<child>
<object class="SampleChooser" id="samplechooser"/>
</child>
<child>
<object class="FontVariations" id="variations">
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
</object>
</child>
<child>
<object class="FontFeatures" id="features">
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
<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-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkStack" id="stack">
<property name="hexpand">1</property>
<child>
<object class="GtkStackPage">
<property name="name">plain</property>
<property name="child">
<object class="PlainView">
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
<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="sampleeditor" 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>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">waterfall</property>
<property name="child">
<object class="WaterfallView">
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
<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="sampleeditor" 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>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">style</property>
<property name="child">
<object class="StyleView" id="styleview">
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
<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="sampleeditor" 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>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">glyphs</property>
<property name="child">
<object class="GlyphsView">
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
<property name="font-desc" bind-source="fontbutton" 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>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">info</property>
<property name="child">
<object class="InfoView">
<property name="font-map" bind-source="FontExplorerWindow" bind-flags="sync-create"/>
<property name="font-desc" bind-source="fontbutton" bind-flags="sync-create"/>
<property name="size" bind-source="controls" bind-flags="sync-create"/>
<property name="variations" bind-source="variations" bind-flags="sync-create"/>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">edit</property>
<property name="child">
<object class="SampleEditor" id="sampleeditor">
<property name="sample-text" bind-source="samplechooser" bind-flags="sync-create"/>
<property name="editing" bind-source="edit_toggle" bind-property="active" bind-flags="sync-create"/>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -1,744 +0,0 @@
#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_MAP = 1,
PROP_FONT_DESC,
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;
Pango2FontMap *font_map;
};
struct _FontFeaturesClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(FontFeatures, font_features, GTK_TYPE_WIDGET);
static Pango2Font *
get_font (FontFeatures *self)
{
Pango2Context *context;
Pango2Font *font;
context = pango2_context_new_with_font_map (self->font_map);
font = pango2_context_load_font (context, self->font_desc);
g_object_unref (context);
return font;
}
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)
{
self->font_map = g_object_ref (pango2_font_map_get_default ());
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_clear_object (&self->font_map);
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_MAP:
g_set_object (&self->font_map, g_value_get_object (value));
break;
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_LANGUAGE:
self->lang = pango2_language_from_string (g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
update_features (self);
}
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_FONT_MAP:
g_value_set_object (value, self->font_map);
break;
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_MAP] =
g_param_spec_object ("font-map", "", "",
PANGO2_TYPE_FONT_MAP,
G_PARAM_READWRITE);
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");
}
GAction *
font_features_get_reset_action (FontFeatures *self)
{
return G_ACTION (self->reset_action);
}

View File

@@ -1,15 +0,0 @@
#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);
GAction * font_features_get_reset_action (FontFeatures *self);

View File

@@ -1,25 +0,0 @@
<?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

@@ -1,508 +0,0 @@
#include "fontvariations.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
#include "rangeedit.h"
enum {
PROP_FONT_MAP = 1,
PROP_FONT_DESC,
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;
Pango2FontMap *font_map;
};
struct _FontVariationsClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(FontVariations, font_variations, GTK_TYPE_WIDGET);
static Pango2Font *
get_font (FontVariations *self)
{
Pango2Context *context;
Pango2Font *font;
context = pango2_context_new_with_font_map (self->font_map);
font = pango2_context_load_font (context, self->font_desc);
g_object_unref (context);
return font;
}
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)
{
self->font_map = g_object_ref (pango2_font_map_get_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);
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_clear_object (&self->font_map);
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_MAP:
g_set_object (&self->font_map, g_value_get_object (value));
break;
case PROP_FONT_DESC:
pango2_font_description_free (self->font_desc);
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
update_variations (self);
}
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_FONT_MAP:
g_value_set_object (value, self->font_map);
break;
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_MAP] =
g_param_spec_object ("font-map", "", "",
PANGO2_TYPE_FONT_MAP,
G_PARAM_READWRITE);
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");
}
GAction *
font_variations_get_reset_action (FontVariations *self)
{
return G_ACTION (self->reset_action);
}

View File

@@ -1,15 +0,0 @@
#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);
GAction * font_variations_get_reset_action (FontVariations *self);

View File

@@ -1,25 +0,0 @@
<?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

@@ -1,56 +0,0 @@
#include "glyphitem.h"
struct _GlyphItem {
GObject parent;
Pango2Font *font;
hb_codepoint_t glyph;
};
struct _GlyphItemClass {
GObjectClass parent_class;
};
G_DEFINE_TYPE (GlyphItem, glyph_item, G_TYPE_OBJECT)
static void
glyph_item_init (GlyphItem *self)
{
}
static void
glyph_item_finalize (GObject *object)
{
GlyphItem *item = GLYPH_ITEM (object);
g_object_unref (item->font);
G_OBJECT_CLASS (glyph_item_parent_class)->finalize (object);
}
static void
glyph_item_class_init (GlyphItemClass *class)
{
G_OBJECT_CLASS (class)->finalize = glyph_item_finalize;
}
GlyphItem *
glyph_item_new (Pango2Font *font,
hb_codepoint_t glyph)
{
GlyphItem *item = g_object_new (GLYPH_ITEM_TYPE, NULL);
item->font = g_object_ref (font);
item->glyph = glyph;
return item;
}
Pango2Font *
glyph_item_get_font (GlyphItem *item)
{
return item->font;
}
hb_codepoint_t
glyph_item_get_glyph (GlyphItem *item)
{
return item->glyph;
}

View File

@@ -1,17 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define GLYPH_ITEM_TYPE (glyph_item_get_type ())
#define GLYPH_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLYPH_ITEM_TYPE, GlyphItem))
typedef struct _GlyphItem GlyphItem;
typedef struct _GlyphItemClass GlyphItemClass;
GType glyph_item_get_type (void);
GlyphItem * glyph_item_new (Pango2Font *font,
hb_codepoint_t glyph);
hb_codepoint_t glyph_item_get_glyph (GlyphItem *item);
Pango2Font * glyph_item_get_font (GlyphItem *item);

View File

@@ -1,97 +0,0 @@
#include "glyphmodel.h"
#include "glyphitem.h"
struct _GlyphModel {
GObject parent;
Pango2Font *font;
unsigned int num_glyphs;
GlyphItem **glyphs;
};
struct _GlyphModelClass {
GObjectClass parent_class;
};
static GType
glyph_model_get_item_type (GListModel *model)
{
return GLYPH_ITEM_TYPE;
}
static guint
glyph_model_get_n_items (GListModel *model)
{
GlyphModel *self = GLYPH_MODEL (model);
return self->num_glyphs;
}
static gpointer
glyph_model_get_item (GListModel *model,
guint position)
{
GlyphModel *self = GLYPH_MODEL (model);
if (position >= self->num_glyphs)
return NULL;
if (self->glyphs[position] == NULL)
self->glyphs[position] = glyph_item_new (self->font, position);
return g_object_ref (self->glyphs[position]);
}
static void
glyph_model_list_model_init (GListModelInterface *iface)
{
iface->get_item_type = glyph_model_get_item_type;
iface->get_n_items = glyph_model_get_n_items;
iface->get_item = glyph_model_get_item;
}
G_DEFINE_TYPE_WITH_CODE (GlyphModel, glyph_model, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, glyph_model_list_model_init))
static void
glyph_model_init (GlyphModel *self)
{
}
static void
glyph_model_finalize (GObject *object)
{
GlyphModel *self = GLYPH_MODEL (object);
g_object_unref (self->font);
for (int i = 0; i < self->num_glyphs; i++)
{
if (self->glyphs[i])
g_object_unref (self->glyphs[i]);
}
g_free (self->glyphs);
G_OBJECT_CLASS (glyph_model_parent_class)->finalize (object);
}
static void
glyph_model_class_init (GlyphModelClass *class)
{
G_OBJECT_CLASS (class)->finalize = glyph_model_finalize;
}
GlyphModel *
glyph_model_new (Pango2Font *font)
{
GlyphModel *self;
hb_face_t *hb_face;
self = g_object_new (GLYPH_MODEL_TYPE, NULL);
self->font = g_object_ref (font);
hb_face = pango2_hb_face_get_hb_face (PANGO2_HB_FACE (pango2_font_get_face (font)));
self->num_glyphs = hb_face_get_glyph_count (hb_face);
self->glyphs = g_new0 (GlyphItem *, self->num_glyphs);
return self;
}

View File

@@ -1,14 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define GLYPH_MODEL_TYPE (glyph_model_get_type ())
#define GLYPH_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLYPH_MODEL_TYPE, GlyphModel))
typedef struct _GlyphModel GlyphModel;
typedef struct _GlyphModelClass GlyphModelClass;
GType glyph_model_get_type (void);
GlyphModel * glyph_model_new (Pango2Font *font);

View File

@@ -1,239 +0,0 @@
#include "glyphsview.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
#include "glyphitem.h"
#include "glyphmodel.h"
#include "glyphview.h"
enum {
PROP_FONT_MAP = 1,
PROP_FONT_DESC,
PROP_VARIATIONS,
PROP_PALETTE,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _GlyphsView
{
GtkWidget parent;
Pango2FontMap *font_map;
GtkGridView *glyphs;
Pango2FontDescription *font_desc;
char *variations;
char *palette;
GQuark palette_quark;
};
struct _GlyphsViewClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(GlyphsView, glyphs_view, GTK_TYPE_WIDGET);
static void
glyphs_view_init (GlyphsView *self)
{
self->font_map = g_object_ref (pango2_font_map_get_default ());
self->font_desc = pango2_font_description_from_string ("sans 12");
self->variations = g_strdup ("");
self->palette = g_strdup (PANGO2_COLOR_PALETTE_DEFAULT);
self->palette_quark = g_quark_from_string (self->palette);
gtk_widget_set_layout_manager (GTK_WIDGET (self),
gtk_box_layout_new (GTK_ORIENTATION_VERTICAL));
gtk_widget_init_template (GTK_WIDGET (self));
}
static void
glyphs_view_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), GLYPHS_VIEW_TYPE);
G_OBJECT_CLASS (glyphs_view_parent_class)->dispose (object);
}
static void
glyphs_view_finalize (GObject *object)
{
GlyphsView *self = GLYPHS_VIEW (object);
g_clear_object (&self->font_map);
pango2_font_description_free (self->font_desc);
g_free (self->variations);
g_free (self->palette);
G_OBJECT_CLASS (glyphs_view_parent_class)->finalize (object);
}
static Pango2Font *
get_font (GlyphsView *self,
int size)
{
Pango2Context *context;
Pango2FontDescription *desc;
Pango2Font *font;
context = pango2_context_new_with_font_map (self->font_map);
desc = pango2_font_description_copy_static (self->font_desc);
pango2_font_description_set_variations (desc, self->variations);
pango2_font_description_set_size (desc, size);
font = pango2_context_load_font (context, desc);
pango2_font_description_free (desc);
g_object_unref (context);
return font;
}
static void
update_glyph_model (GlyphsView *self)
{
Pango2Font *font = get_font (self, 60 * PANGO2_SCALE);
GlyphModel *gm;
GtkSelectionModel *model;
gm = glyph_model_new (font);
model = GTK_SELECTION_MODEL (gtk_no_selection_new (G_LIST_MODEL (gm)));
gtk_grid_view_set_model (self->glyphs, model);
g_object_unref (model);
g_object_unref (font);
}
static void
setup_glyph (GtkSignalListItemFactory *factory,
GObject *listitem)
{
gtk_list_item_set_child (GTK_LIST_ITEM (listitem), GTK_WIDGET (glyph_view_new ()));
}
static void
bind_glyph (GtkSignalListItemFactory *factory,
GObject *listitem,
GlyphsView *self)
{
GlyphView *view;
GObject *item;
view = GLYPH_VIEW (gtk_list_item_get_child (GTK_LIST_ITEM (listitem)));
item = gtk_list_item_get_item (GTK_LIST_ITEM (listitem));
glyph_view_set_font (view, glyph_item_get_font (GLYPH_ITEM (item)));
glyph_view_set_glyph (view, glyph_item_get_glyph (GLYPH_ITEM (item)));
glyph_view_set_palette (view, self->palette_quark);
}
static void
glyphs_view_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GlyphsView *self = GLYPHS_VIEW (object);
switch (prop_id)
{
case PROP_FONT_MAP:
g_set_object (&self->font_map, g_value_get_object (value));
break;
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_VARIATIONS:
g_free (self->variations);
self->variations = g_strdup (g_value_get_string (value));
break;
case PROP_PALETTE:
g_free (self->palette);
self->palette = g_strdup (g_value_get_string (value));
self->palette_quark = g_quark_from_string (self->palette);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
update_glyph_model (self);
}
static void
glyphs_view_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GlyphsView *self = GLYPHS_VIEW (object);
switch (prop_id)
{
case PROP_FONT_MAP:
g_value_set_object (value, self->font_map);
break;
case PROP_FONT_DESC:
g_value_set_boxed (value, self->font_desc);
break;
case PROP_VARIATIONS:
g_value_set_string (value, self->variations);
break;
case PROP_PALETTE:
g_value_set_string (value, self->palette);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
glyphs_view_class_init (GlyphsViewClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = glyphs_view_dispose;
object_class->finalize = glyphs_view_finalize;
object_class->get_property = glyphs_view_get_property;
object_class->set_property = glyphs_view_set_property;
properties[PROP_FONT_MAP] =
g_param_spec_object ("font-map", "", "",
PANGO2_TYPE_FONT_MAP,
G_PARAM_READWRITE);
properties[PROP_FONT_DESC] =
g_param_spec_boxed ("font-desc", "", "",
PANGO2_TYPE_FONT_DESCRIPTION,
G_PARAM_READWRITE);
properties[PROP_VARIATIONS] =
g_param_spec_string ("variations", "", "",
"",
G_PARAM_READWRITE);
properties[PROP_PALETTE] =
g_param_spec_string ("palette", "", "",
PANGO2_COLOR_PALETTE_DEFAULT,
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/glyphsview.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), GlyphsView, glyphs);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), setup_glyph);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class), bind_glyph);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "glyphsview");
}

View File

@@ -1,14 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define GLYPHS_VIEW_TYPE (glyphs_view_get_type ())
#define GLYPHS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLYPHS_VIEW_TYPE, GlyphsView))
typedef struct _GlyphsView GlyphsView;
typedef struct _GlyphsViewClass GlyphsViewClass;
GType glyphs_view_get_type (void);

View File

@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GlyphsView" parent="GtkWidget">
<style>
<class name="view"/>
</style>
<child>
<object class="GtkScrolledWindow">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<child>
<object class="GtkGridView" id="glyphs">
<style>
<class name="content"/>
</style>
<property name="factory">
<object class="GtkSignalListItemFactory">
<signal name="setup" handler="setup_glyph"/>
<signal name="bind" handler="bind_glyph"/>
</object>
</property>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -1,321 +0,0 @@
#include "glyphview.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
struct _GlyphView
{
GtkWidget parent;
Pango2Font *font;
GQuark palette;
int palette_index;
hb_codepoint_t glyph;
int n_layers;
int layer;
};
struct _GlyphViewClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(GlyphView, glyph_view, GTK_TYPE_WIDGET);
static void
click_cb (GtkGestureClick *gesture,
int n_press,
double x,
double y,
GlyphView *self)
{
if (self->n_layers == 0)
return;
self->layer++;
if (self->layer == self->n_layers)
self->layer = -1;
gtk_widget_queue_draw (GTK_WIDGET (self));
}
static void
glyph_view_init (GlyphView *self)
{
GtkGesture *click;
self->n_layers = 0;
self->layer = -1;
click = gtk_gesture_click_new ();
g_signal_connect (click, "pressed", G_CALLBACK (click_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (click));
}
static void
glyph_view_dispose (GObject *object)
{
GlyphView *self = GLYPH_VIEW (object);
g_clear_object (&self->font);
G_OBJECT_CLASS (glyph_view_parent_class)->dispose (object);
}
static void
glyph_view_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot)
{
GlyphView *self = GLYPH_VIEW (widget);
Pango2GlyphString *glyphs;
Pango2Rectangle ink, logical;
cairo_t *cr;
int width, height;
char name[80];
pango2_font_get_glyph_extents (self->font, self->glyph, &ink, &logical);
width = gtk_widget_get_width (widget);
height = gtk_widget_get_height (widget);
cr = gtk_snapshot_append_cairo (snapshot, &GRAPHENE_RECT_INIT (0, 0, width, height));
glyphs = pango2_glyph_string_new ();
pango2_glyph_string_set_size (glyphs, 1);
glyphs->glyphs[0].geometry.width = ink.width;
glyphs->glyphs[0].geometry.x_offset = ink.x;
glyphs->glyphs[0].geometry.y_offset = -ink.y;
if (self->layer == -1)
{
glyphs->glyphs[0].glyph = self->glyph;
cairo_set_source_rgb (cr, 0, 0, 0);
}
else
{
hb_face_t *face = hb_font_get_face (pango2_font_get_hb_font (self->font));
hb_ot_color_layer_t *layers;
unsigned int count;
layers = g_newa (hb_ot_color_layer_t, self->n_layers);
count = self->n_layers;
hb_ot_color_glyph_get_layers (face,
self->glyph,
0,
&count,
layers);
glyphs->glyphs[0].glyph = layers[self->layer].glyph;
if (layers[self->layer].color_index == 0xffff)
{
cairo_set_source_rgb (cr, 0, 0, 0);
}
else
{
hb_color_t *colors;
unsigned int n_colors;
hb_color_t color;
n_colors = hb_ot_color_palette_get_colors (face,
self->palette_index,
0,
NULL,
NULL);
colors = g_newa (hb_color_t, n_colors);
hb_ot_color_palette_get_colors (face,
self->palette_index,
0,
&n_colors,
colors);
color = colors[layers[self->layer].color_index];
cairo_set_source_rgba (cr, hb_color_get_red (color)/255.,
hb_color_get_green (color)/255.,
hb_color_get_blue (color)/255.,
hb_color_get_alpha (color)/255.);
}
}
cairo_move_to (cr, (width - logical.width/1024.)/2, (height - logical.height/1024.)/2);
pango2_cairo_show_color_glyph_string (cr, self->font, self->palette, glyphs);
{
Pango2Layout *layout;
Pango2FontDescription *desc;
char gid[20];
hb_font_t *hb_font;
hb_face_t *hb_face;
g_snprintf (gid, sizeof (gid), "%d", self->glyph);
layout = gtk_widget_create_pango_layout (widget, gid);
desc = pango2_font_description_from_string ("Cantarell 8");
pango2_layout_set_font_description (layout, desc);
pango2_font_description_free (desc);
gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (5, 5));
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA){ 0.,0.,0.,0.7});
gtk_snapshot_restore (snapshot);
hb_font = pango2_font_get_hb_font (self->font);
hb_face = hb_font_get_face (hb_font);
if (hb_ot_layout_has_glyph_classes (hb_face))
{
hb_ot_layout_glyph_class_t class;
const char *class_names[] = {
NULL, "Base", "Ligature", "Mark", "Component"
};
int w, h;
class = hb_ot_layout_get_glyph_class (hb_face, self->glyph);
if (class != HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED)
{
pango2_layout_set_text (layout, class_names[class], -1);
pango2_lines_get_size (pango2_layout_get_lines (layout), &w, &h);
gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (width - w/1024. - 5, 5));
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA){ 0.,0.,0.,.7});
gtk_snapshot_restore (snapshot);
}
}
if (hb_font_get_glyph_name (hb_font, self->glyph, name, sizeof (name)))
{
int w, h;
pango2_layout_set_text (layout, name, -1);
pango2_lines_get_size (pango2_layout_get_lines (layout), &w, &h);
gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (5, height - h/1024. - 5));
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA){ 0.,0.,0.,.7});
gtk_snapshot_restore (snapshot);
}
if (self->n_layers > 0)
{
char buf[128];
int w, h;
if (self->layer == -1)
g_snprintf (buf, sizeof (buf), "%d Layers", self->n_layers);
else
g_snprintf (buf, sizeof (buf), "Layer %d", self->layer);
pango2_layout_set_text (layout, buf, -1);
pango2_lines_get_size (pango2_layout_get_lines (layout), &w, &h);
gtk_snapshot_save (snapshot);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (width - w/1024. - 5, height - h/1024. - 5));
gtk_snapshot_append_layout (snapshot, layout, &(GdkRGBA){ 0.,0.,0.,.7});
gtk_snapshot_restore (snapshot);
}
g_object_unref (layout);
}
}
static void
glyph_view_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GlyphView *self = GLYPH_VIEW (widget);
Pango2Rectangle ink, logical;
pango2_font_get_glyph_extents (self->font, self->glyph, &ink, &logical);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
*minimum = *natural = 2 * logical.width / PANGO2_SCALE;
else
*minimum = *natural = 2 * logical.height / PANGO2_SCALE;
}
static void
glyph_view_class_init (GlyphViewClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
object_class->dispose = glyph_view_dispose;
widget_class->snapshot = glyph_view_snapshot;
widget_class->measure = glyph_view_measure;
gtk_widget_class_set_css_name (widget_class, "glyphview");
}
GlyphView *
glyph_view_new (void)
{
return g_object_new (GLYPH_VIEW_TYPE, NULL);
}
void
glyph_view_set_font (GlyphView *self,
Pango2Font *font)
{
if (g_set_object (&self->font, font))
gtk_widget_queue_resize (GTK_WIDGET (self));
}
static unsigned int
find_palette_index_by_flag (hb_face_t *hbface,
hb_ot_color_palette_flags_t flag)
{
unsigned int n_palettes;
n_palettes = hb_ot_color_palette_get_count (hbface);
for (unsigned int i = 0; i < n_palettes; i++)
{
if (hb_ot_color_palette_get_flags (hbface, i) & flag)
return i;
}
return 0;
}
void
glyph_view_set_palette (GlyphView *self,
GQuark palette)
{
if (self->palette == palette)
return;
self->palette = palette;
if (palette == g_quark_from_string (PANGO2_COLOR_PALETTE_DEFAULT))
self->palette_index = 0;
else if (palette == g_quark_from_string (PANGO2_COLOR_PALETTE_LIGHT))
self->palette_index = find_palette_index_by_flag (hb_font_get_face (pango2_font_get_hb_font (self->font)), HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND);
else if (palette == g_quark_from_string (PANGO2_COLOR_PALETTE_DARK))
self->palette_index = find_palette_index_by_flag (hb_font_get_face (pango2_font_get_hb_font (self->font)), HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND);
else
{
const char *str = g_quark_to_string (palette);
char *endp;
if (g_str_has_prefix (str, "palette"))
self->palette_index = g_ascii_strtoll (str + strlen ("palette"), &endp, 10);
}
gtk_widget_queue_resize (GTK_WIDGET (self));
}
void
glyph_view_set_glyph (GlyphView *self,
hb_codepoint_t glyph)
{
if (self->glyph == glyph)
return;
self->glyph = glyph;
self->n_layers = hb_ot_color_glyph_get_layers (hb_font_get_face (pango2_font_get_hb_font (self->font)), glyph, 0, NULL, NULL);
self->layer = -1;
gtk_widget_queue_resize (GTK_WIDGET (self));
}

View File

@@ -1,21 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define GLYPH_VIEW_TYPE (glyph_view_get_type ())
#define GLYPH_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLYPH_VIEW_TYPE, GlyphView))
typedef struct _GlyphView GlyphView;
typedef struct _GlyphViewClass GlyphViewClass;
GType glyph_view_get_type (void);
GlyphView * glyph_view_new (void);
void glyph_view_set_font (GlyphView *view,
Pango2Font *font);
void glyph_view_set_palette (GlyphView *view,
GQuark palette);
void glyph_view_set_glyph (GlyphView *view,
hb_codepoint_t glyph);

View File

@@ -1,423 +0,0 @@
#include "infoview.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
enum {
PROP_FONT_MAP = 1,
PROP_FONT_DESC,
PROP_SIZE,
PROP_VARIATIONS,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _InfoView
{
GtkWidget parent;
GtkGrid *info;
Pango2FontMap *font_map;
Pango2FontDescription *font_desc;
float size;
char *variations;
};
struct _InfoViewClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(InfoView, info_view, GTK_TYPE_WIDGET);
static void
info_view_init (InfoView *self)
{
self->font_map = g_object_ref (pango2_font_map_get_default ());
self->font_desc = pango2_font_description_from_string ("sans 12");
self->size = 12.;
self->variations = g_strdup ("");
gtk_widget_set_layout_manager (GTK_WIDGET (self),
gtk_box_layout_new (GTK_ORIENTATION_VERTICAL));
gtk_widget_init_template (GTK_WIDGET (self));
}
static void
info_view_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), INFO_VIEW_TYPE);
G_OBJECT_CLASS (info_view_parent_class)->dispose (object);
}
static void
info_view_finalize (GObject *object)
{
InfoView *self = INFO_VIEW (object);
g_clear_object (&self->font_map);
pango2_font_description_free (self->font_desc);
g_free (self->variations);
G_OBJECT_CLASS (info_view_parent_class)->finalize (object);
}
static Pango2Font *
get_font (InfoView *self,
int size)
{
Pango2Context *context;
Pango2FontDescription *desc;
Pango2Font *font;
context = pango2_context_new_with_font_map (self->font_map);
desc = pango2_font_description_copy_static (self->font_desc);
pango2_font_description_set_variations (desc, self->variations);
pango2_font_description_set_size (desc, size);
font = pango2_context_load_font (context, desc);
pango2_font_description_free (desc);
g_object_unref (context);
return font;
}
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
add_misc_line (InfoView *self,
const char *title,
const char *value,
int row)
{
GtkWidget *label;
label = gtk_label_new (title);
gtk_widget_set_halign (label, GTK_ALIGN_START);
gtk_widget_set_valign (label, GTK_ALIGN_START);
gtk_label_set_xalign (GTK_LABEL (label), 0);
gtk_widget_set_hexpand (label, TRUE);
gtk_grid_attach (self->info, label, 0, row, 1, 1);
label = gtk_label_new (value);
gtk_widget_set_halign (label, GTK_ALIGN_END);
gtk_widget_set_valign (label, GTK_ALIGN_START);
gtk_label_set_xalign (GTK_LABEL (label), 1);
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
gtk_label_set_width_chars (GTK_LABEL (label), 40);
gtk_label_set_max_width_chars (GTK_LABEL (label), 40);
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
gtk_grid_attach (self->info, label, 1, row, 1, 1);
}
static void
add_info_line (InfoView *self,
hb_face_t *face,
hb_ot_name_id_t name_id,
const char *title,
int row)
{
char info[256];
unsigned int len = sizeof (info);
if (hb_ot_name_get_utf8 (face, name_id, HB_LANGUAGE_INVALID, &len, info) > 0)
add_misc_line (self, title, info, row);
}
static void
add_metrics_line (InfoView *self,
hb_font_t *font,
hb_ot_metrics_tag_t metrics_tag,
const char *title,
int row)
{
hb_position_t pos;
if (hb_ot_metrics_get_position (font, metrics_tag, &pos))
{
char buf[128];
g_snprintf (buf, sizeof (buf), "%d", pos);
add_misc_line (self, title, buf, row);
}
}
static void
add_style_line (InfoView *self,
hb_font_t *font,
hb_style_tag_t style_tag,
const char *title,
int row)
{
float value;
char buf[16];
value = hb_style_get_value (font, style_tag);
g_snprintf (buf, sizeof (buf), "%.2f", value);
add_misc_line (self, title, buf, row);
}
static void
update_info (InfoView *self)
{
GtkWidget *child;
int size = pango2_font_description_get_size (self->font_desc);
Pango2Font *pango_font = get_font (self, MAX (size, 10 * PANGO2_SCALE));
hb_font_t *font1 = pango2_font_get_hb_font (pango_font);
hb_face_t *face = hb_font_get_face (font1);
hb_font_t *font = hb_font_create_sub_font (font1);
int row = 0;
char buf[128];
unsigned int count;
GString *s;
hb_tag_t *tables;
const char *path;
hb_font_set_scale (font, hb_face_get_upem (face), hb_face_get_upem (face));
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self->info))) != NULL)
gtk_widget_unparent (child);
gtk_grid_attach (self->info, make_title_label ("General Info"), 0, row++, 2, 1);
path = pango2_hb_face_get_file (PANGO2_HB_FACE (pango2_font_get_face (pango_font)));
if (path)
add_misc_line (self, "File ", path, row++);
add_info_line (self, face, HB_OT_NAME_ID_FONT_FAMILY, "Font Family Name", row++);
add_info_line (self, face, HB_OT_NAME_ID_FONT_SUBFAMILY, "Font Subfamily Name", row++);
add_info_line (self, face, HB_OT_NAME_ID_UNIQUE_ID, "Unique Font Identifier", row++);
add_info_line (self, face, HB_OT_NAME_ID_FULL_NAME, "Full Name", row++);
add_info_line (self, face, HB_OT_NAME_ID_VERSION_STRING, "Version", row++);
add_info_line (self, face, HB_OT_NAME_ID_POSTSCRIPT_NAME, "Postscript Name", row++);
add_info_line (self, face, HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY, "Typographic Family Name", row++);
add_info_line (self, face, HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY, "Typographic Subfamily Name", row++);
add_info_line (self, face, HB_OT_NAME_ID_MANUFACTURER, "Vendor ID", row++);
add_info_line (self, face, HB_OT_NAME_ID_DESIGNER, "Designer", row++);
add_info_line (self, face, HB_OT_NAME_ID_DESCRIPTION, "Description", row++);
add_info_line (self, face, HB_OT_NAME_ID_COPYRIGHT, "Copyright", row++);
gtk_grid_attach (self->info, make_title_label ("Metrics"), 0, row++, 2, 1);
g_snprintf (buf, sizeof (buf), "%d", hb_face_get_upem (face));
add_misc_line (self, "Units per Em", buf, row++);
add_metrics_line (self, font, HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER, "Ascender", row++);
add_metrics_line (self, font, HB_OT_METRICS_TAG_HORIZONTAL_DESCENDER, "Descender", row++);
add_metrics_line (self, font, HB_OT_METRICS_TAG_HORIZONTAL_LINE_GAP, "Line Gap", row++);
add_metrics_line (self, font, HB_OT_METRICS_TAG_HORIZONTAL_CARET_RISE, "Caret Rise", row++);
add_metrics_line (self, font, HB_OT_METRICS_TAG_HORIZONTAL_CARET_RUN, "Caret Run", row++);
add_metrics_line (self, font, HB_OT_METRICS_TAG_HORIZONTAL_CARET_OFFSET, "Caret Offset", row++);
add_metrics_line (self, font, HB_OT_METRICS_TAG_X_HEIGHT, "x Height", row++);
add_metrics_line (self, font, HB_OT_METRICS_TAG_CAP_HEIGHT, "Cap Height", row++);
add_metrics_line (self, font, HB_OT_METRICS_TAG_STRIKEOUT_SIZE, "Strikeout Size", row++);
add_metrics_line (self, font, HB_OT_METRICS_TAG_STRIKEOUT_OFFSET, "Strikeout Offset", row++);
add_metrics_line (self, font, HB_OT_METRICS_TAG_STRIKEOUT_SIZE, "Underline Size", row++);
add_metrics_line (self, font, HB_OT_METRICS_TAG_STRIKEOUT_OFFSET, "Underline Offset", row++);
gtk_grid_attach (self->info, make_title_label ("Style"), 0, row++, 2, 1);
add_style_line (self, font, HB_STYLE_TAG_ITALIC, "Italic", row++);
add_style_line (self, font, HB_STYLE_TAG_OPTICAL_SIZE, "Optical Size", row++);
add_style_line (self, font, HB_STYLE_TAG_SLANT_ANGLE, "Slant Angle", row++);
add_style_line (self, font, HB_STYLE_TAG_WIDTH, "Width", row++);
add_style_line (self, font, HB_STYLE_TAG_WEIGHT, "Weight", row++);
gtk_grid_attach (self->info, make_title_label ("Miscellaneous"), 0, row++, 2, 1);
count = hb_face_get_glyph_count (face);
g_snprintf (buf, sizeof (buf), "%d", count);
add_misc_line (self, "Glyph Count", buf, row++);
if (hb_ot_var_get_axis_count (face) > 0)
{
s = g_string_new ("");
hb_ot_var_axis_info_t *axes;
axes = g_newa (hb_ot_var_axis_info_t, hb_ot_var_get_axis_count (face));
count = hb_ot_var_get_axis_count (face);
hb_ot_var_get_axis_infos (face, 0, &count, axes);
for (int i = 0; i < count; i++)
{
char name[256];
unsigned int len;
len = sizeof (buf);
hb_ot_name_get_utf8 (face, axes[i].name_id, HB_LANGUAGE_INVALID, &len, name);
if (s->len > 0)
g_string_append (s, ", ");
g_string_append (s, name);
}
add_misc_line (self, "Axes", s->str, row++);
g_string_free (s, TRUE);
}
if (hb_ot_var_get_named_instance_count (face) > 0)
{
s = g_string_new ("");
for (int i = 0; i < hb_ot_var_get_named_instance_count (face); i++)
{
hb_ot_name_id_t name_id;
char name[256];
unsigned int len;
name_id = hb_ot_var_named_instance_get_subfamily_name_id (face, i);
len = sizeof (buf);
hb_ot_name_get_utf8 (face, name_id, HB_LANGUAGE_INVALID, &len, name);
if (s->len > 0)
g_string_append (s, ", ");
g_string_append (s, name);
}
add_misc_line (self, "Named Instances", s->str, row++);
g_string_free (s, TRUE);
}
s = g_string_new ("");
count = hb_face_get_table_tags (face, 0, NULL, NULL);
tables = g_newa (hb_tag_t, count);
hb_face_get_table_tags (face, 0, &count, tables);
for (int i = 0; i < count; i++)
{
memset (buf, 0, sizeof (buf));
hb_tag_to_string (tables[i], buf);
if (s->len > 0)
g_string_append (s, ", ");
g_string_append (s, buf);
}
add_misc_line (self, "Tables", s->str, row++);
g_string_free (s, TRUE);
s = g_string_new ("");
if (hb_ot_color_has_palettes (face))
g_string_append_printf (s, "%s", "Palettes");
if (hb_ot_color_has_layers (face))
g_string_append_printf (s, "%s%s", s->len > 0 ? ", " : "", "Layers");
if (hb_ot_color_has_svg (face))
g_string_append_printf (s, "%s%s", s->len > 0 ? ", " : "", "SVG");
if (hb_ot_color_has_png (face))
g_string_append_printf (s, "%s%s", s->len > 0 ? ", " : "", "PNG");
if (s->len > 0)
add_misc_line (self, "Color", s->str, row++);
g_string_free (s, TRUE);
hb_font_destroy (font);
}
static void
info_view_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
InfoView *self = INFO_VIEW (object);
switch (prop_id)
{
case PROP_FONT_MAP:
g_set_object (&self->font_map, g_value_get_object (value));
break;
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_VARIATIONS:
g_free (self->variations);
self->variations = g_strdup (g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
update_info (self);
}
static void
info_view_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
InfoView *self = INFO_VIEW (object);
switch (prop_id)
{
case PROP_FONT_MAP:
g_value_set_object (value, self->font_map);
break;
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_VARIATIONS:
g_value_set_string (value, self->variations);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
info_view_class_init (InfoViewClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = info_view_dispose;
object_class->finalize = info_view_finalize;
object_class->get_property = info_view_get_property;
object_class->set_property = info_view_set_property;
properties[PROP_FONT_MAP] =
g_param_spec_object ("font-map", "", "",
PANGO2_TYPE_FONT_MAP,
G_PARAM_READWRITE);
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_VARIATIONS] =
g_param_spec_string ("variations", "", "",
"",
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/infoview.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), InfoView, info);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "infoview");
}

View File

@@ -1,14 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define INFO_VIEW_TYPE (info_view_get_type ())
#define INFO_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INFO_VIEW_TYPE, InfoView))
typedef struct _InfoView InfoView;
typedef struct _InfoViewClass InfoViewClass;
GType info_view_get_type (void);

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="InfoView" parent="GtkWidget">
<style>
<class name="view"/>
</style>
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<child>
<object class="GtkGrid" id="info">
<style>
<class name="content"/>
</style>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -1,334 +0,0 @@
#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

@@ -1,13 +0,0 @@
#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

@@ -1,9 +0,0 @@
#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

@@ -1,35 +0,0 @@
fontexplorer_sources = [
'fontcolors.c',
'fontcontrols.c',
'fontexplorerapp.c',
'fontexplorerwin.c',
'fontfeatures.c',
'fontvariations.c',
'glyphitem.c',
'glyphmodel.c',
'glyphsview.c',
'glyphview.c',
'infoview.c',
'language-names.c',
'main.c',
'plainview.c',
'rangeedit.c',
'samplechooser.c',
'sampleeditor.c',
'styleview.c',
'waterfallview.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

@@ -1,343 +0,0 @@
#include "plainview.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
#include "glyphitem.h"
#include "glyphmodel.h"
#include "glyphview.h"
enum {
PROP_FONT_MAP = 1,
PROP_FONT_DESC,
PROP_SIZE,
PROP_LETTERSPACING,
PROP_LINE_HEIGHT,
PROP_FOREGROUND,
PROP_BACKGROUND,
PROP_VARIATIONS,
PROP_FEATURES,
PROP_PALETTE,
PROP_SAMPLE_TEXT,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _PlainView
{
GtkWidget parent;
GtkLabel *content;
GtkScrolledWindow *swin;
Pango2FontMap *font_map;
Pango2FontDescription *font_desc;
float size;
char *variations;
char *features;
char *palette;
GQuark palette_quark;
int letterspacing;
float line_height;
GdkRGBA foreground;
GdkRGBA background;
GtkCssProvider *bg_provider;
char *sample_text;
};
struct _PlainViewClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(PlainView, plain_view, GTK_TYPE_WIDGET);
static void
plain_view_init (PlainView *self)
{
self->font_map = g_object_ref (pango2_font_map_get_default ());
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->palette_quark = g_quark_from_string (self->palette);
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
plain_view_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), PLAIN_VIEW_TYPE);
G_OBJECT_CLASS (plain_view_parent_class)->dispose (object);
}
static void
plain_view_finalize (GObject *object)
{
PlainView *self = PLAIN_VIEW (object);
g_clear_object (&self->font_map);
pango2_font_description_free (self->font_desc);
g_free (self->variations);
g_free (self->features);
g_free (self->palette);
G_OBJECT_CLASS (plain_view_parent_class)->finalize (object);
}
static void
update_view (PlainView *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_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 (".content { 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
plain_view_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
PlainView *self = PLAIN_VIEW (object);
switch (prop_id)
{
case PROP_FONT_MAP:
g_set_object (&self->font_map, g_value_get_object (value));
gtk_widget_set_font_map (GTK_WIDGET (self->content), self->font_map);
break;
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));
self->palette_quark = g_quark_from_string (self->palette);
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
plain_view_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
PlainView *self = PLAIN_VIEW (object);
switch (prop_id)
{
case PROP_FONT_MAP:
g_value_set_object (value, self->font_map);
break;
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;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
plain_view_class_init (PlainViewClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = plain_view_dispose;
object_class->finalize = plain_view_finalize;
object_class->get_property = plain_view_get_property;
object_class->set_property = plain_view_set_property;
properties[PROP_FONT_MAP] =
g_param_spec_object ("font-map", "", "",
PANGO2_TYPE_FONT_MAP,
G_PARAM_READWRITE);
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);
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/plainview.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PlainView, swin);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), PlainView, content);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "plainview");
}

View File

@@ -1,14 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define PLAIN_VIEW_TYPE (plain_view_get_type ())
#define PLAIN_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PLAIN_VIEW_TYPE, PlainView))
typedef struct _PlainView PlainView;
typedef struct _PlainViewClass PlainViewClass;
GType plain_view_get_type (void);

View File

@@ -1,32 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="PlainView" parent="GtkWidget">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<child>
<object class="GtkScrolledWindow" id="swin">
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<style>
<class name="view"/>
</style>
<child>
<object class="GtkLabel" id="content">
<property name="label">Content</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="content"/>
</style>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -1,174 +0,0 @@
#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

@@ -1,15 +0,0 @@
#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

@@ -1,24 +0,0 @@
<?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

@@ -1,163 +0,0 @@
#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

@@ -1,15 +0,0 @@
#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

@@ -1,46 +0,0 @@
<?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

@@ -1,162 +0,0 @@
#include "sampleeditor.h"
#include <gtk/gtk.h>
enum {
PROP_SAMPLE_TEXT = 1,
PROP_EDITING,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _SampleEditor
{
GtkWidget parent;
GtkTextView *edit;
char *sample_text;
gboolean editing;
};
struct _SampleEditorClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(SampleEditor, sample_editor, GTK_TYPE_WIDGET);
static void
sample_editor_init (SampleEditor *self)
{
self->sample_text = g_strdup ("Some sample text is better than other sample text");
self->editing = FALSE;
gtk_widget_set_layout_manager (GTK_WIDGET (self),
gtk_box_layout_new (GTK_ORIENTATION_VERTICAL));
gtk_widget_init_template (GTK_WIDGET (self));
}
static void
sample_editor_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), SAMPLE_EDITOR_TYPE);
G_OBJECT_CLASS (sample_editor_parent_class)->dispose (object);
}
static void
sample_editor_finalize (GObject *object)
{
SampleEditor *self = SAMPLE_EDITOR (object);
g_free (self->sample_text);
G_OBJECT_CLASS (sample_editor_parent_class)->finalize (object);
}
static void
update_editing (SampleEditor *self,
gboolean editing)
{
GtkTextBuffer *buffer;
if (self->editing == editing)
return;
self->editing = editing;
buffer = gtk_text_view_get_buffer (self->edit);
if (self->editing)
{
gtk_text_buffer_set_text (buffer, self->sample_text, -1);
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);
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SAMPLE_TEXT]);
}
}
static void
sample_editor_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
SampleEditor *self = SAMPLE_EDITOR (object);
switch (prop_id)
{
case PROP_SAMPLE_TEXT:
g_free (self->sample_text);
self->sample_text = g_strdup (g_value_get_string (value));
break;
case PROP_EDITING:
update_editing (self, g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sample_editor_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
SampleEditor *self = SAMPLE_EDITOR (object);
switch (prop_id)
{
case PROP_SAMPLE_TEXT:
g_value_set_string (value, self->sample_text);
break;
case PROP_EDITING:
g_value_set_boolean (value, self->editing);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sample_editor_class_init (SampleEditorClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = sample_editor_dispose;
object_class->finalize = sample_editor_finalize;
object_class->get_property = sample_editor_get_property;
object_class->set_property = sample_editor_set_property;
properties[PROP_SAMPLE_TEXT] =
g_param_spec_string ("sample-text", "", "",
"",
G_PARAM_READWRITE);
properties[PROP_EDITING] =
g_param_spec_boolean ("editing", "", "",
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/sampleeditor.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), SampleEditor, edit);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "sampleeditor");
}

View File

@@ -1,14 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define SAMPLE_EDITOR_TYPE (sample_editor_get_type ())
#define SAMPLE_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SAMPLE_EDITOR_TYPE, SampleEditor))
typedef struct _SampleEditor SampleEditor;
typedef struct _SampleEditorClass SampleEditorClass;
GType sample_editor_get_type (void);

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="SampleEditor" parent="GtkWidget">
<style>
<class name="view"/>
</style>
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<child>
<object class="GtkTextView" id="edit">
<property name="wrap-mode">word-char</property>
<property name="left-margin">20</property>
<property name="right-margin">20</property>
<property name="top-margin">20</property>
<property name="bottom-margin">20</property>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -1,506 +0,0 @@
#include "styleview.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
#include "glyphitem.h"
#include "glyphmodel.h"
#include "glyphview.h"
enum {
PROP_FONT_MAP = 1,
PROP_FONT_DESC,
PROP_SIZE,
PROP_LETTERSPACING,
PROP_LINE_HEIGHT,
PROP_FOREGROUND,
PROP_BACKGROUND,
PROP_VARIATIONS,
PROP_FEATURES,
PROP_PALETTE,
PROP_SAMPLE_TEXT,
PROP_HAS_STYLES,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _StyleView
{
GtkWidget parent;
GtkLabel *content;
GtkScrolledWindow *swin;
Pango2FontMap *font_map;
Pango2FontDescription *font_desc;
float size;
char *variations;
char *features;
char *palette;
GQuark palette_quark;
int letterspacing;
float line_height;
GdkRGBA foreground;
GdkRGBA background;
GtkCssProvider *bg_provider;
char *sample_text;
gboolean has_styles;
};
struct _StyleViewClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(StyleView, style_view, GTK_TYPE_WIDGET);
static void
style_view_init (StyleView *self)
{
self->font_map = g_object_ref (pango2_font_map_get_default ());
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->palette_quark = g_quark_from_string (self->palette);
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");
self->has_styles = FALSE;
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
style_view_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), STYLE_VIEW_TYPE);
G_OBJECT_CLASS (style_view_parent_class)->dispose (object);
}
static void
style_view_finalize (GObject *object)
{
StyleView *self = STYLE_VIEW (object);
g_clear_object (&self->font_map);
pango2_font_description_free (self->font_desc);
g_free (self->variations);
g_free (self->features);
g_free (self->palette);
G_OBJECT_CLASS (style_view_parent_class)->finalize (object);
}
static Pango2Font *
get_font (StyleView *self)
{
Pango2Context *context;
Pango2FontDescription *desc;
Pango2Font *font;
context = pango2_context_new_with_font_map (self->font_map);
desc = pango2_font_description_copy_static (self->font_desc);
pango2_font_description_set_variations (desc, self->variations);
pango2_font_description_set_size (desc, self->size * PANGO2_SCALE);
font = pango2_context_load_font (context, desc);
pango2_font_description_free (desc);
g_object_unref (context);
return font;
}
static void
update_has_styles (StyleView *self)
{
Pango2Font *font = get_font (self);
hb_face_t *hb_face = hb_font_get_face (pango2_font_get_hb_font (font));
gboolean has_styles;
has_styles = hb_ot_var_get_named_instance_count (hb_face) > 0;
g_object_unref (font);
if (self->has_styles == has_styles)
return;
self->has_styles = has_styles;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HAS_STYLES]);
}
static int
measure_names (Pango2Context *context,
hb_face_t *hb_face)
{
Pango2Layout *layout;
Pango2FontDescription *desc;
GString *str;
int width, height;
layout = pango2_layout_new (context);
desc = pango2_font_description_from_string ("Cantarell Regular 12");
pango2_layout_set_font_description (layout, desc);
pango2_font_description_free (desc);
str = g_string_new ("");
for (int i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
{
hb_ot_name_id_t name_id;
char name[20];
unsigned int name_len = 20;
name_id = hb_ot_var_named_instance_get_subfamily_name_id (hb_face, i);
hb_ot_name_get_utf8 (hb_face, name_id, HB_LANGUAGE_INVALID, &name_len, name);
g_string_append_printf (str, " %s\n", name);
}
pango2_layout_set_text (layout, str->str, -1);
pango2_lines_get_size (pango2_layout_get_lines (layout), &width, &height);
g_string_free (str, TRUE);
g_object_unref (layout);
return width;
}
static void
update_view (StyleView *self)
{
Pango2FontDescription *desc;
Pango2AttrList *attrs;
char *fg, *bg, *css;
GString *str;
int start, end, text_len;
Pango2Font *font = get_font (self);
hb_face_t *hb_face = hb_font_get_face (pango2_font_get_hb_font (font));
unsigned int n_axes;
float *coords = NULL;
hb_ot_var_axis_info_t *axes;
Pango2FontDescription *label_desc;
Pango2TabArray *tabs;
int width;
desc = pango2_font_description_copy_static (self->font_desc);
pango2_font_description_set_variations (desc, self->variations);
pango2_font_description_set_size (desc, self->size * PANGO2_SCALE);
attrs = pango2_attr_list_new ();
pango2_attr_list_insert (attrs, pango2_attr_font_desc_new (desc));
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));
str = g_string_new ("");
start = 0;
text_len = strlen (self->sample_text);
n_axes = hb_ot_var_get_axis_count (hb_face);
axes = g_newa (hb_ot_var_axis_info_t, n_axes);
hb_ot_var_get_axis_infos (hb_face, 0, &n_axes, axes);
coords = g_newa (float, n_axes);
label_desc = pango2_font_description_from_string ("Cantarell Regular 12");
width = measure_names (gtk_widget_get_pango_context (GTK_WIDGET (self->content)), hb_face);
tabs = pango2_tab_array_new (1, PANGO2_TAB_POSITIONS_DEFAULT);
pango2_tab_array_set_tab (tabs, 0, PANGO2_TAB_LEFT, width);
gtk_label_set_tabs (self->content, tabs);
pango2_tab_array_free (tabs);
for (int i = 0; i < hb_ot_var_get_named_instance_count (hb_face); i++)
{
unsigned int n_coords = n_axes;
Pango2Attribute *attr;
GString *variations;
hb_ot_name_id_t name_id;
char name[20];
unsigned int name_len = 20;
name_id = hb_ot_var_named_instance_get_subfamily_name_id (hb_face, i);
hb_ot_name_get_utf8 (hb_face, name_id, HB_LANGUAGE_INVALID, &name_len, name);
g_string_append_printf (str, "%s\t", name);
end = str->len;
attr = pango2_attr_font_desc_new (label_desc);
pango2_attribute_set_range (attr, start, end);
pango2_attr_list_insert (attrs, attr);
start = end;
hb_ot_var_named_instance_get_design_coords (hb_face, i, &n_coords, coords);
variations = g_string_new ("");
for (int j = 0; j < n_axes; j++)
{
char buf[5] = { 0, };
if (variations->len > 0)
g_string_append_c (variations, ',');
hb_tag_to_string (axes[j].tag, buf);
g_string_append_printf (variations, "%s=%f", buf, coords[j]);
}
g_string_append (str, self->sample_text);
g_string_append (str, ""); /* Unicode line separator */
end = start + text_len + strlen ("");
pango2_font_description_set_variations (desc, variations->str);
g_string_free (variations, TRUE);
attr = pango2_attr_font_desc_new (desc);
pango2_attribute_set_range (attr, start, end);
pango2_attr_list_insert (attrs, attr);
start = end;
}
pango2_font_description_free (label_desc);
gtk_label_set_text (self->content, str->str);
gtk_label_set_attributes (self->content, attrs);
g_string_free (str, TRUE);
pango2_attr_list_unref (attrs);
pango2_font_description_free (desc);
fg = gdk_rgba_to_string (&self->foreground);
bg = gdk_rgba_to_string (&self->background);
css = g_strdup_printf (".content { 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);
g_object_unref (font);
}
static void
style_view_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
StyleView *self = STYLE_VIEW (object);
switch (prop_id)
{
case PROP_FONT_MAP:
g_set_object (&self->font_map, g_value_get_object (value));
gtk_widget_set_font_map (GTK_WIDGET (self->content), self->font_map);
update_has_styles (self);
break;
case PROP_FONT_DESC:
pango2_font_description_free (self->font_desc);
self->font_desc = pango2_font_description_copy (g_value_get_boxed (value));
update_has_styles (self);
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));
self->palette_quark = g_quark_from_string (self->palette);
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
style_view_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
StyleView *self = STYLE_VIEW (object);
switch (prop_id)
{
case PROP_FONT_MAP:
g_value_set_object (value, self->font_map);
break;
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_HAS_STYLES:
g_value_set_boolean (value, self->has_styles);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
style_view_class_init (StyleViewClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = style_view_dispose;
object_class->finalize = style_view_finalize;
object_class->get_property = style_view_get_property;
object_class->set_property = style_view_set_property;
properties[PROP_FONT_MAP] =
g_param_spec_object ("font-map", "", "",
PANGO2_TYPE_FONT_MAP,
G_PARAM_READWRITE);
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_HAS_STYLES] =
g_param_spec_boolean ("has-styles", "", "",
FALSE,
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/styleview.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), StyleView, swin);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), StyleView, content);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "styleview");
}

View File

@@ -1,14 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define STYLE_VIEW_TYPE (style_view_get_type ())
#define STYLE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), STYLE_VIEW_TYPE, StyleView))
typedef struct _StyleView StyleView;
typedef struct _StyleViewClass StyleViewClass;
GType style_view_get_type (void);

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="StyleView" parent="GtkWidget">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<style>
<class name="view"/>
</style>
<child>
<object class="GtkScrolledWindow" id="swin">
<property name="hscrollbar-policy">automatic</property>
<property name="vscrollbar-policy">automatic</property>
<child>
<object class="GtkLabel" id="content">
<property name="label">Content</property>
<property name="wrap">0</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="content"/>
</style>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -1,401 +0,0 @@
#include "waterfallview.h"
#include <gtk/gtk.h>
#include <hb-ot.h>
#include "glyphitem.h"
#include "glyphmodel.h"
#include "glyphview.h"
enum {
PROP_FONT_MAP = 1,
PROP_FONT_DESC,
PROP_SIZE,
PROP_LETTERSPACING,
PROP_LINE_HEIGHT,
PROP_FOREGROUND,
PROP_BACKGROUND,
PROP_VARIATIONS,
PROP_FEATURES,
PROP_PALETTE,
PROP_SAMPLE_TEXT,
NUM_PROPERTIES
};
static GParamSpec *properties[NUM_PROPERTIES] = { NULL, };
struct _WaterfallView
{
GtkWidget parent;
GtkLabel *content;
GtkScrolledWindow *swin;
Pango2FontMap *font_map;
Pango2FontDescription *font_desc;
float size;
char *variations;
char *features;
char *palette;
GQuark palette_quark;
int letterspacing;
float line_height;
GdkRGBA foreground;
GdkRGBA background;
GtkCssProvider *bg_provider;
char *sample_text;
};
struct _WaterfallViewClass
{
GtkWidgetClass parent_class;
};
G_DEFINE_TYPE(WaterfallView, waterfall_view, GTK_TYPE_WIDGET);
static void
waterfall_view_init (WaterfallView *self)
{
self->font_map = g_object_ref (pango2_font_map_get_default ());
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->palette_quark = g_quark_from_string (self->palette);
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
waterfall_view_dispose (GObject *object)
{
gtk_widget_clear_template (GTK_WIDGET (object), WATERFALL_VIEW_TYPE);
G_OBJECT_CLASS (waterfall_view_parent_class)->dispose (object);
}
static void
waterfall_view_finalize (GObject *object)
{
WaterfallView *self = WATERFALL_VIEW (object);
g_clear_object (&self->font_map);
pango2_font_description_free (self->font_desc);
g_free (self->variations);
g_free (self->features);
g_free (self->palette);
G_OBJECT_CLASS (waterfall_view_parent_class)->finalize (object);
}
static void
update_view (WaterfallView *self)
{
Pango2FontDescription *desc;
Pango2AttrList *attrs;
char *fg, *bg, *css;
GString *str;
int sizes[] = { 7, 8, 9, 10, 12, 14, 16, 20, 24, 30, 40, 50, 60, 70, 90, 120 };
int start, end, text_len;
Pango2TabArray *tabs;
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_line_height_new (self->line_height));
pango2_attr_list_insert (attrs, pango2_attr_letter_spacing_new (self->letterspacing));
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);
tabs = pango2_tab_array_new (2, PANGO2_TAB_POSITIONS_SPACES);
pango2_tab_array_set_tab (tabs, 0, PANGO2_TAB_RIGHT, 5);
pango2_tab_array_set_tab (tabs, 1, PANGO2_TAB_LEFT, 8);
gtk_label_set_tabs (self->content, tabs);
pango2_tab_array_free (tabs);
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_printf (str, "\t%d\t", sizes[i]);
end = str->len;
attr = pango2_attr_family_new ("Cantarell");
pango2_attribute_set_range (attr, start, end);
pango2_attr_list_insert (attrs, attr);
attr = pango2_attr_weight_new (PANGO2_WEIGHT_NORMAL);
pango2_attribute_set_range (attr, start, end);
pango2_attr_list_insert (attrs, attr);
attr = pango2_attr_style_new (PANGO2_STYLE_NORMAL);
pango2_attribute_set_range (attr, start, end);
pango2_attr_list_insert (attrs, attr);
attr = pango2_attr_size_new (12 * PANGO2_SCALE);
pango2_attribute_set_range (attr, start, end);
pango2_attr_list_insert (attrs, attr);
attr = pango2_attr_font_features_new ("tnum=1");
pango2_attribute_set_range (attr, start, end);
pango2_attr_list_insert (attrs, attr);
attr = pango2_attr_letter_spacing_new (0);
pango2_attribute_set_range (attr, start, end);
pango2_attr_list_insert (attrs, attr);
start = end;
g_string_append (str, self->sample_text);
g_string_append (str, ""); /* Unicode line separator */
end = start + text_len + strlen ("");
attr = pango2_attr_size_new (sizes[i] * PANGO2_SCALE);
pango2_attribute_set_range (attr, start, end);
pango2_attr_list_insert (attrs, attr);
start = end;
}
gtk_label_set_text (self->content, str->str);
gtk_label_set_attributes (self->content, attrs);
g_string_free (str, TRUE);
pango2_attr_list_unref (attrs);
fg = gdk_rgba_to_string (&self->foreground);
bg = gdk_rgba_to_string (&self->background);
css = g_strdup_printf (".content { 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
waterfall_view_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
WaterfallView *self = WATERFALL_VIEW (object);
switch (prop_id)
{
case PROP_FONT_MAP:
g_set_object (&self->font_map, g_value_get_object (value));
gtk_widget_set_font_map (GTK_WIDGET (self->content), self->font_map);
break;
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));
self->palette_quark = g_quark_from_string (self->palette);
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
waterfall_view_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
WaterfallView *self = WATERFALL_VIEW (object);
switch (prop_id)
{
case PROP_FONT_MAP:
g_value_set_object (value, self->font_map);
break;
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;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
waterfall_view_class_init (WaterfallViewClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = waterfall_view_dispose;
object_class->finalize = waterfall_view_finalize;
object_class->get_property = waterfall_view_get_property;
object_class->set_property = waterfall_view_set_property;
properties[PROP_FONT_MAP] =
g_param_spec_object ("font-map", "", "",
PANGO2_TYPE_FONT_MAP,
G_PARAM_READWRITE);
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);
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/waterfallview.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), WaterfallView, swin);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class), WaterfallView, content);
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), "waterfallview");
}

View File

@@ -1,14 +0,0 @@
#pragma once
#include <gtk/gtk.h>
#define WATERFALL_VIEW_TYPE (waterfall_view_get_type ())
#define WATERFALL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), WATERFALL_VIEW_TYPE, WaterfallView))
typedef struct _WaterfallView WaterfallView;
typedef struct _WaterfallViewClass WaterfallViewClass;
GType waterfall_view_get_type (void);

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="WaterfallView" parent="GtkWidget">
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<style>
<class name="view"/>
</style>
<child>
<object class="GtkScrolledWindow" id="swin">
<property name="hscrollbar-policy">automatic</property>
<property name="vscrollbar-policy">automatic</property>
<child>
<object class="GtkLabel" id="content">
<property name="label">Content</property>
<property name="wrap">0</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="content"/>
</style>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@@ -341,13 +341,16 @@ do_clipboard (GtkWidget *do_widget)
GtkWidget *button;
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback (scope, copy_button_clicked);
gtk_builder_cscope_add_callback (scope, paste_button_clicked);
gtk_builder_cscope_add_callback (scope, source_changed_cb);
gtk_builder_cscope_add_callback (scope, text_changed_cb);
gtk_builder_cscope_add_callback (scope, open_file_cb);
gtk_builder_cscope_add_callback (scope, on_drop);
gtk_builder_cscope_add_callback (scope, drag_prepare);
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
"copy_button_clicked", G_CALLBACK (copy_button_clicked),
"paste_button_clicked", G_CALLBACK (paste_button_clicked),
"source_changed_cb", G_CALLBACK (source_changed_cb),
"text_changed_cb", G_CALLBACK (text_changed_cb),
"open_file_cb", G_CALLBACK (open_file_cb),
"on_drop", G_CALLBACK (on_drop),
"drag_prepare", G_CALLBACK (drag_prepare),
NULL);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
gtk_builder_add_from_resource (builder, "/clipboard/clipboard.ui", NULL);

View File

@@ -260,13 +260,12 @@ mask_entry_set_background (MaskEntry *entry)
{
if (!g_regex_match_simple (entry->mask, gtk_editable_get_text (GTK_EDITABLE (entry)), 0, 0))
{
Pango2AttrList *attrs;
Pango2Color color = { 65535, 32767, 32767, 65535 };
PangoAttrList *attrs;
attrs = pango2_attr_list_new ();
pango2_attr_list_insert (attrs, pango2_attr_foreground_new (&color));
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_foreground_new (65535, 32767, 32767));
gtk_entry_set_attributes (GTK_ENTRY (entry), attrs);
pango2_attr_list_unref (attrs);
pango_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", PANGO2_LINE_STYLE_SOLID,
"underline", PANGO_UNDERLINE_SINGLE,
NULL);
gtk_text_buffer_create_tag (text,
"error",
"underline", PANGO2_LINE_STYLE_DOTTED,
"underline", PANGO_UNDERLINE_ERROR,
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", PANGO2_LINE_STYLE_SOLID,
"underline", PANGO_UNDERLINE_SINGLE,
NULL);
gtk_text_buffer_create_tag (text,
"error",
"underline", PANGO2_LINE_STYLE_DOTTED,
"underline", PANGO_UNDERLINE_ERROR,
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", PANGO2_LINE_STYLE_SOLID,
"underline", PANGO_UNDERLINE_SINGLE,
NULL);
gtk_text_buffer_create_tag (text,
"error",
"underline", PANGO2_LINE_STYLE_DOTTED,
"underline", PANGO_UNDERLINE_ERROR,
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", PANGO2_LINE_STYLE_SOLID,
"underline", PANGO_UNDERLINE_SINGLE,
NULL);
gtk_text_buffer_create_tag (text,
"error",
"underline", PANGO2_LINE_STYLE_DOTTED,
"underline", PANGO_UNDERLINE_ERROR,
NULL);
provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());

View File

@@ -329,7 +329,6 @@
<file>pickers.c</file>
<file>printing.c</file>
<file>revealer.c</file>
<file>read_more.c</file>
<file>rotated_text.c</file>
<file>scale.c</file>
<file>search_entry.c</file>
@@ -376,7 +375,7 @@
<file>glarea-gles.vs.glsl</file>
</gresource>
<gresource prefix="/font_features">
<file>font_features.ui</file>
<file>font-features.ui</file>
<file>fontplane.c</file>
</gresource>
<gresource prefix="/spinbutton">

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 (pango2_font_family_get_name (PANGO2_FONT_FAMILY (item)));
return g_strdup (pango_font_family_get_name (PANGO_FONT_FAMILY (item)));
}
static char *
@@ -326,8 +326,8 @@ bind_highlight_item (GtkSignalListItemFactory *factory,
{
MatchObject *obj;
GtkWidget *label;
Pango2AttrList *attrs;
Pango2Attribute *attr;
PangoAttrList *attrs;
PangoAttribute *attr;
const char *str;
obj = MATCH_OBJECT (gtk_list_item_get_item (item));
@@ -336,14 +336,13 @@ bind_highlight_item (GtkSignalListItemFactory *factory,
str = match_object_get_string (obj);
gtk_label_set_label (GTK_LABEL (label), str);
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);
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);
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango2_attr_list_unref (attrs);
pango_attr_list_unref (attrs);
}
static void
@@ -435,7 +434,7 @@ do_dropdown (GtkWidget *do_widget)
button = gtk_drop_down_new (NULL, NULL);
model = G_LIST_MODEL (pango2_font_map_get_default ());
model = G_LIST_MODEL (pango_cairo_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

@@ -90,9 +90,12 @@ do_errorstates (GtkWidget *do_widget)
toplevel = GTK_WIDGET (gtk_widget_get_root (do_widget));
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback (scope, validate_more_details);
gtk_builder_cscope_add_callback (scope, mode_switch_state_set);
gtk_builder_cscope_add_callback (scope, level_scale_value_changed);
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
"validate_more_details", G_CALLBACK (validate_more_details),
"mode_switch_state_set", G_CALLBACK (mode_switch_state_set),
"level_scale_value_changed", G_CALLBACK (level_scale_value_changed),
NULL);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);
gtk_builder_expose_object (builder, "toplevel", G_OBJECT (toplevel));

View File

@@ -0,0 +1,190 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" id="window">
<property name="default-width">600</property>
<property name="default-height">500</property>
<property name="title">Font Explorer</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>
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<child>
<object class="GtkViewport">
<child>
<object class="GtkBox">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkFontButton" id="font">
<property name="receives-default">1</property>
<property name="font">Sans 12</property>
<property name="level">family|style|size|variations|features</property>
<signal name="font-set" handler="font_features_font_changed" swapped="no"/>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="label" translatable="yes">Font Features</property>
<attributes>
<attribute name="weight" value="bold"></attribute>
</attributes>
</object>
</child>
<child>
<object class="GtkBox" id="feature_list">
<property name="orientation">vertical</property>
<child>
<object class="GtkComboBox" id="script_lang">
<property name="margin-top">10</property>
<signal name="changed" handler="font_features_script_changed" swapped="no"/>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel" id="variations_heading">
<property name="label" translatable="yes">Font Variations</property>
<property name="xalign">0</property>
<attributes>
<attribute name="weight" value="bold"></attribute>
</attributes>
</object>
</child>
<child>
<object class="GtkGrid" id="variations_grid">
<property name="column-spacing">10</property>
<property name="row-spacing">10</property>
</object>
</child>
</object>
</child>
</object>
</child>
<style>
<class name="view"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
<property name="margin-top">20</property>
<property name="margin-bottom">20</property>
<property name="spacing">20</property>
<child>
<object class="GtkStack" id="stack">
<child>
<object class="GtkStackPage">
<property name="name">label</property>
<property name="child">
<object class="GtkLabel" id="label">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="valign">start</property>
<property name="selectable">1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">entry</property>
<property name="child">
<object class="GtkEntry" id="entry">
<property name="text">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.
Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
<signal name="activate" handler="font_features_stop_edit"/>
<property name="valign">start</property>
<property name="width-chars">50</property>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkLabel" id="settings">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="width-chars">50</property>
<property name="max-width-chars">50</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<style>
<class name="monospace"/>
</style>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkLabel" id="description">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="width-chars">50</property>
<property name="max-width-chars">50</property>
<property name="hexpand">1</property>
<style>
<class name="monospace"/>
</style>
</object>
</child>
<child>
<object class="GtkToggleButton" id="edit_toggle">
<property name="icon-name">document-edit-symbolic</property>
<property name="halign">end</property>
<property name="valign">end</property>
<signal name="toggled" handler="font_features_toggle_edit"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

File diff suppressed because it is too large Load Diff

View File

@@ -1,65 +0,0 @@
--- demos/gtk-demo/font_features.c
+++ demos/gtk-demo/font_features.c
@@ -434,7 +434,7 @@ static void
update_display (void)
{
GString *s;
- const char *text;
+ char *text;
gboolean has_feature;
GtkTreeIter iter;
GtkTreeModel *model;
@@ -452,8 +452,12 @@ update_display (void)
gboolean do_waterfall;
GString *waterfall;
char *palette;
+ GtkTextBuffer *buffer;
+ GtkTextIter start_iter, end_iter;
- text = gtk_editable_get_text (GTK_EDITABLE (demo->the_entry));
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry));
+ gtk_text_buffer_get_bounds (buffer, &start_iter, &end_iter);
+ text = gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, FALSE);
text_len = strlen (text);
do_waterfall = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (demo->waterfall_toggle));
@@ -631,6 +635,8 @@ update_display (void)
pango2_font_description_free (desc);
g_free (features);
pango2_attr_list_unref (attrs);
+
+ g_free (text);
}
static Pango2Font *
@@ -1603,8 +1609,12 @@ font_features_toggle_edit (void)
{
if (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (demo->stack)), "entry") != 0)
{
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
g_free (demo->text);
- demo->text = g_strdup (gtk_editable_get_text (GTK_EDITABLE (demo->the_entry)));
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry));
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
+ demo->text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
gtk_stack_set_visible_child_name (GTK_STACK (demo->stack), "entry");
gtk_widget_grab_focus (demo->the_entry);
gtk_adjustment_set_value (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (demo->swin)), 0);
@@ -1632,7 +1642,7 @@ entry_key_press (GtkEventController *controller,
{
if (keyval == GDK_KEY_Escape)
{
- gtk_editable_set_text (GTK_EDITABLE (entry), demo->text);
+ gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (demo->the_entry)), demo->text, -1);
return GDK_EVENT_STOP;
}
@@ -1701,7 +1711,6 @@ do_font_features (GtkWidget *do_widget)
basic_value_changed (demo->line_height_adjustment, demo->line_height_entry);
controller = gtk_event_controller_key_new ();
- g_object_set_data_full (G_OBJECT (demo->the_entry), "controller", g_object_ref (controller), g_object_unref);
g_signal_connect (controller, "key-pressed", G_CALLBACK (entry_key_press), demo->the_entry);
gtk_widget_add_controller (demo->the_entry, controller);

View File

@@ -1,476 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<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="basic_value_changed" object="size_entry" swapped="false"/>
</object>
<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="basic_value_changed" object="letterspacing_entry" swapped="false"/>
</object>
<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="basic_value_changed" object="line_height_entry" swapped="false"/>
</object>
<object class="GtkWindow" id="window">
<property name="default-width">600</property>
<property name="default-height">500</property>
<property name="title">Font Explorer</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>
<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>
</child>
<child>
<object class="GtkBox">
<child>
<object class="GtkScrolledWindow">
<property name="hscrollbar-policy">never</property>
<child>
<object class="GtkViewport">
<child>
<object class="GtkBox">
<property name="margin-start">10</property>
<property name="margin-end">10</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkFontButton" id="font">
<property name="receives-default">1</property>
<property name="font">Sans 12</property>
<property name="level">family|style</property>
<signal name="font-set" handler="font_features_font_changed" swapped="no"/>
</object>
</child>
<child>
<object class="GtkGrid">
<property name="column-spacing">10</property>
<property name="row-spacing">10</property>
<child>
<object class="GtkLabel">
<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="GtkScale" id="size_scale">
<property name="hexpand">1</property>
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">size_adjustment</property>
<layout>
<property name="column">1</property>
<property name="row">0</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="size_entry">
<property name="width-chars">4</property>
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<signal name="activate" handler="basic_entry_activated"
object="size_adjustment" swapped="false"/>
<layout>
<property name="column">2</property>
<property name="row">0</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="GtkScale">
<property name="hexpand">1</property>
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">letterspacing_adjustment</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="letterspacing_entry">
<property name="width-chars">4</property>
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<signal name="activate" handler="basic_entry_activated"
object="letterspacing_adjustment" swapped="false"/>
<layout>
<property name="column">2</property>
<property name="row">1</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="GtkScale">
<property name="hexpand">1</property>
<property name="width-request">100</property>
<property name="valign">baseline</property>
<property name="adjustment">line_height_adjustment</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
</layout>
</object>
</child>
<child>
<object class="GtkEntry" id="line_height_entry">
<property name="width-chars">4</property>
<property name="max-width-chars">4</property>
<property name="hexpand">0</property>
<property name="valign">baseline</property>
<signal name="activate" handler="basic_entry_activated"
object="line_height_adjustment" swapped="false"/>
<layout>
<property name="column">2</property>
<property name="row">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="valign">baseline</property>
<property name="rgba">black</property>
<signal name="notify::rgba" handler="color_set_cb"/>
<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="valign">baseline</property>
<property name="rgba">white</property>
<signal name="notify::rgba" handler="color_set_cb"/>
<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>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel">
<property name="xalign">0</property>
<property name="label" translatable="yes">OpenType Features</property>
<property name="margin-top">10</property>
<property name="margin-bottom">10</property>
<style>
<class name="title-4"/>
</style>
</object>
</child>
<child>
<object class="GtkBox" id="feature_list">
<property name="orientation">vertical</property>
<child>
<object class="GtkComboBox" id="script_lang">
<property name="tooltip-text" translatable="yes">Language System</property>
<property name="margin-top">10</property>
<signal name="changed" handler="font_features_script_changed" swapped="no"/>
<child>
<object class="GtkCellRendererText"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkExpander">
<child type="label">
<object class="GtkLabel" id="variations_heading">
<property name="label" translatable="yes">Variation Axes</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="variations_grid">
<property name="column-spacing">10</property>
<property name="row-spacing">10</property>
</object>
</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>
<class name="view"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="hexpand">1</property>
<property name="vexpand">1</property>
<property name="margin-start">20</property>
<property name="margin-end">20</property>
<property name="margin-top">20</property>
<property name="margin-bottom">20</property>
<property name="spacing">20</property>
<child>
<object class="GtkScrolledWindow" id="swin">
<property name="hscrollbar-policy">automatic</property>
<property name="vscrollbar-policy">automatic</property>
<property name="propagate-natural-height">1</property>
<property name="vexpand">1</property>
<style>
<class name="font_features_background"/>
</style>
<child>
<object class="GtkStack" id="stack">
<child>
<object class="GtkStackPage">
<property name="name">label</property>
<property name="child">
<object class="GtkLabel" id="label">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="valign">start</property>
<property name="selectable">1</property>
</object>
</property>
</object>
</child>
<child>
<object class="GtkStackPage">
<property name="name">entry</property>
<property name="child">
<object class="GtkTextView" id="entry">
<property name="buffer">
<object class="GtkTextBuffer">
<property name="text">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.
Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
</object>
</property>
<property name="valign">fill</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkLabel" id="settings">
<property name="wrap">1</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="width-chars">50</property>
<property name="max-width-chars">50</property>
<property name="hexpand">1</property>
<style>
<class name="monospace"/>
</style>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Alphabet</property>
<signal name="clicked" handler="set_text_alphabet"/>
</object>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Paragraph</property>
<signal name="clicked" handler="set_text_paragraph"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="spacing">10</property>
<child>
<object class="GtkLabel" id="description">
<property name="wrap">1</property>
<property name="wrap-mode">char</property>
<property name="xalign">0</property>
<property name="valign">end</property>
<property name="width-chars">50</property>
<property name="max-width-chars">50</property>
<property name="hexpand">1</property>
<style>
<class name="monospace"/>
</style>
</object>
</child>
<child>
<object class="GtkBox">
<style>
<class name="linked"/>
</style>
<property name="valign">end</property>
<child>
<object class="GtkToggleButton" id="plain_toggle">
<property name="label" translatable="yes">Plain</property>
<property name="active">1</property>
<property name="valign">baseline</property>
<signal name="toggled" handler="font_features_toggle_plain"/>
</object>
</child>
<child>
<object class="GtkToggleButton" id="waterfall_toggle">
<property name="label" translatable="yes">Waterfall</property>
<property name="valign">baseline</property>
<property name="group">plain_toggle</property>
<signal name="toggled" handler="font_features_toggle_plain"/>
<signal name="notify::active" handler="font_features_notify_waterfall"/>
</object>
</child>
</object>
</child>
<child>
<object class="GtkToggleButton" id="edit_toggle">
<property name="group">waterfall_toggle</property>
<property name="icon-name">document-edit-symbolic</property>
<property name="halign">end</property>
<property name="valign">end</property>
<signal name="clicked" handler="font_features_toggle_edit"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -19,7 +19,7 @@
*/
static void
insert_tags_for_attributes (GtkTextBuffer *buffer,
Pango2AttrIterator *iter,
PangoAttrIterator *iter,
GtkTextIter *start,
GtkTextIter *end)
{
@@ -27,12 +27,13 @@ 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 = pango2_language_to_string (pango2_attribute_get_language (attr)); \
const char *language = pango_language_to_string (((PangoAttrLanguage*)attr)->value); \
g_snprintf (name, 256, "language=%s", language); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
@@ -47,7 +48,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
#define STRING_ATTR(attr_name) \
{ \
const char *string = pango2_attribute_get_string (attr); \
const char *string = ((PangoAttrString*)attr)->value; \
g_snprintf (name, 256, #attr_name "=%s", string); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
@@ -62,7 +63,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
#define INT_ATTR(attr_name) \
{ \
int value = pango2_attribute_get_int (attr); \
int value = ((PangoAttrInt*)attr)->value; \
g_snprintf (name, 256, #attr_name "=%d", value); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
@@ -77,8 +78,8 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
#define FONT_ATTR(attr_name) \
{ \
Pango2FontDescription *desc = pango2_attribute_get_font_desc (attr); \
char *str = pango2_font_description_to_string (desc); \
PangoFontDescription *desc = ((PangoAttrFontDesc*)attr)->desc; \
char *str = pango_font_description_to_string (desc); \
g_snprintf (name, 256, "font-desc=%s", str); \
g_free (str); \
tag = gtk_text_tag_table_lookup (table, name); \
@@ -94,7 +95,7 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
#define FLOAT_ATTR(attr_name) \
{ \
float value = pango2_attribute_get_float (attr); \
float value = ((PangoAttrFloat*)attr)->value; \
g_snprintf (name, 256, #attr_name "=%g", value); \
tag = gtk_text_tag_table_lookup (table, name); \
if (!tag) \
@@ -107,14 +108,15 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
#define RGBA_ATTR(attr_name) \
#define RGBA_ATTR(attr_name, alpha_value) \
{ \
Pango2Color *color = pango2_attribute_get_color (attr); \
PangoColor *color; \
GdkRGBA rgba; \
color = &((PangoAttrColor*)attr)->color; \
rgba.red = color->red / 65535.; \
rgba.green = color->green / 65535.; \
rgba.blue = color->blue / 65535.; \
rgba.alpha = color->alpha / 65535.; \
rgba.alpha = alpha_value; \
char *str = gdk_rgba_to_string (&rgba); \
g_snprintf (name, 256, #attr_name "=%s", str); \
g_free (str); \
@@ -142,157 +144,173 @@ insert_tags_for_attributes (GtkTextBuffer *buffer,
gtk_text_buffer_apply_tag (buffer, tag, start, end); \
}
attrs = pango2_attr_iterator_get_attrs (iter);
fg_alpha = bg_alpha = 1.;
attrs = pango_attr_iterator_get_attrs (iter);
for (l = attrs; l; l = l->next)
{
Pango2Attribute *attr = l->data;
PangoAttribute *attr = l->data;
switch (pango2_attribute_type (attr))
switch ((int)attr->klass->type)
{
case PANGO2_ATTR_LANGUAGE:
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:
LANGUAGE_ATTR (language);
break;
case PANGO2_ATTR_FAMILY:
case PANGO_ATTR_FAMILY:
STRING_ATTR (family);
break;
case PANGO2_ATTR_STYLE:
case PANGO_ATTR_STYLE:
INT_ATTR (style);
break;
case PANGO2_ATTR_WEIGHT:
case PANGO_ATTR_WEIGHT:
INT_ATTR (weight);
break;
case PANGO2_ATTR_VARIANT:
case PANGO_ATTR_VARIANT:
INT_ATTR (variant);
break;
case PANGO2_ATTR_STRETCH:
case PANGO_ATTR_STRETCH:
INT_ATTR (stretch);
break;
case PANGO2_ATTR_SIZE:
case PANGO_ATTR_SIZE:
INT_ATTR (size);
break;
case PANGO2_ATTR_FONT_DESC:
case PANGO_ATTR_FONT_DESC:
FONT_ATTR (font-desc);
break;
case PANGO2_ATTR_FOREGROUND:
RGBA_ATTR (foreground_rgba);
case PANGO_ATTR_FOREGROUND:
RGBA_ATTR (foreground_rgba, fg_alpha);
break;
case PANGO2_ATTR_BACKGROUND:
RGBA_ATTR (background_rgba);
case PANGO_ATTR_BACKGROUND:
RGBA_ATTR (background_rgba, bg_alpha);
break;
case PANGO2_ATTR_UNDERLINE:
case PANGO_ATTR_UNDERLINE:
INT_ATTR (underline);
break;
case PANGO2_ATTR_UNDERLINE_COLOR:
RGBA_ATTR (underline_rgba);
case PANGO_ATTR_UNDERLINE_COLOR:
RGBA_ATTR (underline_rgba, fg_alpha);
break;
case PANGO2_ATTR_OVERLINE:
case PANGO_ATTR_OVERLINE:
INT_ATTR (overline);
break;
case PANGO2_ATTR_OVERLINE_COLOR:
RGBA_ATTR (overline_rgba);
case PANGO_ATTR_OVERLINE_COLOR:
RGBA_ATTR (overline_rgba, fg_alpha);
break;
case PANGO2_ATTR_STRIKETHROUGH:
case PANGO_ATTR_STRIKETHROUGH:
INT_ATTR (strikethrough);
break;
case PANGO2_ATTR_STRIKETHROUGH_COLOR:
RGBA_ATTR (strikethrough_rgba);
case PANGO_ATTR_STRIKETHROUGH_COLOR:
RGBA_ATTR (strikethrough_rgba, fg_alpha);
break;
case PANGO2_ATTR_RISE:
case PANGO_ATTR_RISE:
INT_ATTR (rise);
break;
case PANGO2_ATTR_SCALE:
case PANGO_ATTR_SCALE:
FLOAT_ATTR (scale);
break;
case PANGO2_ATTR_FALLBACK:
case PANGO_ATTR_FALLBACK:
INT_ATTR (fallback);
break;
case PANGO2_ATTR_LETTER_SPACING:
case PANGO_ATTR_LETTER_SPACING:
INT_ATTR (letter_spacing);
break;
case PANGO2_ATTR_FONT_FEATURES:
case PANGO_ATTR_FONT_FEATURES:
STRING_ATTR (font_features);
break;
case PANGO2_ATTR_ALLOW_BREAKS:
case PANGO_ATTR_ALLOW_BREAKS:
INT_ATTR (allow_breaks);
break;
case PANGO2_ATTR_SHOW:
case PANGO_ATTR_SHOW:
INT_ATTR (show_spaces);
break;
case PANGO2_ATTR_INSERT_HYPHENS:
case PANGO_ATTR_INSERT_HYPHENS:
INT_ATTR (insert_hyphens);
break;
case PANGO2_ATTR_LINE_HEIGHT:
case PANGO_ATTR_LINE_HEIGHT:
FLOAT_ATTR (line_height);
break;
case PANGO2_ATTR_ABSOLUTE_LINE_HEIGHT:
case PANGO_ATTR_ABSOLUTE_LINE_HEIGHT:
break;
case PANGO2_ATTR_LINE_SPACING:
INT_ATTR (pixels_inside_wrap);
break;
case PANGO2_ATTR_WORD:
case PANGO_ATTR_WORD:
VOID_ATTR (word);
break;
case PANGO2_ATTR_SENTENCE:
case PANGO_ATTR_SENTENCE:
VOID_ATTR (sentence);
break;
case PANGO2_ATTR_PARAGRAPH:
VOID_ATTR (paragraph);
break;
case PANGO2_ATTR_BASELINE_SHIFT:
case PANGO_ATTR_BASELINE_SHIFT:
INT_ATTR (baseline_shift);
break;
case PANGO2_ATTR_FONT_SCALE:
case PANGO_ATTR_FONT_SCALE:
INT_ATTR (font_scale);
break;
case PANGO2_ATTR_ABSOLUTE_SIZE:
case PANGO2_ATTR_GRAVITY:
case PANGO2_ATTR_GRAVITY_HINT:
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:
break;
case PANGO2_ATTR_TEXT_TRANSFORM:
case PANGO_ATTR_TEXT_TRANSFORM:
INT_ATTR (text_transform);
break;
case PANGO2_ATTR_INVALID:
case PANGO_ATTR_INVALID:
default:
g_assert_not_reached ();
break;
}
}
g_slist_free_full (attrs, (GDestroyNotify)pango2_attribute_destroy);
g_slist_free_full (attrs, (GDestroyNotify)pango_attribute_destroy);
#undef LANGUAGE_ATTR
#undef STRING_ATTR
@@ -311,9 +329,9 @@ typedef struct
GtkTextBuffer *buffer;
GtkTextIter iter;
GtkTextMark *mark;
Pango2AttrList *attributes;
PangoAttrList *attributes;
char *text;
Pango2AttrIterator *attr;
PangoAttrIterator *attr;
} MarkupData;
static void
@@ -322,8 +340,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, pango2_attr_iterator_destroy);
g_clear_pointer (&mdata->attributes, pango2_attr_list_unref);
g_clear_pointer (&mdata->attr, pango_attr_iterator_destroy);
g_clear_pointer (&mdata->attributes, pango_attr_list_unref);
g_free (mdata->text);
g_object_unref (mdata->buffer);
g_free (mdata);
@@ -349,7 +367,7 @@ insert_markup_idle (gpointer data)
return G_SOURCE_REMOVE;
}
pango2_attr_iterator_range (mdata->attr, &start, &end);
pango_attr_iterator_range (mdata->attr, &start, &end);
if (end == G_MAXINT) /* last chunk */
end = start - 1; /* resulting in -1 to be passed to _insert */
@@ -362,7 +380,7 @@ insert_markup_idle (gpointer data)
gtk_text_buffer_get_iter_at_mark (mdata->buffer, &mdata->iter, mdata->mark);
}
while (pango2_attr_iterator_next (mdata->attr));
while (pango_attr_iterator_next (mdata->attr));
free_markup_data (mdata);
return G_SOURCE_REMOVE;
@@ -398,7 +416,7 @@ parse_markup_idle (gpointer data)
mdata->pos += 4096;
} while (mdata->pos < mdata->len);
if (!pango2_markup_parser_finish (mdata->parser,
if (!pango_markup_parser_finish (mdata->parser,
&mdata->attributes,
&mdata->text,
NULL,
@@ -417,7 +435,7 @@ parse_markup_idle (gpointer data)
return G_SOURCE_REMOVE;
}
mdata->attr = pango2_attr_list_get_iterator (mdata->attributes);
mdata->attr = pango_attr_list_get_iterator (mdata->attributes);
insert_markup_idle (data);
return G_SOURCE_REMOVE;
@@ -443,7 +461,7 @@ insert_markup (GtkTextBuffer *buffer,
data->markup = markup;
data->len = len;
data->parser = pango2_markup_parser_new (0);
data->parser = pango_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 Pango2Context *context;
static PangoContext *context;
static int scale = 7;
static double pixel_alpha = 1.0;
@@ -35,9 +35,9 @@ static void
update_image (void)
{
const char *text;
Pango2FontDescription *desc;
Pango2Layout *layout;
Pango2Rectangle ink, logical;
PangoFontDescription *desc;
PangoLayout *layout;
PangoRectangle 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 (pango2_cairo_context_get_font_options (context));
fopt = cairo_font_options_copy (pango_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);
pango2_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
pango2_cairo_context_set_font_options (context, fopt);
pango_context_set_round_glyph_positions (context, hintmetrics == CAIRO_HINT_METRICS_ON);
pango_cairo_context_set_font_options (context, fopt);
cairo_font_options_destroy (fopt);
pango2_context_changed (context);
pango_context_changed (context);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (text_radio)))
{
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));
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);
pango2_extents_to_pixels (&ink, NULL);
pango_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);
pango2_cairo_show_layout (cr, layout);
pango_cairo_show_layout (cr, layout);
pango2_cairo_layout_path (cr, layout);
pango_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 + 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);
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);
cairo_stroke (cr);
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_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_stroke (cr);
cairo_set_source_rgb (cr, 1, 0, 0);
cairo_rectangle (cr,
@@ -206,10 +206,9 @@ update_image (void)
}
else
{
Pango2LineIter *iter;
Pango2Run *run;
Pango2GlyphString *glyphs;
Pango2GlyphInfo *g;
PangoLayoutIter *iter;
PangoLayoutRun *run;
PangoGlyphInfo *g;
int i, j;
GString *str;
gunichar ch;
@@ -227,44 +226,43 @@ update_image (void)
g_string_append_unichar (str, 0x200c);
}
layout = pango2_layout_new (context);
pango2_layout_set_font_description (layout, desc);
pango2_layout_set_text (layout, str->str, -1);
layout = pango_layout_new (context);
pango_layout_set_font_description (layout, desc);
pango_layout_set_text (layout, str->str, -1);
g_string_free (str, TRUE);
pango2_lines_get_extents (pango2_layout_get_lines (layout), &ink, &logical);
pango2_extents_to_pixels (&logical, NULL);
pango_layout_get_extents (layout, &ink, &logical);
pango_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 = pango2_layout_get_iter (layout);
run = pango2_line_iter_get_run (iter);
glyphs = pango2_run_get_glyphs (run);
iter = pango_layout_get_iter (layout);
run = pango_layout_iter_get_run (iter);
cairo_set_source_rgb (cr, 0, 0, 0);
for (i = 0; i < 4; i++)
{
g = &(glyphs->glyphs[2*i]);
g->geometry.width = PANGO2_UNITS_ROUND (g->geometry.width * 3 / 2);
g = &(run->glyphs->glyphs[2*i]);
g->geometry.width = PANGO_UNITS_ROUND (g->geometry.width * 3 / 2);
}
for (j = 0; j < 4; j++)
{
for (i = 0; i < 4; i++)
{
g = &(glyphs->glyphs[2*i]);
g->geometry.x_offset = i * (PANGO2_SCALE / 4);
g->geometry.y_offset = j * (PANGO2_SCALE / 4);
g = &(run->glyphs->glyphs[2*i]);
g->geometry.x_offset = i * (PANGO_SCALE / 4);
g->geometry.y_offset = j * (PANGO_SCALE / 4);
}
cairo_move_to (cr, 0, j * logical.height);
pango2_cairo_show_layout (cr, layout);
pango_cairo_show_layout (cr, layout);
}
cairo_destroy (cr);
pango2_line_iter_free (iter);
pango_layout_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));
@@ -277,7 +275,7 @@ update_image (void)
g_object_unref (pixbuf2);
pango2_font_description_free (desc);
pango_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", PANGO2_LINE_STYLE_SOLID,
"underline", PANGO_UNDERLINE_SINGLE,
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", PANGO2_WEIGHT_BOLD,
"scale", PANGO2_SCALE_X_LARGE,
"weight", PANGO_WEIGHT_BOLD,
"scale", PANGO_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=\"solid\" underline_color=\"red\">x</span>");
g_string_append (s, "<span underline=\"single\" underline_color=\"red\">x</span>");
for (int j = 0; j < 30; j++)
{
g_string_append (s, "💓");
g_string_append (s, "<span underline=\"solid\" underline_color=\"red\">x</span>");
g_string_append (s, "<span underline=\"single\" 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;
Pango2Language *lang;
PangoLanguage *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 = pango2_language_from_string (locale);
lang = pango_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 = pango2_language_from_string (locale_abbrev);
lang = pango_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,
pango2_language_from_string (ccode),
pango_language_from_string (ccode),
g_strdup (display_name));
if (ccode_longB != NULL)
g_hash_table_insert (language_map,
pango2_language_from_string (ccode_longB),
pango_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),
pango_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),
pango_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 (Pango2Language *language)
get_language_name (PangoLanguage *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 (pango2_language_from_string (s));
return get_language_name (pango_language_from_string (s));
}

View File

@@ -1,11 +1,11 @@
#ifndef LANGUAGE_NAMES_H
#define LANGUAGE_NAMES_H
#include <pango2/pango.h>
#include <pango/pango.h>
G_BEGIN_DECLS
const char * get_language_name (Pango2Language *language);
const char * get_language_name (PangoLanguage *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), PANGO2_WRAP_WORD);
gtk_label_set_wrap_mode (GTK_LABEL (label), PANGO_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

@@ -42,7 +42,8 @@ do_listbox_controls (GtkWidget *do_widget)
GtkBuilder *builder;
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback (scope, row_activated);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope),
"row_activated", G_CALLBACK (row_activated));
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);

View File

@@ -758,15 +758,15 @@ setup_number_item (GtkSignalListItemFactory *factory,
GtkListItem *item)
{
GtkWidget *label;
Pango2AttrList *attrs;
PangoAttrList *attrs;
label = gtk_label_new ("");
gtk_label_set_xalign (GTK_LABEL (label), 1);
attrs = pango2_attr_list_new ();
pango2_attr_list_insert (attrs, pango2_attr_font_features_new ("tnum"));
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum"));
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango2_attr_list_unref (attrs);
pango_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;
Pango2AttrList *attrs;
PangoAttrList *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 = pango2_attr_list_new ();
pango2_attr_list_insert (attrs, pango2_attr_font_features_new ("tnum"));
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_font_features_new ("tnum"));
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango2_attr_list_unref (attrs);
pango_attr_list_unref (attrs);
string = g_strdup_printf ("%'u", 4096);
len = g_utf8_strlen (string, -1);
g_free (string);

View File

@@ -356,10 +356,10 @@ do_listview_settings (GtkWidget *do_widget)
g_type_ensure (SETTINGS_TYPE_KEY);
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback (scope, search_enabled);
gtk_builder_cscope_add_callback (scope, search_changed);
gtk_builder_cscope_add_callback (scope, stop_search);
gtk_builder_cscope_add_callback (scope, item_value_changed);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_enabled", (GCallback)search_enabled);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "search_changed", (GCallback)search_changed);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "stop_search", (GCallback)stop_search);
gtk_builder_cscope_add_callback_symbol (GTK_BUILDER_CSCOPE (scope), "item_value_changed", (GCallback)item_value_changed);
builder = gtk_builder_new ();
gtk_builder_set_scope (builder, scope);

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), PANGO2_ELLIPSIZE_END);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
gtk_label_set_width_chars (GTK_LABEL (label), 20);
gtk_list_item_set_child (GTK_LIST_ITEM (listitem), label);
}

View File

@@ -1,5 +1,5 @@
/* Lists/Words
* #Keywords: GtkListView, GtkFilterListModel, GtkInscription
* #Keywords: GtkListView, GtkFilterListModel
*
* This demo shows filtering a long list - of words.
*
@@ -17,9 +17,10 @@ const char *factory_text =
"<interface>\n"
" <template class='GtkListItem'>\n"
" <property name='child'>\n"
" <object class='GtkInscription'>\n"
" <object class='GtkLabel'>\n"
" <property name='ellipsize'>end</property>\n"
" <property name='xalign'>0</property>\n"
" <binding name='text'>\n"
" <binding name='label'>\n"
" <lookup name='string' type='GtkStringObject'>\n"
" <lookup name='item'>GtkListItem</lookup>\n"
" </lookup>\n"

View File

@@ -7,9 +7,9 @@
<lookup name="item">GtkListItem</lookup>
</binding>
<property name="child">
<object class="GtkInscription">
<property name="hexpand">1</property>
<binding name="text">
<object class="GtkLabel">
<property name="halign">start</property>
<binding name="label">
<lookup name="title" type="GtkDemo">
<lookup name="item">expander</lookup>
</lookup>

View File

@@ -190,8 +190,8 @@ activate_about (GSimpleAction *action,
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, "\tPango\t%s\n",
pango_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_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 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 strikethrough="solid" strikethrough-color="magenta">strikethroughs</span> and <span overline="solid" overline_color="green">overlines</span>
Colorful <span strikethrough="true" strikethrough-color="magenta">strikethroughs</span> and <span overline="single" 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>
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.
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

@@ -73,9 +73,8 @@ demos = files([
'peg_solitaire.c',
'pickers.c',
'printing.c',
'read_more.c',
'revealer.c',
#'rotated_text.c', FIXME
'rotated_text.c',
'scale.c',
'search_entry.c',
'search_entry2.c',

View File

@@ -2,7 +2,7 @@
* #Keywords: GtkColorChooser, GtkFontChooser, GtkApplicationChooser
*
* These widgets are mainly intended for use in preference dialogs.
* They allow to select colors, fonts and applications.
* They allow to select colors, fonts, directories and applications.
*
* This demo shows both the default appearance for these dialogs,
* as well as some of the customizations that are possible.
@@ -11,8 +11,8 @@
#include <gtk/gtk.h>
static gboolean
filter_font_cb (const Pango2FontFamily *family,
const Pango2FontFace *face,
filter_font_cb (const PangoFontFamily *family,
const PangoFontFace *face,
gpointer data)
{
const char *alias_families[] = {
@@ -26,15 +26,9 @@ filter_font_cb (const Pango2FontFamily *family,
};
const char *family_name;
family_name = pango2_font_family_get_name ((Pango2FontFamily *)family);
family_name = pango_font_family_get_name (PANGO_FONT_FAMILY (family));
for (int i = 0; alias_families[i]; i++)
{
if (g_ascii_strcasecmp (alias_families[i], family_name) == 0)
return TRUE;
}
return FALSE;
return g_strv_contains (alias_families, family_name);
}
#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;
Pango2Layout *layout;
Pango2Rectangle ext;
PangoLayout *layout;
int text_width, text_height;
double width;
int line, i;
Pango2FontDescription *desc;
PangoFontDescription *desc;
char *page_str;
cr = gtk_print_context_get_cairo_context (context);
@@ -80,50 +80,47 @@ draw_page (GtkPrintOperation *operation,
layout = gtk_print_context_create_pango_layout (context);
desc = pango2_font_description_from_string ("sans 14");
pango2_layout_set_font_description (layout, desc);
pango2_font_description_free (desc);
desc = pango_font_description_from_string ("sans 14");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
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);
pango_layout_set_text (layout, data->resourcename, -1);
pango_layout_get_pixel_size (layout, &text_width, &text_height);
if (ext.width > width)
if (text_width > width)
{
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);
pango_layout_set_width (layout, width);
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_START);
pango_layout_get_pixel_size (layout, &text_width, &text_height);
}
cairo_move_to (cr, (width - ext.width) / 2, (HEADER_HEIGHT - ext.height) / 2);
pango2_cairo_show_layout (cr, layout);
cairo_move_to (cr, (width - text_width) / 2, (HEADER_HEIGHT - text_height) / 2);
pango_cairo_show_layout (cr, layout);
page_str = g_strdup_printf ("%d/%d", page_nr + 1, data->num_pages);
pango2_layout_set_text (layout, page_str, -1);
pango_layout_set_text (layout, page_str, -1);
g_free (page_str);
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);
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);
g_object_unref (layout);
layout = gtk_print_context_create_pango_layout (context);
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);
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);
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++)
{
pango2_layout_set_text (layout, data->lines[line], -1);
pango2_cairo_show_layout (cr, layout);
pango_layout_set_text (layout, data->lines[line], -1);
pango_cairo_show_layout (cr, layout);
cairo_rel_move_to (cr, 0, data->font_size);
line++;
}

View File

@@ -1,239 +0,0 @@
/* Read More
* #Keywords: GtkInscription
*
* A simple implementation of a widget that can either
* display a lot of text or just the first few lines with a
* "Read More" button.
*/
#include <gtk/gtk.h>
#define READ_TYPE_MORE (read_more_get_type ())
G_DECLARE_FINAL_TYPE(ReadMore, read_more, READ, MORE, GtkWidget)
struct _ReadMore {
GtkWidget parent_instance;
GtkWidget *label;
GtkWidget *inscription;
GtkWidget *box;
gboolean show_more;
};
G_DEFINE_TYPE (ReadMore, read_more, GTK_TYPE_WIDGET)
static GtkSizeRequestMode
read_more_get_request_mode (GtkWidget *widget)
{
return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
}
static void
read_more_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
ReadMore *self = READ_MORE (widget);
int label_min, label_nat, label_min_baseline, label_nat_baseline;
int box_min, box_nat, box_min_baseline, box_nat_baseline;
int min_check;
if (self->show_more)
min_check = G_MAXINT;
else if (for_size >= 0)
gtk_widget_measure (self->box, 1 - orientation, -1, &min_check, NULL, NULL, NULL);
else
min_check = -1;
if (min_check > for_size)
{
gtk_widget_measure (self->label,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
return;
}
else if (for_size >= 0)
gtk_widget_measure (self->label, 1 - orientation, -1, &min_check, NULL, NULL, NULL);
else
min_check = -1;
if (min_check > for_size)
{
gtk_widget_measure (self->box,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
return;
}
gtk_widget_measure (self->label,
orientation,
for_size,
&label_min, &label_nat,
&label_min_baseline, &label_nat_baseline);
gtk_widget_measure (self->box,
orientation,
for_size,
&box_min, &box_nat,
&box_min_baseline, &box_nat_baseline);
*minimum = MIN (label_min, box_min);
*natural = MIN (label_nat, box_nat);
/* FIXME: Figure out baselines! */
}
static void
read_more_allocate (GtkWidget *widget,
int width,
int height,
int baseline)
{
ReadMore *self = READ_MORE (widget);
gboolean show_more;
if (self->show_more)
{
show_more = TRUE;
}
else
{
int needed;
/* check to see if we have enough space to show all text */
gtk_widget_measure (self->label,
GTK_ORIENTATION_VERTICAL,
width,
&needed, NULL, NULL, NULL);
show_more = needed <= height;
}
gtk_widget_set_child_visible (self->label, show_more);
gtk_widget_set_child_visible (self->box, !show_more);
if (show_more)
gtk_widget_size_allocate (self->label, &(GtkAllocation) { 0, 0, width, height }, baseline);
else
gtk_widget_size_allocate (self->box, &(GtkAllocation) { 0, 0, width, height }, baseline);
}
static void
read_more_dispose (GObject *object)
{
ReadMore *self = READ_MORE (object);
g_clear_pointer (&self->label, gtk_widget_unparent);
g_clear_pointer (&self->box, gtk_widget_unparent);
G_OBJECT_CLASS (read_more_parent_class)->dispose (object);
}
static void
read_more_class_init (ReadMoreClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
widget_class->get_request_mode = read_more_get_request_mode;
widget_class->measure = read_more_measure;
widget_class->size_allocate = read_more_allocate;
object_class->dispose = read_more_dispose;
}
static void
read_more_clicked (GtkButton *button,
ReadMore *self)
{
self->show_more = TRUE;
gtk_widget_queue_resize (GTK_WIDGET (self));
}
static void
read_more_init (ReadMore *self)
{
GtkWidget *button;
self->label = gtk_label_new (NULL);
gtk_label_set_xalign (GTK_LABEL (self->label), 0.0);
gtk_label_set_yalign (GTK_LABEL (self->label), 0.0);
gtk_label_set_wrap (GTK_LABEL (self->label), TRUE);
gtk_label_set_width_chars (GTK_LABEL (self->label), 3);
gtk_label_set_max_width_chars (GTK_LABEL (self->label), 30);
gtk_widget_set_parent (self->label, GTK_WIDGET (self));
self->box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_widget_set_vexpand (self->box, FALSE);
gtk_widget_set_parent (self->box, GTK_WIDGET (self));
self->inscription = gtk_inscription_new (NULL);
gtk_inscription_set_xalign (GTK_INSCRIPTION (self->inscription), 0.0);
gtk_inscription_set_yalign (GTK_INSCRIPTION (self->inscription), 0.0);
gtk_inscription_set_min_lines (GTK_INSCRIPTION (self->inscription), 3);
gtk_inscription_set_nat_chars (GTK_INSCRIPTION (self->inscription), 30);
gtk_widget_set_vexpand (self->inscription, TRUE);
gtk_box_append (GTK_BOX (self->box), self->inscription);
button = gtk_button_new_with_label ("Read More");
g_signal_connect (button, "clicked", G_CALLBACK (read_more_clicked), self);
gtk_box_append (GTK_BOX (self->box), button);
}
static void
read_more_set_text (ReadMore *self,
const char *text)
{
gtk_label_set_label (GTK_LABEL (self->label), text);
gtk_inscription_set_text (GTK_INSCRIPTION (self->inscription), text);
}
static GtkWidget *
read_more_new (const char *text)
{
ReadMore *self = g_object_new (READ_TYPE_MORE, NULL);
read_more_set_text (self, text);
return GTK_WIDGET (self);
}
GtkWidget *
do_read_more (GtkWidget *do_widget)
{
static GtkWidget *window = NULL;
if (!window)
{
GtkWidget *readmore;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
gtk_widget_get_display (do_widget));
gtk_window_set_title (GTK_WINDOW (window), "Read More");
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
readmore = read_more_new (
"I'd just like to interject for a moment. What you're referring to as Linux, is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX.\n"
"\n"
"Many computer users run a modified version of the GNU system every day, without realizing it. Through a peculiar turn of events, the version of GNU which is widely used today is often called \"Linux\", and many of its users are not aware that it is basically the GNU system, developed by the GNU Project.\n"
"\n"
"There really is a Linux, and these people are using it, but it is just a part of the system they use. Linux is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called \"Linux\" distributions are really distributions of GNU/Linux.");
gtk_window_set_child (GTK_WINDOW (window), readmore);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}

View File

@@ -1,9 +1,9 @@
/* Pango2/Rotated Text
/* Pango/Rotated Text
*
* This demo shows how to use Pango2Cairo to draw rotated and transformed
* This demo shows how to use PangoCairo to draw rotated and transformed
* text. The right pane shows a rotated GtkLabel widget.
*
* In both cases, a custom Pango2Cairo shape renderer is installed to draw
* In both cases, a custom PangoCairo shape renderer is installed to draw
* a red heart using cairo drawing operations instead of the Unicode heart
* character.
*/
@@ -14,118 +14,75 @@
#define HEART "♥"
const char text[] = "I ♥ GTK";
static gboolean
glyph_cb (Pango2UserFace *face,
hb_codepoint_t unicode,
hb_codepoint_t *glyph,
gpointer data)
static void
fancy_shape_renderer (cairo_t *cr,
PangoAttrShape *attr,
gboolean do_path,
gpointer data)
{
if (unicode == 0x2665)
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 */
{
*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;
}
return FALSE;
if (!do_path)
{
cairo_set_source_rgb (cr, 1., 0., 0.);
cairo_fill (cr);
}
}
static void
setup_fontmap (void)
static PangoAttrList *
create_fancy_attr_list_for_layout (PangoLayout *layout)
{
Pango2FontMap *fontmap = pango2_font_map_get_default ();
Pango2FontDescription *desc;
Pango2UserFace *face;
PangoAttrList *attrs;
PangoFontMetrics *metrics;
int ascent;
PangoRectangle ink_rect, logical_rect;
const char *p;
desc = pango2_font_description_new ();
pango2_font_description_set_family (desc, "Bullets");
/* 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);
/* 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);
/* Set fancy shape attributes for all hearts */
attrs = pango_attr_list_new ();
for (p = text; (p = strstr (p, HEART)); p += strlen (HEART))
{
PangoAttribute *attr;
/* And add it to the default fontmap */
pango2_font_map_add_face (fontmap, PANGO2_FONT_FACE (face));
attr = pango_attr_shape_new_with_data (&ink_rect,
&logical_rect,
GUINT_TO_POINTER (g_utf8_get_char (p)),
NULL, NULL);
pango2_font_description_free (desc);
attr->start_index = p - text;
attr->end_index = attr->start_index + strlen (HEART);
pango_attr_list_insert (attrs, attr);
}
return attrs;
}
static void
@@ -137,12 +94,16 @@ rotated_text_draw (GtkDrawingArea *da,
{
#define RADIUS 150
#define N_WORDS 5
#define FONT "Bullets 18"
#define FONT "Serif 18"
PangoContext *context;
PangoLayout *layout;
PangoFontDescription *desc;
Pango2Context *context;
Pango2Layout *layout;
Pango2FontDescription *desc;
cairo_pattern_t *pattern;
PangoAttrList *attrs;
double device_radius;
int i;
@@ -162,34 +123,40 @@ rotated_text_draw (GtkDrawingArea *da,
cairo_pattern_add_color_stop_rgb (pattern, 1., .0, .0, .5);
cairo_set_source (cr, pattern);
/* Create a Pango2Context and set up our shape renderer */
/* Create a PangoContext 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 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);
/* 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);
/* Draw the layout N_WORDS times in a circle */
for (i = 0; i < N_WORDS; i++)
{
Pango2Rectangle ext;
int layout_width, layout_height;
/* Inform Pango2 to re-layout the text with the new transformation matrix */
pango2_cairo_update_layout (cr, layout);
/* Inform Pango to re-layout the text with the new transformation matrix */
pango_cairo_update_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);
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);
/* Rotate for the next turn */
cairo_rotate (cr, G_PI*2 / N_WORDS);
}
/* free the objects we created */
pango2_font_description_free (desc);
pango_font_description_free (desc);
g_object_unref (layout);
g_object_unref (context);
cairo_pattern_destroy (pattern);
@@ -205,10 +172,8 @@ do_rotated_text (GtkWidget *do_widget)
GtkWidget *box;
GtkWidget *drawing_area;
GtkWidget *label;
Pango2Attribute *attr;
Pango2AttrList *attrs;
setup_fontmap ();
PangoLayout *layout;
PangoAttrList *attrs;
window = gtk_window_new ();
gtk_window_set_display (GTK_WINDOW (window),
@@ -232,12 +197,16 @@ do_rotated_text (GtkWidget *do_widget)
/* And a label */
label = gtk_label_new (text);
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);
pango2_attr_list_unref (attrs);
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);
gtk_label_set_attributes (GTK_LABEL (label), attrs);
pango_attr_list_unref (attrs);
}
if (!gtk_widget_get_visible (window))

View File

@@ -21,7 +21,7 @@ do_tabs (GtkWidget *do_widget)
GtkWidget *view;
GtkWidget *sw;
GtkTextBuffer *buffer;
Pango2TabArray *tabs;
PangoTabArray *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 = 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);
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);
gtk_text_view_set_tabs (GTK_TEXT_VIEW (view), tabs);
pango2_tab_array_free (tabs);
pango_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 Pango to draw text with more than
* This demo shows how to use PangoCairo to draw text with more than
* just a single color.
*/
@@ -15,18 +15,18 @@ draw_text (GtkDrawingArea *da,
gpointer data)
{
cairo_pattern_t *pattern;
Pango2Layout *layout;
Pango2FontDescription *desc;
PangoLayout *layout;
PangoFontDescription *desc;
cairo_save (cr);
layout = gtk_widget_create_pango_layout (GTK_WIDGET (da), "Pango power!\nPango power!\nPango power!");
desc = pango2_font_description_from_string ("sans bold 34");
pango2_layout_set_font_description (layout, desc);
pango2_font_description_free (desc);
desc = pango_font_description_from_string ("sans bold 34");
pango_layout_set_font_description (layout, desc);
pango_font_description_free (desc);
cairo_move_to (cr, 30, 20);
pango2_cairo_layout_path (cr, layout);
pango_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", PANGO2_WEIGHT_BOLD,
"size", 15 * PANGO2_SCALE,
"weight", PANGO_WEIGHT_BOLD,
"size", 15 * PANGO_SCALE,
NULL);
gtk_text_buffer_create_tag (buffer, "italic",
"style", PANGO2_STYLE_ITALIC, NULL);
"style", PANGO_STYLE_ITALIC, NULL);
gtk_text_buffer_create_tag (buffer, "bold",
"weight", PANGO2_WEIGHT_BOLD, NULL);
"weight", PANGO_WEIGHT_BOLD, NULL);
gtk_text_buffer_create_tag (buffer, "big",
/* points times the PANGO2_SCALE factor */
"size", 20 * PANGO2_SCALE, NULL);
/* points times the PANGO_SCALE factor */
"size", 20 * PANGO_SCALE, NULL);
gtk_text_buffer_create_tag (buffer, "xx-small",
"scale", PANGO2_SCALE_XX_SMALL, NULL);
"scale", PANGO_SCALE_XX_SMALL, NULL);
gtk_text_buffer_create_tag (buffer, "x-large",
"scale", PANGO2_SCALE_X_LARGE, NULL);
"scale", PANGO_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", PANGO2_LINE_STYLE_SOLID, NULL);
"underline", PANGO_UNDERLINE_SINGLE, NULL);
gtk_text_buffer_create_tag (buffer, "double_underline",
"underline", PANGO2_LINE_STYLE_DOUBLE, NULL);
"underline", PANGO_UNDERLINE_DOUBLE, NULL);
gtk_text_buffer_create_tag (buffer, "superscript",
"rise", 10 * PANGO2_SCALE, /* 10 pixels */
"size", 8 * PANGO2_SCALE, /* 8 points */
"rise", 10 * PANGO_SCALE, /* 10 pixels */
"size", 8 * PANGO_SCALE, /* 8 points */
NULL);
gtk_text_buffer_create_tag (buffer, "subscript",
"rise", -10 * PANGO2_SCALE, /* 10 pixels */
"size", 8 * PANGO2_SCALE, /* 8 points */
"rise", -10 * PANGO_SCALE, /* 10 pixels */
"size", 8 * PANGO_SCALE, /* 8 points */
NULL);
gtk_text_buffer_create_tag (buffer, "rtl_quote",
@@ -137,7 +137,7 @@ insert_text (GtkTextView *view)
icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
icon = gtk_icon_theme_lookup_icon (icon_theme,
"drive-harddisk",
"face-cool",
NULL,
32, 1,
gtk_widget_get_direction (widget),
@@ -239,6 +239,8 @@ insert_text (GtkTextView *view)
gtk_text_buffer_insert (buffer, &iter, "The buffer can have images in it: ", -1);
gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (icon));
gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (icon));
gtk_text_buffer_insert_paintable (buffer, &iter, nuclear);
gtk_text_buffer_insert (buffer, &iter, " for example.\n\n", -1);
@@ -439,12 +441,11 @@ attach_widgets (GtkTextView *text_view)
{
widget = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, NULL);
gtk_range_set_range (GTK_RANGE (widget), 0, 100);
gtk_widget_set_size_request (widget, 100, -1);
gtk_widget_set_size_request (widget, 70, -1);
}
else if (i == 3)
{
widget = gtk_entry_new ();
gtk_editable_set_width_chars (GTK_EDITABLE (widget), 10);
}
else
{

View File

@@ -70,8 +70,8 @@ about_activated (GSimpleAction *action,
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, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),

View File

@@ -22,4 +22,3 @@ 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, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (s, "\tPango\t%s\n",
pango_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)
{
Pango2Layout *layout;
PangoLayout *layout;
GtkSnapshot *snapshot;
GskRenderNode *node;
GBytes *bytes;
layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), error_message);
pango2_layout_set_width (layout, 300 * PANGO2_SCALE);
pango_layout_set_width (layout, 300 * PANGO_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", PANGO2_LINE_STYLE_DOTTED,
"underline", PANGO_UNDERLINE_ERROR,
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 <pango2/pangocairo.h>
#include <pango/pangocairo.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
@@ -200,7 +200,7 @@ save_file (GFile *save_filename)
typedef struct {
char *text;
Pango2Layout *layout;
PangoLayout *layout;
GList *page_breaks;
GtkWidget *font_button;
char *font;
@@ -211,41 +211,39 @@ begin_print (GtkPrintOperation *operation,
GtkPrintContext *context,
PrintData *print_data)
{
Pango2FontDescription *desc;
Pango2Lines *lines;
Pango2Line *line;
PangoFontDescription *desc;
PangoLayoutLine *layout_line;
double width, height;
double page_height;
GList *page_breaks;
int num_lines;
int i;
int line;
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 = pango2_font_description_from_string (print_data->font);
pango2_layout_set_font_description (print_data->layout, desc);
pango2_font_description_free (desc);
desc = pango_font_description_from_string (print_data->font);
pango_layout_set_font_description (print_data->layout, desc);
pango_font_description_free (desc);
pango2_layout_set_width (print_data->layout, width * PANGO2_SCALE);
pango_layout_set_width (print_data->layout, width * PANGO_SCALE);
pango2_layout_set_text (print_data->layout, print_data->text, -1);
pango_layout_set_text (print_data->layout, print_data->text, -1);
lines = pango2_layout_get_lines (print_data->layout);
num_lines = pango2_lines_get_line_count (lines);
num_lines = pango_layout_get_line_count (print_data->layout);
page_breaks = NULL;
page_height = 0;
for (i = 0; i < num_lines; i++)
for (line = 0; line < num_lines; line++)
{
Pango2Rectangle logical_rect;
PangoRectangle ink_rect, logical_rect;
double line_height;
line = pango2_lines_get_lines (lines)[i];
pango2_line_get_extents (line, NULL, &logical_rect);
layout_line = pango_layout_get_line (print_data->layout, line);
pango_layout_line_get_extents (layout_line, &ink_rect, &logical_rect);
line_height = logical_rect.height / 1024.0;
@@ -273,7 +271,7 @@ draw_page (GtkPrintOperation *operation,
cairo_t *cr;
GList *pagebreak;
int start, end, i;
Pango2LineIter *iter;
PangoLayoutIter *iter;
double start_pos;
if (page_nr == 0)
@@ -286,7 +284,7 @@ draw_page (GtkPrintOperation *operation,
pagebreak = g_list_nth (print_data->page_breaks, page_nr);
if (pagebreak == NULL)
end = pango2_lines_get_line_count (pango2_layout_get_lines (print_data->layout));
end = pango_layout_get_line_count (print_data->layout);
else
end = GPOINTER_TO_INT (pagebreak->data);
@@ -296,33 +294,33 @@ draw_page (GtkPrintOperation *operation,
i = 0;
start_pos = 0;
iter = pango2_layout_get_iter (print_data->layout);
iter = pango_layout_get_iter (print_data->layout);
do
{
Pango2Rectangle logical_rect;
Pango2Line *line;
int baseline;
PangoRectangle logical_rect;
PangoLayoutLine *line;
int baseline;
if (i >= start)
{
line = pango2_line_iter_get_line (iter);
line = pango_layout_iter_get_line (iter);
pango2_line_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango2_line_iter_get_line_baseline (iter);
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango_layout_iter_get_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);
pango2_cairo_show_line (cr, line);
pango_cairo_show_layout_line (cr, line);
}
i++;
}
while (i < end &&
pango2_line_iter_next_line (iter));
pango_layout_iter_next_line (iter));
pango2_line_iter_free (iter);
pango_layout_iter_free (iter);
}
static void
@@ -628,8 +626,8 @@ activate_about (GSimpleAction *action,
glib_major_version,
glib_minor_version,
glib_micro_version);
g_string_append_printf (sysinfo, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (sysinfo, "\tPango\t%s\n",
pango_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, "\tPango2\t%s\n",
pango2_version_string ());
g_string_append_printf (s, "\tPango\t%s\n",
pango_version_string ());
g_string_append_printf (s, "\tGTK \t%d.%d.%d\n",
gtk_get_major_version (),
gtk_get_minor_version (),
@@ -2081,23 +2081,26 @@ activate (GApplication *app)
builder = gtk_builder_new ();
scope = gtk_builder_cscope_new ();
gtk_builder_cscope_add_callback (scope, on_entry_icon_release);
gtk_builder_cscope_add_callback (scope, on_scale_button_value_changed);
gtk_builder_cscope_add_callback (scope, on_record_button_toggled);
gtk_builder_cscope_add_callback (scope, on_page_combo_changed);
gtk_builder_cscope_add_callback (scope, on_range_from_changed);
gtk_builder_cscope_add_callback (scope, on_range_to_changed);
gtk_builder_cscope_add_callback (scope, on_picture_drag_prepare);
gtk_builder_cscope_add_callback (scope, on_picture_drop);
gtk_builder_cscope_add_callback (scope, tab_close_cb);
gtk_builder_cscope_add_callback (scope, increase_icon_size);
gtk_builder_cscope_add_callback (scope, decrease_icon_size);
gtk_builder_cscope_add_callback (scope, osd_frame_pressed);
gtk_builder_cscope_add_callback (scope, age_entry_changed);
gtk_builder_cscope_add_callback (scope, validate_more_details);
gtk_builder_cscope_add_callback (scope, mode_switch_state_set);
gtk_builder_cscope_add_callback (scope, level_scale_value_changed);
gtk_builder_cscope_add_callback (scope, transition_speed_changed);
gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
"on_entry_icon_release", (GCallback)on_entry_icon_release,
"on_scale_button_value_changed", (GCallback)on_scale_button_value_changed,
"on_record_button_toggled", (GCallback)on_record_button_toggled,
"on_page_combo_changed", (GCallback)on_page_combo_changed,
"on_range_from_changed", (GCallback)on_range_from_changed,
"on_range_to_changed", (GCallback)on_range_to_changed,
"on_picture_drag_prepare", (GCallback)on_picture_drag_prepare,
"on_picture_drop", (GCallback)on_picture_drop,
"tab_close_cb", (GCallback)tab_close_cb,
"increase_icon_size", (GCallback)increase_icon_size,
"decrease_icon_size", (GCallback)decrease_icon_size,
"reset_icon_size", (GCallback)reset_icon_size,
"osd_frame_pressed", (GCallback)osd_frame_pressed,
"age_entry_changed", (GCallback)age_entry_changed,
"validate_more_details", (GCallback)validate_more_details,
"mode_switch_state_set", (GCallback)mode_switch_state_set,
"level_scale_value_changed", (GCallback)level_scale_value_changed,
"transition_speed_changed", (GCallback)transition_speed_changed,
NULL);
gtk_builder_set_scope (builder, scope);
g_object_unref (scope);
if (!gtk_builder_add_from_resource (builder, "/org/gtk/WidgetFactory4/widget-factory.ui", &error))

View File

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

View File

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

View File

@@ -117,7 +117,6 @@ static const GdkDebugKey gdk_debug_keys[] = {
{ "selection", GDK_DEBUG_SELECTION, "Information about selections" },
{ "clipboard", GDK_DEBUG_CLIPBOARD, "Information about clipboards" },
{ "nograbs", GDK_DEBUG_NOGRABS, "Disable pointer and keyboard grabs (X11)" },
{ "portals", GDK_DEBUG_PORTALS, "Force the use of portals" },
{ "gl-disable", GDK_DEBUG_GL_DISABLE, "Disable OpenGL support" },
{ "gl-software", GDK_DEBUG_GL_SOFTWARE, "Force OpenGL software rendering" },
{ "gl-texture-rect", GDK_DEBUG_GL_TEXTURE_RECT, "Use OpenGL texture rectangle extension" },
@@ -361,16 +360,24 @@ gdk_running_in_sandbox (void)
gboolean
gdk_should_use_portal (void)
{
if (GDK_DISPLAY_DEBUG_CHECK (NULL, PORTALS))
return TRUE;
static const char *use_portal = NULL;
if (gdk_running_in_sandbox ())
return TRUE;
if (G_UNLIKELY (use_portal == NULL))
{
if (gdk_running_in_sandbox ())
use_portal = "1";
else
{
use_portal = g_getenv ("GTK_USE_PORTAL");
if (!use_portal)
use_portal = "";
}
}
return FALSE;
return use_portal[0] == '1';
}
Pango2Direction
PangoDirection
gdk_unichar_direction (gunichar ch)
{
FriBidiCharType fribidi_ch_type;
@@ -380,21 +387,21 @@ gdk_unichar_direction (gunichar ch)
fribidi_ch_type = fribidi_get_bidi_type (ch);
if (!FRIBIDI_IS_STRONG (fribidi_ch_type))
return PANGO2_DIRECTION_NEUTRAL;
return PANGO_DIRECTION_NEUTRAL;
else if (FRIBIDI_IS_RTL (fribidi_ch_type))
return PANGO2_DIRECTION_RTL;
return PANGO_DIRECTION_RTL;
else
return PANGO2_DIRECTION_LTR;
return PANGO_DIRECTION_LTR;
}
Pango2Direction
PangoDirection
gdk_find_base_dir (const char *text,
int length)
{
Pango2Direction dir = PANGO2_DIRECTION_NEUTRAL;
PangoDirection dir = PANGO_DIRECTION_NEUTRAL;
const char *p;
g_return_val_if_fail (text != NULL || length == 0, PANGO2_DIRECTION_NEUTRAL);
g_return_val_if_fail (text != NULL || length == 0, PANGO_DIRECTION_NEUTRAL);
p = text;
while ((length < 0 || p < text + length) && *p)
@@ -403,7 +410,7 @@ gdk_find_base_dir (const char *text,
dir = gdk_unichar_direction (wc);
if (dir != PANGO2_DIRECTION_NEUTRAL)
if (dir != PANGO_DIRECTION_NEUTRAL)
break;
p = g_utf8_next_char (p);

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