FreeBASIC
0.91.0
Main Page
Data Structures
Files
File List
Globals
gfx_draw.c
Go to the documentation of this file.
1
/* DRAW command */
2
3
#include "
fb_gfx.h
"
4
#include <math.h>
5
#include <ctype.h>
6
7
#define FB_NAN 0x80000000
8
#define SQRT_2 1.4142135623730950488016
9
10
static
float
base_scale
= 1.0,
base_angle
= 0.0;
11
12
static
intptr_t
parse_number
(
char
**str)
13
{
14
char
*c = *str;
15
intptr_t n =
FB_NAN
;
16
int
negative =
FALSE
;
17
18
while
((*c ==
' '
) || (*c ==
'\t'
) || (*c ==
'+'
) || (*c ==
'-'
))
19
{
20
if
(*c ==
'-'
)
21
negative = !negative;
22
c++;
23
}
24
while
((*c >=
'0'
) && (*c <=
'9'
)) {
25
if
(n ==
FB_NAN
)
26
n = 0;
27
n = (n * 10) + (*c -
'0'
);
28
c++;
29
}
30
*str = c;
31
if
((negative) && (n !=
FB_NAN
))
32
n = -n;
33
34
return
n;
35
}
36
37
FBCALL
void
fb_GfxDraw
(
void
*target,
FBSTRING
*command)
38
{
39
FB_GFXCTX
*
context
=
fb_hGetContext
();
40
float
x, y, dx, dy, ax, ay, x2, y2, scale = 1.0, angle = 0.0;
41
char
*c;
42
intptr_t value1;
43
int
draw =
TRUE
, move =
TRUE
, length = 0, value2,
flags
, rel, ix, iy;
44
45
if
((!
__fb_gfx
) || (!command) || (!command->
data
)) {
46
if
(command)
47
fb_hStrDelTemp
(command);
48
return
;
49
}
50
51
fb_hPrepareTarget
(context, target);
52
fb_hSetPixelTransfer
(context,
MASK_A_32
);
53
54
x = context->
last_x
+ 0.5;
55
y = context->
last_y
+ 0.5;
56
57
DRIVER_LOCK
();
58
59
flags = context->
flags
;
60
context->
flags
|=
CTX_VIEW_SCREEN
;
61
62
for
(c = command->
data
; *c;) {
63
switch
(toupper(*c)) {
64
case
'B'
:
65
c++;
66
draw =
FALSE
;
67
break
;
68
69
case
'N'
:
70
c++;
71
move =
FALSE
;
72
break
;
73
74
case
'C'
:
75
c++;
76
if
((value1 =
parse_number
(&c)) ==
FB_NAN
)
77
goto
error;
78
context->
fg_color
=
fb_hFixColor
(context->
target_bpp
, value1);
79
break
;
80
81
case
'S'
:
82
c++;
83
if
((value1 =
parse_number
(&c)) ==
FB_NAN
)
84
goto
error;
85
base_scale
= (float)value1 / 4.0;
86
break
;
87
88
case
'A'
:
89
c++;
90
if
((value1 =
parse_number
(&c)) ==
FB_NAN
)
91
goto
error;
92
base_angle
= (float)(value1 & 0x3) *
PI
* 0.5;
93
break
;
94
95
case
'T'
:
96
c++;
97
if
(toupper(*c) !=
'A'
)
98
goto
error;
99
c++;
100
if
((value1 =
parse_number
(&c)) ==
FB_NAN
)
101
goto
error;
102
base_angle
= (float)value1 *
PI
/ 180.0;
103
break
;
104
105
case
'X'
:
106
c++;
107
/* Here we could be more severe with checking, but it's unlikely our substring
108
* resides at location FB_NAN (0x80000000) */
109
if
((value1 =
parse_number
(&c)) ==
FB_NAN
)
110
goto
error;
111
context->
last_x
= x - 0.5;
112
context->
last_y
= y - 0.5;
113
DRIVER_UNLOCK
();
114
fb_GfxDraw
(target, (
FBSTRING
*)value1);
115
DRIVER_LOCK
();
116
x = context->
last_x
+ 0.5;
117
y = context->
last_y
+ 0.5;
118
break
;
119
120
case
'P'
:
121
c++;
122
if
((value1 =
parse_number
(&c)) ==
FB_NAN
)
123
goto
error;
124
value2 = value1;
125
if
(*c ==
','
) {
126
c++;
127
if
((value2 =
parse_number
(&c)) ==
FB_NAN
)
128
goto
error;
129
}
130
DRIVER_UNLOCK
();
131
fb_GfxPaint
(target, x, y, value1 &
__fb_gfx
->
color_mask
, value2 &
__fb_gfx
->
color_mask
,
NULL
,
PAINT_TYPE_FILL
,
COORD_TYPE_A
);
132
DRIVER_LOCK
();
133
break
;
134
135
case
'M'
:
136
c++;
137
rel =
FALSE
;
138
while
((*c ==
' '
) || (*c ==
'\t'
))
139
c++;
140
if
((*c ==
'+'
) || (*c ==
'-'
))
141
{
142
rel =
TRUE
;
143
}
144
if
((value1 =
parse_number
(&c)) ==
FB_NAN
)
145
goto
error;
146
if
(*c++ !=
','
)
147
goto
error;
148
if
((value2 =
parse_number
(&c)) ==
FB_NAN
)
149
goto
error;
150
x2 = (float)value1;
151
y2 = (float)value2;
152
if
(rel) {
153
ax = cos(
base_angle
);
154
ay = -sin(
base_angle
);
155
dx = x2;
156
dy = y2;
157
x2 = (((dx * ax) - (dy * ay)) *
base_scale
) + x;
158
y2 = (((dy * ax) + (dx * ay)) * base_scale) + y;
159
}
160
else
{
161
x2 += 0.5;
162
y2 += 0.5;
163
}
164
if
(draw) {
165
DRIVER_UNLOCK
();
166
fb_GfxLine
(target, (
int
)x, (
int
)y, (
int
)x2, (
int
)y2, 0,
LINE_TYPE_LINE
, 0xFFFF,
COORD_TYPE_AA
|
DEFAULT_COLOR_1
);
167
DRIVER_LOCK
();
168
}
169
if
(move) {
170
x = floor(x2) + 0.5;
171
y = floor(y2) + 0.5;
172
}
173
move = draw =
TRUE
;
174
break
;
175
176
case
'F'
: angle +=
PI
* 0.25;
177
case
'D'
: angle +=
PI
* 0.25;
178
case
'G'
: angle +=
PI
* 0.25;
179
case
'L'
: angle +=
PI
* 0.25;
180
case
'H'
: angle +=
PI
* 0.25;
181
case
'U'
: angle +=
PI
* 0.25;
182
case
'E'
: angle +=
PI
* 0.25;
183
case
'R'
:
184
if
((toupper(*c) >=
'E'
) && (toupper(*c) <=
'H'
))
185
scale =
SQRT_2
;
186
c++;
187
if
((value1 =
parse_number
(&c)) !=
FB_NAN
)
188
length = value1;
189
else
190
length = 1;
191
break
;
192
193
default
:
194
c++;
195
break
;
196
}
197
198
if
(length) {
199
length = (int)(((
float
)length * (
base_scale
* scale)) + 0.5);
200
if
(length < 0) {
201
angle +=
PI
;
202
length = -length;
203
}
204
angle +=
base_angle
;
205
dx = x;
206
dy = y;
207
208
for
(; length >= 0; length--) {
209
if
(draw) {
210
ix = dx;
211
iy = dy;
212
if
((ix >= context->
view_x
) && (ix < context->
view_x
+ context->
view_w
) &&
213
(iy >= context->
view_y
) && (iy < context->
view_y
+ context->
view_h
)) {
214
context->
put_pixel
(context, ix, iy, context->
fg_color
);
215
if
(
__fb_gfx
->
framebuffer
== context->
line
[0])
216
__fb_gfx
->
dirty
[iy] =
TRUE
;
217
}
218
}
219
if
(length) {
220
dx += cos(angle);
221
dy -= sin(angle);
222
}
223
}
224
if
(move) {
225
x = floor(dx) + 0.5;
226
y = floor(dy) + 0.5;
227
}
228
angle = 0.0;
229
scale = 1.0;
230
length = 0;
231
move = draw =
TRUE
;
232
}
233
}
234
235
context->
last_x
= floor(x);
236
context->
last_y
= floor(y);
237
238
error:
239
context->
flags
=
flags
;
240
241
DRIVER_UNLOCK
();
242
243
/* del if temp */
244
fb_hStrDelTemp
( command );
245
}
gfxlib2
gfx_draw.c
Generated on Thu Jan 23 2014 19:40:06 for FreeBASIC by
1.8.4