]> git.cworth.org Git - scherzo/commitdiff
Add some (particularly cheesy) drawing of a brace and clefs on the grand staff.
authorCarl Worth <cworth@cworth.org>
Sat, 17 Sep 2011 15:55:09 +0000 (08:55 -0700)
committerCarl Worth <cworth@cworth.org>
Sat, 17 Sep 2011 15:55:09 +0000 (08:55 -0700)
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
scherzo.c
score.c
score.h

index 3df2349670582e7e7aa607abbe0556beea729aab..a5e8015e0bb73a569359d0b04a76217e0739d97d 100644 (file)
--- 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.
index fbb23f0ed34da8efa4df50f9309258ca6c4840d7..c49584c2465e2c153f3f6690fa2df3045e829751 100644 (file)
--- a/scherzo.c
+++ b/scherzo.c
 
 #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 89371622453998b9536e879922662254d580b9f3..598c298752d13d42634b487176dd90267419169c 100644 (file)
--- 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 ece395137be54c92949c3d1951cc3f0d9368e1df..02b56e3a0956aa18238279b9db474555db6aac4d 100644 (file)
--- a/score.h
+++ b/score.h
@@ -21,6 +21,7 @@
 #ifndef SCORE_H
 #define SCORE_H
 
+#include <talloc.h>
 #include <cairo.h>
 
 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