moreupdates
[synfig.git] / synfig-core / trunk / src / modules / mod_filter / halftone.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file halftone.cpp
3 **      \brief blehh
4 **
5 **      $Id: halftone.cpp,v 1.1.1.1 2005/01/04 01:23:10 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === H E A D E R S ======================================================= */
23
24 #ifdef USING_PCH
25 #       include "pch.h"
26 #else
27 #ifdef HAVE_CONFIG_H
28 #       include <config.h>
29 #endif
30
31 #include "halftone.h"
32
33 #endif
34
35 /* === M A C R O S ========================================================= */
36
37 using namespace synfig;
38 using namespace std;
39 using namespace etl;
40
41 /* === G L O B A L S ======================================================= */
42
43
44 /* === P R O C E D U R E S ================================================= */
45
46 #define SQRT2   (1.414213562f)
47
48 /* === M E T H O D S ======================================================= */
49
50 float
51 Halftone::operator()(const Point &point, const float& luma, float supersample)const
52 {
53         float halftone(mask(point));
54         
55         if(supersample>=0.5f)
56                 supersample=0.4999999999f;
57         
58         halftone=(halftone-0.5f)*(1.0f-supersample*2.0f)+0.5f;
59         
60         const float diff(halftone-luma);
61         
62         if(supersample)
63         {
64                 const float amount(diff/(supersample*2.0f)+0.5f);
65
66                 if(amount<=0.0f+0.01f)
67                         return 1.0f;
68                 else if(amount>=1.0f-0.01f)
69                         return 0.0f;
70                 else
71                         return 1.0f-amount;
72         }
73         else
74         {
75                 if(diff>=0)
76                         return 0.0f;
77                 else
78                         return 1.0f;
79         }
80
81         return 0.0f;
82 }
83
84 float
85 Halftone::mask(synfig::Point point)const
86 {
87         float radius1;
88         float radius2;
89         
90         point-=offset;
91
92         {
93                 const float     a(Angle::sin(-angle).get()),    b(Angle::cos(-angle).get());
94                 const float     u(point[0]),v(point[1]);
95         
96                 point[0]=b*u-a*v;
97                 point[1]=a*u+b*v;
98         }
99
100         if(type==TYPE_STRIPE)
101         {
102                 Point pnt(fmod(point[0],size[0]),fmod(point[1],size[1]));
103                 while(pnt[0]<0)pnt[0]+=abs(size[0]);
104                 while(pnt[1]<0)pnt[1]+=abs(size[1]);
105
106                 float x(pnt[1]/size[1]);
107                 if(x>0.5)x=1.0-x;
108                 x*=2;
109                 return x;
110         }
111         
112         {
113                 Point pnt(fmod(point[0],size[0]),fmod(point[1],size[1]));
114                 while(pnt[0]<0)pnt[0]+=abs(size[0]);
115                 while(pnt[1]<0)pnt[1]+=abs(size[1]);
116                 pnt-=Vector(size[0]*0.5,size[1]*0.5);
117                 pnt*=2.0;
118                 pnt[0]/=size[0];
119                 pnt[1]/=size[1];
120                 
121                 radius1=pnt.mag()/SQRT2;
122                 radius1*=radius1;
123         }
124         if(type==TYPE_DARKONLIGHT || type== TYPE_LIGHTONDARK)
125                 return radius1;
126         
127         {
128                 Point pnt(fmod(point[0]+size[0]*0.5,size[0]),fmod(point[1]+size[0]*0.5,size[1]));
129                 while(pnt[0]<0)pnt[0]+=abs(size[0]);
130                 while(pnt[1]<0)pnt[1]+=abs(size[1]);
131                 pnt-=Vector(size[0]*0.5,size[1]*0.5);
132                 pnt*=2.0;
133                 pnt[0]/=size[0];
134                 pnt[1]/=size[1];
135                 
136                 radius2=pnt.mag()/SQRT2;
137                 radius2*=radius2;
138         }
139         
140         if(type==TYPE_DIAMOND)
141         {
142                 //return (radius1+(1.0f-radius2))*0.5;
143                 float x((radius1+(1.0f-radius2))*0.5);
144                 //float x(((radius2-radius1)*((radius1+(1.0f-radius2))*0.5)+radius1)*2.0f);
145                 x-=0.5;
146                 x*=2.0;
147                 if(x<0)x=-sqrt(-x);else x=sqrt(x);
148                 x*=1.01f;       
149                 x/=2.0;
150                 x+=0.5;
151                 return x;
152         }
153         
154         if(type==TYPE_SYMMETRIC)
155         {
156                 float x(((radius2-radius1)*((radius1+(1.0f-radius2))*0.5)+radius1)*2.0f);
157                 x-=0.5;
158                 x*=2.0;
159                 if(x<0)x=-sqrt(-x);else x=sqrt(x);
160                 x*=1.01f;       
161                 x/=2.0;
162                 x+=0.5;
163                 return x;
164         }
165         return 0;
166 }