From 87b653f093e5cc9da0ee0d0987b20f362fea9b8e Mon Sep 17 00:00:00 2001 From: Alexandros Theodotou Date: Wed, 5 Jan 2022 19:48:18 +0000 Subject: [PATCH] port digital meters to snapshot API Also allow using DSEG fonts directly from the prefix instead of requiring the fonts to be installed on the system. --- inc/gui/widgets/digital_meter.h | 12 +- inc/utils/pango.h | 46 +++ inc/zrythm.h | 5 +- meson.build | 3 + src/gui/widgets/digital_meter.c | 525 +++++++++++++++++--------------- src/utils/cairo.c | 11 +- src/utils/meson.build | 1 + src/utils/pango.c | 111 +++++++ src/zrythm.c | 8 +- 9 files changed, 468 insertions(+), 254 deletions(-) create mode 100644 inc/utils/pango.h create mode 100644 src/utils/pango.c diff --git a/inc/gui/widgets/digital_meter.h b/inc/gui/widgets/digital_meter.h index 17c53f166..89c6b78c7 100644 --- a/inc/gui/widgets/digital_meter.h +++ b/inc/gui/widgets/digital_meter.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2021 Alexandros Theodotou + * Copyright (C) 2019-2022 Alexandros Theodotou * * This file is part of Zrythm * @@ -37,10 +37,8 @@ #define DIGITAL_METER_WIDGET_TYPE \ (digital_meter_widget_get_type ()) G_DECLARE_FINAL_TYPE ( - DigitalMeterWidget, - digital_meter_widget, - Z, DIGITAL_METER_WIDGET, - GtkDrawingArea) + DigitalMeterWidget, digital_meter_widget, + Z, DIGITAL_METER_WIDGET, GtkWidget) typedef enum NoteLength NoteLength; typedef enum NoteType NoteType; @@ -65,7 +63,7 @@ typedef struct SnapGrid SnapGrid; typedef struct _DigitalMeterWidget { - GtkDrawingArea parent_instance; + GtkWidget parent_instance; DigitalMeterType type; @@ -177,6 +175,8 @@ typedef struct _DigitalMeterWidget PangoLayout * caption_layout; PangoLayout * seg7_layout; PangoLayout * normal_layout; + + bool initialized; } DigitalMeterWidget; /** diff --git a/inc/utils/pango.h b/inc/utils/pango.h new file mode 100644 index 000000000..70341293c --- /dev/null +++ b/inc/utils/pango.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2022 Alexandros Theodotou + * + * This file is part of Zrythm + * + * Zrythm is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Zrythm is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +/** + * @file + * + * Pango utils. + */ + +#ifndef __UTILS_PANGO_H__ +#define __UTILS_PANGO_H__ + +#include + +/** + * @addtogroup utils + * + * @{ + */ + +PangoLayout * +z_pango_create_layout_from_description ( + GtkWidget * widget, + PangoFontDescription * descr); + +/** + * @} + */ + +#endif /* __UTILS_PANGO_H__ */ diff --git a/inc/zrythm.h b/inc/zrythm.h index c89ec6b1e..76577e4f0 100644 --- a/inc/zrythm.h +++ b/inc/zrythm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2021 Alexandros Theodotou + * Copyright (C) 2019-2022 Alexandros Theodotou * * This file is part of Zrythm * @@ -137,6 +137,9 @@ typedef enum ZrythmDirType /** Built-in plugins path. */ ZRYTHM_DIR_SYSTEM_LV2_PLUGINS_DIR, + /** The directory fonts/zrythm under datadir. */ + ZRYTHM_DIR_SYSTEM_FONTSDIR, + /* ************************************ */ /* diff --git a/meson.build b/meson.build index 42264f0b1..5d15022d5 100644 --- a/meson.build +++ b/meson.build @@ -414,6 +414,9 @@ cdata.set_quoted ('CONFIGURE_BINDIR', bindir) cdata.set_quoted ('LIB_SUFFIX', lib_suffix) cdata.set_quoted ('BIN_SUFFIX', bin_suffix) cdata.set_quoted ('GSCHEMAS_DIR', schemasdir) +if get_option ('dseg_font') + cdata.set ('HAVE_BUNDLED_DSEG', 1) +endif cdata.set_quoted ( 'BUILD_TYPE', get_option ('buildtype')) cdata.set_quoted ( diff --git a/src/gui/widgets/digital_meter.c b/src/gui/widgets/digital_meter.c index d481b7257..e5c19b0f2 100644 --- a/src/gui/widgets/digital_meter.c +++ b/src/gui/widgets/digital_meter.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Alexandros Theodotou + * Copyright (C) 2018-2022 Alexandros Theodotou * * This file is part of Zrythm * @@ -53,9 +53,8 @@ #include G_DEFINE_TYPE ( - DigitalMeterWidget, - digital_meter_widget, - GTK_TYPE_DRAWING_AREA) + DigitalMeterWidget, digital_meter_widget, + GTK_TYPE_WIDGET) #define FONT_SIZE 16 /*#define SEG7_FONT "Segment7 Bold 16"*/ @@ -78,72 +77,171 @@ G_DEFINE_TYPE ( #define GET_POS \ ((*self->getter) (self->obj, &pos)) +static void +recreate_pango_layouts ( + DigitalMeterWidget * self) +{ + if (PANGO_IS_LAYOUT (self->caption_layout)) + g_object_unref (self->caption_layout); + if (PANGO_IS_LAYOUT (self->seg7_layout)) + g_object_unref (self->seg7_layout); + if (PANGO_IS_LAYOUT (self->normal_layout)) + g_object_unref (self->normal_layout); + + self->caption_layout = + z_cairo_create_pango_layout_from_string ( + GTK_WIDGET (self), CAPTION_FONT, + PANGO_ELLIPSIZE_NONE, -1); + self->seg7_layout = + z_cairo_create_pango_layout_from_string ( + GTK_WIDGET (self), SEG7_FONT, + PANGO_ELLIPSIZE_NONE, -1); + self->normal_layout = + z_cairo_create_pango_layout_from_string ( + GTK_WIDGET (self), NORMAL_FONT, + PANGO_ELLIPSIZE_NONE, -1); +} static void -digital_meter_draw_cb ( - GtkDrawingArea * drawing_area, - cairo_t * cr, - int width, - int height, - gpointer user_data) +init_dm ( + DigitalMeterWidget * self) { - DigitalMeterWidget * self = - Z_DIGITAL_METER_WIDGET (user_data); - GtkWidget * widget = GTK_WIDGET (drawing_area); + g_return_if_fail (Z_DIGITAL_METER_WIDGET (self)); - if (!PROJECT->loaded) - return; + recreate_pango_layouts (self); - g_return_if_fail ( - Z_IS_DIGITAL_METER_WIDGET (self) && - PANGO_IS_LAYOUT (self->caption_layout) && - PANGO_IS_LAYOUT (self->seg7_layout) && - PANGO_IS_LAYOUT (self->normal_layout)); + int caption_textw, caption_texth; + z_cairo_get_text_extents_for_widget ( + self, self->caption_layout, self->caption, + &caption_textw, &caption_texth); + int textw, texth; + switch (self->type) + { + case DIGITAL_METER_TYPE_BPM: + { + gtk_widget_set_tooltip_text ( + (GtkWidget *) self, _("Tempo/BPM")); + z_cairo_get_text_extents_for_widget ( + self, self->seg7_layout, "888888", + &textw, &texth); + /* caption + padding between caption and + * BPM + padding top/bottom */ + gtk_widget_set_size_request ( + GTK_WIDGET (self), textw + PADDING_W * 2, + caption_texth + HALF_SPACE_BETWEEN + + texth + PADDING_TOP * 2); + } + break; + case DIGITAL_METER_TYPE_POSITION: + gtk_widget_set_tooltip_text ( + (GtkWidget *) self, _("Position")); + z_cairo_get_text_extents_for_widget ( + self, self->seg7_layout, "-888888888", + &textw, &texth); + /* caption + padding between caption and + * BPM + padding top/bottom */ + gtk_widget_set_size_request ( + GTK_WIDGET (self), + textw + PADDING_W * 2 + HALF_SPACE_BETWEEN * 3, + caption_texth + HALF_SPACE_BETWEEN + + texth + PADDING_TOP * 2); + + break; + case DIGITAL_METER_TYPE_NOTE_LENGTH: + gtk_widget_set_size_request ( + GTK_WIDGET (self), + -1, + 30); + break; - GtkStyleContext *context = + case DIGITAL_METER_TYPE_NOTE_TYPE: + gtk_widget_set_size_request ( + GTK_WIDGET (self), + -1, + 30); + break; + case DIGITAL_METER_TYPE_TIMESIG: + { + gtk_widget_set_tooltip_text ( + GTK_WIDGET (self), + _("Time Signature - Beats per bar / " + "Beat unit")); + z_cairo_get_text_extents_for_widget ( + self, self->seg7_layout, "16/16", + &textw, &texth); + /* caption + padding between caption and + * BPM + padding top/bottom */ + gtk_widget_set_size_request ( + GTK_WIDGET (self), textw + PADDING_W * 2, + caption_texth + HALF_SPACE_BETWEEN + + texth + PADDING_TOP * 2); + } + break; + } + + self->initialized = true; +} + + +static void +digital_meter_snapshot ( + GtkWidget * widget, + GtkSnapshot * snapshot) +{ + DigitalMeterWidget * self = + Z_DIGITAL_METER_WIDGET (widget); + + int width = + gtk_widget_get_allocated_width (widget); + int height = + gtk_widget_get_allocated_height (widget); + + GtkStyleContext * context = gtk_widget_get_style_context (widget); - gtk_render_background ( - context, cr, 0, 0, width, height); + gtk_snapshot_render_background ( + snapshot, context, 0, 0, width, height); + + if (!PROJECT->loaded) + return; + + if (!self->initialized) + init_dm (self); /* draw caption and get its extents */ int caption_textw, caption_texth; + GdkRGBA color; if (gtk_widget_is_sensitive (GTK_WIDGET (self))) { - cairo_set_source_rgba ( - cr, 1.0, 1.0, 1.0, 1.0); + color = Z_GDK_RGBA_INIT (1, 1, 1, 1); } else { - cairo_set_source_rgba ( - cr, 0.6, 0.6, 0.6, 1.0); + color = Z_GDK_RGBA_INIT (0.6, 0.6, 0.6, 1); } z_cairo_get_text_extents_for_widget ( self, self->caption_layout, self->caption, &caption_textw, &caption_texth); - z_cairo_draw_text_full ( - cr, widget, self->caption_layout, - self->caption, - width / 2 - caption_textw / 2, - PADDING_TOP); - /* uncomment to make text slightly thickerr */ - /*z_cairo_draw_text_full (*/ - /*cr, self->caption, width / 2 - caption_textw / 2,*/ - /*PADDING_TOP, CAPTION_FONT);*/ + pango_layout_set_markup ( + self->caption_layout, self->caption, -1); + gtk_snapshot_save (snapshot); + gtk_snapshot_translate ( + snapshot, + &GRAPHENE_POINT_INIT ( + width / 2.f - caption_textw / 2.f, + PADDING_TOP)); + gtk_snapshot_append_layout ( + snapshot, self->caption_layout, &color); + gtk_snapshot_restore (snapshot); /* draw line */ if (self->draw_line) { - cairo_set_line_width (cr, 1.0); - cairo_move_to ( - cr, 0, - caption_texth + - PADDING_TOP); - cairo_line_to ( - cr, width, - caption_texth + - PADDING_TOP); - cairo_stroke (cr); + gtk_snapshot_append_color ( + snapshot, &color, + &GRAPHENE_RECT_INIT ( + 0, caption_texth + PADDING_TOP, + width, 1)); } /*GdkRGBA color;*/ @@ -151,13 +249,11 @@ digital_meter_draw_cb ( /*gdk_cairo_set_source_rgba (cr, &color);*/ if (gtk_widget_is_sensitive (GTK_WIDGET (self))) { - cairo_set_source_rgba ( - cr, 0.0, 1.0, 0.1, 1.0); + color = Z_GDK_RGBA_INIT (0.0, 1.0, 0.1, 1.0); } else { - cairo_set_source_rgba ( - cr, 0.0, 0.6, 0.06, 1.0); + color = Z_GDK_RGBA_INIT (0.0, 0.6, 0.06, 1.0); } char text[20]; char * heap_text = NULL; @@ -205,20 +301,34 @@ digital_meter_draw_cb ( sprintf (text, "!%d.", num_part); else sprintf (text, "%d.", num_part); - z_cairo_draw_text_full ( - cr, widget, self->seg7_layout, text, - self->num_part_start_pos, - self->height_start_pos); + pango_layout_set_markup ( + self->seg7_layout, text, -1); + gtk_snapshot_save (snapshot); + gtk_snapshot_translate ( + snapshot, + &GRAPHENE_POINT_INIT ( + self->num_part_start_pos, + self->height_start_pos)); + gtk_snapshot_append_layout ( + snapshot, self->seg7_layout, &color); + gtk_snapshot_restore (snapshot); /* draw decimal part */ if (dec_part < 10) sprintf (text, "0%d", dec_part); else sprintf (text, "%d", dec_part); - z_cairo_draw_text_full ( - cr, widget, self->seg7_layout, text, - self->dec_part_start_pos, - self->height_start_pos); + pango_layout_set_markup ( + self->seg7_layout, text, -1); + gtk_snapshot_save (snapshot); + gtk_snapshot_translate ( + snapshot, + &GRAPHENE_POINT_INIT ( + self->dec_part_start_pos, + self->height_start_pos)); + gtk_snapshot_append_layout ( + snapshot, self->seg7_layout, &color); + gtk_snapshot_restore (snapshot); break; case DIGITAL_METER_TYPE_POSITION: @@ -270,20 +380,34 @@ digital_meter_draw_cb ( sprintf (text, "!%d.", mins); else sprintf (text, "%d.", mins); - z_cairo_draw_text_full ( - cr, widget, self->seg7_layout, text, - self->minutes_start_pos, - self->height_start_pos); + pango_layout_set_markup ( + self->seg7_layout, text, -1); + gtk_snapshot_save (snapshot); + gtk_snapshot_translate ( + snapshot, + &GRAPHENE_POINT_INIT ( + self->minutes_start_pos, + self->height_start_pos)); + gtk_snapshot_append_layout ( + snapshot, self->seg7_layout, &color); + gtk_snapshot_restore (snapshot); /* draw seconds */ if (secs < 10) sprintf (text, "0%ld.", secs); else sprintf (text, "%ld.", secs); - z_cairo_draw_text_full ( - cr, widget, self->seg7_layout, text, - self->seconds_start_pos, - self->height_start_pos); + pango_layout_set_markup ( + self->seg7_layout, text, -1); + gtk_snapshot_save (snapshot); + gtk_snapshot_translate ( + snapshot, + &GRAPHENE_POINT_INIT ( + self->seconds_start_pos, + self->height_start_pos)); + gtk_snapshot_append_layout ( + snapshot, self->seg7_layout, &color); + gtk_snapshot_restore (snapshot); /* draw ms */ if (ms < 10) @@ -292,10 +416,17 @@ digital_meter_draw_cb ( sprintf (text, "0%ld", ms); else sprintf (text, "%ld", ms); - z_cairo_draw_text_full ( - cr, widget, self->seg7_layout, text, - self->ms_start_pos, - self->height_start_pos); + pango_layout_set_markup ( + self->seg7_layout, text, -1); + gtk_snapshot_save (snapshot); + gtk_snapshot_translate ( + snapshot, + &GRAPHENE_POINT_INIT ( + self->ms_start_pos, + self->height_start_pos)); + gtk_snapshot_append_layout ( + snapshot, self->seg7_layout, &color); + gtk_snapshot_restore (snapshot); } else { @@ -354,22 +485,43 @@ digital_meter_draw_cb ( else sprintf (text, "!%d", bars); strcat (text, "."); - z_cairo_draw_text_full ( - cr, widget, self->seg7_layout, text, - self->bars_start_pos, - self->height_start_pos); + pango_layout_set_markup ( + self->seg7_layout, text, -1); + gtk_snapshot_save (snapshot); + gtk_snapshot_translate ( + snapshot, + &GRAPHENE_POINT_INIT ( + self->bars_start_pos, + self->height_start_pos)); + gtk_snapshot_append_layout ( + snapshot, self->seg7_layout, &color); + gtk_snapshot_restore (snapshot); sprintf (text, "%d.", abs (beats)); - z_cairo_draw_text_full ( - cr, widget, self->seg7_layout, text, - self->beats_start_pos, - self->height_start_pos); + pango_layout_set_markup ( + self->seg7_layout, text, -1); + gtk_snapshot_save (snapshot); + gtk_snapshot_translate ( + snapshot, + &GRAPHENE_POINT_INIT ( + self->beats_start_pos, + self->height_start_pos)); + gtk_snapshot_append_layout ( + snapshot, self->seg7_layout, &color); + gtk_snapshot_restore (snapshot); sprintf (text, "%d.", abs (sixteenths)); - z_cairo_draw_text_full ( - cr, widget, self->seg7_layout, text, - self->sixteenths_start_pos, - self->height_start_pos); + pango_layout_set_markup ( + self->seg7_layout, text, -1); + gtk_snapshot_save (snapshot); + gtk_snapshot_translate ( + snapshot, + &GRAPHENE_POINT_INIT ( + self->sixteenths_start_pos, + self->height_start_pos)); + gtk_snapshot_append_layout ( + snapshot, self->seg7_layout, &color); + gtk_snapshot_restore (snapshot); if (abs (ticks) < 10) sprintf (text, "00%d", abs (ticks)); @@ -377,10 +529,17 @@ digital_meter_draw_cb ( sprintf (text, "0%d", abs (ticks)); else sprintf (text, "%d", abs (ticks)); - z_cairo_draw_text_full ( - cr, widget, self->seg7_layout, text, - self->ticks_start_pos, - self->height_start_pos); + pango_layout_set_markup ( + self->seg7_layout, text, -1); + gtk_snapshot_save (snapshot); + gtk_snapshot_translate ( + snapshot, + &GRAPHENE_POINT_INIT ( + self->ticks_start_pos, + self->height_start_pos)); + gtk_snapshot_append_layout ( + snapshot, self->seg7_layout, &color); + gtk_snapshot_restore (snapshot); } break; case DIGITAL_METER_TYPE_NOTE_LENGTH: @@ -396,10 +555,17 @@ digital_meter_draw_cb ( caption_texth + HALF_SPACE_BETWEEN; self->height_end_pos = self->height_start_pos + texth; - z_cairo_draw_text_full ( - cr, widget, self->seg7_layout, - heap_text, width / 2 - textw / 2, - self->height_start_pos); + pango_layout_set_markup ( + self->seg7_layout, heap_text, -1); + gtk_snapshot_save (snapshot); + gtk_snapshot_translate ( + snapshot, + &GRAPHENE_POINT_INIT ( + width / 2 - textw / 2, + self->height_start_pos)); + gtk_snapshot_append_layout ( + snapshot, self->seg7_layout, &color); + gtk_snapshot_restore (snapshot); g_free (heap_text); break; @@ -424,10 +590,17 @@ digital_meter_draw_cb ( caption_texth + HALF_SPACE_BETWEEN; self->height_end_pos = self->height_start_pos + texth; - z_cairo_draw_text_full ( - cr, widget, self->seg7_layout, heap_text, - width / 2 - textw / 2, - self->height_start_pos); + pango_layout_set_markup ( + self->seg7_layout, heap_text, -1); + gtk_snapshot_save (snapshot); + gtk_snapshot_translate ( + snapshot, + &GRAPHENE_POINT_INIT ( + width / 2 - textw / 2, + self->height_start_pos)); + gtk_snapshot_append_layout ( + snapshot, self->seg7_layout, &color); + gtk_snapshot_restore (snapshot); break; case DIGITAL_METER_TYPE_TIMESIG: @@ -465,10 +638,17 @@ digital_meter_draw_cb ( text[2] = '\0'; heap_text = g_strdup_printf ("%s/%s", text, beat_unit); - z_cairo_draw_text_full ( - cr, widget, self->seg7_layout, heap_text, - width / 2 - textw / 2, - self->height_start_pos); + pango_layout_set_markup ( + self->seg7_layout, heap_text, -1); + gtk_snapshot_save (snapshot); + gtk_snapshot_translate ( + snapshot, + &GRAPHENE_POINT_INIT ( + width / 2 - textw / 2, + self->height_start_pos)); + gtk_snapshot_append_layout ( + snapshot, self->seg7_layout, &color); + gtk_snapshot_restore (snapshot); g_free (heap_text); break; @@ -1188,137 +1368,6 @@ button_press_cb ( update_flags (self, x, y); } -static void -recreate_pango_layouts ( - DigitalMeterWidget * self) -{ - if (PANGO_IS_LAYOUT (self->caption_layout)) - g_object_unref (self->caption_layout); - if (PANGO_IS_LAYOUT (self->seg7_layout)) - g_object_unref (self->seg7_layout); - if (PANGO_IS_LAYOUT (self->normal_layout)) - g_object_unref (self->normal_layout); - - self->caption_layout = - z_cairo_create_pango_layout_from_string ( - GTK_WIDGET (self), CAPTION_FONT, - PANGO_ELLIPSIZE_NONE, -1); - self->seg7_layout = - z_cairo_create_pango_layout_from_string ( - GTK_WIDGET (self), SEG7_FONT, - PANGO_ELLIPSIZE_NONE, -1); - self->normal_layout = - z_cairo_create_pango_layout_from_string ( - GTK_WIDGET (self), NORMAL_FONT, - PANGO_ELLIPSIZE_NONE, -1); -} - -static void -digital_meter_widget_on_resize ( - GtkDrawingArea * drawing_area, - gint width, - gint height, - gpointer user_data) -{ - DigitalMeterWidget * self = - Z_DIGITAL_METER_WIDGET (user_data); - recreate_pango_layouts (self); -} - -#if 0 -static void -on_screen_changed ( - GtkWidget * widget, - GdkScreen * previous_screen, - DigitalMeterWidget * self) -{ - recreate_pango_layouts (self); -} -#endif - -static void -init_dm ( - DigitalMeterWidget * self) -{ - g_return_if_fail (Z_DIGITAL_METER_WIDGET (self)); - - recreate_pango_layouts (self); - - int caption_textw, caption_texth; - z_cairo_get_text_extents_for_widget ( - self, self->caption_layout, self->caption, - &caption_textw, &caption_texth); - int textw, texth; - switch (self->type) - { - case DIGITAL_METER_TYPE_BPM: - { - gtk_widget_set_tooltip_text ( - (GtkWidget *) self, _("Tempo/BPM")); - z_cairo_get_text_extents_for_widget ( - self, self->seg7_layout, "888888", - &textw, &texth); - /* caption + padding between caption and - * BPM + padding top/bottom */ - gtk_widget_set_size_request ( - GTK_WIDGET (self), textw + PADDING_W * 2, - caption_texth + HALF_SPACE_BETWEEN + - texth + PADDING_TOP * 2); - } - break; - case DIGITAL_METER_TYPE_POSITION: - gtk_widget_set_tooltip_text ( - (GtkWidget *) self, _("Position")); - z_cairo_get_text_extents_for_widget ( - self, self->seg7_layout, "-888888888", - &textw, &texth); - /* caption + padding between caption and - * BPM + padding top/bottom */ - gtk_widget_set_size_request ( - GTK_WIDGET (self), - textw + PADDING_W * 2 + HALF_SPACE_BETWEEN * 3, - caption_texth + HALF_SPACE_BETWEEN + - texth + PADDING_TOP * 2); - - break; - case DIGITAL_METER_TYPE_NOTE_LENGTH: - gtk_widget_set_size_request ( - GTK_WIDGET (self), - -1, - 30); - break; - - case DIGITAL_METER_TYPE_NOTE_TYPE: - gtk_widget_set_size_request ( - GTK_WIDGET (self), - -1, - 30); - break; - case DIGITAL_METER_TYPE_TIMESIG: - { - gtk_widget_set_tooltip_text ( - GTK_WIDGET (self), - _("Time Signature - Beats per bar / " - "Beat unit")); - z_cairo_get_text_extents_for_widget ( - self, self->seg7_layout, "16/16", - &textw, &texth); - /* caption + padding between caption and - * BPM + padding top/bottom */ - gtk_widget_set_size_request ( - GTK_WIDGET (self), textw + PADDING_W * 2, - caption_texth + HALF_SPACE_BETWEEN + - texth + PADDING_TOP * 2); - } - break; - } - - gtk_drawing_area_set_draw_func ( - GTK_DRAWING_AREA (self), - digital_meter_draw_cb, - self, NULL); -} - /** * Creates a digital meter with the given type (bpm or position). */ @@ -1336,7 +1385,6 @@ digital_meter_widget_new ( self->caption = g_strdup (caption); self->note_length = note_length; self->note_type = note_type; - init_dm (self); return self; } @@ -1371,7 +1419,6 @@ _digital_meter_widget_new_for_position ( self->on_drag_end = on_drag_end; self->caption = g_strdup (caption); self->type = DIGITAL_METER_TYPE_POSITION; - init_dm (self); return self; } @@ -1398,6 +1445,12 @@ static void digital_meter_widget_class_init ( DigitalMeterWidgetClass * klass) { + GtkWidgetClass * wklass = + GTK_WIDGET_CLASS (klass); + wklass->snapshot = digital_meter_snapshot; + gtk_widget_class_set_css_name ( + wklass, "digital-meter"); + GObjectClass * oklass = G_OBJECT_CLASS (klass); oklass->finalize = @@ -1455,14 +1508,4 @@ digital_meter_widget_init ( gtk_widget_add_controller ( GTK_WIDGET (self), GTK_EVENT_CONTROLLER (click_gesture)); - -#if 0 - g_signal_connect ( - G_OBJECT (self), "screen-changed", - G_CALLBACK (on_screen_changed), self); -#endif - g_signal_connect ( - G_OBJECT (self), "resize", - G_CALLBACK (digital_meter_widget_on_resize), - self); } diff --git a/src/utils/cairo.c b/src/utils/cairo.c index eb55c57d6..442dc0c0f 100644 --- a/src/utils/cairo.c +++ b/src/utils/cairo.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2021 Alexandros Theodotou + * Copyright (C) 2019-2022 Alexandros Theodotou * * This file is part of Zrythm * @@ -17,10 +17,13 @@ * along with Zrythm. If not, see . */ +#include "zrythm-config.h" + #include "utils/cairo.h" #include "utils/dictionary.h" #include "utils/gtk.h" #include "utils/objects.h" +#include "utils/pango.h" #include "utils/string.h" #include "zrythm.h" #include "zrythm_app.h" @@ -124,8 +127,8 @@ z_cairo_create_pango_layout_from_description ( int ellipsize_padding) { PangoLayout * layout = - gtk_widget_create_pango_layout ( - widget, NULL); + z_pango_create_layout_from_description ( + widget, descr); if (ellipsize_mode > PANGO_ELLIPSIZE_NONE) { @@ -139,8 +142,6 @@ z_cairo_create_pango_layout_from_description ( pango_layout_set_ellipsize ( layout, ellipsize_mode); } - pango_layout_set_font_description ( - layout, descr); return layout; } diff --git a/src/utils/meson.build b/src/utils/meson.build index 7065e639a..458ddae5a 100644 --- a/src/utils/meson.build +++ b/src/utils/meson.build @@ -43,6 +43,7 @@ util_srcs = [ 'object_utils.c', 'object_pool.c', 'objects.c', + 'pango.c', 'resources.c', #'smf.c', 'sort.c', diff --git a/src/utils/pango.c b/src/utils/pango.c new file mode 100644 index 000000000..49b982d71 --- /dev/null +++ b/src/utils/pango.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2022 Alexandros Theodotou + * + * This file is part of Zrythm + * + * Zrythm is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Zrythm is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "zrythm-config.h" + +#include "utils/pango.h" +#include "utils/string.h" +#include "zrythm.h" + +#include +#include + +PangoLayout * +z_pango_create_layout_from_description ( + GtkWidget * widget, + PangoFontDescription * descr) +{ + PangoLayout * layout = NULL; + + char * str = + pango_font_description_to_string (descr); + g_debug ("font description: %s", str); + +#ifdef HAVE_BUNDLED_DSEG + if (string_contains_substr (str, "DSEG")) + { + FcConfig * fc_config = FcConfigCreate (); + + /* add fonts/zrythm dir to find DSEG font */ + char * fontdir = + zrythm_get_dir (ZRYTHM_DIR_SYSTEM_FONTSDIR); + FcConfigAppFontAddDir ( + fc_config, (const unsigned char *) fontdir); + g_free (fontdir); + FcConfigBuildFonts (fc_config); + FcConfigSetCurrent (fc_config); + + PangoFontMap * font_map = + pango_cairo_font_map_new_for_font_type ( + CAIRO_FONT_TYPE_FT); + pango_fc_font_map_set_config ( + PANGO_FC_FONT_MAP (font_map), fc_config); + + PangoContext * context = + pango_font_map_create_context ( + PANGO_FONT_MAP (font_map)); + PangoLayout * pangoLayout = + pango_layout_new (context); + + FcPattern *p = FcPatternCreate (); + FcObjectSet *os = + FcObjectSetBuild (FC_FAMILY, NULL); + FcFontSet *fs = FcFontList (fc_config, p, os); + FcPatternDestroy (p); + FcObjectSetDestroy (os); + for (int i = 0; i < fs->nfont; ++i) + { + guchar * fontName = + FcNameUnparse (fs->fonts[i]); + PangoFontDescription* fontDesc = + pango_font_description_from_string ( + (gchar*)fontName ); + pango_font_map_load_font ( + PANGO_FONT_MAP (font_map), context, + fontDesc ); + pango_font_description_free( fontDesc ); + g_debug ("fontname: %s", fontName); + g_free(fontName); + } + + layout = pangoLayout; + } + else + { +#endif + layout = + gtk_widget_create_pango_layout ( + widget, NULL); +#ifdef HAVE_BUNDLED_DSEG + } +#endif + g_free (str); + + g_return_val_if_fail (layout, NULL); + + pango_layout_set_font_description (layout, descr); + + /* try a small test */ + int test_w, test_h; + pango_layout_set_markup (layout, "test", -1); + pango_layout_get_pixel_size ( + layout, &test_w, &test_h); + + return layout; +} diff --git a/src/zrythm.c b/src/zrythm.c index 294e0df7b..ef18770d8 100644 --- a/src/zrythm.c +++ b/src/zrythm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2021 Alexandros Theodotou + * Copyright (C) 2018-2022 Alexandros Theodotou * * This file is part of Zrythm * @@ -560,6 +560,12 @@ zrythm_get_dir ( prefix, "share", "zrythm", "lv2", NULL); break; + case ZRYTHM_DIR_SYSTEM_FONTSDIR: + res = + g_build_filename ( + prefix, "share", "fonts", + "zrythm", NULL); + break; default: break; }