]> git.imager.perl.org - imager.git/blobdiff - fills.c
sacrifice a chicken to the spell-checker gods
[imager.git] / fills.c
diff --git a/fills.c b/fills.c
index fb6e4106a93da8d3f71981b0e6e752f8b0de64eb..ea5864760feea726ed274982bc580c4cafc51093 100644 (file)
--- a/fills.c
+++ b/fills.c
@@ -1,3 +1,4 @@
+#define IMAGER_NO_CONTEXT
 #include "imager.h"
 #include "imageri.h"
 
@@ -163,10 +164,10 @@ typedef struct
   i_fcolor fc;
 } i_fill_solid_t;
 
-static void fill_solid(i_fill_t *, int x, int y, int width, int channels, 
-                       i_color *);
-static void fill_solidf(i_fill_t *, int x, int y, int width, int channels, 
-                        i_fcolor *);
+static void fill_solid(i_fill_t *, i_img_dim x, i_img_dim y, i_img_dim width,
+                      int channels, i_color *);
+static void fill_solidf(i_fill_t *, i_img_dim x, i_img_dim y, i_img_dim width,
+                       int channels, i_fcolor *);
 
 static i_fill_solid_t base_solid_fill =
 {
@@ -398,79 +399,83 @@ typedef struct
   i_color fg, bg;
   i_fcolor ffg, fbg;
   unsigned char hatch[8];
-  int dx, dy;
+  i_img_dim dx, dy;
 } i_fill_hatch_t;
 
-static void fill_hatch(i_fill_t *fill, int x, int y, int width, int channels, 
-                       i_color *data);
-static void fill_hatchf(i_fill_t *fill, int x, int y, int width, int channels, 
-                        i_fcolor *data);
+static void fill_hatch(i_fill_t *fill, i_img_dim x, i_img_dim y,
+                      i_img_dim width, int channels, i_color *data);
+static void fill_hatchf(i_fill_t *fill, i_img_dim x, i_img_dim y,
+                       i_img_dim width, int channels, i_fcolor *data);
 static
 i_fill_t *
 i_new_hatch_low(const i_color *fg, const i_color *bg, const i_fcolor *ffg, const i_fcolor *fbg, 
                 int combine, int hatch, const unsigned char *cust_hatch,
-                int dx, int dy);
+                i_img_dim dx, i_img_dim dy);
 
 /*
-=item i_new_fill_hatch(fg, bg, combine, hatch, cust_hatch, dx, dy)
+=item i_new_fill_hatch(C<fg>, C<bg>, C<combine>, C<hatch>, C<cust_hatch>, C<dx>, C<dy>)
 
 =category Fills
 =synopsis i_fill_t *fill = i_new_fill_hatch(&fg_color, &bg_color, combine, hatch, custom_hatch, dx, dy);
 
-Creates a new hatched fill with the fg color used for the 1 bits in
-the hatch and bg for the 0 bits.  If combine is non-zero alpha values
-will be combined.
+Creates a new hatched fill with the C<fg> color used for the 1 bits in
+the hatch and C<bg> for the 0 bits.  If C<combine> is non-zero alpha
+values will be combined.
 
-If cust_hatch is non-NULL it should be a pointer to 8 bytes of the
+If C<cust_hatch> is non-NULL it should be a pointer to 8 bytes of the
 hash definition, with the high-bits to the left.
 
-If cust_hatch is NULL then one of the standard hatches is used.
+If C<cust_hatch> is NULL then one of the standard hatches is used.
 
-(dx, dy) are an offset into the hatch which can be used to unalign adjoining areas, or to align the origin of a hatch with the the side of a filled area.
+(C<dx>, C<dy>) are an offset into the hatch which can be used to hatch
+adjoining areas out of alignment, or to align the origin of a hatch
+with the side of a filled area.
 
 =cut
 */
 i_fill_t *
 i_new_fill_hatch(const i_color *fg, const i_color *bg, int combine, int hatch, 
-            const unsigned char *cust_hatch, int dx, int dy) {
+            const unsigned char *cust_hatch, i_img_dim dx, i_img_dim dy) {
   return i_new_hatch_low(fg, bg, NULL, NULL, combine, hatch, cust_hatch, 
                          dx, dy);
 }
 
 /*
-=item i_new_fill_hatchf(fg, bg, combine, hatch, cust_hatch, dx, dy)
+=item i_new_fill_hatchf(C<fg>, C<bg>, C<combine>, C<hatch>, C<cust_hatch>, C<dx>, C<dy>)
 
 =category Fills
 =synopsis i_fill_t *fill = i_new_fill_hatchf(&fg_fcolor, &bg_fcolor, combine, hatch, custom_hatch, dx, dy);
 
-Creates a new hatched fill with the fg color used for the 1 bits in
-the hatch and bg for the 0 bits.  If combine is non-zero alpha values
-will be combined.
+Creates a new hatched fill with the C<fg> color used for the 1 bits in
+the hatch and C<bg> for the 0 bits.  If C<combine> is non-zero alpha
+values will be combined.
 
-If cust_hatch is non-NULL it should be a pointer to 8 bytes of the
+If C<cust_hatch> is non-NULL it should be a pointer to 8 bytes of the
 hash definition, with the high-bits to the left.
 
-If cust_hatch is NULL then one of the standard hatches is used.
+If C<cust_hatch> is NULL then one of the standard hatches is used.
 
-(dx, dy) are an offset into the hatch which can be used to unalign adjoining areas, or to align the origin of a hatch with the the side of a filled area.
+(C<dx>, C<dy>) are an offset into the hatch which can be used to hatch
+adjoining areas out of alignment, or to align the origin of a hatch
+with the side of a filled area.
 
 =cut
 */
 i_fill_t *
 i_new_fill_hatchf(const i_fcolor *fg, const i_fcolor *bg, int combine, int hatch, 
-                 const unsigned char *cust_hatch, int dx, int dy) {
+                 const unsigned char *cust_hatch, i_img_dim dx, i_img_dim dy) {
   return i_new_hatch_low(NULL, NULL, fg, bg, combine, hatch, cust_hatch, 
                          dx, dy);
 }
 
