>From 95935842f96790c7a0423636e3c8a03c2bd83e3a Mon Sep 17 00:00:00 2001 From: Knut Petersen Date: Fri, 25 Jun 2021 11:30:53 +0200 Subject: [PATCH] Cairo improvements - implemented rotation - coloring of grobs works - transparency works - improved drawing of ellipses --- lily/cairo.cc | 79 ++++++++++++++++++++++++++++++++++------------- scm/output-ps.scm | 7 ++++- 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/lily/cairo.cc b/lily/cairo.cc index dd7edc9d25..216b7ea4d4 100644 --- a/lily/cairo.cc +++ b/lily/cairo.cc @@ -436,7 +436,6 @@ LY_DEFINE (ly_cairo_set_paper_height, "ly:cairo-set-paper-height", // This assumes that lily_paper_height is set after lily_paper_width and pdf_file_name surface = cairo_pdf_surface_create(cairo_pdf_filename.c_str(), lily_paper_width, lily_paper_height); cr = cairo_create(surface); - cairo_set_source_rgba(cr,0, 0, 0, 1); return SCM_UNSPECIFIED; } @@ -498,42 +497,37 @@ LY_DEFINE (ly_cairo_set_staff_height, "ly:cairo-set-staff-height", -LY_DEFINE (ly_cairo_setrgbcolor, "ly:cairo-setrgbcolor", - 3, 0, 0, (SCM varr, SCM varg, SCM varb), - "CAIRO equivalent of the postscript primitive setrgbcolor.") +LY_DEFINE (ly_cairo_setrgbacolor, "ly:cairo-setrgbacolor", + 4, 0, 0, (SCM varr, SCM varg, SCM varb, SCM vara), + "CAIRO equivalent of our postscript procedure setrgbacolor" + " defined in music-drawing-routines.ps.") { if (!from_scm (ly_get_option (ly_symbol2scm ("cairotest")))) return SCM_UNSPECIFIED; LY_ASSERT_TYPE (scm_is_real, varr, 1); LY_ASSERT_TYPE (scm_is_real, varg, 2); LY_ASSERT_TYPE (scm_is_real, varb, 3); + LY_ASSERT_TYPE (scm_is_real, vara, 4); double r = from_scm (varr); double g = from_scm (varg); double b = from_scm (varb); - cairo_set_source_rgba(cr,r, g, b, 1.0); - debug_output (_f ("setrgbcolor r:%f g:%f b:%f", r, g, b)); + double a = from_scm (vara); + cairo_save(cr); + cairo_set_source_rgba(cr,r, g, b, a); + debug_output (_f ("setrgbacolor r:%f g:%f b:%f a:%f", r, g, b, a)); return SCM_UNSPECIFIED; } -LY_DEFINE (ly_cairo_setrgbacolor, "ly:cairo-setrgbacolor", - 4, 0, 0, (SCM varr, SCM varg, SCM varb, SCM vara), - "CAIRO equivalent of our postscript procedure setrgbacolor" +LY_DEFINE (ly_cairo_resetrgbacolor, "ly:cairo-resetrgbacolor", + 0, 0, 0, (), + "CAIRO equivalent of our postscript procedure resetrgbacolor" " defined in music-drawing-routines.ps.") { if (!from_scm (ly_get_option (ly_symbol2scm ("cairotest")))) return SCM_UNSPECIFIED; - LY_ASSERT_TYPE (scm_is_real, varr, 1); - LY_ASSERT_TYPE (scm_is_real, varg, 2); - LY_ASSERT_TYPE (scm_is_real, varb, 3); - LY_ASSERT_TYPE (scm_is_real, vara, 4); - double r = from_scm (varr); - double g = from_scm (varg); - double b = from_scm (varb); - double a = from_scm (vara); - cairo_set_source_rgba(cr,r, g, b, a); - debug_output (_f ("setrgbacolor r:%f g:%f b:%f a:%f", r, g, b, a)); + cairo_restore(cr); return SCM_UNSPECIFIED; } @@ -695,14 +689,13 @@ LY_DEFINE(ly_cairo_draw_ellipse, "ly:cairo-draw-ellipse", double yrad = from_scm (yradius); double blot = from_scm (thickness); double cx, cy; - cairo_matrix_t old_matrix; - cairo_get_matrix(cr, &old_matrix); + cairo_save(cr); cairo_get_current_point(cr,&cx, &cy); cairo_translate(cr,cx,cy); cairo_scale(cr,1,yrad/xrad); cairo_new_path(cr); cairo_arc(cr,0,0,xrad*sf,0,2*M_PI); - cairo_set_matrix(cr,&old_matrix); + cairo_restore(cr); cairo_set_line_width(cr,blot*sf); if (fill) { cairo_stroke_preserve(cr); @@ -714,6 +707,47 @@ LY_DEFINE(ly_cairo_draw_ellipse, "ly:cairo-draw-ellipse", +LY_DEFINE(ly_cairo_set_rotation, "ly:cairo-set-rotation", + 3, 0, 0, (SCM angle, SCM varx, SCM vary), + "CAIRO: equivalent of setrotation.") +{ + if (!from_scm (ly_get_option (ly_symbol2scm ("cairotest")))) + return SCM_UNSPECIFIED; + LY_ASSERT_TYPE (scm_is_real, angle, 1); + LY_ASSERT_TYPE (scm_is_real, varx, 2); + LY_ASSERT_TYPE (scm_is_real, vary, 3); + double ang = from_scm (angle); + double x = from_scm (varx); + double y = from_scm (vary); + debug_output(_f("set_rotation angle:%f, x:%f, y%f", ang, x, y)); + cairo_save(cr); + cairo_translate(cr,x*sf,-y*sf); + cairo_rotate(cr,-ang/180*M_PI); + cairo_translate(cr,-x*sf,y*sf); + return SCM_UNSPECIFIED; +} + + + +LY_DEFINE(ly_cairo_reset_rotation, "ly:cairo-reset-rotation", + 3, 0, 0, (SCM angle, SCM varx, SCM vary), + "CAIRO: equivalent of resetrotation.") +{ + if (!from_scm (ly_get_option (ly_symbol2scm ("cairotest")))) + return SCM_UNSPECIFIED; + LY_ASSERT_TYPE (scm_is_real, angle, 1); + LY_ASSERT_TYPE (scm_is_real, varx, 2); + LY_ASSERT_TYPE (scm_is_real, vary, 3); + double ang = from_scm (angle); + double x = from_scm (varx); + double y = from_scm (vary); + debug_output(_f("reset_rotation angle:%f, x:%f, y%f", ang, x, y)); + cairo_restore(cr); + return SCM_UNSPECIFIED; +} + + + LY_DEFINE(ly_cairo_at_eof, "ly:cairo-at-eof", 0, 0, 0, (), "CAIRO: Inform cairo to finalize the pdf and to clean up.") @@ -727,6 +761,7 @@ LY_DEFINE(ly_cairo_at_eof, "ly:cairo-at-eof", } + // // // still missing: music-drawing-routines.ps: /draw_partial_ellipse % filled connect x-radius y-radius startangle endangle thickness draw_partial_ellipse diff --git a/scm/output-ps.scm b/scm/output-ps.scm index 788af6141d..09ebf66997 100644 --- a/scm/output-ps.scm +++ b/scm/output-ps.scm @@ -215,19 +215,24 @@ (if a (list r g b a) (list r g b)))) (colors (length colorlist))) + (ly:cairo-setrgbacolor r g b (if (= colors 3) 1.0 a)) (if (= colors 3) (apply ly:format "gsave ~4f ~4f ~4f setrgbcolor\n" colorlist) (apply ly:format "gsave ~4f ~4f ~4f ~4f setrgbacolor\n" colorlist)))) ;; restore color from stack -(define (resetcolor) "grestore\n") +(define (resetcolor) + (ly:cairo-resetrgbacolor) + "grestore\n") ;; rotation around given point (define (setrotation ang x y) + (ly:cairo-set-rotation ang x y) (ly:format "gsave ~4f ~4f translate ~a rotate ~4f ~4f translate\n" x y ang (- x) (- y))) (define (resetrotation ang x y) + (ly:cairo-reset-rotation ang x y) "grestore\n") (define (unknown) -- 2.31.1