Esempio n. 1
0
void
gimp_paint_core_validate_canvas_tiles (GimpPaintCore *core,
                                       gint           x,
                                       gint           y,
                                       gint           w,
                                       gint           h)
{
  gint i, j;

  g_return_if_fail (GIMP_IS_PAINT_CORE (core));
  g_return_if_fail (core->canvas_tiles != NULL);

  for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
    {
      for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
        {
          Tile *tile = tile_manager_get_tile (core->canvas_tiles, j, i,
                                              FALSE, FALSE);

          if (! tile_is_valid (tile))
            {
              tile = tile_manager_get_tile (core->canvas_tiles, j, i,
                                            TRUE, TRUE);
              memset (tile_data_pointer (tile, 0, 0), 0, tile_size (tile));
              tile_release (tile, TRUE);
            }
        }
    }
}
Esempio n. 2
0
static void
gimp_paint_core_copy_valid_tiles (TileManager *src_tiles,
                                  TileManager *dest_tiles,
                                  gint         x,
                                  gint         y,
                                  gint         w,
                                  gint         h)
{
  Tile *src_tile;
  gint  i, j;

  for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
    {
      for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
        {
          src_tile = tile_manager_get_tile (src_tiles,
                                            j, i, FALSE, FALSE);

          if (tile_is_valid (src_tile))
            {
              src_tile = tile_manager_get_tile (src_tiles,
                                                j, i, TRUE, FALSE);

              tile_manager_map_tile (dest_tiles, j, i, src_tile);

              tile_release (src_tile, FALSE);
            }
        }
    }
}
Esempio n. 3
0
void
gimp_paint_core_validate_saved_proj_tiles (GimpPaintCore *core,
                                           GimpPickable  *pickable,
                                           gint           x,
                                           gint           y,
                                           gint           w,
                                           gint           h)
{
  gint i, j;

  g_return_if_fail (GIMP_IS_PAINT_CORE (core));
  g_return_if_fail (GIMP_IS_PICKABLE (pickable));
  g_return_if_fail (core->saved_proj_tiles != NULL);

  for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
    {
      for (j = x; j < (x + w); j += (TILE_WIDTH - (j % TILE_WIDTH)))
        {
          Tile *dest_tile = tile_manager_get_tile (core->saved_proj_tiles,
                                                   j, i, FALSE, FALSE);

          if (! tile_is_valid (dest_tile))
            {
              Tile *src_tile =
                tile_manager_get_tile (gimp_pickable_get_tiles (pickable),
                                       j, i, TRUE, FALSE);

              tile_manager_map_tile (core->saved_proj_tiles, j, i, src_tile);
              tile_release (src_tile, FALSE);
            }
        }
    }
}
Esempio n. 4
0
static void
find_empty_segs (PixelRegion  *maskPR,
                 gint          scanline,
                 gint          empty_segs[],
                 gint          max_empty,
                 gint         *num_empty,
                 BoundaryType  type,
                 gint          x1,
                 gint          y1,
                 gint          x2,
                 gint          y2,
                 guchar        threshold)
{
    const guchar *data  = NULL;
    Tile         *tile  = NULL;
    gint          start = 0;
    gint          end   = 0;
    gint          endx  = 0;
    gint          bpp   = 0;
    gint          tilex = -1;
    gint          last  = -1;
    gint          l_num_empty;
    gint          x;

    *num_empty = 0;

    if (scanline < maskPR->y || scanline >= (maskPR->y + maskPR->h))
    {
        empty_segs[(*num_empty)++] = 0;
        empty_segs[(*num_empty)++] = G_MAXINT;
        return;
    }

    if (type == BOUNDARY_WITHIN_BOUNDS)
    {
        if (scanline < y1 || scanline >= y2)
        {
            empty_segs[(*num_empty)++] = 0;
            empty_segs[(*num_empty)++] = G_MAXINT;
            return;
        }

        start = x1;
        end   = x2;
    }
    else if (type == BOUNDARY_IGNORE_BOUNDS)
    {
        start = maskPR->x;
        end   = maskPR->x + maskPR->w;
        if (scanline < y1 || scanline >= y2)
            x2 = -1;
    }

    empty_segs[(*num_empty)++] = 0;

    l_num_empty = *num_empty;

    bpp = maskPR->bytes;

    if (! maskPR->tiles)
    {
        data  = maskPR->data + scanline * maskPR->rowstride;
        endx = end;
    }

    for (x = start; x < end;)
    {
        /*  Check to see if we must advance to next tile  */
        if (maskPR->tiles)
        {
            if ((x / TILE_WIDTH) != tilex)
            {
                if (tile)
                    tile_release (tile, FALSE);

                tile = tile_manager_get_tile (maskPR->tiles,
                                              x, scanline, TRUE, FALSE);
                data = ((const guchar *) tile_data_pointer (tile, x, scanline) +
                        bpp - 1);

                tilex = x / TILE_WIDTH;
            }

            endx = x + (TILE_WIDTH - (x % TILE_WIDTH));
            endx = MIN (end, endx);
        }

        if (type == BOUNDARY_IGNORE_BOUNDS && (endx > x1 || x < x2))
        {
            for (; x < endx; x++)
            {
                gint val;

                if (*data > threshold)
                {
                    if (x >= x1 && x < x2)
                        val = -1;
                    else
                        val = 1;
                }
                else
                {
                    val = -1;
                }

                data += bpp;

                if (last != val)
                    empty_segs[l_num_empty++] = x;

                last = val;
            }
        }
        else
        {
            for (; x < endx; x++)
            {
                gint val;

                if (*data > threshold)
                    val = 1;
                else
                    val = -1;

                data += bpp;

                if (last != val)
                    empty_segs[l_num_empty++] = x;

                last = val;
            }
        }
    }

    *num_empty = l_num_empty;

    if (last > 0)
        empty_segs[(*num_empty)++] = x;

    empty_segs[(*num_empty)++] = G_MAXINT;

    if (tile)
        tile_release (tile, FALSE);
}
Esempio n. 5
0
TempBuf *
gimp_paint_core_get_orig_proj (GimpPaintCore *core,
                               GimpPickable  *pickable,
                               gint           x,
                               gint           y,
                               gint           width,
                               gint           height)
{
  TileManager  *src_tiles;
  PixelRegion   srcPR;
  PixelRegion   destPR;
  Tile         *saved_tile;
  gboolean      release_tile;
  gint          h;
  gint          pixelwidth;
  gint          pickable_width;
  gint          pickable_height;
  const guchar *s;
  guchar       *d;
  gpointer      pr;

  g_return_val_if_fail (GIMP_IS_PAINT_CORE (core), NULL);
  g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), NULL);
  g_return_val_if_fail (core->saved_proj_tiles != NULL, NULL);

  core->orig_proj_buf = temp_buf_resize (core->orig_proj_buf,
                                         gimp_pickable_get_bytes (pickable),
                                         x, y, width, height);

  src_tiles = gimp_pickable_get_tiles (pickable);

  pickable_width  = tile_manager_width  (src_tiles);
  pickable_height = tile_manager_height (src_tiles);

  gimp_rectangle_intersect (x, y,
                            width, height,
                            0, 0,
                            pickable_width, pickable_height,
                            &x, &y,
                            &width, &height);

  /*  configure the pixel regions  */
  pixel_region_init (&srcPR, src_tiles,
                     x, y, width, height,
                     FALSE);

  pixel_region_init_temp_buf (&destPR, core->orig_proj_buf,
                              x - core->orig_proj_buf->x,
                              y - core->orig_proj_buf->y,
                              width, height);

  for (pr = pixel_regions_register (2, &srcPR, &destPR);
       pr != NULL;
       pr = pixel_regions_process (pr))
    {
      /*  If the saved tile corresponding to this location is valid, use it  */
      saved_tile = tile_manager_get_tile (core->saved_proj_tiles,
                                          srcPR.x, srcPR.y,
                                          FALSE, FALSE);

      if (tile_is_valid (saved_tile))
        {
          release_tile = TRUE;

          saved_tile = tile_manager_get_tile (core->saved_proj_tiles,
                                              srcPR.x, srcPR.y,
                                              TRUE, FALSE);
          s = tile_data_pointer (saved_tile, srcPR.x, srcPR.y);
        }
      else
        {
          release_tile = FALSE;

          s = srcPR.data;
        }

      d = destPR.data;

      pixelwidth = srcPR.w * srcPR.bytes;

      h = srcPR.h;
      while (h --)
        {
          memcpy (d, s, pixelwidth);

          s += srcPR.rowstride;
          d += destPR.rowstride;
        }

      if (release_tile)
        tile_release (saved_tile, FALSE);
    }

  return core->orig_proj_buf;
}