-static void fill_image(i_fill_t *fill, int x, int y, int width, int channels,
-                       i_color *data);
-static void fill_imagef(i_fill_t *fill, int x, int y, int width, int channels,
-                       i_fcolor *data);
+static void fill_image(i_fill_t *fill, i_img_dim x, i_img_dim y,
+                      i_img_dim width, int channels, i_color *data);
+static void fill_imagef(i_fill_t *fill, i_img_dim x, i_img_dim y,
+                       i_img_dim width, int channels, i_fcolor *data);
 struct i_fill_image_t {
   i_fill_t base;
   i_img *src;
-  int xoff, yoff;
+  i_img_dim xoff, yoff;
   int has_matrix;
   double matrix[9];
 };
@@ -486,7 +491,7 @@ image_fill_proto =
   };
 
 /*
-=item i_new_fill_image(im, matrix, xoff, yoff, combine)
+=item i_new_fill_image(C<im>, C<matrix>, C<xoff>, C<yoff>, C<combine>)
 
 =category Fills
 =synopsis i_fill_t *fill = i_new_fill_image(src_img, matrix, x_offset, y_offset, combine);
@@ -495,12 +500,12 @@ Create an image based fill.
 
 matrix is an array of 9 doubles representing a transformation matrix.
 
-xoff and yoff are the offset into the image to start filling from.
+C<xoff> and C<yoff> are the offset into the image to start filling from.
 
 =cut
 */
 i_fill_t *
