Пример #1
0
static void
gimp_view_renderer_gradient_render (GimpViewRenderer *renderer,
                                    GtkWidget        *widget)
{
  GimpViewRendererGradient *rendergrad = GIMP_VIEW_RENDERER_GRADIENT (renderer);
  GimpGradient             *gradient   = GIMP_GRADIENT (renderer->viewable);
  GimpGradientSegment      *seg        = NULL;
  GimpColorTransform       *transform;
  guchar                   *buf;
  guchar                   *dest;
  gint                      dest_stride;
  gint                      x;
  gint                      y;
  gdouble                   dx, cur_x;
  GimpRGB                   color;

  buf   = g_alloca (4 * renderer->width);
  dx    = (rendergrad->right - rendergrad->left) / (renderer->width - 1);
  cur_x = rendergrad->left;

  for (x = 0, dest = buf; x < renderer->width; x++, dest += 4)
    {
      guchar r, g, b, a;

      seg = gimp_gradient_get_color_at (gradient, renderer->context, seg,
                                        cur_x, rendergrad->reverse, &color);
      cur_x += dx;

      gimp_rgba_get_uchar (&color, &r, &g, &b, &a);

      GIMP_CAIRO_ARGB32_SET_PIXEL (dest, r, g, b, a);
    }

  if (! renderer->surface)
    renderer->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                                    renderer->width,
                                                    renderer->height);

  cairo_surface_flush (renderer->surface);

  dest        = cairo_image_surface_get_data (renderer->surface);
  dest_stride = cairo_image_surface_get_stride (renderer->surface);

  transform = gimp_view_renderer_get_color_transform (renderer, widget,
                                                      babl_format ("cairo-ARGB32"),
                                                      babl_format ("cairo-ARGB32"));

  if (transform)
    gimp_color_transform_process_pixels (transform,
                                         babl_format ("cairo-ARGB32"), buf,
                                         babl_format ("cairo-ARGB32"), buf,
                                         renderer->width);

  for (y = 0; y < renderer->height; y++, dest += dest_stride)
    {
      memcpy (dest, buf, renderer->width * 4);
    }

  cairo_surface_mark_dirty (renderer->surface);
}
Пример #2
0
static void
gimp_view_renderer_palette_render (GimpViewRenderer *renderer,
                                   GtkWidget        *widget)
{
  GimpViewRendererPalette *renderpal = GIMP_VIEW_RENDERER_PALETTE (renderer);
  GimpPalette             *palette;
  GimpColorTransform      *transform;
  guchar                  *row;
  guchar                  *dest;
  GList                   *list;
  gdouble                  cell_width;
  gint                     grid_width;
  gint                     dest_stride;
  gint                     y;

  palette = GIMP_PALETTE (renderer->viewable);

  if (gimp_palette_get_n_colors (palette) == 0)
    return;

  grid_width = renderpal->draw_grid ? 1 : 0;

  if (renderpal->cell_size > 0)
    {
      gint n_columns = gimp_palette_get_columns (palette);

      if (n_columns > 0)
        cell_width = MAX ((gdouble) renderpal->cell_size,
                          (gdouble) (renderer->width - grid_width) /
                          (gdouble) n_columns);
      else
        cell_width = renderpal->cell_size;
    }
  else
    {
      gint n_columns = gimp_palette_get_columns (palette);

      if (n_columns > 0)
        cell_width = ((gdouble) (renderer->width - grid_width) /
                      (gdouble) n_columns);
      else
        cell_width = (gdouble) (renderer->width - grid_width) / 16.0;
    }

  cell_width = MAX (4.0, cell_width);

  renderpal->cell_width = cell_width;

  renderpal->columns = (gdouble) (renderer->width - grid_width) / cell_width;

  renderpal->rows = gimp_palette_get_n_colors (palette) / renderpal->columns;
  if (gimp_palette_get_n_colors (palette) % renderpal->columns)
    renderpal->rows += 1;

  renderpal->cell_height = MAX (4, ((renderer->height - grid_width) /
                                    renderpal->rows));

  if (! renderpal->draw_grid)
    renderpal->cell_height = MIN (renderpal->cell_height,
                                  renderpal->cell_width);

  list = gimp_palette_get_colors (palette);

  if (! renderer->surface)
    renderer->surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
                                                    renderer->width,
                                                    renderer->height);

  cairo_surface_flush (renderer->surface);

  row = g_new (guchar, renderer->width * 4);

  dest        = cairo_image_surface_get_data (renderer->surface);
  dest_stride = cairo_image_surface_get_stride (renderer->surface);

  transform = gimp_view_renderer_get_color_transform (renderer, widget,
                                                      babl_format ("cairo-RGB24"),
                                                      babl_format ("cairo-RGB24"));

  for (y = 0; y < renderer->height; y++)
    {
      if ((y % renderpal->cell_height) == 0)
        {
          guchar  r, g, b;
          gint    x;
          gint    n = 0;
          guchar *d = row;

          memset (row, renderpal->draw_grid ? 0 : 255, renderer->width * 4);

          r = g = b = (renderpal->draw_grid ? 0 : 255);

          for (x = 0; x < renderer->width; x++, d += 4)
            {
              if ((x % renderpal->cell_width) == 0)
                {
                  if (list && n < renderpal->columns &&
                      renderer->width - x >= renderpal->cell_width)
                    {
                      GimpPaletteEntry *entry = list->data;

                      list = g_list_next (list);
                      n++;

                      gimp_rgb_get_uchar (&entry->color, &r, &g, &b);
                    }
                  else
                    {
                      r = g = b = (renderpal->draw_grid ? 0 : 255);
                    }
                }

              if (renderpal->draw_grid && (x % renderpal->cell_width) == 0)
                {
                  GIMP_CAIRO_RGB24_SET_PIXEL (d, 0, 0, 0);
                }
              else
                {
                  GIMP_CAIRO_RGB24_SET_PIXEL (d, r, g, b);
                }
            }
        }

      if (renderpal->draw_grid && (y % renderpal->cell_height) == 0)
        {
          memset (dest, 0, renderer->width * 4);
        }
      else
        {
          if (transform)
            {
              gimp_color_transform_process_pixels (transform,
                                                   babl_format ("cairo-RGB24"),
                                                   row,
                                                   babl_format ("cairo-RGB24"),
                                                   dest,
                                                   renderer->width);
            }
          else
            {
              memcpy (dest, row, renderer->width * 4);
            }
        }

      dest += dest_stride;
    }

  g_free (row);

  cairo_surface_mark_dirty (renderer->surface);
}
Пример #3
0
static gboolean
gimp_fg_bg_view_expose (GtkWidget      *widget,
                        GdkEventExpose *eevent)
{
  GimpFgBgView *view   = GIMP_FG_BG_VIEW (widget);
  GtkStyle     *style  = gtk_widget_get_style (widget);
  GdkWindow    *window = gtk_widget_get_window (widget);
  cairo_t      *cr;
  GtkAllocation allocation;
  gint          rect_w, rect_h;
  GimpRGB       color;

  if (! gtk_widget_is_drawable (widget))
    return FALSE;

  cr = gdk_cairo_create (eevent->window);

  gdk_cairo_region (cr, eevent->region);
  cairo_clip (cr);

  gtk_widget_get_allocation (widget, &allocation);

  cairo_translate (cr, allocation.x, allocation.y);

  rect_w = allocation.width  * 3 / 4;
  rect_h = allocation.height * 3 / 4;

  if (! view->transform)
    gimp_fg_bg_view_create_transform (view);

  /*  draw the background area  */

  if (view->context)
    {
      gimp_context_get_background (view->context, &color);

      if (view->transform)
        gimp_color_transform_process_pixels (view->transform,
                                             babl_format ("R'G'B'A double"),
                                             &color,
                                             babl_format ("R'G'B'A double"),
                                             &color,
                                             1);

      gimp_cairo_set_source_rgb (cr, &color);

      cairo_rectangle (cr,
                       allocation.width  - rect_w + 1,
                       allocation.height - rect_h + 1,
                       rect_w - 2,
                       rect_h - 2);
      cairo_fill (cr);
    }

  gtk_paint_shadow (style, window, GTK_STATE_NORMAL,
                    GTK_SHADOW_IN,
                    NULL, widget, NULL,
                    allocation.x + allocation.width  - rect_w,
                    allocation.y + allocation.height - rect_h,
                    rect_w, rect_h);

  /*  draw the foreground area  */

  if (view->context)
    {
      gimp_context_get_foreground (view->context, &color);

      if (view->transform)
        gimp_color_transform_process_pixels (view->transform,
                                             babl_format ("R'G'B'A double"),
                                             &color,
                                             babl_format ("R'G'B'A double"),
                                             &color,
                                             1);

      gimp_cairo_set_source_rgb (cr, &color);

      cairo_rectangle (cr, 1, 1, rect_w - 2, rect_h - 2);
      cairo_fill (cr);
    }

  gtk_paint_shadow (style, window, GTK_STATE_NORMAL,
                    GTK_SHADOW_OUT,
                    NULL, widget, NULL,
                    allocation.x, allocation.y, rect_w, rect_h);

  cairo_destroy (cr);

  return TRUE;
}
Пример #4
0
static void
gimp_pick_button_pick (GimpPickButton *button,
                       GdkEvent       *event)
{
  GdkScreen        *screen = gdk_event_get_screen (event);
  GimpColorProfile *monitor_profile;
  GdkMonitor       *monitor;
  GimpRGB           rgb;
  gint              x_root;
  gint              y_root;
  gdouble           x_win;
  gdouble           y_win;

  gdk_window_get_origin (gdk_event_get_window (event), &x_root, &y_root);
  gdk_event_get_coords (event, &x_win, &y_win);
  x_root += x_win;
  y_root += y_win;

#ifdef G_OS_WIN32

  {
    HDC      hdc;
    RECT     rect;
    COLORREF win32_color;

    /* For MS Windows, use native GDI functions to get the pixel, as
     * cairo does not handle the case where you have multiple monitors
     * with a monitor on the left or above the primary monitor.  That
     * scenario create a cairo primary surface with negative extent,
     * which is not handled properly (bug 740634).
     */

    hdc = GetDC (HWND_DESKTOP);
    GetClipBox (hdc, &rect);
    win32_color = GetPixel (hdc, x_root + rect.left, y_root + rect.top);
    ReleaseDC (HWND_DESKTOP, hdc);

    gimp_rgba_set_uchar (&rgb,
                         GetRValue (win32_color),
                         GetGValue (win32_color),
                         GetBValue (win32_color),
                         255);
  }

#else

  {
    GdkWindow       *window;
    gint             x_window;
    gint             y_window;
    cairo_surface_t *image;
    cairo_t         *cr;
    guchar          *data;
    guchar           color[3];

    /* we try to pick from the local window under the cursor, and fall
     * back to picking from the root window if this fails (i.e., if
     * the cursor is not under a local window).  on wayland, picking
     * from the root window is not supported, so this at least allows
     * us to pick from local windows.  see bug #780375.
     */
    window = gdk_device_get_window_at_position (gdk_event_get_device (event),
                                                &x_window, &y_window);
    if (! window)
      {
        window   = gdk_screen_get_root_window (screen);
        x_window = x_root;
        y_window = y_root;
      }

    image = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1);

    cr = cairo_create (image);

    gdk_cairo_set_source_window (cr, window, -x_window, -y_window);
    cairo_paint (cr);

    cairo_destroy (cr);

    data = cairo_image_surface_get_data (image);
    GIMP_CAIRO_RGB24_GET_PIXEL (data, color[0], color[1], color[2]);

    cairo_surface_destroy (image);

    gimp_rgba_set_uchar (&rgb, color[0], color[1], color[2], 255);
  }

#endif

  monitor = gdk_display_get_monitor_at_point (gdk_screen_get_display (screen),
                                              x_root, y_root);
  monitor_profile = gimp_monitor_get_color_profile (monitor);

  if (monitor_profile)
    {
      GimpColorProfile        *srgb_profile;
      GimpColorTransform      *transform;
      const Babl              *format;
      GimpColorTransformFlags  flags = 0;

      format = babl_format ("R'G'B'A double");

      flags |= GIMP_COLOR_TRANSFORM_FLAGS_NOOPTIMIZE;
      flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION;

      srgb_profile = gimp_color_profile_new_rgb_srgb ();
      transform = gimp_color_transform_new (monitor_profile, format,
                                            srgb_profile,    format,
                                            GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
                                            flags);
      g_object_unref (srgb_profile);

      if (transform)
        {
          gimp_color_transform_process_pixels (transform,
                                               format, &rgb,
                                               format, &rgb,
                                               1);
          gimp_rgb_clamp (&rgb);

          g_object_unref (transform);
        }
    }

  g_signal_emit_by_name (button, "color-picked", &rgb);
}