コード例 #1
2
ファイル: gdkdrawing.c プロジェクト: bro1/deadbeef
void
draw_set_fg_color (drawctx_t *ctx, float *rgb) {
    cairo_set_source_rgb (ctx->drawable, rgb[0], rgb[1], rgb[2]);
}
コード例 #2
0
ファイル: simple_drawing.c プロジェクト: atkm/cs441
void set_color_arc(cairo_t *cr){
  cairo_set_source_rgb(cr, 0.2, 0.5, 0.4); 
}
コード例 #3
0
ファイル: testcairo.c プロジェクト: Aridna/gtk2
static void
draw (cairo_t *cr,
      int      width,
      int      height)
{
  cairo_surface_t *overlay, *punch, *circles;
  cairo_t *overlay_cr, *punch_cr, *circles_cr;

  /* Fill the background */
  double radius = 0.5 * (width < height ? width : height) - 10;
  double xc = width / 2.;
  double yc = height / 2.;

  overlay = cairo_surface_create_similar (cairo_get_target (cr),
					  CAIRO_CONTENT_COLOR_ALPHA,
					  width, height);
  if (overlay == NULL)
    return;

  punch = cairo_surface_create_similar (cairo_get_target (cr),
					CAIRO_CONTENT_ALPHA,
					width, height);
  if (punch == NULL)
    return;

  circles = cairo_surface_create_similar (cairo_get_target (cr),
					  CAIRO_CONTENT_COLOR_ALPHA,
					  width, height);
  if (circles == NULL)
    return;
    
  fill_checks (cr, 0, 0, width, height);

  /* Draw a black circle on the overlay
   */
  overlay_cr = cairo_create (overlay);
  cairo_set_source_rgb (overlay_cr, 0., 0., 0.);
  oval_path (overlay_cr, xc, yc, radius, radius);
  cairo_fill (overlay_cr);

  /* Draw 3 circles to the punch surface, then cut
   * that out of the main circle in the overlay
   */
  punch_cr = cairo_create (punch);
  draw_3circles (punch_cr, xc, yc, radius, 1.0);
  cairo_destroy (punch_cr);

  cairo_set_operator (overlay_cr, CAIRO_OPERATOR_DEST_OUT);
  cairo_set_source_surface (overlay_cr, punch, 0, 0);
  cairo_paint (overlay_cr);

  /* Now draw the 3 circles in a subgroup again
   * at half intensity, and use OperatorAdd to join up
   * without seams.
   */
  circles_cr = cairo_create (circles);
  
  cairo_set_operator (circles_cr, CAIRO_OPERATOR_OVER);
  draw_3circles (circles_cr, xc, yc, radius, 0.5);
  cairo_destroy (circles_cr);

  cairo_set_operator (overlay_cr, CAIRO_OPERATOR_ADD);
  cairo_set_source_surface (overlay_cr, circles, 0, 0);
  cairo_paint (overlay_cr);

  cairo_destroy (overlay_cr);

  cairo_set_source_surface (cr, overlay, 0, 0);
  cairo_paint (cr);

  cairo_surface_destroy (overlay);
  cairo_surface_destroy (punch);
  cairo_surface_destroy (circles);
}
コード例 #4
0
	WindowPanel::WindowPanel()
		: auto_hide_(false) {
		ClutterLayoutManager * main_layout = clutter_bin_layout_new(CLUTTER_BIN_ALIGNMENT_FIXED,
		                                                            CLUTTER_BIN_ALIGNMENT_FIXED);
		actor_ = clutter_box_new(main_layout);

		ClutterActor * menu = clutter_cairo_texture_new(110, 22);
		clutter_actor_set_position(menu, 10.0f, 0.0f);

		cairo_t * context = clutter_cairo_texture_create(CLUTTER_CAIRO_TEXTURE(menu));

		cairo_move_to(context, 0.0, 0.0);
		cairo_line_to(context, 0.0, 19.0);
		cairo_curve_to(context, 1.0, 21.0, 2.0, 22.0, 3.0, 22.0);
		cairo_line_to(context, 107.0, 22.0);
		cairo_curve_to(context, 108.0, 22.0, 109.0, 21.0, 110.0, 19.0);
		cairo_line_to(context, 110.0, 0.0);
		cairo_close_path(context);
		cairo_set_source_rgb(context, 0.8, 0.8, 0.8);
		cairo_fill_preserve(context);
		cairo_set_line_width(context, 1.0);
		cairo_set_source_rgb(context, 0.0, 0.0, 0.0);
		cairo_stroke(context);

		cairo_select_font_face(context, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
		cairo_set_font_size(context, 12.0);

		cairo_text_extents_t extents;
		cairo_text_extents(context, DISPLAY_NAME, &extents);
		cairo_move_to(context, 55.0 - ((extents.width / 2.0) + extents.x_bearing),
		              11.0 - ((extents.height / 2.0) + extents.y_bearing));

		cairo_text_path(context, DISPLAY_NAME);
		cairo_set_source_rgb(context, 0.0, 0.0, 0.0);
		cairo_fill(context);

		cairo_destroy(context);

		clutter_box_pack(CLUTTER_BOX(actor_), menu, NULL, NULL);

		ClutterLayoutManager * controls_layout = clutter_box_layout_new();
		clutter_box_layout_set_spacing(CLUTTER_BOX_LAYOUT(controls_layout), 10u);
		ClutterActor * controls = clutter_box_new(controls_layout);
		clutter_actor_add_constraint(controls, clutter_align_constraint_new(clutter_stage_get_default(),
		                             CLUTTER_ALIGN_X_AXIS, 0.95f));
		clutter_actor_add_constraint(controls, clutter_bind_constraint_new(clutter_stage_get_default(),
		                             CLUTTER_BIND_Y, 5.0f));

		fullscreen_button_ = clutter_cairo_texture_new(18, 16);
		clutter_actor_set_reactive(fullscreen_button_, TRUE);
		g_signal_connect(fullscreen_button_, "button-press-event", G_CALLBACK(fullscreen_clicked_cb), this);
		g_signal_connect(fullscreen_button_, "enter-event", G_CALLBACK(actor_highlight_on_cb), fullscreen_button_);
		g_signal_connect(fullscreen_button_, "leave-event", G_CALLBACK(actor_highlight_off_cb), fullscreen_button_);
		clutter_box_pack(CLUTTER_BOX(controls), fullscreen_button_, NULL, NULL);

		close_button_ = clutter_cairo_texture_new(15, 15);

		context = clutter_cairo_texture_create(CLUTTER_CAIRO_TEXTURE(close_button_));

		cairo_move_to(context, 1.0, 3.0);
		cairo_line_to(context, 3.0, 1.0);
		cairo_line_to(context, 8.0, 6.0);
		cairo_line_to(context, 13.0, 1.0);
		cairo_line_to(context, 15.0, 3.0);
		cairo_line_to(context, 10.0, 8.0);
		cairo_line_to(context, 15.0, 13.0);
		cairo_line_to(context, 13.0, 15.0);
		cairo_line_to(context, 8.0, 10.0);
		cairo_line_to(context, 3.0, 15.0);
		cairo_line_to(context, 1.0, 13.0);
		cairo_line_to(context, 6.0, 8.0);
		cairo_close_path(context);
		cairo_set_source_rgb(context, 1.0, 1.0, 1.0);
		cairo_fill_preserve(context);
		cairo_set_line_width(context, 1.0);
		cairo_set_source_rgb(context, 0.0, 0.0, 0.0);
		cairo_stroke(context);

		cairo_destroy(context);

		clutter_actor_set_reactive(close_button_, TRUE);
		g_signal_connect(close_button_, "button-press-event", G_CALLBACK(close_clicked_cb), NULL);
		g_signal_connect(close_button_, "enter-event", G_CALLBACK(actor_highlight_on_cb), close_button_);
		g_signal_connect(close_button_, "leave-event", G_CALLBACK(actor_highlight_off_cb), close_button_);
		clutter_box_pack(CLUTTER_BOX(controls), close_button_, NULL, NULL);

		draw_window_controls();

		clutter_box_pack(CLUTTER_BOX(actor_), controls, NULL, NULL);

		g_signal_connect(clutter_stage_get_default(), "fullscreen", G_CALLBACK(fullscreen_status_changed_cb), this);
		g_signal_connect(clutter_stage_get_default(), "unfullscreen", G_CALLBACK(fullscreen_status_changed_cb), this);
		g_signal_connect(clutter_stage_get_default(), "motion-event", G_CALLBACK(show_panel_cb), this);
	}
コード例 #5
0
/* TODO: Split each ppi case out to its own CAIRO_TEST() test case */
static cairo_test_status_t
preamble (cairo_test_context_t *ctx)
{
    cairo_t *cr;
    cairo_test_status_t ret = CAIRO_TEST_UNTESTED;
    struct {
	double x, y;
    } ppi[] = {
	{ 576, 576 },
	{ 576, 72 },

	{ 288, 288 },
	{ 288, 72 },

	{ 144, 144 },
	{ 144, 72 },

	{ 72, 576 },
	{ 72, 288 },
	{ 72, 144 },
	{ 72, 72 },
    };
    unsigned int i;
    int n, num_ppi;
    const char *path = _cairo_test_mkdir (CAIRO_TEST_OUTPUT_DIR) ? CAIRO_TEST_OUTPUT_DIR : ".";

    num_ppi = ARRAY_LENGTH (ppi);

#if GENERATE_REFERENCE
    for (n = 0; n < num_ppi; n++) {
	char *ref_name;
	xasprintf (&ref_name, "reference/fallback-resolution.ppi%gx%g.ref.png",
		   ppi[n].x, ppi[n].y);
	generate_reference (ppi[n].x, ppi[n].y, ref_name);
	free (ref_name);
    }
#endif

    for (i = 0; i < ctx->num_targets; i++) {
	const cairo_boilerplate_target_t *target = ctx->targets_to_test[i];
	cairo_surface_t *surface = NULL;
	char *base_name;
	void *closure;
	const char *format;
	cairo_status_t status;

	if (! target->is_vector)
	    continue;

	if (! cairo_test_is_target_enabled (ctx, target->name))
	    continue;

	format = cairo_boilerplate_content_name (target->content);
	xasprintf (&base_name, "%s/fallback-resolution.%s.%s",
		   path, target->name,
		   format);

	surface = (target->create_surface) (base_name,
					    target->content,
					    SIZE, SIZE,
					    SIZE, SIZE,
					    CAIRO_BOILERPLATE_MODE_TEST,
					    &closure);

	if (surface == NULL) {
	    free (base_name);
	    continue;
	}

	if (ret == CAIRO_TEST_UNTESTED)
	    ret = CAIRO_TEST_SUCCESS;

	cairo_surface_destroy (surface);
	if (target->cleanup)
	    target->cleanup (closure);
	free (base_name);

	/* we need to recreate the surface for each resolution as we include
	 * SVG in testing which does not support the paginated interface.
	 */
	for (n = 0; n < num_ppi; n++) {
	    char *test_name;
	    cairo_bool_t pass;

	    xasprintf (&test_name, "fallback-resolution.ppi%gx%g",
		       ppi[n].x, ppi[n].y);
	    xasprintf (&base_name, "%s/%s.%s.%s",
		       path, test_name,
		       target->name,
		       format);

	    surface = (target->create_surface) (base_name,
						target->content,
						SIZE + 25, SIZE + 25,
						SIZE + 25, SIZE + 25,
						CAIRO_BOILERPLATE_MODE_TEST,
						&closure);
	    if (surface == NULL || cairo_surface_status (surface)) {
		cairo_test_log (ctx, "Failed to generate surface: %s.%s\n",
				target->name,
				format);
		free (base_name);
		free (test_name);
		ret = CAIRO_TEST_FAILURE;
		continue;
	    }

	    cairo_test_log (ctx,
			    "Testing fallback-resolution %gx%g with %s target\n",
			    ppi[n].x, ppi[n].y, target->name);
	    printf ("%s:\t", base_name);
	    fflush (stdout);

	    if (target->force_fallbacks != NULL)
		target->force_fallbacks (surface, ppi[n].x, ppi[n].y);
	    cr = cairo_create (surface);
#if SET_TOLERANCE
	    cairo_set_tolerance (cr, 3.0);
#endif

	    cairo_surface_set_device_offset (surface, 25, 25);

	    cairo_save (cr); {
		cairo_set_source_rgb (cr, 1, 1, 1);
		cairo_paint (cr);
	    } cairo_restore (cr);

	    /* First draw the top half in a conventional way. */
	    cairo_save (cr); {
		cairo_rectangle (cr, 0, 0, SIZE, SIZE / 2.0);
		cairo_clip (cr);

		draw (cr, SIZE, SIZE);
	    } cairo_restore (cr);

	    /* Then draw the bottom half in a separate group,
	     * (exposing a bug in 1.6.4 with the group not being
	     * rendered with the correct fallback resolution). */
	    cairo_save (cr); {
		cairo_rectangle (cr, 0, SIZE / 2.0, SIZE, SIZE / 2.0);
		cairo_clip (cr);

		cairo_push_group (cr); {
		    draw (cr, SIZE, SIZE);
		} cairo_pop_group_to_source (cr);

		cairo_paint (cr);
	    } cairo_restore (cr);

	    status = cairo_status (cr);
	    cairo_destroy (cr);

	    pass = FALSE;
	    if (status) {
		cairo_test_log (ctx, "Error: Failed to create target surface: %s\n",
				cairo_status_to_string (status));
		ret = CAIRO_TEST_FAILURE;
	    } else {
		/* extract the image and compare it to our reference */
		if (! check_result (ctx, target, test_name, base_name, surface))
		    ret = CAIRO_TEST_FAILURE;
		else
		    pass = TRUE;
	    }
	    cairo_surface_destroy (surface);
	    if (target->cleanup)
		target->cleanup (closure);

	    free (base_name);
	    free (test_name);

	    if (pass) {
		printf ("PASS\n");
	    } else {
		printf ("FAIL\n");
	    }
	    fflush (stdout);
	}
    }

    return ret;
}
コード例 #6
0
ファイル: stats_graph.c プロジェクト: Prince781/gtorrent
gboolean
gt_gui_stats_graph_draw(GtkWidget *canvas, cairo_t *cr, gpointer data) {
	int width, height;
	double x, y;
	double largest = 1.0;
	double damp = 0.7;	// damp height factor
	char buf[50];
	cairo_text_extents_t te;
	uint64_t rate;
	int t;			// time
	struct sess_stat *p, *pb;

	if ((p = gt_gui_get_stat()) == NULL)
		return FALSE;

	width = gtk_widget_get_allocated_width(canvas);
	height = gtk_widget_get_allocated_height(canvas);

	cairo_set_line_width(cr, 0.3);

	// draw grid first
	cairo_set_source_rgba(cr, 0.3, 0.3, 0.3, 1.0);
	cairo_rectangle(cr, 15, 15, width-30, height-30);
	cairo_stroke(cr);

	for (y = 15 + (height-30)/4; y < height-15; y += (height-30)/4) {
		cairo_move_to(cr, 15, y);
		cairo_line_to(cr, width-15, y);
		cairo_stroke(cr);
	}

	// draw chart
	cairo_set_line_width(cr, 1.3);
	cairo_set_source_rgb(cr, 0.7, 0.1, 0.3);
	largest = 0;
	for (pb = p; ; p = p->next) {
		if (p->val > largest)
			largest = p->val;
		if (p->next == pb)
			break;
	}
	p = pb;
	x = 15;
	for (pb = p; ; p = p->next) {
		if (x == 15)
			cairo_move_to(cr, x, 
				height-15-damp*(height-30)*(p->val/largest));
		else
			cairo_line_to(cr, x,
				height-15-damp*(height-30)*(p->val/largest));
		x += width / (STATSIZE-1);
		if (p->next == pb)
			break;
	}

	cairo_stroke(cr);

	// draw labels
	cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
	cairo_select_font_face(cr, "Cantarell", CAIRO_FONT_SLANT_NORMAL,
				CAIRO_FONT_WEIGHT_NORMAL);
	cairo_set_font_size(cr, 12);
	for (y = height-15; y >= 15; y -= (height-30)/4) {
		rate = (uint64_t)(largest/damp*(height-15-y)/(height-30));
		gt_trnt_getratep(rate, 2, buf);
		cairo_text_extents(cr, buf, &te);
		cairo_move_to(cr, 15.5, y - te.height/2);
		cairo_show_text(cr, buf);
	}
	for (x = 15.5, t = STATSIZE/2; x <= width-15; x += (width-30)/ 4) {
		snprintf(buf, 50, "%d", t);
		cairo_text_extents(cr, buf, &te);
		cairo_move_to(cr, x - te.width/2, height-14.5 + te.height);
		cairo_show_text(cr, buf);
		t -= STATSIZE/8;
	}

	return FALSE;
}
コード例 #7
0
ファイル: timebar.c プロジェクト: sergei-dyshel/workrave
static void set_color(cairo_t *cr, GdkColor color)
{
  cairo_set_source_rgb(cr, color.red / 65535.0, color.green / 65535.0, color.blue / 65535.0);
}
コード例 #8
0
ファイル: status.c プロジェクト: ilyak/vimol
void
status_render(struct status *status, cairo_t *cairo)
{
	cairo_font_extents_t exfont;
	cairo_text_extents_t extext;
	color_t color;
	double size;
	int width, height;
	const char *font;
	char *text;

	font = settings_get_string("status.font");
	size = settings_get_double("status.font.size");

	cairo_reset_clip(cairo);
	cairo_identity_matrix(cairo);
	cairo_select_font_face(cairo, font, CAIRO_FONT_SLANT_NORMAL,
	    CAIRO_FONT_WEIGHT_NORMAL);
	cairo_set_font_size(cairo, size);
	cairo_font_extents(cairo, &exfont);

	width = cairo_image_surface_get_width(cairo_get_target(cairo));
	height = cairo_image_surface_get_height(cairo_get_target(cairo));

	if (!settings_get_bool("status.transparent")) {
		color = settings_get_color("status.color");
		cairo_set_source_rgb(cairo, color.r, color.g, color.b);
		cairo_rectangle(cairo, 0, height - exfont.height - 10,
		    width, exfont.height + 10);
		cairo_fill(cairo);
	}

	color = settings_get_color("status.text.color");
	cairo_set_source_rgb(cairo, color.r, color.g, color.b);

	cairo_text_extents(cairo, status->info, &extext);
	cairo_move_to(cairo, width - extext.x_advance - 5,
	    height - exfont.descent - 5);
	cairo_show_text(cairo, status->info);

	cairo_rectangle(cairo, 0, height - exfont.height - 10,
	    width - extext.x_advance - 10, exfont.height + 10);
	cairo_clip(cairo);

	if (status->is_error) {
		color = settings_get_color("status.error.color");
		cairo_set_source_rgb(cairo, color.r, color.g, color.b);
	}

	cairo_move_to(cairo, 5, height - exfont.descent - 5);
	cairo_show_text(cairo, status->text);

	if (status->cursor_pos > -1) {
		text = xstrndup(status->text, (size_t)status->cursor_pos);
		cairo_text_extents(cairo, text, &extext);
		cairo_move_to(cairo, extext.x_advance + 5,
		    height - exfont.descent - 5);
		cairo_show_text(cairo, "_");
		free(text);
	}
}
コード例 #9
0
ファイル: unlock_indicator.c プロジェクト: ramnes/i3lock
/*
 * Draws global image with fill color onto a pixmap with the given
 * resolution and returns it.
 *
 */
xcb_pixmap_t draw_image(uint32_t *resolution) {
    xcb_pixmap_t bg_pixmap = XCB_NONE;
    int button_diameter_physical = ceil(scaling_factor() * BUTTON_DIAMETER);
    DEBUG("scaling_factor is %.f, physical diameter is %d px\n",
          scaling_factor(), button_diameter_physical);

    if (!vistype)
        vistype = get_root_visual_type(screen);
    bg_pixmap = create_bg_pixmap(conn, screen, resolution, color);
    /* Initialize cairo: Create one in-memory surface to render the unlock
     * indicator on, create one XCB surface to actually draw (one or more,
     * depending on the amount of screens) unlock indicators on. */
    cairo_surface_t *output = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, button_diameter_physical, button_diameter_physical);
    cairo_t *ctx = cairo_create(output);

    cairo_surface_t *xcb_output = cairo_xcb_surface_create(conn, bg_pixmap, vistype, resolution[0], resolution[1]);
    cairo_t *xcb_ctx = cairo_create(xcb_output);

    if (img) {
        if (!tile) {
            cairo_set_source_surface(xcb_ctx, img, 0, 0);
            cairo_paint(xcb_ctx);
        } else {
            /* create a pattern and fill a rectangle as big as the screen */
            cairo_pattern_t *pattern;
            pattern = cairo_pattern_create_for_surface(img);
            cairo_set_source(xcb_ctx, pattern);
            cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
            cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]);
            cairo_fill(xcb_ctx);
            cairo_pattern_destroy(pattern);
        }
    } else {
        char strgroups[3][3] = {{color[0], color[1], '\0'},
                                {color[2], color[3], '\0'},
                                {color[4], color[5], '\0'}};
        uint32_t rgb16[3] = {(strtol(strgroups[0], NULL, 16)),
                             (strtol(strgroups[1], NULL, 16)),
                             (strtol(strgroups[2], NULL, 16))};
        cairo_set_source_rgb(xcb_ctx, rgb16[0] / 255.0, rgb16[1] / 255.0, rgb16[2] / 255.0);
        cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]);
        cairo_fill(xcb_ctx);
    }

    if (unlock_state >= STATE_KEY_PRESSED && unlock_indicator) {
        cairo_scale(ctx, scaling_factor(), scaling_factor());
        /* Draw a (centered) circle with transparent background. */
        cairo_set_line_width(ctx, 10.0);
        cairo_arc(ctx,
                  BUTTON_CENTER /* x */,
                  BUTTON_CENTER /* y */,
                  BUTTON_RADIUS /* radius */,
                  0 /* start */,
                  2 * M_PI /* end */);

        /* Use the appropriate color for the different PAM states */
        /* (currently verifying, wrong password, or default) */
        switch (pam_state) {
            case STATE_PAM_VERIFY:
                cairo_set_source_rgba(ctx, 0.5, 0.5, 0.5, 0.25);
                break;
            case STATE_PAM_WRONG:
                cairo_set_source_rgba(ctx, 1, 0.5, 0, 0.25);
                break;
            default:
                cairo_set_source_rgba(ctx, 0.25, 0.25, 1, 0.25);
                break;
        }
        cairo_fill_preserve(ctx);

        switch (pam_state) {
            case STATE_PAM_VERIFY:
                cairo_set_source_rgba(ctx, 0.5, 0.5, 0.5, 0.50);
                break;
            case STATE_PAM_WRONG:
                cairo_set_source_rgba(ctx, 1, 0.5, 0, 0.50);
                break;
            case STATE_PAM_IDLE:
                cairo_set_source_rgba(ctx, 0.25, 0.25, 1, 0.50);
                break;
        }
        cairo_stroke(ctx);

        cairo_set_line_width(ctx, 10.0);

        /* Display a (centered) text of the current PAM state. */
        char *text = NULL;
        /* We don't want to show more than a 3-digit number. */
        char buf[4];

        cairo_set_source_rgb(ctx, 0, 0, 0);
        cairo_set_font_size(ctx, 28.0);
        if (show_failed_attempts && failed_attempts > 0) {
            if (failed_attempts > 999) {
                text = "> 999";
            } else {
                snprintf(buf, sizeof(buf), "%d", failed_attempts);
                text = buf;
            }
            cairo_set_source_rgb(ctx, 1, 0, 0);
            cairo_set_font_size(ctx, 32.0);
        }

        if (text) {
            cairo_text_extents_t extents;
            double x, y;

            cairo_text_extents(ctx, text, &extents);
            x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing);
            y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing);

            cairo_move_to(ctx, x, y);
            cairo_show_text(ctx, text);
            cairo_close_path(ctx);
        }

        if (pam_state == STATE_PAM_WRONG && (modifier_string != NULL)) {
            cairo_text_extents_t extents;
            double x, y;

            cairo_set_font_size(ctx, 14.0);

            cairo_text_extents(ctx, modifier_string, &extents);
            x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing);
            y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing) + 1.0;

            cairo_move_to(ctx, x, y);
            cairo_show_text(ctx, modifier_string);
            cairo_close_path(ctx);
        }

        /* After the user pressed any valid key or the backspace key, we
         * highlight a random part of the unlock indicator to confirm this
         * keypress. */
        if (unlock_state == STATE_KEY_ACTIVE ||
            unlock_state == STATE_BACKSPACE_ACTIVE) {
            cairo_new_sub_path(ctx);
            double highlight_start = (rand() % (int)(2 * M_PI * 100)) / 100.0;
            cairo_arc(ctx,
                      BUTTON_CENTER /* x */,
                      BUTTON_CENTER /* y */,
                      BUTTON_RADIUS /* radius */,
                      highlight_start,
                      highlight_start + (M_PI / 3.0));
            if (unlock_state == STATE_KEY_ACTIVE) {
                /* For normal keys, we use a lighter blue. */
                cairo_set_source_rgba(ctx, 0.25, 0.25, 1, 0.5);
            } else {
                /* For backspace, we use orange. */
                cairo_set_source_rgba(ctx, 1, 0.5, 0, 0.5);
            }
            cairo_stroke(ctx);
        }
    }

    if (xr_screens > 0) {
        /* Composite the unlock indicator in the middle of each screen. */
        for (int screen = 0; screen < xr_screens; screen++) {
            int x = (xr_resolutions[screen].x + ((xr_resolutions[screen].width / 2) - (button_diameter_physical / 2)));
            int y = (xr_resolutions[screen].y + ((xr_resolutions[screen].height / 2) - (button_diameter_physical / 2)));
            cairo_set_source_surface(xcb_ctx, output, x, y);
            cairo_rectangle(xcb_ctx, x, y, button_diameter_physical, button_diameter_physical);
            cairo_fill(xcb_ctx);
        }
    } else {
        /* We have no information about the screen sizes/positions, so we just
         * place the unlock indicator in the middle of the X root window and
         * hope for the best. */
        int x = (last_resolution[0] / 2) - (button_diameter_physical / 2);
        int y = (last_resolution[1] / 2) - (button_diameter_physical / 2);
        cairo_set_source_surface(xcb_ctx, output, x, y);
        cairo_rectangle(xcb_ctx, x, y, button_diameter_physical, button_diameter_physical);
        cairo_fill(xcb_ctx);
    }

    cairo_surface_destroy(xcb_output);
    cairo_surface_destroy(output);
    cairo_destroy(ctx);
    cairo_destroy(xcb_ctx);
    return bg_pixmap;
}
コード例 #10
0
ファイル: fish.c プロジェクト: lanoxx/gnome-panel
static void
update_surface (FishApplet *fish)
{
	GtkWidget     *widget = fish->drawing_area;
	GtkRequisition prev_requisition;
	GtkAllocation  allocation;
	int            width  = -1;
	int            height = -1;
	int            pixbuf_width = -1;
	int            pixbuf_height = -1;
	gboolean       rotate = FALSE;
	cairo_t       *cr;
	cairo_matrix_t matrix;
	cairo_pattern_t *pattern;

	gtk_widget_get_allocation (widget, &allocation);

	if (!gtk_widget_get_realized (widget) ||
	    allocation.width <= 0 ||
	    allocation.height <= 0)
		return;

	if (!fish->pixbuf && !load_fish_image (fish))
		return;

	if (fish->rotate &&
	    (fish->orientation == PANEL_APPLET_ORIENT_LEFT ||
	     fish->orientation == PANEL_APPLET_ORIENT_RIGHT))
		rotate = TRUE;

	pixbuf_width  = gdk_pixbuf_get_width  (fish->pixbuf);
	pixbuf_height = gdk_pixbuf_get_height (fish->pixbuf);

	prev_requisition = fish->requisition;

	if (fish->orientation == PANEL_APPLET_ORIENT_UP ||
	    fish->orientation == PANEL_APPLET_ORIENT_DOWN) {
		height = allocation.height;
		width  = pixbuf_width * ((gdouble) height / pixbuf_height);

		fish->requisition.width = width / fish->n_frames;
		fish->requisition.height = height;
	} else {
		if (!rotate) {
			width = allocation.width * fish->n_frames;
			height = pixbuf_height * ((gdouble) width / pixbuf_width);
			fish->requisition.width = allocation.width;
			fish->requisition.height = height;
		} else {
			width = allocation.width;
			height = pixbuf_width * ((gdouble) width / pixbuf_height);
			fish->requisition.width = width;
			fish->requisition.height = height / fish->n_frames;
		}
	}

	if (prev_requisition.width  != fish->requisition.width ||
	    prev_requisition.height != fish->requisition.height) {
		gtk_widget_set_size_request (widget,
					     fish->requisition.width,
					     fish->requisition.height);
	}

	g_assert (width != -1 && height != -1);

	if (width == 0 || height == 0)
		return;

	if (fish->surface)
		cairo_surface_destroy (fish->surface);
	fish->surface = gdk_window_create_similar_surface (
			               gtk_widget_get_window (widget),
			               CAIRO_CONTENT_COLOR_ALPHA,
			               width, height);

	gtk_widget_queue_resize (widget);

	g_assert (pixbuf_width != -1 && pixbuf_height != -1);

	cr = cairo_create (fish->surface);

	cairo_set_source_rgb (cr, 1, 1, 1);
	cairo_paint (cr);

	gdk_cairo_set_source_pixbuf (cr, fish->pixbuf, 0, 0);
	pattern = cairo_get_source (cr);
	cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);

	cairo_matrix_init_identity (&matrix);

	if (fish->april_fools) {
		cairo_matrix_translate (&matrix,
					pixbuf_width - 1, pixbuf_height - 1);
		cairo_matrix_rotate (&matrix, M_PI);
	}

	if (rotate) {
		if (fish->orientation == PANEL_APPLET_ORIENT_RIGHT) {
			cairo_matrix_translate (&matrix, pixbuf_width - 1, 0);
			cairo_matrix_rotate (&matrix, M_PI * 0.5);
		} else {
			cairo_matrix_translate (&matrix, 0, pixbuf_height - 1);
			cairo_matrix_rotate (&matrix, M_PI * 1.5);
		}
		cairo_matrix_scale (&matrix,
				    (double) (pixbuf_height - 1) / width,
				    (double) (pixbuf_width - 1) / height);
	} else {
		cairo_matrix_scale (&matrix,
				    (double) (pixbuf_width - 1) / width,
				    (double) (pixbuf_height - 1) / height);
	}

	cairo_pattern_set_matrix (pattern, &matrix);

	cairo_rectangle (cr, 0, 0, width, height);
	cairo_fill (cr);

	if (fish->april_fools) {
		cairo_set_source_rgb (cr, 1, 0.5, 0);
		cairo_paint_with_alpha (cr, 0.25);
	}

	cairo_destroy (cr);
}
コード例 #11
0
ファイル: Cursor.cpp プロジェクト: gitter-badger/xournalpp
GdkCursor* Cursor::getPenCursor()
{
	XOJ_CHECK_TYPE(Cursor);

	ToolHandler* handler = control->getToolHandler();

	bool big = control->getSettings()->isShowBigCursor();

	int height = 3;
	int width = 3;
	if (big)
	{
		height = 22;
		width = 15;
	}

	cairo_surface_t* crCursor = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
	                                                       width, height);
	cairo_t* cr = cairo_create(crCursor);

	Util::cairo_set_source_rgbi(cr, handler->getColor());

	if (big)
	{
		cairo_set_source_rgb(cr, 1, 1, 1);
		cairo_set_line_width(cr, 1.2);
		cairo_move_to(cr, 1.5, 1.5);
		cairo_line_to(cr, 2, 19);
		cairo_line_to(cr, 5.5, 15.5);
		cairo_line_to(cr, 8.5, 20.5);
		cairo_line_to(cr, 10.5, 19);
		cairo_line_to(cr, 8.5, 14);
		cairo_line_to(cr, 13, 14);
		cairo_close_path(cr);
		cairo_fill_preserve(cr);

		cairo_set_source_rgb(cr, 0, 0, 0);
		cairo_stroke(cr);

		Util::cairo_set_source_rgbi(cr, handler->getColor());
		cairo_rectangle(cr, 0, 0, 3, 3);
		cairo_fill(cr);
	}
	else
	{
		cairo_rectangle(cr, 0, 0, 3, 3);
		cairo_fill(cr);
	}

	cairo_destroy(cr);

	GdkPixbuf* pixbuf = xoj_pixbuf_get_from_surface(crCursor, 0, 0, width, height);

	//	cairo_surface_write_to_png(crCursor, "/home/andreas/xoj-cursor-orig.png");
	//	gdk_pixbuf_save(pixbuf, "/home/andreas/xoj-cursor.png", "png", NULL, NULL);

	cairo_surface_destroy(crCursor);

	GdkCursor* cursor = gdk_cursor_new_from_pixbuf(gtk_widget_get_display(
	                                                   control->getWindow()->getXournal()->getWidget()), pixbuf, 1, 1);

	gdk_pixbuf_unref(pixbuf);

	return cursor;
}
コード例 #12
0
void expose(dt_view_t *self, cairo_t *cri, int32_t width_i, int32_t height_i, int32_t pointerx, int32_t pointery)
{
  // startup-time conf parameter:
  const int32_t capwd = darktable.thumbnail_width;
  const int32_t capht = darktable.thumbnail_height;
  // if width or height > max pipeline pixels: center the view and clamp.
  int32_t width  = MIN(width_i,  capwd);
  int32_t height = MIN(height_i, capht);

  cairo_set_source_rgb (cri, .2, .2, .2);
  cairo_save(cri);
  cairo_set_fill_rule(cri, CAIRO_FILL_RULE_EVEN_ODD);
  cairo_rectangle(cri, 0, 0, width_i, height_i);
  cairo_rectangle(cri,
                  MAX(1.0, width_i -capwd) *.5f,
                  MAX(1.0, height_i-capht) *.5f,
                  MIN(width, width_i-1), MIN(height, height_i-1));
  cairo_fill (cri);
  cairo_restore(cri);

  if(width_i  > capwd) cairo_translate(cri, -(capwd-width_i) *.5f, 0.0f);
  if(height_i > capht) cairo_translate(cri, 0.0f, -(capht-height_i)*.5f);
  cairo_save(cri);

  dt_develop_t *dev = (dt_develop_t *)self->data;

  if(dev->gui_synch && !dev->image_loading)
  {
    // synch module guis from gtk thread:
    darktable.gui->reset = 1;
    GList *modules = dev->iop;
    while(modules)
    {
      dt_iop_module_t *module = (dt_iop_module_t *)(modules->data);
      dt_iop_gui_update(module);
      modules = g_list_next(modules);
    }
    darktable.gui->reset = 0;
    dev->gui_synch = 0;
  }

  if(dev->image_dirty || dev->pipe->input_timestamp < dev->preview_pipe->input_timestamp) dt_dev_process_image(dev);
  if(dev->preview_dirty || dev->pipe->input_timestamp > dev->preview_pipe->input_timestamp) dt_dev_process_preview(dev);

  dt_pthread_mutex_t *mutex = NULL;
  int wd, ht, stride, closeup;
  int32_t zoom;
  float zoom_x, zoom_y;
  DT_CTL_GET_GLOBAL(zoom_y, dev_zoom_y);
  DT_CTL_GET_GLOBAL(zoom_x, dev_zoom_x);
  DT_CTL_GET_GLOBAL(zoom, dev_zoom);
  DT_CTL_GET_GLOBAL(closeup, dev_closeup);
  static cairo_surface_t *image_surface = NULL;
  static int image_surface_width = 0, image_surface_height = 0, image_surface_imgid = -1;

  if(image_surface_width != width || image_surface_height != height || image_surface == NULL)
  {
    // create double-buffered image to draw on, to make modules draw more fluently.
    image_surface_width = width;
    image_surface_height = height;
    if(image_surface) cairo_surface_destroy(image_surface);
    image_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
    image_surface_imgid = -1; // invalidate old stuff
  }
  cairo_surface_t *surface;
  cairo_t *cr = cairo_create(image_surface);

  // adjust scroll bars
  {
    float zx = zoom_x, zy = zoom_y, boxw = 1., boxh = 1.;
    dt_dev_check_zoom_bounds(dev, &zx, &zy, zoom, closeup, &boxw, &boxh);
    dt_view_set_scrollbar(self, zx+.5-boxw*.5, 1.0, boxw, zy+.5-boxh*.5, 1.0, boxh);
  }

  if(!dev->image_dirty && dev->pipe->input_timestamp >= dev->preview_pipe->input_timestamp)
  {
    // draw image
    mutex = &dev->pipe->backbuf_mutex;
    dt_pthread_mutex_lock(mutex);
    wd = dev->pipe->backbuf_width;
    ht = dev->pipe->backbuf_height;
    stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, wd);
    surface = cairo_image_surface_create_for_data (dev->pipe->backbuf, CAIRO_FORMAT_RGB24, wd, ht, stride);
    cairo_set_source_rgb (cr, .2, .2, .2);
    cairo_paint(cr);
    cairo_translate(cr, .5f*(width-wd), .5f*(height-ht));
    if(closeup)
    {
      const float closeup_scale = 2.0;
      cairo_scale(cr, closeup_scale, closeup_scale);
      float boxw = 1, boxh = 1, zx0 = zoom_x, zy0 = zoom_y, zx1 = zoom_x, zy1 = zoom_y, zxm = -1.0, zym = -1.0;
      dt_dev_check_zoom_bounds(dev, &zx0, &zy0, zoom, 0, &boxw, &boxh);
      dt_dev_check_zoom_bounds(dev, &zx1, &zy1, zoom, 1, &boxw, &boxh);
      dt_dev_check_zoom_bounds(dev, &zxm, &zym, zoom, 1, &boxw, &boxh);
      const float fx = 1.0 - fmaxf(0.0, (zx0 - zx1)/(zx0 - zxm)), fy = 1.0 - fmaxf(0.0, (zy0 - zy1)/(zy0 - zym));
      cairo_translate(cr, -wd/(2.0*closeup_scale) * fx, -ht/(2.0*closeup_scale) * fy);
    }
    cairo_rectangle(cr, 0, 0, wd, ht);
    cairo_set_source_surface (cr, surface, 0, 0);
    cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST);
    cairo_fill_preserve(cr);
    cairo_set_line_width(cr, 1.0);
    cairo_set_source_rgb (cr, .3, .3, .3);
    cairo_stroke(cr);
    cairo_surface_destroy (surface);
    dt_pthread_mutex_unlock(mutex);
    image_surface_imgid = dev->image_storage.id;
  }
  else if(!dev->preview_dirty)
  {
    // draw preview
    mutex = &dev->preview_pipe->backbuf_mutex;
    dt_pthread_mutex_lock(mutex);

    wd = dev->preview_pipe->backbuf_width;
    ht = dev->preview_pipe->backbuf_height;
    float zoom_scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2 : 1, 1);
    cairo_set_source_rgb (cr, .2, .2, .2);
    cairo_paint(cr);
    cairo_rectangle(cr, 0, 0, width, height);
    cairo_clip(cr);
    stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, wd);
    surface = cairo_image_surface_create_for_data (dev->preview_pipe->backbuf, CAIRO_FORMAT_RGB24, wd, ht, stride);
    cairo_translate(cr, width/2.0, height/2.0f);
    cairo_scale(cr, zoom_scale, zoom_scale);
    cairo_translate(cr, -.5f*wd-zoom_x*wd, -.5f*ht-zoom_y*ht);
    // avoid to draw the 1px garbage that sometimes shows up in the preview :(
    cairo_rectangle(cr, 0, 0, wd-1, ht-1);
    cairo_set_source_surface (cr, surface, 0, 0);
    cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_FAST);
    cairo_fill(cr);
    cairo_surface_destroy (surface);
    dt_pthread_mutex_unlock(mutex);
    image_surface_imgid = dev->image_storage.id;
  }
  cairo_restore(cri);

  if(image_surface_imgid == dev->image_storage.id)
  {
    cairo_destroy(cr);
    cairo_set_source_surface(cri, image_surface, 0, 0);
    cairo_paint(cri);
  }

  /* check if we should create a snapshot of view */
  if(darktable.develop->proxy.snapshot.request)
  {
    /* reset the request */
    darktable.develop->proxy.snapshot.request = FALSE;

    /* validation of snapshot filename */
    g_assert(darktable.develop->proxy.snapshot.filename != NULL);

    /* Store current image surface to snapshot file.
       FIXME: add checks so that we dont make snapshots of preview pipe image surface.
    */
    cairo_surface_write_to_png(image_surface, darktable.develop->proxy.snapshot.filename);
  }

  // Displaying sample areas if enabled
  if(darktable.lib->proxy.colorpicker.live_samples &&
      darktable.lib->proxy.colorpicker.display_samples)
  {
    GSList *samples = darktable.lib->proxy.colorpicker.live_samples;
    dt_colorpicker_sample_t *sample = NULL;

    cairo_save(cri);

    int32_t zoom, closeup;
    float zoom_x, zoom_y;
    float wd = dev->preview_pipe->backbuf_width;
    float ht = dev->preview_pipe->backbuf_height;
    DT_CTL_GET_GLOBAL(zoom_y, dev_zoom_y);
    DT_CTL_GET_GLOBAL(zoom_x, dev_zoom_x);
    DT_CTL_GET_GLOBAL(zoom, dev_zoom);
    DT_CTL_GET_GLOBAL(closeup, dev_closeup);
    float zoom_scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2 : 1, 1);

    cairo_translate(cri, width/2.0, height/2.0f);
    cairo_scale(cri, zoom_scale, zoom_scale);
    cairo_translate(cri, -.5f*wd-zoom_x*wd, -.5f*ht-zoom_y*ht);

    while(samples)
    {
      sample = samples->data;

      cairo_set_line_width(cri, 1.0/zoom_scale);
      if(sample == darktable.lib->proxy.colorpicker.selected_sample)
        cairo_set_source_rgb(cri, .2, 0, 0);
      else
        cairo_set_source_rgb(cri, 0, 0, .2);

      float *box = sample->box;
      float *point = sample->point;
      if(sample->size == DT_COLORPICKER_SIZE_BOX)
      {
        cairo_rectangle(cri, box[0]*wd, box[1]*ht,
                        (box[2] - box[0])*wd, (box[3] - box[1])*ht);
        cairo_stroke(cri);
        cairo_translate(cri, 1.0/zoom_scale, 1.0/zoom_scale);
        if(sample == darktable.lib->proxy.colorpicker.selected_sample)
          cairo_set_source_rgb(cri, .8, 0, 0);
        else
          cairo_set_source_rgb(cri, 0, 0, .8);
        cairo_rectangle(cri, box[0]*wd + 1.0/zoom_scale, box[1]*ht,
                        (box[2] - box[0])*wd - 3./zoom_scale,
                        (box[3] - box[1])*ht - 2./zoom_scale);
        cairo_stroke(cri);
      }
      else
      {
        cairo_rectangle(cri, point[0] * wd - .01 * wd, point[1] * ht - .01 * wd,
                        .02 * wd, .02 * wd);
        cairo_stroke(cri);

        if(sample == darktable.lib->proxy.colorpicker.selected_sample)
          cairo_set_source_rgb(cri, .8, 0, 0);
        else
          cairo_set_source_rgb(cri, 0, 0, .8);
        cairo_rectangle(cri, (point[0] - 0.01) * wd + 1.0/zoom_scale,
                        point[1] * ht - 0.01 * wd + 1.0/zoom_scale,
                        .02 * wd - 2./zoom_scale, .02 * wd - 2./zoom_scale);
        cairo_move_to(cri, point[0] * wd,
                      point[1] * ht - .01 * wd + 1./zoom_scale);
        cairo_line_to(cri, point[0] * wd,
                      point[1] * ht + .01 * wd - 1./zoom_scale);
        cairo_move_to(cri, point[0] * wd - .01 * wd + 1./zoom_scale,
                      point[1] * ht);
        cairo_line_to(cri, point[0] * wd + .01 * wd - 1./zoom_scale,
                      point[1] * ht);
        cairo_stroke(cri);
      }

      samples = g_slist_next(samples);
    }

    cairo_restore(cri);
  }

  // execute module callback hook.
  if(dev->gui_module && dev->gui_module->request_color_pick)
  {
    int32_t zoom, closeup;
    float zoom_x, zoom_y;
    float wd = dev->preview_pipe->backbuf_width;
    float ht = dev->preview_pipe->backbuf_height;
    DT_CTL_GET_GLOBAL(zoom_y, dev_zoom_y);
    DT_CTL_GET_GLOBAL(zoom_x, dev_zoom_x);
    DT_CTL_GET_GLOBAL(zoom, dev_zoom);
    DT_CTL_GET_GLOBAL(closeup, dev_closeup);
    float zoom_scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2 : 1, 1);

    cairo_translate(cri, width/2.0, height/2.0f);
    cairo_scale(cri, zoom_scale, zoom_scale);
    cairo_translate(cri, -.5f*wd-zoom_x*wd, -.5f*ht-zoom_y*ht);

    // cairo_set_operator(cri, CAIRO_OPERATOR_XOR);
    cairo_set_line_width(cri, 1.0/zoom_scale);
    cairo_set_source_rgb(cri, .2, .2, .2);

    float *box = dev->gui_module->color_picker_box;
    float *point = dev->gui_module->color_picker_point;
    if(darktable.lib->proxy.colorpicker.size)
    {
      cairo_rectangle(cri, box[0]*wd, box[1]*ht,
                      (box[2] - box[0])*wd, (box[3] - box[1])*ht);
      cairo_stroke(cri);
      cairo_translate(cri, 1.0/zoom_scale, 1.0/zoom_scale);
      cairo_set_source_rgb(cri, .8, .8, .8);
      cairo_rectangle(cri, box[0]*wd + 1.0/zoom_scale, box[1]*ht,
                      (box[2] - box[0])*wd - 3./zoom_scale,
                      (box[3] - box[1])*ht - 2./zoom_scale);
      cairo_stroke(cri);
    }
    else
    {
      cairo_rectangle(cri, point[0] * wd - .01 * wd, point[1] * ht - .01 * wd,
                      .02 * wd, .02 * wd);
      cairo_stroke(cri);

      cairo_set_source_rgb(cri, .8, .8, .8);
      cairo_rectangle(cri, (point[0] - 0.01) * wd + 1.0/zoom_scale,
                      point[1] * ht - 0.01 * wd + 1.0/zoom_scale,
                      .02 * wd - 2./zoom_scale, .02 * wd - 2./zoom_scale);
      cairo_move_to(cri, point[0] * wd,
                    point[1] * ht - .01 * wd + 1./zoom_scale);
      cairo_line_to(cri, point[0] * wd,
                    point[1] * ht + .01 * wd - 1./zoom_scale);
      cairo_move_to(cri, point[0] * wd - .01 * wd + 1./zoom_scale,
                    point[1] * ht);
      cairo_line_to(cri, point[0] * wd + .01 * wd - 1./zoom_scale,
                    point[1] * ht);
      cairo_stroke(cri);
    }
  }
  else if(dev->gui_module && dev->gui_module->gui_post_expose)
  {
    if(width_i  > capwd) pointerx += (capwd-width_i) *.5f;
    if(height_i > capht) pointery += (capht-height_i)*.5f;
    dev->gui_module->gui_post_expose(dev->gui_module, cri, width, height, pointerx, pointery);
  }
}
コード例 #13
0
ファイル: print.c プロジェクト: MaximeCheramy/zathura
static void
cb_print_draw_page(GtkPrintOperation* print_operation, GtkPrintContext*
                   context, gint page_number, zathura_t* zathura)
{
  if (context == NULL || zathura == NULL || zathura->document == NULL ||
      zathura->ui.session == NULL || zathura->ui.statusbar.file == NULL) {
    gtk_print_operation_cancel(print_operation);
    return;
  }

  /* Update statusbar. */
  char* tmp = g_strdup_printf("Printing %d...", page_number);
  girara_statusbar_item_set_text(zathura->ui.session,
                                 zathura->ui.statusbar.file, tmp);
  g_free(tmp);

  /* Get the page and cairo handle.  */
  cairo_t* cairo       = gtk_print_context_get_cairo_context(context);
  zathura_page_t* page = zathura_document_get_page(zathura->document, page_number);
  if (cairo == NULL || page == NULL) {
    gtk_print_operation_cancel(print_operation);
    return;
  }

  /* Try to render the page without a temporary surface. This only works with
   * plugins that support rendering to any surface.  */
  girara_debug("printing page %d ...", page_number);
  zathura_renderer_lock(zathura->sync.render_thread);
  int err = zathura_page_render(page, cairo, true);
  zathura_renderer_unlock(zathura->sync.render_thread);
  if (err == ZATHURA_ERROR_OK) {
    return;
  }

  /* Try to render the page on a temporary image surface. */
  const gdouble width = gtk_print_context_get_width(context);
  const gdouble height = gtk_print_context_get_height(context);

  /* Render to a surface that is 5 times larger to workaround quality issues. */
  const double page_height = zathura_page_get_height(page) * 5;
  const double page_width  = zathura_page_get_width(page) * 5;
  cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, page_width, page_height);
  if (surface == NULL) {
    gtk_print_operation_cancel(print_operation);
    return;
  }

  cairo_t* temp_cairo = cairo_create(surface);
  if (cairo == NULL) {
    gtk_print_operation_cancel(print_operation);
    cairo_surface_destroy(surface);
    return;
  }

  /* Draw a white background. */
  cairo_save(temp_cairo);
  cairo_set_source_rgb(temp_cairo, 1, 1, 1);
  cairo_rectangle(temp_cairo, 0, 0, page_width, page_height);
  cairo_fill(temp_cairo);
  cairo_restore(temp_cairo);

  /* Render the page to the temporary surface */
  girara_debug("printing page %d (fallback) ...", page_number);
  zathura_renderer_lock(zathura->sync.render_thread);
  err = zathura_page_render(page, temp_cairo, true);
  zathura_renderer_unlock(zathura->sync.render_thread);
  if (err != ZATHURA_ERROR_OK) {
    cairo_destroy(temp_cairo);
    cairo_surface_destroy(surface);
    gtk_print_operation_cancel(print_operation);
    return;
  }

  /* Rescale the page and keep the aspect ratio */
  const gdouble scale = MIN(width / page_width, height / page_height);
  cairo_scale(cairo, scale, scale);

  /* Blit temporary surface to original cairo object. */
  cairo_set_source_surface(cairo, surface, 0.0, 0.0);
  cairo_paint(cairo);
  cairo_destroy(temp_cairo);
  cairo_surface_destroy(surface);
}
コード例 #14
0
static gboolean _lib_filmstrip_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
{
  dt_lib_module_t *self = (dt_lib_module_t *)user_data;
  dt_lib_filmstrip_t *strip = (dt_lib_filmstrip_t *)self->data;

  int32_t width = widget->allocation.width;
  int32_t height = widget->allocation.height;

  gdouble pointerx = strip->pointerx;
  gdouble pointery = strip->pointery;

  if(darktable.gui->center_tooltip == 1)
    darktable.gui->center_tooltip++;

  strip->image_over = DT_VIEW_DESERT;
  DT_CTL_SET_GLOBAL(lib_image_mouse_over_id, -1);

  /* create cairo surface */
  cairo_t *cr = gdk_cairo_create(widget->window);

  /* fill background */
  cairo_set_source_rgb (cr, .2, .2, .2);
  cairo_paint(cr);

  int offset = strip->offset;

  const float wd = height;
  const float ht = height;

  int max_cols = (int)(width/(float)wd) + 2;
  if (max_cols%2 == 0)
    max_cols += 1;

  const int col_start = max_cols/2 - strip->offset;
  const int empty_edge = (width - (max_cols * wd))/2;
  int step_res = SQLITE_ROW;

  sqlite3_stmt *stmt = NULL;

  /* mouse over image position in filmstrip */
  pointerx -= empty_edge;
  const int seli = (pointery > 0 && pointery <= ht) ? pointerx / (float)wd : -1;
  const int img_pointerx = (int)fmodf(pointerx, wd);
  const int img_pointery = (int)pointery;


  /* get the count of current collection */
  strip->collection_count = dt_collection_get_count (darktable.collection);

  /* get the collection query */
  const gchar *query=dt_collection_get_query (darktable.collection);
  if(!query)
    return FALSE;

  if(offset < 0)
    strip->offset = offset = 0;
  if(offset > strip->collection_count-1)
    strip->offset = offset = strip->collection_count-1;

  // dt_view_set_scrollbar(self, offset, count, max_cols, 0, 1, 1);

  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, &stmt, NULL);
  DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, offset - max_cols/2);
  DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, max_cols);


  cairo_save(cr);
  cairo_translate(cr, empty_edge, 0.0f);
  for(int col = 0; col < max_cols; col++)
  {
    if(col < col_start)
    {
      cairo_translate(cr, wd, 0.0f);
      continue;
    }

    if(step_res != SQLITE_DONE)
    {
      step_res = sqlite3_step(stmt);
    }

    if(step_res == SQLITE_ROW)
    {
      int id = sqlite3_column_int(stmt, 0);
      // set mouse over id
      if(seli == col)
      {
        strip->mouse_over_id = id;
        DT_CTL_SET_GLOBAL(lib_image_mouse_over_id, strip->mouse_over_id);
      }
      cairo_save(cr);
      // FIXME find out where the y translation is done, how big the value is and use it directly instead of getting it from the matrix ...
      cairo_matrix_t m;
      cairo_get_matrix(cr, &m);
      dt_view_image_expose(&(strip->image_over), id, cr, wd, ht, max_cols, img_pointerx, img_pointery, FALSE);
      cairo_restore(cr);
    }
    else if (step_res == SQLITE_DONE)
    {
      /* do nothing, just add some empty thumb frames */
    }
    else goto failure;
    cairo_translate(cr, wd, 0.0f);
  }
