1 
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 
6 #include "GPBitmap.h"
7 #include "GPView.h"
8 #include "constants.h"
9 #include <Region.h>
10 #include <ScrollBar.h>
11 
12 #define LineSolid 1
13 
14 
15 /*******************************************************************/
16 // GPBitmap
GPBitmap(float width,float height)17 GPBitmap::GPBitmap(float width, float height)
18 {
19 	m_bitmap = new BBitmap(BRect(0,0,width-1,height-1),B_RGB_32_BIT,TRUE);
20 	BRect r(0,0,width-1,height-1);
21 	m_view = new BView(r,"BitmapDrawer",B_FOLLOW_ALL,0);
22 	m_bitmap->AddChild(m_view);
23 	max_commands	= 7;
24 	ncommands		= 0;
25 	m_needRedraw	= false;
26 	m_redrawing 	= false;
27 	commands		= (char **) malloc(max_commands * sizeof(char *));
28 	this->width		= nwidth = width;
29 	this->height	= nheight = height;
30 
31 	for(int i=1 ; i<16 ; i++) {
32 		colors[i].red	= i*16;
33 		colors[i].green	= i*16;
34 		colors[i].blue	= i*16;
35 		colors[i].alpha	= 255;
36 	}
37 };
38 
GPBitmap(float width,float height,char ** cmds)39 GPBitmap::GPBitmap(float width, float height, char **cmds)
40 {
41 
42 }
43 
~GPBitmap()44 GPBitmap::~GPBitmap()
45 {
46 	if (m_bitmap)
47 		delete m_bitmap;
48 	if(m_view)
49 		delete m_view;
50 	if(ncommands)
51 		clearCommands();
52 	if(commands) {
53 		free(commands);
54 		commands = NULL;
55 	}
56 }
57 
SetDirty(BRegion * r)58 void GPBitmap::SetDirty(BRegion *r)
59 {
60 	BMessage msg(bmsgBitmapDirty);
61 	m_needRedraw = true;
62 }
63 
clearCommands()64 void GPBitmap::clearCommands()
65 {
66 	int32 ncmds = atomic_add(&ncommands,-ncommands);
67 	if(ncmds > 0) {
68 		for( --ncmds ; ncmds >= 0 ; ncmds--) {
69 			if(commands[ncmds])
70 				free(commands[ncmds]);
71 			commands[ncmds] = NULL;
72 		}
73 	}
74 }
75 
76 #if 1
addCommands(BMessage * msg,int32 numCmds)77 void GPBitmap::addCommands(BMessage *msg, int32 numCmds)
78 {
79 	char *p, **cmd = NULL;
80 
81 	if (numCmds+ncommands >= max_commands) {
82 		max_commands = max_commands + numCmds + 2;
83 		commands = (commands)
84 			? (char **) realloc(commands, max_commands * sizeof(char *))
85 			: (char **) malloc(sizeof(char *));
86 	}
87 	if (!commands) {
88 		fputs("gnuplot: can't get memory. aborted.\n", stderr);
89 //		exit(1);
90 	} else {
91 		msg->FindPointer("cmds", (void **)&cmd);
92 //		printf("got : %X at %X\n",cmd[0], cmd);
93 		for(int i=0; i< numCmds; i++) {
94 //			cmd = msg->FindString("cmd", i);
95 //			p = (char *) malloc((unsigned) strlen(cmd[i]) + 1);
96 //			if (!p) {
97 //				fputs("gnuplot: can't get memory. aborted.\n", stderr);
98 //				exit(1);
99 //			} else
100 //				commands[ncommands++] = strcpy(p, cmd[i]);
101 			commands[ncommands++] = strdup(cmd[i]);
102 //			commands[ncommands++] = cmd[i];
103 			m_needRedraw = true;
104 		}
105 	}
106 }
107 #else
addCommands(BMessage * msg,int32 numCmds)108 void GPBitmap::addCommands(BMessage *msg, int32 numCmds)
109 {
110 	char *cmd = NULL;
111 
112 	if (numCmds+ncommands >= max_commands) {
113 		max_commands = max_commands + numCmds + 2;
114 		commands = (commands)
115 			? (char **) realloc(commands, max_commands * sizeof(char *))
116 			: (char **) malloc(sizeof(char *));
117 	}
118 	if (!commands) {
119 		fputs("gnuplot: can't get memory. aborted.\n", stderr);
120 //		exit(1);
121 	} else {
122 		for(int i=0; i< numCmds; i++) {
123 			cmd = msg->FindString("cmd", i);
124 			commands[ncommands++] = strdup(cmd);
125 			m_needRedraw = true;
126 		}
127 	}
128 }
129 #endif
130 
addCommand(char * cmd)131 void GPBitmap::addCommand(char *cmd)
132 {
133 //	printf("adding a cmd : %s\n",cmd);
134 	if(!cmd)
135 		return;
136 	if (ncommands >= max_commands) {
137 		max_commands = max_commands * 2 + 1;
138 		commands = (commands)
139 			? (char **) realloc(commands, max_commands * sizeof(char *))
140 			: (char **) malloc(sizeof(char *));
141 	}
142 	if (!commands) {
143 		fputs("gnuplot: can't get memory. X11 aborted.\n", stderr);
144 		return; // exit(1);
145 	} else {
146 		commands[ncommands++] = strdup(cmd);
147 		m_needRedraw = true;
148 	}
149 }
150 
ResizeTo(float width,float height,uint32 btns)151 void GPBitmap::ResizeTo(float width, float height, uint32 btns)
152 {
153 	if(btns) {
154 		nwidth  = width;
155 		nheight = height;
156 //		m_needRedraw = true;
157 		return;
158 	}
159 	BRect r(0,0,width-1,height-1);
160 	if (m_bitmap)
161 		m_bitmap->Lock();
162 	if(m_view) {
163 		m_bitmap->RemoveChild(m_view);
164 		m_view->ResizeTo(nwidth, nheight);
165 	} else
166 		m_view = new BView(r,"BitmapDrawer",B_FOLLOW_ALL,0);
167 
168 //    drawing_thread = spawn_thread(&drawing_loop, "gnuplot io_loop", B_LOW_PRIORITY, this);
169 //    resume_thread(drawing_thread);
170 //	kill_thread(drawing_thread);
171 
172 	if (m_bitmap) {
173 		m_bitmap->Unlock();
174 		delete m_bitmap;
175 	}
176 
177 	m_bitmap = new BBitmap(r,B_RGB_32_BIT,TRUE);
178 	m_bitmap->Lock();
179 	m_bitmap->AddChild(m_view);
180 	this->width = nwidth = width;
181 	this->height = nheight = height;
182 	m_needRedraw = true;
183 }
184 
drawing_loop(void * data)185 int32 GPBitmap::drawing_loop(void* data)
186 {
187 	int32 res = 1;
188 	GPBitmap * bmp = (GPBitmap *)data;
189 
190 	return res;
191 }
192 
193 /*-----------------------------------------------------------------------------
194  *   display - display a stored plot
195  *---------------------------------------------------------------------------*/
196 
display(float v_width,float v_height)197 void GPBitmap::display(float v_width, float v_height)
198 {
199 	int n, x, y, jmode, sl, lt = 0, type, point, px, py;
200 	int uwidth, user_width = 1;		/* as specified by plot...linewidth */
201 	char *buffer, *str;
202 	float sw, vchar;
203 
204 	uint32 buttons;
205 	BPoint cursor;
206 	m_view->GetMouse(&cursor, &buttons);
207 
208 	if(buttons == 0) {
209 		if ((width != v_width ) || (height != v_height))
210 			ResizeTo(v_width, v_height, 0);
211 	}
212 
213 	if (ncommands == 0 || m_needRedraw == false)
214 		return;
215 
216 	vchar = 11.0;
217 	m_view->SetFontSize(vchar);
218 
219 	/* set scaling factor between internal driver & window geometry */
220 	xscale = width / 4096.0;
221 	yscale = height / 4096.0;
222 
223 	/* initial point sizes, until overridden with P7xxxxyyyy */
224 	px = (int) (xscale * pointsize);
225 	py = (int) (yscale * pointsize);
226 
227 	/* set pixmap background */
228 	m_view->SetHighColor(255,255,255);
229 	m_view->FillRect(BRect(0,0,width,height));
230 	m_view->SetViewColor(colors[2]);
231 
232 	/* loop over accumulated commands from inboard driver */
233 	for (n = 0; n < ncommands; n++) {
234 		buffer = commands[n];
235 
236 		/*   X11_vector(x,y) - draw vector  */
237 		if (*buffer == 'V') {
238 			sscanf(buffer, "V%4d%4d", &x, &y);
239 			m_view->StrokeLine( BPoint(X(cx), Y(cy)),BPoint(X(x), Y(y)));
240 			cx = x;
241 			cy = y;
242 		}
243 		/*   X11_move(x,y) - move  */
244 		else if (*buffer == 'M') {
245 			sscanf(buffer, "M%4d%4d", &cx, &cy);
246 			m_view->MovePenTo(BPoint(X(cx), Y(cy)));
247 		}
248 		/*   X11_put_text(x,y,str) - draw text   */
249 		else if (*buffer == 'T') {
250 
251 			sscanf(buffer, "T%4d%4d", &x, &y);
252 			str = buffer + 9;
253 			sl = strlen(str) - 1;
254 			sw = m_view->StringWidth(str, sl);
255 
256 			switch (jmode) {
257 				case CENTRE:				sw = -sw / 2;	break;
258 				case RIGHT:					sw = -sw;		break;
259 				case LEFT:					sw = 0;			break;
260 			}
261 
262 			m_view->SetHighColor(colors[2]);
263 			m_view->DrawString(str, sl, BPoint(X(x) + sw, Y(y) + vchar / 3 ));
264 			m_view->SetHighColor(colors[lt + 3]);
265 		}
266 		else if (*buffer == 'F') {	/* fill box */
267 			int style, xtmp, ytmp, w, h;
268 
269 			if (sscanf(buffer + 1, "%4d%4d%4d%4d%4d", &style, &xtmp, &ytmp, &w, &h) == 5) {
270 				/* gnuplot has origin at bottom left, but X uses top left
271 				 * There may be an off-by-one (or more) error here.
272 				 * style ignored here for the moment
273 				 */
274                                 /* ULIG: the style parameter is now used for the fillboxes style
275                                  * (not implemented here), see the documentation */
276 				m_view->SetHighColor(colors[0]);
277 				m_view->FillRect(BRect(X(xtmp), Y(ytmp + h), w * xscale, h * yscale));
278 				m_view->SetHighColor(colors[lt + 3]);
279 			}
280 		}
281 		/*   X11_justify_text(mode) - set text justification mode  */
282 		else if (*buffer == 'J')
283 			sscanf(buffer, "J%4d", (int *) &jmode);
284 
285 		/*  X11_linewidth(width) - set line width */
286 		else if (*buffer == 'W')
287 			sscanf(buffer + 1, "%4d", &user_width);
288 
289 		/*   X11_linetype(type) - set line type  */
290 		else if (*buffer == 'L') {
291 			sscanf(buffer, "L%4d", &lt);
292 			lt = (lt % 8) + 2;
293 			/* default width is 0 {which X treats as 1} */
294 			uwidth = user_width; // widths[lt] ? user_width * widths[lt] : user_width;
295 //			if (dashes[lt][0]) {
296 //				type = LineOnOffDash;
297 //				XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
298 //			} else {
299 				type = LineSolid;
300 //			}
301 			m_view->SetHighColor(colors[lt + 3]);
302 			m_view->SetPenSize(uwidth);
303 			m_view->SetLineMode(B_ROUND_CAP,B_BEVEL_JOIN);
304 //			XSetLineAttributes(dpy, gc, width, type, CapButt, JoinBevel);
305 		}
306 		/*   X11_point(number) - draw a point */
307 		else if (*buffer == 'P') {
308 			/* linux sscanf does not like %1d%4d%4d" with Oxxxxyyyy */
309 			/* sscanf(buffer, "P%1d%4d%4d", &point, &x, &y); */
310 			point = buffer[1] - '0';
311 			sscanf(buffer + 2, "%4d%4d", &x, &y);
312 			if (point == 7) {
313 				/* set point size */
314 				px = (int) (x * xscale * pointsize);
315 				py = (int) (y * yscale * pointsize);
316 			} else {
317 				if (type != LineSolid || uwidth != 0) {	/* select solid line */
318 					m_view->SetPenSize(1.0);
319 					m_view->SetLineMode(B_ROUND_CAP,B_BEVEL_JOIN);
320 //					XSetLineAttributes(dpy, gc, 0, LineSolid, CapButt, JoinBevel);
321 				}
322 				switch (point) {
323 					case 0:	/* dot */			doDot(x,y);				break;
324 					case 1:	/* do diamond */	doDiamond(x,y,px,py);	break;
325 					case 2:	/* do plus */		doPlus(x,y,px,py);		break;
326 					case 3:	/* do box */		doBox(x,y,px,py);		break;
327 					case 4:	/* do X */			doCross(x,y,px,py);		break;
328 					case 5:	/* do triangle */	doTriangle(x,y,px,py);	break;
329 					case 6:	/* do star */		doStar(x,y,px,py);		break;
330 				}
331 				if (type != LineSolid || uwidth != 0) {	/* select solid line */
332 					m_view->SetPenSize(uwidth);
333 //					canview->SetLineMode(B_ROUND_CAP,B_ROUND_JOIN);
334 //				    XSetLineAttributes(dpy, gc, width, type, CapButt, JoinBevel);
335 				}
336 			}
337 		} /* end  X11_point(number) - draw a point */
338 	} /* end loop over accumulated commands from inboard driver */
339 	m_view->Sync();
340 	m_needRedraw = false;
341 }
342 
doDiamond(int x,int y,int px,int py)343 void GPBitmap::doDiamond(int x, int y, int px, int py) {
344 	m_view->StrokeLine(BPoint(X(x) - px, Y(y)),BPoint(X(x), Y(y) - py));
345 	m_view->StrokeLine(BPoint(X(x) + px, Y(y)));
346 	m_view->StrokeLine(BPoint(X(x), Y(y) + py));
347 	m_view->StrokeLine(BPoint(X(x) - px, Y(y)));
348 	m_view->StrokeLine(BPoint(X(x), Y(y)),BPoint(X(x), Y(y)));
349 }
350 
doPlus(int x,int y,int px,int py)351 void GPBitmap::doPlus(int x, int y, int px, int py) {
352 	m_view->StrokeLine(BPoint(X(x) - px, Y(y)),BPoint(X(x) + px, Y(y)));
353 	m_view->StrokeLine(BPoint(X(x), Y(y) - py),BPoint(X(x), Y(y) + py));
354 }
355 
doBox(int x,int y,int px,int py)356 void GPBitmap::doBox(int x, int y, int px, int py) {
357 	m_view->StrokeRect(BRect(X(x) - px, Y(y) - py, (px + px), (py + py)));
358 	m_view->StrokeLine(BPoint(X(x), Y(y)),BPoint(X(x), Y(y)));
359 }
360 
doCross(int x,int y,int px,int py)361 void GPBitmap::doCross(int x, int y, int px, int py) {
362 	m_view->StrokeLine(BPoint(X(x) - px, Y(y) - py),BPoint(X(x) + px, Y(y) + py));
363 	m_view->StrokeLine(BPoint(X(x) - px, Y(y) + py),BPoint(X(x) + px, Y(y) - py));
364 }
365 
doTriangle(int x,int y,int px,int py)366 void GPBitmap::doTriangle(int x, int y, int px, int py) {
367 	short temp_x, temp_y;
368 
369 	temp_x = (short) (1.33 * (double) px + 0.5);
370 	temp_y = (short) (1.33 * (double) py + 0.5);
371 
372 	m_view->StrokeLine(BPoint(X(x), Y(y) - temp_y), BPoint(X(x) + temp_x, Y(y) - temp_y + 2 * py));
373 	m_view->StrokeLine(BPoint(X(x) - temp_x, Y(y) - temp_y + 2 * py));
374 	m_view->StrokeLine(BPoint(X(x), Y(y) - temp_y));
375 	m_view->StrokeLine(BPoint(X(x), Y(y)),BPoint(X(x), Y(y)));
376 }
377 
doStar(int x,int y,int px,int py)378 void GPBitmap::doStar(int x, int y, int px, int py) {
379 	m_view->StrokeLine(BPoint(X(x)-px, Y(y)), BPoint(X(x) + px, Y(y)));
380 	m_view->StrokeLine(BPoint(X(x), Y(y)-py), BPoint(X(x), Y(y)+py));
381 	m_view->StrokeLine(BPoint(X(x)-px, Y(y)-py), BPoint(X(x)+px, Y(y)+py));
382 	m_view->StrokeLine(BPoint(X(x)-px, Y(y)+py), BPoint(X(x)+px, Y(y)-py));
383 }
384 
doDot(int x,int y)385 void GPBitmap::doDot(int x, int y) {
386 	m_view->StrokeLine(BPoint(X(x), Y(y)),BPoint(X(x), Y(y)));
387 }
388 
389