[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

scaling a GdkImage



Hi,

I thought I should bring this to the attention of the gtk+ team, invite 
comments, and take the opportunity to put a question or two.

I'm just finishing porting a Win32 program to linux using gtk+ 1.2.  I'm 
proposing to release with the program a mini shared library which lumps 
together slight extensions to gdk and also gnome-print, just for use by the 
program.

The gdk stuff comprises a quick hack of code by Owen Taylor from the 
gdk-pixbuf library, providing a basic facility to scale a GdkImage.  I 
don't know anything about scaling, but it seems to work adequately for my 
purposes.

The program displays charts drawn directly to the screen using gdk drawing 
functions.  Under Win32, scaled-down versions of the charts are provided 
using the Window/Viewport scaling facility.  They can be larger than the 
screen, so need to be scrollable.  Under Linux, the chart is drawn to a 
pixmap, the pixels extracted to a GdkImage, this is scaled directly, and 
then drawn to the screen.

A couple of questions for the gtk+ team:

1  Why was this facility never provided in gdk 1.2 ?
2  Would it still be worth providing it in gdk 2 ?

I attach the code for anyone interested.

David J. Cooke
/***************************************************************************
                          libwt-gdkimage-x.c  -  description
                             -------------------
    begin                : Wed Apr 10 2002
    author               : David J. Cooke
    email                : d.j.cooke@lineone.net
    copyright            : (C) 2002, David J. Cooke

    Function pixops_image_scale_nearest is adapted from code by
    Owen Taylor <otaylor@redhat.com> which is copyright (C) Red Hat, Inc,
    2000.

    Function gdk_image_scale_nearest is adapted from code by
    Owen Taylor <otaylor@redhat.com> which is copyright (C) 1999,
    The Free Software Foundation.

 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 ***************************************************************************/

#include <math.h>
#include "libwtgext.h"

#define SCALE_SHIFT 16

void
pixops_image_scale_nearest (GdkImage *destIm,
		int            render_x0,
		int            render_y0,
		int            render_x1,
		int            render_y1,
		const GdkImage *srcIm,
		int            src_width,
		int            src_height,
		double         scale_x,
		double         scale_y)
{
  int i, j;
  int x0, x, y;
  int x_step = (1 << SCALE_SHIFT) / scale_x;
  int y_step = (1 << SCALE_SHIFT) / scale_y;

  for (i = 0; i < (render_y1 - render_y0); i++)
    {
      y = ((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT;
      x0 = render_x0 * x_step + x_step / 2;
      x = x0 >> SCALE_SHIFT;

      for (j=0; j < (render_x1 - render_x0); j++)
	    {
		 gdk_image_put_pixel(destIm, (gint) j, (gint) i,
	             gdk_image_get_pixel(srcIm, (gint) x, (gint) y) );

		 x0 += x_step;
		 x = x0 >> SCALE_SHIFT;
	     }
    }
}

void
gdk_image_scale_nearest(const GdkImage *srcIm,
		GdkImage *destIm,
		int              dest_x,
		int              dest_y,         /* seems to work OK for */
		int              dest_width,     /* 8bit and 16bit colour */
		int              dest_height,
		double           offset_x,
		double           offset_y)
{
  g_return_if_fail (srcIm != NULL);
  g_return_if_fail (destIm != NULL);
  g_return_if_fail (dest_x >= 0 && dest_x + dest_width <= destIm->width);
  g_return_if_fail (dest_y >= 0 && dest_y + dest_height <= destIm->height);

  offset_x = floor (offset_x + 0.5);
  offset_y = floor (offset_y + 0.5);

  pixops_image_scale_nearest (destIm,
		dest_x - offset_x, dest_y - offset_y,
		dest_x + dest_width - offset_x, dest_y + dest_height - offset_y,
		srcIm, srcIm->width, srcIm->height,
		    ((double) dest_width) / ((double) srcIm->width),
		    ((double) dest_height) / ((double) srcIm->height) );
}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]