[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

(mgp-users 00032) drawing extensions for mgp



Hi,

the following patches to mgp-snap-981005 implement the following:

 * simple drawing commands in the form

    %icon "command" "color" x0 y0 x1 y1

    where command can be "line", "rect" (filled rectangle) or
    "frame" (unfilled rectangle).  Dimensions are scaled to the
    current char size, 100 means one char width.
    I tried to define a new keyword, %draw, for these commands,
    but somehow i failed to do all things were needed...

 * line width from drawing is set to 2 for screen widths > 300,
   to 1 otherwhise. A few redundant commands in the jotting code
   are also removed.

and (less useful, but used by the drawing command code):

 * a hack that lets you specify non-square icon size as WWWHHH
   where WWW is the width and HHH is the height.

 * a couple of new icon types, 8 and 9, ("rect" and "frame").

  
I have not implemented printing for these things, essentially because this
code is a bit raw and also i am waiting for the print fixes that Mark
Handley sent some time ago to go in.

I hope the drawing commands are useful. I definitely needed them!

	cheers
	luigi

diff -ubwr kit/draw.c mgp-snap-981005/draw.c
--- kit/draw.c	Thu Oct  1 08:14:08 1998
+++ mgp-snap-981005/draw.c	Wed Oct  7 17:14:38 1998
@@ -72,7 +72,7 @@
 static int obj_new_xfont __P((struct render_state *, int, int, int,
 	u_int, char *));
 static int obj_new_image __P((struct render_state *, int, int, Image *, int, int));
-static int obj_new_icon __P((struct render_state *, int, int, u_int, u_int, u_long, u_int, XPoint *));
+static int obj_new_icon __P((struct render_state *, int, int, u_int, u_int, u_int, u_long, u_int, XPoint *));
 static Pixel obj_image_color __P((Image *, Image *, Pixel));
 static Image *obj_image_trans __P((Image *, u_int, u_int));
 static void obj_draw_image __P((Drawable, u_int, u_int, struct render_object *));
@@ -622,6 +622,9 @@
 		process_icon(state, cp);
 		break;
 
+	case CTL_DRAW:
+		process_draw(state, cp);
+		break;
 #ifdef VFLIB
 	case CTL_VFCAP:
 		vfcap_name = cp->ctc_value;
@@ -1328,10 +1331,10 @@
 }
 
 static int
-obj_new_icon(state, x, y, itype, isize, color, npoint, xpoint)
+obj_new_icon(state, x, y, itype, iwidth, iheight, color, npoint, xpoint)
 	struct render_state *state;
 	int x, y;
-	u_int itype, isize;
+	u_int itype, iwidth, iheight;
 	u_long color;
 	u_int npoint;
 	XPoint *xpoint;
@@ -1347,7 +1350,7 @@
 	obj->fore = color;
 	obj->type = O_ICON;
 	obj->data.icon.itype = itype;
-	obj->data.icon.isize = isize;
+	obj->data.icon.isize = iwidth;
 	obj->data.icon.npoint = npoint;
 	if (npoint) {
 		obj->data.icon.xpoint = malloc(sizeof(XPoint) * npoint);
@@ -1360,7 +1363,7 @@
 	} else
 		obj->data.icon.xpoint = NULL;
 	obj->ascent = 0;	/*XXX*/
-	obj->descent = isize;	/*XXX*/
+	obj->descent = iheight;	/*XXX*/
 	obj->vertloc = VL_CENTER;
 	return 1;
 }
@@ -1805,6 +1808,8 @@
 #endif
 			break;
 		case O_ICON:
