From 0261a9e510c766d7c8c69a8d66783bf050683c9f Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sat, 17 Sep 2011 08:55:09 -0700 Subject: [PATCH] Add some (particularly cheesy) drawing of a brace and clefs on the grand staff. This assumes the presence of the Gonville-26 and Gonville-Brace fonts, (by Simon Tatham). Though it would be simple enough to change the code to use any Lilypond-compatible font, (if the glyph selection were also update or just fixed to lookup glyphs by name instead of hard-coding the index). --- Makefile | 2 +- scherzo.c | 20 ++++++++++----- score.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++----- score.h | 5 ++++ 4 files changed, 91 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 3df2349..a5e8015 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ WARN_CFLAGS = -Wall -Wextra SCHERZO_CFLAGS = $(CFLAGS) $(WARN_CFLAGS) $(CONFIGURE_CFLAGS) $(extra_cflags) `pkg-config --cflags gtk+-2.0` -SCHERZO_LDFLAGS = $(LDFLAGS) `pkg-config --libs gtk+-2.0` +SCHERZO_LDFLAGS = $(LDFLAGS) `pkg-config --libs gtk+-2.0` -ltalloc # The user has not set any verbosity, default to quiet mode and inform the # user how to enable verbose compiles. diff --git a/scherzo.c b/scherzo.c index fbb23f0..c49584c 100644 --- a/scherzo.c +++ b/scherzo.c @@ -22,6 +22,12 @@ #define unused(foo) foo __attribute__((unused)) +typedef struct scherzo +{ + score_t *score; + int staff_height; +} scherzo_t; + static int on_delete_event_quit (unused (GtkWidget *widget), unused (GdkEvent *event), @@ -39,11 +45,12 @@ on_expose_event_draw (GtkWidget *widget, unused (GdkEventExpose *event), void * user_data) { - score_t *score = user_data; + scherzo_t *scherzo = user_data; + score_t *score = scherzo->score; cairo_t *cr; GtkAllocation allocation; static const int pad = 10; - int widget_width, staff_width; + int widget_width; gtk_widget_get_allocation (widget, &allocation); widget_width = allocation.width; @@ -56,7 +63,6 @@ on_expose_event_draw (GtkWidget *widget, /* Add some padding on the left/right */ cairo_translate (cr, pad, pad); - score_set_width (score, widget_width - 2 * pad); score_draw (score, cr); @@ -69,11 +75,13 @@ main (int argc, char *argv[]) { GtkWidget *window; GtkWidget *drawing_area; - score_t score; + scherzo_t scherzo; gtk_init (&argc, &argv); - score_init (&score); + scherzo.score = score_create (NULL); + scherzo.staff_height = 20; + score_set_staff_height (scherzo.score, scherzo.staff_height); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); @@ -88,7 +96,7 @@ main (int argc, char *argv[]) g_signal_connect (drawing_area, "expose-event", G_CALLBACK (on_expose_event_draw), - &score); + &scherzo); gtk_widget_show_all (window); diff --git a/score.c b/score.c index 8937162..598c298 100644 --- a/score.c +++ b/score.c @@ -32,10 +32,15 @@ struct score int width; }; -void -score_init (score_t *score) +score_t * +score_create (void *ctx) { + score_t *score; + + score = talloc (ctx, score_t); score_set_staff_height (score, 24); + + return score; } int @@ -52,13 +57,44 @@ score_set_width (score_t *score, int width) score->width = width; } +typedef enum score_clef +{ + SCORE_CLEF_G, + SCORE_CLEF_F +} score_clef_t; + static void -_draw_staff (score_t *score, cairo_t *cr) +_draw_staff (score_t *score, cairo_t *cr, score_clef_t clef) { int i; + cairo_glyph_t glyph; cairo_save (cr); + cairo_select_font_face (cr, "Gonville-26", 0, 0); + + /* XXX: This font size is a rough guess at best. We should figure + * out to correctly measure, size, and place clefs. */ + cairo_set_font_size (cr, 24); + + /* XXX: The hard-coded glyph indices here are very ugly. We should + * figure out how to lookup glyphs by name from this font. */ + switch (clef) { + case SCORE_CLEF_G: + default: + glyph.index = 46; + glyph.y = 3 * score->space_height; + break; + case SCORE_CLEF_F: + glyph.index = 45; + glyph.y = 1 * score->space_height; + break; + } + glyph.x = 2; + + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ + cairo_show_glyphs (cr, &glyph, 1); + cairo_rectangle (cr, 0.5, 0.5, score->width - 1.0, score->space_height * 4); @@ -79,23 +115,52 @@ _draw_staff (score_t *score, cairo_t *cr) static void _draw_grand_staff (score_t *score, cairo_t *cr) { +#define BRACE_GLYPHS 1 + cairo_glyph_t brace; cairo_save (cr); + /* Brace test */ + cairo_select_font_face (cr, "Gonville-Brace", 0, 0); + + /* XXX: This font size (in conjunction with the glyph selection) + * is a rough guess at best. We should figure out how the brace + * font is intended to be used and actually measure to find the + * correctly sized glyph. */ + cairo_set_font_size (cr, 40); + + cairo_translate (cr, 5, 0); + score->width -= 5; + + /* XXX: This hard-coded glyph index is pretty ugly. We should + * figure out how to lookup the glyph we want, (though, as it + * turns out, this brace font pretty much just has numbered glyph + * names for different sizes, so it wouldn't be all that different + * than just the bare index here). */ + brace.index = 185; + brace.x = 0; + brace.y = score->staff_height * 1.5; + + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ + cairo_show_glyphs (cr, &brace, 1); + + cairo_translate (cr, 2, 0); + score->width -= 2; + /* Vertical lines at each end */ cairo_rectangle (cr, 0.5, 0.5, score->width - 1.0, score->staff_height * 3); - cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); + cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ cairo_set_line_width (cr, 1.0); cairo_stroke (cr); /* Top staff */ - _draw_staff (score, cr); + _draw_staff (score, cr, SCORE_CLEF_G); /* Bottom staff */ cairo_translate (cr, 0, score->staff_height * 2); - _draw_staff (score, cr); + _draw_staff (score, cr, SCORE_CLEF_F); cairo_restore (cr); } diff --git a/score.h b/score.h index ece3951..02b56e3 100644 --- a/score.h +++ b/score.h @@ -21,6 +21,7 @@ #ifndef SCORE_H #define SCORE_H +#include #include typedef struct score score_t; @@ -38,6 +39,10 @@ score_create (void *ctx); int score_set_staff_height (score_t *score, int height); +/* Set the total width available for drawing the score. */ +void +score_set_width (score_t *score, int width); + /* Draw the given score_t onto the given cairo_t. * * The caller can call cairo_translate before calling score_draw to -- 2.43.0