示例#1
0
static void
cdisplay_lcms_convert_surface (GimpColorDisplay *display,
                               cairo_surface_t  *surface)
{
  CdisplayLcms   *lcms   = CDISPLAY_LCMS (display);
  gint            width  = cairo_image_surface_get_width (surface);
  gint            height = cairo_image_surface_get_height (surface);
  gint            stride = cairo_image_surface_get_stride (surface);
  guchar         *buf    = cairo_image_surface_get_data (surface);
  cairo_format_t  fmt    = cairo_image_surface_get_format (surface);
  guchar         *rowbuf;
  gint            x, y;
  guchar          r, g, b, a;

  if (fmt != CAIRO_FORMAT_ARGB32)
    return;

  if (! lcms->transform)
    return;

  rowbuf = g_malloc (stride);

  for (y = 0; y < height; y++, buf += stride)
    {
      /* Switch buf from ARGB premul to ARGB non-premul, since lcms ignores the
       * alpha channel.  The macro takes care of byte order.
       */
      for (x = 0; x < width; x++)
        {
          GIMP_CAIRO_ARGB32_GET_PIXEL (buf + 4*x, r, g, b, a);
          rowbuf[4*x+0] = a;
          rowbuf[4*x+1] = r;
          rowbuf[4*x+2] = g;
          rowbuf[4*x+3] = b;
        }

      cmsDoTransform (lcms->transform, rowbuf, rowbuf, width);

      /* And back to ARGB premul */
      for (x = 0; x < width; x++)
        {
          a = rowbuf[4*x+0];
          r = rowbuf[4*x+1];
          g = rowbuf[4*x+2];
          b = rowbuf[4*x+3];
          GIMP_CAIRO_ARGB32_SET_PIXEL (buf + 4*x, r, g, b, a);
        }
    }

  g_free (rowbuf);
}
static void
cdisplay_gamma_convert_surface (GimpColorDisplay *display,
                                cairo_surface_t  *surface)
{
  CdisplayGamma  *gamma  = CDISPLAY_GAMMA (display);
  gint            width  = cairo_image_surface_get_width (surface);
  gint            height = cairo_image_surface_get_height (surface);
  gint            stride = cairo_image_surface_get_stride (surface);
  guchar         *buf    = cairo_image_surface_get_data (surface);
  cairo_format_t  fmt    = cairo_image_surface_get_format (surface);
  gint            i, j, skip;
  gint            r, g, b, a;

  if (fmt != CAIRO_FORMAT_ARGB32)
    return;

  /* You will not be using the entire buffer most of the time.
   * Hence, the simplistic code for this is as follows:
   *
   * for (j = 0; j < height; j++)
   *   {
   *     for (i = 0; i < width * bpp; i++)
   *       buf[i] = lookup[buf[i]];
   *     buf += bpl;
   *   }
   */

  j = height;
  skip = stride - 4 * width;

  while (j--)
    {
      i = width;
      while (i--)
        {
          GIMP_CAIRO_ARGB32_GET_PIXEL (buf, r, g, b, a);
          r = gamma->lookup[r];
          g = gamma->lookup[g];
          b = gamma->lookup[b];
          GIMP_CAIRO_ARGB32_SET_PIXEL (buf, r, g, b, a);
          buf += 4;
        }
      buf += skip;
    }
}
static void
gimp_text_layer_render_layout (GimpTextLayer  *layer,
                               GimpTextLayout *layout)
{
  GimpDrawable    *drawable = GIMP_DRAWABLE (layer);
  GimpItem        *item     = GIMP_ITEM (layer);
  GimpImage       *image    = gimp_item_get_image (item);
  cairo_t         *cr;
  cairo_surface_t *surface;
  PixelRegion      layerPR;
  const guchar    *data;
  GimpImageType    layer_type;
  gint             layer_alpha_byte;
  gint             rowstride;
  gint             width;
  gint             height;
  gpointer         pr;

  g_return_if_fail (gimp_drawable_has_alpha (drawable));

  width  = gimp_item_get_width  (item);
  height = gimp_item_get_height (item);

  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);

  cr = cairo_create (surface);
  gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE);
  cairo_destroy (cr);

  pixel_region_init (&layerPR, gimp_drawable_get_tiles (drawable),
                     0, 0, width, height, TRUE);

  layer_type = gimp_drawable_type (drawable);
  layer_alpha_byte = layerPR.bytes - 1;

  cairo_surface_flush (surface);
  data      = cairo_image_surface_get_data (surface);
  rowstride = cairo_image_surface_get_stride (surface);

  for (pr = pixel_regions_register (1, &layerPR);
       pr != NULL;
       pr = pixel_regions_process (pr))
    {
      const guchar *src  = data + layerPR.y * rowstride + layerPR.x * 4;
      guchar       *dest = layerPR.data;
      gint          rows = layerPR.h;

      while (rows--)
        {
          const guchar *s = src;
          guchar       *d = dest;
          gint          w = layerPR.w;

          while (w--)
            {
              guchar color[4];

              GIMP_CAIRO_ARGB32_GET_PIXEL (s,
                                           color[0],
                                           color[1],
                                           color[2],
                                           color[3]);

              gimp_image_transform_color (image,
                                          layer_type, d, GIMP_RGB, color);
              d[layer_alpha_byte] = color[3];

              s += 4;
              d += layerPR.bytes;
            }

          src  += rowstride;
          dest += layerPR.rowstride;
        }
    }

  cairo_surface_destroy (surface);

  gimp_drawable_update (drawable, 0, 0, width, height);
}