failure:
  cairo_restore(cr);
  sqlite3_finalize(stmt);

  if(darktable.gui->center_tooltip == 1) // set in this round
  {
    char* tooltip = dt_history_get_items_as_string(strip->mouse_over_id);
    if(tooltip != NULL)
    {
      g_object_set(G_OBJECT(strip->filmstrip), "tooltip-text", tooltip, (char *)NULL);
      g_free(tooltip);
    }
  }
  else if(darktable.gui->center_tooltip == 2)   // not set in this round
  {
    darktable.gui->center_tooltip = 0;
    g_object_set(G_OBJECT(strip->filmstrip), "tooltip-text", "", (char *)NULL);
  }

#ifdef _DEBUG
  if(darktable.unmuted & DT_DEBUG_CACHE)
    dt_mipmap_cache_print(darktable.mipmap_cache);
#endif

  /* cleanup */
  cairo_destroy(cr);

  return TRUE;
}
コード例 #15
0
/*
void layout_paint(GtkWidget *widget,
                  cairo_t   *cr,
                  GtkRange  *range)
*/
extern gboolean 
layout_expose(GtkWidget *widget,
              GdkEventExpose *event,
              Score_t *score)
{
        cairo_t *cr = gdk_cairo_create(widget->window);

        GList * listrunner_staff = NULL;
        GList * listrunner_object = NULL;

        gint width, height;
        gint i;


        g_assert( score );

        width  = widget->allocation.width;
        height = widget->allocation.height;

        /*
	 * enclosing the painting function in a save/restore pair is a
         * good idea since we'll return to a sane state then
         */

        cairo_save (cr);

        /* clear background */

        cairo_rectangle (cr, 0, 0, width, height);
        cairo_set_source_rgb (cr, 1,1,1);
        cairo_fill (cr);


        /* enclosing in a save/restore pair since we alter the
         * font size
         */
        cairo_save (cr);


        /***************
         * Draw Staves *
         ***************/
        /* We walk through staves */
        listrunner_staff = g_list_first(score->Staff_list);
        while ( listrunner_staff ) {
                measure_number = 1;

                Staff_t *staff;
                staff = (Staff_t *)listrunner_staff->data;

                object_x = staff->extremity_begin_x + Spacings.Clefs.sb + (score->zoom * TREBLE_CLEF_WIDTH_FACTOR) + Spacings.Clefs.sa + get_key_signature_spacing(score, staff) + Spacings.KeySignatures.saks + Spacings.TimeSignatures.width + Spacings.TimeSignatures.sats;

                draw_staff(score, cr, 
                           staff->nb_lines, staff->space_btw_lines,
                           staff->extremity_begin_x, staff->extremity_begin_y,
                           score->staff_extremity_end_x, staff->is_selected);
                
/*                 if ( display->clefs ) */
                        draw_key(score, staff, cr, FALSE);

/*                 if ( display->key_signature ) */
                        draw_key_signature(score, staff, cr, FALSE);

/*                 if ( display->time_signature ) */
                        draw_time_signature(score, staff, cr, FALSE);

		listrunner_object = g_list_first(staff->Object_list);
 		while ( listrunner_object ) { 
 			Object_t *object = NULL;
 			object = (Object_t *)listrunner_object->data;

/*                         g_print("object->pitch = %d \n", object->pitch); */
/*                         g_print("%s:%d: x = %f\n", __FILE__, __LINE__, object_x); */
			
			if (object) {

                                draw_staff_extension(score, staff, cr, object->pitch, object_x);
/*                                 g_print("layout engine, object_type = %d\n", object->type); */

				switch(object->type) {

				case PITCH_CURSOR:
					object_x = draw_pitch_cursor(score, staff, cr, object_x, object->pitch);
				        break;
                                case BARLINE_SINGLE:
                                        object_x = draw_barline_single(score, staff, object, cr, object_x);
                                        break;
				case DOUBLEWHOLE:
                                case DOUBLEWHOLEREST:
				case WHOLE:
                                case WHOLEREST:
				case HALF:
                                case HALFREST:
				case QUARTER:
                                case QUARTERREST:
				case EIGHTH:
                                case EIGHTHREST:
				case SIXTEENTH:
                                case SIXTEENTHREST:
                                        object_x = draw_note_rest(score, staff, object, cr, object_x);
					break;
                                default:
                                        g_print("Unknown object type: %d\n", object->type);

				}
			}
			
			listrunner_object = g_list_next(listrunner_object);
		}
		
                listrunner_staff = g_list_next(listrunner_staff);
        } /* while ( listrunner_staff ) */


        cairo_set_source_rgb (cr, 0, 0, 0);

        /* Show the quarter note head */
/*         cairo_select_font (cr, "gscore", CAIRO_FONT_SLANT_NORMAL, */
/*                            CAIRO_FONT_WEIGHT_BOLD); */
/*         cairo_save (cr); */
/*         cairo_scale_font (cr, 30); */
/*         cairo_move_to (cr, 100.5, 54); */
/*         cairo_set_rgb_color (cr, 0,0,0); */
/*         cairo_show_text (cr, QUARTER_GLYPH); */

        /* Show the stem */
        /* Line */
/*         cairo_move_to(cr, 100.5, 54); */
/*         cairo_rel_line_to(cr, 0, 30.5); */
/*         cairo_stroke(cr); */
/*         /\* Sixteenth *\/ */
/*         cairo_move_to (cr, 101, 84.5); */
/*         cairo_show_text (cr, SIXTEENTH_STEM_DOWN_GLYPH); */


/*         /\* Add a sharp to the note *\/ */
/*         cairo_move_to (cr, 90, 54); */
/*         cairo_scale_font (cr, 1); */
/*         cairo_set_rgb_color (cr, 0,0,0); */
/*         cairo_show_text (cr, SHARP_GLYPH); */
/*         cairo_stroke(cr); */

/*         /\* Show the key *\/ */
/*         cairo_move_to (cr, 15.5, 75); */
/*         cairo_scale_font (cr, 1); */
/*         cairo_set_rgb_color (cr, 0,0,0); */
/*         cairo_show_text (cr, TREBLE_GLYPH); */
/*         cairo_stroke(cr); */

/*         /\* Add 2/4 *\/ */
/*         cairo_move_to (cr, 40, 66.5); */
/*         cairo_scale_font (cr, 0.5); */
/*         cairo_show_text (cr, "2"); */

/*         cairo_move_to (cr, 40, 82.5); */
/*         cairo_show_text (cr, "4"); */


/*         cairo_restore (cr); */

/*         cairo_set_rgb_color (cr, 1,0,0); */
/*         cairo_scale_font (cr, 15); */
/*         cairo_move_to (cr, 50, 100); */


        cairo_stroke (cr);

        cairo_restore (cr);

        selection_paint(cr, score);
}
コード例 #16
0
ファイル: gtk-example-03.c プロジェクト: joilar/gtk-practice
static void clear_surface ( void ) {
    cairo_t *cr = cairo_create( surface );
    cairo_set_source_rgb( cr, 1, 1, 1 );
    cairo_paint( cr );
    cairo_destroy( cr );
}
コード例 #17
0
int main(int argc, char *argv[]) {
    int pid = fork();
    if (!pid) {

      drawing_information dinformation;
      drawing_information* di = &dinformation;

      di->ball_x = 360;
      di->ball_y = 240;
      di->paddle_one_y = 0;
      di->paddle_two_y = 0;
      di->score_one = 0;
      di->score_two = 0;
      di->ball_speed = 1;

      int shmid;
      key_t key = 25568;

      if ((shmid = shmget(key, sizeof(drawing_information), IPC_CREAT | 0666)) < 0) {
	printf("Error shmgetting...\n");
	exit(1);
      }
      
      int width = 720;
      int height = 520;
      int videoFlags = SDL_SWSURFACE | SDL_RESIZABLE | SDL_DOUBLEBUF;
      int bpp = 32;
      
      if (SDL_Init(SDL_INIT_VIDEO) < 0) {
	return -1;
      }
      
      SDL_WM_SetCaption("Pong", "Pong");
      
      SDL_Surface *screen;
      screen = SDL_SetVideoMode(width, height, bpp, videoFlags);
      
      SDL_EnableKeyRepeat(300, 130);
      SDL_EnableUNICODE(1);
      
      SDL_Surface *sdl_surface = SDL_CreateRGBSurface ( 
						       videoFlags, width, height, 32, 
						       0x00ff0000, 
						       0x0000ff00, 
						       0x000000ff, 
						       0
							);
      
      int done = 0;
      
      while (!done) {
	di = (drawing_information *)shmat(shmid, NULL, 0);
	
	SDL_FillRect(sdl_surface, NULL, 0);
	
	cairo_surface_t *cairo_surface = cairo_image_surface_create_for_data((unsigned char *)sdl_surface->pixels, CAIRO_FORMAT_RGB24, sdl_surface->w, sdl_surface->h, sdl_surface->pitch);
	
	cairo_t *cr = cairo_create(cairo_surface);
	
	//do_drawing(cr);
	cairo_set_source_rgb(cr,255,255,255);
	cairo_rectangle(cr, 20, di->paddle_one_y, 7, 40);
	cairo_fill(cr);
	
	cairo_rectangle(cr, 693, di->paddle_two_y, 7, 40);
	cairo_fill(cr);
	
	cairo_arc(cr, di->ball_x, di->ball_y, 5, 0, 2*M_PI);
	cairo_fill(cr);

	cairo_move_to(cr, 0, 480);
	cairo_line_to(cr, 720, 480);

	cairo_stroke(cr);
	
	cairo_select_font_face(cr, "Courier",
			       CAIRO_FONT_SLANT_NORMAL,
			       CAIRO_FONT_WEIGHT_BOLD);

	cairo_set_font_size(cr, 38);

	cairo_move_to(cr, 20, 510);
	char *to_send = (char *)malloc(100);
	sprintf(to_send,
	  "%d",
	  di->score_one);

	cairo_show_text(cr, to_send);

	cairo_move_to(cr, 693, 510);
	sprintf(to_send,
		"%d",
		di->score_two);

	cairo_show_text(cr, to_send); 
		
	SDL_BlitSurface(sdl_surface, NULL, screen, NULL);
	SDL_Flip(screen);
	
	//dont with cairo surface
	cairo_surface_destroy(cairo_surface);
	cairo_destroy(cr);
	
	//Event handling
	SDL_Event event;
	while (SDL_PollEvent(&event)) {
	  switch(event.type) {
	  case SDL_KEYDOWN:
	    if (event.key.keysym.sym == SDLK_ESCAPE) {
	      done = 1;
	    }
	    else if (event.key.keysym.sym == SDLK_w) {
	      if (di->paddle_one_y > 15) {
		di->paddle_one_y -= 15;
	      }
	    }
	    else if (event.key.keysym.sym == SDLK_s) {
	      if (di->paddle_one_y < 410) {
		di->paddle_one_y += 15;
	      }
	    }
	    else if (event.key.keysym.sym == SDLK_UP) {
	      if (di->paddle_two_y > 15) {
		di->paddle_two_y -= 15;
	      }
	    }
	    else if (event.key.keysym.sym == SDLK_DOWN) {
	      if (di->paddle_two_y < 410) {
		di->paddle_two_y += 15;
	      }
	    }
	    break;
	  case SDL_QUIT:
	    done = 1;
	    break;
	  }
	}
	
	SDL_Delay(1);
	
      }
      
      //cleanup
      SDL_FreeSurface(sdl_surface);
      SDL_Quit();
      
      return 0;
      
    }
    else {
      drawing_information dinformation;
      drawing_information* di = &dinformation;

      di->ball_x = 360;
      di->ball_y = 240;
      di->paddle_one_y = 0;
      di->paddle_two_y = 0;
      di->score_one = 0;
      di->score_two = 0;

      int to_server;
      int from_server;
      char buffer[100];
      
      to_server = client_handshake(&from_server);
      
      while (1) {
	// Reading loop
	
	// Take input from user
	
	// Write to server
	
	// If the message is exit, then shut down
	// write(to_server, buffer, sizeof(buffer));
	
	// Get message from server
	read(from_server, buffer, sizeof(buffer));
	// Print confirmation
	char *to_send = parse_input(buffer, di);
	write(to_server, to_send, 100);
      }
    }
}
コード例 #18
0
ファイル: printing.c プロジェクト: terfect/Geany-plus
static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context,
					  gint page_nr, gpointer user_data)
{
	DocInfo *dinfo = user_data;
	GeanyEditor *editor;
	cairo_t *cr;
	gdouble width, height;
	gdouble x, y;
	/*gint layout_h;*/
	gint count;
	GString *str;

	if (dinfo == NULL || page_nr >= dinfo->n_pages)
		return;

	editor = dinfo->doc->editor;

	if (dinfo->n_pages > 0)
	{
		gdouble fraction = (page_nr + 1) / (gdouble) dinfo->n_pages;
		gchar *text = g_strdup_printf(_("Page %d of %d"), page_nr, dinfo->n_pages);
		gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_widgets.progressbar), fraction);
		gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_widgets.progressbar), text);
		g_free(text);
	}

