gboolean update_window_decoration_size (WnckWindow *win) { decor_t *d; GdkPixmap *pixmap, *buffer_pixmap = NULL; Picture picture; Display *xdisplay; XRenderPictFormat *format; if (win == NULL) return FALSE; d = g_object_get_data (G_OBJECT (win), "decor"); if (!d->decorated) return FALSE; xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); gdk_error_trap_push (); /* Get the correct depth for the frame window in reparenting mode, otherwise * enforce 32 */ if (d->frame_window) pixmap = create_native_pixmap_and_wrap (d->width, d->height, d->frame->style_window_rgb); else pixmap = create_native_pixmap_and_wrap (d->width, d->height, d->frame->style_window_rgba); gdk_flush (); /* Handle failure */ if (!pixmap || gdk_error_trap_pop ()) { memset (pixmap, 0, sizeof (*pixmap)); return FALSE; } gdk_error_trap_push (); if (d->frame_window) buffer_pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgb); else buffer_pixmap = create_pixmap (d->width, d->height, d->frame->style_window_rgba); gdk_flush (); /* Handle failure */ if (!buffer_pixmap || gdk_error_trap_pop ()) { memset (buffer_pixmap, 0, sizeof (*buffer_pixmap)); g_object_unref (G_OBJECT (pixmap)); return FALSE; } /* Create XRender context */ format = get_format_for_drawable (d, GDK_DRAWABLE (buffer_pixmap)); picture = XRenderCreatePicture (xdisplay, GDK_PIXMAP_XID (buffer_pixmap), format, 0, NULL); /* Destroy the old pixmaps and pictures */ if (d->pixmap) g_object_unref (d->pixmap); if (d->x11Pixmap) decor_post_delete_pixmap (xdisplay, wnck_window_get_xid (d->win), d->x11Pixmap); if (d->buffer_pixmap) g_object_unref (G_OBJECT (d->buffer_pixmap)); if (d->picture) XRenderFreePicture (xdisplay, d->picture); if (d->cr) cairo_destroy (d->cr); /* Assign new pixmaps and pictures */ d->pixmap = pixmap; d->x11Pixmap = GDK_PIXMAP_XID (d->pixmap); d->buffer_pixmap = buffer_pixmap; d->cr = gdk_cairo_create (pixmap); d->picture = picture; d->prop_xid = wnck_window_get_xid (win); update_window_decoration_name (win); /* Redraw decoration on idle */ queue_decor_draw (d); return TRUE; }
/*! \brief draws the static elements of the gauge (only on resize), This includes the border, units and name strings, tick marks and warning regions This is the cairo version. \param widget (MtxPieGauge *) pointer to the gauge object */ void generate_pie_gauge_background(MtxPieGauge *gauge) { cairo_t *cr = NULL; gint w = 0; gint h = 0; MtxPieGaugePrivate *priv = MTX_PIE_GAUGE_GET_PRIVATE(gauge); w = GTK_WIDGET(gauge)->allocation.width; h = GTK_WIDGET(gauge)->allocation.height; if (!priv->bg_pixmap) return; /* get a cairo_t */ cr = gdk_cairo_create (priv->bg_pixmap); cairo_set_font_options(cr,priv->font_options); cairo_set_source_rgb (cr, priv->colors[COL_BG].red/65535.0, priv->colors[COL_BG].green/65535.0, priv->colors[COL_BG].blue/65535.0); /* Background Rectangle */ cairo_rectangle (cr, 0,0,w,h); cairo_fill(cr); /* first one big yellow, with the green and red on top * This prevents seeing BG pixels due to antialiasing errors */ cairo_move_to(cr,priv->pie_xc,priv->pie_yc); cairo_set_source_rgb (cr, priv->colors[COL_MID].red/65535.0, priv->colors[COL_MID].green/65535.0, priv->colors[COL_MID].blue/65535.0); cairo_arc(cr, priv->pie_xc, priv->pie_yc, priv->pie_radius, priv->start_angle*(M_PI/180.0), (priv->start_angle+priv->sweep_angle)*(M_PI/180.0)); cairo_fill(cr); /* Low green Arc (*/ cairo_move_to(cr,priv->pie_xc,priv->pie_yc); cairo_set_source_rgb (cr, priv->colors[COL_LOW].red/65535.0, priv->colors[COL_LOW].green/65535.0, priv->colors[COL_LOW].blue/65535.0); cairo_arc(cr, priv->pie_xc, priv->pie_yc, priv->pie_radius, priv->start_angle*(M_PI/180.0), (priv->start_angle+45)*(M_PI/180.0)); cairo_fill(cr); /* High red Arc */ cairo_move_to(cr,priv->pie_xc,priv->pie_yc); cairo_set_source_rgb (cr, priv->colors[COL_HIGH].red/65535.0, priv->colors[COL_HIGH].green/65535.0, priv->colors[COL_HIGH].blue/65535.0); cairo_arc(cr, priv->pie_xc, priv->pie_yc, priv->pie_radius, (priv->start_angle+135)*(M_PI/180.0), (priv->start_angle+180)*(M_PI/180.0)); cairo_fill(cr); /* Pie Gauge Arcs */ cairo_set_line_width (cr, 1.0); cairo_set_source_rgb (cr, priv->colors[COL_NEEDLE].red/65535.0, priv->colors[COL_NEEDLE].green/65535.0, priv->colors[COL_NEEDLE].blue/65535.0); cairo_arc(cr, priv->pie_xc, priv->pie_yc, priv->pie_radius, priv->start_angle*(M_PI/180.0), (priv->start_angle+priv->sweep_angle)*(M_PI/180.0)); cairo_stroke(cr); cairo_destroy (cr); }
static gboolean gimp_tag_popup_list_expose (GtkWidget *widget, GdkEventExpose *event, GimpTagPopup *popup) { GdkWindow *window = gtk_widget_get_window (widget); GtkStyle *style = gtk_widget_get_style (widget); cairo_t *cr; PangoAttribute *attribute; PangoAttrList *attributes; gint i; cr = gdk_cairo_create (event->window); gdk_cairo_region (cr, event->region); cairo_clip (cr); cairo_set_line_width (cr, 1.0); cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); for (i = 0; i < popup->tag_count; i++) { PopupTagData *tag_data = &popup->tag_data[i]; pango_layout_set_text (popup->layout, gimp_tag_get_name (tag_data->tag), -1); switch (tag_data->state) { case GTK_STATE_SELECTED: attributes = pango_attr_list_copy (popup->combo_entry->selected_item_attr); break; case GTK_STATE_INSENSITIVE: attributes = pango_attr_list_copy (popup->combo_entry->insensitive_item_attr); break; default: attributes = pango_attr_list_copy (popup->combo_entry->normal_item_attr); break; } if (tag_data == popup->prelight && tag_data->state != GTK_STATE_INSENSITIVE) { attribute = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE); pango_attr_list_insert (attributes, attribute); } pango_layout_set_attributes (popup->layout, attributes); pango_attr_list_unref (attributes); if (tag_data->state == GTK_STATE_SELECTED) { gdk_cairo_set_source_color (cr, &popup->combo_entry->selected_item_color); cairo_rectangle (cr, tag_data->bounds.x - 1, tag_data->bounds.y - popup->scroll_y, tag_data->bounds.width + 2, tag_data->bounds.height); cairo_fill (cr); cairo_translate (cr, 0.5, 0.5); cairo_move_to (cr, tag_data->bounds.x, tag_data->bounds.y - popup->scroll_y - 1); cairo_line_to (cr, tag_data->bounds.x + tag_data->bounds.width - 1, tag_data->bounds.y - popup->scroll_y - 1); cairo_move_to (cr, tag_data->bounds.x, tag_data->bounds.y - popup->scroll_y + tag_data->bounds.height); cairo_line_to (cr, tag_data->bounds.x + tag_data->bounds.width - 1, tag_data->bounds.y - popup->scroll_y + tag_data->bounds.height); cairo_stroke (cr); cairo_translate (cr, -0.5, -0.5); } cairo_move_to (cr, (tag_data->bounds.x + GIMP_TAG_POPUP_PADDING), (tag_data->bounds.y - popup->scroll_y + GIMP_TAG_POPUP_PADDING)); pango_cairo_show_layout (cr, popup->layout); if (tag_data == popup->prelight && tag_data->state != GTK_STATE_INSENSITIVE && ! popup->single_select_disabled) { gtk_paint_focus (style, window, tag_data->state, &event->area, widget, NULL, tag_data->bounds.x, tag_data->bounds.y - popup->scroll_y, tag_data->bounds.width, tag_data->bounds.height); } } cairo_destroy (cr); return FALSE; }
/*! \brief updates the chart position, This is the CAIRO implementation \param chart is the pointer to the chart object */ void update_stripchart_position (MtxStripChart *chart) { GtkWidget * widget = NULL; cairo_font_weight_t weight; cairo_font_slant_t slant; gfloat tmpf = 0.0; gfloat needle_pos = 0.0; gchar * tmpbuf = NULL; gchar * message = NULL; gint shift = 0; gfloat start_x = 0.0; gfloat start_y = 0.0; gfloat buffer = 0.0; gboolean draw_quarters = TRUE; gint i = 0; gint j = 0; gfloat x = 0.0; gfloat y = 0.0; gfloat text_offset[NUM_TXTS] = {0.0,0.0,0.0,0.0,0.0}; GdkPoint tip; cairo_t *cr = NULL; cairo_t *cr2 = NULL; cairo_text_extents_t extents; MtxStripChartTrace *trace = NULL; MtxStripChartPrivate *priv = MTX_STRIPCHART_GET_PRIVATE(chart); widget = GTK_WIDGET(chart); shift = priv->newsamples; /* Draw new data to trace pixmap */ /* Scroll trace pixmap */ cr = gdk_cairo_create(priv->trace_pixmap); gdk_cairo_set_source_pixmap(cr,priv->trace_pixmap,-shift,0); cairo_rectangle(cr,0,0,priv->w,priv->h); cairo_fill(cr); cairo_set_source_rgb(cr,0,0,0); cairo_rectangle(cr,priv->w-shift,0,shift,priv->h); cairo_fill(cr); /* Render new data */ for (i=0;i<priv->num_traces;i++) { trace = g_array_index(priv->traces,MtxStripChartTrace *,i); cairo_set_line_width(cr,trace->lwidth); cairo_set_source_rgb (cr, trace->color.red/65535.0, trace->color.green/65535.0, trace->color.blue/65535.0); for(j=shift;j>0;j--) { if (trace->history->len > 1) { start_x = priv->w - j; start_y = priv->h - (((g_array_index(trace->history,gfloat,trace->history->len-j-1)-trace->min) / (trace->max - trace->min))*priv->h); cairo_move_to(cr,start_x,start_y); x = priv->w-j+1; y = priv->h - (((g_array_index(trace->history,gfloat,trace->history->len-j)-trace->min) / (trace->max - trace->min))*priv->h); cairo_line_to(cr,x,y); cairo_stroke(cr); } } } cairo_destroy(cr); /* Copy background trace pixmap to grat for grat rendering */ cr = gdk_cairo_create(priv->grat_pixmap); gdk_cairo_set_source_pixmap(cr,priv->trace_pixmap,0,0); cairo_rectangle(cr,0,0,priv->w,priv->h); cairo_fill(cr); /* Render the graticule lines */ cairo_set_source_rgba (cr, priv->colors[COL_GRAT].red/65535.0, priv->colors[COL_GRAT].green/65535.0, priv->colors[COL_GRAT].blue/65535.0, 0.5); cairo_move_to(cr,0,priv->h/4); cairo_line_to(cr,priv->w,priv->h/4); cairo_stroke(cr); cairo_move_to(cr,0,priv->h/2); cairo_line_to(cr,priv->w,priv->h/2); cairo_stroke(cr); cairo_move_to(cr,0,priv->h*3/4); cairo_line_to(cr,priv->w,priv->h*3/4); cairo_stroke(cr); cairo_set_font_options(cr,priv->font_options); tmpbuf = g_utf8_strup(priv->font,-1); if (g_strrstr(tmpbuf,"BOLD")) weight = CAIRO_FONT_WEIGHT_BOLD; else weight = CAIRO_FONT_WEIGHT_NORMAL; if (g_strrstr(tmpbuf,"OBLIQUE")) slant = CAIRO_FONT_SLANT_OBLIQUE; else if (g_strrstr(tmpbuf,"ITALIC")) slant = CAIRO_FONT_SLANT_ITALIC; else slant = CAIRO_FONT_SLANT_NORMAL; g_free(tmpbuf); cairo_select_font_face (cr, priv->font, slant, weight); cairo_set_font_size (cr, 12); cairo_set_antialias(cr,CAIRO_ANTIALIAS_DEFAULT); buffer = 0; text_offset[BOTTOM] = 0.0; message = g_strdup_printf("123"); cairo_text_extents(cr,message,&extents); if ((extents.height * 4) > (priv->h/4)) draw_quarters = FALSE; else draw_quarters = TRUE; g_free(message); /* render the new data */ cr2 = gdk_cairo_create(priv->grat_pixmap); cairo_set_source_rgba(cr2,0.13,0.13,0.13,0.75); for (i=0;i<priv->num_traces;i++) { trace = g_array_index(priv->traces,MtxStripChartTrace *,i); cairo_set_source_rgb (cr, trace->color.red/65535.0, trace->color.green/65535.0, trace->color.blue/65535.0 ); message = g_strdup_printf("%1$.*2$f", trace->min,trace->precision); cairo_text_extents (cr, message, &extents); cairo_rectangle(cr2,2.0+text_offset[BOTTOM],priv->h-2.0,extents.width,-extents.height); cairo_fill(cr2); cairo_move_to(cr,2.0+text_offset[BOTTOM],priv->h-2.0); cairo_show_text (cr, message); g_free(message); text_offset[BOTTOM] += extents.width + 7; if (draw_quarters) { message = g_strdup_printf("%1$.*2$f", trace->min+((trace->max-trace->min)/4),trace->precision); cairo_text_extents (cr, message, &extents); cairo_rectangle(cr2,2.0+text_offset[QUARTER],priv->h*3/4-2.0,extents.width,-extents.height); cairo_fill(cr2); cairo_move_to(cr,2.0+text_offset[QUARTER],(priv->h*3/4)-2.0); cairo_show_text (cr, message); g_free(message); text_offset[QUARTER] += extents.width + 7; } message = g_strdup_printf("%1$.*2$f", trace->min+((trace->max-trace->min)/2),trace->precision); cairo_text_extents (cr, message, &extents); cairo_rectangle(cr2,2.0+text_offset[HALF],(priv->h/2.0)-2.0,extents.width,-extents.height); cairo_fill(cr2); cairo_move_to(cr,2.0+text_offset[HALF],(priv->h/2.0)-2.0); cairo_show_text (cr, message); g_free(message); text_offset[HALF] += extents.width + 7; if (draw_quarters) { message = g_strdup_printf("%1$.*2$f", trace->min+((trace->max-trace->min)*3/4),trace->precision); cairo_text_extents (cr, message, &extents); cairo_rectangle(cr2,2.0+text_offset[THREEQUARTER],priv->h/4-2.0,extents.width,-extents.height); cairo_fill(cr2); cairo_move_to(cr,2.0+text_offset[THREEQUARTER],(priv->h/4)-2.0); cairo_show_text (cr, message); g_free(message); text_offset[THREEQUARTER] += extents.width + 7; } message = g_strdup_printf("%1$.*2$f", trace->max,trace->precision); cairo_text_extents (cr, message, &extents); cairo_rectangle(cr2,2.0+text_offset[TOP],2.0,extents.width,extents.height); cairo_fill(cr2); cairo_move_to(cr,2.0+text_offset[TOP],extents.height+2.0); cairo_show_text (cr, message); g_free(message); text_offset[TOP] += extents.width + 7; /* Trace names */ message = g_strdup_printf("%s", trace->name); cairo_text_extents (cr, message, &extents); cairo_rectangle(cr2,priv->w-extents.width - 20, 2.0+buffer +extents.height,extents.width,-extents.height); cairo_fill(cr2); cairo_move_to(cr,priv->w-extents.width - 20, 2.0 + buffer + extents.height); cairo_show_text (cr, message); g_free(message); buffer += (extents.height + 3); } cairo_destroy(cr); cairo_destroy(cr2); }
/*! \brief updates the gauge position, This is the CAIRO implementation that looks a bit nicer, though is a little bit slower \param widget (MtxPieGauge *) pointer to the gauge object */ void update_pie_gauge_position (MtxPieGauge *gauge) { GtkWidget * widget = NULL; cairo_font_weight_t weight; cairo_font_slant_t slant; gfloat tmpf = 0.0; gfloat needle_pos = 0.0; gchar * tmpbuf = NULL; gchar * message = NULL; GdkPoint tip; cairo_t *cr = NULL; cairo_text_extents_t extents; MtxPieGaugePrivate *priv = MTX_PIE_GAUGE_GET_PRIVATE(gauge); widget = GTK_WIDGET(gauge); /* Copy background pixmap to intermediary for final rendering */ gdk_draw_drawable(priv->pixmap, widget->style->fg_gc[GTK_WIDGET_STATE (widget)], priv->bg_pixmap, 0,0, 0,0, widget->allocation.width,widget->allocation.height); cr = gdk_cairo_create (priv->pixmap); cairo_set_font_options(cr,priv->font_options); cairo_set_antialias(cr,CAIRO_ANTIALIAS_DEFAULT); /* Update the VALUE text */ cairo_set_source_rgb (cr, priv->colors[COL_VALUE_FONT].red/65535.0, priv->colors[COL_VALUE_FONT].green/65535.0, priv->colors[COL_VALUE_FONT].blue/65535.0); tmpbuf = g_utf8_strup(priv->value_font,-1); if (g_strrstr(tmpbuf,"BOLD")) weight = CAIRO_FONT_WEIGHT_BOLD; else weight = CAIRO_FONT_WEIGHT_NORMAL; if (g_strrstr(tmpbuf,"OBLIQUE")) slant = CAIRO_FONT_SLANT_OBLIQUE; else if (g_strrstr(tmpbuf,"ITALIC")) slant = CAIRO_FONT_SLANT_ITALIC; else slant = CAIRO_FONT_SLANT_NORMAL; g_free(tmpbuf); cairo_select_font_face (cr, priv->value_font, slant, weight); cairo_set_font_size (cr, 11); if (priv->valname) message = g_strdup_printf("%s:%.*f", priv->valname,priv->precision,priv->value); else message = g_strdup_printf("%.*f", priv->precision,priv->value); cairo_text_extents (cr, message, &extents); cairo_move_to (cr, ((priv->w-(priv->pie_radius*2.0 + 5)-extents.width)/2.0) +priv->pie_radius*2.0, priv->pie_yc - (extents.height/4.0)); cairo_show_text (cr, message); g_free(message); cairo_stroke (cr); /* gauge hands */ tmpf = (priv->value-priv->min)/(priv->max-priv->min); needle_pos = (priv->start_angle+(tmpf*priv->sweep_angle))*(M_PI/180); cairo_set_source_rgb (cr, priv->colors[COL_NEEDLE].red/65535.0, priv->colors[COL_NEEDLE].green/65535.0, priv->colors[COL_NEEDLE].blue/65535.0); cairo_set_line_width (cr, 1.5); tip.x = priv->pie_xc + (priv->pie_radius * cos (needle_pos)); tip.y = priv->pie_yc + (priv->pie_radius * sin (needle_pos)); cairo_move_to (cr, priv->pie_xc,priv->pie_yc); cairo_line_to (cr, tip.x,tip.y); cairo_stroke(cr); cairo_destroy(cr); }
void html_engine_draw_cursor_in_area (HTMLEngine *engine, gint x, gint y, gint width, gint height) { HTMLObject *obj; guint offset; gint x1, y1, x2, y2, sc_x, sc_y; GdkRectangle pos; GtkAdjustment *hadj, *vadj; if ((engine->editable || engine->caret_mode) && (engine->cursor_hide_count <= 0 && !engine->thaw_idle_id)) { html_engine_draw_table_cursor (engine); html_engine_draw_cell_cursor (engine); html_engine_draw_image_cursor (engine); } if (!cursor_enabled || engine->cursor_hide_count > 0 || !(engine->editable || engine->caret_mode) || engine->thaw_idle_id) return; obj = engine->cursor->object; if (obj == NULL || engine->window == NULL) return; offset = engine->cursor->offset; if (width < 0 || height < 0) { width = html_engine_get_doc_width (engine); height = html_engine_get_doc_height (engine); x = 0; y = 0; } html_object_get_cursor (obj, engine->painter, offset, &x1, &y1, &x2, &y2); while (obj) { if (html_object_is_frame (obj)) { x1 -= HTML_EMBEDDED (obj)->abs_x; x2 -= HTML_EMBEDDED (obj)->abs_x; y1 -= HTML_EMBEDDED (obj)->abs_y; y2 -= HTML_EMBEDDED (obj)->abs_y; break; } obj = obj->parent; } /* get scroll offset */ hadj = gtk_layout_get_hadjustment (GTK_LAYOUT (engine->widget)); vadj = gtk_layout_get_vadjustment (GTK_LAYOUT (engine->widget)); sc_x = (gint) gtk_adjustment_get_value (hadj); sc_y = (gint) gtk_adjustment_get_value (vadj); pos.x = x1 - sc_x; pos.y = y1 - sc_y; pos.width = x2 - x1; pos.height = y2 - y1; gtk_im_context_set_cursor_location (GTK_HTML (engine->widget)->priv->im_context, &pos); if (clip_cursor (engine, x, y, width, height, &x1, &y1, &x2, &y2)) { cairo_t *cr; gboolean using_painter_cr; using_painter_cr = engine->painter && HTML_IS_GDK_PAINTER (engine->painter) && HTML_GDK_PAINTER (engine->painter)->cr != NULL; if (using_painter_cr) { HTMLGdkPainter *gdk_painter = HTML_GDK_PAINTER (engine->painter); cr = gdk_painter->cr; cairo_save (cr); x1 -= gdk_painter->x1; y1 -= gdk_painter->y1; x2 -= gdk_painter->x1; y2 -= gdk_painter->y1; } else { cr = gdk_cairo_create (engine->window); } cairo_set_source_rgb (cr, 1, 1, 1); cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE); cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); cairo_move_to (cr, x1 + 0.5, y1 + 0.5); cairo_line_to (cr, x2 + 0.5, y2 - 0.5); cairo_set_line_width (cr, 1); cairo_stroke (cr); if (using_painter_cr) cairo_restore (cr); else cairo_destroy (cr); } }
static gboolean load_graph_expose (GtkWidget *widget, GdkEventExpose *event, gpointer data_ptr) { LoadGraph * const g = static_cast<LoadGraph*>(data_ptr); guint i, j; gdouble sample_width, x_offset; if (g->background == NULL) { draw_background(g); } gdk_draw_drawable (g->disp->window, g->gc, g->background, 0, 0, 0, 0, g->disp->allocation.width, g->disp->allocation.height); /* Number of pixels wide for one graph point */ sample_width = (float)(g->draw_width - g->rmargin - g->indent) / (float)LoadGraph::NUM_POINTS; /* General offset */ x_offset = g->draw_width - g->rmargin + (sample_width*2); /* Subframe offset */ x_offset += g->rmargin - ((sample_width / g->frames_per_unit) * g->render_counter); /* draw the graph */ cairo_t* cr; cr = gdk_cairo_create (g->disp->window); cairo_set_line_width (cr, 1); cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); cairo_rectangle (cr, g->rmargin + g->indent + FRAME_WIDTH + 1, FRAME_WIDTH - 1, g->draw_width - g->rmargin - g->indent - 1, g->real_draw_height + FRAME_WIDTH - 1); cairo_clip(cr); for (j = 0; j < g->n; ++j) { cairo_move_to (cr, x_offset, (1.0f - g->data[0][j]) * g->real_draw_height); gdk_cairo_set_source_color (cr, &(g->colors [j])); for (i = 1; i < LoadGraph::NUM_POINTS; ++i) { if (g->data[i][j] == -1.0f) continue; cairo_curve_to (cr, x_offset - ((i - 0.5f) * g->graph_delx), (1.0f - g->data[i-1][j]) * g->real_draw_height + 3.5f, x_offset - ((i - 0.5f) * g->graph_delx), (1.0f - g->data[i][j]) * g->real_draw_height + 3.5f, x_offset - (i * g->graph_delx), (1.0f - g->data[i][j]) * g->real_draw_height + 3.5f); } cairo_stroke (cr); } cairo_destroy (cr); return TRUE; }
static void draw_window (GtkWidget *widget, #if GTK_CHECK_VERSION(3, 0, 0) cairo_t *cr, #else GdkDrawable *drawable, #endif const WnckWindowDisplayInfo *win, const GdkRectangle *winrect, GtkStateType state) { #if !GTK_CHECK_VERSION(3, 0, 0) cairo_t *cr; #endif GdkPixbuf *icon; int icon_x, icon_y, icon_w, icon_h; gboolean is_active; GdkColor *color; GtkStyle *style; is_active = win->is_active; #if GTK_CHECK_VERSION(3, 0, 0) cairo_save(cr); #else cr = gdk_cairo_create (drawable); #endif cairo_rectangle (cr, winrect->x, winrect->y, winrect->width, winrect->height); cairo_clip (cr); style = gtk_widget_get_style (widget); if (is_active) color = &style->light[state]; else color = &style->bg[state]; cairo_set_source_rgb (cr, color->red / 65535., color->green / 65535., color->blue / 65535.); cairo_rectangle (cr, winrect->x + 1, winrect->y + 1, MAX (0, winrect->width - 2), MAX (0, winrect->height - 2)); cairo_fill (cr); icon = win->icon; icon_w = icon_h = 0; if (icon) { icon_w = gdk_pixbuf_get_width (icon); icon_h = gdk_pixbuf_get_height (icon); /* If the icon is too big, fall back to mini icon. * We don't arbitrarily scale the icon, because it's * just too slow on my Athlon 850. */ if (icon_w > (winrect->width - 2) || icon_h > (winrect->height - 2)) { icon = win->mini_icon; if (icon) { icon_w = gdk_pixbuf_get_width (icon); icon_h = gdk_pixbuf_get_height (icon); /* Give up. */ if (icon_w > (winrect->width - 2) || icon_h > (winrect->height - 2)) icon = NULL; } } } if (icon) { icon_x = winrect->x + (winrect->width - icon_w) / 2; icon_y = winrect->y + (winrect->height - icon_h) / 2; cairo_save (cr); gdk_cairo_set_source_pixbuf (cr, icon, icon_x, icon_y); cairo_rectangle (cr, icon_x, icon_y, icon_w, icon_h); cairo_clip (cr); cairo_paint (cr); cairo_restore (cr); } if (is_active) color = &style->fg[state]; else color = &style->fg[state]; cairo_set_source_rgb (cr, color->red / 65535., color->green / 65535., color->blue / 65535.); cairo_set_line_width (cr, 1.0); cairo_rectangle (cr, winrect->x + 0.5, winrect->y + 0.5, MAX (0, winrect->width - 1), MAX (0, winrect->height - 1)); cairo_stroke (cr); #if GTK_CHECK_VERSION(3, 0, 0) cairo_restore(cr); #else cairo_destroy (cr); #endif }
static void gtk_attractor_view_paint(GtkWidget *widget) { GtkAttractor_View *attractor_view = GTK_ATTRACTOR_VIEW(widget); int width, height; PangoLayout *layout; CairoxTextParameters text_p; char buffer[64]; cairo_t *cr; int p, c; width = widget->allocation.width; height = widget->allocation.height; cr = gdk_cairo_create(widget->window); /* Transparent background */ cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.0); cairo_paint(cr); //int current_attractor_i = ((iterations_so_far) && (iterations_so_far < C_MAX)) ? (iterations_so_far) : (0); layout = pango_cairo_create_layout(cr); // if (!training) { // g_snprintf(buffer, 64, "Step: %d", step_number); // cairox_text_parameters_set(&text_p, 20, height-20, PANGOX_XALIGN_LEFT, PANGOX_YALIGN_TOP, 0.0); // cairox_paint_pango_text(cr, &text_p, layout, buffer); cairo_set_source_rgb(cr, 0, 0, 0); cairo_set_line_width(cr, 1); // cairo_rectangle(cr, 20, 20, 120, 80); cairo_rectangle(cr, X_MARGIN, Y_MARGIN, width - (2.0 * X_MARGIN), height - (2.0 * Y_MARGIN)); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 1, 1, 1); cairo_fill(cr); double n_rows = (double) (P + 6); double row_height = (height - (Y_MARGIN*2)) / n_rows; double n_columns = ATTRACTOR_LESION_LEVEL + 1.0; double column_width = (width - (X_MARGIN*2)) / n_columns; int smaller_font_size = 14, bigger_font_size = 16; if (n_rows > 36) { smaller_font_size = 12; bigger_font_size = 15; } pangox_layout_set_font_size(layout, bigger_font_size); g_snprintf(buffer, 64, "Pattern Name"); cairox_text_parameters_set(&text_p, X_MARGIN*2, row_height*2, PANGOX_XALIGN_LEFT, PANGOX_YALIGN_TOP, 0.0); cairox_paint_pango_text(cr, &text_p, layout, buffer); for (c = 0; c < ATTRACTOR_LESION_LEVEL; c++) { g_snprintf(buffer, 64, "%1.1f%% Lesioned", c * 100.0 / (double) ATTRACTOR_LESION_LEVEL); cairox_text_parameters_set(&text_p, column_width*(c+1), row_height*2, PANGOX_XALIGN_LEFT, PANGOX_YALIGN_TOP, 0.0); cairox_paint_pango_text(cr, &text_p, layout, buffer); } pangox_layout_set_font_size(layout, smaller_font_size); for (p = 0; p < P; p++) { g_snprintf(buffer, 64, "%s", get_name_string(p)); cairox_text_parameters_set(&text_p, X_MARGIN*2, (p+4)* row_height, PANGOX_XALIGN_LEFT, PANGOX_YALIGN_TOP, 0.0); cairox_paint_pango_text(cr, &text_p, layout, buffer); } if (attractor_view->response[0][0][0] != -1) { for (c = 0; c < ATTRACTOR_LESION_LEVEL; c++) { for (p = 0; p < P; p++) { g_snprintf(buffer, 64, "%s", get_name_string(attractor_view->response[c][attractor_view->type][p])); cairox_text_parameters_set(&text_p, column_width*(c+1), (p+4)* row_height, PANGOX_XALIGN_LEFT, PANGOX_YALIGN_TOP, 0.0); cairox_paint_pango_text(cr, &text_p, layout, buffer); } } } g_object_unref(layout); cairo_destroy(cr); }
static void draw_icon() { gboolean tsin_pho_mode(); // dbg("draw_icon\n"); if (!da) return; GdkPixbuf *pix = ((! current_CS) || (current_CS->im_state != HIME_STATE_CHINESE)) ? pixbuf : pixbuf_ch; #if GTK_CHECK_VERSION(2,17,7) GtkAllocation dwdh; gtk_widget_get_allocation(da, &dwdh); int dw = dwdh.width, dh = dwdh.height; #else int dw = da->allocation.width, dh = da->allocation.height; #endif int w, h; GdkColor color_fg; // dbg("wh %d,%d\n", dw,dh); gdk_color_parse("black", &color_fg); #if !GTK_CHECK_VERSION(2,90,6) gdk_gc_set_rgb_fg_color(gc, &color_fg); #else gc = gdk_cairo_create (tray_da_win); gdk_cairo_set_source_color (gc, &color_fg); #endif if (pix) { int ofs = (dh - gdk_pixbuf_get_height (pix))/2; #if !GTK_CHECK_VERSION(2,90,6) gdk_draw_pixbuf(tray_da_win, NULL, pix, 0, 0, 0, ofs, -1, -1, GDK_RGB_DITHER_NORMAL, 0, 0); #else gdk_cairo_set_source_pixbuf (gc, pix, 0, ofs); cairo_paint (gc); cairo_destroy (gc); #endif } else { get_text_w_h(inmd[current_CS->in_method].cname, &w, &h); #if !GTK_CHECK_VERSION(2,90,6) gdk_draw_layout(tray_da_win, gc, 0, 0, pango); #else cairo_move_to (gc, 0, 0); pango_cairo_show_layout (gc, pango); cairo_destroy (gc); #endif } if (current_CS) { if (current_CS->b_half_full_char || ( #if USE_TSIN current_method_type()==method_type_TSIN && tss.tsin_half_full && #endif current_CS->im_state == HIME_STATE_CHINESE)) { static char full[] = N_("全"); get_text_w_h(full, &w, &h); #if !GTK_CHECK_VERSION(2,90,6) gdk_draw_layout(tray_da_win, gc, dw - w, dh - h, pango); #else cairo_move_to (gc, dw - w, dh - h); pango_cairo_show_layout (gc, pango); cairo_destroy (gc); #endif } if (current_CS->im_state == HIME_STATE_ENG_FULL) { static char efull[] = N_("A全"); get_text_w_h(efull, &w, &h); #if !GTK_CHECK_VERSION(2,90,6) gdk_draw_layout(tray_da_win, gc, 0, 0, pango); #else cairo_move_to (gc, 0, 0); pango_cairo_show_layout (gc, pango); cairo_destroy (gc); #endif } #if USE_TSIN if (((current_method_type()==method_type_TSIN) || (current_method_type()==method_type_MODULE)) && (current_CS->im_state == HIME_STATE_CHINESE) && (! tsin_pho_mode())) { static char efull[] = "ABC"; gdk_color_parse("blue", &color_fg); #if !GTK_CHECK_VERSION(2,90,6) gdk_gc_set_rgb_fg_color(gc, &color_fg); #else gc = gdk_cairo_create (tray_da_win); gdk_cairo_set_source_color (gc, &color_fg); #endif get_text_w_h(efull, &w, &h); #if !GTK_CHECK_VERSION(2,90,6) gdk_draw_layout(tray_da_win, gc, 0, 0, pango); #else cairo_move_to (gc, 0, 0); pango_cairo_show_layout (gc, pango); cairo_destroy (gc); #endif } #endif } gdk_color_parse("red", &color_fg); #if !GTK_CHECK_VERSION(2,90,6) gdk_gc_set_rgb_fg_color(gc, &color_fg); #else gc = gdk_cairo_create (tray_da_win); gdk_cairo_set_source_color (gc, &color_fg); #endif if (gb_output) { static char sim[] = "简"; get_text_w_h(sim, &w, &h); #if !GTK_CHECK_VERSION(2,90,6) gdk_draw_layout(tray_da_win, gc, 0, dh - h, pango); #else cairo_move_to (gc, 0, dh - h); pango_cairo_show_layout (gc, pango); cairo_destroy (gc); #endif } }
void wnck_draw_workspace (GtkWidget *widget, #if GTK_CHECK_VERSION(3, 0, 0) cairo_t *cr, #else GdkDrawable *drawable, #endif int x, int y, int width, int height, int screen_width, int screen_height, GdkPixbuf *workspace_background, gboolean is_active, const WnckWindowDisplayInfo *windows, int n_windows) { int i; GdkRectangle workspace_rect; GtkStateType state; #if !GTK_CHECK_VERSION(3, 0, 0) cairo_t *cr; #endif workspace_rect.x = x; workspace_rect.y = y; workspace_rect.width = width; workspace_rect.height = height; if (is_active) state = GTK_STATE_SELECTED; else if (workspace_background) state = GTK_STATE_PRELIGHT; else state = GTK_STATE_NORMAL; #if GTK_CHECK_VERSION(3, 0, 0) cairo_save(cr); #else cr = gdk_cairo_create (drawable); #endif if (workspace_background) { gdk_cairo_set_source_pixbuf (cr, workspace_background, x, y); cairo_paint (cr); } else { gdk_cairo_set_source_color (cr, >k_widget_get_style (widget)->dark[state]); cairo_rectangle (cr, x, y, width, height); cairo_fill (cr); } #if !GTK_CHECK_VERSION(3, 0, 0) cairo_destroy (cr); #endif i = 0; while (i < n_windows) { const WnckWindowDisplayInfo *win = &windows[i]; GdkRectangle winrect; get_window_rect (win, screen_width, screen_height, &workspace_rect, &winrect); draw_window (widget, #if GTK_CHECK_VERSION(3, 0, 0) cr, #else drawable, #endif win, &winrect, state); ++i; } #if GTK_CHECK_VERSION(3, 0, 0) cairo_restore(cr); #endif }
static gboolean _gradient_slider_expose(GtkWidget *widget, GdkEventExpose *event) { GtkDarktableGradientSlider *gslider=DTGTK_GRADIENT_SLIDER(widget); assert(gslider->position > 0); g_return_val_if_fail(widget != NULL, FALSE); g_return_val_if_fail(DTGTK_IS_GRADIENT_SLIDER(widget), FALSE); g_return_val_if_fail(event != NULL, FALSE); GtkStyle *style=gtk_rc_get_style_by_paths(gtk_settings_get_default(), NULL,"GtkButton", GTK_TYPE_BUTTON); if(!style) style = gtk_rc_get_style(widget); int state = gtk_widget_get_state(widget); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); /*int x = allocation.x; int y = allocation.y;*/ int width = allocation.width; int height = allocation.height; int margins = gslider->margins; // Begin cairo drawing cairo_t *cr; cr = gdk_cairo_create(gtk_widget_get_window(widget)); // First build the cairo gradient and then fill the gradient float gheight=height/2.0; float gwidth=width-2*margins; GList *current=NULL; cairo_pattern_t *gradient=NULL; if((current=g_list_first(gslider->colors)) != NULL) { gradient=cairo_pattern_create_linear(0,0,gwidth,gheight); do { _gradient_slider_stop_t *stop=(_gradient_slider_stop_t *)current->data; cairo_pattern_add_color_stop_rgb(gradient,stop->position,stop->color.red/65535.0,stop->color.green/65535.0,stop->color.blue/65535.0); } while((current=g_list_next(current))!=NULL); } if(gradient!=NULL) // Do we got a gradient, lets draw it { cairo_set_line_width(cr,0.1); cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND); cairo_set_source(cr,gradient); cairo_rectangle(cr,margins,(height-gheight)/2.0,gwidth,gheight); cairo_fill(cr); cairo_stroke(cr); } // Lets draw position arrows cairo_set_source_rgba(cr, style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0, 1.0 ); // do we have a picker value to draw? gdouble *picker = gslider->picker; if(picker[0] >= 0.0 && picker[0] <= 1.0) { int vx_min=_scale_to_screen(widget, picker[1]); int vx_max=_scale_to_screen(widget, picker[2]); int vx_avg=_scale_to_screen(widget, picker[0]); cairo_set_source_rgba(cr, style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0, 0.33 ); cairo_rectangle(cr,vx_min,(height-gheight)/2.0,fmax((float)vx_max-vx_min, 0.0f),gheight); cairo_fill(cr); cairo_set_source_rgba(cr, style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0, 1.0 ); cairo_move_to(cr,vx_avg,(height-gheight)/2.0); cairo_line_to(cr,vx_avg,(height+gheight)/2.0); cairo_set_antialias(cr,CAIRO_ANTIALIAS_NONE); cairo_set_line_width(cr,1.0); cairo_stroke(cr); } int indirect[GRADIENT_SLIDER_MAX_POSITIONS]; for(int k=0; k<gslider->positions; k++) indirect[k] = gslider->selected == -1 ? k : (gslider->selected + 1 + k) % gslider->positions; for(int k=0; k<gslider->positions; k++) { int l = indirect[k]; int vx=_scale_to_screen(widget, gslider->position[l]); int mk=gslider->marker[l]; int sz=(mk & (1<<3)) ? 13 : 10; // big or small marker? if(l == gslider->selected && (gslider->is_entered == TRUE || gslider->is_dragging == TRUE)) { cairo_set_source_rgba(cr, style->fg[state].red/65535.0, style->fg[state].green/65535.0, style->fg[state].blue/65535.0 * 0.5, 1.0 ); } else { cairo_set_source_rgba(cr, style->fg[state].red/65535.0*0.8, style->fg[state].green/65535.0*0.8, style->fg[state].blue/65535.0*0.8, 1.0 ); } cairo_set_antialias(cr,CAIRO_ANTIALIAS_DEFAULT); if(mk & 0x04) /* upper arrow */ { if (mk & 0x01) /* filled */ dtgtk_cairo_paint_solid_triangle(cr, vx-sz/2, sz < 10 ? 1 : -2,sz,sz,CPF_DIRECTION_DOWN); else dtgtk_cairo_paint_triangle(cr, vx-sz/2, sz < 10 ? 1 : -2,sz,sz,CPF_DIRECTION_DOWN); } if(mk & 0x02) /* lower arrow */ { if (mk & 0x01) /* filled */ dtgtk_cairo_paint_solid_triangle(cr, vx-sz/2,sz < 10 ? height-6 : height-11,sz,sz,CPF_DIRECTION_UP); else dtgtk_cairo_paint_triangle(cr, vx-sz/2,sz < 10 ? height-6 : height-11,sz,sz,CPF_DIRECTION_UP); } } cairo_destroy(cr); return FALSE; }
/*! \brief draws the static part of the stripchart, i.e. this is only the history of the trace, as there's no point to re-render the whole f*****g thing every damn time when only 1 datapoint is being appended, This writes to a pixmap, which is shifted and new trace data rendered, before graticaule/text overlay is added on. \param chart is the pointer to the chart object */ void generate_stripchart_static_traces(MtxStripChart *chart) { cairo_t *cr = NULL; gint w = 0; gint h = 0; gint i = 0; gint j = 0; gfloat x = 0.0; gfloat y = 0.0; gfloat start_x = 0.0; gfloat start_y = 0.0; gint points = 0; MtxStripChartTrace *trace = NULL; MtxStripChartPrivate *priv = MTX_STRIPCHART_GET_PRIVATE(chart); GtkAllocation allocation; gtk_widget_get_allocation(GTK_WIDGET(chart),&allocation); w = allocation.width; h = allocation.height; if (!priv->trace_pixmap) return; /* get a cairo_t */ cr = gdk_cairo_create (priv->trace_pixmap); cairo_set_font_options(cr,priv->font_options); cairo_set_source_rgb (cr, priv->colors[COL_BG].red/65535.0, priv->colors[COL_BG].green/65535.0, priv->colors[COL_BG].blue/65535.0); /* Background Rectangle */ cairo_rectangle (cr, 0,0,w,h); cairo_fill(cr); for (i=0;i<priv->num_traces;i++) { trace = g_array_index(priv->traces,MtxStripChartTrace *,i); if (!trace) continue; cairo_set_line_width(cr,trace->lwidth); cairo_set_source_rgb (cr, trace->color.red/65535.0, trace->color.green/65535.0, trace->color.blue/65535.0); points = trace->history->len < priv->w ? trace->history->len-1:priv->w; if (points < 1) continue; start_x = priv->w - points; start_y = priv->h - (((g_array_index(trace->history,gfloat,trace->history->len - points)-trace->min) / (trace->max - trace->min))*priv->h); cairo_move_to(cr,start_x,start_y); for (j=0;j<points;j++) { x = priv->w - points + j; y = priv->h - (((g_array_index(trace->history,gfloat,trace->history->len - points + j)-trace->min) / (trace->max - trace->min))*priv->h); cairo_line_to(cr,x,y); } cairo_stroke(cr); } cairo_destroy (cr); }
/*! \brief handles configure events when the chart gets created or resized. Takes care of creating/destroying graphics contexts, backing pixmaps (two levels are used to split the rendering for speed reasons) colormaps are also created here as well \param widget is the pointer to the chart object \param event is the pointer to the GdkEventConfigure structure that encodes important info like window dimensions and depth. \returns TRUE on success, FALSE otherwise */ gboolean mtx_stripchart_configure (GtkWidget *widget, GdkEventConfigure *event) { MtxStripChart * chart = MTX_STRIPCHART(widget); MtxStripChartPrivate *priv = NULL; cairo_t *cr = NULL; GtkAllocation allocation; GdkWindow *window = gtk_widget_get_window(widget); g_return_val_if_fail(MTX_IS_STRIPCHART(widget),FALSE); gtk_widget_get_allocation(widget,&allocation); priv = MTX_STRIPCHART_GET_PRIVATE(chart); priv->w = allocation.width; priv->h = allocation.height; /* Backing pixmap (copy of window) */ if (priv->bg_pixmap) g_object_unref(priv->bg_pixmap); priv->bg_pixmap=gdk_pixmap_new(window, priv->w,priv->h, gtk_widget_get_visual(widget)->depth); cr = gdk_cairo_create(priv->bg_pixmap); cairo_set_operator(cr,CAIRO_OPERATOR_DEST_OUT); cairo_paint(cr); cairo_destroy(cr); /* Trace pixmap */ if (priv->trace_pixmap) g_object_unref(priv->trace_pixmap); priv->trace_pixmap=gdk_pixmap_new(window, priv->w,priv->h, gtk_widget_get_visual(widget)->depth); cr = gdk_cairo_create(priv->trace_pixmap); cairo_set_operator(cr,CAIRO_OPERATOR_DEST_OUT); cairo_paint(cr); cairo_destroy(cr); /* Grat pixmap */ if (priv->grat_pixmap) g_object_unref(priv->grat_pixmap); priv->grat_pixmap=gdk_pixmap_new(window, priv->w,priv->h, gtk_widget_get_visual(widget)->depth); cr = gdk_cairo_create(priv->grat_pixmap); cairo_set_operator(cr,CAIRO_OPERATOR_DEST_OUT); cairo_paint(cr); cairo_destroy(cr); gdk_window_set_back_pixmap(window,priv->bg_pixmap,0); if (priv->font_options) cairo_font_options_destroy(priv->font_options); priv->font_options = cairo_font_options_create(); cairo_font_options_set_antialias(priv->font_options, CAIRO_ANTIALIAS_GRAY); generate_stripchart_static_traces(chart); render_marker (chart); return TRUE; }
inf_text_gtk_viewport_scrollbar_expose_event_cb(GtkWidget* scrollbar, GdkEventExpose* event, gpointer user_data) #endif { InfTextGtkViewport* viewport; InfTextGtkViewportPrivate* priv; InfTextGtkViewportUser* viewport_user; GdkRectangle* rectangle; GdkColor* color; double h,s,v; double r,g,b; GSList* item; double line_width; #if GTK_CHECK_VERSION(2, 91, 0) GdkRectangle clip_area; #else cairo_t* cr; #endif viewport = INF_TEXT_GTK_VIEWPORT(user_data); priv = INF_TEXT_GTK_VIEWPORT_PRIVATE(viewport); /* Can this happen? */ #if GTK_CHECK_VERSION(2, 91, 0) if(!gtk_cairo_should_draw_window(cr, gtk_widget_get_window(scrollbar))) #elif GTK_CHECK_VERSION(2,14,0) if(event->window != gtk_widget_get_window(scrollbar)) #else if(event->window != GTK_WIDGET(scrollbar)->window) #endif return FALSE; if(priv->show_user_markers) { color = >k_widget_get_style(scrollbar)->bg[GTK_STATE_NORMAL]; h = color->red / 65535.0; s = color->green / 65535.0; v = color->blue / 65535.0; rgb_to_hsv(&h, &s, &v); s = MIN(MAX(s, 0.5), 0.8); v = MAX(v, 0.5); #if GTK_CHECK_VERSION(2, 91, 0) gtk_cairo_transform_to_window( cr, GTK_WIDGET(scrollbar), gtk_widget_get_window(scrollbar) ); gdk_cairo_get_clip_rectangle(cr, &clip_area); #else cr = gdk_cairo_create(event->window); #endif line_width = cairo_get_line_width(cr); for(item = priv->users; item != NULL; item = item->next) { viewport_user = (InfTextGtkViewportUser*)item->data; rectangle = &viewport_user->rectangle; #if GTK_CHECK_VERSION(2, 91, 0) if(gdk_rectangle_intersect(&clip_area, rectangle, NULL)) #elif GTK_CHECK_VERSION(2,90,5) if(cairo_region_contains_rectangle(event->region, rectangle) != CAIRO_REGION_OVERLAP_OUT) #else if(gdk_region_rect_in(event->region, rectangle) != GDK_OVERLAP_RECTANGLE_OUT) #endif { h = inf_text_user_get_hue(viewport_user->user); cairo_rectangle( cr, rectangle->x + line_width/2, rectangle->y + line_width/2, rectangle->width - line_width, rectangle->height - line_width ); r = h; g = s; b = v/2.0; hsv_to_rgb(&r, &g, &b); cairo_set_source_rgba(cr, r, g, b, 0.6); cairo_stroke_preserve(cr); r = h; g = s; b = v; hsv_to_rgb(&r, &g, &b); cairo_set_source_rgba(cr, r, g, b, 0.6); cairo_fill(cr); } } #if ! GTK_CHECK_VERSION(2, 91, 0) cairo_destroy(cr); #endif } return FALSE; }
static gboolean calf_vumeter_expose (GtkWidget *widget, GdkEventExpose *event) { g_assert(CALF_IS_VUMETER(widget)); CalfVUMeter *vu = CALF_VUMETER(widget); cairo_t *c = gdk_cairo_create(GDK_DRAWABLE(widget->window)); float r, g, b; int x = widget->allocation.x; int y = widget->allocation.y; int width = widget->allocation.width; int height = widget->allocation.height; int border_x = widget->style->xthickness; int border_y = widget->style->ythickness; int space_x = 1; int space_y = 1; // inner border around led bar int led = 2; // single LED size int led_m = 1; // margin between LED int led_s = led + led_m; // size of LED with margin int led_x = widget->style->xthickness; int led_y = widget->style->ythickness; // position of first LED int led_w = width - 2 * led_x + led_m; // width of LED bar w/o text calc (additional led margin, is removed later; used for filling the led bar completely w/o margin gap) int led_h = height - 2 * led_y; // height of LED bar w/o text calc int text_x = 0; int text_y = 0; int text_w = 0; int text_h = 0; // only valid if vumeter is enabled cairo_text_extents_t extents; if(vu->vumeter_position) { cairo_select_font_face(c, "cairo:sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(c, 8); cairo_text_extents(c, "-88.88", &extents); text_w = extents.width; text_h = extents.height; switch(vu->vumeter_position) { case 1: text_x = width / 2 - text_w / 2; text_y = border_y + led_y - extents.y_bearing; led_y += text_h + led_y; led_h -= text_h + led_y; break; case 2: text_x = width - border_x - led_x - text_w; text_y = height / 2 - text_h / 2 - extents.y_bearing; led_w -= led_x + text_w; break; case 3: text_x = width / 2 - text_w / 2; text_y = height - border_y - led_y - text_h - extents.y_bearing; led_h -= led_y + text_h; break; case 4: text_x = border_x + led_x; text_y = height / 2 - text_h / 2 - extents.y_bearing; led_x += led_x + text_w; led_w -= led_x + text_w; break; } } led_w -= led_w % led_s + led_m; //round LED width to LED size and remove margin gap, width is filled with LED without margin gap now if( vu->cache_surface == NULL ) { // looks like its either first call or the widget has been resized. // create the cache_surface. vu->cache_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height ); cairo_t *cache_cr = cairo_create( vu->cache_surface ); float radius, bevel; get_bg_color(widget, NULL, &r, &g, &b); gtk_widget_style_get(widget, "border-radius", &radius, "bevel", &bevel, NULL); create_rectangle(cache_cr, 0, 0, width, height, radius); cairo_set_source_rgb(cache_cr, r, g, b); cairo_fill(cache_cr); draw_bevel(cache_cr, 0, 0, width, height, radius, bevel); // border around LED cairo_rectangle(cache_cr, led_x, led_y, led_w, led_h); cairo_set_source_rgb (cache_cr, 0, 0, 0); cairo_fill(cache_cr); led_x += space_x; led_y += space_y; led_w -= 2 * space_x; led_h -= 2 * space_y; // LED bases cairo_set_line_width(cache_cr, 1); for (int x = led_x; x + led <= led_x + led_w; x += led_s) { float ts = (x - led_x) * 1.0 / led_w; float r = 0.f, g = 0.f, b = 0.f; switch(vu->mode) { case VU_STANDARD: default: if (ts < 0.75) r = ts / 0.75, g = 0.5 + ts * 0.66, b = 1 - ts / 0.75; else r = 1, g = 1 - (ts - 0.75) / 0.25, b = 0; // if (vu->value < ts || vu->value <= 0) // r *= 0.5, g *= 0.5, b *= 0.5; break; case VU_STANDARD_CENTER: if (ts < 0.25) // 0.0 -> 0.25 // green: 0.f -> 1.f r = 1, g = (ts) / 0.25, b = 0; else if (ts > 0.75) // 0.75 -> 1.0 // green: 1.f -> 0.f r = 1, g = 1 - (ts - 0.75) / 0.25, b = 0; else if (ts > 0.5) // 0.5 -> 0.75 // red: 0.f -> 1.f // green: 0.5 -> 1.f // blue: 1.f -> 0.f r = (ts - 0.5) / 0.25, g = 0.5 + (ts - 0.5) * 2.f, b = 1 - (ts - 0.5) / 0.25; else // 0.25 -> 0.5 // red: 1.f -> 0.f // green: 1.f -> 0.5 // blue: 0.f -> 1.f r = 1 - (ts - 0.25) / 0.25, g = 1.f - (ts * 2.f - .5f), b = (ts - 0.25) / 0.25; // if (vu->value < ts || vu->value <= 0) // r *= 0.5, g *= 0.5, b *= 0.5; break; case VU_MONOCHROME_REVERSE: r = 0, g = 170.0 / 255.0, b = 1; // if (!(vu->value < ts) || vu->value >= 1.0) // r *= 0.5, g *= 0.5, b *= 0.5; break; case VU_MONOCHROME: r = 0, g = 170.0 / 255.0, b = 1; // if (vu->value < ts || vu->value <= 0) // r *= 0.5, g *= 0.5, b *= 0.5; break; case VU_MONOCHROME_CENTER: r = 0, g = 170.0 / 255.0, b = 1; // if (vu->value < ts || vu->value <= 0) // r *= 0.5, g *= 0.5, b *= 0.5; break; } GdkColor sc2 = { 0, (guint16)(65535 * r + 0.2), (guint16)(65535 * g), (guint16)(65535 * b) }; GdkColor sc3 = { 0, (guint16)(65535 * r * 0.7), (guint16)(65535 * g * 0.7), (guint16)(65535 * b * 0.7) }; gdk_cairo_set_source_color(cache_cr, &sc2); cairo_move_to(cache_cr, x + 0.5, led_y); cairo_line_to(cache_cr, x + 0.5, led_y + led_h); cairo_stroke(cache_cr); gdk_cairo_set_source_color(cache_cr, &sc3); cairo_move_to(cache_cr, x + 1.5, led_y + led_h); cairo_line_to(cache_cr, x + 1.5, led_y); cairo_stroke(cache_cr); } // create blinder pattern cairo_pattern_t *pat = cairo_pattern_create_linear (led_x, led_y, led_x, led_y + led_h); cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 0.25); cairo_pattern_add_color_stop_rgba (pat, 0.5, 0.5, 0.5, 0.5, 0.0); cairo_pattern_add_color_stop_rgba (pat, 1, 0.0, 0.0, 0.0, 0.25); cairo_rectangle(cache_cr, led_x, led_y, led_w, led_h); cairo_set_source(cache_cr, pat); cairo_fill(cache_cr); // create overlay vu->cache_overlay = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *over_cr = cairo_create(vu->cache_overlay); // copy surface to overlay cairo_set_source_surface(over_cr, vu->cache_surface, 0, 0); cairo_rectangle(over_cr, 0, 0, width, height); cairo_fill(over_cr); // create blinder pattern pat = cairo_pattern_create_linear (led_x, led_y, led_x, led_y + led_h); cairo_pattern_add_color_stop_rgba (pat, 0, 0.2, 0.2, 0.2, 0.7); cairo_pattern_add_color_stop_rgba (pat, 0.4, 0.05, 0.05, 0.05, 0.7); cairo_pattern_add_color_stop_rgba (pat, 0.401, 0.05, 0.05, 0.05, 0.9); cairo_pattern_add_color_stop_rgba (pat, 1, 0.05, 0.05, 0.05, 0.75); // draw on top of overlay cairo_set_source(over_cr, pat); cairo_rectangle(over_cr, 0, 0, width, height); cairo_paint(over_cr); // clean up cairo_destroy(cache_cr); cairo_destroy(over_cr); } else { led_x += space_x; led_y += space_y; led_w -= 2 * space_x; led_h -= 2 * space_y; } led_x += x; led_y += y; text_x += x; text_y += y; // draw LED blinder cairo_set_source_surface( c, vu->cache_surface, x, y ); cairo_paint( c ); cairo_set_source_surface( c, vu->cache_overlay, x, y ); // get microseconds timeval tv; gettimeofday(&tv, 0); long time = tv.tv_sec * 1000 * 1000 + tv.tv_usec; // limit to 1.f float value_orig = std::max(std::min(vu->value, 1.f), 0.f); float value = 0.f; // falloff? if(vu->vumeter_falloff > 0.f and vu->mode != VU_MONOCHROME_REVERSE) { // fall off a bit float s = ((float)(time - vu->last_falltime) / 1000000.0); float m = vu->last_falloff * s * vu->vumeter_falloff; vu->last_falloff -= m; // new max value? if(value_orig > vu->last_falloff) { vu->last_falloff = value_orig; } value = vu->last_falloff; vu->last_falltime = time; vu->falling = vu->last_falloff > 0.00000001; } else { // falloff disabled vu->last_falloff = 0.f; vu->last_falltime = 0.f; value = value_orig; vu->falling = false; } float draw = 0.f; float draw_last = 0.f; if(vu->vumeter_hold > 0.0) { // peak hold timer if(time - (long)(vu->vumeter_hold * 1000 * 1000) > vu->last_hold) { // time's up, reset vu->last_value = value; vu->last_hold = time; vu->holding = false; vu->disp_value = value_orig; } if( vu->mode == VU_MONOCHROME_REVERSE ) { if(value < vu->last_value) { // value is above peak hold vu->last_value = value; vu->last_hold = time; vu->holding = true; } draw = log10(1 + value * 9); draw_last = log10(1 + vu->last_value * 9); // blinder left -> hold LED int hold_x = round((draw_last) * (led_w + led_m)); // add last led_m removed earlier hold_x -= hold_x % led_s + led_m; hold_x = std::max(0, hold_x); cairo_rectangle( c, led_x, led_y, hold_x, led_h); // blinder hold LED -> value int val_x = round((1 - draw) * (led_w + led_m)); // add last led_m removed earlier val_x -= val_x % led_s; int blind_x = std::min(hold_x + led_s, led_w); int blind_w = std::min(std::max(led_w - val_x - hold_x - led_s, 0), led_w); cairo_rectangle(c, led_x + blind_x, led_y, blind_w, led_h); } else if( vu->mode == VU_STANDARD_CENTER ) { if(value > vu->last_value) { // value is above peak hold vu->last_value = value; vu->last_hold = time; vu->holding = true; } draw = log10(1 + value * 9); int val_x = round((1 - draw) / 2.f * (led_w + led_m)); // add last led_m removed earlier cairo_rectangle(c, led_x, led_y, val_x, led_h); cairo_rectangle(c, led_x + led_w - val_x, led_y, val_x, led_h); } else { if(value > vu->last_value) { // value is above peak hold vu->last_value = value; vu->last_hold = time; vu->holding = true; } draw = log10(1 + value * 9); draw_last = log10(1 + vu->last_value * 9); int hold_x = round((1 - draw_last) * (led_w + led_m)); // add last led_m removed earlier hold_x -= hold_x % led_s; int val_x = round(draw * (led_w + led_m)); // add last led_m removed earlier val_x -= val_x % led_s; int blind_w = led_w - hold_x - led_s - val_x; blind_w = std::min(std::max(blind_w, 0), led_w); cairo_rectangle(c, led_x + val_x, led_y, blind_w, led_h); cairo_rectangle( c, led_x + led_w - hold_x, led_y, hold_x, led_h); } } else { // darken normally float draw = log10(1 + value * 9); if( vu->mode == VU_MONOCHROME_REVERSE ) cairo_rectangle( c, led_x, led_y, draw * led_w, led_h); else if( vu->mode == VU_STANDARD_CENTER ) { int val_x = round((1 - draw) / 2.f * (led_w + led_m)); // add last led_m removed earlier cairo_rectangle(c, led_x, led_y, val_x, led_h); cairo_rectangle(c, led_x + led_w - val_x, led_y, val_x, led_h); } else cairo_rectangle( c, led_x + draw * led_w, led_y, led_w * (1 - draw), led_h); } cairo_fill( c ); if (vu->vumeter_position) { char str[32]; if((vu->value > vu->disp_value and vu->mode != VU_MONOCHROME_REVERSE) or (vu->value < vu->disp_value and vu->mode == VU_MONOCHROME_REVERSE)) vu->disp_value = vu->value; if (vu->disp_value < 1.0 / 32768.0) snprintf(str, sizeof(str), "-inf"); else snprintf(str, sizeof(str), "%0.2f", dsp::amp2dB(vu->disp_value)); // draw value as number cairo_text_extents(c, str, &extents); cairo_move_to(c, text_x + (text_w - extents.width) / 2.0, text_y); GtkStateType state; if(vu->disp_value > 1.f and vu->mode != VU_MONOCHROME_REVERSE) state = GTK_STATE_ACTIVE; else state = GTK_STATE_NORMAL; get_fg_color(widget, &state, &r, &g, &b); cairo_set_source_rgba (c, r, g, b, 1); cairo_show_text(c, str); cairo_fill(c); } cairo_destroy(c); //gtk_paint_shadow(widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, NULL, widget, NULL, ox - 2, oy - 2, sx + 4, sy + 4); //printf("exposed %p %d+%d\n", widget->window, widget->allocation.x, widget->allocation.y); return TRUE; }
static gboolean _lib_filmstrip_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_filmstrip_t *strip = (dt_lib_filmstrip_t *)self->data; int32_t width = widget->allocation.width; int32_t height = widget->allocation.height; gdouble pointerx = strip->pointerx; gdouble pointery = strip->pointery; if(darktable.gui->center_tooltip == 1) darktable.gui->center_tooltip++; strip->image_over = DT_VIEW_DESERT; DT_CTL_SET_GLOBAL(lib_image_mouse_over_id, -1); /* create cairo surface */ cairo_t *cr = gdk_cairo_create(widget->window); /* fill background */ cairo_set_source_rgb (cr, .2, .2, .2); cairo_paint(cr); int offset = strip->offset; const float wd = height; const float ht = height; int max_cols = (int)(width/(float)wd) + 2; if (max_cols%2 == 0) max_cols += 1; const int col_start = max_cols/2 - strip->offset; const int empty_edge = (width - (max_cols * wd))/2; int step_res = SQLITE_ROW; sqlite3_stmt *stmt = NULL; /* mouse over image position in filmstrip */ pointerx -= empty_edge; const int seli = (pointery > 0 && pointery <= ht) ? pointerx / (float)wd : -1; const int img_pointerx = (int)fmodf(pointerx, wd); const int img_pointery = (int)pointery; /* get the count of current collection */ strip->collection_count = dt_collection_get_count (darktable.collection); /* get the collection query */ const gchar *query=dt_collection_get_query (darktable.collection); if(!query) return FALSE; if(offset < 0) strip->offset = offset = 0; if(offset > strip->collection_count-1) strip->offset = offset = strip->collection_count-1; // dt_view_set_scrollbar(self, offset, count, max_cols, 0, 1, 1); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, offset - max_cols/2); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, max_cols); cairo_save(cr); cairo_translate(cr, empty_edge, 0.0f); for(int col = 0; col < max_cols; col++) { if(col < col_start) { cairo_translate(cr, wd, 0.0f); continue; } if(step_res != SQLITE_DONE) { step_res = sqlite3_step(stmt); } if(step_res == SQLITE_ROW) { int id = sqlite3_column_int(stmt, 0); // set mouse over id if(seli == col) { strip->mouse_over_id = id; DT_CTL_SET_GLOBAL(lib_image_mouse_over_id, strip->mouse_over_id); } cairo_save(cr); // FIXME find out where the y translation is done, how big the value is and use it directly instead of getting it from the matrix ... cairo_matrix_t m; cairo_get_matrix(cr, &m); dt_view_image_expose(&(strip->image_over), id, cr, wd, ht, max_cols, img_pointerx, img_pointery, FALSE); cairo_restore(cr); } else if (step_res == SQLITE_DONE) { /* do nothing, just add some empty thumb frames */ } else goto failure; cairo_translate(cr, wd, 0.0f); } failure: cairo_restore(cr); sqlite3_finalize(stmt); if(darktable.gui->center_tooltip == 1) // set in this round { char* tooltip = dt_history_get_items_as_string(strip->mouse_over_id); if(tooltip != NULL) { g_object_set(G_OBJECT(strip->filmstrip), "tooltip-text", tooltip, (char *)NULL); g_free(tooltip); } } else if(darktable.gui->center_tooltip == 2) // not set in this round { darktable.gui->center_tooltip = 0; g_object_set(G_OBJECT(strip->filmstrip), "tooltip-text", "", (char *)NULL); } #ifdef _DEBUG if(darktable.unmuted & DT_DEBUG_CACHE) dt_mipmap_cache_print(darktable.mipmap_cache); #endif /* cleanup */ cairo_destroy(cr); return TRUE; }
gboolean draw_callback (GtkWidget *widget, GdkEventExpose *event, UNUSED gpointer data) { guint width, height; cairo_pattern_t *color; cairo_path_t *bolt, *fill, *text; // Grab our widget size width = widget->allocation.width; height = widget->allocation.height; // Set up Cairo cairo_t *cr = gdk_cairo_create(widget->window); cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST); // Clear canvas #ifdef BACKGROUND_FILL_ENTIRE_WIDGET cairo_rectangle(cr, 0, 0, width, height); #else cairo_rectangle(cr, (MARGIN / 2) + STROKE_WIDTH, (MARGIN / 2) + STROKE_WIDTH, BATTERY_WIDTH, BATTERY_HEIGHT); #endif cairo_set_source_rgba(cr, COLOR_BACKGROUND, OPACITY_BACKGROUND); cairo_fill(cr); // Decide on a color color = cairo_pattern_create_rgb(COLOR_DEFAULT); if (battery_get_charging()) color = cairo_pattern_create_rgb(COLOR_CHARGING); if (battery_get_critical()) color = cairo_pattern_create_rgb(COLOR_CRITICAL); battery_border_draw(cr, color, (int)CENTERED(width, BATTERY_WIDTH), (int)CENTERED(height, BATTERY_HEIGHT), BATTERY_WIDTH, BATTERY_HEIGHT, STROKE_WIDTH, PEG_WIDTH, PEG_HEIGHT); int fill_x = CENTERED(width, BATTERY_WIDTH); int fill_y = CENTERED(height, BATTERY_HEIGHT); // Set fill style cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD); // Generate battery fill fill = battery_fill_generate(BATTERY_WIDTH, BATTERY_HEIGHT, battery_get_percent()); cairo_translate(cr, fill_x, fill_y); cairo_append_path(cr, fill); if (battery_get_charging()) { int bolt_x = CENTERED(BATTERY_WIDTH, BOLT_WIDTH); int bolt_y = CENTERED(BATTERY_HEIGHT, BOLT_HEIGHT); cairo_translate(cr, bolt_x, bolt_y); bolt = battery_bolt_generate(BOLT_WIDTH, BOLT_HEIGHT); cairo_append_path(cr, bolt); cairo_translate(cr, bolt_x, bolt_y); } else { cairo_text_extents_t extents; char strpercent[5]; snprintf(strpercent, 5, "%i%%", (int)(battery_get_percent() * 100)); cairo_select_font_face(cr, FONT_FACE, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cr, FONT_SIZE); cairo_text_extents(cr, strpercent, &extents); int text_x = CENTERED(BATTERY_WIDTH, extents.width); int text_y = CENTERED(BATTERY_HEIGHT, extents.height + extents.y_bearing*2); text = battery_text_generate(strpercent, FONT_FACE, FONT_SIZE); cairo_translate(cr, text_x, text_y); cairo_append_path(cr, text); cairo_translate(cr, -text_x, -text_y); } cairo_translate(cr, -fill_x, -fill_y); cairo_set_source(cr, color); cairo_fill(cr); return FALSE; }
static gboolean gx_selector_expose (GtkWidget *widget, GdkEventExpose *event) { g_assert(GX_IS_SELECTOR(widget)); GxSelector *selector = GX_SELECTOR(widget); GxSelectorPrivate *priv = selector->priv; int selectorstate = get_selector_state(selector); gx_selector_create_icon(selector); PangoLayout *layout = gtk_widget_create_pango_layout(widget, NULL); GdkRectangle arrow, text; gint off_x, off_y; gx_selector_get_positions(widget, &arrow, &text, &off_x, &off_y); gint rad; float bevel; gtk_widget_style_get(widget, "border-radius", &rad, "bevel", &bevel, NULL); if (!rad) rad = 0; if (!bevel) bevel = 0; cairo_t * cr = gdk_cairo_create(GDK_DRAWABLE(widget->window)); GdkRegion *reg = gdk_region_rectangle(&widget->allocation); if (event->region) gdk_region_intersect(reg, event->region); gdk_cairo_region(cr, reg); cairo_clip (cr); gx_draw_rect(widget, "bg", NULL, widget->allocation.x, widget->allocation.y + (widget->allocation.height - widget->requisition.height) / 2, widget->allocation.width, widget->requisition.height, rad, bevel); if (widget->style->ythickness >= 3) gx_draw_inset(widget, text.x, text.y, text.width, text.height, std::max(rad - std::max(widget->style->ythickness, widget->style->ythickness), 0), 1); gx_draw_rect(widget, "base", NULL, text.x, text.y, text.width, text.height, std::max(rad - std::max(widget->style->ythickness, widget->style->ythickness), 0), 0); gx_draw_glass(widget, text.x, text.y, text.width, text.height, std::max(rad - std::max(widget->style->ythickness, widget->style->ythickness), 0)); gdk_cairo_set_source_pixbuf(cr, selector->icon, arrow.x, arrow.y); cairo_rectangle(cr, arrow.x, arrow.y, arrow.width, arrow.height); cairo_fill(cr); cairo_destroy(cr); if (selector->model) { gint x, y; PangoRectangle logical; char *s; GtkTreeIter iter; gtk_tree_model_iter_nth_child(selector->model, &iter, NULL, selectorstate); gtk_tree_model_get(selector->model, &iter, 0, &s, -1); pango_layout_set_text(layout, s, -1); pango_layout_get_pixel_extents(layout, NULL, &logical); x = text.x + (text.width - logical.width) / 2; y = text.y + off_y + (priv->textsize.height - logical.height)/ 2; gtk_paint_layout(widget->style, widget->window, gtk_widget_get_state(widget), FALSE, NULL, widget, "label", x, y, layout); g_free(s); } g_object_unref(layout); gdk_region_destroy(reg); return TRUE; }
static gboolean dt_iop_tonecurve_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_tonecurve_gui_data_t *c = (dt_iop_tonecurve_gui_data_t *)self->gui_data; dt_iop_tonecurve_params_t *p = (dt_iop_tonecurve_params_t *)self->params; dt_develop_t *dev = darktable.develop; const float color_labels_left[3][3] = { { 0.3f, 0.3f, 0.3f }, { 0.0f, 0.34f, 0.27f }, { 0.0f, 0.27f, 0.58f } }; const float color_labels_right[3][3] = {{ 0.3f, 0.3f, 0.3f }, { 0.53f, 0.08f, 0.28f}, { 0.81f, 0.66f, 0.0f } }; int ch = c->channel; int nodes = p->tonecurve_nodes[ch]; dt_iop_tonecurve_node_t *tonecurve = p->tonecurve[ch]; int autoscale_ab = p->tonecurve_autoscale_ab; if(c->minmax_curve_type[ch] != p->tonecurve_type[ch] || c->minmax_curve_nodes[ch] != p->tonecurve_nodes[ch]) { dt_draw_curve_destroy(c->minmax_curve[ch]); c->minmax_curve[ch] = dt_draw_curve_new(0.0, 1.0, p->tonecurve_type[ch]); c->minmax_curve_nodes[ch] = p->tonecurve_nodes[ch]; c->minmax_curve_type[ch] = p->tonecurve_type[ch]; for(int k=0; k<p->tonecurve_nodes[ch]; k++) (void)dt_draw_curve_add_point(c->minmax_curve[ch], p->tonecurve[ch][k].x, p->tonecurve[ch][k].y); } else { for(int k=0; k<p->tonecurve_nodes[ch]; k++) dt_draw_curve_set_point(c->minmax_curve[ch], k, p->tonecurve[ch][k].x, p->tonecurve[ch][k].y); } dt_draw_curve_t *minmax_curve = c->minmax_curve[ch]; dt_draw_curve_calc_values(minmax_curve, 0.0, 1.0, DT_IOP_TONECURVE_RES, c->draw_xs, c->draw_ys); const float xm = tonecurve[nodes-1].x; const float x[4] = {0.7f*xm, 0.8f*xm, 0.9f*xm, 1.0f*xm}; const float y[4] = {c->draw_ys[CLAMP((int)(x[0]*DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES-1)], c->draw_ys[CLAMP((int)(x[1]*DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES-1)], c->draw_ys[CLAMP((int)(x[2]*DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES-1)], c->draw_ys[CLAMP((int)(x[3]*DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES-1)] }; float unbounded_coeffs[3]; dt_iop_estimate_exp(x, y, 4, unbounded_coeffs); const int inset = DT_GUI_CURVE_EDITOR_INSET; int width = widget->allocation.width, height = widget->allocation.height; cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); // clear bg cairo_set_source_rgb (cr, .2, .2, .2); cairo_paint(cr); cairo_translate(cr, inset, inset); width -= 2*inset; height -= 2*inset; #if 0 // draw shadow around float alpha = 1.0f; for(int k=0; k<inset; k++) { cairo_rectangle(cr, -k, -k, width + 2*k, height + 2*k); cairo_set_source_rgba(cr, 0, 0, 0, alpha); alpha *= 0.6f; cairo_fill(cr); } #else cairo_set_line_width(cr, 1.0); cairo_set_source_rgb (cr, .1, .1, .1); cairo_rectangle(cr, 0, 0, width, height); cairo_stroke(cr); #endif cairo_set_source_rgb (cr, .3, .3, .3); cairo_rectangle(cr, 0, 0, width, height); cairo_fill(cr); // draw color labels const int cells = 8; for(int j=0; j<cells; j++) { for(int i=0; i<cells; i++) { const float f = (cells-1-j+i)/(2.0f*cells-2.0f); cairo_set_source_rgba (cr, (1.0f-f)*color_labels_left[ch][0] + f*color_labels_right[ch][0], (1.0f-f)*color_labels_left[ch][1] + f*color_labels_right[ch][1], (1.0f-f)*color_labels_left[ch][2] + f*color_labels_right[ch][2], .5f); // blend over to make colors darker, so the overlay is more visible cairo_rectangle(cr, width*i/(float)cells, height*j/(float)cells, width/(float)cells, height/(float)cells); cairo_fill(cr); } } // draw grid cairo_set_line_width(cr, .4); cairo_set_source_rgb (cr, .1, .1, .1); if(dev->histogram_type == DT_DEV_HISTOGRAM_WAVEFORM) dt_draw_waveform_lines(cr, 0, 0, width, height); else dt_draw_grid(cr, 4, 0, 0, width, height); // if autoscale_ab is on: do not display a and b curves if (autoscale_ab && ch != ch_L) goto finally; // draw nodes positions cairo_set_line_width(cr, 1.); cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_translate(cr, 0, height); for(int k=0; k<nodes; k++) { cairo_arc(cr, tonecurve[k].x*width, -tonecurve[k].y*height, 3, 0, 2.*M_PI); cairo_stroke(cr); } // draw selected cursor cairo_set_line_width(cr, 1.); // draw histogram in background // only if module is enabled if (self->enabled) { float *hist, hist_max; float *raw_mean, *raw_min, *raw_max; float *raw_mean_output; float picker_mean[3], picker_min[3], picker_max[3]; char text[256]; raw_mean = self->picked_color; raw_min = self->picked_color_min; raw_max = self->picked_color_max; raw_mean_output = self->picked_output_color; hist = self->histogram; hist_max = dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR?self->histogram_max[ch]:logf(1.0 + self->histogram_max[ch]); if(hist && hist_max > 0) { cairo_save(cr); cairo_scale(cr, width/63.0, -(height-5)/(float)hist_max); cairo_set_source_rgba(cr, .2, .2, .2, 0.5); dt_draw_histogram_8(cr, hist, ch, dev->histogram_type == DT_DEV_HISTOGRAM_WAVEFORM?DT_DEV_HISTOGRAM_LOGARITHMIC:dev->histogram_type); // TODO: make draw handle waveform histograms cairo_restore(cr); } if(self->request_color_pick) { // the global live samples ... GSList *samples = darktable.lib->proxy.colorpicker.live_samples; dt_colorpicker_sample_t *sample = NULL; while(samples) { sample = samples->data; picker_scale(sample->picked_color_lab_mean, picker_mean); picker_scale(sample->picked_color_lab_min, picker_min); picker_scale(sample->picked_color_lab_max, picker_max); cairo_set_source_rgba(cr, 0.5, 0.7, 0.5, 0.15); cairo_rectangle(cr, width*picker_min[ch], 0, width*fmax(picker_max[ch]-picker_min[ch], 0.0f), -height); cairo_fill(cr); cairo_set_source_rgba(cr, 0.5, 0.7, 0.5, 0.5); cairo_move_to(cr, width*picker_mean[ch], 0); cairo_line_to(cr, width*picker_mean[ch], -height); cairo_stroke(cr); samples = g_slist_next(samples); } // ... and the local sample if(raw_max[0] >= 0.0f) { picker_scale(raw_mean, picker_mean); picker_scale(raw_min, picker_min); picker_scale(raw_max, picker_max); cairo_set_source_rgba(cr, 0.7, 0.5, 0.5, 0.33); cairo_rectangle(cr, width*picker_min[ch], 0, width*fmax(picker_max[ch]-picker_min[ch], 0.0f), -height); cairo_fill(cr); cairo_set_source_rgba(cr, 0.9, 0.7, 0.7, 0.5); cairo_move_to(cr, width*picker_mean[ch], 0); cairo_line_to(cr, width*picker_mean[ch], -height); cairo_stroke(cr); snprintf(text, 256, "%.1f → %.1f", raw_mean[ch], raw_mean_output[ch]); cairo_set_source_rgb(cr, 0.1, 0.1, 0.1); cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, 0.06*height); cairo_move_to (cr, 0.02f*width, -0.94*height); cairo_show_text(cr, text); cairo_stroke(cr); } } } if(c->selected >= 0) { cairo_set_source_rgb(cr, .9, .9, .9); cairo_arc(cr, tonecurve[c->selected].x*width, -tonecurve[c->selected].y*height, 4, 0, 2.*M_PI); cairo_stroke(cr); } // draw curve cairo_set_line_width(cr, 2.); cairo_set_source_rgb(cr, .9, .9, .9); // cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); cairo_move_to(cr, 0, -height*c->draw_ys[0]); for(int k=1; k<DT_IOP_TONECURVE_RES; k++) { const float xx = k/(DT_IOP_TONECURVE_RES-1.0); if(xx > xm) { const float yy = dt_iop_eval_exp(unbounded_coeffs, xx); cairo_line_to(cr, xx*width, - height*yy); } else { cairo_line_to(cr, xx*width, - height*c->draw_ys[k]); } } cairo_stroke(cr); finally: cairo_destroy(cr); cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface (cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; }
void draw_background(LoadGraph *g) { double dash[2] = { 1.0, 2.0 }; cairo_t *cr; guint i; unsigned num_bars; char *caption; cairo_text_extents_t extents; num_bars = g->num_bars(); g->graph_dely = (g->draw_height - 15) / num_bars; /* round to int to avoid AA blur */ g->real_draw_height = g->graph_dely * num_bars; g->graph_delx = (g->draw_width - 2.0 - g->rmargin - g->indent) / (LoadGraph::NUM_POINTS - 3); g->graph_buffer_offset = (int) (1.5 * g->graph_delx) + FRAME_WIDTH ; g->background = gdk_pixmap_new (GDK_DRAWABLE (g->disp->window), g->disp->allocation.width, g->disp->allocation.height, -1); cr = gdk_cairo_create (g->background); // set the background colour GtkStyle *style = gtk_widget_get_style (ProcData::get_instance()->notebook); gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_NORMAL]); cairo_paint (cr); /* draw frame */ cairo_translate (cr, FRAME_WIDTH, FRAME_WIDTH); /* Draw background rectangle */ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); cairo_rectangle (cr, g->rmargin + g->indent, 0, g->draw_width - g->rmargin - g->indent, g->real_draw_height); cairo_fill(cr); cairo_set_line_width (cr, 1.0); cairo_set_dash (cr, dash, 2, 0); cairo_set_font_size (cr, g->fontsize); for (i = 0; i <= num_bars; ++i) { double y; if (i == 0) y = 0.5 + g->fontsize / 2.0; else if (i == num_bars) y = i * g->graph_dely + 0.5; else y = i * g->graph_dely + g->fontsize / 2.0; gdk_cairo_set_source_color (cr, &style->fg[GTK_STATE_NORMAL]); if (g->type == LOAD_GRAPH_NET) { // operation orders matters so it's 0 if i == num_bars unsigned rate = g->net.max - (i * g->net.max / num_bars); const std::string caption(procman::format_rate(rate, g->net.max)); cairo_text_extents (cr, caption.c_str(), &extents); cairo_move_to (cr, g->indent - extents.width + 20, y); cairo_show_text (cr, caption.c_str()); } else { // operation orders matters so it's 0 if i == num_bars caption = g_strdup_printf("%d %%", 100 - i * (100 / num_bars)); cairo_text_extents (cr, caption, &extents); cairo_move_to (cr, g->indent - extents.width + 20, y); cairo_show_text (cr, caption); g_free (caption); } cairo_set_source_rgba (cr, 0, 0, 0, 0.75); cairo_move_to (cr, g->rmargin + g->indent - 3, i * g->graph_dely + 0.5); cairo_line_to (cr, g->draw_width - 0.5, i * g->graph_dely + 0.5); } cairo_stroke (cr); cairo_set_dash (cr, dash, 2, 1.5); const unsigned total_seconds = g->speed * (LoadGraph::NUM_POINTS - 2) / 1000; for (unsigned int i = 0; i < 7; i++) { double x = (i) * (g->draw_width - g->rmargin - g->indent) / 6; cairo_set_source_rgba (cr, 0, 0, 0, 0.75); cairo_move_to (cr, (ceil(x) + 0.5) + g->rmargin + g->indent, 0.5); cairo_line_to (cr, (ceil(x) + 0.5) + g->rmargin + g->indent, g->real_draw_height + 4.5); cairo_stroke(cr); unsigned seconds = total_seconds - i * total_seconds / 6; const char* format; if (i == 0) format = dngettext(GETTEXT_PACKAGE, "%u second", "%u seconds", seconds); else format = "%u"; caption = g_strdup_printf(format, seconds); cairo_text_extents (cr, caption, &extents); cairo_move_to (cr, ((ceil(x) + 0.5) + g->rmargin + g->indent) - (extents.width/2), g->draw_height); gdk_cairo_set_source_color (cr, &style->fg[GTK_STATE_NORMAL]); cairo_show_text (cr, caption); g_free (caption); } cairo_stroke (cr); cairo_destroy (cr); }
static gboolean dt_iop_basecurve_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_basecurve_gui_data_t *c = (dt_iop_basecurve_gui_data_t *)self->gui_data; dt_iop_basecurve_params_t *p = (dt_iop_basecurve_params_t *)self->params; int nodes = p->basecurve_nodes[0]; dt_iop_basecurve_node_t *basecurve = p->basecurve[0]; if(c->minmax_curve_type != p->basecurve_type[0] || c->minmax_curve_nodes != p->basecurve_nodes[0]) { dt_draw_curve_destroy(c->minmax_curve); c->minmax_curve = dt_draw_curve_new(0.0, 1.0, p->basecurve_type[0]); c->minmax_curve_nodes = p->basecurve_nodes[0]; c->minmax_curve_type = p->basecurve_type[0]; for(int k=0; k<p->basecurve_nodes[0]; k++) (void)dt_draw_curve_add_point(c->minmax_curve, p->basecurve[0][k].x, p->basecurve[0][k].y); } else { for(int k=0; k<p->basecurve_nodes[0]; k++) dt_draw_curve_set_point(c->minmax_curve, k, p->basecurve[0][k].x, p->basecurve[0][k].y); } dt_draw_curve_t *minmax_curve = c->minmax_curve; dt_draw_curve_calc_values(minmax_curve, 0.0, 1.0, DT_IOP_TONECURVE_RES, c->draw_xs, c->draw_ys); const float xm = basecurve[nodes-1].x; const float x[4] = {0.7f*xm, 0.8f*xm, 0.9f*xm, 1.0f*xm}; const float y[4] = {c->draw_ys[CLAMP((int)(x[0]*DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES-1)], c->draw_ys[CLAMP((int)(x[1]*DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES-1)], c->draw_ys[CLAMP((int)(x[2]*DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES-1)], c->draw_ys[CLAMP((int)(x[3]*DT_IOP_TONECURVE_RES), 0, DT_IOP_TONECURVE_RES-1)] }; float unbounded_coeffs[3]; dt_iop_estimate_exp(x, y, 4, unbounded_coeffs); const int inset = DT_GUI_CURVE_EDITOR_INSET; int width = widget->allocation.width, height = widget->allocation.height; cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); // clear bg cairo_set_source_rgb (cr, .2, .2, .2); cairo_paint(cr); cairo_translate(cr, inset, inset); width -= 2*inset; height -= 2*inset; #if 0 // draw shadow around float alpha = 1.0f; for(int k=0; k<inset; k++) { cairo_rectangle(cr, -k, -k, width + 2*k, height + 2*k); cairo_set_source_rgba(cr, 0, 0, 0, alpha); alpha *= 0.6f; cairo_fill(cr); } #else cairo_set_line_width(cr, 1.0); cairo_set_source_rgb (cr, .1, .1, .1); cairo_rectangle(cr, 0, 0, width, height); cairo_stroke(cr); #endif cairo_set_source_rgb (cr, .3, .3, .3); cairo_rectangle(cr, 0, 0, width, height); cairo_fill(cr); #if 1 // draw grid cairo_set_line_width(cr, .4); cairo_set_source_rgb (cr, .1, .1, .1); dt_draw_grid(cr, 4, 0, 0, width, height); // draw nodes positions cairo_set_line_width(cr, 1.); cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_translate(cr, 0, height); for(int k=0; k<nodes; k++) { cairo_arc(cr, basecurve[k].x*width, -basecurve[k].y*height, 3, 0, 2.*M_PI); cairo_stroke(cr); } // draw selected cursor cairo_set_line_width(cr, 1.); if(c->selected >= 0) { cairo_set_source_rgb(cr, .9, .9, .9); cairo_arc(cr, basecurve[c->selected].x*width, -basecurve[c->selected].y*height, 4, 0, 2.*M_PI); cairo_stroke(cr); } // draw curve cairo_set_line_width(cr, 2.); cairo_set_source_rgb(cr, .9, .9, .9); // cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); cairo_move_to(cr, 0, -height*c->draw_ys[0]); for(int k=1; k<DT_IOP_TONECURVE_RES; k++) { const float xx = k/(DT_IOP_TONECURVE_RES-1.0); if(xx > xm) { const float yy = dt_iop_eval_exp(unbounded_coeffs, xx); cairo_line_to(cr, xx*width, - height*yy); } else { cairo_line_to(cr, xx*width, - height*c->draw_ys[k]); } } cairo_stroke(cr); cairo_destroy(cr); cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface (cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; #endif }