KiCad PCB EDA Suite
render.cpp File Reference
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "render.h"
#include "greymap.h"
#include "auxiliary.h"

Go to the source code of this file.

Functions

render_trender_new (greymap_t *gm)
 
void render_free (render_t *rm)
 
void render_close (render_t *rm)
 
void render_moveto (render_t *rm, double x, double y)
 
static void incrow (render_t *rm, int x, int y, int b)
 
void render_lineto (render_t *rm, double x2, double y2)
 
void render_curveto (render_t *rm, double x2, double y2, double x3, double y3, double x4, double y4)
 

Function Documentation

static void incrow ( render_t rm,
int  x,
int  y,
int  b 
)
static

Definition at line 118 of file render.cpp.

References render_s::gm, GM_INC, greymap_s::h, render_s::incrow_buf, and greymap_s::w.

Referenced by render_lineto().

119 {
120  int i, x0;
121 
122  if( y < 0 || y >= rm->gm->h )
123  {
124  return;
125  }
126 
127  if( x < 0 )
128  {
129  x = 0;
130  }
131  else if( x > rm->gm->w )
132  {
133  x = rm->gm->w;
134  }
135 
136  if( rm->incrow_buf[y] == 0 )
137  {
138  rm->incrow_buf[y] = x + 1; /* store x+1 so that we can use 0 for "vacant" */
139  return;
140  }
141 
142  x0 = rm->incrow_buf[y] - 1;
143  rm->incrow_buf[y] = 0;
144 
145  if( x0 < x )
146  {
147  for( i = x0; i<x; i++ )
148  {
149  GM_INC( rm->gm, i, y, -b );
150  }
151  }
152  else
153  {
154  for( i = x; i<x0; i++ )
155  {
156  GM_INC( rm->gm, i, y, b );
157  }
158  }
159 }
int h
Definition: greymap.h:20
#define GM_INC(gm, x, y, b)
Definition: greymap.h:38
int * incrow_buf
Definition: render.h:17
int w
Definition: greymap.h:19
greymap_t * gm
Definition: render.h:13
void render_close ( render_t rm)

Definition at line 85 of file render.cpp.

References render_s::a0, render_s::a1, render_s::gm, GM_INC, render_lineto(), render_s::x0, render_s::x0i, render_s::x1, render_s::y0, render_s::y0i, and render_s::y1.

Referenced by render_moveto().

86 {
87  if( rm->x0 != rm->x1 || rm->y0 != rm->y1 )
88  {
89  render_lineto( rm, rm->x0, rm->y0 );
90  }
91 
92  GM_INC( rm->gm, rm->x0i, rm->y0i, (rm->a0 + rm->a1) * 255 );
93 
94  /* assert (rm->x0i != rm->x1i || rm->y0i != rm->y1i); */
95 
96  /* the persistent state is now undefined */
97 }
#define GM_INC(gm, x, y, b)
Definition: greymap.h:38
int x0i
Definition: render.h:15
double a0
Definition: render.h:16
void render_lineto(render_t *rm, double x2, double y2)
Definition: render.cpp:163
int y0i
Definition: render.h:15
greymap_t * gm
Definition: render.h:13
double x0
Definition: render.h:14
double x1
Definition: render.h:14
double y1
Definition: render.h:14
double y0
Definition: render.h:14
double a1
Definition: render.h:16
void render_curveto ( render_t rm,
double  x2,
double  y2,
double  x3,
double  y3,
double  x4,
double  y4 
)

Definition at line 270 of file render.cpp.

References cu, delta, max, render_lineto(), sq, render_s::x1, and render_s::y1.