#ifdef GEANY_PRINT_DEBUG
	geany_debug("draw_page = %d, pages = %d, (real) lines_per_page = %d",
		page_nr, dinfo->n_pages, dinfo->lines_per_page);
#endif

	str = g_string_sized_new(256);
	cr = gtk_print_context_get_cairo_context(context);
	width = gtk_print_context_get_width(context);
	height = gtk_print_context_get_height(context);

	cairo_set_source_rgb(cr, 0, 0, 0);
#ifdef GEANY_PRINT_DEBUG
	cairo_set_line_width(cr, 0.2);
	cairo_rectangle(cr, 0, 0, width, height);
	cairo_stroke(cr);
#endif
	cairo_move_to(cr, 0, 0);

	pango_layout_set_width(dinfo->layout, width * PANGO_SCALE);
	pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_LEFT);
	pango_layout_set_ellipsize(dinfo->layout, FALSE);
	pango_layout_set_justify(dinfo->layout, FALSE);

	if (printing_prefs.print_page_header)
		add_page_header(dinfo, cr, width, page_nr);

	count = 0;	/* the actual line counter for the current page, might be different from
				 * dinfo->cur_line due to possible line breaks */
	while (count < dinfo->lines_per_page)
	{
		gchar c = 'a';
		gint style = -1;
		PangoAttrList *layout_attr;
		PangoAttribute *attr;
		gint colours[3] = { 0 };
		gboolean add_linenumber = TRUE;
		gboolean at_eol;

		while (count < dinfo->lines_per_page && c != '\0')
		{
			at_eol = FALSE;

			g_string_erase(str, 0, str->len); /* clear the string */

			/* line numbers */
			if (printing_prefs.print_line_numbers && add_linenumber)
			{
				/* if we had a wrapped line on the last page which needs to be continued, don't
				 * add a line number */
				if (dinfo->long_line)
				{
					add_linenumber = FALSE;
				}
				else
				{
					gchar *line_number = NULL;
					gint cur_line_number_margin = get_line_numbers_arity(dinfo->cur_line + 1);
					gchar *fill = g_strnfill(
						dinfo->max_line_number_margin - cur_line_number_margin - 1, ' ');

					line_number = g_strdup_printf("%s%d ", fill, dinfo->cur_line + 1);
					g_string_append(str, line_number);
					dinfo->cur_line++; /* increase document line */
					add_linenumber = FALSE;
					style = STYLE_LINENUMBER;
					c = 'a'; /* dummy value */
					g_free(fill);
					g_free(line_number);
				}
			}
			/* data */
			else
			{
				style = sci_get_style_at(dinfo->doc->editor->sci, dinfo->cur_pos);
				c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos);
				if (c == '\0' || style == -1)
				{	/* if c gets 0, we are probably out of document boundaries,
					 * so stop to break out of outer loop */
					count = dinfo->lines_per_page;
					break;
				}
				dinfo->cur_pos++;

				/* convert tabs to spaces which seems to be better than using Pango tabs */
				if (c == '\t')
				{
					gint tab_width = sci_get_tab_width(editor->sci);
					gchar *s = g_strnfill(tab_width, ' ');
					g_string_append(str, s);
					g_free(s);
				}
				/* don't add line breaks, they are handled manually below */
				else if (c == '\r' || c == '\n')
				{
					gchar c_next = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos);
					at_eol = TRUE;
					if (c == '\r' && c_next == '\n')
						dinfo->cur_pos++; /* skip LF part of CR/LF */
				}
				else
				{
					g_string_append_c(str, c); /* finally add the character */

					/* handle UTF-8: since we add char by char (better: byte by byte), we need to
					 * keep UTF-8 characters together(e.g. two bytes for one character)
					 * the input is always UTF-8 and c is signed, so all non-Ascii
					 * characters are less than 0 and consist of all bytes less than 0.
					 * style doesn't change since it is only one character with multiple bytes. */
					while (c < 0)
					{
						c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos);
						if (c < 0)
						{	/* only add the byte when it is part of the UTF-8 character
							 * otherwise we could add e.g. a '\n' and it won't be visible in the
							 * printed document */
							g_string_append_c(str, c);
							dinfo->cur_pos++;
						}
					}
				}
			}

			if (! at_eol)
			{
				/* set text */
				pango_layout_set_text(dinfo->layout, str->str, -1);
				/* attributes */
				layout_attr = pango_attr_list_new();
				/* foreground colour */
				get_rgb_values(dinfo->styles[style][FORE], &colours[0], &colours[1], &colours[2]);
				attr = pango_attr_foreground_new(colours[0], colours[1], colours[2]);
				ADD_ATTR(layout_attr, attr);
				/* background colour */
				get_rgb_values(dinfo->styles[style][BACK], &colours[0], &colours[1], &colours[2]);
				attr = pango_attr_background_new(colours[0], colours[1], colours[2]);
				ADD_ATTR(layout_attr, attr);
				/* bold text */
				if (dinfo->styles[style][BOLD])
				{
					attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
					ADD_ATTR(layout_attr, attr);
				}
				/* italic text */
				if (dinfo->styles[style][ITALIC])
				{
					attr = pango_attr_style_new(PANGO_STYLE_ITALIC);
					ADD_ATTR(layout_attr, attr);
				}
				pango_layout_set_attributes(dinfo->layout, layout_attr);
				pango_layout_context_changed(dinfo->layout);
				pango_attr_list_unref(layout_attr);
			}

			cairo_get_current_point(cr, &x, &y);


			/* normal line break at eol character in document */
			if (at_eol)
			{
				/*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/
				/*cairo_move_to(cr, 0, y + (gdouble)layout_h / PANGO_SCALE);*/
				cairo_move_to(cr, 0, y + dinfo->line_height);

				count++;
				/* we added a new document line so request a new line number */
				add_linenumber = TRUE;
			}
			else
			{
				gint x_offset = 0;
				/* maybe we need to force a line break because of too long line */
				if (x >= (width - dinfo->font_width))
				{
					/* don't start the line at horizontal origin because we need to skip the
					 * line number margin */
					if (printing_prefs.print_line_numbers)
					{
						x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width;
					}

					/*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/
					/*cairo_move_to(cr, x_offset, y + (gdouble)layout_h / PANGO_SCALE);*/
					/* this is faster but not exactly the same as above */
					cairo_move_to(cr, x_offset, y + dinfo->line_height);
					cairo_get_current_point(cr, &x, &y);
					count++;
				}
				if (count < dinfo->lines_per_page)
				{
					/* str->len is counted in bytes not characters, so use g_utf8_strlen() */
					x_offset = (g_utf8_strlen(str->str, -1) * dinfo->font_width);

					if (dinfo->long_line && count == 0)
					{
						x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width;
						dinfo->long_line = FALSE;
					}

					pango_cairo_show_layout(cr, dinfo->layout);
					cairo_move_to(cr, x + x_offset, y);
				}
				else
				/* we are on a wrapped line but we are out of lines on this page, so continue
				 * the current line on the next page and remember to continue in current line */
					dinfo->long_line = TRUE;
			}
		}
	}

	if (printing_prefs.print_line_numbers)
	{	/* print a thin line between the line number margin and the data */
		gint y_start = 0;

		if (printing_prefs.print_page_header)
			y_start = (dinfo->line_height * 3) - 2;	/* "- 2": to connect the line number line to
													 * the page header frame */

		cairo_set_line_width(cr, 0.3);
		cairo_move_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1, y_start);
		cairo_line_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1,
			y + dinfo->line_height); /* y is last added line, we reuse it */
		cairo_stroke(cr);
	}

	if (printing_prefs.print_page_numbers)
	{
		gchar *line = g_strdup_printf("<small>- %d -</small>", page_nr + 1);
		pango_layout_set_markup(dinfo->layout, line, -1);
		pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_CENTER);
		cairo_move_to(cr, 0, height - dinfo->line_height);
		pango_cairo_show_layout(cr, dinfo->layout);
		g_free(line);

