2006-12-10 05:33:38 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
1997-11-25 06:05:25 +08:00
|
|
|
* 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 <string.h>
|
2000-04-28 01:27:28 +08:00
|
|
|
|
2000-12-17 05:37:03 +08:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
2004-09-03 08:06:21 +08:00
|
|
|
#include "libgimpbase/gimpbase.h"
|
2007-03-09 21:00:01 +08:00
|
|
|
#include "libgimpmath/gimpmath.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"
|
2005-07-31 02:19:54 +08:00
|
|
|
#include "core/gimpdrawable.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"
|
2004-07-14 00:36:29 +08:00
|
|
|
#include "core/gimpprojection.h"
|
2001-05-09 10:32:03 +08:00
|
|
|
|
2005-07-20 04:42:14 +08:00
|
|
|
#include "widgets/gimprender.h"
|
|
|
|
|
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
|
|
|
|
2007-08-24 04:12:49 +08:00
|
|
|
#define GIMP_DISPLAY_ZOOM_FAST 1 << 0 /* use the fastest possible code
|
|
|
|
path trading quality for speed
|
|
|
|
*/
|
|
|
|
#define GIMP_DISPLAY_ZOOM_PIXEL_AA 1 << 1 /* provide AA edges when zooming in
|
2007-08-24 23:39:23 +08:00
|
|
|
on the actual pixels (in current
|
2007-09-11 22:45:06 +08:00
|
|
|
code only enables it between
|
|
|
|
100% and 200% zoom)
|
|
|
|
*/
|
2007-08-24 04:12:49 +08:00
|
|
|
|
|
|
|
/* The default settings are debatable, and perhaps this should even somehow be
|
|
|
|
* configurable by the user. */
|
2007-08-24 23:39:23 +08:00
|
|
|
static gint gimp_zoom_quality = GIMP_DISPLAY_ZOOM_PIXEL_AA;
|
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;
|
2007-03-14 22:37:04 +08:00
|
|
|
const guint *alpha;
|
|
|
|
const guchar *src;
|
2001-12-01 02:23:49 +08:00
|
|
|
guchar *dest;
|
|
|
|
gint x, y;
|
|
|
|
gint w, h;
|
2004-02-04 10:00:04 +08:00
|
|
|
gdouble scalex;
|
|
|
|
gdouble scaley;
|
2005-07-31 06:29:02 +08:00
|
|
|
gint src_x;
|
|
|
|
gint src_y;
|
2001-12-01 02:23:49 +08:00
|
|
|
gint dest_bpp;
|
|
|
|
gint dest_bpl;
|
|
|
|
gint dest_width;
|
2007-09-23 06:28:51 +08:00
|
|
|
|
|
|
|
/* Bresenham helpers */
|
|
|
|
gint x_dest_inc; /* amount to increment for each dest. pixel */
|
|
|
|
gint x_src_dec; /* amount to decrement for each source pixel */
|
|
|
|
gint dx_start; /* pixel fraction for first pixel */
|
2007-09-23 08:36:17 +08:00
|
|
|
|
|
|
|
gint y_dest_inc;
|
|
|
|
gint y_src_dec;
|
|
|
|
gint dy_start;
|
|
|
|
|
|
|
|
gint dy;
|
1997-11-25 06:05:25 +08:00
|
|
|
};
|
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
static void gimp_display_shell_render_info_scale (RenderInfo *info,
|
|
|
|
GimpDisplayShell *shell,
|
|
|
|
TileManager *src_tiles,
|
|
|
|
gdouble scale_x,
|
|
|
|
gdouble scale_y);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
static void gimp_display_shell_render_setup_notify (GObject *config,
|
|
|
|
GParamSpec *param_spec,
|
|
|
|
Gimp *gimp);
|
2002-11-21 23:46:19 +08:00
|
|
|
|
|
|
|
|
2005-07-20 04:42:14 +08:00
|
|
|
static guchar *tile_buf = NULL;
|
2007-03-14 22:37:04 +08:00
|
|
|
|
2005-07-20 04:42:14 +08:00
|
|
|
static guint check_mod = 0;
|
|
|
|
static guint check_shift = 0;
|
2004-09-02 22:28:37 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
void
|
2005-07-20 04:42:14 +08:00
|
|
|
gimp_display_shell_render_init (Gimp *gimp)
|
2002-11-21 23:46:19 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
2007-03-14 22:37:04 +08:00
|
|
|
g_return_if_fail (tile_buf == NULL);
|
2002-11-21 23:46:19 +08:00
|
|
|
|
2003-01-06 06:07:10 +08:00
|
|
|
g_signal_connect (gimp->config, "notify::transparency-size",
|
2007-08-16 05:29:43 +08:00
|
|
|
G_CALLBACK (gimp_display_shell_render_setup_notify),
|
2002-11-21 23:46:19 +08:00
|
|
|
gimp);
|
2003-01-06 06:07:10 +08:00
|
|
|
g_signal_connect (gimp->config, "notify::transparency-type",
|
2007-08-16 05:29:43 +08:00
|
|
|
G_CALLBACK (gimp_display_shell_render_setup_notify),
|
2002-11-21 23:46:19 +08:00
|
|
|
gimp);
|
|
|
|
|
2007-03-14 22:37:04 +08:00
|
|
|
/* allocate a buffer for arranging information from a row of tiles */
|
|
|
|
tile_buf = g_new (guchar, GIMP_RENDER_BUF_WIDTH * MAX_CHANNELS);
|
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
gimp_display_shell_render_setup_notify (G_OBJECT (gimp->config), NULL, gimp);
|
2002-11-21 23:46:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2005-07-20 04:42:14 +08:00
|
|
|
gimp_display_shell_render_exit (Gimp *gimp)
|
2002-11-21 23:46:19 +08:00
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_GIMP (gimp));
|
|
|
|
|
2003-01-06 06:07:10 +08:00
|
|
|
g_signal_handlers_disconnect_by_func (gimp->config,
|
2007-08-16 05:29:43 +08:00
|
|
|
gimp_display_shell_render_setup_notify,
|
2002-11-21 23:46:19 +08:00
|
|
|
gimp);
|
|
|
|
|
|
|
|
if (tile_buf)
|
|
|
|
{
|
|
|
|
g_free (tile_buf);
|
|
|
|
tile_buf = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2007-08-16 05:29:43 +08:00
|
|
|
gimp_display_shell_render_setup_notify (GObject *config,
|
|
|
|
GParamSpec *param_spec,
|
|
|
|
Gimp *gimp)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2002-11-21 23:46:19 +08:00
|
|
|
GimpCheckSize check_size;
|
2001-01-30 11:17:26 +08:00
|
|
|
|
2002-11-21 23:46:19 +08:00
|
|
|
g_object_get (config,
|
|
|
|
"transparency-size", &check_size,
|
|
|
|
NULL);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
switch (check_size)
|
|
|
|
{
|
2004-09-02 22:28:37 +08:00
|
|
|
case GIMP_CHECK_SIZE_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;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2004-09-02 22:28:37 +08:00
|
|
|
case GIMP_CHECK_SIZE_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;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2004-09-02 22:28:37 +08:00
|
|
|
case GIMP_CHECK_SIZE_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
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Render Image functions */
|
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
static void render_image_rgb_a (RenderInfo *info);
|
|
|
|
static void render_image_gray_a (RenderInfo *info);
|
2001-12-01 02:23:49 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
static const guint * render_image_init_alpha (gint mult);
|
2007-03-14 22:37:04 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
static const guchar * render_image_tile_fault (RenderInfo *info);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
|
2004-10-01 17:50:04 +08:00
|
|
|
static void gimp_display_shell_render_highlight (GimpDisplayShell *shell,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
gint w,
|
|
|
|
gint h,
|
|
|
|
GdkRectangle *highlight);
|
2005-07-31 06:29:02 +08:00
|
|
|
static void gimp_display_shell_render_mask (GimpDisplayShell *shell,
|
2005-07-31 02:19:54 +08:00
|
|
|
RenderInfo *info);
|
2004-10-01 17:50:04 +08:00
|
|
|
|
|
|
|
|
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 */
|
2006-03-29 01:55:52 +08:00
|
|
|
/* display object. It handles color, grayscale, 8, 15, 16, 24 */
|
1997-11-25 06:05:25 +08:00
|
|
|
/* & 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,
|
2004-10-01 17:50:04 +08:00
|
|
|
gint h,
|
|
|
|
GdkRectangle *highlight)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2005-07-31 06:29:02 +08:00
|
|
|
GimpProjection *projection;
|
|
|
|
RenderInfo info;
|
|
|
|
GimpImageType type;
|
2001-12-01 02:23:49 +08:00
|
|
|
|
2005-04-28 07:27:10 +08:00
|
|
|
g_return_if_fail (w > 0 && h > 0);
|
|
|
|
|
2006-03-29 01:55:52 +08:00
|
|
|
projection = shell->display->image->projection;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
/* Initialize RenderInfo with values that don't change during the
|
|
|
|
* call of this function.
|
2007-06-22 04:27:19 +08:00
|
|
|
*/
|
|
|
|
info.shell = shell;
|
2001-01-30 11:17:26 +08:00
|
|
|
|
2007-06-22 04:27:19 +08:00
|
|
|
info.x = x + shell->offset_x;
|
|
|
|
info.y = y + shell->offset_y;
|
|
|
|
info.w = w;
|
|
|
|
info.h = h;
|
|
|
|
|
|
|
|
info.dest_bpp = 3;
|
|
|
|
info.dest_bpl = info.dest_bpp * GIMP_RENDER_BUF_WIDTH;
|
|
|
|
info.dest_width = info.dest_bpp * info.w;
|
|
|
|
|
|
|
|
if (GIMP_IMAGE_TYPE_HAS_ALPHA (gimp_projection_get_image_type (projection)))
|
|
|
|
{
|
|
|
|
gdouble opacity = gimp_projection_get_opacity (projection);
|
|
|
|
|
|
|
|
info.alpha = render_image_init_alpha (opacity * 255.999);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Setup RenderInfo for rendering a GimpProjection level. */
|
|
|
|
{
|
|
|
|
TileManager *src_tiles;
|
|
|
|
gint level;
|
|
|
|
|
|
|
|
level = gimp_projection_get_level (projection,
|
|
|
|
shell->scale_x,
|
|
|
|
shell->scale_y);
|
|
|
|
|
|
|
|
src_tiles = gimp_projection_get_tiles_at_level (projection, level);
|
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
gimp_display_shell_render_info_scale (&info,
|
|
|
|
shell,
|
|
|
|
src_tiles,
|
|
|
|
shell->scale_x * (1 << level),
|
|
|
|
shell->scale_y * (1 << level));
|
2007-06-22 04:27:19 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
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.
|
2007-09-23 08:36:17 +08:00
|
|
|
*
|
|
|
|
* I retired them before they reach the age of 9 years unused...
|
|
|
|
* -- simon, 23rd Sep 2007.
|
2001-01-30 11:17:26 +08:00
|
|
|
*/
|
2007-06-22 04:27:19 +08:00
|
|
|
type = gimp_projection_get_image_type (projection);
|
|
|
|
|
2005-04-28 01:01:56 +08:00
|
|
|
if (G_UNLIKELY (type != GIMP_RGBA_IMAGE && type != GIMP_GRAYA_IMAGE))
|
|
|
|
g_warning ("using untested projection type %d", type);
|
1998-12-06 05:48:37 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case GIMP_RGBA_IMAGE:
|
|
|
|
render_image_rgb_a (&info);
|
|
|
|
break;
|
|
|
|
case GIMP_GRAYA_IMAGE:
|
|
|
|
render_image_gray_a (&info);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_printerr ("gimp_display_shell_render: unsupported projection type\n");
|
|
|
|
g_assert_not_reached ();
|
|
|
|
}
|
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,
|
2005-07-20 04:42:14 +08:00
|
|
|
3 * GIMP_RENDER_BUF_WIDTH);
|
2001-12-01 02:23:49 +08:00
|
|
|
|
2004-10-01 17:50:04 +08:00
|
|
|
/* dim pixels outside the highlighted rectangle */
|
|
|
|
if (highlight)
|
2005-07-31 02:19:54 +08:00
|
|
|
{
|
|
|
|
gimp_display_shell_render_highlight (shell, x, y, w, h, highlight);
|
|
|
|
}
|
2005-07-31 18:40:54 +08:00
|
|
|
else if (shell->mask)
|
2005-07-31 02:19:54 +08:00
|
|
|
{
|
2007-06-22 04:27:19 +08:00
|
|
|
TileManager *src_tiles = gimp_drawable_get_tiles (shell->mask);
|
|
|
|
|
|
|
|
/* The mask does not (yet) have an image pyramid, use the base scale of
|
|
|
|
* the shell.
|
|
|
|
*/
|
2007-08-16 05:29:43 +08:00
|
|
|
gimp_display_shell_render_info_scale (&info,
|
|
|
|
shell,
|
|
|
|
src_tiles,
|
|
|
|
shell->scale_x,
|
|
|
|
shell->scale_y);
|
2005-07-31 06:29:02 +08:00
|
|
|
|
2005-07-31 18:40:54 +08:00
|
|
|
gimp_display_shell_render_mask (shell, &info);
|
2005-07-31 02:19:54 +08:00
|
|
|
}
|
2004-10-01 17:50:04 +08:00
|
|
|
|
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,
|
2005-07-20 04:42:14 +08:00
|
|
|
3 * GIMP_RENDER_BUF_WIDTH,
|
2003-11-11 03:35:56 +08:00
|
|
|
shell->offset_x, shell->offset_y);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-01 17:50:04 +08:00
|
|
|
#define GIMP_DISPLAY_SHELL_DIM_PIXEL(buf,x) \
|
|
|
|
{ \
|
|
|
|
buf[3 * (x) + 0] >>= 1; \
|
|
|
|
buf[3 * (x) + 1] >>= 1; \
|
|
|
|
buf[3 * (x) + 2] >>= 1; \
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This function highlights the given area by dimming all pixels outside. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_display_shell_render_highlight (GimpDisplayShell *shell,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
gint w,
|
|
|
|
gint h,
|
|
|
|
GdkRectangle *highlight)
|
|
|
|
{
|
|
|
|
guchar *buf = shell->render_buf;
|
|
|
|
GdkRectangle rect;
|
|
|
|
|
|
|
|
rect.x = shell->offset_x + x;
|
|
|
|
rect.y = shell->offset_y + y;
|
|
|
|
rect.width = w;
|
|
|
|
rect.height = h;
|
|
|
|
|
|
|
|
if (gdk_rectangle_intersect (highlight, &rect, &rect))
|
|
|
|
{
|
|
|
|
rect.x -= shell->offset_x + x;
|
|
|
|
rect.y -= shell->offset_y + y;
|
|
|
|
|
|
|
|
for (y = 0; y < rect.y; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < w; x++)
|
|
|
|
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
|
|
|
|
|
2005-07-20 04:42:14 +08:00
|
|
|
buf += 3 * GIMP_RENDER_BUF_WIDTH;
|
2004-10-01 17:50:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for ( ; y < rect.y + rect.height; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < rect.x; x++)
|
|
|
|
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
|
|
|
|
|
|
|
|
for (x += rect.width; x < w; x++)
|
|
|
|
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
|
|
|
|
|
2005-07-20 04:42:14 +08:00
|
|
|
buf += 3 * GIMP_RENDER_BUF_WIDTH;
|
2004-10-01 17:50:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for ( ; y < h; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < w; x++)
|
|
|
|
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
|
|
|
|
|
2005-07-20 04:42:14 +08:00
|
|
|
buf += 3 * GIMP_RENDER_BUF_WIDTH;
|
2004-10-01 17:50:04 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (y = 0; y < h; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < w; x++)
|
|
|
|
GIMP_DISPLAY_SHELL_DIM_PIXEL (buf, x)
|
|
|
|
|
2005-07-20 04:42:14 +08:00
|
|
|
buf += 3 * GIMP_RENDER_BUF_WIDTH;
|
2004-10-01 17:50:04 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-07-31 02:19:54 +08:00
|
|
|
static void
|
2005-07-31 06:29:02 +08:00
|
|
|
gimp_display_shell_render_mask (GimpDisplayShell *shell,
|
|
|
|
RenderInfo *info)
|
2005-07-31 02:19:54 +08:00
|
|
|
{
|
|
|
|
gint y, ye;
|
|
|
|
gint x, xe;
|
|
|
|
|
|
|
|
y = info->y;
|
|
|
|
ye = info->y + info->h;
|
|
|
|
xe = info->x + info->w;
|
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
info->dy = info->dy_start;
|
2005-07-31 02:19:54 +08:00
|
|
|
info->src = render_image_tile_fault (info);
|
|
|
|
|
|
|
|
while (TRUE)
|
|
|
|
{
|
2007-09-23 08:57:15 +08:00
|
|
|
const guchar *src = info->src;
|
|
|
|
guchar *dest = info->dest;
|
2005-07-31 02:19:54 +08:00
|
|
|
|
2007-09-23 08:57:15 +08:00
|
|
|
switch (shell->mask_color)
|
2006-04-12 20:49:29 +08:00
|
|
|
{
|
2007-09-23 08:57:15 +08:00
|
|
|
case GIMP_RED_CHANNEL:
|
|
|
|
for (x = info->x; x < xe; x++, src++, dest += 3)
|
|
|
|
{
|
|
|
|
if (*src & 0x80)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
dest[1] = dest[1] >> 2;
|
|
|
|
dest[2] = dest[2] >> 2;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_GREEN_CHANNEL:
|
|
|
|
for (x = info->x; x < xe; x++, src++, dest += 3)
|
|
|
|
{
|
|
|
|
if (*src & 0x80)
|
|
|
|
continue;
|
2005-07-31 02:19:54 +08:00
|
|
|
|
2007-09-23 08:57:15 +08:00
|
|
|
dest[0] = dest[0] >> 2;
|
|
|
|
dest[2] = dest[2] >> 2;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_BLUE_CHANNEL:
|
|
|
|
for (x = info->x; x < xe; x++, src++, dest += 3)
|
2006-03-17 21:27:08 +08:00
|
|
|
{
|
2007-09-23 08:57:15 +08:00
|
|
|
if (*src & 0x80)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
dest[0] = dest[0] >> 2;
|
|
|
|
dest[1] = dest[1] >> 2;
|
2005-07-31 02:19:54 +08:00
|
|
|
}
|
2007-09-23 08:57:15 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2006-03-17 21:27:08 +08:00
|
|
|
}
|
2005-07-31 02:19:54 +08:00
|
|
|
|
|
|
|
if (++y == ye)
|
|
|
|
break;
|
|
|
|
|
2007-09-23 08:57:15 +08:00
|
|
|
info->dest += info->dest_bpl;
|
2005-07-31 02:19:54 +08:00
|
|
|
|
2007-09-23 08:57:15 +08:00
|
|
|
info->dy += info->y_dest_inc;
|
|
|
|
info->src_y += info->dy / info->y_src_dec;
|
|
|
|
info->dy = info->dy % info->y_src_dec;
|
2005-07-31 02:19:54 +08:00
|
|
|
|
2007-09-23 08:57:15 +08:00
|
|
|
info->src = render_image_tile_fault (info);
|
2005-07-31 02:19:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-10-01 17:50:04 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/*************************/
|
|
|
|
/* 8 Bit functions */
|
|
|
|
/*************************/
|
|
|
|
|
|
|
|
static void
|
1998-08-20 14:46:07 +08:00
|
|
|
render_image_gray_a (RenderInfo *info)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2005-04-28 00:44:28 +08:00
|
|
|
const guint *alpha = info->alpha;
|
|
|
|
gint y, ye;
|
|
|
|
gint x, xe;
|
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;
|
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
info->dy = info->dy_start;
|
1997-11-25 06:05:25 +08:00
|
|
|
info->src = render_image_tile_fault (info);
|
|
|
|
|
2005-04-28 07:27:10 +08:00
|
|
|
while (TRUE)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2007-09-23 08:36:17 +08:00
|
|
|
const guchar *src = info->src;
|
|
|
|
guchar *dest = info->dest;
|
|
|
|
guint dark_light;
|
1998-12-06 05:48:37 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
dark_light = (y >> check_shift) + (info->x >> check_shift);
|
2005-04-28 07:27:10 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
for (x = info->x; x < xe; x++)
|
2005-04-28 07:27:10 +08:00
|
|
|
{
|
2007-09-23 08:36:17 +08:00
|
|
|
guint a = alpha[src[ALPHA_G_PIX]];
|
|
|
|
guint val;
|
2001-01-30 11:17:26 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
if (dark_light & 0x1)
|
|
|
|
val = gimp_render_blend_dark_check[(a | src[GRAY_PIX])];
|
|
|
|
else
|
|
|
|
val = gimp_render_blend_light_check[(a | src[GRAY_PIX])];
|
2000-10-26 07:14:11 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
src += 2;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
dest[0] = val;
|
|
|
|
dest[1] = val;
|
|
|
|
dest[2] = val;
|
|
|
|
dest += 3;
|
2003-04-04 19:42:46 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
if (((x + 1) & check_mod) == 0)
|
|
|
|
dark_light += 1;
|
2006-04-12 20:49:29 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
|
2005-04-28 07:27:10 +08:00
|
|
|
if (++y == ye)
|
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
info->dest += info->dest_bpl;
|
1998-12-06 05:48:37 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
info->dy += info->y_dest_inc;
|
|
|
|
info->src_y += info->dy / info->y_src_dec;
|
|
|
|
info->dy = info->dy % info->y_src_dec;
|
2005-04-28 07:27:10 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
info->src = render_image_tile_fault (info);
|
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
|
|
|
{
|
2005-04-28 00:44:28 +08:00
|
|
|
const guint *alpha = info->alpha;
|
|
|
|
gint y, ye;
|
|
|
|
gint x, xe;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
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;
|
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
info->dy = info->dy_start;
|
1997-11-25 06:05:25 +08:00
|
|
|
info->src = render_image_tile_fault (info);
|
|
|
|
|
2005-04-28 07:27:10 +08:00
|
|
|
while (TRUE)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2007-08-16 05:29:43 +08:00
|
|
|
const guchar *src = info->src;
|
|
|
|
guchar *dest = info->dest;
|
|
|
|
guint dark_light;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
dark_light = (y >> check_shift) + (info->x >> check_shift);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
for (x = info->x; x < xe; x++)
|
|
|
|
{
|
|
|
|
guint r, g, b, a = alpha[src[ALPHA_PIX]];
|
2005-04-28 00:44:28 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
if (dark_light & 0x1)
|
|
|
|
{
|
|
|
|
r = gimp_render_blend_dark_check[(a | src[RED_PIX])];
|
|
|
|
g = gimp_render_blend_dark_check[(a | src[GREEN_PIX])];
|
|
|
|
b = gimp_render_blend_dark_check[(a | src[BLUE_PIX])];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
r = gimp_render_blend_light_check[(a | src[RED_PIX])];
|
|
|
|
g = gimp_render_blend_light_check[(a | src[GREEN_PIX])];
|
|
|
|
b = gimp_render_blend_light_check[(a | src[BLUE_PIX])];
|
|
|
|
}
|
2006-04-12 20:49:29 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
src += 4;
|
2006-04-12 20:49:29 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
dest[0] = r;
|
|
|
|
dest[1] = g;
|
|
|
|
dest[2] = b;
|
|
|
|
dest += 3;
|
2006-04-12 20:49:29 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
if (((x + 1) & check_mod) == 0)
|
|
|
|
dark_light += 1;
|
2006-04-12 20:49:29 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2005-04-28 07:27:10 +08:00
|
|
|
if (++y == ye)
|
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-09-23 08:57:15 +08:00
|
|
|
info->dest += info->dest_bpl;
|
1998-12-06 05:48:37 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
info->dy += info->y_dest_inc;
|
|
|
|
info->src_y += info->dy / info->y_src_dec;
|
|
|
|
info->dy = info->dy % info->y_src_dec;
|
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
info->src = render_image_tile_fault (info);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2007-08-16 05:29:43 +08:00
|
|
|
gimp_display_shell_render_info_scale (RenderInfo *info,
|
|
|
|
GimpDisplayShell *shell,
|
|
|
|
TileManager *src_tiles,
|
|
|
|
gdouble scale_x,
|
|
|
|
gdouble scale_y)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2007-06-22 04:27:19 +08:00
|
|
|
info->src_tiles = src_tiles;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-06-22 04:27:19 +08:00
|
|
|
/* We must reset info->dest because this member is modified in render
|
|
|
|
* functions.
|
|
|
|
*/
|
2007-09-23 06:28:51 +08:00
|
|
|
info->dest = shell->render_buf;
|
2005-07-31 06:29:02 +08:00
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
info->scalex = scale_x;
|
|
|
|
info->scaley = scale_y;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
info->src_y = (gdouble) info->y / info->scaley;
|
2007-08-14 23:17:30 +08:00
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
/* use Bresenham like stepping */
|
|
|
|
info->x_dest_inc = tile_manager_width (src_tiles);
|
|
|
|
info->x_src_dec = ceil (tile_manager_width (src_tiles) * info->scalex);
|
2007-09-17 07:38:37 +08:00
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
info->dx_start = info->x_dest_inc * info->x + info->x_dest_inc/2;
|
|
|
|
info->src_x = info->dx_start / info->x_src_dec;
|
|
|
|
info->dx_start = info->dx_start % info->x_src_dec;
|
2007-09-23 08:36:17 +08:00
|
|
|
|
|
|
|
/* same for y */
|
|
|
|
info->y_dest_inc = tile_manager_height (src_tiles);
|
|
|
|
info->y_src_dec = ceil (tile_manager_height (src_tiles) * info->scaley);
|
|
|
|
|
|
|
|
info->dy_start = info->y_dest_inc * info->y + info->y_dest_inc/2;
|
|
|
|
info->src_y = info->dy_start / info->y_src_dec;
|
|
|
|
info->dy_start = info->dy_start % info->y_src_dec;
|
2005-07-31 06:29:02 +08:00
|
|
|
}
|
|
|
|
|
2007-03-14 22:37:04 +08:00
|
|
|
static const 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)
|
2006-04-12 20:49:29 +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++)
|
2006-04-12 20:49:29 +08:00
|
|
|
alpha_mult[i] = ((mult * i) / 255) << 8;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return alpha_mult;
|
|
|
|
}
|
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
static inline void
|
2007-08-25 00:13:27 +08:00
|
|
|
box_filter (guint left_weight,
|
|
|
|
guint center_weight,
|
|
|
|
guint right_weight,
|
|
|
|
guint top_weight,
|
|
|
|
guint middle_weight,
|
|
|
|
guint bottom_weight,
|
2007-08-31 17:36:16 +08:00
|
|
|
guint sum,
|
2007-08-25 00:13:27 +08:00
|
|
|
const guchar **src, /* the 9 surrounding source pixels */
|
|
|
|
guchar *dest,
|
|
|
|
gint bpp)
|
2007-08-16 05:29:43 +08:00
|
|
|
{
|
2007-08-22 22:31:22 +08:00
|
|
|
switch (bpp)
|
2007-08-16 05:29:43 +08:00
|
|
|
{
|
|
|
|
gint i;
|
2007-08-24 04:12:49 +08:00
|
|
|
|
2007-08-24 22:33:44 +08:00
|
|
|
guint a;
|
2007-08-16 05:29:43 +08:00
|
|
|
case 4:
|
|
|
|
#define ALPHA 3
|
2007-08-24 04:12:49 +08:00
|
|
|
{
|
2007-09-24 23:43:01 +08:00
|
|
|
guint factors[9] =
|
2007-09-11 22:45:06 +08:00
|
|
|
{
|
|
|
|
(src[1][ALPHA] * top_weight) >> 8,
|
|
|
|
(src[4][ALPHA] * middle_weight) >> 8,
|
|
|
|
(src[7][ALPHA] * bottom_weight) >> 8,
|
|
|
|
(src[2][ALPHA] * top_weight) >> 8,
|
|
|
|
(src[5][ALPHA] * middle_weight) >> 8,
|
|
|
|
(src[8][ALPHA] * bottom_weight) >> 8,
|
|
|
|
(src[0][ALPHA] * top_weight) >> 8,
|
|
|
|
(src[3][ALPHA] * middle_weight) >> 8,
|
|
|
|
(src[6][ALPHA] * bottom_weight) >> 8
|
|
|
|
};
|
2007-08-24 04:12:49 +08:00
|
|
|
|
2007-08-31 17:36:16 +08:00
|
|
|
a = (center_weight * (factors[0] + factors[1] + factors[2]) +
|
|
|
|
right_weight * (factors[3] + factors[4] + factors[5]) +
|
|
|
|
left_weight * (factors[6] + factors[7] + factors[8]));
|
2007-08-24 22:33:44 +08:00
|
|
|
|
2007-08-24 23:39:23 +08:00
|
|
|
dest[ALPHA] = a / sum;
|
2007-08-24 04:12:49 +08:00
|
|
|
|
2007-08-31 17:36:16 +08:00
|
|
|
for (i = 0; i <= ALPHA; i++)
|
2007-08-24 04:12:49 +08:00
|
|
|
{
|
2007-08-24 23:39:23 +08:00
|
|
|
if (a)
|
2007-08-24 10:34:06 +08:00
|
|
|
{
|
2007-08-31 17:36:16 +08:00
|
|
|
dest[i] = ((center_weight * (factors[0] * src[1][i] +
|
|
|
|
factors[1] * src[4][i] +
|
|
|
|
factors[2] * src[7][i]) +
|
|
|
|
|
|
|
|
right_weight * (factors[3] * src[2][i] +
|
|
|
|
factors[4] * src[5][i] +
|
|
|
|
factors[5] * src[8][i]) +
|
|
|
|
|
|
|
|
left_weight * (factors[6] * src[0][i] +
|
|
|
|
factors[7] * src[3][i] +
|
|
|
|
factors[8] * src[6][i])
|
|
|
|
) / a) & 0xff;
|
2007-08-24 10:34:06 +08:00
|
|
|
}
|
2007-08-24 04:12:49 +08:00
|
|
|
}
|
|
|
|
}
|
2007-08-16 05:29:43 +08:00
|
|
|
#undef ALPHA
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
#define ALPHA 1
|
2007-08-24 22:33:44 +08:00
|
|
|
|
2007-08-24 04:12:49 +08:00
|
|
|
/* NOTE: this is a copy and paste of the code above, the ALPHA changes
|
|
|
|
* the behavior in all needed ways. */
|
|
|
|
{
|
2007-09-24 23:43:01 +08:00
|
|
|
guint factors[9] =
|
2007-09-11 22:45:06 +08:00
|
|
|
{
|
|
|
|
(src[1][ALPHA] * top_weight) >> 8,
|
|
|
|
(src[4][ALPHA] * middle_weight) >> 8,
|
|
|
|
(src[7][ALPHA] * bottom_weight) >> 8,
|
|
|
|
(src[2][ALPHA] * top_weight) >> 8,
|
|
|
|
(src[5][ALPHA] * middle_weight) >> 8,
|
|
|
|
(src[8][ALPHA] * bottom_weight) >> 8,
|
|
|
|
(src[0][ALPHA] * top_weight) >> 8,
|
|
|
|
(src[3][ALPHA] * middle_weight) >> 8,
|
|
|
|
(src[6][ALPHA] * bottom_weight) >> 8
|
|
|
|
};
|
2007-08-24 04:12:49 +08:00
|
|
|
|
2007-08-31 17:36:16 +08:00
|
|
|
a = (center_weight * (factors[0] + factors[1] + factors[2]) +
|
|
|
|
right_weight * (factors[3] + factors[4] + factors[5]) +
|
|
|
|
left_weight * (factors[6] + factors[7] + factors[8]));
|
2007-08-24 10:34:06 +08:00
|
|
|
|
2007-08-24 23:39:23 +08:00
|
|
|
dest[ALPHA] = a / sum;
|
2007-08-24 22:33:44 +08:00
|
|
|
|
2007-08-31 17:36:16 +08:00
|
|
|
for (i = 0; i <= ALPHA; i++)
|
2007-08-24 04:12:49 +08:00
|
|
|
{
|
2007-08-24 23:39:23 +08:00
|
|
|
if (a)
|
2007-08-24 10:34:06 +08:00
|
|
|
{
|
2007-08-31 17:36:16 +08:00
|
|
|
dest[i] = ((center_weight * (factors[0] * src[1][i] +
|
|
|
|
factors[1] * src[4][i] +
|
|
|
|
factors[2] * src[7][i]) +
|
|
|
|
|
|
|
|
right_weight * (factors[3] * src[2][i] +
|
|
|
|
factors[4] * src[5][i] +
|
|
|
|
factors[5] * src[8][i]) +
|
|
|
|
|
|
|
|
left_weight * (factors[6] * src[0][i] +
|
|
|
|
factors[7] * src[3][i] +
|
|
|
|
factors[8] * src[6][i])
|
|
|
|
) / a) & 0xff;
|
2007-08-24 10:34:06 +08:00
|
|
|
}
|
2007-08-24 04:12:49 +08:00
|
|
|
}
|
|
|
|
}
|
2007-08-16 05:29:43 +08:00
|
|
|
#undef ALPHA
|
|
|
|
break;
|
2007-08-22 22:31:22 +08:00
|
|
|
default:
|
2007-08-25 00:13:27 +08:00
|
|
|
g_warning ("bpp=%i not implemented as box filter", bpp);
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fast paths */
|
|
|
|
static const guchar * render_image_tile_fault_one_row (RenderInfo *info);
|
|
|
|
static const guchar * render_image_tile_fault_nearest (RenderInfo *info);
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
/* 012 <- this is the order of the numbered source tiles / pixels.
|
|
|
|
* 345 for the 3x3 neighbourhoods.
|
|
|
|
* 678
|
2007-08-22 22:31:22 +08:00
|
|
|
*/
|
|
|
|
|
2007-08-14 21:52:42 +08:00
|
|
|
/* function to render a horizontal line of view data */
|
2007-03-14 22:37:04 +08:00
|
|
|
static const guchar *
|
1997-11-25 06:05:25 +08:00
|
|
|
render_image_tile_fault (RenderInfo *info)
|
2007-08-16 05:29:43 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
Tile *tile[9];
|
|
|
|
const guchar *src[9];
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
guchar *dest;
|
|
|
|
gint width;
|
2007-08-22 22:31:22 +08:00
|
|
|
gint tilex0; /* the current x-tile indice used for the middle
|
2007-08-16 05:29:43 +08:00
|
|
|
sample pair*/
|
|
|
|
gint tilex1; /* the current x-tile indice used for the right
|
|
|
|
sample pair */
|
2007-08-22 22:31:22 +08:00
|
|
|
gint tilexL; /* the current x-tile indice used for the left
|
|
|
|
sample pair */
|
2007-08-16 05:29:43 +08:00
|
|
|
gint bpp;
|
2007-09-23 06:28:51 +08:00
|
|
|
gint dx;
|
|
|
|
gint src_x;
|
|
|
|
gint skipped;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
guint footprint_x;
|
|
|
|
guint footprint_y;
|
2007-08-24 23:58:49 +08:00
|
|
|
guint foosum;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-08-24 23:39:23 +08:00
|
|
|
guint left_weight;
|
2007-08-25 00:00:48 +08:00
|
|
|
guint center_weight;
|
2007-08-24 23:39:23 +08:00
|
|
|
guint right_weight;
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-24 23:39:23 +08:00
|
|
|
guint top_weight;
|
2007-08-25 00:00:48 +08:00
|
|
|
guint middle_weight;
|
2007-08-24 23:39:23 +08:00
|
|
|
guint bottom_weight;
|
2007-09-17 07:38:37 +08:00
|
|
|
|
2007-09-13 04:26:58 +08:00
|
|
|
guint source_width;
|
|
|
|
guint source_height;
|
|
|
|
|
|
|
|
source_width = tile_manager_width (info->src_tiles);
|
|
|
|
source_height = tile_manager_height (info->src_tiles);
|
2007-08-31 17:36:16 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
/* dispatch to fast path functions on special conditions */
|
2007-08-31 18:04:37 +08:00
|
|
|
if ((gimp_zoom_quality & GIMP_DISPLAY_ZOOM_FAST)
|
2007-08-31 17:36:16 +08:00
|
|
|
|
2007-08-24 23:39:23 +08:00
|
|
|
/* use nearest neighbour for exact levels */
|
2007-08-31 18:04:37 +08:00
|
|
|
|| (info->scalex == 1.0 &&
|
2007-09-11 22:45:06 +08:00
|
|
|
info->scaley == 1.0)
|
2007-08-24 22:33:44 +08:00
|
|
|
|
2007-08-24 23:39:23 +08:00
|
|
|
/* or when we're larger than 1.0 and not using any AA */
|
|
|
|
|| (info->shell->scale_x > 1.0 &&
|
|
|
|
info->shell->scale_y > 1.0 &&
|
2007-08-31 17:36:16 +08:00
|
|
|
(!(gimp_zoom_quality & GIMP_DISPLAY_ZOOM_PIXEL_AA)))
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-31 17:36:16 +08:00
|
|
|
/* or at any point when both scale factors are greater or equal to 200% */
|
|
|
|
|| (info->shell->scale_x >= 2.0 &&
|
|
|
|
info->shell->scale_y >= 2.0 )
|
2007-09-11 22:45:06 +08:00
|
|
|
|
2007-08-31 18:04:37 +08:00
|
|
|
/* or when we're scaling a 1bpp texture, this code-path seems to be
|
|
|
|
* invoked when interacting with SIOX which uses a palletized drawable
|
|
|
|
*/
|
|
|
|
|| (tile_manager_bpp (info->src_tiles)==1)
|
2007-08-24 22:33:44 +08:00
|
|
|
)
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-16 05:29:43 +08:00
|
|
|
return render_image_tile_fault_nearest (info);
|
|
|
|
}
|
|
|
|
else if (((info->src_y) & ~(TILE_WIDTH -1)) ==
|
2007-08-22 22:31:22 +08:00
|
|
|
((info->src_y + 1) & ~(TILE_WIDTH -1)) &&
|
|
|
|
((info->src_y) & ~(TILE_WIDTH -1)) ==
|
2007-09-13 04:26:58 +08:00
|
|
|
((info->src_y - 1) & ~(TILE_WIDTH -1)) &&
|
|
|
|
(info->src_y + 1 < source_height)
|
2007-08-22 22:31:22 +08:00
|
|
|
)
|
2007-08-16 05:29:43 +08:00
|
|
|
{
|
2007-08-25 00:13:27 +08:00
|
|
|
/* all the tiles needed are in a single row, use a tile iterator
|
|
|
|
* optimized for this case. */
|
2007-08-16 05:29:43 +08:00
|
|
|
return render_image_tile_fault_one_row (info);
|
|
|
|
}
|
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
footprint_y = info->y_src_dec;
|
2007-09-23 06:28:51 +08:00
|
|
|
footprint_x = info->x_src_dec;
|
2007-09-13 02:29:11 +08:00
|
|
|
|
2007-08-24 23:58:49 +08:00
|
|
|
foosum = footprint_x * footprint_y;
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
top_weight = MAX (footprint_y / 2, info->dy) - info->dy;
|
|
|
|
bottom_weight = MAX (info->dy, footprint_y / 2) - footprint_y / 2;
|
|
|
|
middle_weight = footprint_y - top_weight - bottom_weight;
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[4] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
info->src_x, info->src_y,
|
|
|
|
TRUE, FALSE);
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[7] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
info->src_x, info->src_y + 1,
|
|
|
|
TRUE, FALSE);
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[1] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
info->src_x, info->src_y - 1,
|
|
|
|
TRUE, FALSE);
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[5] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
info->src_x + 1, info->src_y,
|
|
|
|
TRUE, FALSE);
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[8] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
info->src_x + 1, info->src_y + 1,
|
|
|
|
TRUE, FALSE);
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[2] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
info->src_x + 1, info->src_y - 1,
|
|
|
|
TRUE, FALSE);
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[3] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
info->src_x - 1, info->src_y,
|
|
|
|
TRUE, FALSE);
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[6] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
info->src_x - 1, info->src_y + 1,
|
|
|
|
TRUE, FALSE);
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[0] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
info->src_x - 1, info->src_y - 1,
|
|
|
|
TRUE, FALSE);
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
g_return_val_if_fail (tile[4] != NULL, tile_buf);
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
src[4] = tile_data_pointer (tile[4], info->src_x, info->src_y);
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[5])
|
2007-08-16 05:29:43 +08:00
|
|
|
{
|
2007-09-13 02:29:11 +08:00
|
|
|
src[5] = tile_data_pointer (tile[5], info->src_x + 1, info->src_y);
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[5] = src[4]; /* reusing existing pixel data */
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[7])
|
2007-08-16 05:29:43 +08:00
|
|
|
{
|
2007-09-13 02:29:11 +08:00
|
|
|
src[7] = tile_data_pointer (tile[7], info->src_x, info->src_y + 1);
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[7] = src[4]; /* reusing existing pixel data */
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[1])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-09-13 02:29:11 +08:00
|
|
|
src[1] = tile_data_pointer (tile[1], info->src_x, info->src_y - 1);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[1] = src[4]; /* reusing existing pixel data */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[8])
|
2007-08-16 05:29:43 +08:00
|
|
|
{
|
2007-09-13 02:29:11 +08:00
|
|
|
src[8] = tile_data_pointer (tile[8], info->src_x + 1, info->src_y + 1);
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[8] = src[5]; /* reusing existing pixel data */
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
|
2007-08-22 22:31:22 +08:00
|
|
|
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[0])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-09-13 02:29:11 +08:00
|
|
|
src[0] = tile_data_pointer (tile[0], info->src_x - 1, info->src_y - 1);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[0] = src[1]; /* reusing existing pixel data */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[2])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-09-13 02:29:11 +08:00
|
|
|
src[2] = tile_data_pointer (tile[2], info->src_x + 1, info->src_y - 1);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[2] = src[4]; /* reusing existing pixel data */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[3])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-09-13 02:29:11 +08:00
|
|
|
src[3] = tile_data_pointer (tile[3], info->src_x - 1, info->src_y);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[3] = src[4]; /* reusing existing pixel data */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[6])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-09-13 02:29:11 +08:00
|
|
|
src[6] = tile_data_pointer (tile[6], info->src_x - 1, info->src_y + 1);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[6] = src[7]; /* reusing existing pixel data */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
bpp = tile_manager_bpp (info->src_tiles);
|
|
|
|
dest = tile_buf;
|
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
dx = info->dx_start;
|
|
|
|
src_x = info->src_x;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
width = info->w;
|
|
|
|
|
|
|
|
tilex0 = info->src_x / TILE_WIDTH;
|
|
|
|
tilex1 = (info->src_x + 1) / TILE_WIDTH;
|
2007-08-22 22:31:22 +08:00
|
|
|
tilexL = (info->src_x - 1) / TILE_WIDTH;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
2007-09-23 06:28:51 +08:00
|
|
|
/* we're dealing with unsigneds here, be extra careful */
|
|
|
|
left_weight = MAX (footprint_x / 2, dx) - dx;
|
|
|
|
right_weight = MAX (dx, footprint_x / 2) - footprint_x / 2;
|
|
|
|
center_weight = footprint_x - left_weight - right_weight;
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
if (src_x + 1 >= source_width)
|
2007-09-13 04:26:58 +08:00
|
|
|
{
|
|
|
|
src[2]=src[1];
|
|
|
|
src[5]=src[4];
|
|
|
|
src[8]=src[7];
|
|
|
|
}
|
2007-09-23 06:28:51 +08:00
|
|
|
if (info->src_y + 1 >= source_height)
|
2007-09-13 04:26:58 +08:00
|
|
|
{
|
|
|
|
src[6]=src[3];
|
|
|
|
src[7]=src[4];
|
|
|
|
src[8]=src[5];
|
|
|
|
}
|
2007-09-23 06:28:51 +08:00
|
|
|
box_filter (left_weight, center_weight, right_weight,
|
|
|
|
top_weight, middle_weight, bottom_weight, foosum,
|
|
|
|
src, dest, bpp);
|
2007-09-11 22:45:06 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
dest += bpp;
|
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
dx += info->x_dest_inc;
|
|
|
|
skipped = dx / info->x_src_dec;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
if (skipped)
|
|
|
|
{
|
2007-09-23 06:28:51 +08:00
|
|
|
dx -= skipped * info->x_src_dec;
|
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
/* if we changed integer source pixel coordinates in the source
|
|
|
|
* buffer, make sure the src pointers (and their backing tiles) are
|
|
|
|
* correct
|
2007-08-31 17:36:16 +08:00
|
|
|
*/
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (src[0] != src[1])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[0] += skipped * bpp;
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-09-11 22:45:06 +08:00
|
|
|
tilexL =- 1; /* this forces a refetch of the left most source
|
|
|
|
samples */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
2007-08-31 17:36:16 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (src[3] != src[4])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[3] += skipped * bpp;
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-09-11 22:45:06 +08:00
|
|
|
tilexL = -1; /* this forces a refetch of the left most source
|
|
|
|
samples */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (src[6] != src[7])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[6] += skipped * bpp;
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-09-11 22:45:06 +08:00
|
|
|
tilexL = -1; /* this forces a refetch of the left most source
|
|
|
|
samples */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
src[1] += skipped * bpp;
|
|
|
|
src[4] += skipped * bpp;
|
|
|
|
src[7] += skipped * bpp;
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
src[5] += skipped * bpp;
|
|
|
|
src[8] += skipped * bpp;
|
|
|
|
src[2] += skipped * bpp;
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
src_x += skipped;
|
|
|
|
|
|
|
|
if ((src_x / TILE_WIDTH) != tilex0)
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
tile_release (tile[4], FALSE);
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[7])
|
|
|
|
tile_release (tile[7], FALSE);
|
|
|
|
if (tile[1])
|
|
|
|
tile_release (tile[1], FALSE);
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
tilex0 += 1;
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[4] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
src_x, info->src_y,
|
|
|
|
TRUE, FALSE);
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[7] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
src_x, info->src_y + 1,
|
|
|
|
TRUE, FALSE);
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[1] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
src_x, info->src_y - 1,
|
|
|
|
TRUE, FALSE);
|
2007-09-13 02:29:11 +08:00
|
|
|
if (! tile[4])
|
2007-08-16 05:29:43 +08:00
|
|
|
goto done;
|
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
src[4] = tile_data_pointer (tile[4], src_x, info->src_y);
|
|
|
|
|
|
|
|
if (! tile[7])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[7] = src[4];
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[7] = tile_data_pointer (tile[7],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x, info->src_y + 1);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
2007-09-13 02:29:11 +08:00
|
|
|
|
|
|
|
if (! tile[1])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[1] = src[4];
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[1] = tile_data_pointer (tile[1],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x, info->src_y - 1);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
|
2007-08-31 17:36:16 +08:00
|
|
|
if (((src_x + 1) / TILE_WIDTH) != tilex1)
|
2007-08-16 05:29:43 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[5])
|
|
|
|
tile_release (tile[5], FALSE);
|
|
|
|
if (tile[8])
|
|
|
|
tile_release (tile[8], FALSE);
|
|
|
|
if (tile[2])
|
|
|
|
tile_release (tile[2], FALSE);
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
tilex1 += 1;
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[5] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
src_x + 1, info->src_y,
|
|
|
|
TRUE, FALSE);
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[8] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
src_x + 1, info->src_y + 1,
|
|
|
|
TRUE, FALSE);
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[2] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
src_x + 1, info->src_y - 1,
|
|
|
|
TRUE, FALSE);
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
if (! tile[5])
|
2007-08-16 05:29:43 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[5] = src[4];
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[5] = tile_data_pointer (tile[5],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x + 1, info->src_y);
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
if (! tile[8])
|
2007-08-16 05:29:43 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[8] = src[7];
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[8] = tile_data_pointer (tile[8],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x + 1, info->src_y + 1);
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
if (! tile[2])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[2] = src[1];
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[2] = tile_data_pointer (tile[2],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x + 1, info->src_y - 1);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-31 17:36:16 +08:00
|
|
|
if (((src_x - 1) / TILE_WIDTH) != tilexL)
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[0])
|
|
|
|
tile_release (tile[0], FALSE);
|
|
|
|
if (tile[3])
|
|
|
|
tile_release (tile[3], FALSE);
|
|
|
|
if (tile[6])
|
|
|
|
tile_release (tile[6], FALSE);
|
2007-08-22 22:31:22 +08:00
|
|
|
|
|
|
|
tilexL += 1;
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[0] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
src_x - 1, info->src_y - 1,
|
|
|
|
TRUE, FALSE);
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[3] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
src_x - 1, info->src_y,
|
|
|
|
TRUE, FALSE);
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[6] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
src_x - 1, info->src_y + 1,
|
|
|
|
TRUE, FALSE);
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
if (! tile[3])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[3] = src[4];
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[3] = tile_data_pointer (tile[3],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x - 1, info->src_y);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
if (! tile[6])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[6] = src[7];
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[6] = tile_data_pointer (tile[6],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x - 1, info->src_y + 1);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
if (! tile[0])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[0] = src[1];
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[0] = tile_data_pointer (tile[0],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x - 1, info->src_y - 1);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
2007-09-13 04:26:58 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
while (--width);
|
|
|
|
|
|
|
|
done:
|
2007-09-23 06:28:51 +08:00
|
|
|
for (dx = 0; dx < 9; dx++)
|
|
|
|
if (tile[dx])
|
|
|
|
tile_release (tile[dx], FALSE);
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
return tile_buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* function to render a horizontal line of view data */
|
|
|
|
static const guchar *
|
|
|
|
render_image_tile_fault_nearest (RenderInfo *info)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2005-04-28 00:44:28 +08:00
|
|
|
Tile *tile;
|
2005-04-28 07:27:10 +08:00
|
|
|
const guchar *src;
|
2005-04-28 00:44:28 +08:00
|
|
|
guchar *dest;
|
|
|
|
gint width;
|
|
|
|
gint tilex;
|
2005-07-31 06:29:02 +08:00
|
|
|
gint bpp;
|
2007-09-23 06:28:51 +08:00
|
|
|
gint src_x;
|
|
|
|
gint dx;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-02-07 23:16:45 +08:00
|
|
|
tile = tile_manager_get_tile (info->src_tiles,
|
2006-04-12 20:49:29 +08:00
|
|
|
info->src_x, info->src_y, TRUE, FALSE);
|
2005-04-28 01:01:56 +08:00
|
|
|
|
2005-04-28 01:53:10 +08:00
|
|
|
g_return_val_if_fail (tile != NULL, tile_buf);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
src = tile_data_pointer (tile, info->src_x, info->src_y);
|
2005-07-31 06:29:02 +08:00
|
|
|
|
|
|
|
bpp = tile_manager_bpp (info->src_tiles);
|
2001-01-30 11:17:26 +08:00
|
|
|
dest = tile_buf;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
dx = info->dx_start;
|
2007-08-14 23:17:30 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
width = info->w;
|
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
src_x = info->src_x;
|
2003-03-22 00:28:06 +08:00
|
|
|
tilex = info->src_x / TILE_WIDTH;
|
|
|
|
|
2005-04-28 07:27:10 +08:00
|
|
|
do
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2007-09-11 22:45:06 +08:00
|
|
|
const guchar *s = src;
|
|
|
|
gint skipped;
|
2005-04-28 07:27:10 +08:00
|
|
|
|
|
|
|
switch (bpp)
|
|
|
|
{
|
|
|
|
case 4:
|
|
|
|
*dest++ = *s++;
|
|
|
|
case 3:
|
|
|
|
*dest++ = *s++;
|
|
|
|
case 2:
|
|
|
|
*dest++ = *s++;
|
|
|
|
case 1:
|
|
|
|
*dest++ = *s++;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
dx += info->x_dest_inc;
|
|
|
|
skipped = dx / info->x_src_dec;
|
2007-09-11 22:45:06 +08:00
|
|
|
|
2007-08-14 21:52:42 +08:00
|
|
|
if (skipped)
|
2006-04-12 20:49:29 +08:00
|
|
|
{
|
2007-08-14 21:52:42 +08:00
|
|
|
src += skipped * bpp;
|
|
|
|
src_x += skipped;
|
2007-09-23 06:28:51 +08:00
|
|
|
dx -= skipped * info->x_src_dec;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-08-14 21:52:42 +08:00
|
|
|
if ((src_x / TILE_WIDTH) != tilex)
|
2006-04-12 20:49:29 +08:00
|
|
|
{
|
|
|
|
tile_release (tile, FALSE);
|
|
|
|
tilex += 1;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2006-04-12 20:49:29 +08:00
|
|
|
tile = tile_manager_get_tile (info->src_tiles,
|
2007-08-14 21:52:42 +08:00
|
|
|
src_x, info->src_y, TRUE, FALSE);
|
2007-09-13 02:29:11 +08:00
|
|
|
if (! tile)
|
2006-04-12 20:49:29 +08:00
|
|
|
return tile_buf;
|
2000-10-26 07:14:11 +08:00
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
src = tile_data_pointer (tile, src_x, info->src_y);
|
2006-04-12 20:49:29 +08:00
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
2005-04-28 07:27:10 +08:00
|
|
|
while (--width);
|
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;
|
|
|
|
}
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
static const guchar *
|
|
|
|
render_image_tile_fault_one_row (RenderInfo *info)
|
|
|
|
{
|
2007-08-22 22:31:22 +08:00
|
|
|
/* NOTE: there are some additional overhead that can be factored out
|
2007-08-23 21:25:30 +08:00
|
|
|
* in the tile administration of this fast path
|
2007-08-31 17:36:16 +08:00
|
|
|
*/
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
Tile *tile[3];
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
const guchar *src[9];
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
guchar *dest;
|
|
|
|
gint width;
|
2007-08-22 22:31:22 +08:00
|
|
|
gint tilex0; /* the current x-tile indice used for the middle
|
|
|
|
sample pair*/
|
|
|
|
gint tilex1; /* the current x-tile indice used for the right
|
|
|
|
sample pair */
|
|
|
|
gint tilexL; /* the current x-tile indice used for the left
|
|
|
|
sample pair */
|
2007-08-16 05:29:43 +08:00
|
|
|
gint bpp;
|
2007-09-23 06:28:51 +08:00
|
|
|
gint dx;
|
|
|
|
gint src_x;
|
|
|
|
gint skipped;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-08-24 23:39:23 +08:00
|
|
|
guint footprint_x;
|
|
|
|
guint footprint_y;
|
2007-08-24 23:58:49 +08:00
|
|
|
guint foosum;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-08-24 23:39:23 +08:00
|
|
|
guint left_weight;
|
2007-08-25 00:00:48 +08:00
|
|
|
guint center_weight;
|
2007-08-24 23:39:23 +08:00
|
|
|
guint right_weight;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-08-24 23:39:23 +08:00
|
|
|
guint top_weight;
|
2007-08-25 00:00:48 +08:00
|
|
|
guint middle_weight;
|
2007-08-24 23:39:23 +08:00
|
|
|
guint bottom_weight;
|
2007-08-31 17:36:16 +08:00
|
|
|
|
2007-09-13 04:26:58 +08:00
|
|
|
guint source_width;
|
|
|
|
|
|
|
|
source_width = tile_manager_width (info->src_tiles);
|
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
footprint_y = info->y_src_dec;
|
2007-09-23 06:28:51 +08:00
|
|
|
footprint_x = info->x_src_dec;
|
2007-08-24 23:58:49 +08:00
|
|
|
foosum = footprint_x * footprint_y;
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-09-23 08:36:17 +08:00
|
|
|
top_weight = MAX (footprint_y / 2, info->dy) - info->dy;
|
|
|
|
bottom_weight = MAX (info->dy, footprint_y / 2) - footprint_y / 2;
|
|
|
|
middle_weight = footprint_y - top_weight - bottom_weight;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[0] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
info->src_x, info->src_y, TRUE, FALSE);
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[1] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
info->src_x + 1, info->src_y, TRUE, FALSE);
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[2] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
info->src_x - 1, info->src_y, TRUE, FALSE);
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
g_return_val_if_fail (tile[0] != NULL, tile_buf);
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
src[4] = tile_data_pointer (tile[0], info->src_x, info->src_y);
|
|
|
|
src[7] = tile_data_pointer (tile[0], info->src_x, info->src_y + 1);
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[1])
|
2007-08-16 05:29:43 +08:00
|
|
|
{
|
2007-09-13 02:29:11 +08:00
|
|
|
src[5] = tile_data_pointer (tile[1], info->src_x + 1, info->src_y);
|
|
|
|
src[8] = tile_data_pointer (tile[1], info->src_x + 1, info->src_y + 1);
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
2007-08-22 22:31:22 +08:00
|
|
|
else
|
2007-08-16 05:29:43 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[5] = src[4]; /* reusing existing pixel data */
|
|
|
|
src[8] = src[5]; /* reusing existing pixel data */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-24 22:33:44 +08:00
|
|
|
if (tile[0])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-09-13 02:29:11 +08:00
|
|
|
src[1] = tile_data_pointer (tile[0], info->src_x, info->src_y - 1);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[1] = src[4]; /* reusing existing pixel data */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[2])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-09-13 02:29:11 +08:00
|
|
|
src[0] = tile_data_pointer (tile[2], info->src_x - 1, info->src_y - 1);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[0] = src[1]; /* reusing existing pixel data */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[1])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-09-13 02:29:11 +08:00
|
|
|
src[2] = tile_data_pointer (tile[1], info->src_x + 1, info->src_y - 1);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[2] = src[4]; /* reusing existing pixel data */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[2])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-09-13 02:29:11 +08:00
|
|
|
src[3] = tile_data_pointer (tile[2], info->src_x - 1, info->src_y);
|
|
|
|
src[6] = tile_data_pointer (tile[2], info->src_x - 1, info->src_y + 1);
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[3] = src[4]; /* reusing existing pixel data */
|
|
|
|
src[6] = src[7]; /* reusing existing pixel data */
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
|
2007-08-22 22:31:22 +08:00
|
|
|
bpp = tile_manager_bpp (info->src_tiles);
|
|
|
|
dest = tile_buf;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
dx = info->dx_start;
|
|
|
|
src_x = info->src_x;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-08-22 22:31:22 +08:00
|
|
|
width = info->w;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-08-22 22:31:22 +08:00
|
|
|
tilex0 = info->src_x / TILE_WIDTH;
|
|
|
|
tilex1 = (info->src_x + 1) / TILE_WIDTH;
|
|
|
|
tilexL = (info->src_x - 1) / TILE_WIDTH;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
2007-09-23 06:28:51 +08:00
|
|
|
left_weight = MAX (footprint_x / 2, dx) - dx;
|
|
|
|
right_weight = MAX (dx, footprint_x / 2) - footprint_x / 2;
|
|
|
|
center_weight = footprint_x - left_weight - right_weight;
|
2007-09-11 22:45:06 +08:00
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
if (src_x + 1 >= source_width)
|
|
|
|
{
|
|
|
|
src[2]=src[1];
|
|
|
|
src[5]=src[4];
|
|
|
|
src[8]=src[7];
|
|
|
|
}
|
|
|
|
box_filter (left_weight, center_weight, right_weight,
|
|
|
|
top_weight, middle_weight, bottom_weight, foosum,
|
|
|
|
src, dest, bpp);
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
dest += bpp;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-09-23 06:28:51 +08:00
|
|
|
dx += info->x_dest_inc;
|
|
|
|
skipped = dx / info->x_src_dec;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
if (skipped)
|
|
|
|
{
|
2007-09-23 06:28:51 +08:00
|
|
|
dx -= skipped * info->x_src_dec;
|
|
|
|
|
2007-08-22 22:31:22 +08:00
|
|
|
/* if we changed integer source pixel coordinates in the source
|
|
|
|
* buffer, make sure the src pointers (and their backing tiles) are
|
|
|
|
* correct
|
2007-08-31 17:36:16 +08:00
|
|
|
*/
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (src[0] != src[1])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[0] += skipped * bpp;
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-09-11 22:45:06 +08:00
|
|
|
tilexL = -1; /* this forces a refetch of the left most source
|
|
|
|
samples */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
2007-08-31 17:36:16 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (src[3] != src[4])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[3] += skipped * bpp;
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-09-11 22:45:06 +08:00
|
|
|
tilexL = -1; /* this forces a refetch of the left most source
|
|
|
|
samples */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
if (src[6] != src[7])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[6] += skipped * bpp;
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-09-11 22:45:06 +08:00
|
|
|
tilexL = -1; /* this forces a refetch of the left most source
|
|
|
|
samples */
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
src[1] += skipped * bpp;
|
|
|
|
src[4] += skipped * bpp;
|
|
|
|
src[7] += skipped * bpp;
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
src[5] += skipped * bpp;
|
|
|
|
src[8] += skipped * bpp;
|
|
|
|
src[2] += skipped * bpp;
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
src_x += skipped;
|
|
|
|
|
|
|
|
if ((src_x / TILE_WIDTH) != tilex0)
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
tile_release (tile[0], FALSE);
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-08-22 22:31:22 +08:00
|
|
|
tilex0 += 1;
|
2007-08-16 05:29:43 +08:00
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[0] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
src_x, info->src_y, TRUE, FALSE);
|
2007-09-13 02:29:11 +08:00
|
|
|
if (! tile[0])
|
2007-08-16 05:29:43 +08:00
|
|
|
goto done;
|
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
src[4] = tile_data_pointer (tile[0], src_x, info->src_y);
|
|
|
|
src[7] = tile_data_pointer (tile[0], src_x, info->src_y + 1);
|
|
|
|
src[1] = tile_data_pointer (tile[0], src_x, info->src_y - 1);
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
|
2007-08-31 17:36:16 +08:00
|
|
|
if (((src_x + 1) / TILE_WIDTH) != tilex1)
|
2007-08-16 05:29:43 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[1])
|
|
|
|
tile_release (tile[1], FALSE);
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
tilex1 += 1;
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[1] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
src_x + 1, info->src_y,
|
|
|
|
TRUE, FALSE);
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
if (! tile[1])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[5] = src[4];
|
|
|
|
src[8] = src[7];
|
|
|
|
src[2] = src[1];
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[5] = tile_data_pointer (tile[1],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x + 1, info->src_y);
|
2007-08-23 21:25:30 +08:00
|
|
|
src[8] = tile_data_pointer (tile[1],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x + 1, info->src_y + 1);
|
2007-08-23 21:25:30 +08:00
|
|
|
src[2] = tile_data_pointer (tile[1],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x + 1, info->src_y - 1);
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-08-31 17:36:16 +08:00
|
|
|
if (((src_x - 1) / TILE_WIDTH) != tilexL)
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
if (tile[2])
|
|
|
|
tile_release (tile[2], FALSE);
|
2007-08-22 22:31:22 +08:00
|
|
|
|
|
|
|
tilexL += 1;
|
|
|
|
|
2007-08-23 21:25:30 +08:00
|
|
|
tile[2] = tile_manager_get_tile (info->src_tiles,
|
2007-08-31 17:36:16 +08:00
|
|
|
src_x - 1, info->src_y,
|
|
|
|
TRUE, FALSE);
|
2007-08-22 22:31:22 +08:00
|
|
|
|
2007-09-13 02:29:11 +08:00
|
|
|
if (! tile[2])
|
2007-08-22 22:31:22 +08:00
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[3] = src[4];
|
|
|
|
src[6] = src[7];
|
|
|
|
src[0] = src[1];
|
2007-08-22 22:31:22 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-08-23 21:25:30 +08:00
|
|
|
src[3] = tile_data_pointer (tile[2],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x - 1, info->src_y);
|
2007-08-23 21:25:30 +08:00
|
|
|
src[6] = tile_data_pointer (tile[2],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x - 1, info->src_y + 1);
|
2007-08-23 21:25:30 +08:00
|
|
|
src[0] = tile_data_pointer (tile[2],
|
2007-09-13 02:29:11 +08:00
|
|
|
src_x - 1, info->src_y - 1);
|
2007-08-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (--width);
|
|
|
|
|
|
|
|
done:
|
2007-09-23 06:28:51 +08:00
|
|
|
for (dx=0; dx<3; dx++)
|
|
|
|
if (tile[dx])
|
|
|
|
tile_release (tile[dx], FALSE);
|
2007-08-16 05:29:43 +08:00
|
|
|
|
|
|
|
return tile_buf;
|
|
|
|
}
|