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; }
/*! \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 dt_view_image_expose( dt_view_image_over_t *image_over, uint32_t imgid, cairo_t *cr, int32_t width, int32_t height, int32_t zoom, int32_t px, int32_t py) { const double start = dt_get_wtime(); // some performance tuning stuff, for your pleasure. // on my machine with 7 image per row it seems grouping has the largest // impact from around 400ms -> 55ms per redraw. #define DRAW_THUMB 1 #define DRAW_COLORLABELS 1 #define DRAW_GROUPING 1 #define DRAW_SELECTED 1 #define DRAW_HISTORY 1 #if DRAW_THUMB == 1 // this function is not thread-safe (gui-thread only), so we // can safely allocate this leaking bit of memory to decompress thumbnails: static int first_time = 1; static uint8_t *scratchmem = NULL; if(first_time) { // scratchmem might still be NULL after this, if compression is off. scratchmem = dt_mipmap_cache_alloc_scratchmem(darktable.mipmap_cache); first_time = 0; } #endif cairo_save (cr); float bgcol = 0.4, fontcol = 0.425, bordercol = 0.1, outlinecol = 0.2; int selected = 0, altered = 0, imgsel = -1, is_grouped = 0; // this is a gui thread only thing. no mutex required: imgsel = darktable.control->global_settings.lib_image_mouse_over_id; #if DRAW_SELECTED == 1 /* clear and reset statements */ DT_DEBUG_SQLITE3_CLEAR_BINDINGS(darktable.view_manager->statements.is_selected); DT_DEBUG_SQLITE3_RESET(darktable.view_manager->statements.is_selected); /* bind imgid to prepared statments */ DT_DEBUG_SQLITE3_BIND_INT(darktable.view_manager->statements.is_selected, 1, imgid); /* lets check if imgid is selected */ if(sqlite3_step(darktable.view_manager->statements.is_selected) == SQLITE_ROW) selected = 1; #endif #if DRAW_HISTORY == 1 DT_DEBUG_SQLITE3_CLEAR_BINDINGS(darktable.view_manager->statements.have_history); DT_DEBUG_SQLITE3_RESET(darktable.view_manager->statements.have_history); DT_DEBUG_SQLITE3_BIND_INT(darktable.view_manager->statements.have_history, 1, imgid); /* lets check if imgid has history */ if(sqlite3_step(darktable.view_manager->statements.have_history) == SQLITE_ROW) altered = 1; #endif const dt_image_t *img = dt_image_cache_read_testget(darktable.image_cache, imgid); #if DRAW_GROUPING == 1 DT_DEBUG_SQLITE3_CLEAR_BINDINGS(darktable.view_manager->statements.get_grouped); DT_DEBUG_SQLITE3_RESET(darktable.view_manager->statements.get_grouped); DT_DEBUG_SQLITE3_BIND_INT(darktable.view_manager->statements.get_grouped, 1, imgid); DT_DEBUG_SQLITE3_BIND_INT(darktable.view_manager->statements.get_grouped, 2, imgid); /* lets check if imgid is in a group */ if(sqlite3_step(darktable.view_manager->statements.get_grouped) == SQLITE_ROW) is_grouped = 1; else if(img && darktable.gui->expanded_group_id == img->group_id) darktable.gui->expanded_group_id = -1; #endif if(selected == 1) { outlinecol = 0.4; bgcol = 0.6; fontcol = 0.5; } if(imgsel == imgid) { bgcol = 0.8; // mouse over fontcol = 0.7; outlinecol = 0.6; // if the user points at this image, we really want it: if(!img) img = dt_image_cache_read_get(darktable.image_cache, imgid); } float imgwd = 0.90f; if(zoom == 1) { imgwd = .97f; // cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); } else { double x0 = 1, y0 = 1, rect_width = width-2, rect_height = height-2, radius = 5; double x1, y1, off, off1; x1=x0+rect_width; y1=y0+rect_height; off=radius*0.666; off1 = radius-off; cairo_move_to (cr, x0, y0 + radius); cairo_curve_to (cr, x0, y0+off1, x0+off1 , y0, x0 + radius, y0); cairo_line_to (cr, x1 - radius, y0); cairo_curve_to (cr, x1-off1, y0, x1, y0+off1, x1, y0 + radius); cairo_line_to (cr, x1 , y1 - radius); cairo_curve_to (cr, x1, y1-off1, x1-off1, y1, x1 - radius, y1); cairo_line_to (cr, x0 + radius, y1); cairo_curve_to (cr, x0+off1, y1, x0, y1-off1, x0, y1- radius); cairo_close_path (cr); cairo_set_source_rgb(cr, bgcol, bgcol, bgcol); cairo_fill_preserve(cr); cairo_set_line_width(cr, 0.005*width); cairo_set_source_rgb(cr, outlinecol, outlinecol, outlinecol); cairo_stroke(cr); if(img) { const char *ext = img->filename + strlen(img->filename); while(ext > img->filename && *ext != '.') ext--; ext++; cairo_set_source_rgb(cr, fontcol, fontcol, fontcol); cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, .25*width); cairo_text_extents_t text_extends; cairo_text_extents (cr, ext, &text_extends); cairo_move_to (cr, .025*width - text_extends.x_bearing, .24*height); cairo_show_text (cr, ext); } } dt_mipmap_buffer_t buf; dt_mipmap_size_t mip = dt_mipmap_cache_get_matching_size( darktable.mipmap_cache, imgwd*width, imgwd*height); dt_mipmap_cache_read_get( darktable.mipmap_cache, &buf, imgid, mip, 0); #if DRAW_THUMB == 1 float scale = 1.0; // decompress image, if necessary. if compression is off, scratchmem will be == NULL, // so get the real pointer back: uint8_t *buf_decompressed = dt_mipmap_cache_decompress(&buf, scratchmem); cairo_surface_t *surface = NULL; if(buf.buf) { const int32_t stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, buf.width); surface = cairo_image_surface_create_for_data (buf_decompressed, CAIRO_FORMAT_RGB24, buf.width, buf.height, stride); if(zoom == 1) { scale = fminf( fminf(darktable.thumbnail_width, width) / (float)buf.width, fminf(darktable.thumbnail_height, height) / (float)buf.height ); } else scale = fminf(width*imgwd/(float)buf.width, height*imgwd/(float)buf.height); } // draw centered and fitted: cairo_save(cr); cairo_translate(cr, width/2.0, height/2.0f); cairo_scale(cr, scale, scale); if(buf.buf) { cairo_translate(cr, -.5f*buf.width, -.5f*buf.height); cairo_set_source_surface (cr, surface, 0, 0); // set filter no nearest: // in skull mode, we want to see big pixels. // in 1 iir mode for the right mip, we want to see exactly what the pipe gave us, 1:1 pixel for pixel. // in between, filtering just makes stuff go unsharp. if((buf.width <= 8 && buf.height <= 8) || fabsf(scale - 1.0f) < 0.01f) cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST); cairo_rectangle(cr, 0, 0, buf.width, buf.height); cairo_fill(cr); cairo_surface_destroy (surface); cairo_rectangle(cr, 0, 0, buf.width, buf.height); } // border around image const float border = zoom == 1 ? 16/scale : 2/scale; cairo_set_source_rgb(cr, bordercol, bordercol, bordercol); if(buf.buf && selected) { cairo_set_line_width(cr, 1./scale); if(zoom == 1) { // draw shadow around border cairo_set_source_rgb(cr, 0.2, 0.2, 0.2); cairo_stroke(cr); // cairo_new_path(cr); cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); float alpha = 1.0f; for(int k=0; k<16; k++) { cairo_rectangle(cr, 0, 0, buf.width, buf.height); cairo_new_sub_path(cr); cairo_rectangle(cr, -k/scale, -k/scale, buf.width+2.*k/scale, buf.height+2.*k/scale); cairo_set_source_rgba(cr, 0, 0, 0, alpha); alpha *= 0.6f; cairo_fill(cr); } } else { cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); cairo_new_sub_path(cr); cairo_rectangle(cr, -border, -border, buf.width+2.*border, buf.height+2.*border); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 1.0-bordercol, 1.0-bordercol, 1.0-bordercol); cairo_fill(cr); } } else if(buf.buf) { cairo_set_line_width(cr, 1); cairo_stroke(cr); } cairo_restore(cr); #endif if(buf.buf) dt_mipmap_cache_read_release(darktable.mipmap_cache, &buf); const float fscale = fminf(width, height); if(imgsel == imgid) { // draw mouseover hover effects, set event hook for mouse button down! *image_over = DT_VIEW_DESERT; cairo_set_line_width(cr, 1.5); cairo_set_source_rgb(cr, outlinecol, outlinecol, outlinecol); cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); float r1, r2; if(zoom != 1) { r1 = 0.05*width; r2 = 0.022*width; } else { r1 = 0.015*fscale; r2 = 0.007*fscale; } float x, y; if(zoom != 1) y = 0.90*height; else y = .12*fscale; gboolean image_is_rejected = (img && ((img->flags & 0x7) == 6)); if(img) for(int k=0; k<5; k++) { if(zoom != 1) x = (0.41+k*0.12)*width; else x = (.08+k*0.04)*fscale; if(!image_is_rejected) //if rejected: draw no stars { dt_view_star(cr, x, y, r1, r2); if((px - x)*(px - x) + (py - y)*(py - y) < r1*r1) { *image_over = DT_VIEW_STAR_1 + k; cairo_fill(cr); } else if((img->flags & 0x7) > k) { cairo_fill_preserve(cr); cairo_set_source_rgb(cr, 1.0-bordercol, 1.0-bordercol, 1.0-bordercol); cairo_stroke(cr); cairo_set_source_rgb(cr, outlinecol, outlinecol, outlinecol); } else cairo_stroke(cr); } } //Image rejected? if(zoom !=1) x = 0.11*width; else x = .04*fscale; if (image_is_rejected) cairo_set_source_rgb(cr, 1., 0., 0.); if((px - x)*(px - x) + (py - y)*(py - y) < r1*r1) { *image_over = DT_VIEW_REJECT; //mouse sensitive cairo_new_sub_path(cr); cairo_arc(cr, x, y, (r1+r2)*.5, 0, 2.0f*M_PI); cairo_stroke(cr); } if (image_is_rejected) cairo_set_line_width(cr, 2.5); //reject cross: cairo_move_to(cr, x-r2, y-r2); cairo_line_to(cr, x+r2, y+r2); cairo_move_to(cr, x+r2, y-r2); cairo_line_to(cr, x-r2, y+r2); cairo_close_path(cr); cairo_stroke(cr); cairo_set_source_rgb(cr, outlinecol, outlinecol, outlinecol); cairo_set_line_width(cr, 1.5); // image part of a group? if(is_grouped && darktable.gui && darktable.gui->grouping) { // draw grouping icon and border if the current group is expanded // align to the right, left of altered float s = (r1+r2)*.75; float _x, _y; if(zoom != 1) { _x = width*0.9 - s*2.5; _y = height*0.1 - s*.4; } else { _x = (.04+7*0.04-1.1*.04)*fscale; _y = y - (.17*.04)*fscale; } cairo_save(cr); if(img && (imgid != img->group_id)) cairo_set_source_rgb(cr, fontcol, fontcol, fontcol); dtgtk_cairo_paint_grouping(cr, _x, _y, s, s, 23); cairo_restore(cr); // mouse is over the grouping icon if(img && abs(px-_x-.5*s) <= .8*s && abs(py-_y-.5*s) <= .8*s) *image_over = DT_VIEW_GROUP; } // image altered? if(altered) { // align to right float s = (r1+r2)*.5; if(zoom != 1) { x = width*0.9; y = height*0.1; } else x = (.04+7*0.04)*fscale; dt_view_draw_altered(cr, x, y, s); //g_print("px = %d, x = %.4f, py = %d, y = %.4f\n", px, x, py, y); if(img && abs(px-x) <= 1.2*s && abs(py-y) <= 1.2*s) // mouse hovers over the altered-icon -> history tooltip! { darktable.gui->center_tooltip = 1; } } } // kill all paths, in case img was not loaded yet, or is blocked: cairo_new_path(cr); #if DRAW_COLORLABELS == 1 // TODO: make mouse sensitive, just as stars! // TODO: cache in image struct! { // color labels: const float x = zoom == 1 ? (0.07)*fscale : .21*width; const float y = zoom == 1 ? 0.17*fscale: 0.1*height; const float r = zoom == 1 ? 0.01*fscale : 0.03*width; /* clear and reset prepared statement */ DT_DEBUG_SQLITE3_CLEAR_BINDINGS(darktable.view_manager->statements.get_color); DT_DEBUG_SQLITE3_RESET(darktable.view_manager->statements.get_color); /* setup statement and iterate rows */ DT_DEBUG_SQLITE3_BIND_INT(darktable.view_manager->statements.get_color, 1, imgid); while(sqlite3_step(darktable.view_manager->statements.get_color) == SQLITE_ROW) { cairo_save(cr); int col = sqlite3_column_int(darktable.view_manager->statements.get_color, 0); // see src/dtgtk/paint.c dtgtk_cairo_paint_label(cr, x+(3*r*col)-5*r, y-r, r*2, r*2, col); cairo_restore(cr); } } #endif if(img && (zoom == 1)) { // some exif data cairo_set_source_rgb(cr, .7, .7, .7); cairo_select_font_face (cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, .025*fscale); cairo_move_to (cr, .02*fscale, .04*fscale); // cairo_show_text(cr, img->filename); cairo_text_path(cr, img->filename); char exifline[50]; cairo_move_to (cr, .02*fscale, .08*fscale); dt_image_print_exif(img, exifline, 50); cairo_text_path(cr, exifline); cairo_fill_preserve(cr); cairo_set_line_width(cr, 1.0); cairo_set_source_rgb(cr, 0.3, 0.3, 0.3); cairo_stroke(cr); } if(img) dt_image_cache_read_release(darktable.image_cache, img); cairo_restore(cr); // if(zoom == 1) cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT); const double end = dt_get_wtime(); dt_print(DT_DEBUG_PERF, "[lighttable] image expose took %0.04f sec\n", end-start); }
/* Draw a single frame, do all your drawing/animation from in here. */ void drawFrame (rsxBuffer *buffer, int frame) { cairo_t *cr; cairo_surface_t *surface = NULL; static time_t starttime = 0; double fps = 0; if (starttime == 0) starttime = time (NULL); else fps = frame / difftime (time (NULL), starttime); DEBUG ("starttime is %lu - now is %lu - diff is %f\n", starttime, time (NULL), difftime (time (NULL), starttime)); DEBUG ("Drawing at %f FPS\n", fps); surface = cairo_image_surface_create_for_data ((u8 *) buffer->ptr, CAIRO_FORMAT_RGB24, buffer->width, buffer->height, buffer->width * 4); if (surface != NULL) { cr = cairo_create (surface); if (cr != NULL) { /* Lets start by clearing everything */ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* White */ cairo_paint (cr); /* Draw what needs tobe drawn */ { int size = 100; float r, g; float rel; char buf[100]; cairo_save(cr); cairo_new_path(cr); cairo_translate(cr, buffer->width / 2, buffer->height / 2); cairo_rotate (cr, frame * M_PI / 180); cairo_set_antialias(cr, CAIRO_ANTIALIAS_SUBPIXEL); cairo_line_to(cr, - (size / 2), - (size / 2)); cairo_line_to(cr, - (size / 2), + (size / 2)); cairo_line_to(cr, + (size / 2), + (size / 2)); cairo_line_to(cr, + (size / 2), - (size / 2)); cairo_close_path(cr); rel = sin ((frame % 180) * M_PI / 180); if (rel < 0.5) { r = 0.85; g = 2 * rel; } else { g = 0.85; r = 2 * (1.0 - rel); } cairo_set_source_rgb(cr, r, g, 0); cairo_fill_preserve(cr); r = g; g = 0.85; cairo_set_source_rgb(cr, r, g, 0); cairo_stroke(cr); cairo_identity_matrix (cr); cairo_set_source_rgb(cr, 0, 0, 0); cairo_select_font_face(cr, "Purisa", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 13); cairo_move_to(cr, 50, 30); snprintf (buf, 100, "FPS : %f", fps); cairo_show_text (cr, buf); } cairo_destroy (cr); /* Realease Surface */ } cairo_surface_finish (surface); cairo_surface_destroy (surface); /* Flush and destroy the cairo surface */ } }
int vfo_update(void *data) { BANDSTACK_ENTRY* entry=bandstack_entry_get_current(); FILTER* band_filters=filters[entry->mode]; FILTER* band_filter=&band_filters[entry->filter]; if(vfo_surface) { cairo_t *cr; cr = cairo_create (vfo_surface); cairo_set_source_rgb (cr, 0, 0, 0); cairo_paint (cr); cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); char version[16]; char text[128]; if(radio->protocol==ORIGINAL_PROTOCOL) { sprintf(version,"%d.%d", radio->software_version/10, radio->software_version%10); } else { sprintf(version,"%d.%d.%d", radio->software_version/100, (radio->software_version%100)/10, radio->software_version%10); } switch(radio->protocol) { case ORIGINAL_PROTOCOL: case NEW_PROTOCOL: sprintf(text,"%s %s %s", radio->name, version, inet_ntoa(radio->info.network.address.sin_addr)); break; #ifdef LIMESDR case LIMESDR_PROTOCOL: sprintf(text,"%s\n", radio->name); break; #endif } cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); cairo_set_font_size(cr, 10); cairo_move_to(cr, 5, 15); cairo_show_text(cr, text); long long f=entry->frequencyA+ddsOffset; char sf[32]; sprintf(sf,"%0lld.%06lld MHz",f/(long long)1000000,f%(long long)1000000); cairo_set_font_size(cr, 28); if(isTransmitting()) { cairo_set_source_rgb(cr, 1, 0, 0); } else { cairo_set_source_rgb(cr, 0, 1, 0); } cairo_move_to(cr, 5, 38); cairo_show_text(cr, sf); cairo_set_font_size(cr, 12); if(rit==0) { cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); } else { cairo_set_source_rgb(cr, 0, 1, 0); } sprintf(sf,"RIT: %d Hz",rit); cairo_move_to(cr, (my_width/4)*3, 38); cairo_show_text(cr, sf); cairo_set_source_rgb(cr, 0, 1, 0); int s=0; while(steps[s]!=step && steps[s]!=0) { s++; } sprintf(sf,"Step %s",step_labels[s]); cairo_move_to(cr, my_width/2, 15); cairo_show_text(cr, sf); cairo_move_to(cr, (my_width/4)*3, 15); cairo_show_text(cr, getFrequencyInfo(f)); if(locked) { cairo_set_source_rgb(cr, 1, 0, 0); cairo_move_to(cr, 10, 50); cairo_show_text(cr, "Locked"); } if(function) { cairo_set_source_rgb(cr, 1, 0.5, 0); cairo_move_to(cr, 70, 50); cairo_show_text(cr, "Function"); } cairo_set_source_rgb(cr, 1, 1, 0); cairo_move_to(cr, 130, 50); cairo_show_text(cr, mode_string[entry->mode]); cairo_move_to(cr, 190, 50); cairo_show_text(cr, band_filter->title); cairo_move_to(cr, 250, 50); if(nr) { cairo_show_text(cr, "NR"); } if(nr2) { cairo_show_text(cr, "NR2"); } if(nb) { cairo_show_text(cr, "NB"); } if(nb2) { cairo_show_text(cr, "NB2"); } if(anf) { cairo_show_text(cr, "ANF"); } if(snb) { cairo_show_text(cr, "SNB"); } cairo_move_to(cr, 310, 50); switch(agc) { case AGC_OFF: cairo_show_text(cr, "AGC OFF"); break; case AGC_LONG: cairo_show_text(cr, "AGC LONG"); break; case AGC_SLOW: cairo_show_text(cr, "AGC SLOW"); break; case AGC_MEDIUM: cairo_show_text(cr, "AGC MEDIUM"); break; case AGC_FAST: cairo_show_text(cr, "AGC FAST"); break; } cairo_destroy (cr); gtk_widget_queue_draw (vfo); } else { fprintf(stderr,"vfo_update: no surface!\n"); } return 0; }
void spectool_channel_draw(GtkWidget *widget, cairo_t *cr, SpectoolWidget *wwidget) { SpectoolChannel *channel; cairo_text_extents_t extents; int x, chpix; char mtext[128]; g_return_if_fail(widget != NULL); channel = SPECTOOL_CHANNEL(wwidget); cairo_save(cr); channel->chan_h = extents.height + ((double) extents.height * 0.1) + 5; /* Try to figure out the channels we use for this spectrum */ for (x = 0; wwidget->chanopts != NULL && channel_list[x].name != NULL && wwidget->chanopts->chanset == NULL; x++) { if (channel_list[x].startkhz >= wwidget->sweepcache->latest->start_khz && channel_list[x].endkhz <= wwidget->sweepcache->latest->end_khz) { int cpos; double r, g, b; wwidget->chanopts->chanset = &(channel_list[x]); /* Allocate the channels that are 'hit' or highlighted */ if (wwidget->chanopts->chanhit) free(wwidget->chanopts->chanhit); wwidget->chanopts->chanhit = malloc(sizeof(int) * wwidget->chanopts->chanset->chan_num); memset(wwidget->chanopts->chanhit, 0, sizeof(int) * wwidget->chanopts->chanset->chan_num); /* Allocate color sweep */ if (wwidget->chanopts->chancolors) free(wwidget->chanopts->chancolors); wwidget->chanopts->chancolors = malloc(sizeof(double) * wwidget->chanopts->chanset->chan_num * 3); for (cpos = 0; cpos < wwidget->chanopts->chanset->chan_num; cpos++) { /* Get the RGB values of a full-intensity color somewhere * along the H slider derived from the channel position */ hsv_to_rgb(&r, &g, &b, (360 / wwidget->chanopts->chanset->chan_num) * cpos, 1, 1); /* Convert the hex colors to cairo colors */ wwidget->chanopts->chancolors[(3 * cpos) + 0] = HC2CC(r); wwidget->chanopts->chancolors[(3 * cpos) + 1] = HC2CC(g); wwidget->chanopts->chancolors[(3 * cpos) + 2] = HC2CC(b); } break; } } /* Plot the channels if we know how */ if (wwidget->chanopts != NULL && wwidget->chanopts->chanset != NULL && wwidget->show_channels) { /* Allocate the channel point array if we haven't yet, so the mouse * handlers know where we've clicked. Points allocated inside the * channel widget itself. */ if (channel->chan_points == NULL) { channel->chan_points = (GdkPoint *) malloc(sizeof(GdkPoint) * wwidget->chanopts->chanset->chan_num * 2); } /* Draw the channel text along the bottom */ cairo_save(cr); for (x = 0; x < wwidget->chanopts->chanset->chan_num; x++) { chpix = ((float) wwidget->g_len_x / (wwidget->sweepcache->latest->end_khz - wwidget->sweepcache->latest->start_khz)) * (wwidget->chanopts->chanset->chan_freqs[x] - wwidget->sweepcache->latest->start_khz); if (x == wwidget->chanopts->hi_chan) { cairo_set_source_rgb(cr, HC2CC(0xFF), HC2CC(0xF6), HC2CC(0x00)); snprintf(mtext, 128, "%s", wwidget->chanopts->chanset->chan_text[x]); } else { cairo_set_source_rgb(cr, 1, 1, 1); snprintf(mtext, 128, "%s", wwidget->chanopts->chanset->chan_text[x]); } cairo_move_to(cr, wwidget->g_start_x + chpix, wwidget->g_start_y); cairo_line_to(cr, wwidget->g_start_x + chpix, wwidget->g_start_y + 5); cairo_stroke(cr); cairo_select_font_face(cr, "Helvetica", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 14); cairo_text_extents(cr, mtext, &extents); cairo_move_to(cr, wwidget->g_start_x + chpix - (extents.width / 2), wwidget->g_start_y + 10 + extents.height); cairo_show_text(cr, mtext); channel->chan_points[x].x = wwidget->g_start_x + chpix - (extents.width / 2) - 4; channel->chan_points[x].y = wwidget->g_start_y + 10 - 4; channel->chan_points[x + wwidget->chanopts->chanset->chan_num].x = channel->chan_points[x].x + extents.width + 8; channel->chan_points[x + wwidget->chanopts->chanset->chan_num].y = channel->chan_points[x].y + extents.height + 10; if (wwidget->chanopts->chanhit[x]) { cairo_save(cr); cairo_set_source_rgba(cr, wwidget->chanopts->chancolors[(3 * x) + 0], wwidget->chanopts->chancolors[(3 * x) + 1], wwidget->chanopts->chancolors[(3 * x) + 2], 0.60); cairo_rectangle(cr, wwidget->g_start_x + chpix - (extents.width / 2) - 3.5, wwidget->g_start_y + 10 - 3.5, extents.width + 8, extents.height + 10); cairo_fill(cr); /* cairo_stroke(cr); */ cairo_restore(cr); } } channel->chan_start_x = channel->chan_points[0].x - 1; channel->chan_end_x = channel->chan_points[(wwidget->chanopts->chanset->chan_num * 2) - 1].x + 1; channel->chan_start_y = channel->chan_points[0].y - 1; channel->chan_end_y = channel->chan_points[(wwidget->chanopts->chanset->chan_num * 2) - 1].y + 1; cairo_restore(cr); } }
void *dt_control_expose(void *voidptr) { int width, height, pointerx, pointery; if(!darktable.gui->surface) return NULL; width = dt_cairo_image_surface_get_width(darktable.gui->surface); height = dt_cairo_image_surface_get_height(darktable.gui->surface); GtkWidget *widget = dt_ui_center(darktable.gui->ui); gtk_widget_get_pointer(widget, &pointerx, &pointery); // create a gtk-independent surface to draw on cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); // TODO: control_expose: only redraw the part not overlapped by temporary control panel show! // float tb = 8; // fmaxf(10, width/100.0); darktable.control->tabborder = tb; darktable.control->width = width; darktable.control->height = height; GtkStyle *style = gtk_widget_get_style(widget); cairo_set_source_rgb(cr, style->bg[GTK_STATE_NORMAL].red / 65535.0, style->bg[GTK_STATE_NORMAL].green / 65535.0, style->bg[GTK_STATE_NORMAL].blue / 65535.0); cairo_set_line_width(cr, tb); cairo_rectangle(cr, tb / 2., tb / 2., width - tb, height - tb); cairo_stroke(cr); cairo_set_line_width(cr, 1.5); cairo_set_source_rgb(cr, .1, .1, .1); cairo_rectangle(cr, tb, tb, width - 2 * tb, height - 2 * tb); cairo_stroke(cr); cairo_save(cr); cairo_translate(cr, tb, tb); cairo_rectangle(cr, 0, 0, width - 2 * tb, height - 2 * tb); cairo_clip(cr); cairo_new_path(cr); // draw view dt_view_manager_expose(darktable.view_manager, cr, width - 2 * tb, height - 2 * tb, pointerx - tb, pointery - tb); cairo_restore(cr); // draw status bar, if any if(darktable.control->progress < 100.0) { tb = fmaxf(20, width / 40.0); char num[10]; cairo_rectangle(cr, width * 0.4, height * 0.85, width * 0.2 * darktable.control->progress / 100.0f, tb); cairo_fill(cr); cairo_set_source_rgb(cr, 0., 0., 0.); cairo_rectangle(cr, width * 0.4, height * 0.85, width * 0.2, tb); cairo_stroke(cr); cairo_set_source_rgb(cr, 0.9, 0.9, 0.9); cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, tb / 3); cairo_move_to(cr, width / 2.0 - 10, height * 0.85 + 2. * tb / 3.); snprintf(num, sizeof(num), "%d%%", (int)darktable.control->progress); cairo_show_text(cr, num); } // draw log message, if any dt_pthread_mutex_lock(&darktable.control->log_mutex); if(darktable.control->log_ack != darktable.control->log_pos) { cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); const float fontsize = 14; cairo_set_font_size(cr, fontsize); cairo_text_extents_t ext; cairo_text_extents(cr, darktable.control->log_message[darktable.control->log_ack], &ext); const float pad = 20.0f, xc = width / 2.0; const float yc = height * 0.85 + 10, wd = pad + ext.width * .5f; float rad = 14; cairo_set_line_width(cr, 1.); cairo_move_to(cr, xc - wd, yc + rad); for(int k = 0; k < 5; k++) { cairo_arc(cr, xc - wd, yc, rad, M_PI / 2.0, 3.0 / 2.0 * M_PI); cairo_line_to(cr, xc + wd, yc - rad); cairo_arc(cr, xc + wd, yc, rad, 3.0 * M_PI / 2.0, M_PI / 2.0); cairo_line_to(cr, xc - wd, yc + rad); if(k == 0) { cairo_set_source_rgb(cr, 0.3, 0.3, 0.3); cairo_fill_preserve(cr); } cairo_set_source_rgba(cr, 0., 0., 0., 1.0 / (1 + k)); cairo_stroke(cr); rad += .5f; } cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_move_to(cr, xc - wd + .5f * pad, yc + 1. / 3. * fontsize); cairo_show_text(cr, darktable.control->log_message[darktable.control->log_ack]); } // draw busy indicator if(darktable.control->log_busy > 0) { cairo_select_font_face(cr, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); const float fontsize = 14; cairo_set_font_size(cr, fontsize); cairo_text_extents_t ext; cairo_text_extents(cr, _("working.."), &ext); const float xc = width / 2.0, yc = height * 0.85 - 30, wd = ext.width * .5f; cairo_move_to(cr, xc - wd, yc + 1. / 3. * fontsize); cairo_text_path(cr, _("working..")); cairo_set_source_rgb(cr, 0.7, 0.7, 0.7); cairo_fill_preserve(cr); cairo_set_line_width(cr, 0.7); cairo_set_source_rgb(cr, 0.3, 0.3, 0.3); cairo_stroke(cr); } dt_pthread_mutex_unlock(&darktable.control->log_mutex); cairo_destroy(cr); cairo_t *cr_pixmap = cairo_create(darktable.gui->surface); cairo_set_source_surface(cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return NULL; }
void grava_renderer_draw_node (cairo_t* ctx, GravaNode* node) { #line 185 "renderer.vala" g_return_if_fail (ctx != NULL); #line 185 "renderer.vala" g_return_if_fail (node != NULL); #line 187 "renderer.vala" cairo_save (ctx); #line 189 "renderer.vala" cairo_set_tolerance (ctx, 0.1); #line 190 "renderer.vala" cairo_set_line_join (ctx, CAIRO_LINE_JOIN_ROUND); #line 191 "renderer.vala" cairo_set_line_width (ctx, (double) 1); #line 192 "renderer.vala" cairo_translate (ctx, node->x, node->y); #line 462 "renderer.c" /*ctx.set_source_rgb (1, 1, 1);*/ #line 195 "renderer.vala" cairo_set_source_rgb (ctx, 0.8, 0.8, 0.8); #line 466 "renderer.c" /*#if 0 if (node.calls.length() >0) set_color(ctx, "red"); else set_color(ctx, "blue"); #endif */ #line 203 "renderer.vala" grava_renderer_set_color (ctx, node->data); #line 204 "renderer.vala" grava_renderer_set_color_str (ctx, (const char*) g_hash_table_lookup (node->data, "bgcolor")); #line 206 "renderer.vala" if (node->has_body) { #line 207 "renderer.vala" switch (node->shape) { #line 482 "renderer.c" case GRAVA_SHAPE_CIRCLE: { #line 209 "renderer.vala" grava_renderer_circle (ctx, node->w, node->h); #line 210 "renderer.vala" cairo_fill (ctx); #line 211 "renderer.vala" break; #line 491 "renderer.c" } default: { #line 214 "renderer.vala" grava_renderer_square (ctx, node->w, node->h); #line 215 "renderer.vala" cairo_fill (ctx); #line 216 "renderer.vala" break; #line 501 "renderer.c" } } } /* title rectangle */ #line 221 "renderer.vala" if (((const char*) g_hash_table_lookup (node->data, "color")) != NULL) { #line 222 "renderer.vala" grava_renderer_set_color_str (ctx, (const char*) g_hash_table_lookup (node->data, "color")); #line 510 "renderer.c" } else { #line 224 "renderer.vala" if (g_slist_length (node->calls) == 1) { #line 225 "renderer.vala" cairo_set_source_rgba (ctx, 0.2, 0.2, 0.4, 0.7); #line 516 "renderer.c" } else { #line 227 "renderer.vala" if (g_slist_length (node->calls) > 0) { #line 228 "renderer.vala" cairo_set_source_rgba (ctx, 0.3, 0.3, (double) 1, 0.7); #line 522 "renderer.c" } else { #line 230 "renderer.vala" cairo_set_source_rgba (ctx, 0.8, 0.8, 0.8, 0.8); #line 526 "renderer.c" } } } #line 231 "renderer.vala" grava_renderer_square (ctx, node->w, (double) 15); #line 232 "renderer.vala" cairo_fill (ctx); #line 233 "renderer.vala" grava_renderer_line (ctx, (double) 0, (double) 15, node->w, (double) 0); #line 536 "renderer.c" /* draw minimize button */ #line 236 "renderer.vala" cairo_save (ctx); #line 540 "renderer.c" /*ctx.set_source_rgba (0.7, 0.0, 0.0, 1);*/ #line 238 "renderer.vala" cairo_set_source_rgba (ctx, 0.6, 0.6, 0.6, 0.8); #line 239 "renderer.vala" cairo_translate (ctx, node->w - 13, (double) 3); #line 240 "renderer.vala" grava_renderer_square (ctx, (double) 10, (double) 10); #line 241 "renderer.vala" cairo_fill (ctx); #line 242 "renderer.vala" cairo_restore (ctx); #line 244 "renderer.vala" cairo_select_font_face (ctx, "Sans Serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); #line 554 "renderer.c" /*Courier", */ #line 247 "renderer.vala" cairo_set_font_size (ctx, (double) 10); #line 558 "renderer.c" /* set label */ #line 250 "renderer.vala" cairo_set_source_rgb (ctx, 0.1, 0.1, 0.1); #line 251 "renderer.vala" cairo_move_to (ctx, (double) 5, (double) 10); #line 252 "renderer.vala" cairo_show_text (ctx, (const char*) g_hash_table_lookup (node->data, "label")); #line 566 "renderer.c" /* set body */ #line 255 "renderer.vala" if (node->has_body) { #line 570 "renderer.c" gint y; const char* _tmp0_; char* body; y = 25; #line 257 "renderer.vala" _tmp0_ = NULL; #line 577 "renderer.c" body = (_tmp0_ = (const char*) g_hash_table_lookup (node->data, "body"), (_tmp0_ == NULL) ? NULL : g_strdup (_tmp0_)); #line 258 "renderer.vala" if (body != NULL) { #line 581 "renderer.c" { char** _tmp1_; char** str_collection; int str_collection_length1; int str_it; _tmp1_ = NULL; #line 259 "renderer.vala" str_collection = _tmp1_ = g_strsplit (body, "\n", 0); #line 590 "renderer.c" str_collection_length1 = _vala_array_length (_tmp1_); for (str_it = 0; str_it < _vala_array_length (_tmp1_); str_it = str_it + 1) { const char* _tmp3_; char* str; #line 822 "glib-2.0.vapi" _tmp3_ = NULL; #line 597 "renderer.c" str = (_tmp3_ = str_collection[str_it], (_tmp3_ == NULL) ? NULL : g_strdup (_tmp3_)); { gboolean _tmp2_ = {0}; #line 260 "renderer.vala" y = y + 10; #line 261 "renderer.vala" cairo_move_to (ctx, (double) 5, (double) y); #line 262 "renderer.vala" if (strstr (str, "call ") != NULL) { #line 262 "renderer.vala" _tmp2_ = TRUE; #line 609 "renderer.c" } else { #line 263 "renderer.vala" _tmp2_ = strstr (str, "bl ") != NULL; #line 613 "renderer.c" } #line 262 "renderer.vala" if (_tmp2_) { #line 264 "renderer.vala" grava_renderer_set_color_str (ctx, "blue"); #line 619 "renderer.c" } else { #line 266 "renderer.vala" if (strstr (str, "goto") != NULL) { #line 267 "renderer.vala" grava_renderer_set_color_str (ctx, "green"); #line 625 "renderer.c" } else { #line 269 "renderer.vala" if (strstr (str, " j") != NULL) { #line 270 "renderer.vala" grava_renderer_set_color_str (ctx, "green"); #line 631 "renderer.c" } else { #line 272 "renderer.vala" if (g_str_has_suffix (str, ":")) { #line 273 "renderer.vala" grava_renderer_set_color_str (ctx, "red"); #line 637 "renderer.c" } else { #line 275 "renderer.vala" grava_renderer_set_color_str (ctx, "black"); #line 641 "renderer.c" } } } } #line 276 "renderer.vala" cairo_show_text (ctx, str); #line 648 "renderer.c" str = (g_free (str), NULL); } } #line 259 "renderer.vala" str_collection = (_vala_array_free (str_collection, str_collection_length1, (GDestroyNotify) g_free), NULL); #line 654 "renderer.c" } } /*set_color(ctx, node.data); box square */ #line 281 "renderer.vala" if (grava_graph_selected == node) { #line 661 "renderer.c" /*ctx.set_source_rgba (1, 0.8, 0.0, 0.9);*/ #line 283 "renderer.vala" cairo_set_source_rgba (ctx, (double) 0, 0.0, 0.0, 1.0); #line 284 "renderer.vala" cairo_set_line_width (ctx, (double) 2); #line 667 "renderer.c" } else { #line 286 "renderer.vala" cairo_set_source_rgba (ctx, 0.2, 0.2, 0.2, 0.4); #line 287 "renderer.vala" cairo_set_line_width (ctx, (double) 1); #line 673 "renderer.c" } #line 290 "renderer.vala" if (node->shape == GRAVA_SHAPE_CIRCLE) { #line 291 "renderer.vala" grava_renderer_circle (ctx, node->w, node->h); #line 679 "renderer.c" } else { #line 292 "renderer.vala" grava_renderer_square (ctx, node->w, node->h); #line 683 "renderer.c" } body = (g_free (body), NULL); } #line 295 "renderer.vala" cairo_stroke (ctx); #line 297 "renderer.vala" cairo_restore (ctx); #line 691 "renderer.c" }
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; }
int main (int argc, char **argv) { FT_Error error; FT_Library library; FT_Face face; GFile *file; gint font_size, thumb_size = THUMB_SIZE; gchar *thumbstr_utf8 = NULL, *help, *uri; gchar **arguments = NULL; GOptionContext *context; GError *gerror = NULL; gchar *contents = NULL; gboolean retval, default_thumbstr = TRUE; gint rv = 1; GdkRGBA white = { 1.0, 1.0, 1.0, 1.0 }; GdkRGBA black = { 0.0, 0.0, 0.0, 1.0 }; cairo_surface_t *surface; cairo_t *cr; cairo_text_extents_t text_extents; cairo_font_face_t *font; gchar *str; gdouble scale, scale_x, scale_y; const GOptionEntry options[] = { { "text", 't', 0, G_OPTION_ARG_STRING, &thumbstr_utf8, N_("Text to thumbnail (default: Aa)"), N_("TEXT") }, { "size", 's', 0, G_OPTION_ARG_INT, &thumb_size, N_("Thumbnail size (default: 128)"), N_("SIZE") }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &arguments, NULL, N_("FONT-FILE OUTPUT-FILE") }, { NULL } }; bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); setlocale (LC_ALL, ""); g_type_init (); context = g_option_context_new (NULL); g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE); retval = g_option_context_parse (context, &argc, &argv, &gerror); if (!retval) { g_printerr ("Error parsing arguments: %s\n", gerror->message); g_option_context_free (context); g_error_free (gerror); return 1; } if (!arguments || g_strv_length (arguments) != 2) { help = g_option_context_get_help (context, TRUE, NULL); g_printerr ("%s", help); g_option_context_free (context); goto out; } g_option_context_free (context); if (thumbstr_utf8 != NULL) default_thumbstr = FALSE; error = FT_Init_FreeType (&library); if (error) { g_printerr("Could not initialise freetype: %s\n", get_ft_error (error)); goto out; } totem_resources_monitor_start (arguments[0], 30 * G_USEC_PER_SEC); file = g_file_new_for_commandline_arg (arguments[0]); uri = g_file_get_uri (file); g_object_unref (file); face = sushi_new_ft_face_from_uri (library, uri, &contents, &gerror); if (gerror) { g_printerr ("Could not load face '%s': %s\n", uri, gerror->message); g_free (uri); g_error_free (gerror); goto out; } g_free (uri); if (default_thumbstr) { if (check_font_contain_text (face, "Aa")) str = g_strdup ("Aa"); else str = build_fallback_thumbstr (face); } else { str = thumbstr_utf8; } surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, thumb_size, thumb_size); cr = cairo_create (surface); gdk_cairo_set_source_rgba (cr, &white); cairo_paint (cr); font = cairo_ft_font_face_create_for_ft_face (face, 0); cairo_set_font_face (cr, font); cairo_font_face_destroy (font); font_size = thumb_size - 2 * PADDING_VERTICAL; cairo_set_font_size (cr, font_size); cairo_text_extents (cr, str, &text_extents); if ((text_extents.width) > (thumb_size - 2 * PADDING_HORIZONTAL)) { scale_x = (gdouble) (thumb_size - 2 * PADDING_HORIZONTAL) / (text_extents.width); } else { scale_x = 1.0; } if ((text_extents.height) > (thumb_size - 2 * PADDING_VERTICAL)) { scale_y = (gdouble) (thumb_size - 2 * PADDING_VERTICAL) / (text_extents.height); } else { scale_y = 1.0; } scale = MIN (scale_x, scale_y); cairo_scale (cr, scale, scale); cairo_translate (cr, PADDING_HORIZONTAL - text_extents.x_bearing + (thumb_size - scale * text_extents.width) / 2.0, PADDING_VERTICAL - text_extents.y_bearing + (thumb_size - scale * text_extents.height) / 2.0); gdk_cairo_set_source_rgba (cr, &black); cairo_show_text (cr, str); cairo_destroy (cr); cairo_surface_write_to_png (surface, arguments[1]); cairo_surface_destroy (surface); totem_resources_monitor_stop (); error = FT_Done_Face (face); if (error) { g_printerr("Could not unload face: %s\n", get_ft_error (error)); goto out; } error = FT_Done_FreeType (library); if (error) { g_printerr ("Could not finalize freetype library: %s\n", get_ft_error (error)); goto out; } rv = 0; /* success */ out: g_strfreev (arguments); g_free (str); g_free (contents); return rv; }
/*! \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); }
void lime_cairo_show_text (value handle, HxString text) { cairo_show_text ((cairo_t*)val_data (handle), (char*)text.__s); }
static void constant_component_state_real_render (ComponentState* base, cairo_t* context) { ConstantComponentState * self; gchar* text = NULL; cairo_matrix_t oldmatrix = {0}; cairo_t* _tmp0_; cairo_matrix_t _tmp1_ = {0}; cairo_t* _tmp2_; ComponentInst* _tmp3_; gint _tmp4_; ComponentInst* _tmp5_; gint _tmp6_; gboolean _tmp7_; cairo_text_extents_t textExtents = {0}; cairo_t* _tmp12_; cairo_t* _tmp13_; const gchar* _tmp14_; cairo_text_extents_t _tmp15_ = {0}; cairo_t* _tmp16_; cairo_text_extents_t _tmp17_; gdouble _tmp18_; cairo_text_extents_t _tmp19_; gdouble _tmp20_; cairo_t* _tmp21_; const gchar* _tmp22_; cairo_t* _tmp23_; cairo_matrix_t _tmp24_; self = (ConstantComponentState*) base; g_return_if_fail (context != NULL); _tmp0_ = context; cairo_get_matrix (_tmp0_, &_tmp1_); oldmatrix = _tmp1_; _tmp2_ = context; _tmp3_ = ((ComponentState*) self)->componentInst; _tmp4_ = _tmp3_->xPosition; _tmp5_ = ((ComponentState*) self)->componentInst; _tmp6_ = _tmp5_->yPosition; cairo_translate (_tmp2_, (gdouble) _tmp4_, (gdouble) _tmp6_); _tmp7_ = self->priv->output; if (_tmp7_) { cairo_t* _tmp8_; gchar* _tmp9_; _tmp8_ = context; cairo_set_source_rgb (_tmp8_, 1.0, (gdouble) 0, (gdouble) 0); _tmp9_ = g_strdup ("1"); _g_free0 (text); text = _tmp9_; } else { cairo_t* _tmp10_; gchar* _tmp11_; _tmp10_ = context; cairo_set_source_rgb (_tmp10_, (gdouble) 0, (gdouble) 0, 1.0); _tmp11_ = g_strdup ("0"); _g_free0 (text); text = _tmp11_; } _tmp12_ = context; cairo_set_font_size (_tmp12_, (gdouble) 16); _tmp13_ = context; _tmp14_ = text; cairo_text_extents (_tmp13_, _tmp14_, &_tmp15_); textExtents = _tmp15_; _tmp16_ = context; _tmp17_ = textExtents; _tmp18_ = _tmp17_.width; _tmp19_ = textExtents; _tmp20_ = _tmp19_.height; cairo_move_to (_tmp16_, (-_tmp18_) / 2, (+_tmp20_) / 2); _tmp21_ = context; _tmp22_ = text; cairo_show_text (_tmp21_, _tmp22_); _tmp23_ = context; _tmp24_ = oldmatrix; cairo_set_matrix (_tmp23_, &_tmp24_); _g_free0 (text); }