#ifdef GEANY_PRINT_DEBUG
		cairo_set_line_width(cr, 0.3);
		cairo_move_to(cr, 0, height - (1.25 * dinfo->line_height));
		cairo_line_to(cr, width - 1, height - (1.25 * dinfo->line_height));
		cairo_stroke(cr);
#endif
	}
	g_string_free(str, TRUE);
}
コード例 #19
0
gboolean cd_do_render_listing_notification (gpointer pUserData, CDListing *pListing, cairo_t *pCairoContext)
{
	//g_print ("%s ()\n", __func__);
	int iWidth = pListing->container.iWidth, iHeight = pListing->container.iHeight;
	int iLeftMargin = myDialogs.dialogTextDescription.iSize + 2, iRightMargin = (myDialogs.dialogTextDescription.iSize + 2) / 2;
	int iTopMargin = (myDialogs.dialogTextDescription.iSize + 2) + GAP, iBottomMargin = (myDialogs.dialogTextDescription.iSize + 2) * 4 + GAP;
	CDEntry *pEntry;
	
	// on dessine un cadre et un fond
	double fRadius = MIN (6, myDialogs.dialogTextDescription.iSize/2+1);
	double fLineWidth = 1.;
	cairo_set_line_width (pCairoContext, fLineWidth);
	
	cairo_save (pCairoContext);
	cairo_translate (pCairoContext, 0, fLineWidth);
	cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, iWidth - 2 * fRadius - fLineWidth, iTopMargin - GAP);
	cairo_set_source_rgba (pCairoContext, .8, .8, 1., 1.);
	cairo_stroke_preserve (pCairoContext);
	cairo_set_source_rgba (pCairoContext, 1., 1., 1., .7);
	cairo_fill (pCairoContext);

	cairo_translate (pCairoContext, 0, iTopMargin + fLineWidth);
	cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, iWidth - 2 * fRadius - fLineWidth, iHeight - iTopMargin - iBottomMargin - GAP);
	cairo_set_source_rgba (pCairoContext, .8, .8, 1., 1.);
	cairo_stroke_preserve (pCairoContext);
	cairo_set_source_rgba (pCairoContext, 1., 1., 1., .7);
	cairo_fill (pCairoContext);
	
	cairo_translate (pCairoContext, 0, iHeight - iTopMargin - 2*fLineWidth - iBottomMargin + GAP);
	cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, iWidth - 2 * fRadius - fLineWidth, iBottomMargin - GAP - fLineWidth);
	cairo_set_source_rgba (pCairoContext, .8, .8, 1., 1.);
	cairo_stroke_preserve (pCairoContext);
	cairo_set_source_rgba (pCairoContext, 1., 1., 1., .7);
	cairo_fill (pCairoContext);
	cairo_restore (pCairoContext);
	
	PangoLayout *pLayout = pango_cairo_create_layout (pCairoContext);
	PangoFontDescription *pDesc = pango_font_description_new ();
	
	pango_font_description_set_absolute_size (pDesc, myDialogs.dialogTextDescription.iSize * PANGO_SCALE);
	pango_font_description_set_family_static (pDesc, myDialogs.dialogTextDescription.cFont);
	pango_font_description_set_weight (pDesc, myDialogs.dialogTextDescription.iWeight);
	pango_font_description_set_style (pDesc, myLabels.iconTextDescription.iStyle);
	pango_layout_set_font_description (pLayout, pDesc);
	pango_font_description_free (pDesc);
	
	// on dessine les entrees.
	if (pListing->pEntries != NULL)
	{
		// on dessine chaque entree.
		int iNbSteps = _listing_compute_nb_steps (pListing);  // nb d'etapes pour l'apparition du texte.
		int iOffsetX = NB_STEPS_FOR_1_ENTRY - (iNbSteps - pListing->iAppearanceAnimationCount) - 1;
		if (pListing->iNbEntries >= myConfig.iNbLinesInListing)
			iOffsetX += myConfig.iNbLinesInListing/4*NB_STEPS_LATE;  // permet de donner une transparence aux 25% dernieres lignes.
		double dx, dy, dm = myConfig.iNbLinesInListing * (myDialogs.dialogTextDescription.iSize + 2) / 2;
		dm = 0;
		dy = iTopMargin - pListing->fCurrentOffset + 1 + dm;
		double ymax = MIN (iTopMargin + pListing->iNbEntries * (myDialogs.dialogTextDescription.iSize + 2), iHeight - iBottomMargin);
		GList *e;
		for (e = pListing->pEntries; e != NULL; e = e->next)
		{
			if (iOffsetX >= NB_STEPS_FOR_1_ENTRY)  // en dehors a droite a partir de celui-ci.
				break ;
			pEntry = e->data;
			if (pEntry->bHidden)
				continue ;
			
			dx = myDialogs.dialogTextDescription.iSize + 2;  // marge a gauche.
			//if (iOffsetX > 0 && pListing->iAppearanceAnimationCount > 0)
			//	dx += (double) iOffsetX * (iWidth - (myDialogs.dialogTextDescription.iSize + 2)) / NB_STEPS_FOR_1_ENTRY;
			dy += (myDialogs.dialogTextDescription.iSize + 2);
			while (dy + myDialogs.dialogTextDescription.iSize + 2 <= iTopMargin + 1)
				dy += pListing->iNbEntries * (myDialogs.dialogTextDescription.iSize + 2);
			while (dy > ymax)
				dy -= pListing->iNbEntries * (myDialogs.dialogTextDescription.iSize + 2);
			if (dy > ymax || dy + myDialogs.dialogTextDescription.iSize + 2 <= iTopMargin + 1)
				continue;
			cairo_save (pCairoContext);
			cairo_translate (pCairoContext, dx, dy);
			
			// on fait un clip si necessaire.
			if (dy + myDialogs.dialogTextDescription.iSize + 2 > iHeight - iBottomMargin || dy < iTopMargin)  // cette entree n'est que partiellement visible.
			{
				if (dy < iTopMargin)  // elle depasse en haut.
					cairo_rectangle (pCairoContext, -iLeftMargin, iTopMargin - dy, iWidth, myDialogs.dialogTextDescription.iSize + 2 -(iTopMargin - dy));
				else  // elle depasse en bas.
					cairo_rectangle (pCairoContext, -iLeftMargin, 0, iWidth, iHeight - iBottomMargin - dy);
				cairo_clip (pCairoContext);
			}
			
			// on dessine l'icone.
			if (pEntry->pIconSurface != NULL)
			{
				cairo_set_source_surface (pCairoContext, pEntry->pIconSurface, - iLeftMargin + 1, 0.);
				cairo_paint (pCairoContext);
			}
			
			// on souligne l'entree courante.
			if (e == pListing->pCurrentEntry)
			{
				double f = 1. - (double) pListing->iCurrentEntryAnimationCount / NB_STEPS_FOR_CURRENT_ENTRY;
				if (f != 0)
				{
					cairo_save (pCairoContext);
					double rx = .5*(iWidth - iLeftMargin - iRightMargin);
					double ry = .5*(myDialogs.dialogTextDescription.iSize + 2);
					cairo_pattern_t *pPattern = cairo_pattern_create_radial (ry,
						ry,
						0.,
						ry,
						ry,
						f * ry);
					cairo_pattern_set_extend (pPattern, CAIRO_EXTEND_NONE);
					
					cairo_pattern_add_color_stop_rgba (pPattern,
						0.,
						0., 0., 1., .3);
					cairo_pattern_add_color_stop_rgba (pPattern,
						1.,
						0., 0., 0., 0.);
					cairo_scale (pCairoContext, rx/ry, 1.);
					cairo_set_source (pCairoContext, pPattern);
					cairo_paint (pCairoContext);
					cairo_pattern_destroy (pPattern);
					cairo_restore (pCairoContext);
					
					// on dessine l'indicateur de sous-listing.
					if (pEntry->list != NULL)
					{
						cairo_set_source_rgba (pCairoContext, 0., 0., 0., f);
						cairo_move_to (pCairoContext, iWidth - iLeftMargin - iRightMargin, myDialogs.dialogTextDescription.iSize/4);
						cairo_rel_line_to (pCairoContext, iRightMargin, myDialogs.dialogTextDescription.iSize/4);
						cairo_rel_line_to (pCairoContext, -iRightMargin, myDialogs.dialogTextDescription.iSize/4);
						cairo_close_path (pCairoContext);
						cairo_stroke (pCairoContext);
					}
				}
			}
			
			// on dessine le texte.
			cairo_set_source_rgba (pCairoContext, 0., 0., 0., 1. - (double) iOffsetX / NB_STEPS_FOR_1_ENTRY);
			pango_layout_set_text (pLayout, pEntry->cName, -1);
			pango_cairo_show_layout (pCairoContext, pLayout);
			
			// on separe la 1ere entree de la derniere.
			if (e->prev == NULL)
			{
				cairo_set_source_rgba (pCairoContext, 0., 0., 0., .5);
				cairo_move_to (pCairoContext, 0., 1.);
				cairo_rel_line_to (pCairoContext, iWidth - iLeftMargin - iRightMargin, 0.);
				double dashes = 2.;
				cairo_set_dash (pCairoContext, &dashes, 1, 0.);
				cairo_stroke (pCairoContext);
				cairo_set_dash (pCairoContext, &dashes, 0, 0.);
			}
			
			cairo_restore (pCairoContext);
			iOffsetX += NB_STEPS_LATE;
		}
		
		// on dessine le chemin de l'entree courante.
		if (pListing->pCurrentEntry)
		{
			pEntry = pListing->pCurrentEntry->data;
			cairo_save (pCairoContext);
			cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
			cairo_translate (pCairoContext, fRadius - pListing->iTitleOffset, 0.);
			pango_layout_set_text (pLayout, pEntry->cPath ? pEntry->cPath : pEntry->cName, -1);
			PangoRectangle ink, log;
			pango_layout_get_pixel_extents (pLayout, &ink, &log);
			pListing->iTitleWidth = ink.width;
			pango_cairo_show_layout (pCairoContext, pLayout);
			cairo_restore (pCairoContext);
		}
	}
	
	// on dessine l'etat de la recherche.
	cairo_translate (pCairoContext, 0, iHeight - iBottomMargin);
	cairo_set_source_surface (pCairoContext, myData.pScoobySurface, 0., 0.);
	cairo_paint (pCairoContext);
	
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	cairo_translate (pCairoContext, 2 * (myDialogs.dialogTextDescription.iSize + 2), GAP);
	if (myData.cStatus != NULL)
	{
		pango_layout_set_text (pLayout, myData.cStatus, -1);
	}
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	// on dessine le filtre.
	cairo_translate (pCairoContext, 0., myDialogs.dialogTextDescription.iSize + 2);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_MATCH_CASE) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F1) Match case"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	cairo_translate (pCairoContext, iWidth/3, 0.);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_MUSIC) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F2) Music"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	cairo_translate (pCairoContext, iWidth/3, 0.);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_IMAGE) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F3) Image"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	cairo_translate (pCairoContext, -2*iWidth/3, myDialogs.dialogTextDescription.iSize + 2);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_VIDEO) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F4) Video"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	cairo_translate (pCairoContext, iWidth/3, 0.);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_TEXT) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F5) Text"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	cairo_translate (pCairoContext, iWidth/3, 0.);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_HTML) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F6) Html"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	cairo_translate (pCairoContext, -2*iWidth/3, myDialogs.dialogTextDescription.iSize + 2);
	cairo_set_source_surface (pCairoContext, (myData.iCurrentFilter & DO_TYPE_SOURCE) ? myData.pActiveButtonSurface : myData.pInactiveButtonSurface, 0., 0.);
	cairo_paint (pCairoContext);
	cairo_set_source_rgb (pCairoContext, 0., 0., 0.);
	pango_layout_set_text (pLayout, D_("(F7) Sources"), -1);
	pango_cairo_show_layout (pCairoContext, pLayout);
	
	g_object_unref (pLayout);
}
コード例 #20
0
void
html_engine_draw_cursor_in_area (HTMLEngine *engine,
                                 gint x,
                                 gint y,
                                 gint width,
                                 gint height)
{
	HTMLObject *obj;
	guint offset;
	gint x1, y1, x2, y2, sc_x, sc_y;
	GdkRectangle pos;
	GtkAdjustment *hadj, *vadj;

	if ((engine->editable || engine->caret_mode) && (engine->cursor_hide_count <= 0 && !engine->thaw_idle_id)) {
		html_engine_draw_table_cursor (engine);
		html_engine_draw_cell_cursor (engine);
		html_engine_draw_image_cursor (engine);
	}

	if (!cursor_enabled || engine->cursor_hide_count > 0 || !(engine->editable || engine->caret_mode) || engine->thaw_idle_id)
		return;

	obj = engine->cursor->object;
	if (obj == NULL || engine->window == NULL)
		return;

	offset = engine->cursor->offset;

	if (width < 0 || height < 0) {
		width = html_engine_get_doc_width (engine);
		height = html_engine_get_doc_height (engine);
		x = 0;
		y = 0;
	}

	html_object_get_cursor (obj, engine->painter, offset, &x1, &y1, &x2, &y2);
	while (obj) {
		if (html_object_is_frame (obj)) {
			x1 -= HTML_EMBEDDED (obj)->abs_x;
			x2 -= HTML_EMBEDDED (obj)->abs_x;
			y1 -= HTML_EMBEDDED (obj)->abs_y;
			y2 -= HTML_EMBEDDED (obj)->abs_y;
			break;
		}
		obj = obj->parent;
	}

	/* get scroll offset */
	hadj = gtk_layout_get_hadjustment (GTK_LAYOUT (engine->widget));
	vadj = gtk_layout_get_vadjustment (GTK_LAYOUT (engine->widget));
	sc_x = (gint) gtk_adjustment_get_value (hadj);
	sc_y = (gint) gtk_adjustment_get_value (vadj);

	pos.x = x1 - sc_x;
	pos.y = y1 - sc_y;
	pos.width = x2 - x1;
	pos.height = y2 - y1;

	gtk_im_context_set_cursor_location (GTK_HTML (engine->widget)->priv->im_context, &pos);

	if (clip_cursor (engine, x, y, width, height, &x1, &y1, &x2, &y2)) {
		cairo_t *cr;
		gboolean using_painter_cr;

		using_painter_cr = engine->painter &&
		    HTML_IS_GDK_PAINTER (engine->painter) &&
		    HTML_GDK_PAINTER (engine->painter)->cr != NULL;

		if (using_painter_cr) {
			HTMLGdkPainter *gdk_painter = HTML_GDK_PAINTER (engine->painter);

			cr = gdk_painter->cr;
			cairo_save (cr);

			x1 -= gdk_painter->x1;
			y1 -= gdk_painter->y1;
			x2 -= gdk_painter->x1;
			y2 -= gdk_painter->y1;
		} else {
			cr = gdk_cairo_create (engine->window);
		}

		cairo_set_source_rgb (cr, 1, 1, 1);
		cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
		cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
		cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
		cairo_line_to (cr, x2 + 0.5, y2 - 0.5);
		cairo_set_line_width (cr, 1);
		cairo_stroke (cr);

		if (using_painter_cr)
			cairo_restore (cr);
		else
			cairo_destroy (cr);
	}
}
コード例 #21
0
ファイル: timebar.c プロジェクト: sergei-dyshel/workrave
static void set_color(cairo_t *cr, GdkRGBA color)
{
  cairo_set_source_rgb(cr, color.red, color.green, color.blue);
}
コード例 #22
0
void draw_background(LoadGraph *g) {
	double dash[2] = { 1.0, 2.0 };
	cairo_t *cr;
	guint i;
	unsigned num_bars;
	char *caption;
	cairo_text_extents_t extents;

	num_bars = g->num_bars();
	g->graph_dely = (g->draw_height - 15) / num_bars; /* round to int to avoid AA blur */
	g->real_draw_height = g->graph_dely * num_bars;
	g->graph_delx = (g->draw_width - 2.0 - g->rmargin - g->indent) / (LoadGraph::NUM_POINTS - 3);
	g->graph_buffer_offset = (int) (1.5 * g->graph_delx) + FRAME_WIDTH ;

	g->background = gdk_pixmap_new (GDK_DRAWABLE (g->disp->window),
					g->disp->allocation.width,
					g->disp->allocation.height,
					-1);
	cr = gdk_cairo_create (g->background);
	
	// set the background colour
	GtkStyle *style = gtk_widget_get_style (ProcData::get_instance()->notebook);
	gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_NORMAL]);
	cairo_paint (cr);

	/* draw frame */
	cairo_translate (cr, FRAME_WIDTH, FRAME_WIDTH);
	
	/* Draw background rectangle */
	cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
	cairo_rectangle (cr, g->rmargin + g->indent, 0,
			 g->draw_width - g->rmargin - g->indent, g->real_draw_height);
	cairo_fill(cr);
	
	cairo_set_line_width (cr, 1.0);
	cairo_set_dash (cr, dash, 2, 0);
	cairo_set_font_size (cr, g->fontsize);

	for (i = 0; i <= num_bars; ++i) {
		double y;

		if (i == 0)
			y = 0.5 + g->fontsize / 2.0;
		else if (i == num_bars)
			y = i * g->graph_dely + 0.5;
		else
			y = i * g->graph_dely + g->fontsize / 2.0;

		gdk_cairo_set_source_color (cr, &style->fg[GTK_STATE_NORMAL]);
		if (g->type == LOAD_GRAPH_NET) {
			// operation orders matters so it's 0 if i == num_bars
			unsigned rate = g->net.max - (i * g->net.max / num_bars);
			const std::string caption(procman::format_rate(rate, g->net.max));
			cairo_text_extents (cr, caption.c_str(), &extents);
			cairo_move_to (cr, g->indent - extents.width + 20, y);
			cairo_show_text (cr, caption.c_str());
		} else {
			// operation orders matters so it's 0 if i == num_bars
			caption = g_strdup_printf("%d %%", 100 - i * (100 / num_bars));
			cairo_text_extents (cr, caption, &extents);
			cairo_move_to (cr, g->indent - extents.width + 20, y);
			cairo_show_text (cr, caption);
			g_free (caption);
		}

		cairo_set_source_rgba (cr, 0, 0, 0, 0.75);
		cairo_move_to (cr, g->rmargin + g->indent - 3, i * g->graph_dely + 0.5);
		cairo_line_to (cr, g->draw_width - 0.5, i * g->graph_dely + 0.5);
	}
	cairo_stroke (cr);

	cairo_set_dash (cr, dash, 2, 1.5);

	const unsigned total_seconds = g->speed * (LoadGraph::NUM_POINTS - 2) / 1000;

	for (unsigned int i = 0; i < 7; i++) {
		double x = (i) * (g->draw_width - g->rmargin - g->indent) / 6;
		cairo_set_source_rgba (cr, 0, 0, 0, 0.75);
		cairo_move_to (cr, (ceil(x) + 0.5) + g->rmargin + g->indent, 0.5);
		cairo_line_to (cr, (ceil(x) + 0.5) + g->rmargin + g->indent, g->real_draw_height + 4.5);
		cairo_stroke(cr);
		unsigned seconds = total_seconds - i * total_seconds / 6;
		const char* format;
		if (i == 0)
			format = dngettext(GETTEXT_PACKAGE, "%u second", "%u seconds", seconds);
		else
			format = "%u";
		caption = g_strdup_printf(format, seconds);
		cairo_text_extents (cr, caption, &extents);
		cairo_move_to (cr, ((ceil(x) + 0.5) + g->rmargin + g->indent) - (extents.width/2), g->draw_height);
		gdk_cairo_set_source_color (cr, &style->fg[GTK_STATE_NORMAL]);
		cairo_show_text (cr, caption);
		g_free (caption);
	}

	cairo_stroke (cr);
	cairo_destroy (cr);
}
コード例 #23
0
static void
generate_reference (double ppi_x, double ppi_y, const char *filename)
{
    cairo_surface_t *surface, *target;
    cairo_t *cr;
    cairo_status_t status;

    surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
	                                  SIZE*ppi_x/72, SIZE*ppi_y/72);
    cr = cairo_create (surface);
    cairo_surface_destroy (surface);

    /* As we wish to mimic a PDF surface, copy across the default font options
     * from the PDF backend.
     */
    {
	cairo_surface_t *pdf;
	cairo_font_options_t *options;

	options = cairo_font_options_create ();

#if CAIRO_HAS_PDF_SURFACE
	pdf = cairo_pdf_surface_create ("tmp.pdf", 1, 1);
	cairo_surface_get_font_options (pdf, options);
	cairo_surface_destroy (pdf);
#endif

	cairo_set_font_options (cr, options);
	cairo_font_options_destroy (options);
    }

