ETL
0.04.19
Main Page
Related Pages
Classes
Files
File List
File Members
ETL
_pen.h
Go to the documentation of this file.
1
25
/* === S T A R T =========================================================== */
26
27
#ifndef __ETL__PEN_H
28
#define __ETL__PEN_H
29
30
/* === H E A D E R S ======================================================= */
31
32
#include "
_curve_func.h
"
33
#include <cassert>
34
#include <iterator>
35
#include <algorithm>
36
37
/* === M A C R O S ========================================================= */
38
39
/* === T Y P E D E F S ===================================================== */
40
41
/* === C L A S S E S & S T R U C T S ======================================= */
42
43
_ETL_BEGIN_NAMESPACE
44
45
template
<
typename
T>
46
class
generic_pen_row_iterator
47
{
48
public
:
49
struct
iterator_category
:
public
std::random_access_iterator_tag {};
50
typedef
T
value_type
;
51
typedef
int
difference_type
;
52
typedef
value_type
*
pointer
;
53
typedef
value_type
&
reference
;
54
55
typedef
generic_pen_row_iterator<value_type>
self_type
;
56
57
pointer
data_
;
58
int
pitch_
;
59
60
reference
operator[]
(
int
i)
const
{ assert(
data_
);
return
*(
pointer
)( (
char
*)
data_
+
pitch_
*i ); }
61
reference
operator*
()
const
{ assert(
data_
);
return
*
data_
; }
62
pointer
operator->
()
const
{ assert(
data_
);
return
&(
operator*
()); }
63
64
void
inc
() { assert(
data_
);
data_
= (
pointer
)((
char
*)
data_
+
pitch_
); }
65
void
inc
(
int
n) { assert(
data_
);
data_
= (
pointer
)((
char
*)
data_
+ n*
pitch_
); }
66
67
void
dec
() { assert(
data_
);
data_
= (
pointer
)((
char
*)
data_
-
pitch_
); }
68
void
dec
(
int
n) { assert(
data_
);
data_
= (
pointer
)((
char
*)
data_
- n*
pitch_
); }
69
70
const
self_type
&
operator++
() { assert(
data_
);
inc
();
return
*
this
; }
71
const
self_type
&
operator--
() { assert(
data_
);
dec
();
return
*
this
; }
72
73
self_type
operator++
(
int
)
74
{ assert(
data_
);
self_type
ret(*
this
);
inc
();
return
ret; }
75
self_type
operator--
(
int
)
76
{ assert(
data_
);
self_type
ret(*
this
);
dec
();
return
ret; }
77
78
bool
operator==
(
const
self_type
&rhs)
const
79
{
return
data_
==rhs.
data_
; }
80
81
bool
operator!=
(
const
self_type
&rhs)
const
82
{
return
data_
!=rhs.
data_
; }
83
84
difference_type
operator-
(
const
self_type
&rhs)
const
85
{ assert(
data_
);
return
((
char
*)
data_
-(
char
*)rhs.
data_
-1)/
pitch_
+1; }
86
87
self_type
operator+
(
const
difference_type
&rhs)
const
88
{
89
assert(
data_
);
90
self_type
ret(*
this
);
91
ret.
inc
(rhs);
92
return
ret;
93
}
94
95
self_type
operator-
(
const
difference_type
&rhs)
const
96
{
97
assert(
data_
);
98
self_type
ret(*
this
);
99
ret.
dec
(rhs);
100
return
ret;
101
}
102
103
operator
const
generic_pen_row_iterator<const value_type>
()
const
104
{
105
return
generic_pen_row_iterator<const value_type>
(
data_
,
pitch_
);
106
}
107
108
operator
bool()
const
{
return
(
bool
)
data_
; }
109
bool
operator!
()
const
{
return
!
data_
; }
110
111
generic_pen_row_iterator
(
pointer
data,
int
pitch):
data_
(data),
pitch_
(pitch) { }
112
generic_pen_row_iterator
():
data_
(
NULL
) { }
113
};
114
115
template
<
typename
T,
typename
AT=T>
116
class
generic_pen
117
{
118
public
:
119
typedef
T
value_type
;
120
typedef
AT
accumulator_type
;
121
typedef
value_type
*
pointer
;
122
typedef
accumulator_type
*
accumulator_pointer
;
123
typedef
const
value_type
*
const_pointer
;
124
typedef
const
accumulator_type
*
const_accumulator_pointer
;
125
typedef
value_type
&
reference
;
126
typedef
const
value_type
&
const_reference
;
127
128
typedef
pointer
iterator_x
;
129
typedef
const_pointer
const_iterator_x
;
130
131
typedef
generic_pen_row_iterator<value_type>
iterator_y
;
132
typedef
generic_pen_row_iterator<const value_type>
const_iterator_y
;
133
134
struct
difference_type
135
{
136
typedef
int
value_type
;
137
value_type
x
,
y
;
138
difference_type
(
value_type
x
,
value_type
y
):x(x),y(y) { }
139
value_type
&
operator[]
(
int
i)
const
{
return
i?
y
:
x
; }
140
};
141
142
protected
:
143
int
x_
,
y_
;
144
int
w_
,
h_
;
145
private
:
146
int
pitch_
;
147
value_type
value_
;
148
value_type
*
data_
;
149
150
typedef
generic_pen<T,AT>
self_type
;
151
152
void
addptr
(
int
nbytes)
153
{
154
data_
= (
pointer
)((
char
*)
data_
+ nbytes);
155
}
156
157
void
subptr
(
int
nbytes)
158
{
159
data_
= (
pointer
)((
char
*)
data_
- nbytes);
160
}
161
162
public
:
163
164
generic_pen
(
value_type
*data,
int
w,
int
h,
int
pitch):
165
x_
(0),
166
y_
(0),
167
w_
(w),
168
h_
(h),
169
pitch_
(pitch),
170
data_
(data)
171
{
172
}
173
174
generic_pen
(
value_type
*data,
int
w,
int
h):
175
x_
(0),
176
y_
(0),
177
w_
(w),
178
h_
(h),
179
pitch_
(sizeof(
value_type
)*w),
180
data_
(data)
181
{
182
}
183
184
generic_pen
():
data_
(
NULL
) { }
185
186
self_type
&
move
(
int
a,
int
b)
187
{
188
assert(
data_
);
189
x_
+= a,
y_
+= b;
190
addptr
(b*
pitch_
+ a*
sizeof
(
value_type
));
191
return
*
this
;
192
}
193
self_type
&
move_to
(
int
x
,
int
y
) { assert(
data_
);
return
move
(x -
x_
,y -
y_
);}
194
void
set_value
(
const
value_type
&v) {
value_
=v; }
195
196
void
inc_x
() { assert(
data_
);
x_
++;
data_
++; }
197
void
dec_x
() { assert(
data_
);
x_
--;
data_
--; }
198
void
inc_y
() { assert(
data_
);
y_
++;
addptr
(
pitch_
); }
199
void
dec_y
() { assert(
data_
);
y_
--;
subptr
(
pitch_
); }
200
201
void
inc_x
(
int
n) { assert(
data_
);
x_
+=n;
data_
+=n; }
202
void
dec_x
(
int
n) { assert(
data_
);
x_
-=n;
data_
-=n; }
203
void
inc_y
(
int
n) { assert(
data_
);
y_
+=n;
data_
= (
pointer
)((
char
*)
data_
+
pitch_
*n); }
204
void
dec_y
(
int
n) { assert(
data_
);
y_
-=n;
data_
= (
pointer
)((
char
*)
data_
-
pitch_
*n); }
205
206
void
put_value
(
const
value_type
&v)
const
{ assert(
data_
); *
data_
=v; }
207
void
put_value
()
const
{ assert(
data_
);
put_value
(
value_
); }
208
209
void
put_value_clip
(
const
value_type
&v)
const
210
{
if
(!
clipped
())
put_value
(v); }
211
void
put_value_clip
()
const
{
put_value_clip
(
value_
); }
212
213
const_reference
get_value
()
const
{ assert(
data_
);
return
*
data_
; }
214
215
const_reference
get_value_at
(
int
x
,
int
y
)
const
{ assert(
data_
);
return
((
pointer
)(((
char
*)
data_
)+y*
pitch_
))[
x
]; }
216
217
const_reference
get_value_clip_at
(
int
x
,
int
y
)
const
{ assert(
data_
);
if
(
clipped
(x,y))
return
value_type
();
return
((
pointer
)(((
char
*)
data_
)+y*
pitch_
))[
x
]; }
218
219
const
value_type
get_value_clip
()
const
{ assert(
data_
);
if
(
clipped
())
return
value_type
();
return
*
data_
; }
220
221
const
value_type
get_pen_value
()
const
{
return
value_
; }
222
223
void
put_hline
(
int
l,
const
value_type
&v)
224
{
for
(;l>0;l--,
inc_x
())
put_value
(v);}
225
226
void
put_hline
(
int
l) {
put_hline
(l,
value_
);}
227
228
void
put_hline_clip
(
int
l,
const
value_type
&v)
229
{l=std::min(l,
w_
-
x_
);
for
(;l>0;l--,
inc_x
())
put_value_clip
(v);}
230
231
void
put_hline_clip
(
int
l) {
put_hline_clip
(l,
value_
);}
232
233
//the put_block functions do not modify the pen
234
void
put_block
(
int
h,
int
w,
const
value_type
&v)
235
{
236
self_type
row(*
this
);
237
for
(;h>0;h--,row.
inc_y
())
238
{
239
self_type
col(row);
240
col.
put_hline
(w,v);
241
}
242
}
243
244
void
put_block
(
int
h,
int
w) {
put_block
(h,w,
value_
); }
245
246
void
put_block_clip
(
int
h,
int
w,
const
value_type
&v)
247
{
248
self_type
row(*
this
);
249
250
//clip start position
251
if
(row.
x_
< 0) { w+=row.
x_
; row.
inc_x
(-row.
x_
); }
252
if
(row.
y_
< 0) { h+=row.
y_
; row.
inc_y
(-row.
y_
); }
253
254
//clip width and height of copy rect
255
h = std::min(h,
h_
-
y_
);
256
w = std::min(w,
w_
-
x_
);
257
258
//copy rect
259
for
(;h>0;h--,row.
inc_y
())
260
{
261
self_type
col(row);
262
col.
put_hline
(w,v);
//already clipped
263
}
264
}
265
266
void
put_block_clip
(
int
h,
int
w) {
put_block
(h,w,
value_
); }
267
268
269
iterator_x
operator[]
(
int
i)
const
{ assert(
data_
);
return
(
pointer
)(((
char
*)
data_
)+i*
pitch_
); }
270
271
iterator_x
x
() { assert(
data_
);
return
data_
; }
272
iterator_x
begin_x
() { assert(
data_
);
return
data_
-
x_
; }
273
iterator_x
end_x
() { assert(
data_
);
return
data_
-
x_
+
w_
; }
274
275
iterator_y
y
() { assert(
data_
);
return
iterator_y
(
data_
,
pitch_
); }
276
iterator_y
begin_y
() { assert(
data_
);
return
iterator_y
((
pointer
)((
char
*)
data_
-
y_
*
pitch_
),pitch_); }
277
iterator_y
end_y
() { assert(
data_
);
return
iterator_y
((
pointer
)((
char
*)
data_
+ (
h_
-
y_
)*
pitch_
),pitch_); }
278
279
operator
bool()
const
{
return
(
bool
)
data_
; }
280
bool
operator!
()
const
{
return
!
data_
; }
281
bool
operator==
(
const
self_type
&rhs)
const
{
return
data_
==rhs.
data_
; }
282
bool
operator!=
(
const
self_type
&rhs)
const
{
return
data_
!=rhs.
data_
; }
283
bool
clipped
(
int
x
,
int
y
)
const
{
return
!(
x_
+x>=0 &&
y_
+y>=0 &&
x_
+x<
w_
&&
y_
+y<
h_
); }
284
bool
clipped
()
const
{
return
!(
x_
>=0 &&
y_
>=0 &&
x_
<
w_
&&
y_
<
h_
); }
285
286
difference_type
operator-
(
const
self_type
&rhs)
const
287
{
288
assert(
data_
);
289
assert(
pitch_
==rhs.
pitch_
);
290
int
ptr_diff=(
char
*)
data_
-(
char
*)rhs.
data_
-1;
291
return
difference_type
(ptr_diff%
pitch_
/
sizeof
(
value_type
)+1,ptr_diff/
pitch_
);
292
}
293
294
self_type
operator+
(
const
difference_type
&rhs)
const
295
{
296
assert(
data_
);
297
self_type
ret(*
this
);
298
ret.
move
(rhs.
x
,rhs.
y
);
299
return
ret;
300
}
301
302
difference_type
diff_begin
()
const
{
return
difference_type
(-
x_
,-
y_
);}
303
difference_type
diff_end
()
const
{
return
difference_type
(
w_
-
x_
,
h_
-
y_
);}
304
305
self_type
get_start
()
const
{
return
*
this
+
diff_begin
(); }
306
self_type
get_end
()
const
{
return
*
this
+
diff_end
(); }
307
308
int
get_width
()
const
{
return
w_
;}
309
int
get_height
()
const
{
return
h_
;}
310
311
int
get_w
()
const
{
return
w_
;}
312
int
get_h
()
const
{
return
h_
;}
313
int
get_pitch
()
const
{
return
pitch_
;}
314
};
315
316
template
<
317
typename
PEN_,
318
typename
A_=float,
319
class
AFFINE_=
affine_combo<typename PEN_::value_type,A_>
320
>
321
class
alpha_pen
:
public
PEN_
322
{
323
public
:
324
typedef
A_
alpha_type
;
325
typedef
AFFINE_
affine_func_type
;
326
327
typedef
typename
PEN_::value_type
value_type
;
328
typedef
alpha_pen
self_type
;
329
330
private
:
331
alpha_type
alpha_
;
332
333
protected
:
334
affine_func_type
affine_func_
;
335
336
public
:
337
using
PEN_::get_value;
338
using
PEN_::get_pen_value;
339
using
PEN_::inc_x;
340
using
PEN_::dec_x;
341
using
PEN_::inc_y;
342
using
PEN_::dec_y;
343
using
PEN_::clipped;
344
using
PEN_::w_;
345
using
PEN_::h_;
346
using
PEN_::x_;
347
using
PEN_::y_;
348
349
alpha_pen
(
const
alpha_type
&a = 1,
const
affine_func_type
&func =
affine_func_type
()):
alpha_
(a),
affine_func_
(func) { }
350
alpha_pen
(
const
PEN_ &x,
const
alpha_type
&a=1,
const
affine_func_type
&func=
affine_func_type
())
351
:PEN_(x),
alpha_
(a),
affine_func_
(func) { }
352
353
const
alpha_type
&
get_alpha
()
const
{
return
alpha_
; }
354
void
get_alpha
(
alpha_type
&a)
const
{ a=
alpha_
; }
355
void
set_alpha
(
alpha_type
a) {
alpha_
=a; }
356
357
void
put_value
(
const
value_type
&v,
alpha_type
a=1)
const
358
{
PEN_::put_value
(
affine_func_
(get_value(),v,
alpha_
*a)); }
359
void
put_value
()
const
{
put_value
(get_pen_value()); }
360
void
put_value_alpha
(
alpha_type
a)
const
{
put_value
(get_pen_value(),a); }
361
void
put_hline
(
int
l,
const
alpha_type
&a = 1){
for
(;l>0;l--,inc_x())
put_value_alpha
(a);}
362
363
void
put_value_clip
(
const
value_type
&v,
alpha_type
a=1)
const
364
{
if
(!clipped())
PEN_::put_value
(
affine_func_
(get_value(),v,
alpha_
*a)); }
365
void
put_value_clip
()
const
{
put_value_clip
(get_pen_value()); }
366
void
put_value_clip_alpha
(
alpha_type
a)
const
{
put_value_clip
(get_pen_value(),a); }
367
void
put_hline_clip
(
int
l,
const
alpha_type
&a = 1){l=std::min(l,w_-x_);
for
(;l>0;l--,inc_x())
put_value_clip_alpha
(a);}
368
369
//the put_block functions do not modify the pen
370
void
put_block
(
int
h,
int
w,
const
alpha_type
&a = 1)
371
{
372
self_type
row(*
this
);
373
for
(;h>0;h--,row.inc_y())
374
{
375
self_type
col(row);
376
col.
put_hline
(w,a);
377
}
378
}
379
380
void
put_block_clip
(
int
h,
int
w,
const
alpha_type
&a = 1)
381
{
382
self_type
row(*
this
);
383
384
//clip start position
385
if
(row.x_ < 0) { w+=row.x_; row.inc_x(-row.x_); }
386
if
(row.y_ < 0) { h+=row.y_; row.inc_y(-row.y_); }
387
388
//clip width and height of copy rect
389
h = std::min(h,h_-y_);
390
w = std::min(w,w_-x_);
391
392
//copy rect
393
for
(;h>0;h--,row.inc_y())
394
{
395
self_type
col(row);
396
col.
put_hline
(w,a);
//already clipped
397
}
398
}
399
};
400
401
_ETL_END_NAMESPACE
402
403
/* === E X T E R N S ======================================================= */
404
405
/* === E N D =============================================================== */
406
407
#endif
Generated on Mon Nov 16 2015 15:32:03 for ETL by
1.8.1.2