+		fprintf(stderr, "rendering icon type %d\n",
+		    obj->data.icon.itype);
 			if (obj->fore != fore) {
 				fore = obj->fore;
 				XSetForeground(display, gcfore, fore);
@@ -1821,10 +1826,18 @@
 				break;
 			case 3: case 4: case 5: case 6:
 			case 7:
+			case 8: /* rect */
+			case 9: /* frame */
 				for (i = 0; i < obj->data.icon.npoint; i++) {
 					obj->data.icon.xpoint[i].x += x;
 					obj->data.icon.xpoint[i].y += y;
 				}
+				if (obj->data.icon.itype==9)
+				XDrawLines(display, target, gcfore,
+					obj->data.icon.xpoint,
+					obj->data.icon.npoint,
+					CoordModeOrigin);
+				else
 				XFillPolygon(display, target, gcfore, 
 					obj->data.icon.xpoint,
 					obj->data.icon.npoint,
@@ -2718,12 +2731,87 @@
 }
 
 static void
+process_draw(state, cp)
+	struct render_state *state;
+	struct ctrl *cp;
+{
+    XPoint xpoint[5];
+    int npoints;
+
+    int sz = (int) char_size ;
+    char *s= "?" ;
+    drawcmds cmd = cp->ct_val.ctrl_drawcmd.cmd ;
+    int icon_x = state->linewidth ;
+    int points = 0 ;
+    int icon_type = 9 ; /* 8 = filled, 9 = not filled */
+
+    switch (cmd) {
+    case DC_LINE:
+	s = "line ";
+	xpoint[0].x = icon_x + cp->ct_val.ctrl_drawcmd.x0*sz/100 ;
+	xpoint[0].y =        -(cp->ct_val.ctrl_drawcmd.y0*sz/100);
+	xpoint[1].x = icon_x + cp->ct_val.ctrl_drawcmd.x1*sz/100 ;
+	xpoint[1].y =        -(cp->ct_val.ctrl_drawcmd.y1*sz/100);
+	points = 2 ;
+	break ;
+
+    case DC_RECT :
+    case DC_BOX :
+	if (cmd == DC_RECT) {
+	    s = "rect";
+	    icon_type = 8 ;
+	    points = 4 ;
+	} else {
+	    s = "box ";
+	    points = 5 ;
+	}
+	xpoint[0].x = icon_x + cp->ct_val.ctrl_drawcmd.x0*sz/100 ;
+	xpoint[0].y =        -(cp->ct_val.ctrl_drawcmd.y0*sz/100);
+	xpoint[4].x = xpoint[0].x ;
+	xpoint[4].y = xpoint[0].y ;
+	xpoint[2].x = icon_x + cp->ct_val.ctrl_drawcmd.x1*sz/100 ;
+	xpoint[2].y =        -(cp->ct_val.ctrl_drawcmd.y1*sz/100);
+	xpoint[1].x = xpoint[2].x ;
+	xpoint[1].y = xpoint[0].y ;
+	xpoint[3].x = xpoint[0].x ;
+	xpoint[3].y = xpoint[2].y ;
+	points = 5 ;
+	break ;
+
+	break ;
+    }
+    obj_new_icon(state, 0, 0, icon_type,
+	    1 /* width */ ,
+	    1 /* icon_height */,
+	    cp->ct_val.ctrl_drawcmd.color,
+	    points, xpoint);
+    state->objlast->vertloc = VL_BASE;
+    fprintf(stderr, "processing draw %s %d %d %d %d , obj %x objlast %x\n",
+	s,
+	xpoint[0].x,
+	xpoint[0].y,
+	xpoint[1].x,
+	xpoint[1].y,
+	state->obj, state->objlast
+	);
+}
+
+/*
+ * icon have a default width of one char, placed centered
+ */
+
+static void
 process_icon(state, cp)
 	struct render_state *state;
 	struct ctrl *cp;
 {
 	u_int i, icon_type, icon_size, icon_x, icon_y, index;
+	u_int icon_height;
 	u_long tmp_color;
+	/*
+	 * if you define new icons, remember to also add
+	 * the case to the switch in obj_draw()
+	 */
 	static struct ctl_words icon_words[] = {
 		{ 1, 'x', "box", 3 },
 		{ 2, 'x', "arc", 3 },
@@ -2732,17 +2820,23 @@
 		{ 5, 'x', "delta3", 6 },
 		{ 6, 'x', "delta4", 6 },
 		{ 7, 'x', "dia", 3 },
+		{ 8, 'x', "rect", 4 },
+		{ 9, 'x', "frame", 5 },
 		{ 0, 'x', NULL, 0 }
 	};
-	XPoint xpoint[4];
+	XPoint xpoint[5];
 	static struct icon_point {
 		int	point_num;
-		XPoint xpoint[4];
-	} icon_point[] = {{ 3, {{1, 0}, {0, 2}, {2, 2}, {0, 0}}},
-			  { 3, {{0, 0}, {2, 0}, {1, 2}, {0, 0}}},
-			  { 3, {{0, 0}, {0, 2}, {2, 1}, {0, 0}}},
-			  { 3, {{2, 0}, {2, 2}, {0, 1}, {0, 0}}},
-			  { 4, {{1, 0}, {0, 1}, {1, 2}, {2, 1}}}};
+		XPoint xpoint[5];
+	} icon_point[] = {
+		{ 3, {{1, 0}, {0, 2}, {2, 2}, {0, 0}, {0,0}}},
+		{ 3, {{0, 0}, {2, 0}, {1, 2}, {0, 0}, {0,0}}},
+		{ 3, {{0, 0}, {0, 2}, {2, 1}, {0, 0}, {0,0}}},
+		{ 3, {{2, 0}, {2, 2}, {0, 1}, {0, 0}, {0,0}}},
+		{ 4, {{1, 0}, {0, 1}, {1, 2}, {2, 1}, {0,0}}},
+		{ 4, {{0, 0}, {0, 2}, {2, 2}, {2, 0}, {0,0}}},
+		{ 5, {{0, 0}, {0, 2}, {2, 2}, {2, 0}, {0,0}}},
+	};
 		
 	for (i = 0; icon_words[i].ctl_strlen != 0; i++) {
 		if (!strncasecmp(cp->ctic_value, icon_words[i].ctl_string,
@@ -2753,6 +2847,15 @@
 
 	icon_type = icon_words[i].ctl_type; /* may be 0 */
 	icon_size = char_size * cp->ctic_size / 100;
+	icon_height = icon_size ;
+	/*
+	 * this hack lets us define geometry as WWWHHH
+	 * for non-square icons.
+	 */
+	if (cp->ctic_size > 1000) {
+	    icon_size = char_size * cp->ctic_size / 100000 ;
+	    icon_height = char_size * (cp->ctic_size % 1000) / 100 ;
+	}
 
 	switch(icon_type){
 	case 0:
@@ -2771,7 +2874,8 @@
 		/* this is box */
 		obj_new_icon(state,
 			state->linewidth + char_size/2 - icon_size/2,
-			POSY(icon_size), icon_type, icon_size,
+			POSY(icon_height), icon_type, icon_size,
+			icon_height,
 			cp->ctic_color, 0, NULL);
 		state->linewidth += char_size;
 		break;
@@ -2781,6 +2885,7 @@
 		obj_new_icon(state,
 			state->linewidth + char_size/2 - icon_size/2,
 			POSY(icon_size), icon_type, icon_size, 
+			icon_height,
 			cp->ctic_color, 0, NULL);
 		state->linewidth += char_size;
 		break;
@@ -2790,10 +2895,19 @@
 	case 5:
 	case 6:
 	case 7:
+	case 8:
+	case 9:
+fprintf(stderr, "processing %s index %d size %dx%d\n", 
+	icon_words[i].ctl_string, icon_type, icon_size, icon_height);
+
 		index = icon_type - 3;
+		/* non-square icons are left-aligned */
+		if (icon_size != icon_height)
+		    icon_x = state->linewidth ;
+		else
 		icon_x = state->linewidth + (char_size - icon_size) / 2;
 #if 0
-		icon_y = POSY(icon_size);
+		icon_y = POSY(icon_height);
 #else
 		icon_y = 0;
 #endif
@@ -2801,11 +2915,13 @@
 			xpoint[i].x = icon_x +
 				icon_point[index].xpoint[i].x * icon_size / 2;
 			xpoint[i].y = icon_y +
-				icon_point[index].xpoint[i].y * icon_size / 2;
+				icon_point[index].xpoint[i].y * icon_height / 2;
 		}
 		obj_new_icon(state, 0, 0, icon_type, icon_size, 
+			icon_height,
 			cp->ctic_color, icon_point[index].point_num, xpoint);
-		state->linewidth += char_size;
+		state->linewidth += 
+			(char_size > icon_size) ? char_size : icon_size;
 		break;
 
 	default:
diff -ubwr kit/globals.c mgp-snap-981005/globals.c
--- kit/globals.c	Sat Sep 26 15:32:33 1998
+++ mgp-snap-981005/globals.c	Wed Oct  7 16:47:01 1998
@@ -71,6 +71,7 @@
 u_long fore_color;
 u_long back_color;
 u_long ctrl_color;
+u_long draw_linewidth;
 u_int b_quality = DEFAULT_BQUALITY;
 u_int quality_flag = 0;
 
@@ -130,5 +131,6 @@
 /*CTL*/	{ CTL_TFONT0,		T_STR,	"tfont0", 6 },
 /*CTL*/	{ CTL_EMBED,		T_STR,	"embed", 5 },
 /*CTL*/	{ CTL_ENDEMBED,		T_VOID,	"endembed", 8 },
+/*CTL*/	{ CTL_DRAW,		T_SP,	"draw", 4 },
 	{ 0, NULL, 0 },
 };
diff -ubwr kit/grammar.y mgp-snap-981005/grammar.y
--- kit/grammar.y	Sat Sep 26 15:32:34 1998
+++ mgp-snap-981005/grammar.y	Wed Oct  7 17:12:53 1998
@@ -350,6 +350,53 @@
 	return ct;
 }
 
+static struct _map {
+    drawcmds cmd;
+    char *name;
+} _draw_cmds[] = {
+    {DC_LINE, "line" },
+    {DC_BOX, "rect" },
+    {DC_RECT, "frame" },
+    {DC_NONE, NULL }
+} ;
+    
+static struct ctrl *
+gen_draw(n, color, x0, y0, x1, y1)
+	char *n;
+	char *color;
+	int x0, y0, x1, y1;
+{
+	struct ctrl *ct;
+	struct _map *p ;
+
+	if (!(ct = ctlalloc1(CTL_DRAW))) {
+		yyerror("cannot allocate node (op=DRAW)");
+		return ct;
+	}
+	for (p = _draw_cmds; p->cmd != DC_NONE ; p++)
+	    if (!strcmp(p->name, n))
+		break ;
+	if (p->cmd == DC_NONE) {
+	    yyerror("invalid draw cmd %s", n);
+	    return NULL ;
+	}
+	ct->ct_val.ctrl_drawcmd.cmd = p->cmd;
+	ct->ct_val.ctrl_drawcmd.x0 = x0;
+	ct->ct_val.ctrl_drawcmd.y0 = y0;
+	ct->ct_val.ctrl_drawcmd.x1 = x1;
+	ct->ct_val.ctrl_drawcmd.y1 = y1;
+fprintf(stderr, "draw %s %d %d %d %d\n",
+	p->name,
+	ct->ct_val.ctrl_drawcmd.x0,
+	ct->ct_val.ctrl_drawcmd.y0,
+	ct->ct_val.ctrl_drawcmd.x1,
+	ct->ct_val.ctrl_drawcmd.y1);
+
+	if (get_color(color, &ct->ct_val.ctrl_drawcmd.color) < 0)
+		yyerror("cannot allocate color %s", color);
+	return ct;
+}
+
 static struct ctrl *
 gen_icon(n, color, siz)
 	char *n;
@@ -516,6 +563,7 @@
 %token KW_LINESTART KW_LINEEND KW_MARK KW_SYSTEM KW_FILTER KW_ENDFILTER
 %token KW_QUALITY KW_ICON KW_LEFTFILL KW_XSYSTEM KW_VFCAP KW_TFONT KW_TFDIR
 %token KW_DEFFONT KW_FONT KW_TFONT0 KW_EMBED KW_ENDEMBED
+%token KW_DRAW
 
 %type <ct> toplevel
 %type <ct> line defaultline tabline shellline deffontline
@@ -691,6 +739,10 @@
 			{ $$ = gen_icon($2, $3, $4); }
 	| KW_ICON ID STRorID NUM
 			{ $$ = gen_icon($2, $3, $4); }
+	| KW_ICON STR STRorID NUM NUM NUM NUM
+			{ $$ = gen_draw($2, $3, $4, $5, $6, $7); }
+	| KW_ICON ID STRorID NUM NUM NUM NUM
+			{ $$ = gen_draw($2, $3, $4, $5, $6, $7); }
 	| KW_VFCAP STR	{
 #ifdef VFLIB
 			  $$ = gen_str(CTL_VFCAP, $2);
diff -ubwr kit/mgp.c mgp-snap-981005/mgp.c
--- kit/mgp.c	Thu Sep 24 13:47:58 1998
+++ mgp-snap-981005/mgp.c	Wed Oct  7 16:55:00 1998
@@ -1058,6 +1058,7 @@
 		XDrawLine(display, state->target, gcpen,
 			x, y,
 			rakugaki_x, rakugaki_y);
+#if 0
 		XDrawLine(display, state->target, gcpen,
 			x + 1, y,
 			rakugaki_x + 1, rakugaki_y);
@@ -1067,6 +1068,7 @@
 		XDrawLine(display, state->target, gcpen,
 			x + 1, y + 1,
 			rakugaki_x + 1, rakugaki_y + 1);
+#endif
 	}
 	rakugaki_x = x;
 	rakugaki_y = y;
diff -ubwr kit/mgp.h mgp-snap-981005/mgp.h
--- kit/mgp.h	Sat Sep 26 15:32:35 1998
+++ mgp-snap-981005/mgp.h	Wed Oct  7 17:10:09 1998
@@ -228,6 +228,18 @@
 	struct g_color **colors;
 };
 
+typedef enum drawcmds {
+   DC_NONE, DC_MOVETO, DC_LINETO, DC_LINE, DC_RECT, DC_BOX
+} drawcmds;
+
+struct ctrl_drawcmd {
+	drawcmds cmd;
+	u_long color ;
+	u_short width ;
+	u_short fill ;
+	short x0, y0, x1, y1 ;
+} ;
+
 struct ctrl_bar {
 	u_long ct_color;
 	u_int ct_width;
@@ -257,6 +269,7 @@
 		struct ctrl_bar ctrl_bar;
 		struct ctrl_args ctrl_args;
 		struct ctrl_icon ctrl_icon;
+		struct ctrl_drawcmd ctrl_drawcmd;
 	} ct_val;
 };
 
