Пример #1
0
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;
}
Пример #2
0
/*!
 \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);
}
Пример #3
0
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);
}
Пример #4
0
/* 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 */
  }

}
Пример #5
0
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;
}
Пример #6
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);

	}
}
Пример #7
0
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;
}
Пример #8
0
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"
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
/*!
 \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);
}
Пример #12
0
	void lime_cairo_show_text (value handle, HxString text) {
		
		cairo_show_text ((cairo_t*)val_data (handle), (char*)text.__s);
		
	}
Пример #13
0
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);
}