Beispiel #1
0
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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
/*
 * 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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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);
}
Beispiel #8
0
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);
}
Beispiel #9
0
/** 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;
}
Beispiel #12
0
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);
     }
}
Beispiel #13
0
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);
}
Beispiel #14
0
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);
        }
    }
}
Beispiel #16
0
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;
}
Beispiel #17
0
	void draw(cairo_t *cr)
	{
		cairo_set_source_surface(cr, image, x, y);
		cairo_paint(cr);
	}
Beispiel #18
0
/**
 * 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;
}
Beispiel #19
0
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;
}
Beispiel #20
0
/**
 * 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;
}
Beispiel #21
0
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;
}
Beispiel #22
0
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;
}
Beispiel #23
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   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));
}
Beispiel #24
0
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, &gtk_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;
}
Beispiel #26
0
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;
            } */
        }
    //}
}
Beispiel #27
-1
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;
}
Beispiel #28
-1
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;
}
Beispiel #30
-1
	void draw(cairo_t *cr)
	{
		cairo_set_source_surface(cr, image, x-20, y-image_height+20);
		cairo_paint(cr);
	}