272 {
273  double x1, y1, dd0, dd1, dd, delta, e2, epsilon, t;
274 
275  x1 = rm->x1; /* starting point */
276  y1 = rm->y1;
277 
278  /* we approximate the curve by small line segments. The interval
279  * size, epsilon, is determined on the fly so that the distance
280  * between the true curve and its approximation does not exceed the
281  * desired accuracy delta. */
282 
283  delta = .1; /* desired accuracy, in pixels */
284 
285  /* let dd = maximal value of 2nd derivative over curve - this must
286  * occur at an endpoint. */
287  dd0 = sq( x1 - 2 * x2 + x3 ) + sq( y1 - 2 * y2 + y3 );
288  dd1 = sq( x2 - 2 * x3 + x4 ) + sq( y2 - 2 * y3 + y4 );
289  dd = 6 * sqrt( max( dd0, dd1 ) );
290  e2 = 8 * delta <= dd ? 8 * delta / dd : 1;
291  epsilon = sqrt( e2 ); /* necessary interval size */
292 
293  for( t = epsilon; t<1; t += epsilon )
294  {
295  render_lineto( rm, x1 * cu( 1 - t ) + 3 * x2 * sq( 1 - t ) * t + 3 * x3 * (1 - t) * sq(
296  t ) + x4 * cu( t ),
297  y1 * cu( 1 - t ) + 3 * y2 * sq( 1 - t ) * t + 3 * y3 * (1 - t) * sq( t ) + y4 *
298  cu( t ) );
299  }
300 
301  render_lineto( rm, x4, y4 );
302 }
#define sq(a)
Definition: auxiliary.h:87
void render_lineto(render_t *rm, double x2, double y2)
Definition: render.cpp:163
#define cu(a)
Definition: auxiliary.h:88
static const int delta[8][2]
Definition: solve.cpp:112
double x1
Definition: render.h:14
double y1
Definition: render.h:14
#define max(a, b)
Definition: auxiliary.h:86
void render_free ( render_t rm)

Definition at line 77 of file render.cpp.

References render_s::incrow_buf.

78 {
79  free( rm->incrow_buf );
80  free( rm );
81 }
int * incrow_buf
Definition: render.h:17
void render_lineto ( render_t rm,
double  x2,
double  y2 
)

Definition at line 163 of file render.cpp.

References render_s::a1, abs, render_s::gm, GM_INC, incrow(), render_s::x1, render_s::x1i, render_s::y1, and render_s::y1i.

Referenced by render_close(), and render_curveto().

