static gboolean expose_borders (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { // draw arrows on borders if(!dt_control_running()) return TRUE; long int which = (long int)user_data; float width = widget->allocation.width, height = widget->allocation.height; cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); GtkStyle *style = gtk_widget_get_style(dt_ui_center(darktable.gui->ui)); cairo_set_source_rgb (cr, .5f*style->bg[GTK_STATE_NORMAL].red/65535.0, .5f*style->bg[GTK_STATE_NORMAL].green/65535.0, .5f*style->bg[GTK_STATE_NORMAL].blue/65535.0 ); // cairo_set_source_rgb (cr, .13, .13, .13); cairo_paint(cr); // draw scrollbar indicators int v = darktable.view_manager->current_view; dt_view_t *view = NULL; if(v >= 0 && v < darktable.view_manager->num_views) view = darktable.view_manager->view + v; // cairo_set_source_rgb (cr, .16, .16, .16); cairo_set_source_rgb (cr, style->bg[GTK_STATE_NORMAL].red/65535.0, style->bg[GTK_STATE_NORMAL].green/65535.0, style->bg[GTK_STATE_NORMAL].blue/65535.0 ); const float border = 0.3; if(!view) cairo_paint(cr); else { switch(which) { case 0: case 1: // left, right: vertical cairo_rectangle(cr, 0.0, view->vscroll_pos/view->vscroll_size * height, width, view->vscroll_viewport_size/view->vscroll_size * height); break; default: // bottom, top: horizontal cairo_rectangle(cr, view->hscroll_pos/view->hscroll_size * width, 0.0, view->hscroll_viewport_size/view->hscroll_size * width, height); break; } cairo_fill(cr); switch(which) { case 0: cairo_rectangle(cr, (1.0-border)*width, 0.0, border*width, height); break; case 1: cairo_rectangle(cr, 0.0, 0.0, border*width, height); break; case 2: cairo_rectangle(cr, (1.0-border)*height, (1.0-border)*height, width-2*(1.0-border)*height, border*height); break; default: cairo_rectangle(cr, (1.0-border)*height, 0.0, width-2*(1.0-border)*height, border*height); break; } cairo_fill(cr); } // draw gui arrows. cairo_set_source_rgb (cr, .6, .6, .6); switch(which) { case 0: // left if(dt_ui_panel_visible(darktable.gui->ui, DT_UI_PANEL_LEFT)) { cairo_move_to (cr, width, height/2-width); cairo_rel_line_to (cr, 0.0, 2*width); cairo_rel_line_to (cr, -width, -width); } else { cairo_move_to (cr, 0.0, height/2-width); cairo_rel_line_to (cr, 0.0, 2*width); cairo_rel_line_to (cr, width, -width); } break; case 1: // right if(dt_ui_panel_visible(darktable.gui->ui, DT_UI_PANEL_RIGHT)) { cairo_move_to (cr, 0.0, height/2-width); cairo_rel_line_to (cr, 0.0, 2*width); cairo_rel_line_to (cr, width, -width); } else { cairo_move_to (cr, width, height/2-width); cairo_rel_line_to (cr, 0.0, 2*width); cairo_rel_line_to (cr, -width, -width); } break; case 2: // top if(dt_ui_panel_visible(darktable.gui->ui, DT_UI_PANEL_CENTER_TOP)) { cairo_move_to (cr, width/2-height, height); cairo_rel_line_to (cr, 2*height, 0.0); cairo_rel_line_to (cr, -height, -height); } else { cairo_move_to (cr, width/2-height, 0.0); cairo_rel_line_to (cr, 2*height, 0.0); cairo_rel_line_to (cr, -height, height); } break; default: // bottom if(dt_ui_panel_visible(darktable.gui->ui, DT_UI_PANEL_CENTER_BOTTOM)) { cairo_move_to (cr, width/2-height, 0.0); cairo_rel_line_to (cr, 2*height, 0.0); cairo_rel_line_to (cr, -height, height); } else { cairo_move_to (cr, width/2-height, height); cairo_rel_line_to (cr, 2*height, 0.0); cairo_rel_line_to (cr, -height, -height); } break; } cairo_close_path (cr); cairo_fill(cr); cairo_destroy(cr); cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface (cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; }
static void gtk_shruler_draw_ticks (GtkSHRuler *ruler) { GtkWidget *widget = GTK_WIDGET (ruler); GtkStyle *style = gtk_widget_get_style (widget); GtkSHRulerPrivate *priv = GTK_SHRULER_GET_PRIVATE (ruler); GtkStateType state = gtk_widget_get_state (widget); GtkAllocation allocation; cairo_t *cr; gint i; gint width, height; gint xthickness; gint ythickness; gint length; gdouble lower, upper; /* Upper and lower limits, in ruler units */ gdouble increment; /* Number of pixels per unit */ gint scale; /* Number of units per major unit */ gdouble start, end, cur; gchar unit_str[32]; gint digit_height; gint digit_offset; gint text_size; gint pos; gdouble max_size; GtkCMUnit unit; PangoLayout *layout; PangoRectangle logical_rect, ink_rect; if (! gtk_widget_is_drawable (widget)) return; gtk_widget_get_allocation (widget, &allocation); xthickness = style->xthickness; ythickness = style->ythickness; layout = gtk_shruler_get_layout (widget, "0123456789"); pango_layout_get_extents (layout, &ink_rect, &logical_rect); digit_height = PANGO_PIXELS (ink_rect.height) + 2; digit_offset = ink_rect.y; if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { width = allocation.width; height = allocation.height - ythickness * 2; } else { width = allocation.height; height = allocation.width - ythickness * 2; } cr = cairo_create (priv->backing_store); gdk_cairo_set_source_color (cr, &style->bg[state]); cairo_paint (cr); gdk_cairo_set_source_color (cr, &style->fg[state]); gtk_shruler_get_range (ruler, &lower, &upper, &max_size); if ((upper - lower) == 0) goto out; increment = (gdouble) width / (upper - lower); /* determine the scale * use the maximum extents of the ruler to determine the largest * possible number to be displayed. Calculate the height in pixels * of this displayed text. Use this height to find a scale which * leaves sufficient room for drawing the ruler. * * We calculate the text size as for the vruler instead of * actually measuring the text width, so that the result for the * scale looks consistent with an accompanying vruler. */ scale = ceil (max_size); g_snprintf (unit_str, sizeof (unit_str), "%d", scale); text_size = strlen (unit_str) * digit_height + 1; for (scale = 0; scale < G_N_ELEMENTS (ruler_metric.ruler_scale); scale++) if (ruler_metric.ruler_scale[scale] * fabs (increment) > 2 * text_size) break; if (scale == G_N_ELEMENTS (ruler_metric.ruler_scale)) scale = G_N_ELEMENTS (ruler_metric.ruler_scale) - 1; unit = gtk_shruler_get_unit (ruler); /* drawing starts here */ length = 0; for (i = G_N_ELEMENTS (ruler_metric.subdivide) - 1; i >= 0; i--) { gdouble subd_incr; /* hack to get proper subdivisions at full pixels */ if (unit == CM_UNIT_PIXEL && scale == 1 && i == 1) subd_incr = 1.0; else subd_incr = ((gdouble) ruler_metric.ruler_scale[scale] / (gdouble) ruler_metric.subdivide[i]); if (subd_incr * fabs (increment) <= MINIMUM_INCR) continue; /* don't subdivide pixels */ if (unit == CM_UNIT_PIXEL && subd_incr < 1.0) continue; if (lower < upper) { start = floor (lower / subd_incr) * subd_incr; end = ceil (upper / subd_incr) * subd_incr; } else { start = floor (upper / subd_incr) * subd_incr; end = ceil (lower / subd_incr) * subd_incr; } for (cur = start; cur <= end; cur += subd_incr) { if (((int)cur) % 10 == 0) length = height * 2 / 3; else if (((int)cur) % 5 == 0) length = height / 3; else length = height / 4; pos = ROUND ((cur - lower) * increment); if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { cairo_rectangle (cr, pos, height + ythickness - length, 1, length); } else { cairo_rectangle (cr, height + xthickness - length, pos, length, 1); } /* draw label */ if (i == 0 && ((int)cur) % 10 == 0) { g_snprintf (unit_str, sizeof (unit_str), "%d", (int) cur); if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { pango_layout_set_text (layout, unit_str, -1); pango_layout_get_extents (layout, &logical_rect, NULL); cairo_move_to (cr, pos + 2, ythickness + PANGO_PIXELS (logical_rect.y - digit_offset)); pango_cairo_show_layout (cr, layout); } else { gint j; for (j = 0; j < (int) strlen (unit_str); j++) { pango_layout_set_text (layout, unit_str + j, 1); pango_layout_get_extents (layout, NULL, &logical_rect); cairo_move_to (cr, xthickness + 1, pos + digit_height * j + 2 + PANGO_PIXELS (logical_rect.y - digit_offset)); pango_cairo_show_layout (cr, layout); } } } } } cairo_fill (cr); out: cairo_destroy (cr); }
/* * 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_operator(xcb_ctx, CAIRO_OPERATOR_SOURCE); cairo_set_source_surface(xcb_ctx, img, 0, 0); cairo_paint(xcb_ctx); cairo_set_operator(xcb_ctx, CAIRO_OPERATOR_OVER); } 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_indicator && (unlock_state >= STATE_KEY_PRESSED || pam_state > STATE_PAM_IDLE)) { 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, 114.0 / 255, 255.0 / 255, 0.75); break; case STATE_PAM_WRONG: cairo_set_source_rgba(ctx, 250.0 / 255, 0, 0, 0.75); break; default: cairo_set_source_rgba(ctx, 0, 0, 0, 0.75); break; } cairo_fill_preserve(ctx); switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgb(ctx, 51.0 / 255, 0, 250.0 / 255); break; case STATE_PAM_WRONG: cairo_set_source_rgb(ctx, 125.0 / 255, 51.0 / 255, 0); break; case STATE_PAM_IDLE: cairo_set_source_rgb(ctx, 51.0 / 255, 125.0 / 255, 0); break; } cairo_stroke(ctx); /* Draw an inner seperator line. */ cairo_set_source_rgb(ctx, 0, 0, 0); cairo_set_line_width(ctx, 2.0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS - 5 /* radius */, 0, 2 * M_PI); 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); switch (pam_state) { case STATE_PAM_VERIFY: text = "verifying…"; break; case STATE_PAM_WRONG: text = "wrong!"; break; default: 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); } break; } 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) + 28.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 green. */ cairo_set_source_rgb(ctx, 51.0 / 255, 219.0 / 255, 0); } else { /* For backspace, we use red. */ cairo_set_source_rgb(ctx, 219.0 / 255, 51.0 / 255, 0); } cairo_stroke(ctx); /* Draw two little separators for the highlighted part of the * unlock indicator. */ cairo_set_source_rgb(ctx, 0, 0, 0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start /* start */, highlight_start + (M_PI / 128.0) /* end */); cairo_stroke(ctx); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start + (M_PI / 3.0) /* start */, (highlight_start + (M_PI / 3.0)) + (M_PI / 128.0) /* end */); 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; }
/* * 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; if (!vistype) vistype = get_root_visual_type(screen); if (fuzzy) { bg_pixmap = create_fg_pixmap(conn, screen, resolution); } else { 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 *xcb_output = cairo_xcb_surface_create(conn, bg_pixmap, vistype, resolution[0], resolution[1]); cairo_t *xcb_ctx = cairo_create(xcb_output); if (img||fuzzy) { if (fuzzy) { blur_image_gl(0, bg_pixmap, last_resolution[0],last_resolution[1], blur_radius, blur_sigma); cairo_surface_t * tmp = cairo_xcb_surface_create(conn, bg_pixmap, get_root_visual_type(screen), last_resolution[0], last_resolution[1]); cairo_set_source_surface(xcb_ctx, tmp, 0, 0); cairo_paint(xcb_ctx); cairo_surface_destroy(tmp); } else 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 (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, unlock_indicator_surface, 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, unlock_indicator_surface, x, y); cairo_rectangle(xcb_ctx, x, y, button_diameter_physical, button_diameter_physical); cairo_fill(xcb_ctx); } cairo_surface_destroy(xcb_output); cairo_destroy(xcb_ctx); return bg_pixmap; }
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[] = { { 600, 600 }, { 600, 72 }, { 300, 300 }, { 300, 72 }, { 150, 150 }, { 150, 72 }, { 75, 75 }, { 75, 72 }, { 72, 600 }, { 72, 300 }, { 72, 150 }, { 72, 75 }, { 72, 72 }, { 72, 37.5 }, { 37.5, 72 }, { 37.5, 37.5 }, }; unsigned int i; int n, num_ppi; num_ppi = sizeof (ppi) / sizeof (ppi[0]); #if GENERATE_REFERENCE for (n = 0; n < num_ppi; n++) { char *ref_name; xasprintf (&ref_name, "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; format = cairo_boilerplate_content_name (target->content); xasprintf (&base_name, "fallback-resolution.%s.%s", target->name, format); surface = (target->create_surface) (base_name, target->content, SIZE, SIZE, SIZE, SIZE, CAIRO_BOILERPLATE_MODE_TEST, 0, &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", 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, 0, &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, ~0U); cr = cairo_create (surface); #if SET_TOLERANCE cairo_set_tolerance (cr, 3.0); #endif cairo_surface_set_device_offset (surface, 25, 25); cairo_surface_set_fallback_resolution (surface, ppi[n].x, ppi[n].y); 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; }
void do_draw_map (cairo_t * cr, GdkRectangle * area, unsigned int layerflags) { int i; int dx, dy; int x = area->x; int y = area->y; int w = area->width; int h = area->height; /*cairo_arc (cr, x + 10, y + 10 ,10, 0, 2 * 3.14); cairo_set_source_rgb (cr, 1, 1, 1); cairo_fill_preserve (cr); cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr); */ if (layerflags & MAGIC_PINK_FLAG) cairo_set_source_rgb (cr, 1, 0, 1); else cairo_set_source_rgb (cr, 0, 0, 0); cairo_rectangle (cr, x, y, w, h); cairo_fill (cr); cairo_select_font_face (cr, "sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size (cr, 12); x /= 16; y /= 16; w /= 16; h /= 16; w += 2; h += 2; w = w + x > gmap.xsize ? gmap.xsize - x : w; h = h + y > gmap.ysize ? gmap.ysize - y : h; /* This loop will draw everything within the view-window */ for (dy = y; dy < h + y; dy++) { for (dx = x; dx < w + x; dx++) { i = (dy * gmap.xsize) + dx; if (layerflags & LAYER_1_FLAG && map[i]) { cairo_set_source_surface (cr, gdk_icons[map[i]], dx * 16, dy * 16); cairo_paint (cr); } if (layerflags & LAYER_2_FLAG && b_map[i]) { cairo_set_source_surface (cr, gdk_icons[b_map[i]], dx * 16, dy * 16); cairo_paint (cr); } if (layerflags & LAYER_3_FLAG && f_map[i]) { cairo_set_source_surface (cr, gdk_icons[f_map[i]], dx * 16, dy * 16); cairo_paint (cr); } if (layerflags & SHADOW_FLAG && sh_map[i] && sh_map[i] < MAX_SHADOWS) { cairo_set_source_surface (cr, gdk_shadows[sh_map[i]], dx * 16, dy * 16); cairo_paint (cr); } if (layerflags & OBSTACLES_FLAG && o_map[i] && o_map[i] <= MAX_OBSTACLES) { switch (o_map[i]) { case 1: // everything cairo_set_source_rgba (cr, 1, 1, 1, 0.5); cairo_rectangle (cr, dx * 16, dy * 16, 16, 16); break; case 2: // up cairo_set_source_rgba (cr, 1, 1, 1, 0.6); cairo_rectangle (cr, dx * 16, dy * 16, 16, 4); break; case 3: // right cairo_set_source_rgba (cr, 1, 1, 1, 0.6); cairo_rectangle (cr, dx * 16 + 12, dy * 16, 4, 16); break; case 4: // down cairo_set_source_rgba (cr, 1, 1, 1, 0.6); cairo_rectangle (cr, dx * 16, dy * 16 + 12, 16, 4); break; case 5: // left cairo_set_source_rgba (cr, 1, 1, 1, 0.6); cairo_rectangle (cr, dx * 16, dy * 16, 4, 16); break; default: cairo_set_source_rgba (cr, 1, 0, 0, 0.5); cairo_rectangle (cr, dx * 16, dy * 16, 16, 16); break; } cairo_fill (cr); } if (layerflags & ZONES_FLAG && z_map[i]) { cairo_set_source_rgba (cr, 0.3, 0.3, 0.5, 0.5); cairo_rectangle (cr, dx * 16, dy * 16, 16, 16); cairo_fill (cr); cairo_set_source_rgb (cr, 1, 1, 1); char *s = g_strdup_printf ("%d", z_map[i]); cairo_text_extents_t extents; cairo_text_extents (cr, s, &extents); cairo_move_to (cr, dx * 16 + 8 - extents.width / 2 - extents.x_bearing, dy * 16 + 8 - extents.height / 2 - extents.y_bearing); cairo_show_text (cr, s); cairo_fill (cr); g_free (s); } } } if (layerflags & ENTITIES_FLAG) { for (i = 0; i < number_of_ents; ++i) { /* Draw only the entities within the view-screen */ if (gent[i].tilex >= x && gent[i].tilex < w + x && gent[i].tiley >= y && gent[i].tiley < h + y) { if (gent[i].transl) { /* FIXME: Draw a translucent sprite */ } cairo_set_source_surface (cr, gdk_eframes[gent[i].chrx][gent[i]. facing * 3], gent[i].tilex * 16, gent[i].tiley * 16); cairo_paint (cr); } } } if (layerflags & MARKERS_FLAG) { for (i = 0; i < gmap.num_markers; ++i) { // do not do manual clipping, I'm too lazy to get that right here cairo_set_source_surface (cr, gdk_marker_image, gmap.markers[i].x * 16 + 8, gmap.markers[i].y * 16 - 8); cairo_paint (cr); } } if (layerflags & BOUNDING_FLAG) { for (i = 0; i < gmap.num_bound_boxes; ++i) { s_bound bound = gmap.bound_box[i]; cairo_set_line_width (cr, 1); cairo_set_source_rgb (cr, 1, 1, 0); cairo_rectangle (cr, bound.x1 * 16, bound.y1 * 16, (bound.x2 - bound.x1 + 1) * 16, (bound.y2 - bound.y1 + 1) * 16); cairo_stroke (cr); } } }
static void draw_unlock_indicator() { /* Initialise the surface if not yet done */ if (unlock_indicator_surface == NULL) { button_diameter_physical = ceil(scaling_factor() * BUTTON_DIAMETER); DEBUG("scaling_factor is %.f, physical diameter is %d px\n", scaling_factor(), button_diameter_physical); unlock_indicator_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, button_diameter_physical, button_diameter_physical); } cairo_t *ctx = cairo_create(unlock_indicator_surface); /* clear the surface */ cairo_save(ctx); cairo_set_operator(ctx, CAIRO_OPERATOR_CLEAR); cairo_paint(ctx); cairo_restore(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, 114.0/255, 255.0/255, 0.75); break; case STATE_PAM_WRONG: cairo_set_source_rgba(ctx, 250.0/255, 0, 0, 0.75); break; default: cairo_set_source_rgba(ctx, 0, 0, 0, 0.75); break; } cairo_fill_preserve(ctx); switch (pam_state) { case STATE_PAM_VERIFY: cairo_set_source_rgb(ctx, 51.0/255, 0, 250.0/255); break; case STATE_PAM_WRONG: cairo_set_source_rgb(ctx, 125.0/255, 51.0/255, 0); break; case STATE_PAM_IDLE: cairo_set_source_rgb(ctx, 51.0/255, 125.0/255, 0); break; } cairo_stroke(ctx); /* Draw an inner seperator line. */ cairo_set_source_rgb(ctx, 0, 0, 0); cairo_set_line_width(ctx, 2.0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS - 5 /* radius */, 0, 2 * M_PI); 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); switch (pam_state) { case STATE_PAM_VERIFY: text = "verifying…"; break; case STATE_PAM_WRONG: text = "wrong!"; break; default: 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); } break; } 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); } /* 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 green. */ cairo_set_source_rgb(ctx, 51.0/255, 219.0/255, 0); } else { /* For backspace, we use red. */ cairo_set_source_rgb(ctx, 219.0/255, 51.0/255, 0); } cairo_stroke(ctx); /* Draw two little separators for the highlighted part of the * unlock indicator. */ cairo_set_source_rgb(ctx, 0, 0, 0); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start /* start */, highlight_start + (M_PI / 128.0) /* end */); cairo_stroke(ctx); cairo_arc(ctx, BUTTON_CENTER /* x */, BUTTON_CENTER /* y */, BUTTON_RADIUS /* radius */, highlight_start + (M_PI / 3.0) /* start */, (highlight_start + (M_PI / 3.0)) + (M_PI / 128.0) /* end */); cairo_stroke(ctx); } } cairo_destroy(ctx); }
void DrawTrayWindow(TrayWindow* trayWindow) { FcitxClassicUI *classicui = trayWindow->owner; FcitxSkin *sc = &classicui->skin; SkinImage *image; int f_state; if (!classicui->bUseTrayIcon) return; if (FcitxInstanceGetCurrentState(classicui->owner) == IS_ACTIVE) f_state = ACTIVE_ICON; else f_state = INACTIVE_ICON; cairo_t *c; cairo_surface_t *png_surface ; if (!trayWindow->bTrayMapped) return; /* 画png */ if (f_state) { image = LoadImage(sc, sc->skinTrayIcon.active, true); } else { image = LoadImage(sc, sc->skinTrayIcon.inactive, true); } if (image == NULL) return; png_surface = image->image; c = cairo_create(trayWindow->cs); cairo_set_source_rgba(c, 0, 0, 0, 0); cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); cairo_paint(c); do { if (png_surface) { int w = cairo_image_surface_get_width(png_surface); int h = cairo_image_surface_get_height(png_surface); if (w == 0 || h == 0) break; double scaleW = 1.0, scaleH = 1.0; if (w > trayWindow->size || h > trayWindow->size) { scaleW = ((double) trayWindow->size) / w; scaleH = ((double) trayWindow->size) / h; if (scaleW > scaleH) scaleH = scaleW; else scaleW = scaleH; } int aw = scaleW * w; int ah = scaleH * h; cairo_scale(c, scaleW, scaleH); cairo_set_source_surface(c, png_surface, (trayWindow->size - aw) / 2 , (trayWindow->size - ah) / 2); cairo_set_operator(c, CAIRO_OPERATOR_OVER); cairo_paint_with_alpha(c, 1); } } while(0); cairo_destroy(c); XVisualInfo* vi = trayWindow->visual.visual ? &trayWindow->visual : NULL; if (!(vi && vi->visual)) { XClearArea(trayWindow->owner->dpy, trayWindow->window, 0, 0, trayWindow->size, trayWindow->size, False); } c = cairo_create(trayWindow->cs_x); if (vi && vi->visual) { cairo_set_source_rgba(c, 0, 0, 0, 0); cairo_set_operator(c, CAIRO_OPERATOR_SOURCE); cairo_paint(c); } cairo_set_operator(c, CAIRO_OPERATOR_OVER); cairo_set_source_surface(c, trayWindow->cs, 0, 0); cairo_rectangle(c, 0, 0, trayWindow->size, trayWindow->size); cairo_clip(c); cairo_paint(c); cairo_destroy(c); }
/** renderer for setups */ static NftResult _render_setup(cairo_surface_t ** surface, gpointer element) { if(!surface || !element) NFT_LOG_NULL(NFT_FAILURE); /* setup to render */ LedSetup *s = (LedSetup *) element; /* get dimensions of setup */ LedFrameCord w, h; led_setup_get_dim(s, &w, &h); /* calculate rendered dimensions of this tile */ double width = (double) w * ui_renderer_scale_factor(); double height = (double) h * ui_renderer_scale_factor(); /* if dimensions changed, we need to allocate a new surface */ if(!renderer_resize(setup_get_renderer(), width, height)) { g_error("Failed to resize renderer to %dx%d", w, h); return NFT_FAILURE; } /* create context for drawing */ cairo_t *cr = cairo_create(*surface); /* clear surface */ #ifdef DEBUG cairo_set_source_rgba(cr, 0.1, 0.1, 0.1, 1); #else cairo_set_source_rgba(cr, 0, 0, 0, 1); #endif cairo_rectangle(cr, 0, 0, (double) cairo_image_surface_get_width(*surface), (double) cairo_image_surface_get_height(*surface)); cairo_fill(cr); /* walk through all hardware LED adapters */ LedHardware *hw; for(hw = led_setup_get_hardware(s); hw; hw = led_hardware_list_get_next(hw)) { /* calculate offset of complete setup */ LedTile *t; double xOff = 0, yOff = 0; for(t = led_hardware_get_tile(hw); t; t = led_tile_list_get_next(t)) { double xOffT, yOffT; tile_calc_render_offset(led_tile_get_privdata(t), (double) w, (double) h, &xOffT, &yOffT); xOff = MIN(xOff, xOffT); yOff = MIN(yOff, yOffT); } renderer_set_offset(setup_get_renderer(), xOff * ui_renderer_scale_factor(), yOff * ui_renderer_scale_factor()); /* Walk all tiles of this hardware & draw their surface */ for(t = led_hardware_get_tile(hw); t; t = led_tile_list_get_next(t)) { /** @todo check for visibility? */ /* get surface from tile */ NiftyconfTile *tile = (NiftyconfTile *) led_tile_get_privdata(t); /* get surface */ cairo_surface_t *tsurface = renderer_get_surface (tile_get_renderer(tile)); /* compensate child tiles' offset */ double xOffT, yOffT; renderer_get_offset(tile_get_renderer(tile), &xOffT, &yOffT); cairo_translate(cr, xOffT, yOffT); /* compensate setup offset */ cairo_translate(cr, -xOff * ui_renderer_scale_factor(), -yOff * ui_renderer_scale_factor()); /* move to x/y */ LedFrameCord x, y; led_tile_get_pos(t, &x, &y); cairo_translate(cr, ((double) x) * ui_renderer_scale_factor(), ((double) y) * ui_renderer_scale_factor()); /* rotate around pivot */ double pX, pY; led_tile_get_pivot(t, &pX, &pY); cairo_translate(cr, pX * ui_renderer_scale_factor(), pY * ui_renderer_scale_factor()); cairo_rotate(cr, led_tile_get_rotation(t)); cairo_translate(cr, -pX * ui_renderer_scale_factor(), -pY * ui_renderer_scale_factor()); /* draw surface */ cairo_set_source_surface(cr, tsurface, 0, 0); /* disable filtering */ cairo_pattern_set_filter(cairo_get_source(cr), ui_renderer_filter()); /* disable antialiasing */ cairo_set_antialias(cr, ui_renderer_antialias()); /* render surface */ cairo_paint(cr); /* reset transformation matrix */ cairo_identity_matrix(cr); } /* Draw chain of this hardware */ /* s = * chain_get_surface(led_chain_get_privdata(led_hardware_get_chain(h))); * cairo_set_source_surface(cr, s, 0, 0); cairo_paint(cr); */ } cairo_destroy(cr); return NFT_SUCCESS; }
static void on_screenshot_finished (GObject *source, GAsyncResult *res, gpointer user_data) { CcBackgroundPanel *panel = user_data; CcBackgroundPanelPrivate *priv = panel->priv; GError *error; GdkRectangle rect; GtkWidget *widget; GdkPixbuf *pixbuf; cairo_surface_t *surface; cairo_t *cr; int width; int height; error = NULL; g_dbus_connection_call_finish (panel->priv->connection, res, &error); if (error != NULL) { g_debug ("Unable to get screenshot: %s", error->message); g_error_free (error); /* fallback? */ goto out; } pixbuf = gdk_pixbuf_new_from_file (panel->priv->screenshot_path, &error); if (error != NULL) { g_debug ("Unable to use GNOME Shell's builtin screenshot interface: %s", error->message); g_error_free (error); goto out; } width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (surface); gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); cairo_paint (cr); g_object_unref (pixbuf); /* clear the workarea */ widget = WID ("background-desktop-drawingarea"); gdk_screen_get_monitor_workarea (gtk_widget_get_screen (widget), 0, &rect); cairo_save (cr); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height); cairo_fill (cr); cairo_restore (cr); g_clear_object (&panel->priv->display_screenshot); panel->priv->display_screenshot = gdk_pixbuf_get_from_surface (surface, 0, 0, width, height); /* remove the temporary file created by the shell */ g_unlink (panel->priv->screenshot_path); g_free (priv->screenshot_path); priv->screenshot_path = NULL; cairo_destroy (cr); cairo_surface_destroy (surface); out: update_display_preview (panel); }
static gboolean RedrawAudioModulePanel (GtkWidget * viewport, GdkEvent * event, AudioModulePanel * action) { cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (viewport)); if (action -> background_image != 0) {cairo_set_source_surface (cr, action -> background_image, 0, 0); cairo_paint (cr);} action -> redraw (cr); cairo_destroy (cr); return FALSE; }
static void eng_image_draw(void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth) { Render_Engine *re; Evas_Cairo_Context *ctxt; Evas_Cairo_Image *im; DATA32 *pix; re = (Render_Engine *)data; ctxt = (Evas_Cairo_Context *)context; if (!image) return; im = image; evas_common_load_image_data_from_file(im->im); pix = im->im->image->data; if (pix) { if (!im->surface) { im->mulpix = malloc(im->im->image->w * im->im->image->h * sizeof(DATA32)); if (im->mulpix) { int i, n; DATA32 *p; n = im->im->image->w * im->im->image->h; p = im->mulpix; for (i = 0; i < n; i++) { int a; a = A_VAL(pix); R_VAL(p) = (R_VAL(pix) * a) / 255; G_VAL(p) = (G_VAL(pix) * a) / 255; B_VAL(p) = (B_VAL(pix) * a) / 255; A_VAL(p) = a; p++; pix++; } im->surface = cairo_image_surface_create_for_data(im->mulpix, CAIRO_FORMAT_ARGB32, im->im->image->w, im->im->image->h, 0); im->pattern = cairo_pattern_create_for_surface(im->surface); } } if (smooth) cairo_pattern_set_filter(im->pattern, CAIRO_FILTER_BILINEAR); else cairo_pattern_set_filter(im->pattern, CAIRO_FILTER_NEAREST); cairo_save(ctxt->cairo); cairo_translate(ctxt->cairo, dst_x, dst_y); cairo_scale(ctxt->cairo, (double)src_w / (double)dst_w, (double)src_h / (double)dst_h); cairo_move_to(ctxt->cairo, 0, 0); // cairo_set_rgb_color(re->win->cairo, // (double)(R_VAL(((RGBA_Draw_Context *)context)->col.col)) / 255.0, // (double)(R_VAL(((RGBA_Draw_Context *)context)->col.col)) / 255.0, // (double)(R_VAL(((RGBA_Draw_Context *)context)->col.col)) / 255.0); // cairo_set_alpha(re->win->cairo, // (double)(A_VAL(((RGBA_Draw_Context *)context)->col.col)) / 255.0); cairo_set_source_surface(ctxt->cairo, im->surface, im->im->image->w, im->im->image->h); cairo_paint(ctxt->cairo); cairo_restore(ctxt->cairo); } }
static void image_set_from_surface (GtkImage *gtkimage, cairo_surface_t *surface) { GdkPixbuf *pixbuf; cairo_surface_t *image; cairo_t *cr; gboolean has_alpha; gint width, height; cairo_format_t surface_format; gint pixbuf_n_channels; gint pixbuf_rowstride; guchar *pixbuf_pixels; gint x, y; width = cairo_image_surface_get_width (surface); height = cairo_image_surface_get_height (surface); surface_format = cairo_image_surface_get_format (surface); has_alpha = (surface_format == CAIRO_FORMAT_ARGB32); pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height); pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf); pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf); pixbuf_pixels = gdk_pixbuf_get_pixels (pixbuf); image = cairo_image_surface_create_for_data (pixbuf_pixels, surface_format, width, height, pixbuf_rowstride); cr = cairo_create (image); cairo_set_source_surface (cr, surface, 0, 0); if (has_alpha) cairo_mask_surface (cr, surface, 0, 0); else cairo_paint (cr); cairo_destroy (cr); cairo_surface_destroy (image); for (y = 0; y < height; y++) { guchar *p = pixbuf_pixels + y * pixbuf_rowstride; for (x = 0; x < width; x++) { guchar tmp; #if G_BYTE_ORDER == G_LITTLE_ENDIAN tmp = p[0]; p[0] = p[2]; p[2] = tmp; p[3] = (has_alpha) ? p[3] : 0xff; #else tmp = p[0]; p[0] = (has_alpha) ? p[3] : 0xff; p[3] = p[2]; p[2] = p[1]; p[1] = tmp; #endif p += pixbuf_n_channels; } } gtk_image_set_from_pixbuf (gtkimage, pixbuf); g_object_unref (pixbuf); }
static gboolean dt_iop_zonesystem_preview_expose (GtkWidget *widget, GdkEventExpose *event, dt_iop_module_t *self) { const int inset = 2; int width = widget->allocation.width, height = widget->allocation.height; dt_iop_zonesystem_gui_data_t *g = (dt_iop_zonesystem_gui_data_t *)self->gui_data; dt_iop_zonesystem_params_t *p = (dt_iop_zonesystem_params_t *)self->params; cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); /* clear background */ GtkStateType state = gtk_widget_get_state(self->expander); GtkStyle *style = gtk_widget_get_style(self->expander); cairo_set_source_rgb (cr, style->bg[state].red/65535.0, style->bg[state].green/65535.0, style->bg[state].blue/65535.0); cairo_paint (cr); width -= 2*inset; height -= 2*inset; cairo_translate(cr, inset, inset); dt_pthread_mutex_lock(&g->lock); if( g->preview_buffer && self->enabled) { /* calculate the zonemap */ float zonemap[MAX_ZONE_SYSTEM_SIZE]= {-1}; _iop_zonesystem_calculate_zonemap (p,zonemap); /* let's generate a pixbuf from pixel zone buffer */ guchar *image = g_malloc ((g->preview_width*g->preview_height)*4); for (int k=0; k<g->preview_width*g->preview_height; k++) { int zone = 255*CLIP (((1.0/(p->size-1))*g->preview_buffer[k])); image[4*k+2] = (g->hilite_zone && g->preview_buffer[k]==g->zone_under_mouse)?255:zone; image[4*k+1] = (g->hilite_zone && g->preview_buffer[k]==g->zone_under_mouse)?255:zone; image[4*k+0] = (g->hilite_zone && g->preview_buffer[k]==g->zone_under_mouse)?0:zone; } dt_pthread_mutex_unlock(&g->lock); const int wd = g->preview_width, ht = g->preview_height; const float scale = fminf(width/(float)wd, height/(float)ht); const int stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, wd); cairo_surface_t *surface = cairo_image_surface_create_for_data (image, CAIRO_FORMAT_RGB24, wd, ht, stride); cairo_translate(cr, width/2.0, height/2.0f); cairo_scale(cr, scale, scale); cairo_translate(cr, -.5f*wd, -.5f*ht); cairo_rectangle(cr, 1, 1, wd-2, ht-2); cairo_set_source_surface (cr, surface, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD); cairo_fill_preserve(cr); cairo_surface_destroy (surface); cairo_set_line_width(cr, 1.0); cairo_set_source_rgb(cr, .1, .1, .1); cairo_stroke(cr); g_free(image); } else dt_pthread_mutex_unlock(&g->lock); cairo_destroy(cr); cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface (cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; }
static void locate_pointer_paint (GsdLocatePointerData *data, cairo_t *cr, gboolean composite) { GdkRGBA color; gdouble progress, circle_progress; gint width, height, i; GtkStyleContext *context; progress = data->progress; width = gdk_window_get_width (data->window); height = gdk_window_get_height (data->window); context = gtk_widget_get_style_context (data->widget); gtk_style_context_get_background_color (context, GTK_STATE_FLAG_SELECTED, &color); cairo_set_source_rgba (cr, 1., 1., 1., 0.); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); for (i = 0; i <= N_CIRCLES; i++) { if (progress < 0.) break; circle_progress = MIN (1., (progress * 2)); progress -= CIRCLES_PROGRESS_INTERVAL; if (circle_progress >= 1.) continue; if (composite) { cairo_set_source_rgba (cr, color.red, color.green, color.blue, 1 - circle_progress); cairo_arc (cr, width / 2, height / 2, circle_progress * width / 2, 0, 2 * G_PI); cairo_fill (cr); } else { cairo_set_source_rgb (cr, 0., 0., 0.); cairo_set_line_width (cr, 3.); cairo_arc (cr, width / 2, height / 2, circle_progress * width / 2, 0, 2 * G_PI); cairo_stroke (cr); cairo_set_source_rgb (cr, 1., 1., 1.); cairo_set_line_width (cr, 1.); cairo_arc (cr, width / 2, height / 2, circle_progress * width / 2, 0, 2 * G_PI); cairo_stroke (cr); } } }
static gboolean dt_iop_zonesystem_preview_draw(GtkWidget *widget, cairo_t *crf, dt_iop_module_t *self) { const int inset = DT_PIXEL_APPLY_DPI(2); GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width, height = allocation.height; dt_iop_zonesystem_gui_data_t *g = (dt_iop_zonesystem_gui_data_t *)self->gui_data; dt_iop_zonesystem_params_t *p = (dt_iop_zonesystem_params_t *)self->params; cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); /* clear background */ GtkStyleContext *context = gtk_widget_get_style_context(self->expander); gtk_render_background(context, cr, 0, 0, allocation.width, allocation.height); width -= 2 * inset; height -= 2 * inset; cairo_translate(cr, inset, inset); dt_pthread_mutex_lock(&g->lock); if(g->in_preview_buffer && g->out_preview_buffer && self->enabled) { /* calculate the zonemap */ float zonemap[MAX_ZONE_SYSTEM_SIZE] = { -1 }; _iop_zonesystem_calculate_zonemap(p, zonemap); /* let's generate a pixbuf from pixel zone buffer */ guchar *image = g_malloc_n((size_t)4 * g->preview_width * g->preview_height, sizeof(guchar)); guchar *buffer = g->mouse_over_output_zones ? g->out_preview_buffer : g->in_preview_buffer; for(int k = 0; k < g->preview_width * g->preview_height; k++) { int zone = 255 * CLIP(((1.0 / (p->size - 1)) * buffer[k])); image[4 * k + 2] = (g->hilite_zone && buffer[k] == g->zone_under_mouse) ? 255 : zone; image[4 * k + 1] = (g->hilite_zone && buffer[k] == g->zone_under_mouse) ? 255 : zone; image[4 * k + 0] = (g->hilite_zone && buffer[k] == g->zone_under_mouse) ? 0 : zone; } dt_pthread_mutex_unlock(&g->lock); const int wd = g->preview_width, ht = g->preview_height; const float scale = fminf(width / (float)wd, height / (float)ht); const int stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, wd); cairo_surface_t *surface = cairo_image_surface_create_for_data(image, CAIRO_FORMAT_RGB24, wd, ht, stride); cairo_translate(cr, width / 2.0, height / 2.0f); cairo_scale(cr, scale, scale); cairo_translate(cr, -.5f * wd, -.5f * ht); cairo_rectangle(cr, DT_PIXEL_APPLY_DPI(1), DT_PIXEL_APPLY_DPI(1), wd - DT_PIXEL_APPLY_DPI(2), ht - DT_PIXEL_APPLY_DPI(2)); cairo_set_source_surface(cr, surface, 0, 0); cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_GOOD); cairo_fill_preserve(cr); cairo_surface_destroy(surface); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.0)); cairo_set_source_rgb(cr, .1, .1, .1); cairo_stroke(cr); g_free(image); } else { dt_pthread_mutex_unlock(&g->lock); // draw a big, subdued dt logo if(g->image) { GdkRGBA *color; gtk_style_context_get(context, gtk_widget_get_state_flags(self->expander), "background-color", &color, NULL); cairo_set_source_surface(cr, g->image, (width - g->image_width) * 0.5, (height - g->image_height) * 0.5); cairo_rectangle(cr, 0, 0, width, height); cairo_set_operator(cr, CAIRO_OPERATOR_HSL_LUMINOSITY); cairo_fill_preserve(cr); cairo_set_operator(cr, CAIRO_OPERATOR_DARKEN); cairo_set_source_rgb(cr, color->red + 0.02, color->green + 0.02, color->blue + 0.02); cairo_fill_preserve(cr); cairo_set_operator(cr, CAIRO_OPERATOR_LIGHTEN); cairo_set_source_rgb(cr, color->red - 0.02, color->green - 0.02, color->blue - 0.02); cairo_fill(cr); gdk_rgba_free(color); } } cairo_destroy(cr); cairo_set_source_surface(crf, cst, 0, 0); cairo_paint(crf); cairo_surface_destroy(cst); return TRUE; }
void draw(cairo_t *cr) { cairo_set_source_surface(cr, image, x, y); cairo_paint(cr); }
/** * gd_create_collection_icon: * @base_size: * @pixbufs: (element-type GdkPixbuf): * * Returns: (transfer full): */ GIcon * gd_create_collection_icon (gint base_size, GList *pixbufs) { cairo_surface_t *surface; GIcon *retval; cairo_t *cr; GtkStyleContext *context; GtkWidgetPath *path; GtkBorder tile_border; gint padding, tile_size; gint idx, cur_x, cur_y; GList *l; context = gtk_style_context_new (); gtk_style_context_add_class (context, "documents-collection-icon"); path = gtk_widget_path_new (); gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW); gtk_style_context_set_path (context, path); gtk_widget_path_unref (path); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, base_size, base_size); cr = cairo_create (surface); /* Render the thumbnail itself */ gtk_render_background (context, cr, 0, 0, base_size, base_size); gtk_render_frame (context, cr, 0, 0, base_size, base_size); /* Now, render the tiles inside */ gtk_style_context_remove_class (context, "documents-collection-icon"); gtk_style_context_add_class (context, "documents-collection-icon-tile"); /* TODO: do not hardcode 4, but scale to another layout if more * pixbufs are provided. */ padding = MAX (floor (base_size / 10), 4); gtk_style_context_get_border (context, GTK_STATE_FLAG_NORMAL, &tile_border); tile_size = (base_size - (3 * padding)) / 2 - MAX (tile_border.left + tile_border.right, tile_border.top + tile_border.bottom); l = pixbufs; idx = 0; cur_x = padding; cur_y = padding; while (l != NULL && idx < 4) { GdkPixbuf *pix; gboolean is_thumbnail; gint pix_width, pix_height, scale_size; pix = l->data; is_thumbnail = (gdk_pixbuf_get_option (pix, "-documents-has-thumb") != NULL); /* Only draw a box for thumbnails */ if (is_thumbnail) { gtk_render_background (context, cr, cur_x, cur_y, tile_size + tile_border.left + tile_border.right, tile_size + tile_border.top + tile_border.bottom); gtk_render_frame (context, cr, cur_x, cur_y, tile_size + tile_border.left + tile_border.right, tile_size + tile_border.top + tile_border.bottom); } pix_width = gdk_pixbuf_get_width (pix); pix_height = gdk_pixbuf_get_height (pix); scale_size = MIN (pix_width, pix_height); cairo_save (cr); cairo_translate (cr, cur_x + tile_border.left, cur_y + tile_border.top); cairo_rectangle (cr, 0, 0, tile_size, tile_size); cairo_clip (cr); cairo_scale (cr, (gdouble) tile_size / (gdouble) scale_size, (gdouble) tile_size / (gdouble) scale_size); gdk_cairo_set_source_pixbuf (cr, pix, 0, 0); cairo_paint (cr); cairo_restore (cr); if ((idx % 2) == 0) { cur_x += tile_size + padding + tile_border.left + tile_border.right; } else { cur_x = padding; cur_y += tile_size + padding + tile_border.top + tile_border.bottom; } idx++; l = l->next; } retval = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, base_size, base_size)); cairo_surface_destroy (surface); cairo_destroy (cr); g_object_unref (context); return retval; }
static gboolean dt_iop_levels_area_draw(GtkWidget *widget, cairo_t *crf, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_levels_gui_data_t *c = (dt_iop_levels_gui_data_t *)self->gui_data; dt_iop_levels_params_t *p = (dt_iop_levels_params_t *)self->params; dt_develop_t *dev = darktable.develop; const int inset = DT_GUI_CURVE_EDITOR_INSET; GtkAllocation allocation; gtk_widget_get_allocation(GTK_WIDGET(c->area), &allocation); int width = allocation.width, height = allocation.height; cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); // clear bg cairo_set_source_rgb(cr, .2, .2, .2); cairo_paint(cr); cairo_translate(cr, inset, inset); width -= 2 * inset; height -= 2 * inset; cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.0)); cairo_set_source_rgb(cr, .1, .1, .1); cairo_rectangle(cr, 0, 0, width, height); cairo_stroke(cr); cairo_set_source_rgb(cr, .3, .3, .3); cairo_rectangle(cr, 0, 0, width, height); cairo_fill(cr); // draw grid cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(.4)); cairo_set_source_rgb(cr, .1, .1, .1); if(dev->histogram_type == DT_DEV_HISTOGRAM_WAVEFORM) dt_draw_waveform_lines(cr, 0, 0, width, height); else dt_draw_vertical_lines(cr, 4, 0, 0, width, height); // Drawing the vertical line indicators cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.)); for(int k = 0; k < 3; k++) { if(k == c->handle_move && c->mouse_x > 0) cairo_set_source_rgb(cr, 1, 1, 1); else cairo_set_source_rgb(cr, .7, .7, .7); cairo_move_to(cr, width * p->levels[k], height); cairo_rel_line_to(cr, 0, -height); cairo_stroke(cr); } // draw x positions cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.)); const float arrw = DT_PIXEL_APPLY_DPI(7.0f); for(int k = 0; k < 3; k++) { switch(k) { case 0: cairo_set_source_rgb(cr, 0, 0, 0); break; case 1: cairo_set_source_rgb(cr, 0.5, 0.5, 0.5); break; default: cairo_set_source_rgb(cr, 1, 1, 1); break; } cairo_move_to(cr, width * p->levels[k], height + inset - 1); cairo_rel_line_to(cr, -arrw * .5f, 0); cairo_rel_line_to(cr, arrw * .5f, -arrw); cairo_rel_line_to(cr, arrw * .5f, arrw); cairo_close_path(cr); if(c->handle_move == k && c->mouse_x > 0) cairo_fill(cr); else cairo_stroke(cr); } cairo_translate(cr, 0, height); // draw lum histogram in background // only if the module is enabled if(self->enabled) { uint32_t *hist = self->histogram; float hist_max = dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR ? self->histogram_max[0] : logf(1.0 + self->histogram_max[0]); if(hist && hist_max > 0.0f) { cairo_save(cr); cairo_scale(cr, width / 255.0, -(height - DT_PIXEL_APPLY_DPI(5)) / hist_max); cairo_set_source_rgba(cr, .2, .2, .2, 0.5); dt_draw_histogram_8(cr, hist, 4, 0, dev->histogram_type == DT_DEV_HISTOGRAM_LINEAR); // TODO: make draw // handle waveform // histograms cairo_restore(cr); } } // Cleaning up cairo_destroy(cr); cairo_set_source_surface(crf, cst, 0, 0); cairo_paint(crf); cairo_surface_destroy(cst); return TRUE; }
/** * gd_create_collection_icon: * @base_size: * @pixbufs: (element-type GdkPixbuf): * * Returns: (transfer full): */ GIcon * gd_create_collection_icon (gint base_size, GList *pixbufs) { cairo_surface_t *surface; GIcon *retval; cairo_t *cr; GtkStyleContext *context; GtkWidgetPath *path; gint padding, tile_size, scale_size; gint pix_width, pix_height; gint idx, cur_x, cur_y; GList *l; GdkPixbuf *pix; /* TODO: do not hardcode 4, but scale to another layout if more * pixbufs are provided. */ padding = MAX (floor (base_size / 10), 4); tile_size = (base_size - (3 * padding)) / 2; context = gtk_style_context_new (); gtk_style_context_add_class (context, "documents-collection-icon"); path = gtk_widget_path_new (); gtk_widget_path_append_type (path, GTK_TYPE_ICON_VIEW); gtk_style_context_set_path (context, path); gtk_widget_path_unref (path); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, base_size, base_size); cr = cairo_create (surface); gtk_render_background (context, cr, 0, 0, base_size, base_size); l = pixbufs; idx = 0; cur_x = padding; cur_y = padding; while (l != NULL && idx < 4) { pix = l->data; pix_width = gdk_pixbuf_get_width (pix); pix_height = gdk_pixbuf_get_height (pix); scale_size = MIN (pix_width, pix_height); cairo_save (cr); cairo_translate (cr, cur_x, cur_y); cairo_rectangle (cr, 0, 0, tile_size, tile_size); cairo_clip (cr); cairo_scale (cr, (gdouble) tile_size / (gdouble) scale_size, (gdouble) tile_size / (gdouble) scale_size); gdk_cairo_set_source_pixbuf (cr, pix, 0, 0); cairo_paint (cr); cairo_restore (cr); if ((idx % 2) == 0) { cur_x += tile_size + padding; } else { cur_x = padding; cur_y += tile_size + padding; } idx++; l = l->next; } retval = G_ICON (gdk_pixbuf_get_from_surface (surface, 0, 0, base_size, base_size)); cairo_surface_destroy (surface); cairo_destroy (cr); g_object_unref (context); return retval; }
static gboolean dt_iop_zonesystem_bar_draw(GtkWidget *widget, cairo_t *crf, dt_iop_module_t *self) { dt_iop_zonesystem_gui_data_t *g = (dt_iop_zonesystem_gui_data_t *)self->gui_data; dt_iop_zonesystem_params_t *p = (dt_iop_zonesystem_params_t *)self->params; const int inset = DT_ZONESYSTEM_INSET; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width, height = allocation.height; cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); /* clear background */ cairo_set_source_rgb(cr, .15, .15, .15); cairo_paint(cr); /* translate and scale */ width -= 2 * inset; height -= 2 * inset; cairo_save(cr); cairo_translate(cr, inset, inset); cairo_scale(cr, width, height); /* render the bars */ float zonemap[MAX_ZONE_SYSTEM_SIZE] = { 0 }; _iop_zonesystem_calculate_zonemap(p, zonemap); float s = (1. / (p->size - 2)); cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); for(int i = 0; i < p->size - 1; i++) { /* draw the reference zone */ float z = s * i; cairo_rectangle(cr, (1. / (p->size - 1)) * i, 0, (1. / (p->size - 1)), DT_ZONESYSTEM_REFERENCE_SPLIT - DT_ZONESYSTEM_BAR_SPLIT_WIDTH); cairo_set_source_rgb(cr, z, z, z); cairo_fill(cr); /* draw zone mappings */ cairo_rectangle(cr, zonemap[i], DT_ZONESYSTEM_REFERENCE_SPLIT + DT_ZONESYSTEM_BAR_SPLIT_WIDTH, (zonemap[i + 1] - zonemap[i]), 1.0 - DT_ZONESYSTEM_REFERENCE_SPLIT); cairo_set_source_rgb(cr, z, z, z); cairo_fill(cr); } cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT); cairo_restore(cr); /* render zonebar control lines */ cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE); cairo_set_line_width(cr, 1.); cairo_rectangle(cr, inset, inset, width, height); cairo_set_source_rgb(cr, .1, .1, .1); cairo_stroke(cr); cairo_set_antialias(cr, CAIRO_ANTIALIAS_DEFAULT); /* render control points handles */ cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.)); const float arrw = DT_PIXEL_APPLY_DPI(7.0f); for(int k = 1; k < p->size - 1; k++) { float nzw = zonemap[k + 1] - zonemap[k]; float pzw = zonemap[k] - zonemap[k - 1]; if((((g->mouse_x / width) > (zonemap[k] - (pzw / 2.0))) && ((g->mouse_x / width) < (zonemap[k] + (nzw / 2.0)))) || p->zone[k] != -1) { gboolean is_under_mouse = ((width * zonemap[k]) - arrw * .5f < g->mouse_x && (width * zonemap[k]) + arrw * .5f > g->mouse_x); cairo_move_to(cr, inset + (width * zonemap[k]), height + (2 * inset) - 1); cairo_rel_line_to(cr, -arrw * .5f, 0); cairo_rel_line_to(cr, arrw * .5f, -arrw); cairo_rel_line_to(cr, arrw * .5f, arrw); cairo_close_path(cr); if(is_under_mouse) cairo_fill(cr); else cairo_stroke(cr); } } /* push mem surface into widget */ cairo_destroy(cr); cairo_set_source_surface(crf, cst, 0, 0); cairo_paint(crf); cairo_surface_destroy(cst); return TRUE; }
static cairo_test_status_t draw (cairo_t *cr, int width, int height) { /* Paint background white, then draw in black. */ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ cairo_paint (cr); cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */ cairo_set_line_width (cr, 1.0); cairo_translate (cr, 1, 1); /* Draw everything first with square caps. */ cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); /* Draw horizontal and vertical segments, each in both * directions. */ cairo_move_to (cr, 4.5, 0.5); cairo_rel_line_to (cr, 2.0, 0.0); cairo_move_to (cr, 10.5, 4.5); cairo_rel_line_to (cr, 0.0, 2.0); cairo_move_to (cr, 6.5, 10.5); cairo_rel_line_to (cr, -2.0, 0.0); cairo_move_to (cr, 0.5, 6.5); cairo_rel_line_to (cr, 0.0, -2.0); /* Draw right angle turns in four directions. */ cairo_move_to (cr, 0.5, 2.5); cairo_rel_line_to (cr, 0.0, -2.0); cairo_rel_line_to (cr, 2.0, 0.0); cairo_move_to (cr, 8.5, 0.5); cairo_rel_line_to (cr, 2.0, 0.0); cairo_rel_line_to (cr, 0.0, 2.0); cairo_move_to (cr, 10.5, 8.5); cairo_rel_line_to (cr, 0.0, 2.0); cairo_rel_line_to (cr, -2.0, 0.0); cairo_move_to (cr, 2.5, 10.5); cairo_rel_line_to (cr, -2.0, 0.0); cairo_rel_line_to (cr, 0.0, -2.0); /* Draw a closed-path rectangle */ cairo_rectangle (cr, 0.5, 12.5, 10.0, 10.0); cairo_stroke (cr); cairo_translate (cr, 12, 0); /* Now draw the same results, but with butt caps. */ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); /* Draw horizontal and vertical segments, each in both * directions. */ cairo_move_to (cr, 4.0, 0.5); cairo_rel_line_to (cr, 3.0, 0.0); cairo_move_to (cr, 10.5, 4.0); cairo_rel_line_to (cr, 0.0, 3.0); cairo_move_to (cr, 7.0, 10.5); cairo_rel_line_to (cr, -3.0, 0.0); cairo_move_to (cr, 0.5, 7.0); cairo_rel_line_to (cr, 0.0, -3.0); /* Draw right angle turns in four directions. */ cairo_move_to (cr, 0.5, 3.0); cairo_rel_line_to (cr, 0.0, -2.5); cairo_rel_line_to (cr, 2.5, 0.0); cairo_move_to (cr, 8.0, 0.5); cairo_rel_line_to (cr, 2.5, 0.0); cairo_rel_line_to (cr, 0.0, 2.5); cairo_move_to (cr, 10.5, 8.0); cairo_rel_line_to (cr, 0.0, 2.5); cairo_rel_line_to (cr, -2.5, 0.0); cairo_move_to (cr, 3.0, 10.5); cairo_rel_line_to (cr, -2.5, 0.0); cairo_rel_line_to (cr, 0.0, -2.5); /* Draw a closed-path rectangle */ cairo_rectangle (cr, 0.5, 12.5, 10.0, 10.0); /* Draw a path that is rectilinear initially, but not completely */ /* We draw this out of the target window. The bug that caused this * addition was leaks if part of the path was rectilinear but not * completely */ cairo_move_to (cr, 3.0, 30.5); cairo_rel_line_to (cr, -2.5, 0.0); cairo_rel_line_to (cr, +2.5, +2.5); cairo_stroke (cr); return CAIRO_TEST_SUCCESS; }
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d P A N G O I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadPANGOImage() reads an image in the Pango Markup Language Format. % % The format of the ReadPANGOImage method is: % % Image *ReadPANGOImage(const ImageInfo *image_info, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image_info: the image info. % % o exception: return any errors or warnings in this structure. % */ static Image *ReadPANGOImage(const ImageInfo *image_info, ExceptionInfo *exception) { cairo_font_options_t *font_options; cairo_surface_t *surface; char *caption, *property; cairo_t *cairo_image; const char *option; DrawInfo *draw_info; Image *image; MagickBooleanType status; PangoAlignment align; PangoContext *context; PangoFontMap *fontmap; PangoGravity gravity; PangoLayout *layout; PangoRectangle extent; PixelPacket fill_color; RectangleInfo page; register unsigned char *p; size_t stride; ssize_t y; unsigned char *pixels; /* Initialize Image structure. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickSignature); if (image_info->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); image=AcquireImage(image_info); (void) ResetImagePage(image,"0x0+0+0"); /* Format caption. */ option=GetImageOption(image_info,"filename"); if (option == (const char *) NULL) property=InterpretImageProperties(image_info,image,image_info->filename); else if (LocaleNCompare(option,"pango:",6) == 0) property=InterpretImageProperties(image_info,image,option+6); else property=InterpretImageProperties(image_info,image,option); (void) SetImageProperty(image,"caption",property); property=DestroyString(property); caption=ConstantString(GetImageProperty(image,"caption")); /* Get context. */ fontmap=pango_cairo_font_map_new(); pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(fontmap), image->x_resolution); font_options=cairo_font_options_create(); option=GetImageOption(image_info,"pango:hinting"); if (option != (const char *) NULL) { if (LocaleCompare(option,"none") != 0) cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_NONE); if (LocaleCompare(option,"full") != 0) cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_FULL); } context=pango_font_map_create_context(fontmap); pango_cairo_context_set_font_options(context,font_options); cairo_font_options_destroy(font_options); option=GetImageOption(image_info,"pango:language"); if (option != (const char *) NULL) pango_context_set_language(context,pango_language_from_string(option)); draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL); pango_context_set_base_dir(context,draw_info->direction == RightToLeftDirection ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR); switch (draw_info->gravity) { case NorthGravity: { gravity=PANGO_GRAVITY_NORTH; break; } case NorthWestGravity: case WestGravity: case SouthWestGravity: { gravity=PANGO_GRAVITY_WEST; break; } case NorthEastGravity: case EastGravity: case SouthEastGravity: { gravity=PANGO_GRAVITY_EAST; break; } case SouthGravity: { gravity=PANGO_GRAVITY_SOUTH; break; } default: { gravity=PANGO_GRAVITY_AUTO; break; } } pango_context_set_base_gravity(context,gravity); option=GetImageOption(image_info,"pango:gravity-hint"); if (option != (const char *) NULL) { if (LocaleCompare(option,"line") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_LINE); if (LocaleCompare(option,"natural") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_NATURAL); if (LocaleCompare(option,"strong") == 0) pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_STRONG); } /* Configure layout. */ layout=pango_layout_new(context); option=GetImageOption(image_info,"pango:auto-dir"); if (option != (const char *) NULL) pango_layout_set_auto_dir(layout,1); option=GetImageOption(image_info,"pango:ellipsize"); if (option != (const char *) NULL) { if (LocaleCompare(option,"end") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_END); if (LocaleCompare(option,"middle") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_MIDDLE); if (LocaleCompare(option,"none") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_NONE); if (LocaleCompare(option,"start") == 0) pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_START); } option=GetImageOption(image_info,"pango:justify"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse)) pango_layout_set_justify(layout,1); option=GetImageOption(image_info,"pango:single-paragraph"); if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse)) pango_layout_set_single_paragraph_mode(layout,1); option=GetImageOption(image_info,"pango:wrap"); if (option != (const char *) NULL) { if (LocaleCompare(option,"char") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_CHAR); if (LocaleCompare(option,"word") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_WORD); if (LocaleCompare(option,"word-char") == 0) pango_layout_set_wrap(layout,PANGO_WRAP_WORD_CHAR); } option=GetImageOption(image_info,"pango:indent"); if (option != (const char *) NULL) pango_layout_set_indent(layout,(int) ((StringToLong(option)* image->x_resolution*PANGO_SCALE+36)/72.0+0.5)); switch (draw_info->align) { case CenterAlign: align=PANGO_ALIGN_CENTER; break; case RightAlign: align=PANGO_ALIGN_RIGHT; break; case LeftAlign: align=PANGO_ALIGN_LEFT; break; default: { if (draw_info->gravity == CenterGravity) { align=PANGO_ALIGN_CENTER; break; } align=PANGO_ALIGN_LEFT; break; } } if ((align != PANGO_ALIGN_CENTER) && (draw_info->direction == RightToLeftDirection)) align=(PangoAlignment) (PANGO_ALIGN_LEFT+PANGO_ALIGN_RIGHT-align); pango_layout_set_alignment(layout,align); if (draw_info->font != (char *) NULL) { PangoFontDescription *description; /* Set font. */ description=pango_font_description_from_string(draw_info->font); pango_font_description_set_size(description,(int) (PANGO_SCALE* draw_info->pointsize+0.5)); pango_layout_set_font_description(layout,description); pango_font_description_free(description); } option=GetImageOption(image_info,"pango:markup"); if ((option != (const char *) NULL) && (IsMagickTrue(option) == MagickFalse)) pango_layout_set_text(layout,caption,-1); else { GError *error; error=(GError *) NULL; if (pango_parse_markup(caption,-1,0,NULL,NULL,NULL,&error) == 0) (void) ThrowMagickException(exception,GetMagickModule(),CoderError, error->message,"`%s'",image_info->filename); pango_layout_set_markup(layout,caption,-1); } pango_layout_context_changed(layout); page.x=0; page.y=0; if (image_info->page != (char *) NULL) (void) ParseAbsoluteGeometry(image_info->page,&page); if (image->columns == 0) { pango_layout_get_pixel_extents(layout,NULL,&extent); image->columns=extent.x+extent.width+2*page.x; } else { image->columns-=2*page.x; pango_layout_set_width(layout,(int) ((PANGO_SCALE*image->columns* image->x_resolution+36.0)/72.0+0.5)); } if (image->rows == 0) { pango_layout_get_pixel_extents(layout,NULL,&extent); image->rows=extent.y+extent.height+2*page.y; } else { image->rows-=2*page.y; pango_layout_set_height(layout,(int) ((PANGO_SCALE*image->rows* image->y_resolution+36.0)/72.0+0.5)); } /* Render markup. */ stride=(size_t) cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, image->columns); pixels=(unsigned char *) AcquireQuantumMemory(image->rows,stride* sizeof(*pixels)); if (pixels == (unsigned char *) NULL) { draw_info=DestroyDrawInfo(draw_info); caption=DestroyString(caption); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } surface=cairo_image_surface_create_for_data(pixels,CAIRO_FORMAT_ARGB32, image->columns,image->rows,stride); cairo_image=cairo_create(surface); cairo_set_operator(cairo_image,CAIRO_OPERATOR_CLEAR); cairo_paint(cairo_image); cairo_set_operator(cairo_image,CAIRO_OPERATOR_OVER); cairo_translate(cairo_image,page.x,page.y); pango_cairo_show_layout(cairo_image,layout); cairo_destroy(cairo_image); cairo_surface_destroy(surface); g_object_unref(layout); g_object_unref(fontmap); /* Convert surface to image. */ (void) SetImageBackgroundColor(image); p=pixels; for (y=0; y < (ssize_t) image->rows; y++) { register PixelPacket *q; register ssize_t x; q=GetAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) break; for (x=0; x < (ssize_t) image->columns; x++) { double gamma; fill_color.blue=ScaleCharToQuantum(*p++); fill_color.green=ScaleCharToQuantum(*p++); fill_color.red=ScaleCharToQuantum(*p++); fill_color.opacity=QuantumRange-ScaleCharToQuantum(*p++); /* Disassociate alpha. */ gamma=1.0-QuantumScale*fill_color.opacity; gamma=PerceptibleReciprocal(gamma); fill_color.blue*=gamma; fill_color.green*=gamma; fill_color.red*=gamma; MagickCompositeOver(&fill_color,fill_color.opacity,q,(MagickRealType) q->opacity,q); q++; } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; if (image->previous == (Image *) NULL) { status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, image->rows); if (status == MagickFalse) break; } } /* Relinquish resources. */ pixels=(unsigned char *) RelinquishMagickMemory(pixels); draw_info=DestroyDrawInfo(draw_info); caption=DestroyString(caption); return(GetFirstImageInList(image)); }
static void BM_NewPage(const pGEcontext gc, pDevDesc dd) { pX11Desc xd = (pX11Desc) dd->deviceSpecific; char buf[PATH_MAX]; cairo_status_t res; xd->npages++; if (xd->type == PNG || xd->type == JPEG || xd->type == BMP) { if (xd->npages > 1) { /* try to preserve the page we do have */ BM_Close_bitmap(xd); if (xd->fp) fclose(xd->fp); } snprintf(buf, PATH_MAX, xd->filename, xd->npages); xd->fp = R_fopen(R_ExpandFileName(buf), "wb"); if (!xd->fp) error(_("could not open file '%s'"), buf); } else if(xd->type == PNGdirect || xd->type == TIFF) { if (xd->npages > 1) { xd->npages--; BM_Close_bitmap(xd); xd->npages++; } } #ifdef HAVE_CAIRO_SVG else if(xd->type == SVG) { if (xd->npages > 1 && xd->cs) { cairo_show_page(xd->cc); if(!xd->onefile) { cairo_surface_destroy(xd->cs); cairo_destroy(xd->cc); } } if(xd->npages == 1 || !xd->onefile) { snprintf(buf, PATH_MAX, xd->filename, xd->npages); xd->cs = cairo_svg_surface_create(R_ExpandFileName(buf), (double)xd->windowWidth, (double)xd->windowHeight); res = cairo_surface_status(xd->cs); if (res != CAIRO_STATUS_SUCCESS) { xd->cs = NULL; error("cairo error '%s'", cairo_status_to_string(res)); } if(xd->onefile) cairo_svg_surface_restrict_to_version(xd->cs, CAIRO_SVG_VERSION_1_2); xd->cc = cairo_create(xd->cs); res = cairo_status(xd->cc); if (res != CAIRO_STATUS_SUCCESS) { error("cairo error '%s'", cairo_status_to_string(res)); } cairo_set_antialias(xd->cc, xd->antialias); } } #endif #ifdef HAVE_CAIRO_PDF else if(xd->type == PDF) { if (xd->npages > 1) { cairo_show_page(xd->cc); if(!xd->onefile) { cairo_surface_destroy(xd->cs); cairo_destroy(xd->cc); } } if(xd->npages == 1 || !xd->onefile) { snprintf(buf, PATH_MAX, xd->filename, xd->npages); xd->cs = cairo_pdf_surface_create(R_ExpandFileName(buf), (double)xd->windowWidth, (double)xd->windowHeight); res = cairo_surface_status(xd->cs); if (res != CAIRO_STATUS_SUCCESS) { error("cairo error '%s'", cairo_status_to_string(res)); } xd->cc = cairo_create(xd->cs); res = cairo_status(xd->cc); if (res != CAIRO_STATUS_SUCCESS) { error("cairo error '%s'", cairo_status_to_string(res)); } cairo_set_antialias(xd->cc, xd->antialias); } } #endif #ifdef HAVE_CAIRO_PS else if(xd->type == PS) { if (xd->npages > 1 && !xd->onefile) { cairo_show_page(xd->cc); cairo_surface_destroy(xd->cs); cairo_destroy(xd->cc); } if(xd->npages == 1 || !xd->onefile) { snprintf(buf, PATH_MAX, xd->filename, xd->npages); xd->cs = cairo_ps_surface_create(R_ExpandFileName(buf), (double)xd->windowWidth, (double)xd->windowHeight); res = cairo_surface_status(xd->cs); if (res != CAIRO_STATUS_SUCCESS) { error("cairo error '%s'", cairo_status_to_string(res)); } // We already require >= 1.2 #if CAIRO_VERSION_MAJOR > 2 || CAIRO_VERSION_MINOR >= 6 if(!xd->onefile) cairo_ps_surface_set_eps(xd->cs, TRUE); #endif xd->cc = cairo_create(xd->cs); res = cairo_status(xd->cc); if (res != CAIRO_STATUS_SUCCESS) { error("cairo error '%s'", cairo_status_to_string(res)); } cairo_set_antialias(xd->cc, xd->antialias); } } #endif else error(_("unimplemented cairo-based device")); cairo_reset_clip(xd->cc); if (xd->type == PNG || xd->type == TIFF|| xd->type == PNGdirect) { /* First clear it */ cairo_set_operator (xd->cc, CAIRO_OPERATOR_CLEAR); cairo_paint (xd->cc); cairo_set_operator (xd->cc, CAIRO_OPERATOR_OVER); xd->fill = gc->fill; } else xd->fill = R_OPAQUE(gc->fill) ? gc->fill: xd->canvas; CairoColor(xd->fill, xd); cairo_new_path(xd->cc); cairo_paint(xd->cc); }
static gint expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer data) #endif { MateColorButton *color_button = MATE_COLOR_BUTTON (data); GtkAllocation allocation; cairo_pattern_t *checkered; #if !GTK_CHECK_VERSION (3, 0, 0) cairo_t *cr; cr = gdk_cairo_create (event->window); gtk_widget_get_allocation (widget, &allocation); gdk_cairo_rectangle (cr, &allocation); cairo_clip (cr); #endif if (mate_color_button_has_alpha (color_button)) { cairo_save (cr); cairo_set_source_rgb (cr, CHECK_DARK, CHECK_DARK, CHECK_DARK); cairo_paint (cr); cairo_set_source_rgb (cr, CHECK_LIGHT, CHECK_LIGHT, CHECK_LIGHT); cairo_scale (cr, CHECK_SIZE, CHECK_SIZE); checkered = mate_color_button_get_checkered (); cairo_mask (cr, checkered); cairo_pattern_destroy (checkered); cairo_restore (cr); cairo_set_source_rgba (cr, color_button->priv->color.red / 65535., color_button->priv->color.green / 65535., color_button->priv->color.blue / 65535., color_button->priv->alpha / 65535.); } else { gdk_cairo_set_source_color (cr, &color_button->priv->color); } cairo_paint (cr); if (!gtk_widget_is_sensitive (GTK_WIDGET (color_button))) { gdk_cairo_set_source_color (cr, >k_widget_get_style (GTK_WIDGET(color_button))->bg[GTK_STATE_INSENSITIVE]); checkered = mate_color_button_get_checkered (); cairo_mask (cr, checkered); cairo_pattern_destroy (checkered); } #if !GTK_CHECK_VERSION (3, 0, 0) cairo_destroy (cr); #endif return FALSE; }
void panadapter_update(float *data,int tx) { int i; int result; float saved_max; float saved_min; gfloat saved_hz_per_pixel; cairo_text_extents_t extents; hz_per_pixel=(double)getSampleRate()/(double)display_width; samples=data; //if(result==1) { if(panadapter_surface) { if(tx) { saved_max=panadapter_high; saved_min=panadapter_low; saved_hz_per_pixel=hz_per_pixel; panadapter_high=20; panadapter_low=-80; //if(protocol==ORIGINAL_PROTOCOL) { hz_per_pixel=48000.0/(double)display_width; //} else { // hz_per_pixel=192000.0/(double)display_width; //} } //clear_panadater_surface(); cairo_t *cr; cr = cairo_create (panadapter_surface); cairo_set_source_rgb (cr, 0, 0, 0); cairo_paint (cr); // filter cairo_set_source_rgb (cr, 0.25, 0.25, 0.25); if(ctun && isTransmitting()) { filter_left=(double)display_width/2.0+((double)getFilterLow()/hz_per_pixel); filter_right=(double)display_width/2.0+((double)getFilterHigh()/hz_per_pixel); } else { filter_left=(double)display_width/2.0+(((double)getFilterLow()+ddsOffset)/hz_per_pixel); filter_right=(double)display_width/2.0+(((double)getFilterHigh()+ddsOffset)/hz_per_pixel); } cairo_rectangle(cr, filter_left, 0.0, filter_right-filter_left, (double)display_height); cairo_fill(cr); // plot the levels int V = (int)(panadapter_high - panadapter_low); int numSteps = V / 20; for (i = 1; i < numSteps; i++) { int num = panadapter_high - i * 20; int y = (int)floor((panadapter_high - num) * display_height / V); cairo_set_source_rgb (cr, 0, 1, 1); cairo_set_line_width(cr, 1.0); cairo_move_to(cr,0.0,(double)y); cairo_line_to(cr,(double)display_width,(double)y); cairo_set_source_rgb (cr, 0, 1, 1); cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 12); char v[32]; sprintf(v,"%d dBm",num); cairo_move_to(cr, 1, (double)y); cairo_show_text(cr, v); } cairo_stroke(cr); // plot frequency markers long f; long divisor=20000; long half=(long)getSampleRate()/2L; long frequency=getFrequency(); if(ctun && isTransmitting()) { frequency+=ddsOffset; } switch(sample_rate) { case 48000: divisor=5000L; break; case 96000: case 100000: divisor=10000L; break; case 192000: divisor=20000L; break; case 384000: divisor=25000L; break; case 768000: divisor=50000L; break; case 1048576: case 1536000: case 2097152: divisor=100000L; break; } for(i=0;i<display_width;i++) { f = frequency - half + (long) (hz_per_pixel * i); if (f > 0) { if ((f % divisor) < (long) hz_per_pixel) { cairo_set_source_rgb (cr, 0, 1, 1); cairo_set_line_width(cr, 1.0); //cairo_move_to(cr,(double)i,0.0); cairo_move_to(cr,(double)i,10.0); cairo_line_to(cr,(double)i,(double)display_height); cairo_set_source_rgb (cr, 0, 1, 1); cairo_select_font_face(cr, "FreeMono", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size(cr, 12); char v[32]; sprintf(v,"%0ld.%03ld",f/1000000,(f%1000000)/1000); //cairo_move_to(cr, (double)i, (double)(display_height-10)); cairo_text_extents(cr, v, &extents); cairo_move_to(cr, (double)i-(extents.width/2.0), 10.0); cairo_show_text(cr, v); } } } cairo_stroke(cr); // band edges long min_display=frequency-half; long max_display=frequency+half; BAND_LIMITS* bandLimits=getBandLimits(min_display,max_display); if(bandLimits!=NULL) { cairo_set_source_rgb (cr, 1, 0, 0); cairo_set_line_width(cr, 2.0); if((min_display<bandLimits->minFrequency)&&(max_display>bandLimits->minFrequency)) { i=(bandLimits->minFrequency-min_display)/(long long)hz_per_pixel; cairo_move_to(cr,(double)i,0.0); cairo_line_to(cr,(double)i,(double)display_height); } if((min_display<bandLimits->maxFrequency)&&(max_display>bandLimits->maxFrequency)) { i=(bandLimits->maxFrequency-min_display)/(long long)hz_per_pixel; cairo_move_to(cr,(double)i,0.0); cairo_line_to(cr,(double)i,(double)display_height); } } // agc if(agc!=AGC_OFF && !tx) { double hang=0.0; double thresh=0; GetRXAAGCHangLevel(CHANNEL_RX0, &hang); GetRXAAGCThresh(CHANNEL_RX0, &thresh, 4096.0, (double)sample_rate); double knee_y=thresh+(double)get_attenuation(); knee_y = floor((panadapter_high - knee_y) * (double) display_height / (panadapter_high - panadapter_low)); double hang_y=hang+(double)get_attenuation(); hang_y = floor((panadapter_high - hang_y) * (double) display_height / (panadapter_high - panadapter_low)); //fprintf(stderr,"hang=%f thresh=%f hang_y=%f knee_y=%f\n",rx1_hang,rx1_thresh,hang_y,knee_y); if(agc!=AGC_MEDIUM && agc!=AGC_FAST) { cairo_set_source_rgb (cr, 1.0, 1.0, 0.0); cairo_move_to(cr,40.0,hang_y-8.0); cairo_rectangle(cr, 40, hang_y-8.0,8.0,8.0); cairo_fill(cr); cairo_move_to(cr,40.0,hang_y); cairo_line_to(cr,(double)display_width-40.0,hang_y); cairo_stroke(cr); cairo_move_to(cr,48.0,hang_y); cairo_show_text(cr, "-H"); } cairo_set_source_rgb (cr, 0.0, 1.0, 0.0); cairo_move_to(cr,40.0,knee_y-8.0); cairo_rectangle(cr, 40, knee_y-8.0,8.0,8.0); cairo_fill(cr); cairo_move_to(cr,40.0,knee_y); cairo_line_to(cr,(double)display_width-40.0,knee_y); cairo_stroke(cr); cairo_move_to(cr,48.0,knee_y); cairo_show_text(cr, "-G"); } // cursor cairo_set_source_rgb (cr, 1, 0, 0); cairo_set_line_width(cr, 1.0); cairo_move_to(cr,(double)(display_width/2.0)+(ddsOffset/hz_per_pixel),0.0); cairo_line_to(cr,(double)(display_width/2.0)+(ddsOffset/hz_per_pixel),(double)display_height); cairo_stroke(cr); // signal double s1,s2; samples[0]=-200.0; samples[display_width-1]=-200.0; if(tx && protocol==NEW_PROTOCOL) { int offset=1200; s1=(double)samples[0+offset]+(double)get_attenuation(); s1 = floor((panadapter_high - s1) * (double) display_height / (panadapter_high - panadapter_low)); cairo_move_to(cr, 0.0, s1); for(i=1;i<display_width;i++) { s2=(double)samples[i+offset]+(double)get_attenuation(); s2 = floor((panadapter_high - s2) * (double) display_height / (panadapter_high - panadapter_low)); cairo_line_to(cr, (double)i, s2); } } else { s1=(double)samples[0]+(double)get_attenuation(); s1 = floor((panadapter_high - s1) * (double) display_height / (panadapter_high - panadapter_low)); cairo_move_to(cr, 0.0, s1); for(i=1;i<display_width;i++) { s2=(double)samples[i]+(double)get_attenuation(); s2 = floor((panadapter_high - s2) * (double) display_height / (panadapter_high - panadapter_low)); cairo_line_to(cr, (double)i, s2); } } if(display_filled) { cairo_close_path (cr); cairo_set_source_rgba(cr, 1, 1, 1,0.5); cairo_fill_preserve (cr); } cairo_set_source_rgb(cr, 1, 1, 1); cairo_set_line_width(cr, 1.0); cairo_stroke(cr); #ifdef FREEDV if(mode==modeFREEDV) { if(tx) { cairo_set_source_rgb(cr, 1, 0, 0); } else { cairo_set_source_rgb(cr, 0, 1, 0); } cairo_set_font_size(cr, 16); cairo_text_extents(cr, freedv_text_data, &extents); cairo_move_to(cr, (double)display_width/2.0-(extents.width/2.0),(double)display_height-2.0); cairo_show_text(cr, freedv_text_data); } #endif cairo_destroy (cr); gtk_widget_queue_draw (panadapter); if(tx) { panadapter_high=saved_max; panadapter_low=saved_min; hz_per_pixel=saved_hz_per_pixel; } /* else if(mode==modeFREEDV) { panadapter_high=saved_max; panadapter_low=saved_min; hz_per_pixel=saved_hz_per_pixel; } */ } //} }
static gboolean UpdatePreviewWindow( GtkWidget* widget, cairo_t* cairo_p, APPLICATION* app ) #endif { // 描画領域のサイズ取得用 GtkAllocation preview_allocation; #if GTK_MAJOR_VERSION <= 2 // 描画用のCairo情報 cairo_t *cairo_p; #endif // 描画領域1行分のバイト数 int stride; // 拡大率更新のフラグ int update_zoom = 0; if(app->window_num == 0) { return FALSE; } gtk_widget_get_allocation(app->preview_window.image, &preview_allocation); stride = preview_allocation.width * 4; if(app->preview_window.width != preview_allocation.width || app->preview_window.height != preview_allocation.height) { app->preview_window.pixels = (uint8*)MEM_REALLOC_FUNC( app->preview_window.pixels, preview_allocation.height * stride); app->preview_window.reverse_buff = (uint8*)MEM_REALLOC_FUNC( app->preview_window.reverse_buff, stride); app->preview_window.width = preview_allocation.width; app->preview_window.height = preview_allocation.height; if(app->preview_window.cairo_p != NULL) { cairo_destroy(app->preview_window.cairo_p); cairo_surface_destroy(app->preview_window.surface_p); } // CAIRO情報作り直し app->preview_window.surface_p = cairo_image_surface_create_for_data(app->preview_window.pixels, CAIRO_FORMAT_ARGB32, preview_allocation.width, preview_allocation.height, stride); app->preview_window.cairo_p = cairo_create(app->preview_window.surface_p); // 拡大率の更新 update_zoom++; } // 描画領域の変更やウィンドウサイズの変更があれば拡大率を更新 if(update_zoom != 0 || app->draw_window[app->active_window] != app->preview_window.draw) { gdouble zoom_x = (gdouble)preview_allocation.width / app->draw_window[app->active_window]->width; gdouble zoom_y = (gdouble)preview_allocation.height / app->draw_window[app->active_window]->height; if(zoom_x < zoom_y) { app->preview_window.zoom = zoom_x; app->preview_window.rev_zoom = 1 / zoom_x; } else { app->preview_window.zoom = zoom_y; app->preview_window.rev_zoom = 1 / zoom_y; } app->preview_window.draw_width = (int32)(app->draw_window[app->active_window]->width * app->preview_window.zoom); app->preview_window.draw_height = (int32)(app->draw_window[app->active_window]->height * app->preview_window.zoom); } // 画像を拡大縮小して描画 cairo_scale(app->preview_window.cairo_p, app->preview_window.zoom, app->preview_window.zoom); cairo_set_source_surface(app->preview_window.cairo_p, app->draw_window[app->active_window]->mixed_layer->surface_p, 0, 0); cairo_paint(app->preview_window.cairo_p); // 拡大率を元に戻す cairo_scale(app->preview_window.cairo_p, app->preview_window.rev_zoom, app->preview_window.rev_zoom); // 左右反転表示中ならピクセルデータを反転 if((app->draw_window[app->active_window]->flags & DRAW_WINDOW_DISPLAY_HORIZON_REVERSE) != 0) { uint8 *src, *ref; int x, y; for(y=0; y<app->preview_window.draw_height; y++) { ref = app->preview_window.reverse_buff; src = &app->preview_window.pixels[y*stride+app->preview_window.draw_width*4-4]; for(x=0; x<app->preview_window.draw_width; x++, ref += 4, src -= 4) { ref[0] = src[0], ref[1] = src[1], ref[2] = src[2], ref[3] = src[3]; } (void)memcpy(src+4, app->preview_window.reverse_buff, app->preview_window.draw_width * 4); } } // 画面更新 #if GTK_MAJOR_VERSION <= 2 //cairo_p = kaburagi_cairo_create((struct _GdkWindow*)app->preview_window.image->window); cairo_p = gdk_cairo_create(app->preview_window.image->window); #endif cairo_rectangle(cairo_p, 0, 0, app->preview_window.draw_width, app->preview_window.draw_height); cairo_clip(cairo_p); cairo_set_source_surface(cairo_p, app->preview_window.surface_p, 0, 0); cairo_paint(cairo_p); #if GTK_MAJOR_VERSION <= 2 cairo_destroy(cairo_p); #endif return TRUE; }
static gboolean _lib_navigation_draw_callback(GtkWidget *widget, cairo_t *crf, gpointer user_data) { dt_lib_module_t *self = (dt_lib_module_t *)user_data; dt_lib_navigation_t *d = (dt_lib_navigation_t *)self->data; const int inset = DT_NAVIGATION_INSET; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width, height = allocation.height; dt_develop_t *dev = darktable.develop; /* double buffering of image data: only take new data if valid */ if(dev->preview_pipe->backbuf && dev->preview_status == DT_DEV_PIXELPIPE_VALID) { /* re-allocate in case of changed image dimensions */ if(d->buffer == NULL || dev->preview_pipe->backbuf_width != d->wd || dev->preview_pipe->backbuf_height != d->ht) { g_free(d->buffer); d->wd = dev->preview_pipe->backbuf_width; d->ht = dev->preview_pipe->backbuf_height; d->buffer = g_malloc0((size_t)d->wd * d->ht * 4 * sizeof(unsigned char)); } /* update buffer if new data is available */ if(d->buffer && dev->preview_pipe->input_timestamp > d->timestamp) { dt_pthread_mutex_t *mutex = &dev->preview_pipe->backbuf_mutex; dt_pthread_mutex_lock(mutex); memcpy(d->buffer, dev->preview_pipe->backbuf, (size_t)d->wd * d->ht * 4 * sizeof(unsigned char)); d->timestamp = dev->preview_pipe->input_timestamp; dt_pthread_mutex_unlock(mutex); } } /* get the current style */ cairo_surface_t *cst = dt_cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); GtkStyleContext *context = gtk_widget_get_style_context(widget); gtk_render_background(context, cr, 0, 0, allocation.width, allocation.height); width -= 2 * inset; height -= 2 * inset; cairo_translate(cr, inset, inset); /* draw navigation image if available */ if(d->buffer) { cairo_save(cr); const int wd = d->wd; const int ht = d->ht; const float scale = fminf(width / (float)wd, height / (float)ht); const int stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, wd); cairo_surface_t *surface = cairo_image_surface_create_for_data(d->buffer, CAIRO_FORMAT_RGB24, wd, ht, stride); cairo_translate(cr, width / 2.0, height / 2.0f); cairo_scale(cr, scale, scale); cairo_translate(cr, -.5f * wd, -.5f * ht); // draw shadow around float alpha = 1.0f; for(int k = 0; k < 4; k++) { cairo_rectangle(cr, -k / scale, -k / scale, wd + 2 * k / scale, ht + 2 * k / scale); cairo_set_source_rgba(cr, 0, 0, 0, alpha); alpha *= 0.6f; cairo_fill(cr); } cairo_rectangle(cr, 0, 0, wd - 2, 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); // draw box where we are dt_dev_zoom_t zoom = dt_control_get_dev_zoom(); int closeup = dt_control_get_dev_closeup(); float zoom_x = dt_control_get_dev_zoom_x(); float zoom_y = dt_control_get_dev_zoom_y(); const float min_scale = dt_dev_get_zoom_scale(dev, DT_ZOOM_FIT, closeup ? 2.0 : 1.0, 0); const float cur_scale = dt_dev_get_zoom_scale(dev, zoom, closeup ? 2.0 : 1.0, 0); // avoid numerical instability for small resolutions: double h, w; if(cur_scale > min_scale) { float boxw = 1, boxh = 1; dt_dev_check_zoom_bounds(darktable.develop, &zoom_x, &zoom_y, zoom, closeup, &boxw, &boxh); cairo_translate(cr, wd * (.5f + zoom_x), ht * (.5f + zoom_y)); cairo_set_source_rgb(cr, 0., 0., 0.); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(1.f / scale)); boxw *= wd; boxh *= ht; cairo_rectangle(cr, -boxw / 2 - 1, -boxh / 2 - 1, boxw + 2, boxh + 2); cairo_stroke(cr); cairo_set_source_rgb(cr, 1., 1., 1.); cairo_rectangle(cr, -boxw / 2, -boxh / 2, boxw, boxh); cairo_stroke(cr); } cairo_restore(cr); if(fabsf(cur_scale - min_scale) > 0.001f) { /* Zoom % */ PangoLayout *layout; PangoRectangle ink; PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); layout = pango_cairo_create_layout(cr); const float fontsize = DT_PIXEL_APPLY_DPI(11); pango_font_description_set_absolute_size(desc, fontsize * PANGO_SCALE); pango_layout_set_font_description(layout, desc); cairo_translate(cr, 0, height); cairo_set_source_rgba(cr, 1., 1., 1., 0.5); cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); char zoomline[5]; snprintf(zoomline, sizeof(zoomline), "%.0f%%", cur_scale * 100); pango_layout_set_text(layout, zoomline, -1); pango_layout_get_pixel_extents(layout, &ink, NULL); h = d->zoom_h = ink.height; w = d->zoom_w = ink.width; cairo_move_to(cr, width - w - h * 1.1 - ink.x, - fontsize); cairo_save(cr); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.0)); GdkRGBA *color; gtk_style_context_get(context, gtk_widget_get_state_flags(widget), "background-color", &color, NULL); gdk_cairo_set_source_rgba(cr, color); pango_cairo_layout_path(cr, layout); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_fill(cr); cairo_restore(cr); gdk_rgba_free(color); pango_font_description_free(desc); g_object_unref(layout); } else { // draw the zoom-to-fit icon cairo_translate(cr, 0, height); cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); static int height = -1; if(height == -1) { PangoLayout *layout; PangoRectangle ink; PangoFontDescription *desc = pango_font_description_copy_static(darktable.bauhaus->pango_font_desc); pango_font_description_set_weight(desc, PANGO_WEIGHT_BOLD); layout = pango_cairo_create_layout(cr); pango_font_description_set_absolute_size(desc, DT_PIXEL_APPLY_DPI(11) * PANGO_SCALE); pango_layout_set_font_description(layout, desc); pango_layout_set_text(layout, "100%", -1); // dummy text, just to get the height pango_layout_get_pixel_extents(layout, &ink, NULL); height = ink.height; pango_font_description_free(desc); g_object_unref(layout); } h = d->zoom_h = height; w = h * 1.5; float sp = h * 0.6; d->zoom_w = w + sp; cairo_move_to(cr, width - w - h - sp, -1.0 * h); cairo_rectangle(cr, width - w - h - sp, -1.0 * h, w, h); cairo_set_source_rgb(cr, 0.2, 0.2, 0.2); cairo_fill(cr); cairo_set_line_width(cr, DT_PIXEL_APPLY_DPI(2.0)); cairo_set_source_rgb(cr, 0.6, 0.6, 0.6); cairo_move_to(cr, width - w * 0.8 - h - sp, -1.0 * h); cairo_line_to(cr, width - w - h - sp, -1.0 * h); cairo_line_to(cr, width - w - h - sp, -0.7 * h); cairo_stroke(cr); cairo_move_to(cr, width - w - h - sp, -0.3 * h); cairo_line_to(cr, width - w - h - sp, 0); cairo_line_to(cr, width - w * 0.8 - h - sp, 0); cairo_stroke(cr); cairo_move_to(cr, width - w * 0.2 - h - sp, 0); cairo_line_to(cr, width - h - sp, 0); cairo_line_to(cr, width - h - sp, -0.3 * h); cairo_stroke(cr); cairo_move_to(cr, width - h - sp, -0.7 * h); cairo_line_to(cr, width - h - sp, -1.0 * h); cairo_line_to(cr, width - w * 0.2 - h - sp, -1.0 * h); cairo_stroke(cr); } cairo_move_to(cr, width - 0.95 * h, -0.9 * h); cairo_line_to(cr, width - 0.05 * h, -0.9 * h); cairo_line_to(cr, width - 0.5 * h, -0.1 * h); cairo_fill(cr); } /* blit memsurface into widget */ cairo_destroy(cr); cairo_set_source_surface(crf, cst, 0, 0); cairo_paint(crf); cairo_surface_destroy(cst); return TRUE; }
/** * gpm_applet_draw_cb: * @applet: Inhibit applet instance * * draws applet content (background + icon) **/ static gboolean gpm_applet_draw_cb (GpmInhibitApplet *applet) { gint w, h, bg_type; #if GTK_CHECK_VERSION (3, 0, 0) GdkRGBA color; cairo_t *cr; cairo_pattern_t *pattern; GtkStyleContext *context; #else GdkColor color; GdkGC *gc; GdkPixmap *background; #endif GtkAllocation allocation; if (gtk_widget_get_window (GTK_WIDGET(applet)) == NULL) { return FALSE; } #if !GTK_CHECK_VERSION (3, 0, 0) /* Clear the window so we can draw on it later */ gdk_window_clear(gtk_widget_get_window (GTK_WIDGET (applet))); #endif /* retrieve applet size */ gpm_applet_get_icon (applet); gpm_applet_check_size (applet); if (applet->size <= 2) { return FALSE; } /* if no icon, then don't try to display */ if (applet->icon == NULL) { return FALSE; } gtk_widget_get_allocation (GTK_WIDGET (applet), &allocation); w = allocation.width; h = allocation.height; #if GTK_CHECK_VERSION (3, 0, 0) cr = gdk_cairo_create (gtk_widget_get_window (GTK_WIDGET(applet))); #else gc = gdk_gc_new (gtk_widget_get_window (GTK_WIDGET(applet))); #endif /* draw pixmap background */ #if GTK_CHECK_VERSION (3, 0, 0) bg_type = mate_panel_applet_get_background (MATE_PANEL_APPLET (applet), &color, &pattern); #else bg_type = mate_panel_applet_get_background (MATE_PANEL_APPLET (applet), &color, &background); #endif if (bg_type == PANEL_PIXMAP_BACKGROUND) { /* fill with given background pixmap */ #if GTK_CHECK_VERSION (3, 0, 0) cairo_set_source (cr, pattern); cairo_rectangle (cr, 0, 0, w, h); cairo_fill (cr); #else gdk_draw_drawable (gtk_widget_get_window (GTK_WIDGET(applet)), gc, background, 0, 0, 0, 0, w, h); #endif } /* draw color background */ if (bg_type == PANEL_COLOR_BACKGROUND) { #if GTK_CHECK_VERSION (3, 0, 0) gdk_cairo_set_source_rgba (cr, &color); cairo_rectangle (cr, 0, 0, w, h); cairo_fill (cr); #else gdk_gc_set_rgb_fg_color (gc,&color); gdk_gc_set_fill (gc,GDK_SOLID); gdk_draw_rectangle (gtk_widget_get_window (GTK_WIDGET(applet)), gc, TRUE, 0, 0, w, h); #endif } /* draw icon at center */ #if GTK_CHECK_VERSION (3, 0, 0) gdk_cairo_set_source_pixbuf (cr, applet->icon, (w - applet->icon_width)/2, (h - applet->icon_height)/2); cairo_paint (cr); #else gdk_draw_pixbuf (gtk_widget_get_window (GTK_WIDGET(applet)), gc, applet->icon, 0, 0, (w - applet->icon_width)/2, (h - applet->icon_height)/2, applet->icon_width, applet->icon_height, GDK_RGB_DITHER_NONE, 0, 0); #endif #if GTK_CHECK_VERSION (3, 0, 0) cairo_destroy (cr); #else g_object_unref (gc); #endif return TRUE; }
void draw(cairo_t *cr) { cairo_set_source_surface(cr, image, x-20, y-image_height+20); cairo_paint(cr); }