#if SET_TOLERANCE
    cairo_set_tolerance (cr, 3.0);
#endif

    cairo_save (cr); {
	cairo_set_source_rgb (cr, 1, 1, 1);
	cairo_paint (cr);
    } cairo_restore (cr);

    cairo_scale (cr, ppi_x/72., ppi_y/72.);
    draw (cr, SIZE, SIZE);

    surface = cairo_surface_reference (cairo_get_target (cr));
    cairo_destroy (cr);

    target = cairo_image_surface_create (CAIRO_FORMAT_RGB24, SIZE, SIZE);
    cr = cairo_create (target);
    cairo_scale (cr, 72./ppi_x, 72./ppi_y);
    cairo_set_source_surface (cr, surface, 0, 0);
    cairo_paint (cr);

    status = cairo_surface_write_to_png (cairo_get_target (cr), filename);
    cairo_destroy (cr);

    if (status) {
	fprintf (stderr, "Failed to generate reference image '%s': %s\n",
		 filename, cairo_status_to_string (status));
	exit (1);
    }
}
コード例 #24
0
ファイル: ch6-overlay.c プロジェクト: kazutomi/xiphqt
void clear_surface(cairo_surface_t *cs){
  cairo_t *c = cairo_create(cs);
  cairo_set_source_rgb(c,1.,1.,1.);
  cairo_paint(c);
  cairo_destroy(c);
}
コード例 #25
0
static void
draw (cairo_t *cr, double width, double height)
{
    const char *text = "cairo";
    cairo_text_extents_t extents;
    const double dash[2] = { 8, 16 };
    cairo_pattern_t *pattern;

    cairo_save (cr);

    cairo_new_path (cr);

    cairo_set_line_width (cr, .05 * SIZE / 2.0);

    cairo_arc (cr, SIZE / 2.0, SIZE / 2.0,
	       0.875 * SIZE / 2.0,
	       0, 2.0 * M_PI);
    cairo_stroke (cr);

    /* use dashes to demonstrate bugs:
     *  https://bugs.freedesktop.org/show_bug.cgi?id=9189
     *  https://bugs.freedesktop.org/show_bug.cgi?id=17223
     */
    cairo_save (cr);
    cairo_set_dash (cr, dash, 2, 0);
    cairo_arc (cr, SIZE / 2.0, SIZE / 2.0,
	       0.75 * SIZE / 2.0,
	       0, 2.0 * M_PI);
    cairo_stroke (cr);
    cairo_restore (cr);

    cairo_save (cr);
    cairo_rectangle (cr, 0, 0, SIZE/2, SIZE);
    cairo_clip (cr);
    cairo_arc (cr, SIZE / 2.0, SIZE / 2.0,
	       0.6 * SIZE / 2.0,
	       0, 2.0 * M_PI);
    cairo_fill (cr);
    cairo_restore (cr);

    /* use a pattern to exercise bug:
     *   https://bugs.launchpad.net/inkscape/+bug/234546
     */
    cairo_save (cr);
    cairo_rectangle (cr, SIZE/2, 0, SIZE/2, SIZE);
    cairo_clip (cr);
    pattern = cairo_pattern_create_linear (SIZE/2, 0, SIZE, 0);
    cairo_pattern_add_color_stop_rgba (pattern, 0, 0, 0, 0, 1.);
    cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 0, 0.);
    cairo_set_source (cr, pattern);
    cairo_pattern_destroy (pattern);
    cairo_arc (cr, SIZE / 2.0, SIZE / 2.0,
	       0.6 * SIZE / 2.0,
	       0, 2.0 * M_PI);
    cairo_fill (cr);
    cairo_restore (cr);

    cairo_set_source_rgb (cr, 1, 1, 1); /* white */
    cairo_set_font_size (cr, .25 * SIZE / 2.0);
    cairo_text_extents (cr, text, &extents);
    cairo_move_to (cr, (SIZE-extents.width)/2.0-extents.x_bearing,
		       (SIZE-extents.height)/2.0-extents.y_bearing);
    cairo_show_text (cr, text);

    cairo_restore (cr);
}
コード例 #26
0
/**
 * ags_note_edit_draw_segment:
 * @note_edit: the #AgsNoteEdit
 * @cr: the #cairo_t surface
 *
 * Draws horizontal and vertical lines.
 *
 * Since: 0.4
 */