164 {
165  int x2i, y2i;
166  double t0 = 2, s0 = 2;
167  int sn, tn;
168  double ss = 2, ts = 2;
169  double r0, r1;
170  int i, j;
171  int rxi, ryi;
172  int s;
173 
174  x2i = (int) floor( x2 );
175  y2i = (int) floor( y2 );
176 
177  sn = abs( x2i - rm->x1i );
178  tn = abs( y2i - rm->y1i );
179 
180  if( sn )
181  {
182  s0 = ( (x2>rm->x1 ? rm->x1i + 1 : rm->x1i) - rm->x1 ) / (x2 - rm->x1);
183  ss = fabs( 1.0 / (x2 - rm->x1) );
184  }
185 
186  if( tn )
187  {
188  t0 = ( (y2>rm->y1 ? rm->y1i + 1 : rm->y1i) - rm->y1 ) / (y2 - rm->y1);
189  ts = fabs( 1.0 / (y2 - rm->y1) );
190  }
191 
192  r0 = 0;
193 
194  i = 0;
195  j = 0;
196 
197  rxi = rm->x1i;
198  ryi = rm->y1i;
199 
200  while( i<sn || j<tn )
201  {
202  if( j>=tn || (i<sn && s0 + i * ss < t0 + j * ts) )
203  {
204  r1 = s0 + i * ss;
205  i++;
206  s = 1;
207  }
208  else
209  {
210  r1 = t0 + j * ts;
211  j++;
212  s = 0;
213  }
214 
215  /* render line from r0 to r1 segment of (rm->x1,rm->y1)..(x2,y2) */
216 
217  /* move point to r1 */
218  rm->a1 += (r1 - r0) * (y2 - rm->y1) *
219  ( rxi + 1 - ( (r0 + r1) / 2.0 * (x2 - rm->x1) + rm->x1 ) );
220 
221  /* move point across pixel boundary */
222  if( s && x2>rm->x1 )
223  {
224  GM_INC( rm->gm, rxi, ryi, rm->a1 * 255 );
225  rm->a1 = 0;
226  rxi++;
227  rm->a1 += rm->y1 + r1 * (y2 - rm->y1) - ryi;
228  }
229  else if( !s && y2>rm->y1 )
230  {
231  GM_INC( rm->gm, rxi, ryi, rm->a1 * 255 );
232  rm->a1 = 0;
233  incrow( rm, rxi + 1, ryi, 255 );
234  ryi++;
235  }
236  else if( s && x2<=rm->x1 )
237  {
238  rm->a1 -= rm->y1 + r1 * (y2 - rm->y1) - ryi;
239  GM_INC( rm->gm, rxi, ryi, rm->a1 * 255 );
240  rm->a1 = 0;
241  rxi--;
242  }
243  else if( !s && y2<=rm->y1 )
244  {
245  GM_INC( rm->gm, rxi, ryi, rm->a1 * 255 );
246  rm->a1 = 0;
247  ryi--;
248  incrow( rm, rxi + 1, ryi, -255 );
249  }
250 
251  r0 = r1;
252  }
253 
254  /* move point to (x2,y2) */
255 
256  r1 = 1;
257  rm->a1 += (r1 - r0) * (y2 - rm->y1) *
258  ( rxi + 1 - ( (r0 + r1) / 2.0 * (x2 - rm->x1) + rm->x1 ) );
259 
260  rm->x1i = x2i;
261  rm->y1i = y2i;
262  rm->x1 = x2;
263  rm->y1 = y2;
264 
265  /* assert (rxi != rm->x1i || ryi != rm->y1i); */
266 }
#define GM_INC(gm, x, y, b)
Definition: greymap.h:38
static void incrow(render_t *rm, int x, int y, int b)
Definition: render.cpp:118
#define abs(a)
Definition: auxiliary.h:84
int y1i
Definition: render.h:15
greymap_t * gm
Definition: render.h:13
double x1
Definition: render.h:14
double y1
Definition: render.h:14
double a1
Definition: render.h:16
int x1i
Definition: render.h:15
void render_moveto ( render_t rm,
double  x,
double  y 
)

Definition at line 101 of file render.cpp.

References render_s::a0, render_s::a1, render_close(), render_s::x0, render_s::x0i, render_s::x1, render_s::x1i, render_s::y0, render_s::y0i, render_s::y1, and render_s::y1i.

102 {
103  /* close the previous path */
104  render_close( rm );
105 
106  rm->x0 = rm->x1 = x;
107  rm->y0 = rm->y1 = y;
108  rm->x0i = (int) floor( rm->x0 );
109  rm->x1i = (int) floor( rm->x1 );
110  rm->y0i = (int) floor( rm->y0 );
111  rm->y1i = (int) floor( rm->y1 );
112  rm->a0 = rm->a1 = 0;
113 }
int x0i
Definition: render.h:15
double a0
Definition: render.h:16
int y0i
Definition: render.h:15
int y1i
Definition: render.h:15
double x0
Definition: render.h:14
double x1
Definition: render.h:14
double y1
Definition: render.h:14
double y0
Definition: render.h:14
double a1
Definition: render.h:16
int x1i
Definition: render.h:15
void render_close(render_t *rm)
Definition: render.cpp:85
render_t* render_new ( greymap_t gm)

Definition at line 49 of file render.cpp.

References render_s::gm, greymap_s::h, and render_s::incrow_buf.

50 {
51  render_t* rm;
52 
53  rm = (render_t*) malloc( sizeof(render_t) );
54 
55  if( !rm )
56  {
57  return NULL;
58  }
59 
60  memset( rm, 0, sizeof(render_t) );
61  rm->gm = gm;
62  rm->incrow_buf = (int*) calloc( gm->h, sizeof(int) );
63 
64  if( !rm->incrow_buf )
65  {
66  free( rm );
67  return NULL;
68  }
69 
70  memset( rm->incrow_buf, 0, gm->h * sizeof(int) );
71  return rm;
72 }
int h
Definition: greymap.h:20
int * incrow_buf
Definition: render.h:17
greymap_t * gm
Definition: render.h:13