1997-11-25 06:05:25 +08:00
|
|
|
/* The GIMP -- an image manipulation program
|
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
1998-04-13 13:44:11 +08:00
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
1997-11-25 06:05:25 +08:00
|
|
|
*/
|
2000-12-17 05:37:03 +08:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2000-04-28 01:27:28 +08:00
|
|
|
|
2000-12-17 05:37:03 +08:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
2002-10-20 18:14:17 +08:00
|
|
|
#include "libgimpwidgets/gimpwidgets.h"
|
|
|
|
|
2001-09-26 07:23:09 +08:00
|
|
|
#include "display-types.h"
|
2000-12-17 05:37:03 +08:00
|
|
|
|
2001-05-15 19:25:25 +08:00
|
|
|
#include "base/tile-manager.h"
|
|
|
|
#include "base/tile.h"
|
|
|
|
|
2002-11-21 23:46:19 +08:00
|
|
|
#include "core/gimp.h"
|
2001-05-09 10:32:03 +08:00
|
|
|
#include "core/gimpimage.h"
|
2003-03-19 22:44:08 +08:00
|
|
|
#include "core/gimpimage-colormap.h"
|
2001-11-28 11:08:03 +08:00
|
|
|
#include "core/gimpimage-projection.h"
|
2001-05-09 10:32:03 +08:00
|
|
|
|
2003-11-10 07:24:40 +08:00
|
|
|
#include "gimpcanvas.h"
|
2001-09-26 07:23:09 +08:00
|
|
|
#include "gimpdisplay.h"
|
2001-11-01 05:20:09 +08:00
|
|
|
#include "gimpdisplayshell.h"
|
2002-03-15 06:42:50 +08:00
|
|
|
#include "gimpdisplayshell-filter.h"
|
2001-11-02 17:31:21 +08:00
|
|
|
#include "gimpdisplayshell-render.h"
|
2001-09-26 07:23:09 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
typedef struct _RenderInfo RenderInfo;
|
2001-01-30 11:17:26 +08:00
|
|
|
|
|
|
|
typedef void (* RenderFunc) (RenderInfo *info);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
struct _RenderInfo
|
|
|
|
{
|
2001-12-01 02:23:49 +08:00
|
|
|
GimpDisplayShell *shell;
|
|
|
|
TileManager *src_tiles;
|
|
|
|
guint *alpha;
|
|
|
|
guchar *scale;
|
|
|
|
guchar *src;
|
|
|
|
guchar *dest;
|
|
|
|
gint x, y;
|
|
|
|
gint w, h;
|
2004-02-04 10:00:04 +08:00
|
|
|
gdouble scalex;
|
|
|
|
gdouble scaley;
|
2001-12-01 02:23:49 +08:00
|
|
|
gint src_x, src_y;
|
|
|
|
gint src_bpp;
|
|
|
|
gint dest_bpp;
|
|
|
|
gint dest_bpl;
|
|
|
|
gint dest_width;
|
|
|
|
gint byte_order;
|
1997-11-25 06:05:25 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2003-01-06 06:07:10 +08:00
|
|
|
static void render_setup_notify (gpointer config,
|
2002-11-21 23:46:19 +08:00
|
|
|
GParamSpec *param_spec,
|
|
|
|
Gimp *gimp);
|
|
|
|
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* accelerate transparency of image scaling */
|
2001-01-30 11:17:26 +08:00
|
|
|
guchar *render_check_buf = NULL;
|
|
|
|
guchar *render_empty_buf = NULL;
|
2003-02-27 00:17:10 +08:00
|
|
|
guchar *render_white_buf = NULL;
|
2001-01-30 11:17:26 +08:00
|
|
|
guchar *render_temp_buf = NULL;
|
2003-02-27 00:17:10 +08:00
|
|
|
|
2001-01-30 11:17:26 +08:00
|
|
|
guchar *render_blend_dark_check = NULL;
|
|
|
|
guchar *render_blend_light_check = NULL;
|
2003-02-27 00:17:10 +08:00
|
|
|
guchar *render_blend_white = NULL;
|
2001-01-30 11:17:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
static guchar *tile_buf = NULL;
|
|
|
|
static guint check_mod = 0;
|
|
|
|
static guint check_shift = 0;
|
|
|
|
static guint tile_shift = 0;
|
1997-11-25 06:05:25 +08:00
|
|
|
static guchar check_combos[6][2] =
|
|
|
|
{
|
|
|
|
{ 204, 255 },
|
|
|
|
{ 102, 153 },
|
2001-01-30 11:17:26 +08:00
|
|
|
{ 0, 51 },
|
1997-11-25 06:05:25 +08:00
|
|
|
{ 255, 255 },
|
|
|
|
{ 127, 127 },
|
2001-01-30 11:17:26 +08:00
|
|
|
{ 0, 0 }
|
1997-11-25 06:05:25 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2002-11-21 23:46:19 +08:00
|
|
|
render_init (Gimp *gimp)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
|
|
|
|
2003-01-06 06:07:10 +08:00
|
|
|
g_signal_connect (gimp->config, "notify::transparency-size",
|
2002-11-21 23:46:19 +08:00
|
|
|
G_CALLBACK (render_setup_notify),
|
|
|
|
gimp);
|
2003-01-06 06:07:10 +08:00
|
|
|
g_signal_connect (gimp->config, "notify::transparency-type",
|
2002-11-21 23:46:19 +08:00
|
|
|
G_CALLBACK (render_setup_notify),
|
|
|
|
gimp);
|
|
|
|
|
2003-01-06 06:07:10 +08:00
|
|
|
render_setup_notify (gimp->config, NULL, gimp);
|
2002-11-21 23:46:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
render_exit (Gimp *gimp)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
|
|
|
|
2003-01-06 06:07:10 +08:00
|
|
|
g_signal_handlers_disconnect_by_func (gimp->config,
|
2002-11-21 23:46:19 +08:00
|
|
|
render_setup_notify,
|
|
|
|
gimp);
|
|
|
|
|
|
|
|
if (tile_buf)
|
|
|
|
{
|
|
|
|
g_free (tile_buf);
|
|
|
|
tile_buf = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (render_blend_dark_check)
|
|
|
|
{
|
|
|
|
g_free (render_blend_dark_check);
|
|
|
|
render_blend_dark_check = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (render_blend_light_check)
|
|
|
|
{
|
|
|
|
g_free (render_blend_light_check);
|
|
|
|
render_blend_light_check = NULL;
|
|
|
|
}
|
|
|
|
|
2003-02-27 00:17:10 +08:00
|
|
|
if (render_blend_white)
|
|
|
|
{
|
|
|
|
g_free (render_blend_white);
|
|
|
|
render_blend_white = NULL;
|
|
|
|
}
|
|
|
|
|
2002-11-21 23:46:19 +08:00
|
|
|
if (render_check_buf)
|
|
|
|
{
|
|
|
|
g_free (render_check_buf);
|
|
|
|
render_check_buf = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (render_empty_buf)
|
|
|
|
{
|
|
|
|
g_free (render_empty_buf);
|
|
|
|
render_empty_buf = NULL;
|
|
|
|
}
|
|
|
|
|
2003-02-27 00:17:10 +08:00
|
|
|
if (render_white_buf)
|
|
|
|
{
|
|
|
|
g_free (render_white_buf);
|
|
|
|
render_white_buf = NULL;
|
|
|
|
}
|
|
|
|
|
2002-11-21 23:46:19 +08:00
|
|
|
if (render_temp_buf)
|
|
|
|
{
|
|
|
|
g_free (render_temp_buf);
|
|
|
|
render_temp_buf = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2003-01-06 06:07:10 +08:00
|
|
|
render_setup_notify (gpointer config,
|
2002-11-21 23:46:19 +08:00
|
|
|
GParamSpec *param_spec,
|
|
|
|
Gimp *gimp)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2002-11-21 23:46:19 +08:00
|
|
|
GimpCheckType check_type;
|
|
|
|
GimpCheckSize check_size;
|
|
|
|
gint i, j;
|
2001-01-30 11:17:26 +08:00
|
|
|
|
2002-11-21 23:46:19 +08:00
|
|
|
g_object_get (config,
|
|
|
|
"transparency-type", &check_type,
|
|
|
|
"transparency-size", &check_size,
|
|
|
|
NULL);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* based on the tile size, determine the tile shift amount
|
|
|
|
* (assume here that tile_height and tile_width are equal)
|
|
|
|
*/
|
2000-10-26 07:14:11 +08:00
|
|
|
tile_shift = 0;
|
|
|
|
while ((1 << tile_shift) < TILE_WIDTH)
|
|
|
|
tile_shift++;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* allocate a buffer for arranging information from a row of tiles */
|
2001-01-30 11:17:26 +08:00
|
|
|
if (! tile_buf)
|
2002-12-05 03:02:45 +08:00
|
|
|
tile_buf = g_new (guchar,
|
|
|
|
GIMP_DISPLAY_SHELL_RENDER_BUF_WIDTH * MAX_CHANNELS);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-01-30 11:17:26 +08:00
|
|
|
if (! render_blend_dark_check)
|
|
|
|
render_blend_dark_check = g_new (guchar, 65536);
|
|
|
|
if (! render_blend_light_check)
|
|
|
|
render_blend_light_check = g_new (guchar, 65536);
|
2003-02-27 00:17:10 +08:00
|
|
|
if (! render_blend_white)
|
|
|
|
render_blend_white = g_new (guchar, 65536);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
for (i = 0; i < 256; i++)
|
|
|
|
for (j = 0; j < 256; j++)
|
|
|
|
{
|
2001-01-30 11:17:26 +08:00
|
|
|
render_blend_dark_check [(i << 8) + j] = (guchar)
|
1997-11-25 06:05:25 +08:00
|
|
|
((j * i + check_combos[check_type][0] * (255 - i)) / 255);
|
2001-01-30 11:17:26 +08:00
|
|
|
render_blend_light_check [(i << 8) + j] = (guchar)
|
1997-11-25 06:05:25 +08:00
|
|
|
((j * i + check_combos[check_type][1] * (255 - i)) / 255);
|
2003-02-27 00:17:10 +08:00
|
|
|
|
|
|
|
render_blend_white [(i << 8) + j] = (guchar)
|
|
|
|
((j * i + 255 * (255 - i)) / 255);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (check_size)
|
|
|
|
{
|
2001-12-09 07:12:59 +08:00
|
|
|
case GIMP_SMALL_CHECKS:
|
2001-01-30 11:17:26 +08:00
|
|
|
check_mod = 0x3;
|
1997-11-25 06:05:25 +08:00
|
|
|
check_shift = 2;
|
|
|
|
break;
|
2001-12-09 07:12:59 +08:00
|
|
|
case GIMP_MEDIUM_CHECKS:
|
2001-01-30 11:17:26 +08:00
|
|
|
check_mod = 0x7;
|
1997-11-25 06:05:25 +08:00
|
|
|
check_shift = 3;
|
|
|
|
break;
|
2001-12-09 07:12:59 +08:00
|
|
|
case GIMP_LARGE_CHECKS:
|
2001-01-30 11:17:26 +08:00
|
|
|
check_mod = 0xf;
|
1997-11-25 06:05:25 +08:00
|
|
|
check_shift = 4;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-01-30 11:17:26 +08:00
|
|
|
g_free (render_check_buf);
|
|
|
|
g_free (render_empty_buf);
|
2003-02-27 00:17:10 +08:00
|
|
|
g_free (render_white_buf);
|
2001-01-30 11:17:26 +08:00
|
|
|
g_free (render_temp_buf);
|
|
|
|
|
2003-04-01 21:53:47 +08:00
|
|
|
#define BUF_SIZE (MAX (GIMP_DISPLAY_SHELL_RENDER_BUF_WIDTH, \
|
|
|
|
GIMP_VIEWABLE_MAX_PREVIEW_SIZE) + 4)
|
|
|
|
|
|
|
|
render_check_buf = g_new (guchar, BUF_SIZE * 3);
|
|
|
|
render_empty_buf = g_new0 (guchar, BUF_SIZE * 3);
|
|
|
|
render_white_buf = g_new (guchar, BUF_SIZE * 3);
|
|
|
|
render_temp_buf = g_new (guchar, BUF_SIZE * 3);
|
2001-12-01 02:23:49 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* calculate check buffer for previews */
|
2003-04-01 21:53:47 +08:00
|
|
|
|
|
|
|
memset (render_white_buf, 255, BUF_SIZE * 3);
|
|
|
|
|
|
|
|
for (i = 0; i < BUF_SIZE; i++)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-04-01 21:53:47 +08:00
|
|
|
if (i & 0x4)
|
|
|
|
{
|
|
|
|
render_check_buf[i * 3 + 0] = render_blend_dark_check[0];
|
|
|
|
render_check_buf[i * 3 + 1] = render_blend_dark_check[0];
|
|
|
|
render_check_buf[i * 3 + 2] = render_blend_dark_check[0];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
render_check_buf[i * 3 + 0] = render_blend_light_check[0];
|
|
|
|
render_check_buf[i * 3 + 1] = render_blend_light_check[0];
|
|
|
|
render_check_buf[i * 3 + 2] = render_blend_light_check[0];
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
2003-04-01 21:53:47 +08:00
|
|
|
|
|
|
|
#undef BUF_SIZE
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
2001-01-30 11:17:26 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Render Image functions */
|
|
|
|
|
2001-12-01 02:23:49 +08:00
|
|
|
static void render_image_rgb (RenderInfo *info);
|
|
|
|
static void render_image_rgb_a (RenderInfo *info);
|
|
|
|
static void render_image_gray (RenderInfo *info);
|
|
|
|
static void render_image_gray_a (RenderInfo *info);
|
|
|
|
static void render_image_indexed (RenderInfo *info);
|
|
|
|
static void render_image_indexed_a (RenderInfo *info);
|
|
|
|
|
|
|
|
static void render_image_init_info (RenderInfo *info,
|
|
|
|
GimpDisplayShell *shell,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
gint w,
|
|
|
|
gint h);
|
|
|
|
static guint * render_image_init_alpha (gint mult);
|
|
|
|
static guchar * render_image_accelerate_scaling (gint width,
|
|
|
|
gint start,
|
2004-02-04 10:00:04 +08:00
|
|
|
gdouble scalex);
|
2001-12-01 02:23:49 +08:00
|
|
|
static guchar * render_image_tile_fault (RenderInfo *info);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
|
1998-08-20 14:46:07 +08:00
|
|
|
static RenderFunc render_funcs[6] =
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-01-30 11:17:26 +08:00
|
|
|
render_image_rgb,
|
|
|
|
render_image_rgb_a,
|
|
|
|
render_image_gray,
|
|
|
|
render_image_gray_a,
|
|
|
|
render_image_indexed,
|
|
|
|
render_image_indexed_a,
|
1997-11-25 06:05:25 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************/
|
|
|
|
/* This function is the core of the display--it offsets and */
|
|
|
|
/* scales the image according to the current parameters in the */
|
|
|
|
/* gdisp object. It handles color, grayscale, 8, 15, 16, 24, */
|
|
|
|
/* & 32 bit output depths. */
|
|
|
|
/*****************************************************************/
|
|
|
|
|
|
|
|
void
|
2001-12-01 02:23:49 +08:00
|
|
|
gimp_display_shell_render (GimpDisplayShell *shell,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
gint w,
|
|
|
|
gint h)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2002-10-20 20:22:39 +08:00
|
|
|
RenderInfo info;
|
|
|
|
GimpImageType image_type;
|
2001-12-01 02:23:49 +08:00
|
|
|
|
|
|
|
render_image_init_info (&info, shell, x, y, w, h);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-12-01 02:23:49 +08:00
|
|
|
image_type = gimp_image_projection_type (shell->gdisp->gimage);
|
2001-01-30 11:17:26 +08:00
|
|
|
|
2002-10-20 20:22:39 +08:00
|
|
|
if ((image_type < GIMP_RGB_IMAGE) || (image_type > GIMP_INDEXEDA_IMAGE))
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-11-15 22:30:26 +08:00
|
|
|
g_message ("unknown gimage projection type: %d", image_type);
|
1997-11-25 06:05:25 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((info.dest_bpp < 1) || (info.dest_bpp > 4))
|
|
|
|
{
|
1998-05-30 15:32:37 +08:00
|
|
|
g_message ("unsupported destination bytes per pixel: %d", info.dest_bpp);
|
1997-11-25 06:05:25 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
/* Currently, only RGBA and GRAYA projection types are used - the rest
|
2001-01-30 11:17:26 +08:00
|
|
|
* are in case of future need. -- austin, 28th Nov 1998.
|
|
|
|
*/
|
2001-12-12 02:11:56 +08:00
|
|
|
if (image_type != GIMP_RGBA_IMAGE && image_type != GIMP_GRAYA_IMAGE)
|
2001-12-01 02:23:49 +08:00
|
|
|
g_warning ("using untested projection type %d", image_type);
|
1998-12-06 05:48:37 +08:00
|
|
|
|
1998-08-20 14:46:07 +08:00
|
|
|
(* render_funcs[image_type]) (&info);
|
2001-12-01 02:23:49 +08:00
|
|
|
|
|
|
|
/* apply filters to the rendered projection */
|
2003-11-22 06:52:36 +08:00
|
|
|
if (shell->filter_stack)
|
|
|
|
gimp_color_display_stack_convert (shell->filter_stack,
|
|
|
|
shell->render_buf,
|
|
|
|
w, h,
|
|
|
|
3,
|
|
|
|
3 * GIMP_DISPLAY_SHELL_RENDER_BUF_WIDTH);
|
2001-12-01 02:23:49 +08:00
|
|
|
|
|
|
|
/* put it to the screen */
|
2003-11-11 03:35:56 +08:00
|
|
|
gimp_canvas_draw_rgb (GIMP_CANVAS (shell->canvas), GIMP_CANVAS_STYLE_RENDER,
|
|
|
|
x + shell->disp_xoffset, y + shell->disp_yoffset,
|
|
|
|
w, h,
|
|
|
|
shell->render_buf,
|
|
|
|
3 * GIMP_DISPLAY_SHELL_RENDER_BUF_WIDTH,
|
|
|
|
shell->offset_x, shell->offset_y);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************/
|
|
|
|
/* 8 Bit functions */
|
|
|
|
/*************************/
|
|
|
|
|
|
|
|
static void
|
1998-08-20 14:46:07 +08:00
|
|
|
render_image_indexed (RenderInfo *info)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
guchar *src;
|
|
|
|
guchar *dest;
|
1998-08-20 14:46:07 +08:00
|
|
|
guchar *cmap;
|
2001-01-30 11:17:26 +08:00
|
|
|
gulong val;
|
|
|
|
gint byte_order;
|
|
|
|
gint y, ye;
|
|
|
|
gint x, xe;
|
|
|
|
gint initial;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-12-01 02:23:49 +08:00
|
|
|
cmap = gimp_image_get_colormap (info->shell->gdisp->gimage);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-01-30 11:17:26 +08:00
|
|
|
y = info->y;
|
1997-11-25 06:05:25 +08:00
|
|
|
ye = info->y + info->h;
|
|
|
|
xe = info->x + info->w;
|
|
|
|
|
|
|
|
initial = TRUE;
|
|
|
|
byte_order = info->byte_order;
|
|
|
|
info->src = render_image_tile_fault (info);
|
|
|
|
|
|
|
|
for (; y < ye; y++)
|
|
|
|
{
|
2003-04-04 19:42:46 +08:00
|
|
|
gint error = RINT (floor ((y + 1) / info->scaley)
|
|
|
|
- floor (y / info->scaley));
|
|
|
|
|
|
|
|
if (!initial && (error == 0))
|
2001-01-30 11:17:26 +08:00
|
|
|
{
|
|
|
|
memcpy (info->dest, info->dest - info->dest_bpl, info->dest_width);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
src = info->src;
|
|
|
|
dest = info->dest;
|
|
|
|
|
1998-03-14 06:56:39 +08:00
|
|
|
g_return_if_fail (src != NULL);
|
2001-01-30 11:17:26 +08:00
|
|
|
|
1998-08-20 14:46:07 +08:00
|
|
|
for (x = info->x; x < xe; x++)
|
|
|
|
{
|
|
|
|
val = src[INDEXED_PIX] * 3;
|
|
|
|
src += 1;
|
1998-03-14 06:56:39 +08:00
|
|
|
|
1998-08-20 14:46:07 +08:00
|
|
|
dest[0] = cmap[val+0];
|
|
|
|
dest[1] = cmap[val+1];
|
|
|
|
dest[2] = cmap[val+2];
|
|
|
|
dest += 3;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
info->dest += info->dest_bpl;
|
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
initial = FALSE;
|
|
|
|
|
2003-04-04 19:42:46 +08:00
|
|
|
if (error >= 1)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-04-04 19:42:46 +08:00
|
|
|
info->src_y += error;
|
1997-11-25 06:05:25 +08:00
|
|
|
info->src = render_image_tile_fault (info);
|
1998-12-06 05:48:37 +08:00
|
|
|
initial = TRUE;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1998-08-20 14:46:07 +08:00
|
|
|
render_image_indexed_a (RenderInfo *info)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
guchar *src;
|
|
|
|
guchar *dest;
|
2001-01-30 11:17:26 +08:00
|
|
|
guint *alpha;
|
1998-08-20 14:46:07 +08:00
|
|
|
guchar *cmap;
|
2001-01-30 11:17:26 +08:00
|
|
|
gulong r, g, b;
|
|
|
|
gulong val;
|
|
|
|
guint a;
|
|
|
|
gint dark_light;
|
|
|
|
gint byte_order;
|
|
|
|
gint y, ye;
|
|
|
|
gint x, xe;
|
|
|
|
gint initial;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-12-01 02:23:49 +08:00
|
|
|
cmap = gimp_image_get_colormap (info->shell->gdisp->gimage);
|
1998-08-20 14:46:07 +08:00
|
|
|
alpha = info->alpha;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-01-30 11:17:26 +08:00
|
|
|
y = info->y;
|
1997-11-25 06:05:25 +08:00
|
|
|
ye = info->y + info->h;
|
|
|
|
xe = info->x + info->w;
|
|
|
|
|
|
|
|
initial = TRUE;
|
|
|
|
byte_order = info->byte_order;
|
|
|
|
info->src = render_image_tile_fault (info);
|
|
|
|
|
|
|
|
for (; y < ye; y++)
|
|
|
|
{
|
2003-04-04 19:42:46 +08:00
|
|
|
gint error = RINT (floor ((y + 1) / info->scaley)
|
|
|
|
- floor (y / info->scaley));
|
|
|
|
|
|
|
|
if (!initial && (error == 0) && (y & check_mod))
|
2001-01-30 11:17:26 +08:00
|
|
|
{
|
|
|
|
memcpy (info->dest, info->dest - info->dest_bpl, info->dest_width);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
src = info->src;
|
|
|
|
dest = info->dest;
|
|
|
|
|
1998-08-20 14:46:07 +08:00
|
|
|
dark_light = (y >> check_shift) + (info->x >> check_shift);
|
|
|
|
|
1998-03-14 06:56:39 +08:00
|
|
|
g_return_if_fail (src != NULL);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-08-20 14:46:07 +08:00
|
|
|
for (x = info->x; x < xe; x++)
|
|
|
|
{
|
|
|
|
a = alpha[src[ALPHA_I_PIX]];
|
|
|
|
val = src[INDEXED_PIX] * 3;
|
|
|
|
src += 2;
|
|
|
|
|
|
|
|
if (dark_light & 0x1)
|
|
|
|
{
|
2001-01-30 11:17:26 +08:00
|
|
|
r = render_blend_dark_check[(a | cmap[val + 0])];
|
|
|
|
g = render_blend_dark_check[(a | cmap[val + 1])];
|
|
|
|
b = render_blend_dark_check[(a | cmap[val + 2])];
|
1998-08-20 14:46:07 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-01-30 11:17:26 +08:00
|
|
|
r = render_blend_light_check[(a | cmap[val + 0])];
|
|
|
|
g = render_blend_light_check[(a | cmap[val + 1])];
|
|
|
|
b = render_blend_light_check[(a | cmap[val + 2])];
|
1998-08-20 14:46:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
dest[0] = r;
|
|
|
|
dest[1] = g;
|
|
|
|
dest[2] = b;
|
1997-11-25 06:05:25 +08:00
|
|
|
dest += 3;
|
|
|
|
|
1998-08-20 14:46:07 +08:00
|
|
|
if (((x + 1) & check_mod) == 0)
|
|
|
|
dark_light += 1;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
info->dest += info->dest_bpl;
|
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
initial = FALSE;
|
|
|
|
|
2003-04-04 19:42:46 +08:00
|
|
|
if (error >= 1)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-04-04 19:42:46 +08:00
|
|
|
info->src_y += error;
|
1997-11-25 06:05:25 +08:00
|
|
|
info->src = render_image_tile_fault (info);
|
1998-12-06 05:48:37 +08:00
|
|
|
initial = TRUE;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1998-08-20 14:46:07 +08:00
|
|
|
render_image_gray (RenderInfo *info)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
guchar *src;
|
|
|
|
guchar *dest;
|
2001-01-30 11:17:26 +08:00
|
|
|
gulong val;
|
|
|
|
gint byte_order;
|
|
|
|
gint y, ye;
|
|
|
|
gint x, xe;
|
|
|
|
gint initial;
|
|
|
|
|
|
|
|
y = info->y;
|
1997-11-25 06:05:25 +08:00
|
|
|
ye = info->y + info->h;
|
|
|
|
xe = info->x + info->w;
|
|
|
|
|
|
|
|
initial = TRUE;
|
|
|
|
byte_order = info->byte_order;
|
|
|
|
info->src = render_image_tile_fault (info);
|
|
|
|
|
|
|
|
for (; y < ye; y++)
|
|
|
|
{
|
2003-04-04 19:42:46 +08:00
|
|
|
gint error = RINT (floor ((y + 1) / info->scaley)
|
|
|
|
- floor (y / info->scaley));
|
|
|
|
|
|
|
|
if (!initial && (error == 0))
|
2001-01-30 11:17:26 +08:00
|
|
|
{
|
|
|
|
memcpy (info->dest, info->dest - info->dest_bpl, info->dest_width);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
src = info->src;
|
|
|
|
dest = info->dest;
|
2003-11-11 03:35:56 +08:00
|
|
|
|
1998-03-14 06:56:39 +08:00
|
|
|
g_return_if_fail (src != NULL);
|
|
|
|
|
1998-08-20 14:46:07 +08:00
|
|
|
for (x = info->x; x < xe; x++)
|
|
|
|
{
|
|
|
|
val = src[GRAY_PIX];
|
|
|
|
src += 1;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-08-20 14:46:07 +08:00
|
|
|
dest[0] = val;
|
|
|
|
dest[1] = val;
|
|
|
|
dest[2] = val;
|
|
|
|
dest += 3;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
info->dest += info->dest_bpl;
|
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
initial = FALSE;
|
|
|
|
|
2003-04-04 19:42:46 +08:00
|
|
|
if (error >= 1)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-04-04 19:42:46 +08:00
|
|
|
info->src_y += error;
|
1997-11-25 06:05:25 +08:00
|
|
|
info->src = render_image_tile_fault (info);
|
1998-12-06 05:48:37 +08:00
|
|
|
initial = TRUE;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1998-08-20 14:46:07 +08:00
|
|
|
render_image_gray_a (RenderInfo *info)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
guchar *src;
|
|
|
|
guchar *dest;
|
2001-01-30 11:17:26 +08:00
|
|
|
guint *alpha;
|
|
|
|
gulong val;
|
|
|
|
guint a;
|
|
|
|
gint dark_light;
|
|
|
|
gint byte_order;
|
|
|
|
gint y, ye;
|
|
|
|
gint x, xe;
|
|
|
|
gint initial;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
alpha = info->alpha;
|
|
|
|
|
2001-01-30 11:17:26 +08:00
|
|
|
y = info->y;
|
1997-11-25 06:05:25 +08:00
|
|
|
ye = info->y + info->h;
|
|
|
|
xe = info->x + info->w;
|
|
|
|
|
|
|
|
initial = TRUE;
|
|
|
|
byte_order = info->byte_order;
|
|
|
|
info->src = render_image_tile_fault (info);
|
|
|
|
|
|
|
|
for (; y < ye; y++)
|
|
|
|
{
|
2003-04-04 19:42:46 +08:00
|
|
|
gint error = RINT (floor ((y + 1) / info->scaley)
|
|
|
|
- floor (y / info->scaley));
|
|
|
|
|
|
|
|
if (!initial && (error == 0) && (y & check_mod))
|
2001-01-30 11:17:26 +08:00
|
|
|
{
|
|
|
|
memcpy (info->dest, info->dest - info->dest_bpl, info->dest_width);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
src = info->src;
|
|
|
|
dest = info->dest;
|
|
|
|
|
|
|
|
dark_light = (y >> check_shift) + (info->x >> check_shift);
|
|
|
|
|
1998-03-14 06:56:39 +08:00
|
|
|
g_return_if_fail (src != NULL);
|
|
|
|
|
1998-08-20 14:46:07 +08:00
|
|
|
for (x = info->x; x < xe; x++)
|
|
|
|
{
|
|
|
|
a = alpha[src[ALPHA_G_PIX]];
|
|
|
|
if (dark_light & 0x1)
|
2001-01-30 11:17:26 +08:00
|
|
|
val = render_blend_dark_check[(a | src[GRAY_PIX])];
|
1998-08-20 14:46:07 +08:00
|
|
|
else
|
2001-01-30 11:17:26 +08:00
|
|
|
val = render_blend_light_check[(a | src[GRAY_PIX])];
|
1998-08-20 14:46:07 +08:00
|
|
|
src += 2;
|
|
|
|
|
|
|
|
dest[0] = val;
|
|
|
|
dest[1] = val;
|
|
|
|
dest[2] = val;
|
|
|
|
dest += 3;
|
|
|
|
|
|
|
|
if (((x + 1) & check_mod) == 0)
|
|
|
|
dark_light += 1;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
info->dest += info->dest_bpl;
|
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
initial = FALSE;
|
|
|
|
|
2003-04-04 19:42:46 +08:00
|
|
|
if (error >= 1)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-04-04 19:42:46 +08:00
|
|
|
info->src_y += error;
|
1997-11-25 06:05:25 +08:00
|
|
|
info->src = render_image_tile_fault (info);
|
1998-12-06 05:48:37 +08:00
|
|
|
initial = TRUE;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1998-08-20 14:46:07 +08:00
|
|
|
render_image_rgb (RenderInfo *info)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-01-30 11:17:26 +08:00
|
|
|
gint byte_order;
|
|
|
|
gint y, ye;
|
2003-02-21 20:48:13 +08:00
|
|
|
gint xe;
|
2001-01-30 11:17:26 +08:00
|
|
|
gint initial;
|
|
|
|
|
|
|
|
y = info->y;
|
2000-10-26 07:14:11 +08:00
|
|
|
ye = info->y + info->h;
|
|
|
|
xe = info->x + info->w;
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
initial = TRUE;
|
2000-10-26 07:14:11 +08:00
|
|
|
byte_order = info->byte_order;
|
1997-11-25 06:05:25 +08:00
|
|
|
info->src = render_image_tile_fault (info);
|
|
|
|
|
|
|
|
for (; y < ye; y++)
|
|
|
|
{
|
2003-04-04 19:42:46 +08:00
|
|
|
gint error = RINT (floor ((y + 1) / info->scaley)
|
|
|
|
- floor (y / info->scaley));
|
|
|
|
|
|
|
|
if (!initial && (error == 0))
|
2001-01-30 11:17:26 +08:00
|
|
|
{
|
|
|
|
memcpy (info->dest, info->dest - info->dest_bpl, info->dest_width);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
|
|
|
{
|
2003-02-21 20:48:13 +08:00
|
|
|
g_return_if_fail (info->src != NULL);
|
1998-03-14 06:56:39 +08:00
|
|
|
|
2003-02-21 20:48:13 +08:00
|
|
|
memcpy (info->dest, info->src, 3 * info->w);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
info->dest += info->dest_bpl;
|
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
initial = FALSE;
|
|
|
|
|
2003-04-04 19:42:46 +08:00
|
|
|
if (error >= 1)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-04-04 19:42:46 +08:00
|
|
|
info->src_y += error;
|
1997-11-25 06:05:25 +08:00
|
|
|
info->src = render_image_tile_fault (info);
|
1998-12-06 05:48:37 +08:00
|
|
|
initial = TRUE;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1998-08-20 14:46:07 +08:00
|
|
|
render_image_rgb_a (RenderInfo *info)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
guchar *src;
|
|
|
|
guchar *dest;
|
2001-01-30 11:17:26 +08:00
|
|
|
guint *alpha;
|
|
|
|
gulong r, g, b;
|
|
|
|
guint a;
|
|
|
|
gint dark_light;
|
|
|
|
gint byte_order;
|
|
|
|
gint y, ye;
|
|
|
|
gint x, xe;
|
|
|
|
gint initial;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
alpha = info->alpha;
|
|
|
|
|
2001-01-30 11:17:26 +08:00
|
|
|
y = info->y;
|
2000-10-26 07:14:11 +08:00
|
|
|
ye = info->y + info->h;
|
|
|
|
xe = info->x + info->w;
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
initial = TRUE;
|
|
|
|
byte_order = info->byte_order;
|
|
|
|
info->src = render_image_tile_fault (info);
|
|
|
|
|
|
|
|
for (; y < ye; y++)
|
|
|
|
{
|
2003-04-04 19:42:46 +08:00
|
|
|
gint error = RINT (floor ((y + 1) / info->scaley)
|
|
|
|
- floor (y / info->scaley));
|
|
|
|
|
|
|
|
if (!initial && (error == 0) && (y & check_mod))
|
2001-01-30 11:17:26 +08:00
|
|
|
{
|
|
|
|
memcpy (info->dest, info->dest - info->dest_bpl, info->dest_width);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
src = info->src;
|
|
|
|
dest = info->dest;
|
|
|
|
|
|
|
|
dark_light = (y >> check_shift) + (info->x >> check_shift);
|
|
|
|
|
1998-03-14 06:56:39 +08:00
|
|
|
g_return_if_fail (src != NULL);
|
|
|
|
|
1999-07-29 07:00:08 +08:00
|
|
|
for (x = info->x; x < xe; x++)
|
|
|
|
{
|
|
|
|
a = alpha[src[ALPHA_PIX]];
|
|
|
|
if (dark_light & 0x1)
|
|
|
|
{
|
2001-01-30 11:17:26 +08:00
|
|
|
r = render_blend_dark_check[(a | src[RED_PIX])];
|
|
|
|
g = render_blend_dark_check[(a | src[GREEN_PIX])];
|
|
|
|
b = render_blend_dark_check[(a | src[BLUE_PIX])];
|
1999-07-29 07:00:08 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-01-30 11:17:26 +08:00
|
|
|
r = render_blend_light_check[(a | src[RED_PIX])];
|
|
|
|
g = render_blend_light_check[(a | src[GREEN_PIX])];
|
|
|
|
b = render_blend_light_check[(a | src[BLUE_PIX])];
|
1999-07-29 07:00:08 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-29 07:00:08 +08:00
|
|
|
src += 4;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-29 07:00:08 +08:00
|
|
|
dest[0] = r;
|
|
|
|
dest[1] = g;
|
|
|
|
dest[2] = b;
|
|
|
|
dest += 3;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-29 07:00:08 +08:00
|
|
|
if (((x + 1) & check_mod) == 0)
|
|
|
|
dark_light += 1;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
info->dest += info->dest_bpl;
|
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
initial = FALSE;
|
|
|
|
|
2003-04-04 19:42:46 +08:00
|
|
|
if (error >= 1)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-04-04 19:42:46 +08:00
|
|
|
info->src_y += error;
|
1997-11-25 06:05:25 +08:00
|
|
|
info->src = render_image_tile_fault (info);
|
1998-12-06 05:48:37 +08:00
|
|
|
initial = TRUE;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2001-12-01 02:23:49 +08:00
|
|
|
render_image_init_info (RenderInfo *info,
|
|
|
|
GimpDisplayShell *shell,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
gint w,
|
|
|
|
gint h)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-12-01 02:23:49 +08:00
|
|
|
info->shell = shell;
|
|
|
|
info->src_tiles = gimp_image_projection (shell->gdisp->gimage);
|
|
|
|
info->x = x + shell->offset_x;
|
|
|
|
info->y = y + shell->offset_y;
|
2001-01-30 11:17:26 +08:00
|
|
|
info->w = w;
|
|
|
|
info->h = h;
|
2002-06-27 06:16:59 +08:00
|
|
|
info->scalex = SCALEFACTOR_X (shell);
|
|
|
|
info->scaley = SCALEFACTOR_Y (shell);
|
2004-02-04 10:00:04 +08:00
|
|
|
info->src_x = (gdouble) info->x / info->scalex;
|
|
|
|
info->src_y = (gdouble) info->y / info->scaley;
|
2001-12-01 02:23:49 +08:00
|
|
|
info->src_bpp = gimp_image_projection_bytes (shell->gdisp->gimage);
|
|
|
|
info->dest = shell->render_buf;
|
|
|
|
info->dest_bpp = 3;
|
|
|
|
info->dest_bpl = info->dest_bpp * GIMP_DISPLAY_SHELL_RENDER_BUF_WIDTH;
|
1997-11-25 06:05:25 +08:00
|
|
|
info->dest_width = info->w * info->dest_bpp;
|
2001-12-01 02:23:49 +08:00
|
|
|
info->byte_order = GDK_MSB_FIRST;
|
2002-12-05 03:02:45 +08:00
|
|
|
info->scale = render_image_accelerate_scaling (w,
|
|
|
|
info->x, info->scalex);
|
2001-01-30 11:17:26 +08:00
|
|
|
info->alpha = NULL;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-12-14 23:30:31 +08:00
|
|
|
if (GIMP_IMAGE_TYPE_HAS_ALPHA (gimp_image_projection_type (shell->gdisp->gimage)))
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-01-30 11:17:26 +08:00
|
|
|
info->alpha =
|
2002-03-04 22:52:54 +08:00
|
|
|
render_image_init_alpha (gimp_image_projection_opacity (shell->gdisp->gimage) * 255.999);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-03-22 00:28:06 +08:00
|
|
|
static guint *
|
2001-01-30 11:17:26 +08:00
|
|
|
render_image_init_alpha (gint mult)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
static guint *alpha_mult = NULL;
|
2001-01-30 11:17:26 +08:00
|
|
|
static gint alpha_val = -1;
|
|
|
|
|
|
|
|
gint i;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
if (alpha_val != mult)
|
|
|
|
{
|
|
|
|
if (!alpha_mult)
|
1998-03-19 06:35:31 +08:00
|
|
|
alpha_mult = g_new (guint, 256);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
alpha_val = mult;
|
|
|
|
for (i = 0; i < 256; i++)
|
|
|
|
alpha_mult[i] = ((mult * i) / 255) << 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
return alpha_mult;
|
|
|
|
}
|
|
|
|
|
2001-12-01 02:23:49 +08:00
|
|
|
static guchar *
|
2004-02-04 10:00:04 +08:00
|
|
|
render_image_accelerate_scaling (gint width,
|
|
|
|
gint start,
|
|
|
|
gdouble scalex)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
static guchar *scale = NULL;
|
2001-01-30 11:17:26 +08:00
|
|
|
|
2003-04-04 19:42:46 +08:00
|
|
|
gint i;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-12-01 02:23:49 +08:00
|
|
|
if (! scale)
|
|
|
|
scale = g_new (guchar, GIMP_DISPLAY_SHELL_RENDER_BUF_WIDTH + 1);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
for (i = 0; i <= width; i++)
|
2001-12-01 02:23:49 +08:00
|
|
|
{
|
2003-04-04 19:42:46 +08:00
|
|
|
scale[i] = RINT (floor ((start + 1) / scalex) - floor (start / scalex));
|
|
|
|
start++;
|
2001-12-01 02:23:49 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
return scale;
|
|
|
|
}
|
|
|
|
|
2001-01-30 11:17:26 +08:00
|
|
|
static guchar *
|
1997-11-25 06:05:25 +08:00
|
|
|
render_image_tile_fault (RenderInfo *info)
|
|
|
|
{
|
2001-01-30 11:17:26 +08:00
|
|
|
Tile *tile;
|
1997-11-25 06:05:25 +08:00
|
|
|
guchar *data;
|
|
|
|
guchar *dest;
|
|
|
|
guchar *scale;
|
2001-01-30 11:17:26 +08:00
|
|
|
gint width;
|
|
|
|
gint tilex;
|
|
|
|
gint step;
|
|
|
|
gint bpp = info->src_bpp;
|
|
|
|
gint x, b;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-02-07 23:16:45 +08:00
|
|
|
tile = tile_manager_get_tile (info->src_tiles,
|
2002-12-05 03:02:45 +08:00
|
|
|
info->src_x, info->src_y,
|
1999-02-07 23:16:45 +08:00
|
|
|
TRUE, FALSE);
|
1997-11-25 06:05:25 +08:00
|
|
|
if (!tile)
|
|
|
|
return NULL;
|
|
|
|
|
2003-11-11 03:35:56 +08:00
|
|
|
data = tile_data_pointer (tile,
|
1998-08-12 01:35:34 +08:00
|
|
|
info->src_x % TILE_WIDTH,
|
|
|
|
info->src_y % TILE_HEIGHT);
|
1997-11-25 06:05:25 +08:00
|
|
|
scale = info->scale;
|
2001-01-30 11:17:26 +08:00
|
|
|
dest = tile_buf;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-01-30 11:17:26 +08:00
|
|
|
x = info->src_x;
|
1997-11-25 06:05:25 +08:00
|
|
|
width = info->w;
|
|
|
|
|
2003-03-22 00:28:06 +08:00
|
|
|
tilex = info->src_x / TILE_WIDTH;
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
while (width--)
|
|
|
|
{
|
1998-12-06 05:48:37 +08:00
|
|
|
for (b = 0; b < bpp; b++)
|
1997-11-25 06:05:25 +08:00
|
|
|
*dest++ = data[b];
|
|
|
|
|
1998-12-06 05:48:37 +08:00
|
|
|
step = *scale++;
|
|
|
|
if (step != 0)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1998-12-06 05:48:37 +08:00
|
|
|
x += step;
|
|
|
|
data += step * bpp;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-10-26 07:14:11 +08:00
|
|
|
if ((x >> tile_shift) != tilex)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1998-07-10 10:43:12 +08:00
|
|
|
tile_release (tile, FALSE);
|
1997-11-25 06:05:25 +08:00
|
|
|
tilex += 1;
|
|
|
|
|
2002-12-05 03:02:45 +08:00
|
|
|
tile = tile_manager_get_tile (info->src_tiles,
|
|
|
|
x, info->src_y,
|
|
|
|
TRUE, FALSE);
|
|
|
|
|
2000-10-26 07:14:11 +08:00
|
|
|
if (!tile)
|
|
|
|
return tile_buf;
|
|
|
|
|
2003-11-11 03:35:56 +08:00
|
|
|
data = tile_data_pointer (tile,
|
2002-12-05 03:02:45 +08:00
|
|
|
x % TILE_WIDTH,
|
|
|
|
info->src_y % TILE_HEIGHT);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-07-10 10:43:12 +08:00
|
|
|
tile_release (tile, FALSE);
|
2001-01-30 11:17:26 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
return tile_buf;
|
|
|
|
}
|