static void
gimp_view_renderer_palette_render (GimpViewRenderer *renderer,
                                   GtkWidget        *widget)
{
  GimpViewRendererPalette *renderpal = GIMP_VIEW_RENDERER_PALETTE (renderer);
  GimpPalette             *palette;
  guchar                  *row;
  guchar                  *dest;
  GList                   *list;
  gdouble                  cell_width;
  gint                     grid_width;
  gint                     dest_stride;
  gint                     y;

  palette = GIMP_PALETTE (renderer->viewable);

  if (palette->n_colors < 1)
    return;

  grid_width = renderpal->draw_grid ? 1 : 0;

  if (renderpal->cell_size > 0)
    {
      if (palette->n_columns > 0)
        cell_width = MAX ((gdouble) renderpal->cell_size,
                          (gdouble) (renderer->width - grid_width) /
                          (gdouble) palette->n_columns);
      else
        cell_width = renderpal->cell_size;
    }
  else
    {
      if (palette->n_columns > 0)
        cell_width = ((gdouble) (renderer->width - grid_width) /
                      (gdouble) palette->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 = palette->n_colors / renderpal->columns;
  if (palette->n_colors % 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 = palette->colors;

  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);

  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
        {
          memcpy (dest, row, renderer->width * 4);
        }

      dest += dest_stride;
    }

  g_free (row);

  cairo_surface_mark_dirty (renderer->surface);

  renderer->needs_render = FALSE;
}
Example #2
0
static gboolean
gimp_color_bar_expose (GtkWidget      *widget,
                       GdkEventExpose *event)
{
  GimpColorBar    *bar = GIMP_COLOR_BAR (widget);
  cairo_t         *cr;
  GtkAllocation    allocation;
  cairo_surface_t *surface;
  cairo_pattern_t *pattern;
  guchar          *src;
  guchar          *dest;
  gint             x, y;
  gint             width, height;
  gint             i;

  cr = gdk_cairo_create (event->window);

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

  gtk_widget_get_allocation (widget, &allocation);

  x = y = gtk_container_get_border_width (GTK_CONTAINER (bar));

  width  = allocation.width  - 2 * x;
  height = allocation.height - 2 * y;

  if (width < 1 || height < 1)
    return TRUE;

  cairo_translate (cr, allocation.x + x, allocation.y + y);
  cairo_rectangle (cr, 0, 0, width, height);
  cairo_clip (cr);

  surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 256, 1);

  for (i = 0, src = bar->buf, dest = cairo_image_surface_get_data (surface);
       i < 256;
       i++, src += 3, dest += 4)
    {
      GIMP_CAIRO_RGB24_SET_PIXEL(dest, src[0], src[1], src[2]);
    }

  cairo_surface_mark_dirty (surface);

  pattern = cairo_pattern_create_for_surface (surface);
  cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REFLECT);
  cairo_surface_destroy (surface);

  if (bar->orientation == GTK_ORIENTATION_HORIZONTAL)
    {
      cairo_scale (cr, (gdouble) width / 256.0, 1.0);
    }
  else
    {
      cairo_translate (cr, 0, height);
      cairo_scale (cr, 1.0, (gdouble) height / 256.0);
      cairo_rotate (cr, - G_PI / 2);
    }

  cairo_set_source (cr, pattern);
  cairo_pattern_destroy (pattern);

  cairo_paint (cr);

  cairo_destroy (cr);

  return TRUE;
}
static void
compute_preview (gint startx, gint starty, gint w, gint h)
{
  gint xcnt, ycnt, f1, f2;
  guchar r, g, b;
  gdouble imagex, imagey;
  gint32 index = 0;
  GimpRGB color;
  GimpRGB lightcheck, darkcheck;
  GimpVector3 pos;
  get_ray_func ray_func;

  if (xpostab_size != w)
    {
      if (xpostab)
        {
          g_free (xpostab);
          xpostab = NULL;
        }
    }

  if (!xpostab)
    {
      xpostab = g_new (gdouble, w);
      xpostab_size = w;
    }

  if (ypostab_size != h)
    {
      if (ypostab)
        {
          g_free (ypostab);
          ypostab = NULL;
        }
    }

  if (!ypostab)
    {
      ypostab = g_new (gdouble, h);
      ypostab_size = h;
    }

  for (xcnt = 0; xcnt < w; xcnt++)
    xpostab[xcnt] = (gdouble) width *((gdouble) xcnt / (gdouble) w);
  for (ycnt = 0; ycnt < h; ycnt++)
    ypostab[ycnt] = (gdouble) height *((gdouble) ycnt / (gdouble) h);

  precompute_init (width, height);

  gimp_rgba_set (&lightcheck,
                 GIMP_CHECK_LIGHT, GIMP_CHECK_LIGHT, GIMP_CHECK_LIGHT,
                 1.0);
  gimp_rgba_set (&darkcheck, GIMP_CHECK_DARK, GIMP_CHECK_DARK,
                 GIMP_CHECK_DARK, 1.0);

  if (mapvals.bump_mapped == TRUE && mapvals.bumpmap_id != -1)
    {
      gimp_pixel_rgn_init (&bump_region,
                           gimp_drawable_get (mapvals.bumpmap_id),
                           0, 0, width, height, FALSE, FALSE);
    }

  imagey = 0;

  if (mapvals.previewquality)
    ray_func = get_ray_color;
  else
    ray_func = get_ray_color_no_bilinear;

  if (mapvals.env_mapped == TRUE && mapvals.envmap_id != -1)
    {
      env_width = gimp_drawable_width (mapvals.envmap_id);
      env_height = gimp_drawable_height (mapvals.envmap_id);

      gimp_pixel_rgn_init (&env_region,
                           gimp_drawable_get (mapvals.envmap_id), 0,
                           0, env_width, env_height, FALSE, FALSE);

      if (mapvals.previewquality)
        ray_func = get_ray_color_ref;
      else
        ray_func = get_ray_color_no_bilinear_ref;
    }

  cairo_surface_flush (preview_surface);

  for (ycnt = 0; ycnt < PREVIEW_HEIGHT; ycnt++)
    {
      index = ycnt * preview_rgb_stride;
      for (xcnt = 0; xcnt < PREVIEW_WIDTH; xcnt++)
        {
          if ((ycnt >= starty && ycnt < (starty + h)) &&
              (xcnt >= startx && xcnt < (startx + w)))
            {
              imagex = xpostab[xcnt - startx];
              imagey = ypostab[ycnt - starty];
              pos = int_to_posf (imagex, imagey);

              if (mapvals.bump_mapped == TRUE &&
                  mapvals.bumpmap_id != -1 &&
                  xcnt == startx)
                {
                  pos_to_float (pos.x, pos.y, &imagex, &imagey);
                  precompute_normals (0, width, RINT (imagey));
                }

              color = (*ray_func) (&pos);

              if (color.a < 1.0)
                {
                  f1 = ((xcnt % 32) < 16);
                  f2 = ((ycnt % 32) < 16);
                  f1 = f1 ^ f2;

                  if (f1)
                    {
                      if (color.a == 0.0)
                        color = lightcheck;
                      else
                        gimp_rgb_composite (&color,
                                            &lightcheck,
                                            GIMP_RGB_COMPOSITE_BEHIND);
                    }
                  else
                    {
                      if (color.a == 0.0)
                        color = darkcheck;
                      else
                        gimp_rgb_composite (&color,
                                            &darkcheck,
                                            GIMP_RGB_COMPOSITE_BEHIND);
                    }
                }

              gimp_rgb_get_uchar (&color, &r, &g, &b);
              GIMP_CAIRO_RGB24_SET_PIXEL((preview_rgb_data + index), r, g, b);
              index += 4;
              imagex++;
            }
          else
            {
              preview_rgb_data[index++] = 200;
              preview_rgb_data[index++] = 200;
              preview_rgb_data[index++] = 200;
              index++;
            }
        }
    }
  cairo_surface_mark_dirty (preview_surface);
}
static gboolean
select_area_expose (GtkWidget      *widget,
                    GdkEventExpose *event)
{
  cairo_t         *cr;
  GtkAllocation    allocation;
  gdouble          dx;
  gdouble          dy;
  cairo_surface_t *surface;
  guchar          *dest;
  gdouble          y;
  gint             j;

  cr = gdk_cairo_create (event->window);

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

  gtk_widget_get_allocation (widget, &allocation);

  dx = 1.0 / allocation.width;
  dy = 1.0 / allocation.height;

  surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
                                        event->area.width,
                                        event->area.height);

  dest = cairo_image_surface_get_data (surface);

  for (j = 0, y = event->area.y / allocation.height;
       j < event->area.height;
       j++, y += dy)
    {
      guchar  *d  = dest;

      gdouble  r  = calc (0, y, 0);
      gdouble  g  = calc (0, y, 120);
      gdouble  b  = calc (0, y, 240);

      gdouble  dr = calc (dx, y, 0)   - r;
      gdouble  dg = calc (dx, y, 120) - g;
      gdouble  db = calc (dx, y, 240) - b;

      gint     i;

      r += event->area.x * dr;
      g += event->area.x * dg;
      b += event->area.x * db;

      for (i = 0; i < event->area.width; i++)
        {
          GIMP_CAIRO_RGB24_SET_PIXEL (d,
                                      CLAMP ((gint) r, 0, 255),
                                      CLAMP ((gint) g, 0, 255),
                                      CLAMP ((gint) b, 0, 255));

          r += dr;
          g += dg;
          b += db;

          d += 4;
        }

      dest += cairo_image_surface_get_stride (surface);
    }

  cairo_surface_mark_dirty (surface);
  cairo_set_source_surface (cr, surface,
                            event->area.x, event->area.y);
  cairo_surface_destroy (surface);

  cairo_paint (cr);

  cairo_destroy (cr);

  return FALSE;
}
Example #5
0
static void
gimp_color_area_render_buf (GtkWidget         *widget,
                            gboolean           insensitive,
                            GimpColorAreaType  type,
                            guchar            *buf,
                            guint              width,
                            guint              height,
                            guint              rowstride,
                            GimpRGB           *color)
{
  GtkStyle *style = gtk_widget_get_style (widget);
  guint     x, y;
  guint     check_size = 0;
  guchar    light[3];
  guchar    dark[3];
  guchar    opaque[3];
  guchar    insens[3];
  guchar   *p;
  gdouble   frac;

  switch (type)
    {
    case GIMP_COLOR_AREA_FLAT:
      check_size = 0;
      break;

    case GIMP_COLOR_AREA_SMALL_CHECKS:
      check_size = GIMP_CHECK_SIZE_SM;
      break;

    case GIMP_COLOR_AREA_LARGE_CHECKS:
      check_size = GIMP_CHECK_SIZE;
      break;
    }

  gimp_rgb_get_uchar (color, opaque, opaque + 1, opaque + 2);

  insens[0] = style->bg[GTK_STATE_INSENSITIVE].red   >> 8;
  insens[1] = style->bg[GTK_STATE_INSENSITIVE].green >> 8;
  insens[2] = style->bg[GTK_STATE_INSENSITIVE].blue  >> 8;

  if (insensitive || check_size == 0 || color->a == 1.0)
    {
      for (y = 0; y < height; y++)
        {
          p = buf + y * rowstride;

          for (x = 0; x < width; x++)
            {
              if (insensitive && ((x + y) % 2))
                {
                  GIMP_CAIRO_RGB24_SET_PIXEL (p,
                                              insens[0],
                                              insens[1],
                                              insens[2]);
                }
              else
                {
                  GIMP_CAIRO_RGB24_SET_PIXEL (p,
                                              opaque[0],
                                              opaque[1],
                                              opaque[2]);
                }

              p += 4;
            }
        }

      return;
    }

  light[0] = (GIMP_CHECK_LIGHT +
              (color->r - GIMP_CHECK_LIGHT) * color->a) * 255.999;
  light[1] = (GIMP_CHECK_LIGHT +
              (color->g - GIMP_CHECK_LIGHT) * color->a) * 255.999;
  light[2] = (GIMP_CHECK_LIGHT +
              (color->b - GIMP_CHECK_LIGHT) * color->a) * 255.999;

  dark[0] = (GIMP_CHECK_DARK +
             (color->r - GIMP_CHECK_DARK)  * color->a) * 255.999;
  dark[1] = (GIMP_CHECK_DARK +
             (color->g - GIMP_CHECK_DARK)  * color->a) * 255.999;
  dark[2] = (GIMP_CHECK_DARK +
             (color->b - GIMP_CHECK_DARK)  * color->a) * 255.999;

  for (y = 0; y < height; y++)
    {
      p = buf + y * rowstride;

      for (x = 0; x < width; x++)
        {
          if ((width - x) * height > y * width)
            {
              GIMP_CAIRO_RGB24_SET_PIXEL (p,
                                          opaque[0],
                                          opaque[1],
                                          opaque[2]);
              p += 4;

              continue;
            }

          frac = y - (gdouble) ((width - x) * height) / (gdouble) width;

          if (((x / check_size) ^ (y / check_size)) & 1)
            {
              if ((gint) frac)
                {
                  GIMP_CAIRO_RGB24_SET_PIXEL (p,
                                              light[0],
                                              light[1],
                                              light[2]);
                }
              else
                {
                  GIMP_CAIRO_RGB24_SET_PIXEL (p,
                                              ((gdouble) light[0]  * frac +
                                               (gdouble) opaque[0] * (1.0 - frac)),
                                              ((gdouble) light[1]  * frac +
                                               (gdouble) opaque[1] * (1.0 - frac)),
                                              ((gdouble) light[2]  * frac +
                                               (gdouble) opaque[2] * (1.0 - frac)));
                }
            }
          else
            {
              if ((gint) frac)
                {
                  GIMP_CAIRO_RGB24_SET_PIXEL (p,
                                              dark[0],
                                              dark[1],
                                              dark[2]);
                }
              else
                {
                  GIMP_CAIRO_RGB24_SET_PIXEL (p,
                                              ((gdouble) dark[0] * frac +
                                               (gdouble) opaque[0] * (1.0 - frac)),
                                              ((gdouble) dark[1] * frac +
                                               (gdouble) opaque[1] * (1.0 - frac)),
                                              ((gdouble) dark[2] * frac +
                                               (gdouble) opaque[2] * (1.0 - frac)));
                }
            }

          p += 4;
        }
    }
}