Back to index

scribus-ng  1.3.4.dfsg+svn20071115
art_render_pattern.c
Go to the documentation of this file.
00001 /*
00002  * art_render_pattern.c: 
00003  *
00004  * Libart_LGPL - library of basic graphic primitives
00005  * Copyright (C) 2000 Raph Levien
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Library General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Library General Public
00018  * License along with this library; if not, write to the
00019  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020  * Boston, MA 02111-1307, USA.
00021  *
00022  */
00023 
00024 #include "scconfig.h"
00025  
00026 #include "art_render_pattern.h"
00027 
00028 #include <math.h>
00029 
00030 typedef struct _ArtImageSourcePattern ArtImageSourcePattern;
00031 
00032 struct _ArtImageSourcePattern {
00033   ArtImageSource super;
00034   const ArtPattern *pattern;
00035 };
00036 
00037 static void
00038 art_render_pattern_done (ArtRenderCallback *self, ArtRender *render)
00039 {
00040   art_free (self);
00041 }
00042 
00043 static void
00044 art_render_pattern_render (ArtRenderCallback *self, ArtRender *render,
00045                                art_u8 *dest, int y)
00046 {
00047   ArtImageSourcePattern *z = (ArtImageSourcePattern *)self;
00048   const ArtPattern *pattern = z->pattern;
00049   int pixstride = (render->n_chan + 1) * (render->depth >> 3);
00050   int n_ch = render->n_chan + 1;
00051   int x, j, index;
00052   int width = render->x1 - render->x0;
00053   int twidth = pattern->twidth;
00054   int theight = pattern->theight;
00055   art_u8 *bufp = render->image_buf;
00056 
00057   double angle = pattern->angle;
00058   double opacity = pattern->opacity;
00059   double cosangle = cos(angle);
00060   double sinangle = sin(angle);
00061 
00062   y = y - render->y0;
00063 
00064   for (x = 0; x < width; x++)
00065   {
00066          int x0 = sinangle * y + cosangle * x;
00067          int y0 = -sinangle * x + cosangle * y;
00068          x0 = (x0 % twidth);
00069          if(x0 < 0) x0 += twidth;
00070          y0 = (y0 % theight);
00071          if(y0 < 0) y0 += theight;
00072          index = (((y0 * twidth + x0) * pixstride) % (twidth * theight * 4));
00073          /*for (j = 0; j < n_ch - 1; j++)
00074               {*/
00075              /* bgra -> rgba */
00076           bufp[0] = pattern->buffer[index + 2];
00077           bufp[1] = pattern->buffer[index + 1];
00078           bufp[2] = pattern->buffer[index + 0];
00079           bufp[3] = opacity;
00080               /*}*/
00081       bufp += pixstride;
00082   }
00083 }
00084 
00085 static void
00086 art_render_pattern_negotiate (ArtImageSource *self, ArtRender *render,
00087                                   ArtImageSourceFlags *p_flags,
00088                                   int *p_buf_depth, ArtAlphaType *p_alpha)
00089 {
00090   self->super.render = art_render_pattern_render;
00091   *p_flags = 0;
00092   *p_buf_depth = render->depth;
00093   *p_alpha = ART_ALPHA_SEPARATE;
00094 }
00095 
00096 void
00097 art_render_pattern (ArtRender *render,
00098                          const ArtPattern *pattern,
00099                          ArtFilterLevel level)
00100 {
00101   ArtImageSourcePattern *image_source = art_new (ArtImageSourcePattern, 1);
00102 
00103   image_source->super.super.render = NULL;
00104   image_source->super.super.done = art_render_pattern_done;
00105   image_source->super.negotiate = art_render_pattern_negotiate;
00106 
00107   image_source->pattern = pattern;
00108 
00109   art_render_add_image_source (render, &image_source->super);
00110 }