void
ags_note_edit_draw_segment(AgsNoteEdit *note_edit, cairo_t *cr)
{
  AgsEditor *editor;
  GtkWidget *widget;
  double tact;
  guint i, j;
  guint j_set;

  widget = (GtkWidget *) note_edit->drawing_area;

  editor = (AgsEditor *) gtk_widget_get_ancestor(GTK_WIDGET(note_edit),
						 AGS_TYPE_EDITOR);

  cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
  cairo_rectangle(cr, 0.0, 0.0, (double) widget->allocation.width, (double) widget->allocation.height);
  cairo_fill(cr);

  cairo_set_line_width(cr, 1.0);

  cairo_set_source_rgb(cr, 0.8, 0.8, 0.8);

  for(i = note_edit->y0 ; i < note_edit->height;){
    cairo_move_to(cr, 0.0, (double) i);
    cairo_line_to(cr, (double) note_edit->width, (double) i);
    cairo_stroke(cr);

    i += note_edit->control_height;
  }

  cairo_move_to(cr, 0.0, (double) i);
  cairo_line_to(cr, (double) note_edit->width, (double) i);
  cairo_stroke(cr);

  tact = exp2((double) gtk_combo_box_get_active(editor->toolbar->zoom) - 4.0);

  i = note_edit->control_current.x0;
  
  if(i < note_edit->width &&
     tact > 1.0 ){
    j_set = note_edit->control_current.nth_x % ((guint) tact);
    cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);

    if(j_set != 0){
      j = j_set;
      goto ags_note_edit_draw_segment0;
    }
  }

  for(; i < note_edit->width; ){
    cairo_set_source_rgb(cr, 1.0, 1.0, 0.0);
    
    cairo_move_to(cr, (double) i, 0.0);
    cairo_line_to(cr, (double) i, (double) note_edit->height);
    cairo_stroke(cr);
    
    i += note_edit->control_current.control_width;
    
    cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
    
    for(j = 1; i < note_edit->width && j < tact; j++){
    ags_note_edit_draw_segment0:
      cairo_move_to(cr, (double) i, 0.0);
      cairo_line_to(cr, (double) i, (double) note_edit->height);
      cairo_stroke(cr);
      
      i += note_edit->control_current.control_width;
    }
  }
}
コード例 #27
0
ファイル: gimpviewrenderer.c プロジェクト: ni1son/gimp
static void
gimp_view_render_temp_buf_to_surface (GimpViewRenderer *renderer,
                                      GtkWidget        *widget,
                                      GimpTempBuf      *temp_buf,
                                      gint              temp_buf_x,
                                      gint              temp_buf_y,
                                      gint              channel,
                                      GimpViewBG        inside_bg,
                                      GimpViewBG        outside_bg,
                                      cairo_surface_t  *surface,
                                      gint              surface_width,
                                      gint              surface_height)
{
  cairo_t    *cr;
  gint        x, y;
  gint        width, height;
  const Babl *temp_buf_format;
  gint        temp_buf_width;
  gint        temp_buf_height;

  g_return_if_fail (temp_buf != NULL);
  g_return_if_fail (surface != NULL);

  temp_buf_format = gimp_temp_buf_get_format (temp_buf);
  temp_buf_width  = gimp_temp_buf_get_width  (temp_buf);
  temp_buf_height = gimp_temp_buf_get_height (temp_buf);

  /*  Here are the different cases this functions handles correctly:
   *  1)  Offset temp_buf which does not necessarily cover full image area
   *  2)  Color conversion of temp_buf if it is gray and image is color
   *  3)  Background check buffer for transparent temp_bufs
   *  4)  Using the optional "channel" argument, one channel can be extracted
   *      from a multi-channel temp_buf and composited as a grayscale
   *  Prereqs:
   *  1)  Grayscale temp_bufs have bytes == {1, 2}
   *  2)  Color temp_bufs have bytes == {3, 4}
   *  3)  If image is gray, then temp_buf should have bytes == {1, 2}
   */

  cr = cairo_create (surface);

  if (outside_bg == GIMP_VIEW_BG_CHECKS ||
      inside_bg  == GIMP_VIEW_BG_CHECKS)
    {
      if (! renderer->pattern)
        renderer->pattern =
          gimp_cairo_checkerboard_create (cr, GIMP_CHECK_SIZE_SM,
                                          gimp_render_light_check_color (),
                                          gimp_render_dark_check_color ());
    }

  switch (outside_bg)
    {
    case GIMP_VIEW_BG_CHECKS:
      cairo_set_source (cr, renderer->pattern);
      break;

    case GIMP_VIEW_BG_WHITE:
      cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
      break;
    }

  cairo_paint (cr);

  if (! gimp_rectangle_intersect (0, 0,
                                  surface_width, surface_height,
                                  temp_buf_x, temp_buf_y,
                                  temp_buf_width, temp_buf_height,
                                  &x, &y,
                                  &width, &height))
    {
      cairo_destroy (cr);
      return;
    }

  if (inside_bg != outside_bg &&
      babl_format_has_alpha (temp_buf_format) && channel == -1)
    {
      cairo_rectangle (cr, x, y, width, height);

      switch (inside_bg)
        {
        case GIMP_VIEW_BG_CHECKS:
          cairo_set_source (cr, renderer->pattern);
          break;

        case GIMP_VIEW_BG_WHITE:
          cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
          break;
        }

      cairo_fill (cr);
    }

  if (babl_format_has_alpha (temp_buf_format) && channel == -1)
    {
      GeglBuffer      *src_buffer;
      GeglBuffer      *dest_buffer;
      cairo_surface_t *alpha_surface;

      alpha_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                                  width, height);

      src_buffer  = gimp_temp_buf_create_buffer (temp_buf);
      dest_buffer = gimp_cairo_surface_create_buffer (alpha_surface);

      if (! renderer->profile_transform)
        gimp_view_renderer_transform_create (renderer, widget,
                                             src_buffer, dest_buffer);

      if (renderer->profile_transform)
        {
          gimp_gegl_convert_color_transform (src_buffer,
                                             GEGL_RECTANGLE (x - temp_buf_x,
                                                             y - temp_buf_y,
                                                             width, height),
                                             renderer->profile_src_format,
                                             dest_buffer,
                                             GEGL_RECTANGLE (0, 0, 0, 0),
                                             renderer->profile_dest_format,
                                             renderer->profile_transform);
        }
      else
        {
          gegl_buffer_copy (src_buffer,
                            GEGL_RECTANGLE (x - temp_buf_x,
                                            y - temp_buf_y,
                                            width, height),
                            GEGL_ABYSS_NONE,
                            dest_buffer,
                            GEGL_RECTANGLE (0, 0, 0, 0));
        }

      g_object_unref (src_buffer);
      g_object_unref (dest_buffer);

      cairo_surface_mark_dirty (alpha_surface);

      cairo_translate (cr, x, y);
      cairo_rectangle (cr, 0, 0, width, height);
      cairo_set_source_surface (cr, alpha_surface, 0, 0);
      cairo_fill (cr);

      cairo_surface_destroy (alpha_surface);
    }
  else if (channel == -1)
    {
      GeglBuffer *src_buffer;
      GeglBuffer *dest_buffer;

      cairo_surface_flush (surface);

      src_buffer  = gimp_temp_buf_create_buffer (temp_buf);
      dest_buffer = gimp_cairo_surface_create_buffer (surface);

      if (! renderer->profile_transform)
        gimp_view_renderer_transform_create (renderer, widget,
                                             src_buffer, dest_buffer);

      if (renderer->profile_transform)
        {
          gimp_gegl_convert_color_transform (src_buffer,
                                             GEGL_RECTANGLE (x - temp_buf_x,
                                                             y - temp_buf_y,
                                                             width, height),
                                             renderer->profile_src_format,
                                             dest_buffer,
                                             GEGL_RECTANGLE (x, y, 0, 0),
                                             renderer->profile_dest_format,
                                             renderer->profile_transform);
        }
      else
        {
          gegl_buffer_copy (src_buffer,
                            GEGL_RECTANGLE (x - temp_buf_x,
                                            y - temp_buf_y,
                                            width, height),
                            GEGL_ABYSS_NONE,
                            dest_buffer,
                            GEGL_RECTANGLE (x, y, 0, 0));
        }

      g_object_unref (src_buffer);
      g_object_unref (dest_buffer);

      cairo_surface_mark_dirty (surface);
    }
  else
    {
      const Babl   *fish;
      const guchar *src;
      guchar       *dest;
      gint          dest_stride;
      gint          bytes;
      gint          rowstride;
      gint          i;

      cairo_surface_flush (surface);

      bytes     = babl_format_get_bytes_per_pixel (temp_buf_format);
      rowstride = temp_buf_width * bytes;

      src = gimp_temp_buf_get_data (temp_buf) + ((y - temp_buf_y) * rowstride +
                                                 (x - temp_buf_x) * bytes);

      dest        = cairo_image_surface_get_data (surface);
      dest_stride = cairo_image_surface_get_stride (surface);

      dest += y * dest_stride + x * 4;

      fish = babl_fish (temp_buf_format,
                        babl_format ("cairo-RGB24"));

      for (i = y; i < (y + height); i++)
        {
          const guchar *s = src;
          guchar       *d = dest;
          gint          j;

          for (j = x; j < (x + width); j++, d += 4, s += bytes)
            {
              if (bytes > 2)
                {
                  guchar pixel[4] = { s[channel], s[channel], s[channel], 255 };

                  babl_process (fish, pixel, d, 1);
                }
              else
                {
                  guchar pixel[2] = { s[channel], 255 };

                  babl_process (fish, pixel, d, 1);
                }
            }

          src += rowstride;
          dest += dest_stride;
        }

      cairo_surface_mark_dirty (surface);
    }

  cairo_destroy (cr);
}
コード例 #28
0
/**
 * ags_note_edit_draw_notation:
 * @note_edit: the #AgsNoteEdit
 * @cr: the #cairo_t surface
 *
 * Draw the #AgsNotation of selected #AgsMachine on @note_edit.
 *
 * Since: 0.4
 */