-i_new_fill_image(i_img *im, const double *matrix, int xoff, int yoff, int combine) {
+i_new_fill_image(i_img *im, const double *matrix, i_img_dim xoff, i_img_dim yoff, int combine) {
   struct i_fill_image_t *fill = mymalloc(sizeof(*fill)); /* checked 14jul05 tonyc */
 
   *fill = image_fill_proto;
@@ -529,10 +534,10 @@ i_new_fill_image(i_img *im, const double *matrix, int xoff, int yoff, int combin
   return &fill->base;
 }
 
-static void fill_opacity(i_fill_t *fill, int x, int y, int width, int channels,
-                       i_color *data);
-static void fill_opacityf(i_fill_t *fill, int x, int y, int width, int channels,
-                       i_fcolor *data);
+static void fill_opacity(i_fill_t *fill, i_img_dim x, i_img_dim y,
+                        i_img_dim width, int channels, i_color *data);
+static void fill_opacityf(i_fill_t *fill, i_img_dim x, i_img_dim y,
+                         i_img_dim width, int channels, i_fcolor *data);
 
 struct i_fill_opacity_t {
   i_fill_t base;
@@ -543,9 +548,11 @@ struct i_fill_opacity_t {
 static struct i_fill_opacity_t
 opacity_fill_proto =
   {
-    fill_opacity,
-    fill_opacityf,
-    NULL
+    {
+      fill_opacity,
+      fill_opacityf,
+      NULL
+    }
   };
 
 i_fill_t *
@@ -559,6 +566,11 @@ i_new_fill_opacity(i_fill_t *base_fill, double alpha_mult) {
   fill->other_fill = base_fill;
   fill->alpha_mult = alpha_mult;
 
+  if (!base_fill->f_fill_with_color) {
+    /* base fill only does floating, so we only do that too */
+    fill->base.f_fill_with_color = NULL;
+  }
+
   return &fill->base;
 }
 
@@ -578,8 +590,8 @@ The 8-bit sample fill function for non-combining solid fills.
 =cut
 */
 static void
-fill_solid(i_fill_t *fill, int x, int y, int width, int channels, 
-           i_color *data) {
+fill_solid(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width,
+          int channels, i_color *data) {
   i_color c = T_SOLID_FILL(fill)->c;
   i_adapt_colors(channels > 2 ? 4 : 2, 4, &c, 1);
   while (width-- > 0) {
@@ -595,8 +607,8 @@ The floating sample fill function for non-combining solid fills.
 =cut
 */
 static void
-fill_solidf(i_fill_t *fill, int x, int y, int width, int channels, 
-           i_fcolor *data) {
+fill_solidf(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width,
+           int channels, i_fcolor *data) {
   i_fcolor c = T_SOLID_FILL(fill)->fc;
   i_adapt_fcolors(channels > 2 ? 4 : 2, 4, &c, 1);
   while (width-- > 0) {
@@ -626,7 +638,7 @@ i_fill_t *
 i_new_hatch_low(const i_color *fg, const i_color *bg, 
                const i_fcolor *ffg, const i_fcolor *fbg, 
                 int combine, int hatch, const unsigned char *cust_hatch,
-                int dx, int dy) {
+                i_img_dim dx, i_img_dim dy) {
   i_fill_hatch_t *fill = mymalloc(sizeof(i_fill_hatch_t)); /* checked 14jul05 tonyc */
 
   *fill = hatch_fill_proto;
@@ -677,15 +689,15 @@ The 8-bit sample fill function for hatched fills.
 
 =cut
 */
-static void fill_hatch(i_fill_t *fill, int x, int y, int width, int channels, 
-                       i_color *data) {
+static void 
+fill_hatch(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width,
+          int channels, i_color *data) {
   i_fill_hatch_t *f = (i_fill_hatch_t *)fill;
   int byte = f->hatch[(y + f->dy) & 7];
   int xpos = (x + f->dx) & 7;
   int mask = 128 >> xpos;
   i_color fg = f->fg;
   i_color bg = f->bg;
-  int want_channels = channels > 2 ? 4 : 2;
 
   if (channels < 3) {
     i_adapt_colors(2, 4, &fg, 1);
@@ -708,10 +720,11 @@ static void fill_hatch(i_fill_t *fill, int x, int y, int width, int channels,
 
 The floating sample fill function for hatched fills.
 
-=back
+=cut
 */
-static void fill_hatchf(i_fill_t *fill, int x, int y, int width, int channels, 
-                        i_fcolor *data) {
+static void
+fill_hatchf(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width,
+           int channels, i_fcolor *data) {
   i_fill_hatch_t *f = (i_fill_hatch_t *)fill;
   int byte = f->hatch[(y + f->dy) & 7];
   int xpos = (x + f->dx) & 7;
@@ -784,10 +797,11 @@ static i_fcolor interp_i_fcolor(i_fcolor before, i_fcolor after, double pos,
 
 =cut
 */
-static void fill_image(i_fill_t *fill, int x, int y, int width, int channels,
-                       i_color *data) {
+static void
+fill_image(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width,
+          int channels, i_color *data) {
   struct i_fill_image_t *f = (struct i_fill_image_t *)fill;
-  int i = 0;
+  i_img_dim i = 0;
   i_color *out = data;
   int want_channels = channels > 2 ? 4 : 2;
   
@@ -800,7 +814,7 @@ static void fill_image(i_fill_t *fill, int x, int y, int width, int channels,
       double iy = floor(ry / f->src->ysize);
       i_color c[2][2];
       i_color c2[2];
-      int dy;
+      i_img_dim dy;
 
       if (f->xoff) {
         rx += iy * f->xoff;
@@ -814,12 +828,12 @@ static void fill_image(i_fill_t *fill, int x, int y, int width, int channels,
       ry -= iy * f->src->ysize;
 
       for (dy = 0; dy < 2; ++dy) {
-        if ((int)rx == f->src->xsize-1) {
-          i_gpix(f->src, f->src->xsize-1, ((int)ry+dy) % f->src->ysize, &c[dy][0]);
-          i_gpix(f->src, 0, ((int)ry+dy) % f->src->xsize, &c[dy][1]);
+        if ((i_img_dim)rx == f->src->xsize-1) {
+          i_gpix(f->src, f->src->xsize-1, ((i_img_dim)ry+dy) % f->src->ysize, &c[dy][0]);
+          i_gpix(f->src, 0, ((i_img_dim)ry+dy) % f->src->xsize, &c[dy][1]);
         }
         else {
-          i_glin(f->src, (int)rx, (int)rx+2, ((int)ry+dy) % f->src->ysize, 
+          i_glin(f->src, (i_img_dim)rx, (i_img_dim)rx+2, ((i_img_dim)ry+dy) % f->src->ysize, 
                  c[dy]);
         }
         c2[dy] = interp_i_color(c[dy][0], c[dy][1], rx, f->src->channels);
@@ -832,10 +846,10 @@ static void fill_image(i_fill_t *fill, int x, int y, int width, int channels,
     /* the easy way */
     /* this should be possible to optimize to use i_glin() */
     while (i < width) {
-      int rx = x+i;
-      int ry = y;
-      int ix = rx / f->src->xsize;
-      int iy = ry / f->src->ysize;
+      i_img_dim rx = x+i;
+      i_img_dim ry = y;
+      i_img_dim ix = rx / f->src->xsize;
+      i_img_dim iy = ry / f->src->ysize;
 
       if (f->xoff) {
         rx += iy * f->xoff;
@@ -843,7 +857,7 @@ static void fill_image(i_fill_t *fill, int x, int y, int width, int channels,
       }
       else if (f->yoff) {
         ry += ix * f->yoff;
-        iy = ry / f->src->xsize;
+        iy = ry / f->src->ysize;
       }
       rx -= ix * f->src->xsize;
       ry -= iy * f->src->ysize;
@@ -861,10 +875,11 @@ static void fill_image(i_fill_t *fill, int x, int y, int width, int channels,
 
 =cut
 */
-static void fill_imagef(i_fill_t *fill, int x, int y, int width, int channels,
-                       i_fcolor *data) {
+static void
+fill_imagef(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width,
+           int channels, i_fcolor *data) {
   struct i_fill_image_t *f = (struct i_fill_image_t *)fill;
-  int i = 0;
+  i_img_dim i = 0;
   int want_channels = channels > 2 ? 4 : 2;
   
   if (f->has_matrix) {
@@ -877,7 +892,7 @@ static void fill_imagef(i_fill_t *fill, int x, int y, int width, int channels,
       double iy = floor(ry / f->src->ysize);
       i_fcolor c[2][2];
       i_fcolor c2[2];
-      int dy;
+      i_img_dim dy;
 
       if (f->xoff) {
         rx += iy * f->xoff;
@@ -891,12 +906,12 @@ static void fill_imagef(i_fill_t *fill, int x, int y, int width, int channels,
       ry -= iy * f->src->ysize;
 
       for (dy = 0; dy < 2; ++dy) {
-        if ((int)rx == f->src->xsize-1) {
-          i_gpixf(f->src, f->src->xsize-1, ((int)ry+dy) % f->src->ysize, &c[dy][0]);
-          i_gpixf(f->src, 0, ((int)ry+dy) % f->src->xsize, &c[dy][1]);
+        if ((i_img_dim)rx == f->src->xsize-1) {
+          i_gpixf(f->src, f->src->xsize-1, ((i_img_dim)ry+dy) % f->src->ysize, &c[dy][0]);
+          i_gpixf(f->src, 0, ((i_img_dim)ry+dy) % f->src->xsize, &c[dy][1]);
         }
         else {
-          i_glinf(f->src, (int)rx, (int)rx+2, ((int)ry+dy) % f->src->ysize, 
+          i_glinf(f->src, (i_img_dim)rx, (i_img_dim)rx+2, ((i_img_dim)ry+dy) % f->src->ysize, 
                  c[dy]);
         }
         c2[dy] = interp_i_fcolor(c[dy][0], c[dy][1], rx, f->src->channels);
@@ -910,10 +925,10 @@ static void fill_imagef(i_fill_t *fill, int x, int y, int width, int channels,
     /* the easy way */
     /* this should be possible to optimize to use i_glin() */
     while (i < width) {
-      int rx = x+i;
-      int ry = y;
-      int ix = rx / f->src->xsize;
-      int iy = ry / f->src->ysize;
+      i_img_dim rx = x+i;
+      i_img_dim ry = y;
+      i_img_dim ix = rx / f->src->xsize;
+      i_img_dim iy = ry / f->src->ysize;
 
       if (f->xoff) {
         rx += iy * f->xoff;
@@ -935,8 +950,8 @@ static void fill_imagef(i_fill_t *fill, int x, int y, int width, int channels,
 }
 
 static void 
-fill_opacity(i_fill_t *fill, int x, int y, int width, int channels,
-            i_color *data) {
+fill_opacity(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width,
+            int channels, i_color *data) {
   struct i_fill_opacity_t *f = (struct i_fill_opacity_t *)fill;
   int alpha_chan = channels > 2 ? 3 : 1;
   i_color *datap = data;
@@ -954,8 +969,8 @@ fill_opacity(i_fill_t *fill, int x, int y, int width, int channels,
   }
 }
 static void 
-fill_opacityf(i_fill_t *fill, int x, int y, int width, int channels,
-           i_fcolor *data) {
+fill_opacityf(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width,
+             int channels, i_fcolor *data) {
   struct i_fill_opacity_t *f = (struct i_fill_opacity_t *)fill;
   int alpha_chan = channels > 2 ? 3 : 1;
   i_fcolor *datap = data;