static void plot_data_fft(SFSUI* ui) { cairo_t* cr; cr = cairo_create (ui->sf_dat); rounded_rectangle (cr, SS_BORDER, SS_BORDER, SS_SIZE, SS_SIZE, SS_BORDER); cairo_clip_preserve (cr); const float persistence = robtk_dial_get_value(ui->screen); float transp; cairo_set_operator (cr, CAIRO_OPERATOR_OVER); if (persistence > 0) { cairo_set_source_rgba(cr, 0, 0, 0, .25 - .0025 * persistence); transp = 0.05; } else { cairo_set_source_rgba(cr, 0, 0, 0, 1.0); transp = .5; } cairo_fill(cr); cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_width (cr, 1.0); const float xmid = rintf(SS_BORDER + SS_SIZE *.5) + .5; const float dnum = SS_SIZE / ui->log_base; const float denom = ui->log_rate / (float)ui->fft_bins; cairo_set_operator (cr, CAIRO_OPERATOR_OVER); for (uint32_t i = 1; i < ui->fft_bins-1 ; ++i) { if (ui->level[i] < 0) continue; const float level = MAKEUP_GAIN + fftx_power_to_dB(ui->level[i]); if (level < -80) continue; const float y = rintf(SS_BORDER + SS_SIZE - dnum * fast_log10(1.0 + i * denom)) + .5; const float y1 = rintf(SS_BORDER + SS_SIZE - dnum * fast_log10(1.0 + (i+1) * denom)) + .5; const float pk = level > 0.0 ? 1.0 : (80 + level) / 80.0; const float a_lr = ui->lr[i]; float clr[3]; hsl2rgb(clr, .70 - .72 * pk, .9, .3 + pk * .4); cairo_set_source_rgba(cr, clr[0], clr[1], clr[2], transp + pk * .2); cairo_set_line_width (cr, MAX(1.0, (y - y1))); cairo_move_to(cr, xmid, y); cairo_line_to(cr, SS_BORDER + SS_SIZE * a_lr, y); cairo_stroke(cr); } cairo_destroy (cr); }
static cairo_time_t do_strokes (cairo_t *cr, int width, int height, int loops) { /* a pair of overlapping rectangles */ rounded_rectangle (cr, 2, 2, width/2. + 10, height/2. + 10, 10); rounded_rectangle (cr, width/2. - 10, height/2. - 10, width/2. - 2, height/2. - 2, 10); cairo_set_line_width (cr, 2.); cairo_perf_timer_start (); cairo_perf_set_thread_aware (cr, FALSE); while (loops--) { if (loops == 0) cairo_perf_set_thread_aware (cr, TRUE); cairo_stroke_preserve (cr); } cairo_perf_timer_stop (); cairo_new_path (cr); return cairo_perf_timer_elapsed (); }
static void clip_2 (cairo_t *cr) { cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); rounded_rectangle (cr, 50, 50, 100, 100, 15); rounded_rectangle (cr, 60, 60, 80, 80, 5); cairo_clip (cr); cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING); }
static void draw_volume_boxes (GsdMediaKeysWindow *window, cairo_t *cr, double percentage, double _x0, double _y0, double width, double height) { gdouble x1; GdkColor color; double r, g, b; GtkStyle *style; _x0 += 0.5; _y0 += 0.5; height = round (height) - 1; width = round (width) - 1; x1 = round ((width - 1) * percentage); style = gtk_widget_get_style (GTK_WIDGET (window)); /* bar background */ color_reverse (&style->dark[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; rounded_rectangle (cr, 1.0, _x0, _y0, height / 6, width, height); cairo_set_source_rgba (cr, r, g, b, FG_ALPHA / 2); cairo_fill_preserve (cr); /* bar border */ color_reverse (&style->light[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; cairo_set_source_rgba (cr, r, g, b, FG_ALPHA / 2); cairo_set_line_width (cr, 1); cairo_stroke (cr); /* bar progress */ if (percentage < 0.01) return; color = style->bg[GTK_STATE_NORMAL]; r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; rounded_rectangle (cr, 1.0, _x0 + 0.5, _y0 + 0.5, height / 6 - 0.5, x1, height - 1); cairo_set_source_rgba (cr, r, g, b, FG_ALPHA); cairo_fill (cr); }
static cairo_test_status_t clip_eo_aa (cairo_t *cr, int width, int height) { background (cr); cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT); cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); rounded_rectangle(cr, 0, 0, 40, 100, 10); rounded_rectangle(cr, 60, 0, 40, 100, 10); cairo_clip(cr); foreground (cr); return CAIRO_TEST_SUCCESS; }
static void label_draw_background_and_frame (GtkWidget *widget, cairo_t *cr, gboolean for_shape) { GdkRGBA shape_color = { 0, 0, 0, 1 }; GdkRGBA *rgba; GtkAllocation allocation; rgba = g_object_get_data (G_OBJECT (widget), "rgba"); gtk_widget_get_allocation (widget, &allocation); cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); /* edge outline */ if (for_shape) gdk_cairo_set_source_rgba (cr, &shape_color); else cairo_set_source_rgba (cr, 0, 0, 0, 0.5); rounded_rectangle (cr, LABEL_WINDOW_EDGE_THICKNESS / 2.0, LABEL_WINDOW_EDGE_THICKNESS / 2.0, allocation.width - LABEL_WINDOW_EDGE_THICKNESS, allocation.height - LABEL_WINDOW_EDGE_THICKNESS, LABEL_CORNER_RADIUS, LABEL_CORNER_RADIUS); cairo_set_line_width (cr, LABEL_WINDOW_EDGE_THICKNESS); cairo_stroke (cr); /* fill */ if (for_shape) { gdk_cairo_set_source_rgba (cr, &shape_color); } else { rgba->alpha = 0.75; gdk_cairo_set_source_rgba (cr, rgba); } rounded_rectangle (cr, LABEL_WINDOW_EDGE_THICKNESS, LABEL_WINDOW_EDGE_THICKNESS, allocation.width - LABEL_WINDOW_EDGE_THICKNESS * 2, allocation.height - LABEL_WINDOW_EDGE_THICKNESS * 2, LABEL_CORNER_RADIUS - LABEL_WINDOW_EDGE_THICKNESS / 2.0, LABEL_CORNER_RADIUS - LABEL_WINDOW_EDGE_THICKNESS / 2.0); cairo_fill (cr); cairo_restore (cr); }
void cairo_container::apply_clip( cairo_t* cr ) { for(const auto& clip_box : m_clips) { rounded_rectangle(cr, clip_box.box, clip_box.radius); cairo_clip(cr); } }
static cairo_perf_ticks_t do_rectangle (cairo_t *cr, int width, int height) { cairo_perf_timer_start (); rounded_rectangle (cr, 0, 0, width, height, 3.0); cairo_fill (cr); cairo_perf_timer_stop (); return cairo_perf_timer_elapsed (); }
static gboolean avatar_image_expose_event (GtkWidget *widget, GdkEventExpose *event) { GiggleAvatarImagePriv *priv = GET_PRIV (widget); GtkAllocation allocation; GtkRequisition requisition; GtkStyle *style; float xalign, yalign; double x, y; int w, h; cairo_t *cr; gtk_widget_size_request (widget, &requisition); gtk_widget_get_allocation (widget, &allocation); style = gtk_widget_get_style (widget); cr = gdk_cairo_create (event->window); gdk_cairo_region (cr, event->region); cairo_clip (cr); w = requisition.width; h = requisition.height; gtk_misc_get_alignment (GTK_MISC (widget), &xalign, &yalign); cairo_translate (cr, (int) ((allocation.width - w) * xalign), (int) ((allocation.height - h) * yalign)); rounded_rectangle (cr, 0.5, 0.5, w - 1, h - 1, MIN (w, h) * 0.2); gdk_cairo_set_source_color (cr, &style->base[GTK_STATE_NORMAL]); cairo_fill_preserve (cr); if (priv->pixbuf) { x = (w - gdk_pixbuf_get_width (priv->pixbuf)) * 0.5; y = (h - gdk_pixbuf_get_height (priv->pixbuf)) * 0.5; gdk_cairo_set_source_pixbuf (cr, priv->pixbuf, x, y); cairo_fill_preserve (cr); } gdk_cairo_set_source_color (cr, &style->text[GTK_STATE_NORMAL]); cairo_set_line_width (cr, 1); cairo_stroke (cr); cairo_destroy (cr); return TRUE; }
static gboolean avatar_image_draw (GtkWidget *widget, cairo_t *cr) { GiggleAvatarImagePriv *priv = GET_PRIV (widget); GtkRequisition requisition; GtkStyleContext *context; GdkRGBA rgba; float xalign, yalign; double x, y; gint width, height; int w, h; gtk_widget_get_preferred_size (widget, &requisition, NULL); width = gtk_widget_get_allocated_width (widget); height = gtk_widget_get_allocated_height (widget); context = gtk_widget_get_style_context (widget); w = requisition.width; h = requisition.height; gtk_misc_get_alignment (GTK_MISC (widget), &xalign, &yalign); cairo_translate (cr, (int) ((width - w) * xalign), (int) ((height - h) * yalign)); rounded_rectangle (cr, 0.5, 0.5, w - 1, h - 1, MIN (w, h) * 0.2); gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL, &rgba); gdk_cairo_set_source_rgba (cr, &rgba); cairo_fill_preserve (cr); if (priv->pixbuf) { x = (w - gdk_pixbuf_get_width (priv->pixbuf)) * 0.5; y = (h - gdk_pixbuf_get_height (priv->pixbuf)) * 0.5; gdk_cairo_set_source_pixbuf (cr, priv->pixbuf, x, y); cairo_fill_preserve (cr); } gtk_style_context_get_background_color (context, GTK_STATE_FLAG_NORMAL, &rgba); gdk_cairo_set_source_rgba (cr, &rgba); cairo_set_line_width (cr, 1); cairo_stroke (cr); return TRUE; }
static cairo_time_t do_rectangle (cairo_t *cr, int width, int height, int loops) { cairo_perf_timer_start (); cairo_perf_set_thread_aware (cr, FALSE); while (loops--) { if (loops == 0) cairo_perf_set_thread_aware (cr, TRUE); rounded_rectangle (cr, 0, 0, width, height, 3.0); cairo_fill (cr); } cairo_perf_timer_stop (); return cairo_perf_timer_elapsed (); }
void gitg_label_renderer_draw(GtkWidget *widget, PangoFontDescription *font, cairo_t *context, GSList *labels, GdkRectangle *area) { GSList *item; double pos = MARGIN + 0.5; cairo_save(context); cairo_set_line_width(context, 1.0); PangoContext *ctx = gtk_widget_get_pango_context(widget); PangoLayout *layout = pango_layout_new(ctx); pango_layout_set_font_description(layout, font); for (item = labels; item; item = item->next) { GitgRef *ref = (GitgRef *)item->data; gint w; gint h; gchar *smaller = g_strdup_printf("<span size='smaller'>%s</span>", ref->shortname); pango_layout_set_markup(layout, smaller, -1); pango_layout_get_pixel_size(layout, &w, &h); // draw rounded rectangle rounded_rectangle(context, pos + 0.5, area->y + MARGIN + 0.5, w + PADDING * 2, area->height - MARGIN * 2, 5); set_source_for_ref_type(context, ref->type); cairo_fill_preserve(context); cairo_set_source_rgb(context, 0, 0, 0); cairo_stroke(context); cairo_save(context); cairo_translate(context, pos + PADDING, area->y + (area->height - h) / 2.0 + 0.5); pango_cairo_show_layout(context, layout); cairo_restore(context); pos += w + PADDING * 2 + MARGIN; g_free(smaller); } g_object_unref(layout); cairo_restore(context); }
static cairo_perf_ticks_t do_rectangles (cairo_t *cr, int width, int height) { int i; cairo_perf_timer_start (); for (i = 0; i < RECTANGLE_COUNT; i++) { rounded_rectangle (cr, rects[i].x, rects[i].y, rects[i].width, rects[i].height, 3.0); cairo_fill (cr); } cairo_perf_timer_stop (); return cairo_perf_timer_elapsed (); }
static void annotation_txt(MF2UI *ui, RobTkDial * d, cairo_t *cr, const char *txt) { int tw, th; cairo_save(cr); PangoLayout * pl = pango_cairo_create_layout(cr); pango_layout_set_font_description(pl, ui->font[1]); pango_layout_set_text(pl, txt, -1); pango_layout_get_pixel_size(pl, &tw, &th); cairo_translate (cr, d->w_cx, d->w_height); cairo_translate (cr, -tw/2.0 - 0.5, -th); cairo_set_source_rgba (cr, .0, .0, .0, .7); rounded_rectangle(cr, -1, -1, tw+3, th+1, 3); cairo_fill(cr); CairoSetSouerceRGBA(c_wht); pango_cairo_layout_path(cr, pl); cairo_fill(cr); g_object_unref(pl); cairo_restore(cr); cairo_new_path(cr); }
static void create_surfaces(SFSUI* ui) { cairo_t* cr; ui->sf_ann = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ui->width, ui->height); cr = cairo_create (ui->sf_ann); cairo_rectangle (cr, 0, 0, ui->width, ui->height); CairoSetSouerceRGBA(ui->c_bg); cairo_fill (cr); cairo_destroy (cr); ui->sf_dat = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ui->width, ui->height); cr = cairo_create (ui->sf_dat); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_rgba(cr, 0, 0, 0, 0.0); cairo_rectangle (cr, 0, 0, ui->width, ui->height); cairo_fill (cr); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_source_rgba(cr, 0, 0, 0, 1.0); rounded_rectangle (cr, SS_BORDER, SS_BORDER, SS_SIZE, SS_SIZE, SS_BORDER); cairo_fill (cr); cairo_destroy (cr); }
static GdkPixbuf * frame_pixbuf (GdkPixbuf *source, gint scale) { GdkPixbuf *dest; cairo_t *cr; cairo_surface_t *surface; guint w; guint h; int frame_width; double radius; frame_width = 2 * scale; w = gdk_pixbuf_get_width (source) + frame_width * 2; h = gdk_pixbuf_get_height (source) + frame_width * 2; radius = w / 10; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); cr = cairo_create (surface); cairo_surface_destroy (surface); /* set up image */ cairo_rectangle (cr, 0, 0, w, h); cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); cairo_fill (cr); rounded_rectangle (cr, 1.0, 0.5, 0.5, radius, w - 1, h - 1); cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 0.3); cairo_fill_preserve (cr); gdk_cairo_set_source_pixbuf (cr, source, frame_width, frame_width); cairo_fill (cr); dest = gdk_pixbuf_get_from_surface (surface, 0, 0, w, h); cairo_destroy (cr); return dest; }
static bool expose_event(RobWidget* handle, cairo_t* cr, cairo_rectangle_t *ev) { SFSUI* ui = (SFSUI*)GET_HANDLE(handle); if (ui->update_grid) { update_grid(ui); ui->update_grid = false; } if (ui->clear_persistence) { cairo_t* crx; crx = cairo_create (ui->sf_dat); rounded_rectangle (crx, SS_BORDER, SS_BORDER, SS_SIZE, SS_SIZE, SS_BORDER); cairo_set_source_rgba(crx, 0, 0, 0, 1.0); cairo_fill(crx); cairo_destroy(crx); ui->clear_persistence = false; } if (pthread_mutex_trylock (&ui->fft_lock) == 0 ) { if (robtk_cbtn_get_active(ui->btn_oct)) { plot_data_oct(ui); } else { plot_data_fft(ui); } pthread_mutex_unlock (&ui->fft_lock); } cairo_rectangle (cr, ev->x, ev->y, ev->width, ev->height); cairo_clip (cr); cairo_set_source_surface(cr, ui->sf_ann, 0, 0); cairo_paint (cr); cairo_set_operator (cr, CAIRO_OPERATOR_ADD); cairo_set_source_surface(cr, ui->sf_dat, 0, 0); cairo_paint (cr); return TRUE; }
static cairo_time_t do_rectangles (cairo_t *cr, int width, int height, int loops) { int i; cairo_perf_timer_start (); cairo_perf_set_thread_aware (cr, FALSE); while (loops--) { if (loops == 0) cairo_perf_set_thread_aware (cr, TRUE); for (i = 0; i < RECTANGLE_COUNT; i++) { rounded_rectangle (cr, rects[i].x, rects[i].y, rects[i].width, rects[i].height, 3.0); cairo_fill (cr); } } cairo_perf_timer_stop (); return cairo_perf_timer_elapsed (); }
void cairo_container::draw_background( litehtml::uint_ptr hdc, const litehtml::background_paint& bg ) { cairo_t* cr = (cairo_t*) hdc; cairo_save(cr); apply_clip(cr); rounded_rectangle(cr, bg.border_box, bg.border_radius); cairo_clip(cr); cairo_rectangle(cr, bg.clip_box.x, bg.clip_box.y, bg.clip_box.width, bg.clip_box.height); cairo_clip(cr); if(bg.color.alpha) { set_color(cr, bg.color); cairo_paint(cr); } std::wstring url; t_make_url(bg.image.c_str(), bg.baseurl.c_str(), url); lock_images_cache(); images_map::iterator img_i = m_images.find(url.c_str()); if(img_i != m_images.end() && img_i->second) { image_ptr bgbmp = img_i->second; image_ptr new_img; if(bg.image_size.width != bgbmp->getWidth() || bg.image_size.height != bgbmp->getHeight()) { new_img = image_ptr(new CTxDIB); bgbmp->resample(bg.image_size.width, bg.image_size.height, new_img.get()); bgbmp = new_img; } cairo_surface_t* img = cairo_image_surface_create_for_data((unsigned char*) bgbmp->getBits(), CAIRO_FORMAT_ARGB32, bgbmp->getWidth(), bgbmp->getHeight(), bgbmp->getWidth() * 4); cairo_pattern_t *pattern = cairo_pattern_create_for_surface(img); cairo_matrix_t flib_m; cairo_matrix_init(&flib_m, 1, 0, 0, -1, 0, 0); cairo_matrix_translate(&flib_m, -bg.position_x, -bg.position_y); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); cairo_pattern_set_matrix (pattern, &flib_m); switch(bg.repeat) { case litehtml::background_repeat_no_repeat: draw_txdib(cr, bgbmp.get(), bg.position_x, bg.position_y, bgbmp->getWidth(), bgbmp->getHeight()); break; case litehtml::background_repeat_repeat_x: cairo_set_source(cr, pattern); cairo_rectangle(cr, bg.clip_box.left(), bg.position_y, bg.clip_box.width, bgbmp->getHeight()); cairo_fill(cr); break; case litehtml::background_repeat_repeat_y: cairo_set_source(cr, pattern); cairo_rectangle(cr, bg.position_x, bg.clip_box.top(), bgbmp->getWidth(), bg.clip_box.height); cairo_fill(cr); break; case litehtml::background_repeat_repeat: cairo_set_source(cr, pattern); cairo_rectangle(cr, bg.clip_box.left(), bg.clip_box.top(), bg.clip_box.width, bg.clip_box.height); cairo_fill(cr); break; } cairo_pattern_destroy(pattern); cairo_surface_destroy(img); } unlock_images_cache(); cairo_restore(cr); }
static void plot_data_oct(SFSUI* ui) { cairo_t* cr; cr = cairo_create (ui->sf_dat); rounded_rectangle (cr, SS_BORDER, SS_BORDER, SS_SIZE, SS_SIZE, SS_BORDER); cairo_clip_preserve (cr); const float persistence = robtk_dial_get_value(ui->screen); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); if (persistence > 0) { cairo_set_source_rgba(cr, 0, 0, 0, .33 - .0033 * persistence); } else { cairo_set_source_rgba(cr, 0, 0, 0, 1.0); } cairo_fill(cr); cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); const float xmid = rintf(SS_BORDER + SS_SIZE *.5) + .5; const float dnum = SS_SIZE / ui->log_base; const float denom = 2.0 * ui->log_rate / ui->rate; uint32_t fi = 1; for (uint32_t i = 0; i < ui->freq_bins; ++i) { float a_lr = 0; float a_level = 0; float a_freq = 0; uint32_t a_cnt = 0; while(fi < ui->freq_band[i]) { if (ui->level[fi] < 0) { fi++; continue; } a_freq += fi * ui->fa->freq_per_bin; a_level += ui->level[fi]; a_lr += ui->lr[fi]; a_cnt++; fi++; } if (a_cnt == 0) continue; a_level = MAKEUP_GAIN + fftx_power_to_dB (a_level); if (a_level < -80) continue; a_freq /= (float)a_cnt; a_lr /= (float)a_cnt; const float y = rintf(SS_BORDER + SS_SIZE - dnum * fast_log10(1.0 + a_freq * denom)) + .5; const float pk = a_level > 0.0 ? 1.0 : (80 + a_level) / 80.0; float clr[3]; hsl2rgb(clr, .70 - .72 * pk, .9, .3 + pk * .4); cairo_set_source_rgba(cr, clr[0], clr[1], clr[2], 0.8); if (fabsf(a_lr -.5) < .05) { cairo_set_line_width (cr, 3.0); } else { cairo_set_line_width (cr, 1.0); } cairo_move_to(cr, xmid, y); cairo_line_to(cr, SS_BORDER + SS_SIZE * a_lr, y); cairo_stroke(cr); } cairo_destroy (cr); }
void fill_rounded_rectangle (cairo_t *cr, double x, double y, double w, double h, int corner, alpha_color * c0, alpha_color * c1, int gravity, window_settings * ws, double radius) { cairo_pattern_t *pattern; rounded_rectangle (cr, x, y, w, h, corner,ws,radius); if (gravity & SHADE_RIGHT) { x = x + w; w = -w; } else if (!(gravity & SHADE_LEFT)) { x = w = 0; } if (gravity & SHADE_BOTTOM) { y = y + h; h = -h; } else if (!(gravity & SHADE_TOP)) { y = h = 0; } if (w && h) { cairo_matrix_t matrix; pattern = cairo_pattern_create_radial (0.0, 0.0, 0.0, 0.0, 0.0, w); cairo_matrix_init_scale (&matrix, 1.0, w / h); cairo_matrix_translate (&matrix, -(x + w), -(y + h)); cairo_pattern_set_matrix (pattern, &matrix); } else { pattern = cairo_pattern_create_linear (x + w, y + h, x, y); } cairo_pattern_add_color_stop_rgba (pattern, 0.0, c0->color.r, c0->color.g, c0->color.b,c0->alpha); cairo_pattern_add_color_stop_rgba (pattern, 1.0, c1->color.r, c1->color.g, c1->color.b,c1->alpha); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); }
static void update_grid(SFSUI* ui) { cairo_t *cr = cairo_create (ui->sf_ann); cairo_rectangle (cr, 0, 0, ui->width, ui->height); CairoSetSouerceRGBA(ui->c_bg); cairo_fill (cr); cairo_set_line_width (cr, 1.0); rounded_rectangle (cr, SS_BORDER, SS_BORDER, SS_SIZE, SS_SIZE, SS_BORDER); cairo_set_source_rgba(cr, 0, 0, 0, 1.0); cairo_fill(cr); rounded_rectangle (cr, SS_BORDER-.5, SS_BORDER-.5, SS_SIZE+1, SS_SIZE+1, SS_BORDER); CairoSetSouerceRGBA(c_g90); cairo_stroke(cr); const double dash1[] = {1.0, 2.0}; cairo_set_dash(cr, dash1, 2, 0); CairoSetSouerceRGBA(c_grd); #define FREQ_ANN(FRQ, TXT) { \ const float py = rintf(SS_BORDER + SS_SIZE * (1.0 - fast_log10(1.0 + 2 * FRQ * ui->log_rate / ui->rate) / ui->log_base)) + .5; \ cairo_move_to(cr, SS_BORDER, py); \ cairo_line_to(cr, SS_BORDER + SS_SIZE, py); \ cairo_stroke(cr); \ write_text_full(cr, TXT, ui->font[0], SS_SIZE, py, 0, -1, c_ahz); \ } float freq = 62.5; while (freq < ui->rate / 2) { char txt[16]; if (freq < 1000) { snprintf(txt, 16, "%d Hz", (int)ceil(freq)); } else { snprintf(txt, 16, "%d KHz", (int)ceil(freq/1000.f)); } FREQ_ANN(freq, txt); freq *= 2.0; } #define LEVEL_ANN(LVL, TXT) { \ const float dx = .5 * SS_SIZE * (1 - powf(10, .05 * (LVL))); \ const float p0 = .5 + rintf(SS_BORDER + .5 * SS_SIZE + dx); \ const float p1 = .5 + rintf(SS_BORDER + .5 * SS_SIZE - dx); \ cairo_move_to(cr, p0, SS_BORDER); \ cairo_line_to(cr, p0, SS_BORDER + SS_SIZE); \ cairo_stroke(cr); \ cairo_move_to(cr, p1, SS_BORDER); \ cairo_line_to(cr, p1, SS_BORDER + SS_SIZE); \ cairo_stroke(cr); \ write_text_full(cr, TXT, ui->font[0], p0, SS_BORDER + 3, -.5 * M_PI, -1, c_ahz); \ write_text_full(cr, TXT, ui->font[0], p1, SS_BORDER + 3, -.5 * M_PI, -1, c_ahz); \ } LEVEL_ANN(-1, "1dB"); LEVEL_ANN(-3, "3dB"); LEVEL_ANN(-6, "6dB"); LEVEL_ANN(-10, "10dB"); LEVEL_ANN(-20, "20dB"); const double dash2[] = {1.0, 3.0}; cairo_set_line_width(cr, 3.5); cairo_set_dash(cr, dash2, 2, 2); const float xmid = rintf(SS_BORDER + SS_SIZE *.5) + .5; cairo_move_to(cr, xmid, SS_BORDER); cairo_line_to(cr, xmid, SS_BORDER + SS_SIZE); cairo_stroke(cr); write_text_full(cr, "L", ui->font[1], SS_BORDER + 6, SS_BORDER + 12, 0, -2, c_ann); write_text_full(cr, "R", ui->font[1], SS_BORDER + SS_SIZE - 6, SS_BORDER + 12, 0, -2, c_ann); cairo_destroy (cr); }
static gboolean on_expose_event (GtkWidget *widget, GdkEventExpose *event, GsdMediaKeysWindow *window) { cairo_t *context; cairo_t *cr; cairo_surface_t *surface; int width; int height; GtkStyle *style; GdkColor color; double r, g, b; context = gdk_cairo_create (gtk_widget_get_window (widget)); style = gtk_widget_get_style (widget); cairo_set_operator (context, CAIRO_OPERATOR_SOURCE); gtk_window_get_size (GTK_WINDOW (widget), &width, &height); surface = cairo_surface_create_similar (cairo_get_target (context), CAIRO_CONTENT_COLOR_ALPHA, width, height); if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) { goto done; } cr = cairo_create (surface); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { goto done; } cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_paint (cr); /* draw a box */ rounded_rectangle (cr, 1.0, 0.5, 0.5, height / 10, width-1, height-1); color_reverse (&style->bg[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; cairo_set_source_rgba (cr, r, g, b, BG_ALPHA); cairo_fill_preserve (cr); color_reverse (&style->text_aa[GTK_STATE_NORMAL], &color); r = (float)color.red / 65535.0; g = (float)color.green / 65535.0; b = (float)color.blue / 65535.0; cairo_set_source_rgba (cr, r, g, b, BG_ALPHA / 2); cairo_set_line_width (cr, 1); cairo_stroke (cr); /* draw action */ draw_action (window, cr); cairo_destroy (cr); /* Make sure we have a transparent background */ cairo_rectangle (context, 0, 0, width, height); cairo_set_source_rgba (context, 0.0, 0.0, 0.0, 0.0); cairo_fill (context); cairo_set_source_surface (context, surface, 0, 0); cairo_paint_with_alpha (context, window->priv->fade_out_alpha); done: if (surface != NULL) { cairo_surface_destroy (surface); } cairo_destroy (context); return FALSE; }
/* stereo-phase correlation display */ static bool pc_expose_event(RobWidget* handle, cairo_t* cr, cairo_rectangle_t *ev) { MF2UI* ui = (MF2UI*)GET_HANDLE(handle); if (!ui->sf_nfo && ui->nfo) { PangoFontDescription *fd = pango_font_description_from_string("Sans 10px"); create_text_surface2(&ui->sf_nfo, 12, PC_BOUNDH, 0, PC_TOP, ui->nfo, fd, M_PI * -.5, 7, c_g60); pango_font_description_free(fd); } cairo_save(cr); cairo_translate(cr, 0, rint((ui->m0_height - ui->height) * .5)); cairo_rectangle (cr, ev->x, ev->y, ev->width, ev->height); cairo_clip (cr); /* display phase-correlation */ cairo_set_operator (cr, CAIRO_OPERATOR_OVER); /* PC meter backgroud */ CairoSetSouerceRGBA(ui->c_bg); cairo_rectangle (cr, 0, 0, PC_BOUNDW, PC_BOUNDH); cairo_fill(cr); CairoSetSouerceRGBA(c_blk); cairo_set_line_width(cr, 1.0); rounded_rectangle (cr, PC_LEFT-1, PC_TOP + 1.0, PC_WIDTH+2, PC_HEIGHT - 2.0, 3); cairo_fill_preserve(cr); cairo_save(cr); cairo_clip(cr); /* value */ CairoSetSouerceRGBA(c_glb); const float c = rintf(PC_TOP + PC_BLOCKSIZE * ui->cor); rounded_rectangle (cr, PC_LEFT, c, PC_WIDTH, PC_BLOCK, 4); cairo_fill(cr); /* labels w/ background */ cairo_set_source_surface(cr, ui->sf_pc[0], PC_LEFT, PC_TOP + 5); cairo_paint (cr); cairo_set_source_surface(cr, ui->sf_pc[1], PC_LEFT, PC_TOP + PC_HEIGHT - 25); cairo_paint (cr); cairo_restore(cr); rounded_rectangle (cr, PC_LEFT - .5, PC_TOP + .5, PC_WIDTH + 1, PC_HEIGHT - 1, 3); CairoSetSouerceRGBA(c_g90); cairo_stroke(cr); /* annotations */ cairo_set_operator (cr, CAIRO_OPERATOR_SCREEN); CairoSetSouerceRGBA(c_grd); cairo_set_line_width(cr, 1.0); #define PC_ANNOTATION(YPOS, OFF) \ cairo_move_to(cr, PC_LEFT + OFF, rintf(PC_TOP + YPOS) + 0.5); \ cairo_line_to(cr, PC_LEFT + PC_WIDTH - OFF, rintf(PC_TOP + YPOS) + 0.5);\ cairo_stroke(cr); PC_ANNOTATION(PC_HEIGHT * 0.1, 4.0); PC_ANNOTATION(PC_HEIGHT * 0.2, 4.0); PC_ANNOTATION(PC_HEIGHT * 0.3, 4.0); PC_ANNOTATION(PC_HEIGHT * 0.4, 4.0); PC_ANNOTATION(PC_HEIGHT * 0.6, 4.0); PC_ANNOTATION(PC_HEIGHT * 0.7, 4.0); PC_ANNOTATION(PC_HEIGHT * 0.8, 4.0); PC_ANNOTATION(PC_HEIGHT * 0.9, 4.0); CairoSetSouerceRGBA(c_glr); cairo_set_line_width(cr, 1.5); PC_ANNOTATION(PC_HEIGHT * 0.5, 1.5); cairo_restore(cr); if (ui->sf_nfo) { cairo_rectangle (cr, ev->x, ev->y, ev->width, ev->height); cairo_clip (cr); cairo_set_source_surface(cr, ui->sf_nfo, PC_BOUNDW - 14, 0); cairo_paint (cr); } return TRUE; }
/** draw level-range display * depends on gain (dial) and cutoff */ static void update_annotations(MF2UI* ui) { cairo_t* cr = cairo_create (ui->sf_gain); cairo_rectangle (cr, 0, 0, ANN_W, 40); CairoSetSouerceRGBA(ui->c_bg); cairo_fill (cr); rounded_rectangle (cr, 3, 3 , ANN_W - 6, ANN_H - 6, 6); if (ui->drag_cutoff_x >= 0 || ui->prelight_cutoff) { cairo_set_source_rgba(cr, .15, .15, .15, 1.0); } else { cairo_set_source_rgba(cr, .0, .0, .0, 1.0); } cairo_fill (cr); cairo_set_line_width (cr, 1.0); const uint32_t mxw = ANN_W - XOFF * 2 - 36; const uint32_t mxo = XOFF + 18; const float cutoff = ui->db_cutoff; const uint32_t cutoff_m = floor(mxw * (MIN_CUTOFF - cutoff) / MIN_CUTOFF); assert(cutoff_m < mxw); const uint32_t cutoff_w = mxw - cutoff_m; for (uint32_t i=0; i < mxw; ++i) { float clr[3]; if (i < cutoff_m) { clr[0] = clr[1] = clr[2] = .1; } else { const float pk = (i-cutoff_m) / (float)cutoff_w; hsl2rgb(clr, .68 - .72 * pk, .9, .2 + pk * .4); } cairo_set_source_rgba(cr, clr[0], clr[1], clr[2], 1.0); cairo_move_to(cr, mxo + i + .5, ANN_B - 5); cairo_line_to(cr, mxo + i + .5, ANN_B); cairo_stroke(cr); } cairo_set_source_rgba(cr, .8, .8, .8, .8); const float gain = robtk_dial_get_value(ui->gain); for (int32_t db = MIN_CUTOFF; db <=0 ; db+= 10) { char dbt[16]; if (db == 0) { snprintf(dbt, 16, "\u2265%+.0fdB", (db - gain)); } else { snprintf(dbt, 16, "%+.0fdB", (db - gain)); } write_text_full(cr, dbt, ui->font[0], mxo + rint(mxw * (-MIN_CUTOFF + db) / -MIN_CUTOFF), ANN_B - 14 , 0, 2, c_wht); cairo_move_to(cr, mxo + rint(mxw * (-MIN_CUTOFF + db) / -MIN_CUTOFF) + .5, ANN_B - 7); cairo_line_to(cr, mxo + rint(mxw * (-MIN_CUTOFF + db) / -MIN_CUTOFF) + .5, ANN_B); cairo_stroke(cr); } /* black overlay above low-end cutoff */ if (ui->db_cutoff > MIN_CUTOFF && (ui->drag_cutoff_x >= 0 || ui->prelight_cutoff)) { const float cox = rint(mxw * (ui->db_cutoff - MIN_CUTOFF)/ -MIN_CUTOFF); cairo_rectangle(cr, mxo, 6, cox, ANN_B - 6); cairo_set_source_rgba(cr, .0, .0, .0, .7); cairo_fill(cr); cairo_set_line_width (cr, 1.0); cairo_set_source_rgba(cr, .9, .5, .5, .6); cairo_move_to(cr, mxo + cox + .5, ANN_B - 6); cairo_line_to(cr, mxo + cox + .5, ANN_B + 1); cairo_stroke(cr); } cairo_destroy (cr); }
void engine_draw_frame (decor_t * d, cairo_t * cr) { frame_settings *fs = d->fs; private_fs *pfs = fs->engine_fs; window_settings *ws = fs->ws; double x1, y1, x2, y2; x1 = ws->left_space - ws->win_extents.left; y1 = ws->top_space - ws->win_extents.top; x2 = d->width - ws->right_space + ws->win_extents.right; y2 = d->height - ws->bottom_space + ws->win_extents.bottom; int top; top = ws->win_extents.top + ws->titlebar_height; double m1 = MIN(ws->win_extents.left, ws->win_extents.right); double m2 = MIN(ws->win_extents.top, ws->win_extents.bottom); double border_width = MIN(m1, m2); double border_offset = border_width/2.0; cairo_set_line_width (cr, border_width); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); rounded_rectangle (cr, x1 + border_offset, y1 + top - border_offset, x2 - x1 - border_width, y2 - y1 - top, 0, ws, 0); cairo_set_source_alpha_color(cr, &pfs->border); cairo_stroke (cr); /* title bar */ if (pfs->title_bar.alpha != 0.0) { rounded_rectangle (cr, x1, y1, x2 - x1, top, 0, ws, 0); cairo_set_source_alpha_color(cr, &pfs->title_bar); cairo_fill(cr); } else { cairo_save(cr); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_rectangle (cr, 0.0, 0.0, d->width, top + y1 - border_width); cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0); cairo_fill(cr); cairo_restore(cr); /* FIXME => find a proper solution for this */ #ifdef SHADOW_FIX cairo_rectangle (cr, 0.0, 0.0, d->width, top + y1 - border_width); cairo_clip(cr); cairo_translate(cr, 0.0, ws->top_space + ws->win_extents.top); draw_shadow_background(d, cr); cairo_translate(cr, 0.0, -ws->top_space - ws->win_extents.top); #endif } }
static void render (GtkCellRenderer *cell, GdkDrawable *window, GtkWidget *widget, GdkRectangle *background_area, GdkRectangle *cell_area, GdkRectangle *expose_area, GtkCellRendererState flags) { GtkCellRendererBubblePrivate *priv; cairo_t *cr; cairo_pattern_t *pattern; GdkColor *start; GdkColor *stop; g_return_if_fail (GTK_IS_CELL_RENDERER_BUBBLE (cell)); priv = GTK_CELL_RENDERER_BUBBLE (cell)->priv; if (priv->show_bubble) { cr = gdk_cairo_create (GDK_DRAWABLE (window)); g_assert (cr); start = &widget->style->light [GTK_STATE_SELECTED]; stop = &widget->style->mid [GTK_STATE_SELECTED]; pattern = cairo_pattern_create_linear (cell_area->x, cell_area->y, cell_area->x, cell_area->y + cell_area->height); cairo_pattern_add_color_stop_rgb (pattern, 0.3, start->red / (gdouble)G_MAXUINT16, start->green / (gdouble)G_MAXUINT16, start->blue / (gdouble)G_MAXUINT16); cairo_pattern_add_color_stop_rgb (pattern, 0.9, stop->red / (gdouble)G_MAXUINT16, stop->green / (gdouble)G_MAXUINT16, stop->blue / (gdouble)G_MAXUINT16); rounded_rectangle (cr, cell_area->x, cell_area->y + 1, cell_area->width, cell_area->height - 2, cell_area->height / 2.5, cell_area->height / 2.5); cairo_set_source (cr, pattern); cairo_fill_preserve (cr); gdk_cairo_set_source_color (cr, &widget->style->dark [GTK_STATE_SELECTED]); cairo_set_line_width (cr, 1.0); cairo_stroke (cr); rounded_rectangle (cr, cell_area->x + 1.0, cell_area->y + 2.0, cell_area->width - 2.0, cell_area->height - 4.0, cell_area->height / 2.5, cell_area->height / 2.5); gdk_cairo_set_source_color (cr, &widget->style->light [GTK_STATE_SELECTED]); cairo_stroke (cr); cairo_destroy (cr); } GTK_CELL_RENDERER_CLASS (gtk_cell_renderer_bubble_parent_class)-> render (cell, window, widget, background_area, cell_area, expose_area, flags); }
bool knob::on_expose_event(GdkEventExpose* event) { // This is where we draw on the window Glib::RefPtr<Gdk::Window> window = get_window(); if(window) { Gtk::Allocation allocation = get_allocation(); const int width = allocation.get_width(); const int height = allocation.get_height() - (allocation.get_height()/3); const int height_offset = allocation.get_height()/6; // coordinates for the center of the window int xc, yc; xc = width / 2; yc = height / 2; Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context(); cr->set_line_width(6.0); // clip to the area indicated by the expose event so that we only redraw // the portion of the window that needs to be redrawn cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height); cr->clip(); // background grad Cairo::RefPtr<Cairo::LinearGradient> back_grad = Cairo::LinearGradient::create( 0,0,0,allocation.get_height() ); switch (pos_mode) { case 0: back_grad->add_color_stop_rgba(0,top_colour.get_red_p(),top_colour.get_green_p(),top_colour.get_blue_p(),1); back_grad->add_color_stop_rgba(1,bottom_colour.get_red_p(),bottom_colour.get_green_p(),bottom_colour.get_blue_p(),1); break; case 1: back_grad->add_color_stop_rgba(0,top_colour.get_red_p(),top_colour.get_green_p(),top_colour.get_blue_p(),1); back_grad->add_color_stop_rgba(1, (bottom_colour.get_red_p() + top_colour.get_red_p())/2, (bottom_colour.get_green_p() + top_colour.get_green_p())/2, (bottom_colour.get_blue_p() + top_colour.get_blue_p())/2, 1); break; case 2: back_grad->add_color_stop_rgba(0, (bottom_colour.get_red_p() + top_colour.get_red_p())/2, (bottom_colour.get_green_p() + top_colour.get_green_p())/2, (bottom_colour.get_blue_p() + top_colour.get_blue_p())/2, 1); back_grad->add_color_stop_rgba(1,bottom_colour.get_red_p(),bottom_colour.get_green_p(),bottom_colour.get_blue_p(),1); break; } // fill background if (rounded<5) { rounded_rectangle(cr,rounded, grad_top_colour, grad_bottom_colour, event->area.x, event->area.y, event->area.width, event->area.height,pos_mode, top_colour.to_string(),bottom_colour.to_string() ); } else { cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height); } cr->set_source(back_grad); cr->fill(); // ------------------------------------------------------------------ float cos_x = (allocation.get_width()/5) * (cos(((((1-knob_value)*0.75)-0.3)*2) * M_PI)); float sin_y = (allocation.get_width()/5) * (sin(((((1-knob_value)*0.75)-0.3)*2) * M_PI)); Cairo::RefPtr<Cairo::RadialGradient> grad1 = Cairo::RadialGradient::create( (allocation.get_width()/2) + sin_y, (allocation.get_height()/2) + cos_x, 0, (allocation.get_width()/2) , (allocation.get_height()/2) ,(allocation.get_width()/2.5)); grad1->add_color_stop_rgba(0,0.4,0.4,0.4,1); grad1->add_color_stop_rgba(0.5,0.2,0.2,0.2,1); grad1->add_color_stop_rgba(0.8,0.17,0.17,0.17,1); grad1->add_color_stop_rgba(1.0,0.0,0.0,0.0,1); cos_x = (allocation.get_width()/5) * (cos((((knob_value*0.75)-0.61)*2) * M_PI)); sin_y = (allocation.get_width()/5) * (sin((((knob_value*0.75)-0.61)*2) * M_PI)); cr->set_source(grad1); cr->arc(allocation.get_width()/2, allocation.get_height()/2, (allocation.get_width()/2.5), 0.0, 2 * M_PI); cr->fill(); cr->set_source_rgb(0.0, 0.0, 0.0); cr->arc((allocation.get_width()/2) +cos_x, (allocation.get_height()/2)+sin_y, (allocation.get_width()/16), 0.0, 2 * M_PI); cr->fill(); // draw text label cr->select_font_face("Bitstream Vera Sans", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL); cr->set_font_size(width/4.5); cr->set_source_rgba(0.9,0.9,0.9,0.8); Cairo::FontOptions font_options; font_options.set_hint_style(Cairo::HINT_STYLE_NONE); font_options.set_hint_metrics(Cairo::HINT_METRICS_OFF); font_options.set_antialias(Cairo::ANTIALIAS_GRAY); int x_font_centre = (width/2) - ((width/5) * (label.length()/3.5)); cr->set_font_options(font_options); cr->move_to(x_font_centre,height/3.5); cr->show_text(label); cr->move_to(x_font_centre,allocation.get_height() - (height_offset/3) ); ostringstream slider_value; slider_value.str(""); if (invert) { slider_value << max - value; } else { slider_value << value; } slider_value.str(slider_value.str().substr(0,5)); x_font_centre = (width/2) - ((width/5) * (slider_value.str().length()/3.5)); cr->move_to(x_font_centre,allocation.get_height() - (height_offset/1.5) ); cr->show_text(slider_value.str()); } return true; }
void engine_draw_frame (decor_t * d, cairo_t * cr) { double x1, y1, x2, y2, h; int top; frame_settings * fs = d->fs; private_fs * pfs = fs->engine_fs; window_settings * ws = fs->ws; private_ws * pws = ws->engine_ws; gdouble pleft; gdouble ptop; gdouble pwidth; gdouble pheight; top = ws->win_extents.top + ws->titlebar_height; x1 = ws->left_space - ws->win_extents.left; y1 = ws->top_space - ws->win_extents.top; x2 = d->width - ws->right_space + ws->win_extents.right; y2 = d->height - ws->bottom_space + ws->win_extents.bottom; pleft = x1 + ws->win_extents.left - 0.5; ptop = y1 + top - 0.5; pwidth = x2 - x1 - ws->win_extents.left - ws->win_extents.right + 1; pheight = y2 - y1 - top-ws->win_extents.bottom + 1; h = d->height - ws->top_space - ws->titlebar_height - ws->bottom_space; int corners = ((pws->round_top_left) ? CORNER_TOPLEFT : 0) | ((pws->round_top_right) ? CORNER_TOPRIGHT : 0) | ((pws->round_bottom_left) ? CORNER_BOTTOMLEFT : 0) | ((pws->round_bottom_right) ? CORNER_BOTTOMRIGHT : 0); /* maximize work-a-round */ if (d->state & (WNCK_WINDOW_STATE_MAXIMIZED_HORIZONTALLY | WNCK_WINDOW_STATE_MAXIMIZED_VERTICALLY)) corners = 0; cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_line_width (cr, 1.0); fill_rounded_rectangle (cr, x1 + 0.5, y1 + 0.5, ws->win_extents.left - 0.5, top - 0.5, CORNER_TOPLEFT & corners, &pfs->title_inner, &pfs->title_outer, SHADE_TOP | SHADE_LEFT, ws, pws->corner_radius); fill_rounded_rectangle (cr, x1 + ws->win_extents.left, y1 + 0.5, x2 - x1 - ws->win_extents.left - ws->win_extents.right, top - 0.5, 0, &pfs->title_inner, &pfs->title_outer, SHADE_TOP, ws, pws->corner_radius); fill_rounded_rectangle (cr, x2 - ws->win_extents.right, y1 + 0.5, ws->win_extents.right - 0.5, top - 0.5, CORNER_TOPRIGHT & corners, &pfs->title_inner, &pfs->title_outer, SHADE_TOP | SHADE_RIGHT, ws, pws->corner_radius); fill_rounded_rectangle (cr, x1 + 0.5, y1 + top, ws->win_extents.left - 0.5, h, 0, &pfs->inner, &pfs->outer, SHADE_LEFT, ws, pws->corner_radius); fill_rounded_rectangle (cr, x2 - ws->win_extents.right, y1 + top, ws->win_extents.right - 0.5, h, 0, &pfs->inner, &pfs->outer, SHADE_RIGHT, ws, pws->corner_radius); fill_rounded_rectangle (cr, x1 + 0.5, y2 - ws->win_extents.bottom, ws->win_extents.left - 0.5, ws->win_extents.bottom - 0.5, CORNER_BOTTOMLEFT & corners, &pfs->inner, &pfs->outer, SHADE_BOTTOM | SHADE_LEFT, ws, pws->corner_radius); fill_rounded_rectangle (cr, x1 + ws->win_extents.left, y2 - ws->win_extents.bottom, x2 - x1 - ws->win_extents.left - ws->win_extents.right, ws->win_extents.bottom - 0.5, 0, &pfs->inner, &pfs->outer, SHADE_BOTTOM, ws, pws->corner_radius); fill_rounded_rectangle (cr, x2 - ws->win_extents.right, y2 - ws->win_extents.bottom, ws->win_extents.right - 0.5, ws->win_extents.bottom - 0.5, CORNER_BOTTOMRIGHT & corners, &pfs->inner, &pfs->outer, SHADE_BOTTOM | SHADE_RIGHT, ws, pws->corner_radius); /* ======= NEW LAYER ======= */ cairo_set_operator (cr, CAIRO_OPERATOR_OVER); /* titlebar separator line */ cairo_set_source_alpha_color(cr, &pfs->separator_line); cairo_move_to (cr, x1 + 0.5, y1 + top - 0.5); cairo_rel_line_to (cr, x2 - x1 - 1.0, 0.0); cairo_stroke (cr); /* do not draw outside the decoration area */ rounded_rectangle (cr, x1 + 0.5, y1 + 0.5, x2 - x1 - 1.0, y2 - y1 - 1.0, (CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) & corners, ws, pws->corner_radius); cairo_clip (cr); cairo_translate (cr, 1.0, 1.0); /* highlight */ rounded_rectangle (cr, x1 + 0.5, y1 + 0.5, x2 - x1 - 1.0, y2 - y1 - 1.0, (CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) & corners, ws, pws->corner_radius); cairo_set_source_alpha_color (cr, &pfs->window_highlight); cairo_stroke (cr); cairo_translate (cr, -2.0, -2.0); /* shadow */ rounded_rectangle (cr, x1 + 0.5, y1 + 0.5, x2 - x1 - 1.0, y2 - y1 - 1.0, (CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) & corners, ws, pws->corner_radius); cairo_set_source_alpha_color (cr, &pfs->window_shadow); cairo_stroke (cr); cairo_translate (cr, 1.0, 1.0); cairo_reset_clip (cr); /* halo */ rounded_rectangle (cr, x1 + 0.5, y1 + 0.5, x2 - x1 - 1.0, y2 - y1 - 1.0, (CORNER_TOPLEFT | CORNER_TOPRIGHT | CORNER_BOTTOMLEFT | CORNER_BOTTOMRIGHT) & corners, ws, pws->corner_radius); cairo_set_source_alpha_color (cr, &pfs->window_halo); cairo_stroke (cr); /* inner border TODO: make this a bit more pixel-perfect... but it works for now */ cairo_set_line_width (cr, 1.0); cairo_move_to (cr, pleft + pwidth + 1.5, ptop - 1); cairo_rel_line_to (cr, -pwidth - 2.5, 0); cairo_rel_line_to (cr, 0, pheight + 2.5); cairo_set_source_alpha_color (cr, &pfs->contents_shadow); cairo_stroke (cr); cairo_move_to (cr, pleft + pwidth + 1, ptop - 1.5); cairo_rel_line_to (cr, 0, pheight + 2.5); cairo_rel_line_to (cr, -pwidth - 2.5, 0); cairo_set_source_alpha_color (cr, &pfs->contents_highlight); cairo_stroke (cr); cairo_move_to (cr, pleft, ptop); cairo_rel_line_to (cr, pwidth, 0); cairo_rel_line_to (cr, 0, pheight); cairo_rel_line_to (cr, -pwidth, 0); cairo_rel_line_to (cr, 0, -pheight); cairo_set_source_alpha_color (cr, &pfs->contents_halo); cairo_stroke(cr); }