diff --git a/gtk2_ardour/ardour_button.cc b/gtk2_ardour/ardour_button.cc index 89f19b001e..8d4e9dca3e 100644 --- a/gtk2_ardour/ardour_button.cc +++ b/gtk2_ardour/ardour_button.cc @@ -193,6 +193,364 @@ ArdourButton::set_alignment (const float xa, const float ya) _yalign = ya; } + +/* TODO make this a dedicated function elsewhere. + * + * Option 1: + * virtual ArdourButton::render_vector_icon() + * ArdourIconButton::render_vector_icon + * + * Option 2: + * ARDOUR_UI_UTILS::render_vector_icon() + */ +static void +render_vector_icon (cairo_t *cr, + const enum ArdourButton::Icon icon, + const int width, const int height, + const Gtkmm2ext::ActiveState state, + const ArdourCanvas::Color fg_color) +{ + +#define VECTORICONSTROKEFILL(fillalpha) \ + cairo_set_line_width(cr, 1.5); \ + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); \ + cairo_stroke_preserve(cr); \ + cairo_set_source_rgba (cr, 1, 1, 1, (fillalpha)); \ + cairo_fill(cr); + + + /* TODO separate these into dedicated class + * it may also be efficient to render them only once for every size (image-surface) */ + switch (icon) { + + case ArdourButton::RecTapeMode: + { + const double x = width * .5; + const double y = height * .5; + const double r = std::min(x, y) * .6; + const double slit = .11 * M_PI; + cairo_save(cr); + cairo_translate(cr, x, y); + + cairo_arc (cr, 0, 0, r, 0, 2 * M_PI); + if (state == Gtkmm2ext::ExplicitActive) { + cairo_set_source_rgba (cr, .95, .1, .1, 1.); + } else { + cairo_set_source_rgba (cr, .95, .44, .44, 1.); // #f46f6f + } + cairo_fill_preserve(cr); + cairo_set_source_rgba (cr, .0, .0, .0, .5); + cairo_set_line_width(cr, 1); + cairo_stroke(cr); + + cairo_save(cr); + cairo_set_source_rgba (cr, .15, .07, .07, 1.0); + + cairo_rotate (cr, -.5 * M_PI); + cairo_move_to(cr, 0, 0); + cairo_arc (cr, 0, 0, r *.85, -slit, slit); + cairo_line_to(cr, 0, 0); + cairo_close_path(cr); + + cairo_fill(cr); + cairo_rotate (cr, 2. * M_PI / 3.); + + cairo_move_to(cr, 0, 0); + cairo_arc (cr, 0, 0, r *.85, -slit, slit); + cairo_line_to(cr, 0, 0); + cairo_close_path(cr); + cairo_fill(cr); + + cairo_rotate (cr, 2. * M_PI / 3.); + cairo_move_to(cr, 0, 0); + cairo_arc (cr, 0, 0, r *.85, -slit, slit); + cairo_line_to(cr, 0, 0); + cairo_close_path(cr); + cairo_fill(cr); + + cairo_restore(cr); + + cairo_arc (cr, 0, 0, r * .3, 0, 2 * M_PI); + if (state == Gtkmm2ext::ExplicitActive) + cairo_set_source_rgba (cr, .95, .1, .1, 1.); + else + cairo_set_source_rgba (cr, .95, .44, .44, 1.); // #f46f6f + cairo_fill(cr); + cairo_set_source_rgba (cr, .0, .0, .0, 1.0); + cairo_arc (cr, 0, 0, r *.15, 0, 2 * M_PI); // hole in the middle + cairo_fill(cr); + + cairo_restore(cr); + } + break; + case ArdourButton::RecButton: + { + const double x = width * .5; + const double y = height * .5; + const double r = std::min(x, y) * .55; + cairo_arc (cr, x, y, r, 0, 2 * M_PI); + if (state == Gtkmm2ext::ExplicitActive) + cairo_set_source_rgba (cr, .95, .1, .1, 1.); + else + cairo_set_source_rgba (cr, .95, .44, .44, 1.); // #f46f6f + cairo_fill_preserve(cr); + cairo_set_source_rgba (cr, .0, .0, .0, .8); + cairo_set_line_width(cr, 1); + cairo_stroke(cr); + } + break; + case ArdourButton::CloseCross: + { + const double x = width * .5; + const double y = height * .5; + const double o = .5 + std::min(x, y) * .4; + ArdourCanvas::set_source_rgba (cr, fg_color); + cairo_set_line_width(cr, 1); + cairo_move_to(cr, x-o, y-o); + cairo_line_to(cr, x+o, y+o); + cairo_move_to(cr, x+o, y-o); + cairo_line_to(cr, x-o, y+o); + cairo_stroke(cr); + } + break; + case ArdourButton::StripWidth: + { + const double x0 = width * .2; + const double x1 = width * .8; + + const double y0 = height * .25; + const double y1= height * .75; + + const double ym= height * .5; + + // arrow + const double xa0= height * .39; + const double xa1= height * .61; + const double ya0= height * .35; + const double ya1= height * .65; + + ArdourCanvas::set_source_rgba (cr, fg_color); + cairo_set_line_width(cr, 1); + + // left + right + cairo_move_to(cr, x0, y0); + cairo_line_to(cr, x0, y1); + cairo_move_to(cr, x1, y0); + cairo_line_to(cr, x1, y1); + + // horiz center line + cairo_move_to(cr, x0, ym); + cairo_line_to(cr, x1, ym); + + // arrow left + cairo_move_to(cr, x0, ym); + cairo_line_to(cr, xa0, ya0); + cairo_move_to(cr, x0, ym); + cairo_line_to(cr, xa0, ya1); + + // arrow right + cairo_move_to(cr, x1, ym); + cairo_line_to(cr, xa1, ya0); + cairo_move_to(cr, x1, ym); + cairo_line_to(cr, xa1, ya1); + cairo_stroke(cr); + } + break; + case ArdourButton::DinMidi: + { + const double x = width * .5; + const double y = height * .5; + const double r = std::min(x, y) * .75; + ArdourCanvas::set_source_rgba (cr, fg_color); + cairo_set_line_width(cr, 1); + cairo_arc (cr, x, y, r, .57 * M_PI, 2.43 * M_PI); + cairo_stroke(cr); + + // pins equally spaced 45deg + cairo_arc (cr, x, y * 0.5, r * .15, 0, 2 * M_PI); + cairo_fill(cr); + cairo_arc (cr, x * 0.5, y, r * .15, 0, 2 * M_PI); + cairo_fill(cr); + cairo_arc (cr, x * 1.5, y, r * .15, 0, 2 * M_PI); + cairo_fill(cr); + // .5 + .5 * .5 * sin(45deg), 1.5 - .5 * .5 * cos(45deg) + cairo_arc (cr, x * 0.677, y * .677, r * .15, 0, 2 * M_PI); + cairo_fill(cr); + cairo_arc (cr, x * 1.323, y * .677, r * .15, 0, 2 * M_PI); + cairo_fill(cr); + + // bottom notch + cairo_arc (cr, x, y+r, r * .26, 1.05 * M_PI, 1.95 * M_PI); + cairo_stroke(cr); + } + break; + case ArdourButton::TransportStop: + { + const int wh = std::min (width, height); + cairo_rectangle (cr, + (width - wh) * .5 + wh * .25, + (height - wh) * .5 + wh * .25, + wh * .5, wh * .5); + + VECTORICONSTROKEFILL(0.8); + } + break; + case ArdourButton::TransportPlay: + { + const int wh = std::min (width, height) * .5; + const double y = height * .5; + const double x = width - wh; + + const float tri = ceil(.577 * wh); // 1/sqrt(3) + + cairo_move_to (cr, x + wh * .5, y); + cairo_line_to (cr, x - wh * .5, y - tri); + cairo_line_to (cr, x - wh * .5, y + tri); + cairo_close_path (cr); + + VECTORICONSTROKEFILL(0.8); + } + break; + case ArdourButton::TransportPanic: + { + const int wh = std::min (width, height) * .1; + const double xc = width * .5; + const double yh = height; + cairo_rectangle (cr, + xc - wh, yh *.19, + wh * 2, yh *.41); + VECTORICONSTROKEFILL(0.8); + + cairo_arc (cr, xc, yh *.75, wh, 0, 2 * M_PI); + VECTORICONSTROKEFILL(0.8); + } + break; + case ArdourButton::TransportStart: + case ArdourButton::TransportEnd: + case ArdourButton::TransportRange: + { + // small play triangle + int wh = std::min (width, height); + const double y = height * .5; + const double x = width - wh * .5; + wh *= .18; + const float tri = ceil(.577 * wh * 2); // 1/sqrt(3) + + const float ln = std::min (width, height) * .07; + + if (icon == ArdourButton::TransportStart || icon == ArdourButton::TransportRange) { + cairo_rectangle (cr, + x - wh - ln, y - tri * 1.7, + ln * 2, tri * 3.4); + + VECTORICONSTROKEFILL(1.0); + } + + if (icon == ArdourButton::TransportEnd || icon == ArdourButton::TransportRange) { + cairo_rectangle (cr, + x + wh - ln, y - tri * 1.7, + ln * 2, tri * 3.4); + + VECTORICONSTROKEFILL(1.0); + } + + if (icon == ArdourButton::TransportStart) { + cairo_move_to (cr, x - wh, y); + cairo_line_to (cr, x + wh, y - tri); + cairo_line_to (cr, x + wh, y + tri); + } else { + cairo_move_to (cr, x + wh, y); + cairo_line_to (cr, x - wh, y - tri); + cairo_line_to (cr, x - wh, y + tri); + } + + cairo_close_path (cr); + VECTORICONSTROKEFILL(1.0); + } + break; + case ArdourButton::TransportLoop: + { + const double x = width * .5; + const double y = height * .5; + const double r = std::min(x, y); + + cairo_arc (cr, x, y, r * .62, 0, 2 * M_PI); + cairo_arc_negative (cr, x, y, r * .35, 2 * M_PI, 0); + + VECTORICONSTROKEFILL(1.0); +#define ARCARROW(rad, ang) \ + x + (rad) * sin((ang) * 2.0 * M_PI), y + (rad) * cos((ang) * 2.0 * M_PI) + + cairo_move_to (cr, ARCARROW(r * .35, .72)); + cairo_line_to (cr, ARCARROW(r * .15, .72)); + cairo_line_to (cr, ARCARROW(r * .56, .60)); + cairo_line_to (cr, ARCARROW(r * .75, .72)); + cairo_line_to (cr, ARCARROW(r * .62, .72)); + + cairo_set_source_rgba (cr, 0, 0, 0, 1.0); + cairo_stroke_preserve(cr); + cairo_close_path (cr); + cairo_set_source_rgba (cr, 1, 1, 1, 1.0); + cairo_fill(cr); +#undef ARCARROW + } + break; + case ArdourButton::TransportMetronom: + { + const double x = width * .5; + const double y = height * .5; + const double wh = std::min(x, y); + const double h = wh * .85; + const double w = wh * .55; + const double lw = w * .34; + + cairo_rectangle (cr, + x - w * .7, y + h * .25, + w * 1.4, lw); + + VECTORICONSTROKEFILL(1.0); + + cairo_move_to (cr, x - w, y + h); + cairo_line_to (cr, x + w, y + h); + cairo_line_to (cr, x + w * .35, y - h); + cairo_line_to (cr, x - w * .35, y - h); + cairo_line_to (cr, x - w, y + h); + + cairo_move_to (cr, x - w + lw, y + h -lw); + cairo_line_to (cr, x - w * .35 + lw, y - h + lw); + cairo_line_to (cr, x + w * .35 - lw, y - h + lw); + cairo_line_to (cr, x + w - lw, y + h -lw); + cairo_line_to (cr, x - w + lw, y + h -lw); + + VECTORICONSTROKEFILL(1.0); + + // ddx = .70 w = .75 * .5 wh = .375 wh + // ddy = .75 h - lw = .75 * .8 wh - wh .5 * .2 = .5 wh + // ang = (ddx/ddy): + // -> angle = atan (ang) = atan (375 / .5) ~= 36deg + const double dx = lw * .2; // 1 - cos(tan^-1(ang)) + const double dy = lw * .4; // 1 - sin(tan^-1(ang)) + cairo_move_to (cr, x - w * .3 , y + h * .25 + lw * .5); + cairo_line_to (cr, x - w + dx , y - h + lw + dy); + cairo_line_to (cr, x - w + lw , y - h + lw); + cairo_line_to (cr, x - w * .3 + lw, y + h * .25 + lw * .5); + cairo_close_path (cr); + + VECTORICONSTROKEFILL(1.0); + + cairo_rectangle (cr, + x - w * .7, y + h * .25, + w * 1.4, lw); + cairo_fill(cr); + } + break; + default: + // missing icon + assert(0); + } // end case(icon) +#undef VECTORICONSTROKEFILL +} + void ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) { @@ -287,13 +645,6 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) } } -#define VECTORICONSTROKEFILL(fillalpha) \ - cairo_set_line_width(cr, 1.5); \ - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); \ - cairo_stroke_preserve(cr); \ - cairo_set_source_rgba (cr, 1, 1, 1, (fillalpha)); \ - cairo_fill(cr); - //Pixbuf, if any if (_pixbuf) { double x = rint((get_width() - _pixbuf->get_width()) * .5); @@ -316,310 +667,9 @@ ArdourButton::render (cairo_t* cr, cairo_rectangle_t *) cairo_fill (cr); } else /* VectorIcons are exclusive to Pixbuf Icons */ - /* TODO separate these into dedicated class - * it may also be efficient to render them only once for every size (image-surface) */ - if ((_elements & VectorIcon) && _icon == RecTapeMode) { - const double x = get_width() * .5; - const double y = get_height() * .5; - const double r = std::min(x, y) * .6; - const double slit = .11 * M_PI; - cairo_save(cr); - cairo_translate(cr, x, y); - - cairo_arc (cr, 0, 0, r, 0, 2 * M_PI); - if (active_state() == Gtkmm2ext::ExplicitActive) { - cairo_set_source_rgba (cr, .95, .1, .1, 1.); - } else { - cairo_set_source_rgba (cr, .95, .44, .44, 1.); // #f46f6f - } - cairo_fill_preserve(cr); - cairo_set_source_rgba (cr, .0, .0, .0, .5); - cairo_set_line_width(cr, 1); - cairo_stroke(cr); - - cairo_save(cr); - cairo_set_source_rgba (cr, .15, .07, .07, 1.0); - - cairo_rotate (cr, -.5 * M_PI); - cairo_move_to(cr, 0, 0); - cairo_arc (cr, 0, 0, r *.85, -slit, slit); - cairo_line_to(cr, 0, 0); - cairo_close_path(cr); - - cairo_fill(cr); - cairo_rotate (cr, 2. * M_PI / 3.); - - cairo_move_to(cr, 0, 0); - cairo_arc (cr, 0, 0, r *.85, -slit, slit); - cairo_line_to(cr, 0, 0); - cairo_close_path(cr); - cairo_fill(cr); - - cairo_rotate (cr, 2. * M_PI / 3.); - cairo_move_to(cr, 0, 0); - cairo_arc (cr, 0, 0, r *.85, -slit, slit); - cairo_line_to(cr, 0, 0); - cairo_close_path(cr); - cairo_fill(cr); - - cairo_restore(cr); - - cairo_arc (cr, 0, 0, r * .3, 0, 2 * M_PI); - if (active_state() == Gtkmm2ext::ExplicitActive) - cairo_set_source_rgba (cr, .95, .1, .1, 1.); - else - cairo_set_source_rgba (cr, .95, .44, .44, 1.); // #f46f6f - cairo_fill(cr); - cairo_set_source_rgba (cr, .0, .0, .0, 1.0); - cairo_arc (cr, 0, 0, r *.15, 0, 2 * M_PI); // hole in the middle - cairo_fill(cr); - - cairo_restore(cr); + if (_elements & VectorIcon) { + render_vector_icon (cr, _icon, get_width(), get_height(), active_state(), text_color); } - else if ((_elements & VectorIcon) && _icon == RecButton) { - const double x = get_width() * .5; - const double y = get_height() * .5; - const double r = std::min(x, y) * .55; - cairo_arc (cr, x, y, r, 0, 2 * M_PI); - if (active_state() == Gtkmm2ext::ExplicitActive) - cairo_set_source_rgba (cr, .95, .1, .1, 1.); - else - cairo_set_source_rgba (cr, .95, .44, .44, 1.); // #f46f6f - cairo_fill_preserve(cr); - cairo_set_source_rgba (cr, .0, .0, .0, .8); - cairo_set_line_width(cr, 1); - cairo_stroke(cr); - } - else if ((_elements & VectorIcon) && _icon == CloseCross) { - const double x = get_width() * .5; - const double y = get_height() * .5; - const double o = .5 + std::min(x, y) * .4; - ArdourCanvas::set_source_rgba (cr, text_color); - cairo_set_line_width(cr, 1); - cairo_move_to(cr, x-o, y-o); - cairo_line_to(cr, x+o, y+o); - cairo_move_to(cr, x+o, y-o); - cairo_line_to(cr, x-o, y+o); - cairo_stroke(cr); - } - else if ((_elements & VectorIcon) && _icon == StripWidth) { - const double x0 = get_width() * .2; - const double x1 = get_width() * .8; - - const double y0 = get_height() * .25; - const double y1= get_height() * .75; - - const double ym= get_height() * .5; - - // arrow - const double xa0= get_height() * .39; - const double xa1= get_height() * .61; - const double ya0= get_height() * .35; - const double ya1= get_height() * .65; - - ArdourCanvas::set_source_rgba (cr, text_color); - cairo_set_line_width(cr, 1); - - // left + right - cairo_move_to(cr, x0, y0); - cairo_line_to(cr, x0, y1); - cairo_move_to(cr, x1, y0); - cairo_line_to(cr, x1, y1); - - // horiz center line - cairo_move_to(cr, x0, ym); - cairo_line_to(cr, x1, ym); - - // arrow left - cairo_move_to(cr, x0, ym); - cairo_line_to(cr, xa0, ya0); - cairo_move_to(cr, x0, ym); - cairo_line_to(cr, xa0, ya1); - - // arrow right - cairo_move_to(cr, x1, ym); - cairo_line_to(cr, xa1, ya0); - cairo_move_to(cr, x1, ym); - cairo_line_to(cr, xa1, ya1); - cairo_stroke(cr); - } - else if ((_elements & VectorIcon) && _icon == DinMidi) { - const double x = get_width() * .5; - const double y = get_height() * .5; - const double r = std::min(x, y) * .75; - ArdourCanvas::set_source_rgba (cr, text_color); - cairo_set_line_width(cr, 1); - cairo_arc (cr, x, y, r, .57 * M_PI, 2.43 * M_PI); - cairo_stroke(cr); - - // pins equally spaced 45deg - cairo_arc (cr, x, y * 0.5, r * .15, 0, 2 * M_PI); - cairo_fill(cr); - cairo_arc (cr, x * 0.5, y, r * .15, 0, 2 * M_PI); - cairo_fill(cr); - cairo_arc (cr, x * 1.5, y, r * .15, 0, 2 * M_PI); - cairo_fill(cr); - // .5 + .5 * .5 * sin(45deg), 1.5 - .5 * .5 * cos(45deg) - cairo_arc (cr, x * 0.677, y * .677, r * .15, 0, 2 * M_PI); - cairo_fill(cr); - cairo_arc (cr, x * 1.323, y * .677, r * .15, 0, 2 * M_PI); - cairo_fill(cr); - - // bottom notch - cairo_arc (cr, x, y+r, r * .26, 1.05 * M_PI, 1.95 * M_PI); - cairo_stroke(cr); - } - else if ((_elements & VectorIcon) && _icon == TransportStop) { - const int wh = std::min (get_width(), get_height()); - cairo_rectangle (cr, - (get_width() - wh) * .5 + wh * .25, - (get_height() - wh) * .5 + wh * .25, - wh * .5, wh * .5); - - VECTORICONSTROKEFILL(0.8); - } - else if ((_elements & VectorIcon) && _icon == TransportPlay) { - const int wh = std::min (get_width(), get_height()) * .5; - const double y = get_height() * .5; - const double x = get_width() - wh; - - const float tri = ceil(.577 * wh); // 1/sqrt(3) - - cairo_move_to (cr, x + wh * .5, y); - cairo_line_to (cr, x - wh * .5, y - tri); - cairo_line_to (cr, x - wh * .5, y + tri); - cairo_close_path (cr); - - VECTORICONSTROKEFILL(0.8); - } - else if ((_elements & VectorIcon) && _icon == TransportPanic) { - const int wh = std::min (get_width(), get_height()) * .1; - const double xc = get_width() * .5; - const double yh = get_height(); - cairo_rectangle (cr, - xc - wh, yh *.19, - wh * 2, yh *.41); - VECTORICONSTROKEFILL(0.8); - - cairo_arc (cr, xc, yh *.75, wh, 0, 2 * M_PI); - VECTORICONSTROKEFILL(0.8); - } - else if ((_elements & VectorIcon) && (_icon == TransportStart || _icon == TransportEnd || _icon == TransportRange)) { - // small play triangle - int wh = std::min (get_width(), get_height()); - const double y = get_height() * .5; - const double x = get_width() - wh * .5; - wh *= .18; - const float tri = ceil(.577 * wh * 2); // 1/sqrt(3) - - const float ln = std::min (get_width(), get_height()) * .07; - - if (_icon == TransportStart || _icon == TransportRange) { - cairo_rectangle (cr, - x - wh - ln, y - tri * 1.7, - ln * 2, tri * 3.4); - - VECTORICONSTROKEFILL(1.0); - } - - if (_icon == TransportEnd || _icon == TransportRange) { - cairo_rectangle (cr, - x + wh - ln, y - tri * 1.7, - ln * 2, tri * 3.4); - - VECTORICONSTROKEFILL(1.0); - } - - if (_icon == TransportStart) { - cairo_move_to (cr, x - wh, y); - cairo_line_to (cr, x + wh, y - tri); - cairo_line_to (cr, x + wh, y + tri); - } else { - cairo_move_to (cr, x + wh, y); - cairo_line_to (cr, x - wh, y - tri); - cairo_line_to (cr, x - wh, y + tri); - } - - cairo_close_path (cr); - VECTORICONSTROKEFILL(1.0); - } - else if ((_elements & VectorIcon) && _icon == TransportLoop) { - const double x = get_width() * .5; - const double y = get_height() * .5; - const double r = std::min(x, y); - - cairo_arc (cr, x, y, r * .62, 0, 2 * M_PI); - cairo_arc_negative (cr, x, y, r * .35, 2 * M_PI, 0); - - VECTORICONSTROKEFILL(1.0); -#define ARCARROW(rad, ang) \ - x + (rad) * sin((ang) * 2.0 * M_PI), y + (rad) * cos((ang) * 2.0 * M_PI) - - cairo_move_to (cr, ARCARROW(r * .35, .72)); - cairo_line_to (cr, ARCARROW(r * .15, .72)); - cairo_line_to (cr, ARCARROW(r * .56, .60)); - cairo_line_to (cr, ARCARROW(r * .75, .72)); - cairo_line_to (cr, ARCARROW(r * .62, .72)); - - cairo_set_source_rgba (cr, 0, 0, 0, 1.0); - cairo_stroke_preserve(cr); - cairo_close_path (cr); - cairo_set_source_rgba (cr, 1, 1, 1, 1.0); - cairo_fill(cr); -#undef ARCARROW - } - else if ((_elements & VectorIcon) && _icon == TransportMetronom) { - const double x = get_width() * .5; - const double y = get_height() * .5; - const double wh = std::min(x, y); - const double h = wh * .85; - const double w = wh * .55; - const double lw = w * .34; - - cairo_rectangle (cr, - x - w * .7, y + h * .25, - w * 1.4, lw); - - VECTORICONSTROKEFILL(1.0); - - cairo_move_to (cr, x - w, y + h); - cairo_line_to (cr, x + w, y + h); - cairo_line_to (cr, x + w * .35, y - h); - cairo_line_to (cr, x - w * .35, y - h); - cairo_line_to (cr, x - w, y + h); - - cairo_move_to (cr, x - w + lw, y + h -lw); - cairo_line_to (cr, x - w * .35 + lw, y - h + lw); - cairo_line_to (cr, x + w * .35 - lw, y - h + lw); - cairo_line_to (cr, x + w - lw, y + h -lw); - cairo_line_to (cr, x - w + lw, y + h -lw); - - VECTORICONSTROKEFILL(1.0); - - // ddx = .70 w = .75 * .5 wh = .375 wh - // ddy = .75 h - lw = .75 * .8 wh - wh .5 * .2 = .5 wh - // ang = (ddx/ddy): - // -> angle = atan (ang) = atan (375 / .5) ~= 36deg - const double dx = lw * .2; // 1 - cos(tan^-1(ang)) - const double dy = lw * .4; // 1 - sin(tan^-1(ang)) - cairo_move_to (cr, x - w * .3 , y + h * .25 + lw * .5); - cairo_line_to (cr, x - w + dx , y - h + lw + dy); - cairo_line_to (cr, x - w + lw , y - h + lw); - cairo_line_to (cr, x - w * .3 + lw, y + h * .25 + lw * .5); - cairo_close_path (cr); - - VECTORICONSTROKEFILL(1.0); - - cairo_rectangle (cr, - x - w * .7, y + h * .25, - w * 1.4, lw); - cairo_fill(cr); - } - else if (_elements & VectorIcon) { - // missing icon - assert(0); - } -#undef VECTORICONSTROKEFILL const int text_margin = char_pixel_width(); // Text, if any