Back to index

scribus-ng  1.3.4.dfsg+svn20071115
art_rgb_affine_private.c
Go to the documentation of this file.
00001 /* Libart_LGPL - library of basic graphic primitives
00002  * Copyright (C) 1998 Raph Levien
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  */
00019 
00020 #include "scconfig.h"
00021 
00022 #include "art_rgb_affine_private.h"
00023 
00024 #include <math.h>
00025 #include <libart_lgpl/art_misc.h>
00026 #include <libart_lgpl/art_point.h>
00027 #include <libart_lgpl/art_affine.h>
00028 
00029 /* Private functions for the rgb affine image compositors - primarily,
00030    the determination of runs, eliminating the need for source image
00031    bbox calculation in the inner loop. */
00032 
00033 /* Determine a "run", such that the inverse affine of all pixels from
00034    (x0, y) inclusive to (x1, y) exclusive fit within the bounds
00035    of the source image.
00036 
00037    Initial values of x0, x1, and result values stored in first two
00038    pointer arguments.
00039 */
00040 
00041 #define EPSILON 1e-6
00042 
00043 void
00044 art_rgb_affine_run (int *p_x0, int *p_x1, int y,
00045                   int src_width, int src_height,
00046                   const double affine[6])
00047 {
00048   int x0, x1;
00049   double z;
00050   double x_intercept;
00051   int xi;
00052 
00053   x0 = *p_x0;
00054   x1 = *p_x1;
00055 
00056   /* do left and right edges */
00057   if (affine[0] > EPSILON)
00058     {
00059       z = affine[2] * (y + 0.5) + affine[4];
00060       x_intercept = -z / affine[0];
00061       xi = ceil (x_intercept + EPSILON - 0.5);
00062       if (xi > x0)
00063        x0 = xi;
00064       x_intercept = (-z + src_width) / affine[0];
00065       xi = ceil (x_intercept - EPSILON - 0.5);
00066       if (xi < x1)
00067        x1 = xi;
00068     }
00069   else if (affine[0] < -EPSILON)
00070     {
00071       z = affine[2] * (y + 0.5) + affine[4];
00072       x_intercept = (-z + src_width) / affine[0];
00073       xi = ceil (x_intercept + EPSILON - 0.5);
00074       if (xi > x0)
00075        x0 = xi;
00076       x_intercept = -z / affine[0];
00077       xi = ceil (x_intercept - EPSILON - 0.5);
00078       if (xi < x1)
00079        x1 = xi;
00080     }
00081   else
00082     {
00083       z = affine[2] * (y + 0.5) + affine[4];
00084       if (z < 0 || z >= src_width)
00085        {
00086          *p_x1 = *p_x0;
00087          return;
00088        }
00089     }
00090 
00091   /* do top and bottom edges */
00092   if (affine[1] > EPSILON)
00093     {
00094       z = affine[3] * (y + 0.5) + affine[5];
00095       x_intercept = -z / affine[1];
00096       xi = ceil (x_intercept + EPSILON - 0.5);
00097       if (xi > x0)
00098        x0 = xi;
00099       x_intercept = (-z + src_height) / affine[1];
00100       xi = ceil (x_intercept - EPSILON - 0.5);
00101       if (xi < x1)
00102        x1 = xi;
00103     }
00104   else if (affine[1] < -EPSILON)
00105     {
00106       z = affine[3] * (y + 0.5) + affine[5];
00107       x_intercept = (-z + src_height) / affine[1];
00108       xi = ceil (x_intercept + EPSILON - 0.5);
00109       if (xi > x0)
00110        x0 = xi;
00111       x_intercept = -z / affine[1];
00112       xi = ceil (x_intercept - EPSILON - 0.5);
00113       if (xi < x1)
00114        x1 = xi;
00115     }
00116   else
00117     {
00118       z = affine[3] * (y + 0.5) + affine[5];
00119       if (z < 0 || z >= src_height)
00120        {
00121          *p_x1 = *p_x0;
00122          return;
00123        }
00124     }
00125 
00126   *p_x0 = x0;
00127   *p_x1 = x1;
00128 }