fix ruler scaling -- #7226
[ardour.git] / libs / gtkmm2ext / cairo_icon.cc
1 /*
2     Copyright (C) 2015 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
21 #define OPTIONAL_CAIRO_IMAGE_SURFACE
22 #endif
23
24
25 #include "gtkmm2ext/cairo_icon.h"
26 #include "gtkmm2ext/gtk_ui.h"
27
28 using namespace Gtkmm2ext;
29
30 CairoIcon::CairoIcon (ArdourIcon::Icon t, uint32_t foreground_color)
31         : icon_type (t)
32         , fg (foreground_color)
33 {
34         add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
35 }
36
37 CairoIcon::~CairoIcon ()
38 {
39 }
40
41 void
42 CairoIcon::set_fg (uint32_t color)
43 {
44         fg = color;
45         queue_draw ();
46 }
47
48 void
49 CairoIcon::render (cairo_t* cr , cairo_rectangle_t* area)
50 {
51         const double scale = UI::instance()->ui_scale;
52         int width = get_width() * scale;
53         int height = get_height () * scale;
54
55         ArdourIcon::render (cr, icon_type, width, height, Off, fg);
56 }
57
58 bool
59 CairoIcon::on_expose_event (GdkEventExpose *ev)
60 {
61 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
62         Cairo::RefPtr<Cairo::Context> cr;
63         if (getenv("ARDOUR_IMAGE_SURFACE")) {
64                 if (!image_surface) {
65                         image_surface = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, get_width(), get_height());
66                 }
67                 cr = Cairo::Context::create (image_surface);
68         } else {
69                 cr = get_window()->create_cairo_context ();
70         }
71 #elif defined USE_CAIRO_IMAGE_SURFACE
72
73         if (!image_surface) {
74                 image_surface = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, get_width(), get_height());
75         }
76
77         Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create (image_surface);
78 #else
79         Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context ();
80 #endif
81
82         cr->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
83         cr->clip ();
84
85         cr->translate (ev->area.x, ev->area.y);
86
87         cairo_rectangle_t expose_area;
88         expose_area.x = ev->area.x;
89         expose_area.y = ev->area.y;
90         expose_area.width = ev->area.width;
91         expose_area.height = ev->area.height;
92
93         CairoIcon::render (cr->cobj(), &expose_area);
94
95 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
96         if (getenv("ARDOUR_IMAGE_SURFACE")) {
97 #endif
98 #if defined USE_CAIRO_IMAGE_SURFACE || defined OPTIONAL_CAIRO_IMAGE_SURFACE
99         image_surface->flush();
100         /* now blit our private surface back to the GDK one */
101
102         Cairo::RefPtr<Cairo::Context> cairo_context = get_window()->create_cairo_context ();
103
104         cairo_context->rectangle (ev->area.x, ev->area.y, ev->area.width, ev->area.height);
105         cairo_context->clip ();
106         cairo_context->set_source (image_surface, 0, 0);
107         cairo_context->set_operator (Cairo::OPERATOR_SOURCE);
108         cairo_context->paint ();
109 #endif
110 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
111         }
112 #endif
113
114         return true;
115 }