@@ -373,7 +386,8 @@
 #endif /* FREETYPE */
 		O_XFONT,
 		O_IMAGE,
-		O_ICON
+		O_ICON,
+		O_DRAW
 	} type;
 	u_long fore;
 	union {
@@ -399,6 +413,11 @@
 			u_int npoint;
 			XPoint *xpoint;
 		} icon;
+		struct {
+			drawcmds cmd ;
+			u_short x0, y0, x1, y1 ;
+		} draw ;
+
 	} data;
 };
 
@@ -492,6 +511,7 @@
 extern u_long fore_color;
 extern u_long back_color;
 extern u_long ctrl_color;
+extern u_long draw_linewidth;
 extern u_int b_quality;
 extern u_int quality_flag;
 
diff -ubwr kit/parse.c mgp-snap-981005/parse.c
--- kit/parse.c	Sat Sep 26 15:32:36 1998
+++ mgp-snap-981005/parse.c	Wed Oct  7 16:36:27 1998
@@ -963,7 +963,7 @@
 
 	/*
 	 * add CTL_LINEEND and CTL_LINESTART to each lines that contain
-	 * CTL_TEXT/CTL_IMAGE/CTL_BAR/CTL_ICON.
+	 * CTL_TEXT/CTL_IMAGE/CTL_BAR/CTL_ICON/CTL_DRAW.
 	 * note that we must carefully handle CTL_CONT.
 	 */
     {
@@ -979,6 +979,7 @@
 				if (cp->ct_op == CTL_TEXT
 				 || cp->ct_op == CTL_IMAGE
 				 || cp->ct_op == CTL_BAR
+				 || cp->ct_op == CTL_DRAW
 				 || cp->ct_op == CTL_ICON) {
 					textseen++;
 					break;
@@ -1010,6 +1011,7 @@
 					if ((*ch)->ct_op == CTL_TEXT
 					 || (*ch)->ct_op == CTL_IMAGE
 					 || (*ch)->ct_op == CTL_BAR
+					 || (*ch)->ct_op == CTL_DRAW
 					 || (*ch)->ct_op == CTL_ICON) {
 					    break;
 					}
@@ -1041,6 +1043,7 @@
 					if (cp1->ct_op == CTL_TEXT
 					 || cp1->ct_op == CTL_IMAGE
 					 || cp1->ct_op == CTL_BAR
+					 || cp1->ct_op == CTL_DRAW
 					 || cp1->ct_op == CTL_ICON) {
 					    cp2 = cp1;
 					}
@@ -1155,6 +1158,7 @@
 			for (cp = cp1; cp->ct_next; cp = cp->ct_next) {
 				if (cp->ct_next->ct_op == CTL_TEXT
 				 || cp->ct_next->ct_op == CTL_IMAGE
+				 || cp->ct_next->ct_op == CTL_DRAW
 				 || cp->ct_next->ct_op == CTL_ICON) {
 					break;
 				}
diff -ubwr kit/x11.c mgp-snap-981005/x11.c
--- kit/x11.c	Wed Aug 26 05:30:02 1998
+++ mgp-snap-981005/x11.c	Wed Oct  7 16:51:06 1998
@@ -153,6 +153,10 @@
 	ctrl_color = fore_color;
 
 	(void)get_color(back_clname, &back_color);
+	if (window_width < 400)
+	    draw_linewidth = 1 ;
+	else
+	    draw_linewidth = 2 ;
 }
 
 void
@@ -201,6 +205,8 @@
 			(void)get_color(pc->color, &color);
 			XSetForeground(display, *pc->gc, color);
 		}
+		XSetLineAttributes(display, *pc->gc,
+			draw_linewidth, LineSolid, CapRound, JoinRound);
 	}
 
  	if (mgp_flag & FL_OVER){