void
ags_note_edit_draw_notation(AgsNoteEdit *note_edit, cairo_t *cr)
{
  AgsMachine *machine;
  AgsEditor *editor;
  GtkWidget *widget;
  AgsNote *note;
  GList *list_notation, *list_note;
  guint x_offset;
  guint control_height;
  guint x, y, width, height;
  gint selected_channel;
  gint i;

  editor = (AgsEditor *) gtk_widget_get_ancestor(GTK_WIDGET(note_edit),
						 AGS_TYPE_EDITOR);

  if(editor->selected_machine == NULL ||
     (machine = editor->selected_machine) == NULL ||
     machine->audio->notation == NULL)
    return;

  widget = (GtkWidget *) note_edit->drawing_area;

  cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);

  i = 0;

  while((selected_channel = ags_notebook_next_active_tab(editor->notebook,
							 i)) != -1){
    list_notation = g_list_nth(machine->audio->notation,
			       selected_channel);
    list_note = AGS_NOTATION(list_notation->data)->notes;

    control_height = note_edit->control_height - 2 * note_edit->control_margin_y;

    x_offset = (guint) GTK_RANGE(note_edit->hscrollbar)->adjustment->value;

    /* draw controls smaller than note_edit->nth_x */
    while(list_note != NULL && (note = (AgsNote *) list_note->data)->x[0] < note_edit->control_unit.nth_x){
      if(note->x[1] >= note_edit->control_unit.nth_x){
	if(note->y >= note_edit->nth_y && note->y <= note_edit->stop_y){
	  x = 0;
	  y = (note->y - note_edit->nth_y) * note_edit->control_height + note_edit->y0 + note_edit->control_margin_y;

	  width = (guint) ((double) note->x[1] * note_edit->control_unit.control_width - (double) x_offset);

	  if(width > widget->allocation.width)
	    width = widget->allocation.width;

	  height = control_height;

	  /* draw note */
	  cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	  cairo_fill(cr);

	  /* check if note is selected */
	  if((AGS_NOTE_IS_SELECTED & (note->flags)) != 0){
	    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.7);

	    cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	    cairo_stroke(cr);

	    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
	  }
	}else if(note->y == (note_edit->nth_y - 1) && note_edit->y0 != 0){
	  if(note_edit->y0 > note_edit->control_margin_y){
	    x = 0;
	    width = (guint) ((double) note->x[1] * (double) note_edit->control_unit.control_width - x_offset);

	    if(width > widget->allocation.width)
	      width = widget->allocation.width;

	    if(note_edit->y0 > control_height + note_edit->control_margin_y){
	      y = note_edit->y0 - (control_height + note_edit->control_margin_y);
	      height = control_height;
	    }else{
	      y = 0;
	      height = note_edit->y0 - note_edit->control_margin_y;
	    }

	    /* draw note */
	    cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	    cairo_fill(cr);

	    /* check if note is selected */
	    if((AGS_NOTE_IS_SELECTED & (note->flags)) != 0){
	      cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.7);
	    
	      cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	      cairo_stroke(cr);
	    
	      cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
	    }
	  }
	}else if(note->y == (note_edit->stop_y + 1) && note_edit->y1 != 0){
	  if(note_edit->y1 > note_edit->control_margin_y){
	    x = 0;
	    width = note->x[1] * note_edit->control_unit.control_width - x_offset;

	    if(width > widget->allocation.width)
	      width = widget->allocation.width;

	    y = (note->y - note_edit->nth_y) * note_edit->control_height + note_edit->control_margin_y;

	    if(note_edit->y1 > control_height + note_edit->control_margin_y){
	      height = control_height;
	    }else{
	      height = note_edit->y1 - note_edit->control_margin_y;
	    }

	    /* draw note */
	    cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	    cairo_fill(cr);
	  
	    /* check if note is selected */
	    if((AGS_NOTE_IS_SELECTED & (note->flags)) != 0){
	      cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.7);
	    
	      cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	      cairo_stroke(cr);
	    
	      cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
	    }
	  }
	}
      }

      list_note = list_note->next;
    }

    /* draw controls equal or greater than note_edit->nth_x */
    while(list_note != NULL && (note = (AgsNote *) list_note->data)->x[0] <= note_edit->control_unit.stop_x){
      if(note->y >= note_edit->nth_y && note->y <= note_edit->stop_y){
	x = (guint) note->x[0] * note_edit->control_unit.control_width;
	y = (note->y - note_edit->nth_y) * note_edit->control_height +
	  note_edit->y0 +
	  note_edit->control_margin_y;

	width = note->x[1] * note_edit->control_unit.control_width - x;
	x -= x_offset;

	if(x + width > widget->allocation.width)
	  width = widget->allocation.width - x;

	height = control_height;

	/* draw note*/
	cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	cairo_fill(cr);

	/* check if note is selected */
	if((AGS_NOTE_IS_SELECTED & (note->flags)) != 0){
	  cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.7);
	
	  cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	  cairo_stroke(cr);
	
	  cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
	}
      }else if(note->y == (note_edit->nth_y - 1) && note_edit->y0 != 0){
	if(note_edit->y0 > note_edit->control_margin_y){
	  x = note->x[0] * note_edit->control_unit.control_width - x_offset;
	  width = note->x[1] * note_edit->control_unit.control_width - x_offset - x;
      
	  if(x + width > widget->allocation.width)
	    width = widget->allocation.width - x;

	  if(note_edit->y0 > control_height + note_edit->control_margin_y){
	    y = note_edit->y0 - (control_height + note_edit->control_margin_y);
	    height = control_height;
	  }else{
	    y = 0;
	    height = note_edit->y0 - note_edit->control_margin_y;
	  }

	  /* draw note */
	  cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	  cairo_fill(cr);

	  /* check if note is selected */
	  if((AGS_NOTE_IS_SELECTED & (note->flags)) != 0){
	    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.7);

	    cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	    cairo_stroke(cr);

	    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
	  }
	}
      }else if(note->y == (note_edit->stop_y + 1) && note_edit->y1 != 0){
	if(note_edit->y1 > note_edit->control_margin_y){
	  x = note->x[0] * note_edit->control_unit.control_width - x_offset;
	  width = note->x[1] * note_edit->control_unit.control_width - x_offset - x;
      
	  if(x + width > widget->allocation.width)
	    width = widget->allocation.width - x;

	  y = (note->y - note_edit->nth_y) * note_edit->control_height + note_edit->control_margin_y;

	  if(note_edit->y1 > control_height + note_edit->control_margin_y){
	    height = control_height;
	  }else{
	    height = note_edit->y1 - note_edit->control_margin_y;
	  }

	  /* draw note */
	  cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	  cairo_fill(cr);

	  /* check if note is selected */
	  if((AGS_NOTE_IS_SELECTED & (note->flags)) != 0){
	    cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 0.7);

	    cairo_rectangle(cr, (double) x, (double) y, (double) width, (double) height);
	    cairo_stroke(cr);

	    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
	  }
	}
      }

      list_note = list_note->next;
    }

    i++;
  }
}
コード例 #29
0
ファイル: live_view.c プロジェクト: CarVac/darktable
/*
    This file is part of darktable,
    copyright (c) 2009--2011 johannes hanika.
    copyright (c) 2012 tobias ellinghaus.
    copyright (c) 2014 henrik andersson.

    darktable is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    darktable is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with darktable.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "bauhaus/bauhaus.h"
#include "common/camera_control.h"
#include "common/darktable.h"
#include "common/image_cache.h"
#include "common/mipmap_cache.h"
#include "control/conf.h"
#include "control/control.h"
#include "control/jobs.h"
#include "dtgtk/button.h"
#include "gui/accelerators.h"
#include "gui/gtk.h"
#include "gui/guides.h"
#include "libs/lib.h"
#include "libs/lib_api.h"
#include <gdk/gdkkeysyms.h>

typedef enum dt_lib_live_view_flip_t
{
  FLAG_FLIP_NONE = 0,
  FLAG_FLIP_HORIZONTAL = 1<<0,
  FLAG_FLIP_VERTICAL = 1<<1,
  FLAG_FLIP_BOTH = FLAG_FLIP_HORIZONTAL|FLAG_FLIP_VERTICAL
} dt_lib_live_view_flip_t;

typedef enum dt_lib_live_view_overlay_t
{
  OVERLAY_NONE = 0,
  OVERLAY_SELECTED,
  OVERLAY_ID
} dt_lib_live_view_overlay_t;

#define HANDLE_SIZE 0.02

static const cairo_operator_t _overlay_modes[] = {
  CAIRO_OPERATOR_OVER, CAIRO_OPERATOR_XOR, CAIRO_OPERATOR_ADD, CAIRO_OPERATOR_SATURATE
#if(CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0))
  ,
  CAIRO_OPERATOR_MULTIPLY, CAIRO_OPERATOR_SCREEN, CAIRO_OPERATOR_OVERLAY, CAIRO_OPERATOR_DARKEN,
  CAIRO_OPERATOR_LIGHTEN, CAIRO_OPERATOR_COLOR_DODGE, CAIRO_OPERATOR_COLOR_BURN, CAIRO_OPERATOR_HARD_LIGHT,
  CAIRO_OPERATOR_SOFT_LIGHT, CAIRO_OPERATOR_DIFFERENCE, CAIRO_OPERATOR_EXCLUSION, CAIRO_OPERATOR_HSL_HUE,
  CAIRO_OPERATOR_HSL_SATURATION, CAIRO_OPERATOR_HSL_COLOR, CAIRO_OPERATOR_HSL_LUMINOSITY
#endif
};

DT_MODULE(1)

typedef struct dt_lib_live_view_t
{
  int imgid;
  int splitline_rotation;
  double overlay_x0, overlay_x1, overlay_y0, overlay_y1;
  double splitline_x, splitline_y; // 0..1
  gboolean splitline_dragging;

  GtkWidget *live_view, *live_view_zoom, *rotate_ccw, *rotate_cw, *flip;
  GtkWidget *focus_out_small, *focus_out_big, *focus_in_small, *focus_in_big;
  GtkWidget *guide_selector, *flip_guides, *guides_widgets;
  GList *guides_widgets_list;
  GtkWidget *overlay, *overlay_id_box, *overlay_id, *overlay_mode, *overlay_splitline;
} dt_lib_live_view_t;

static void guides_presets_set_visibility(dt_lib_live_view_t *lib, int which)
{
  if(which == 0)
  {
    gtk_widget_set_no_show_all(lib->guides_widgets, TRUE);
    gtk_widget_hide(lib->guides_widgets);
    gtk_widget_set_no_show_all(lib->flip_guides, TRUE);
    gtk_widget_hide(lib->flip_guides);
  }
  else
  {
    GtkWidget *widget = g_list_nth_data(lib->guides_widgets_list, which - 1);
    if(widget)
    {
      gtk_widget_set_no_show_all(lib->guides_widgets, FALSE);
      gtk_widget_show_all(lib->guides_widgets);
      gtk_stack_set_visible_child(GTK_STACK(lib->guides_widgets), widget);
    }
    else
    {
      gtk_widget_set_no_show_all(lib->guides_widgets, TRUE);
      gtk_widget_hide(lib->guides_widgets);
    }
    gtk_widget_set_no_show_all(lib->flip_guides, FALSE);
    gtk_widget_show_all(lib->flip_guides);
  }

  // TODO: add a support_flip flag to guides to hide the flip gui?
}

static void guides_presets_changed(GtkWidget *combo, dt_lib_live_view_t *lib)
{
  int which = dt_bauhaus_combobox_get(combo);
  guides_presets_set_visibility(lib, which);
}

static void overlay_changed(GtkWidget *combo, dt_lib_live_view_t *lib)
{
  int which = dt_bauhaus_combobox_get(combo);
  if(which == OVERLAY_NONE)
  {
    gtk_widget_set_visible(GTK_WIDGET(lib->overlay_mode), FALSE);
    gtk_widget_set_visible(GTK_WIDGET(lib->overlay_splitline), FALSE);
  }
  else
  {
    gtk_widget_set_visible(GTK_WIDGET(lib->overlay_mode), TRUE);
    gtk_widget_set_visible(GTK_WIDGET(lib->overlay_splitline), TRUE);
  }

  if(which == OVERLAY_ID)
    gtk_widget_set_visible(GTK_WIDGET(lib->overlay_id_box), TRUE);
  else
    gtk_widget_set_visible(GTK_WIDGET(lib->overlay_id_box), FALSE);
}


const char *name(dt_lib_module_t *self)
{
  return _("live view");
}

uint32_t views(dt_lib_module_t *self)
{
  return DT_VIEW_TETHERING;
}

uint32_t container(dt_lib_module_t *self)
{
  return DT_UI_CONTAINER_PANEL_RIGHT_CENTER;
}


void gui_reset(dt_lib_module_t *self)
{
}

int position()
{
  return 998;
}

void init_key_accels(dt_lib_module_t *self)
{
  dt_accel_register_lib(self, NC_("accel", "toggle live view"), GDK_KEY_v, 0);
  dt_accel_register_lib(self, NC_("accel", "zoom live view"), GDK_KEY_z, 0);
  dt_accel_register_lib(self, NC_("accel", "rotate 90 degrees CCW"), 0, 0);
  dt_accel_register_lib(self, NC_("accel", "rotate 90 degrees CW"), 0, 0);
  dt_accel_register_lib(self, NC_("accel", "flip horizontally"), 0, 0);
  dt_accel_register_lib(self, NC_("accel", "move focus point in (big steps)"), 0, 0);
  dt_accel_register_lib(self, NC_("accel", "move focus point in (small steps)"), 0, 0);
  dt_accel_register_lib(self, NC_("accel", "move focus point out (small steps)"), 0, 0);
  dt_accel_register_lib(self, NC_("accel", "move focus point out (big steps)"), 0, 0);
}

void connect_key_accels(dt_lib_module_t *self)
{
  dt_lib_live_view_t *lib = (dt_lib_live_view_t *)self->data;

  dt_accel_connect_button_lib(self, "toggle live view", GTK_WIDGET(lib->live_view));
  dt_accel_connect_button_lib(self, "zoom live view", GTK_WIDGET(lib->live_view_zoom));
  dt_accel_connect_button_lib(self, "rotate 90 degrees CCW", GTK_WIDGET(lib->rotate_ccw));
  dt_accel_connect_button_lib(self, "rotate 90 degrees CW", GTK_WIDGET(lib->rotate_cw));
  dt_accel_connect_button_lib(self, "flip horizontally", GTK_WIDGET(lib->flip));
  dt_accel_connect_button_lib(self, "move focus point in (big steps)", GTK_WIDGET(lib->focus_in_big));
  dt_accel_connect_button_lib(self, "move focus point in (small steps)", GTK_WIDGET(lib->focus_in_small));
  dt_accel_connect_button_lib(self, "move focus point out (small steps)", GTK_WIDGET(lib->focus_out_small));
  dt_accel_connect_button_lib(self, "move focus point out (big steps)", GTK_WIDGET(lib->focus_out_big));
}

static void _rotate_ccw(GtkWidget *widget, gpointer user_data)
{
  dt_camera_t *cam = (dt_camera_t *)darktable.camctl->active_camera;
  cam->live_view_rotation = (cam->live_view_rotation + 1) % 4; // 0 -> 1 -> 2 -> 3 -> 0 -> ...
}

static void _rotate_cw(GtkWidget *widget, gpointer user_data)
{
  dt_camera_t *cam = (dt_camera_t *)darktable.camctl->active_camera;
  cam->live_view_rotation = (cam->live_view_rotation + 3) % 4; // 0 -> 3 -> 2 -> 1 -> 0 -> ...
}

// Congratulations to Simon for being the first one recognizing live view in a screen shot ^^
static void _toggle_live_view_clicked(GtkWidget *widget, gpointer user_data)
{
  if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == TRUE)
  {
    if(dt_camctl_camera_start_live_view(darktable.camctl) == FALSE)
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), FALSE);
  }
  else
  {
    dt_camctl_camera_stop_live_view(darktable.camctl);
  }
}

// TODO: using a toggle button would be better, but this setting can also be changed by right clicking on the
// canvas (src/views/capture.c).
//       maybe using a signal would work? i have no idea.
static void _zoom_live_view_clicked(GtkWidget *widget, gpointer user_data)
{
  dt_camera_t *cam = (dt_camera_t *)darktable.camctl->active_camera;
  if(cam->is_live_viewing)
  {
    cam->live_view_zoom = !cam->live_view_zoom;
    if(cam->live_view_zoom == TRUE)
      dt_camctl_camera_set_property_string(darktable.camctl, NULL, "eoszoom", "5");
    else
      dt_camctl_camera_set_property_string(darktable.camctl, NULL, "eoszoom", "1");
  }
}

static void _focus_button_clicked(GtkWidget *widget, gpointer user_data)
{
  int focus = GPOINTER_TO_INT(user_data);
  dt_camctl_camera_set_property_choice(darktable.camctl, NULL, "manualfocusdrive", focus);
}

static void _toggle_flip_clicked(GtkWidget *widget, gpointer user_data)
{
  dt_camera_t *cam = (dt_camera_t *)darktable.camctl->active_camera;
  cam->live_view_flip = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
}

static void _overlay_id_changed(GtkWidget *widget, gpointer user_data)
{
  dt_lib_live_view_t *lib = (dt_lib_live_view_t *)user_data;
  lib->imgid = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget));
  dt_conf_set_int("plugins/lighttable/live_view/overlay_imgid", lib->imgid);
}

static void _overlay_mode_changed(GtkWidget *combo, gpointer user_data)
{
  dt_conf_set_int("plugins/lighttable/live_view/overlay_mode", dt_bauhaus_combobox_get(combo));
}

static void _overlay_splitline_changed(GtkWidget *combo, gpointer user_data)
{
  dt_conf_set_int("plugins/lighttable/live_view/splitline", dt_bauhaus_combobox_get(combo));
}

void gui_init(dt_lib_module_t *self)
{
  self->data = calloc(1, sizeof(dt_lib_live_view_t));

  // Setup lib data
  dt_lib_live_view_t *lib = self->data;
  lib->splitline_x = lib->splitline_y = 0.5;

  // Setup gui
  self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
  GtkWidget *box;

  box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
  gtk_box_pack_start(GTK_BOX(self->widget), box, TRUE, TRUE, 0);
  lib->live_view = dtgtk_togglebutton_new(dtgtk_cairo_paint_eye, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER);
  lib->live_view_zoom = dtgtk_button_new(
      dtgtk_cairo_paint_zoom, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER); // TODO: see _zoom_live_view_clicked
  lib->rotate_ccw = dtgtk_button_new(dtgtk_cairo_paint_refresh, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER);
  lib->rotate_cw = dtgtk_button_new(dtgtk_cairo_paint_refresh,
                                    CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER | CPF_DIRECTION_UP);
  lib->flip = dtgtk_togglebutton_new(dtgtk_cairo_paint_flip,
                                     CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER | CPF_DIRECTION_UP);

  gtk_box_pack_start(GTK_BOX(box), lib->live_view, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(box), lib->live_view_zoom, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(box), lib->rotate_ccw, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(box), lib->rotate_cw, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(box), lib->flip, TRUE, TRUE, 0);

  gtk_widget_set_tooltip_text(lib->live_view, _("toggle live view"));
  gtk_widget_set_tooltip_text(lib->live_view_zoom, _("zoom live view"));
  gtk_widget_set_tooltip_text(lib->rotate_ccw, _("rotate 90 degrees ccw"));
  gtk_widget_set_tooltip_text(lib->rotate_cw, _("rotate 90 degrees cw"));
  gtk_widget_set_tooltip_text(lib->flip, _("flip live view horizontally"));

  g_signal_connect(G_OBJECT(lib->live_view), "clicked", G_CALLBACK(_toggle_live_view_clicked), lib);
  g_signal_connect(G_OBJECT(lib->live_view_zoom), "clicked", G_CALLBACK(_zoom_live_view_clicked), lib);
  g_signal_connect(G_OBJECT(lib->rotate_ccw), "clicked", G_CALLBACK(_rotate_ccw), lib);
  g_signal_connect(G_OBJECT(lib->rotate_cw), "clicked", G_CALLBACK(_rotate_cw), lib);
  g_signal_connect(G_OBJECT(lib->flip), "clicked", G_CALLBACK(_toggle_flip_clicked), lib);

  // focus buttons
  box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
  gtk_box_pack_start(GTK_BOX(self->widget), box, TRUE, TRUE, 0);
  lib->focus_in_big = dtgtk_button_new(dtgtk_cairo_paint_solid_triangle,
                                       CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER | CPF_DIRECTION_LEFT);
  lib->focus_in_small
      = dtgtk_button_new(dtgtk_cairo_paint_arrow, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER
                                                  | CPF_DIRECTION_LEFT); // TODO icon not centered
  lib->focus_out_small = dtgtk_button_new(dtgtk_cairo_paint_arrow, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER
                                                                   | CPF_DIRECTION_RIGHT); // TODO same here
  lib->focus_out_big = dtgtk_button_new(dtgtk_cairo_paint_solid_triangle,
                                        CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER | CPF_DIRECTION_RIGHT);

  gtk_box_pack_start(GTK_BOX(box), lib->focus_in_big, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(box), lib->focus_in_small, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(box), lib->focus_out_small, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(box), lib->focus_out_big, TRUE, TRUE, 0);

  gtk_widget_set_tooltip_text(lib->focus_in_big, _("move focus point in (big steps)"));
  gtk_widget_set_tooltip_text(lib->focus_in_small, _("move focus point in (small steps)"));
  gtk_widget_set_tooltip_text(lib->focus_out_small, _("move focus point out (small steps)"));
  gtk_widget_set_tooltip_text(lib->focus_out_big, _("move focus point out (big steps)"));

  // Near 3
  g_signal_connect(G_OBJECT(lib->focus_in_big), "clicked", G_CALLBACK(_focus_button_clicked),
                   GINT_TO_POINTER(2));
  // Near 1
  g_signal_connect(G_OBJECT(lib->focus_in_small), "clicked", G_CALLBACK(_focus_button_clicked),
                   GINT_TO_POINTER(0));
  // Far 1
  g_signal_connect(G_OBJECT(lib->focus_out_small), "clicked", G_CALLBACK(_focus_button_clicked),
                   GINT_TO_POINTER(4));
  // Far 3
  g_signal_connect(G_OBJECT(lib->focus_out_big), "clicked", G_CALLBACK(_focus_button_clicked),
                   GINT_TO_POINTER(6));

  // Guides
  lib->guide_selector = dt_bauhaus_combobox_new(NULL);
  dt_bauhaus_widget_set_label(lib->guide_selector, NULL, _("guides"));
  gtk_box_pack_start(GTK_BOX(self->widget), lib->guide_selector, TRUE, TRUE, 0);

  lib->guides_widgets = gtk_stack_new();
  gtk_stack_set_homogeneous(GTK_STACK(lib->guides_widgets), FALSE);
  gtk_box_pack_start(GTK_BOX(self->widget), lib->guides_widgets, TRUE, TRUE, 0);

  dt_bauhaus_combobox_add(lib->guide_selector, _("none"));
  int i = 0;
  for(GList *iter = darktable.guides; iter; iter = g_list_next(iter), i++)
  {
    GtkWidget *widget = NULL;
    dt_guides_t *guide = (dt_guides_t *)iter->data;
    dt_bauhaus_combobox_add(lib->guide_selector, _(guide->name));
    if(guide->widget)
    {
      // generate some unique name so that we can have the same name several times
      char name[5];
      snprintf(name, sizeof(name), "%d", i);
      widget = guide->widget(NULL, guide->user_data);
      gtk_widget_show_all(widget);
      gtk_stack_add_named(GTK_STACK(lib->guides_widgets), widget, name);
    }
    lib->guides_widgets_list = g_list_append(lib->guides_widgets_list, widget);
  }
  gtk_widget_set_no_show_all(lib->guides_widgets, TRUE);

  gtk_widget_set_tooltip_text(lib->guide_selector, _("display guide lines to help compose your photograph"));
  g_signal_connect(G_OBJECT(lib->guide_selector), "value-changed", G_CALLBACK(guides_presets_changed), lib);

  lib->flip_guides = dt_bauhaus_combobox_new(NULL);
  dt_bauhaus_widget_set_label(lib->flip_guides, NULL, _("flip"));
  dt_bauhaus_combobox_add(lib->flip_guides, _("none"));
  dt_bauhaus_combobox_add(lib->flip_guides, _("horizontally"));
  dt_bauhaus_combobox_add(lib->flip_guides, _("vertically"));
  dt_bauhaus_combobox_add(lib->flip_guides, _("both"));
  gtk_widget_set_tooltip_text(lib->flip_guides, _("flip guides"));
  gtk_box_pack_start(GTK_BOX(self->widget), lib->flip_guides, TRUE, TRUE, 0);

  lib->overlay = dt_bauhaus_combobox_new(NULL);
  dt_bauhaus_widget_set_label(lib->overlay, NULL, _("overlay"));
  dt_bauhaus_combobox_add(lib->overlay, _("none"));
  dt_bauhaus_combobox_add(lib->overlay, _("selected image"));
  dt_bauhaus_combobox_add(lib->overlay, _("id"));
  gtk_widget_set_tooltip_text(lib->overlay, _("overlay another image over the live view"));
  g_signal_connect(G_OBJECT(lib->overlay), "value-changed", G_CALLBACK(overlay_changed), lib);
  gtk_box_pack_start(GTK_BOX(self->widget), lib->overlay, TRUE, TRUE, 0);

  lib->overlay_id_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
  GtkWidget *label = gtk_label_new(_("image id"));
  gtk_widget_set_halign(label, GTK_ALIGN_START);
  lib->overlay_id = gtk_spin_button_new_with_range(0, 1000000000, 1);
  gtk_spin_button_set_digits(GTK_SPIN_BUTTON(lib->overlay_id), 0);
  gtk_widget_set_tooltip_text(lib->overlay_id, _("enter image id of the overlay manually"));
  g_signal_connect(G_OBJECT(lib->overlay_id), "value-changed", G_CALLBACK(_overlay_id_changed), lib);
  gtk_spin_button_set_value(GTK_SPIN_BUTTON(lib->overlay_id),
                            dt_conf_get_int("plugins/lighttable/live_view/overlay_imgid"));
  gtk_box_pack_start(GTK_BOX(lib->overlay_id_box), label, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(lib->overlay_id_box), lib->overlay_id, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(self->widget), lib->overlay_id_box, TRUE, TRUE, 0);
  gtk_widget_show(lib->overlay_id);
  gtk_widget_show(label);

  lib->overlay_mode = dt_bauhaus_combobox_new(NULL);
  dt_bauhaus_widget_set_label(lib->overlay_mode, NULL, _("overlay mode"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "normal"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "xor"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "add"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "saturate"));
#if(CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 10, 0))
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "multiply"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "screen"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "overlay"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "darken"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "lighten"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "color dodge"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "color burn"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "hard light"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "soft light"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "difference"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "exclusion"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "HSL hue"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "HSL saturation"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "HSL color"));
  dt_bauhaus_combobox_add(lib->overlay_mode, C_("blendmode", "HSL luminosity"));
#endif
  gtk_widget_set_tooltip_text(lib->overlay_mode, _("mode of the overlay"));
  dt_bauhaus_combobox_set(lib->overlay_mode, dt_conf_get_int("plugins/lighttable/live_view/overlay_mode"));
  g_signal_connect(G_OBJECT(lib->overlay_mode), "value-changed", G_CALLBACK(_overlay_mode_changed), lib);
  gtk_box_pack_start(GTK_BOX(self->widget), lib->overlay_mode, TRUE, TRUE, 0);

  lib->overlay_splitline = dt_bauhaus_combobox_new(NULL);
  dt_bauhaus_widget_set_label(lib->overlay_splitline, NULL, _("split line"));
  dt_bauhaus_combobox_add(lib->overlay_splitline, _("off"));
  dt_bauhaus_combobox_add(lib->overlay_splitline, _("on"));
  gtk_widget_set_tooltip_text(lib->overlay_splitline, _("only draw part of the overlay"));
  dt_bauhaus_combobox_set(lib->overlay_splitline, dt_conf_get_int("plugins/lighttable/live_view/splitline"));
  g_signal_connect(G_OBJECT(lib->overlay_splitline), "value-changed", G_CALLBACK(_overlay_splitline_changed),
                   lib);
  gtk_box_pack_start(GTK_BOX(self->widget), lib->overlay_splitline, TRUE, TRUE, 0);

  gtk_widget_set_visible(GTK_WIDGET(lib->overlay_mode), FALSE);
  gtk_widget_set_visible(GTK_WIDGET(lib->overlay_id_box), FALSE);
  gtk_widget_set_visible(GTK_WIDGET(lib->overlay_splitline), FALSE);

  gtk_widget_set_no_show_all(GTK_WIDGET(lib->overlay_mode), TRUE);
  gtk_widget_set_no_show_all(GTK_WIDGET(lib->overlay_id_box), TRUE);
  gtk_widget_set_no_show_all(GTK_WIDGET(lib->overlay_splitline), TRUE);

  guides_presets_set_visibility(lib, 0);
}

void gui_cleanup(dt_lib_module_t *self)
{
  // dt_lib_live_view_t *lib = self->data;

  // g_list_free(lib->guides_widgets_list);
  // INTENTIONAL. it's supposed to be leaky until lua is fixed.

  free(self->data);
  self->data = NULL;
}

void view_enter(struct dt_lib_module_t *self,struct dt_view_t *old_view,struct dt_view_t *new_view)
{
  // disable buttons that won't work with this camera
  // TODO: initialize tethering mode outside of libs/camera.s so we can use darktable.camctl->active_camera
  // here
  dt_lib_live_view_t *lib = self->data;
  const dt_camera_t *cam = darktable.camctl->active_camera;
  if(cam == NULL) cam = darktable.camctl->wanted_camera;

  gboolean sensitive = cam && cam->can_live_view_advanced;

  gtk_widget_set_sensitive(lib->live_view_zoom, sensitive);
  gtk_widget_set_sensitive(lib->focus_in_big, sensitive);
  gtk_widget_set_sensitive(lib->focus_in_small, sensitive);
  gtk_widget_set_sensitive(lib->focus_out_big, sensitive);
  gtk_widget_set_sensitive(lib->focus_out_small, sensitive);
}

// TODO: find out where the zoom window is and draw overlay + grid accordingly
#define MARGIN 20
#define BAR_HEIGHT 18 /* see libs/camera.c */
void gui_post_expose(dt_lib_module_t *self, cairo_t *cr, int32_t width, int32_t height, int32_t pointerx,
                     int32_t pointery)
{
  dt_camera_t *cam = (dt_camera_t *)darktable.camctl->active_camera;
  dt_lib_live_view_t *lib = self->data;

  if(cam->is_live_viewing == FALSE || cam->live_view_zoom == TRUE) return;

  dt_pthread_mutex_lock(&cam->live_view_pixbuf_mutex);
  if(GDK_IS_PIXBUF(cam->live_view_pixbuf) == FALSE)
  {
    dt_pthread_mutex_unlock(&cam->live_view_pixbuf_mutex);
    return;
  }
  double w = width - (MARGIN * 2.0f);
  double h = height - (MARGIN * 2.0f) - BAR_HEIGHT;
  gint pw = gdk_pixbuf_get_width(cam->live_view_pixbuf);
  gint ph = gdk_pixbuf_get_height(cam->live_view_pixbuf);
  lib->overlay_x0 = lib->overlay_x1 = lib->overlay_y0 = lib->overlay_y1 = 0.0;

  gboolean use_splitline = (dt_bauhaus_combobox_get(lib->overlay_splitline) == 1);

  // OVERLAY
  int imgid = 0;
  switch(dt_bauhaus_combobox_get(lib->overlay))
  {
    case OVERLAY_SELECTED:
      imgid = dt_view_tethering_get_selected_imgid(darktable.view_manager);
      break;
    case OVERLAY_ID:
      imgid = lib->imgid;
      break;
  }
  if(imgid > 0)
  {
    cairo_save(cr);
    const dt_image_t *img = dt_image_cache_testget(darktable.image_cache, imgid, 'r');
    // if the user points at this image, we really want it:
    if(!img) img = dt_image_cache_get(darktable.image_cache, imgid, 'r');

    int zoom = 1;
    float imgwd = 0.90f;
    if(zoom == 1)
    {
      imgwd = .97f;
    }

    dt_mipmap_buffer_t buf;
    dt_mipmap_size_t mip = dt_mipmap_cache_get_matching_size(darktable.mipmap_cache, imgwd * w, imgwd * h);
    dt_mipmap_cache_get(darktable.mipmap_cache, &buf, imgid, mip, 0, 'r');

    float scale = 1.0;
    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.buf, CAIRO_FORMAT_RGB24, buf.width,
                                                    buf.height, stride);
      if(zoom == 1)
      {
        scale = fminf(fminf(w, pw) / (float)buf.width, fminf(h, ph) / (float)buf.height);
      }
      else
        scale = fminf(w * imgwd / (float)buf.width, h * imgwd / (float)buf.height);
    }

    // draw centered and fitted:
    cairo_translate(cr, width / 2.0, (height + BAR_HEIGHT) / 2.0f);
    cairo_scale(cr, scale, scale);

    if(buf.buf)
    {
      cairo_translate(cr, -.5f * buf.width, -.5f * buf.height);

      if(use_splitline)
      {
        double x0, y0, x1, y1;
        switch(lib->splitline_rotation)
        {
          case 0:
            x0 = 0.0;
            y0 = 0.0;
            x1 = buf.width * lib->splitline_x;
            y1 = buf.height;
            break;
          case 1:
            x0 = 0.0;
            y0 = 0.0;
            x1 = buf.width;
            y1 = buf.height * lib->splitline_y;
            break;
          case 2:
            x0 = buf.width * lib->splitline_x;
            y0 = 0.0;
            x1 = buf.width;
            y1 = buf.height;
            break;
          case 3:
            x0 = 0.0;
            y0 = buf.height * lib->splitline_y;
            x1 = buf.width;
            y1 = buf.height;
            break;
          default:
            fprintf(stderr, "OMFG, the world will collapse, this shouldn't be reachable!\n");
            return;
        }

        cairo_rectangle(cr, x0, y0, x1, y1);
        cairo_clip(cr);
      }

      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);
      int overlay_modes_index = dt_bauhaus_combobox_get(lib->overlay_mode);
      if(overlay_modes_index >= 0)
      {
        cairo_operator_t mode = _overlay_modes[overlay_modes_index];
        cairo_set_operator(cr, mode);
      }
      cairo_fill(cr);
      cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
      cairo_surface_destroy(surface);
    }
    cairo_restore(cr);
    if(buf.buf) dt_mipmap_cache_release(darktable.mipmap_cache, &buf);
    if(img) dt_image_cache_read_release(darktable.image_cache, img);

    // ON CANVAS CONTROLS
    if(use_splitline)
    {
      float scale = fminf(1.0, fminf(w / pw, h / ph));

      // image coordinates
      lib->overlay_x0 = 0.5 * (width - pw * scale);
      lib->overlay_y0 = 0.5 * (height - ph * scale + BAR_HEIGHT);
      lib->overlay_x1 = lib->overlay_x0 + pw * scale;
      lib->overlay_y1 = lib->overlay_y0 + ph * scale;

      // splitline position to absolute coords:
      double sl_x = lib->overlay_x0 + lib->splitline_x * pw * scale;
      double sl_y = lib->overlay_y0 + lib->splitline_y * ph * scale;

      int x0 = sl_x, y0 = 0.0, x1 = x0, y1 = height;
      if(lib->splitline_rotation % 2 != 0)
      {
        x0 = 0.0;
        y0 = sl_y;
        x1 = width;
        y1 = y0;
      }
      gboolean mouse_over_control = (lib->splitline_rotation % 2 == 0) ? (fabs(sl_x - pointerx) < 5)
                                                                       : (fabs(sl_y - pointery) < 5);
      cairo_save(cr);
      cairo_set_source_rgb(cr, .7, .7, .7);
      cairo_set_line_width(cr, (mouse_over_control ? 2.0 : 0.5));

      cairo_move_to(cr, x0, y0);
      cairo_line_to(cr, x1, y1);
      cairo_stroke(cr);

      /* if mouse over control lets draw center rotate control, hide if split is dragged */
      if(!lib->splitline_dragging && mouse_over_control)
      {
        cairo_set_line_width(cr, 0.5);
        double s = width * HANDLE_SIZE;
        dtgtk_cairo_paint_refresh(cr, sl_x - (s * 0.5), sl_y - (s * 0.5), s, s, 1);
      }

      cairo_restore(cr);
    }
  }

  // GUIDES
  if(cam->live_view_rotation % 2 == 1)
  {
    gint tmp = pw;
    pw = ph;
    ph = tmp;
  }
  float scale = 1.0;
  //   if(cam->live_view_zoom == FALSE)
  //   {
  if(pw > w) scale = w / pw;
  if(ph > h) scale = fminf(scale, h / ph);
  //   }
  double sw = scale * pw;
  double sh = scale * ph;

  // draw guides
  int guide_flip = dt_bauhaus_combobox_get(lib->flip_guides);
  double left = (width - sw) * 0.5;
  double top = (height + BAR_HEIGHT - sh) * 0.5;

  double dashes = 5.0;

  cairo_save(cr);
  cairo_rectangle(cr, left, top, sw, sh);
  cairo_clip(cr);
  cairo_set_dash(cr, &dashes, 1, 0);

  // Move coordinates to local center selection.
  cairo_translate(cr, (sw / 2 + left), (sh / 2 + top));

  // Flip horizontal.
  if(guide_flip & FLAG_FLIP_HORIZONTAL) cairo_scale(cr, -1, 1);
  // Flip vertical.
  if(guide_flip & FLAG_FLIP_VERTICAL) cairo_scale(cr, 1, -1);

  int which = dt_bauhaus_combobox_get(lib->guide_selector);
  dt_guides_t *guide = (dt_guides_t *)g_list_nth_data(darktable.guides, which - 1);
  if(guide)
  {
    guide->draw(cr, -sw / 2, -sh / 2, sw, sh, 1.0, guide->user_data);
    cairo_stroke_preserve(cr);
    cairo_set_dash(cr, &dashes, 0, 0);
    cairo_set_source_rgba(cr, .3, .3, .3, .8);
    cairo_stroke(cr);
  }
  cairo_restore(cr);
  dt_pthread_mutex_unlock(&cam->live_view_pixbuf_mutex);
}
コード例 #30
0
ファイル: simple_drawing.c プロジェクト: atkm/cs441
void set_color_black(cairo_t *cr){
  cairo_set_source_rgb (cr, 0, 0, 0);
}