Ilya Zakharevich on Mon, 11 Oct 1999 19:16:08 -0400 (EDT) |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
[PATCH 2.0.17] Device-independent graphic |
This patch: a) Adds optional arguments to plotcopy/plotdraw/plothsizes/plotinit/psdraw; These optional arguments allow one to make plots device-independently (sizes are given not in pixels, but in fractions of the screen size); b) The optional argument to psdraw() to inform it that the plotting is prepared device-independently. so psdraw() better rescale it to the expected size. Without this psdraw is almost useless with gnuplot output (since it assumes some undocumented hardwired sizes for plottings). c) Improves string-positioning logic to allow for vertical alignment and insertion of gaps between the point and the string. Now to annotate the rectangle of the plotting the same way as ploth() does you put strings *at the corners* specifying the gap positions: right-top-align +horizontal gap for 7, right-bottom-align +hor-gap +vert-gap for 5, left-top-align +vertical gap for -11 right-top-align +vertical gap for 567 ___________________________ 7 | | | | | | | | 5 ___________________________ -11 567 Summary: you delegate the complexity of putting strings in a device-independent way to PARI via optional arguments to plotstring(). d) What else? Some minor cleanups. like some functions using rectangles without first checking that they are initialized. Enjoy, Ilya P.S. I tested ps/gnuplot/X11 output. Could not compile sunview here: ../src/graph/plotsun.c:9: suntool/sunview.h: No such file or directory ../src/graph/plotsun.c:10: suntool/canvas.h: No such file or directory ../src/graph/plotsun.c:11: suntool/textsw.h: No such file or directory ../src/graph/plotsun.c:12: suntool/panel.h: No such file or directory I was find()ing 5 levels deep, but did not find any suntool (Solaris 7, cc: WorkShop Compilers 5.0 98/12/15 C 5.0). --- ./src/gp/highlvl.c.orig Mon Oct 11 18:19:15 1999 +++ ./src/gp/highlvl.c Mon Oct 11 18:19:33 1999 @@ -180,14 +180,14 @@ entree functions_highlevel[]={ {"plotbox",35,(void*)rectbox,10,"vLGG"}, {"plotclip",99,(void*)rectclip,10,"vL"}, {"plotcolor",19,(void*)rectcolor,10,"vLL"}, -{"plotcopy",99,(void*)rectcopy,10,"vLLLL"}, +{"plotcopy",99,(void*)rectcopy_gen,10,"vLLGGD0,L,"}, {"plotcursor",11,(void*)rectcursor,10,"L"}, -{"plotdraw",99,(void*)rectdraw,10,"vG"}, +{"plotdraw",99,(void*)rectdraw_flag,10,"vGD0,L,"}, {"plotfile",16,(void*)plot_outfile_set,10,"ls"}, {"ploth",99,(void*)ploth,10,"V=GGIpD0,L,D0,L,"}, {"plothraw",25,(void*)plothraw,10,"GGD0,L,"}, -{"plothsizes",0,(void*)plothsizes,10,""}, -{"plotinit",34,(void*)initrect,10,"vLLL"}, +{"plothsizes",0,(void*)plothsizes_flag,10,"D0,L,"}, +{"plotinit",34,(void*)initrect_gen,10,"vLD0,G,D0,G,D0,L,"}, {"plotkill",99,(void*)killrect,10,"vL"}, {"plotlines",99,(void*)rectlines,10,"vLGGD0,L,"}, {"plotlinetype",19,(void*)rectlinetype,10,"vLL"}, @@ -204,7 +204,7 @@ entree functions_highlevel[]={ {"plotscale",59,(void*)rectscale,10,"vLGGGG"}, {"plotstring",57,(void*)rectstring3,10,"vLsD0,L,"}, {"plotterm",16,(void*)term_set,10,"ls"}, -{"psdraw",99,(void*)postdraw,10,"vG"}, +{"psdraw",99,(void*)postdraw_flag,10,"vGD0,L,"}, {"psploth",99,(void*)postploth,10,"V=GGIpD0,L,D0,L,"}, {"psplothraw",25,(void*)postplothraw,10,"GGD0,L,"}, {"type",99,(void*)type0,11,"GD\"\",r,"}, @@ -220,14 +220,14 @@ char *helpmessages_highlevel[]={ "plotbox(w,x2,y2): if the cursor is at position (x1,y1), draw a box with diagonal (x1,y1) and (x2,y2) in rectwindow w (cursor does not move)", "plotclip(w): clip the contents of the rectwindow to the bounding box (except strings)", "plotcolor(w,c): in rectwindow w, set default color to c. Possible values for c are 1=black, 2=blue, 3=sienna, 4=red, 5=cornsilk, 6=grey, 7=gainsborough", - "plotcopy(sourcew,destw,dx,dy): copy the contents of rectwindow sourcew to rectwindow destw with offset (dx,dy)", + "plotcopy(sourcew,destw,dx,dy,{flag=0}): copy the contents of rectwindow sourcew to rectwindow destw with offset (dx,dy). If flag's bit 1 is set, dx and dy express fractions of the size of the current output device, otherwise dx and dy are in pixels. dx and dy are relative positions of northwest corners if other bits of flag vanish, otherwise of: 2: southwest, 4: southeast, 6: northeast corners", "plotcursor(w): current position of cursor in rectwindow w", - "plotdraw(list): draw vector of rectwindows list at indicated x,y positions; list is a vector w1,x1,y1,w2,x2,y2,etc. . ", + "plotdraw(list, {flag=0}): draw vector of rectwindows list at indicated x,y positions; list is a vector w1,x1,y1,w2,x2,y2,etc. . If flag!=0, x1, y1 etc. express fractions of the size of the current output device", "plotfile(filename): set the output file for plotting output. \"-\" redirects to the same place as PARI output", "ploth(X=a,b,expr,{flags=0},{n=0}): plot of expression expr, X goes from a to b in high resolution. Both flags and n are optional. Binary digits of flags mean : 1 parametric plot, 2 recursive plot, 8 omit x-axis, 16 omit y-axis, 32 omit frame, 64 do not join points, 128 plot both lines and points, 256 use cubic splines. n specifies number of reference points on the graph (0=use default value). Returns a vector for the bounding box", "plothraw(listx,listy,{flag=0}): plot in high resolution points whose x (resp. y) coordinates are in listx (resp. listy). If flag is non zero, join points", - "plothsizes(): returns array of 6 elements: terminal width and height, sizes for ticks in horizontal and vertical directions (in pixels), width and height of characters", - "plotinit(w,x,y): initialize rectwindow w to size x,y", + "plothsizes({flag=0}): returns array of 6 elements: terminal width and height, sizes for ticks in horizontal and vertical directions, width and height of characters. If flag=0, sizes of ticks and characters are in pixels, otherwise are fractions of the screen size", + "plotinit(w,{x=0},{y=0},{flag=0}): initialize rectwindow w to size x,y. If flag!=0, x and y express fractions of the size of the current output device. x=0 or y=0 means use the full size of the device", "plotkill(w): erase the rectwindow w", "plotlines(w,listx,listy,{flag=0}): draws an open polygon in rectwindow w where listx and listy contain the x (resp. y) coordinates of the vertices. If listx and listy are both single values (i.e not vectors), draw the corresponding line (and move cursor). If (optional) flag is non-zero, close the polygon", "plotlinetype(w,type): change the type of following lines in rectwindow w. type -2 corresponds to frames, -1 to axes, larger values may correspond to something else. w=-1 changes highlevel plotting", @@ -242,9 +242,9 @@ char *helpmessages_highlevel[]={ "plotrmove(w,dx,dy): move cursor to position (dx,dy) relative to the present position in the rectwindow w", "plotrpoint(w,dx,dy): draw a point (and move cursor) at position dx,dy relative to present position of the cursor in rectwindow w", "plotscale(w,x1,x2,y1,y2): scale the coordinates in rectwindow w so that x goes from x1 to x2 and y from y1 to y2 (y2<y1 is allowed)", - "plotstring(w,x,{flags=0}): draw in rectwindow w the string corresponding to x, justify left if flag is 0, right if it is 2, center if 1", - "plotterm(\"termname\"): set terminal to plot in high resolution to. Ignored by some drivers. In gnuplot driver possible terminals are the same as in gnuplot. Positive value means success", - "psdraw(list): same as plotdraw, except that the output is a postscript program in psfile (pari.ps by default)", + "plotstring(w,x,{flags=0}): draw in rectwindow w the string corresponding to x. Bits 1 and 2 of flag regulate horizontal alignment: left if 0, right if 2, center if 1. Bits 4 and 8 regulate vertical alignment: bottom if 0, top if 8, v-center if 4. Can insert additional gap between point and string: horizontal if bit 16 is set, vertical if bit 32 is set", + "plotterm(\"termname\"): set terminal to plot in high resolution to. Ignored by some drivers. In gnuplot driver possible terminals are the same as in gnuplot, terminal options can be put after the terminal name and space; terminal size can be put immediately after the name, as in \"gif=300,200\". If term is \"?\", lists possible values. Positive return value means success", + "psdraw(list, {flag=0}): same as plotdraw, except that the output is a postscript program in psfile (pari.ps by default), and flag!=0 scales the plot from size of the current output device to the standard postscript plotting size", "psploth(X=a,b,expr,{flags=0},{n=0}): same as ploth, except that the output is a postscript program in psfile (pari.ps by default)", "psplothraw(listx,listy,{flag=0}): same as plothraw, except that the output is a postscript program in psfile (pari.ps by default)", "type(x,{t}): if t is not present, output the type of the GEN x. Else make a copy of x with type t. Use with extreme care, usually with t = t_FRACN or t = t_RFRACN). Try \\t for a list of types", --- ./src/graph/plotgnuplot.c.orig Mon Oct 11 18:19:15 1999 +++ ./src/graph/plotgnuplot.c Mon Oct 11 18:19:34 1999 @@ -25,7 +25,7 @@ void rectdraw0(long *w, long *x, long *y, long lw, long do_free) { long *ptx,*pty; - long i,j,x0,y0; + long i,j,x0,y0, hjust, vjust, hgap, vgap, hgapsize, vgapsize; long good, seen_graph = 0; int point_type = -1, line_type = 0; PariRect *e; @@ -34,6 +34,9 @@ rectdraw0(long *w, long *x, long *y, lon PARI_get_plot(0); + hgapsize = h_unit; vgapsize = v_unit; + if (hgapsize == 1) + hgapsize = 2; /* Vertical direction is subjectively different! */ /* Find the info about the *actual* x and y-coords of the rectangles. Use the first rectangle with has_graph attribute. */ @@ -133,14 +136,23 @@ rectdraw0(long *w, long *x, long *y, lon } break; case ROt_ST: - if (strdir != RoSTdir(p1)) { - shift = (RoSTdir(p1) == RoSTdirLEFT ? 0 : - (RoSTdir(p1) == RoSTdirRIGHT ? 2 : 1)); - + hjust = RoSTdir(p1) & RoSTdirHPOS_mask; + vjust = RoSTdir(p1) & RoSTdirVPOS_mask; + hgap = RoSTdir(p1) & RoSTdirHGAP; + if (hgap) + hgap = (hjust == RoSTdirLEFT) ? hgapsize : -hgapsize; + vgap = RoSTdir(p1) & RoSTdirVGAP; + if (vgap) + vgap = (vjust == RoSTdirBOTTOM) ? vgapsize : -vgapsize; + if (vjust != RoSTdirVCENTER) + vgap += ((vjust == RoSTdirTOP) ? -1 : 1) * (f_height - 1)/2; + if (strdir != hjust) { + shift = (hjust == RoSTdirLEFT ? 0 : + (hjust == RoSTdirRIGHT ? 2 : 1)); can_justify = justify_text(shift); /* 1 for LEFT */ strdir = RoSTdir(p1); } - xstart = RoSTx(p1) + x0 + xstart = RoSTx(p1) + x0 + hgap - (can_justify ? 0 : ((RoSTl(p1) * pari_plot.fwidth - 1) * shift / 2)); xend = xstart + (can_justify ? 0 : RoSTl(p1) * pari_plot.fwidth - 1); @@ -148,7 +160,7 @@ rectdraw0(long *w, long *x, long *y, lon || RoSTy(p1) + y0 < 0 || RoSTy(p1) + y0 >= w_height) { } else { put_text(xstart, - w_height - 1 - RoSTy(p1) - y0 + (f_height - 1)/2, + w_height - 1 - RoSTy(p1) - y0 + vgap, RoSTs(p1)); } break; --- ./src/graph/plotport.c.orig Mon Oct 11 18:19:15 1999 +++ ./src/graph/plotport.c Mon Oct 11 18:19:34 1999 @@ -10,6 +10,7 @@ void push_val(entree *ep, GEN a); void pop_val(entree *ep); void postdraw0(long *w, long *x, long *y, long lw); +void postdraw00(long *w, long *x, long *y, long lw, long scale); void rectdraw0(long *w, long *x, long *y, long lw, long do_free); static void PARI_get_psplot(); @@ -213,6 +214,31 @@ check_rect_init(long ne) } void +initrect_gen(long ne, GEN x, GEN y, long flag) +{ + long xi, yi; + if (flag) { + double xd = gtodouble(x), yd = gtodouble(y); + + PARI_get_plot(0); + xi = w_width - 1; yi = w_height - 1; + if (xd) + xi = xd*xi + 0.5; + if (yd) + yi = yd*yi + 0.5; + } else { + xi = itos(x); yi = itos(y); + if (!xi || !yi) + PARI_get_plot(0); + if (!xi) + xi = w_width - 1; + if (!yi) + yi = w_height - 1; + } + initrect(ne, xi, yi); +} + +void initrect(long ne, long x, long y) { PariRect *e; @@ -647,6 +673,40 @@ rectlinetype(long ne, long type) } void +rectcopy_gen(long source, long dest, GEN xoff, GEN yoff, long flag) +{ + long xi, yi; + if (flag & RECT_CP_RELATIVE) { + double xd = gtodouble(xoff), yd = gtodouble(yoff); + + PARI_get_plot(0); + xi = w_width - 1; yi = w_height - 1; + xi = xd*xi + 0.5; + yi = yd*yi + 0.5; + } else { + xi = itos(xoff); yi = itos(yoff); + } + if (flag & ~RECT_CP_RELATIVE) { + PariRect *s = check_rect_init(source), *d = check_rect_init(dest); + + switch (flag & ~RECT_CP_RELATIVE) { + case RECT_CP_NW: + break; + case RECT_CP_SW: + yi = RYsize(d) - RYsize(s) - yi; + break; + case RECT_CP_SE: + yi = RYsize(d) - RYsize(s) - yi; + /* FALL THROUGH */ + case RECT_CP_NE: + xi = RXsize(d) - RXsize(s) - xi; + break; + } + } + rectcopy(source, dest, xi, yi); +} + +void rectcopy(long source, long dest, long xoff, long yoff) { PariRect *s = check_rect_init(source), *d = check_rect_init(dest); @@ -1509,12 +1569,14 @@ rectplothrawin(long stringrect, long dra rectlinetype(stringrect,-2); /* Frame */ current_color[stringrect]=BLACK; - put_string(stringrect, lm - gap, W.fheight - 1, c1, RoSTdirRIGHT); - put_string(stringrect, lm - gap, W.height - (bm+ 2 * W.vunit), c2, RoSTdirRIGHT); - put_string(stringrect, lm, W.height - bm + W.fheight - 1, - c3, RoSTdirLEFT); - put_string(stringrect, W.width - rm - 1, W.height - bm + W.fheight - 1, - c4, RoSTdirRIGHT); + put_string( stringrect, lm, 0, c1, + RoSTdirRIGHT | RoSTdirHGAP | RoSTdirTOP); + put_string(stringrect, lm, W.height - bm, c2, + RoSTdirRIGHT | RoSTdirHGAP | RoSTdirVGAP); + put_string(stringrect, lm, W.height - bm, c3, + RoSTdirLEFT | RoSTdirTOP); + put_string(stringrect, W.width - rm - 1, W.height - bm, c4, + RoSTdirRIGHT | RoSTdirTOP); if (flags & PLOT_POSTSCRIPT) postdraw0(w,wx,wy,2); @@ -1635,14 +1697,28 @@ postploth2(entree *ep, GEN a, GEN b, cha GEN plothsizes() { + return plothsizes_flag(0); +} + +GEN +plothsizes_flag(long flag) +{ GEN vect = cgetg(1+6,t_VEC); int i; PARI_get_plot(0); - for (i=1; i<7; i++) vect[i]=lgeti(3); + for (i=1; i<=2; i++) vect[i]=lgeti(3); affsi(w_width,(GEN)vect[1]); affsi(w_height,(GEN)vect[2]); - affsi(h_unit, (GEN)vect[3]); affsi(v_unit, (GEN)vect[4]); - affsi(f_width,(GEN)vect[5]); affsi(f_height,(GEN)vect[6]); + if (flag) { + vect[3] = (long)dbltor(h_unit*1.0/w_width); + vect[4] = (long)dbltor(v_unit*1.0/w_height); + vect[5] = (long)dbltor(f_width*1.0/w_width); + vect[6] = (long)dbltor(f_height*1.0/w_height); + } else { + for (; i <= 6; i++) vect[i]=lgeti(3); + affsi(h_unit, (GEN)vect[3]); affsi(v_unit, (GEN)vect[4]); + affsi(f_width,(GEN)vect[5]); affsi(f_height,(GEN)vect[6]); + } return vect; } @@ -1681,7 +1757,7 @@ PARI_get_psplot() } static void -gendraw(GEN list,long ps) +gendraw(GEN list, long ps, long flag) { long i,n,ne,*w,*x,*y; GEN x0,y0,win; @@ -1693,23 +1769,42 @@ gendraw(GEN list,long ps) w = (long*)gpmalloc(n*sizeof(long)); x = (long*)gpmalloc(n*sizeof(long)); y = (long*)gpmalloc(n*sizeof(long)); + if (flag) + PARI_get_plot(0); for (i=0; i<n; i++) { win=(GEN)list[3*i+1]; x0=(GEN)list[3*i+2]; y0=(GEN)list[3*i+3]; - if (typ(win)!=t_INT || typ(x0)!=t_INT || typ(y0)!= t_INT) + if (typ(win)!=t_INT || (!flag && (typ(x0)!=t_INT || typ(y0)!= t_INT))) err(talker, "not an integer type in rectdraw"); + if (flag) { + double xd = gtodouble(x0), yd = gtodouble(y0); + long xi, yi; + + xi = w_width - 1; yi = w_height - 1; + xi = xd*xi + 0.5; + yi = yd*yi + 0.5; + x[i] = xi; y[i] = yi; + } else { + x[i]=itos(x0); y[i]=itos(y0); + } ne=itos(win); check_rect(ne); - x[i]=itos(x0); y[i]=itos(y0); w[i]=ne; + w[i]=ne; } - if (ps) postdraw0(w,x,y,n); else rectdraw0(w,x,y,n, 1); + if (ps) postdraw00(w,x,y,n,flag); else rectdraw0(w,x,y,n, 1); free(x); free(y); free(w); } void -postdraw(GEN list) { gendraw(list,1); } +postdraw(GEN list) { gendraw(list, 1, 0); } + +void +rectdraw(GEN list) { gendraw(list, 0, 0); } void -rectdraw(GEN list) { gendraw(list,0); } +postdraw_flag(GEN list, long flag) { gendraw(list, 1, flag); } + +void +rectdraw_flag(GEN list, long flag) { gendraw(list, 0, flag); } static char* zmalloc(size_t x) @@ -1720,6 +1815,12 @@ zmalloc(size_t x) void postdraw0(long *w, long *x, long *y, long lw) { + postdraw00(w, x, y, lw, 0); +} + +void +postdraw00(long *w, long *x, long *y, long lw, long scale) +{ long *ptx,*pty,*numpoints,*numtexts,*xtexts,*ytexts,*dirtexts; RectObj *p1; PariRect *e; @@ -1727,11 +1828,25 @@ postdraw0(long *w, long *x, long *y, lon long a,b,c,d,nd[ROt_MAX+1]; char **texts; FILE *psfile; + double xscale = 0.65, yscale = 0.65; + long fontsize = 16, xtick = 5, ytick = 5; SPoint *points, **lines, *SLine; SSegment *seg; SRectangle *rect, SRec; + if (scale) { + double termxsize, termysize, postxsize, postysize; + + PARI_get_psplot(); + postxsize = pari_psplot.width; + postysize = pari_psplot.height; + PARI_get_plot(0); + xscale *= pari_psplot.width * 1.0/w_width; + fontsize = fontsize/(pari_psplot.width * 1.0/w_width); + yscale *= pari_psplot.height * 1.0/w_height; + xtick = h_unit; ytick = v_unit; + } psfile = fopen(current_psfile, "a"); if (!psfile) err(openfiler,"postscript",current_psfile); @@ -1740,7 +1855,7 @@ postdraw0(long *w, long *x, long *y, lon for (i=0; i<lw; i++) { - e=rectgraph[w[i]]; p1=RHead(e); + e = check_rect_init(w[i]); p1=RHead(e); while (p1) { if (RoType(p1) != ROt_MP) nd[RoType(p1)]++; @@ -1814,8 +1929,18 @@ postdraw0(long *w, long *x, long *y, lon } } /* Definitions taken from post terminal of Gnuplot. */ - fprintf(psfile,"%%!\n50 50 translate\n/Times-Roman findfont 16 scalefont setfont\n0.65 0.65 scale\n"); + fprintf(psfile,"%%!\n50 50 translate\n/Times-Roman findfont %ld scalefont setfont\n%g %g scale\n", fontsize, yscale,xscale); fprintf(psfile,"/Lshow { moveto 90 rotate show -90 rotate } def\n/Rshow { 3 -1 roll dup 4 1 roll stringwidth pop sub Lshow } def\n/Cshow { 3 -1 roll dup 4 1 roll stringwidth pop 2 div sub Lshow } def\n"); + fprintf(psfile,"/Xgap %ld def\n/Ygap %ld def\n", xtick, ytick); + fprintf(psfile,"/Bbox { gsave newpath 0 0 moveto true charpath pathbbox grestore } def\n"); + fprintf(psfile,"/Height { Bbox 4 1 roll pop pop pop } def\n"); + fprintf(psfile,"/TopAt { 3 -1 roll dup 4 1 roll Height 3 -1 roll add exch } def\n"); + fprintf(psfile,"/VCenter { 3 -1 roll dup 4 1 roll Height 2 div 3 -1 roll add exch } def\n"); + fprintf(psfile,"/Tgap { exch Ygap add exch } def\n"); + fprintf(psfile,"/Bgap { exch Ygap sub exch } def\n"); + fprintf(psfile,"/Lgap { Xgap add } def\n"); + fprintf(psfile,"/Rgap { Xgap sub } def\n"); + for (i=0; i<nd[ROt_PT]; i++) ps_point(psfile,points[i].x,points[i].y); for (i=0; i<nd[ROt_LN]; i++) @@ -1875,7 +2000,16 @@ ps_string(FILE *psfile, int x, int y, ch } } else fprintf(psfile,"(%s", s); - fprintf(psfile,") %d %d %sshow\n", - y, x, - (dir == RoSTdirLEFT ? "L" : (dir == RoSTdirRIGHT ? "R" : "C"))); + fprintf(psfile,") %d %d %s%s%s%sshow\n", + y, x, + ((dir & RoSTdirVGAP) + ? ((dir & RoSTdirVPOS_mask) == RoSTdirTOP ? "Tgap " : "Bgap ") + : ""), + ((dir & RoSTdirHGAP) + ? ((dir & RoSTdirHPOS_mask) == RoSTdirRIGHT ? "Rgap " : "Lgap ") + : ""), + ((dir & RoSTdirVPOS_mask) == RoSTdirBOTTOM ? "" + : (dir & RoSTdirVPOS_mask) == RoSTdirTOP ? "TopAt " : "VCenter "), + ((dir & RoSTdirHPOS_mask) == RoSTdirLEFT ? "L" + : ((dir & RoSTdirHPOS_mask) == RoSTdirRIGHT ? "R" : "C"))); } --- ./src/graph/plotsun.c.orig Mon Oct 11 18:19:15 1999 +++ ./src/graph/plotsun.c Mon Oct 11 18:28:28 1999 @@ -23,7 +23,7 @@ rectdraw0(long *w, long *x, long *y, lon { long *ptx,*pty,*numpoints,*numtexts,*xtexts,*ytexts; long n,i,j,x0,y0,shift; - long a,b,c,d,ne; + long a,b,c,d,ne, hjust, vjust, hgap, vgap, hgapsize, vgapsize; long rcnt[ROt_MAX+1]; char **texts; PariRect *e; @@ -42,6 +42,7 @@ rectdraw0(long *w, long *x, long *y, lon /* child process goes on */ freeall(); /* PARI stack isn't needed anymore, keep rectgraph */ PARI_get_plot(1); + hgapsize = h_unit; vgapsize = v_unit; rcnt[ROt_MV]=rcnt[ROt_PT]=rcnt[ROt_LN]=0; rcnt[ROt_BX]=rcnt[ROt_MP]=rcnt[ROt_ML]=0; @@ -110,12 +111,22 @@ rectdraw0(long *w, long *x, long *y, lon } rcnt[ROt_ML]++;break; case ROt_ST: + hjust = RoSTdir(p1) & RoSTdirHPOS_mask; + vjust = RoSTdir(p1) & RoSTdirVPOS_mask; + hgap = RoSTdir(p1) & RoSTdirHGAP; + if (hgap) + hgap = (hjust == RoSTdirLEFT) ? hgapsize : -hgapsize; + vgap = RoSTdir(p1) & RoSTdirVGAP; + if (vgap) + vgap = (vjust == RoSTdirBOTTOM) ? 2*vgapsize : -2*vgapsize; + if (vjust != RoSTdirBOTTOM) + vgap -= ((vjust == RoSTdirTOP) ? 2 : 1)*(f_height - 1); texts[rcnt[ROt_ST]]=RoSTs(p1); numtexts[rcnt[ROt_ST]]=RoSTl(p1); - shift = (RoSTdir(p1) == RoSTdirLEFT ? 0 : - (RoSTdir(p1) == RoSTdirRIGHT ? 2 : 1)); - xtexts[rcnt[ROt_ST]]=RoSTx(p1)+x0 + shift = (hjust == RoSTdirLEFT ? 0 : + (hjust == RoSTdirRIGHT ? 2 : 1)); + xtexts[rcnt[ROt_ST]]=RoSTx(p1)+x0+hgap - (strlen(RoSTs(p1)) * pari_plot.fwidth * shift)/2; - ytexts[rcnt[ROt_ST]]=RoSTy(p1)+y0; + ytexts[rcnt[ROt_ST]]=RoSTy(p1)+y0-vgap/2; rcnt[ROt_ST]++;break; default: break; } --- ./src/graph/plotX.c.orig Mon Oct 11 18:19:15 1999 +++ ./src/graph/plotX.c Mon Oct 11 18:25:19 1999 @@ -121,7 +121,7 @@ rectdraw0(long *w, long *x, long *y, lon long *xtexts[MAX_COLORS],*ytexts[MAX_COLORS]; long rcolcnt[MAX_COLORS][ROt_MAX]; long col,i,j,x0,y0,a,b,oldwidth,oldheight,force; - long rcnt[ROt_MAX+1]; + long rcnt[ROt_MAX+1], hjust, vjust, hgap, vgap, hgapsize, vgapsize; char **texts[MAX_COLORS]; PariRect *e; RectObj *p1; @@ -148,6 +148,7 @@ rectdraw0(long *w, long *x, long *y, lon display = XOpenDisplay(NULL); font_info = XLoadQueryFont(display, "9x15"); if (!font_info) exiterr("cannot open 9x15 font"); + hgapsize = h_unit; vgapsize = v_unit; XSetErrorHandler(Xerror); XSetIOErrorHandler(IOerror); @@ -316,15 +317,25 @@ rectdraw0(long *w, long *x, long *y, lon } c[ROt_ML]++;break; case ROt_ST: + hjust = RoSTdir(p1) & RoSTdirHPOS_mask; + vjust = RoSTdir(p1) & RoSTdirVPOS_mask; + hgap = RoSTdir(p1) & RoSTdirHGAP; + if (hgap) + hgap = (hjust == RoSTdirLEFT) ? hgapsize : -hgapsize; + vgap = RoSTdir(p1) & RoSTdirVGAP; + if (vgap) + vgap = (vjust == RoSTdirBOTTOM) ? 2*vgapsize : -2*vgapsize; + if (vjust != RoSTdirBOTTOM) + vgap -= ((vjust == RoSTdirTOP) ? 2 : 1)*(f_height - 1); texts[col][c[ROt_ST]]=RoSTs(p1); numtexts[col][c[ROt_ST]]=RoSTl(p1); - shift = (RoSTdir(p1) == RoSTdirLEFT ? 0 : - (RoSTdir(p1) == RoSTdirRIGHT ? 2 : 1)); + shift = (hjust == RoSTdirLEFT ? 0 : + (hjust == RoSTdirRIGHT ? 2 : 1)); xtexts[col][c[ROt_ST]] - = (long)(( RoSTx(p1) + x0 + = (long)(( RoSTx(p1) + x0 + hgap - (strlen(RoSTs(p1)) * pari_plot.fwidth * shift)/2)*xs); - ytexts[col][c[ROt_ST]]= (long)((RoSTy(p1)+y0)*ys); + ytexts[col][c[ROt_ST]]= (long)((RoSTy(p1)+y0-vgap/2)*ys); c[ROt_ST]++;break; default: break; } --- ./src/graph/rect.h.orig Mon Oct 11 18:19:16 1999 +++ ./src/graph/rect.h Mon Oct 11 18:19:34 1999 @@ -173,9 +173,19 @@ typedef struct RectObjPS { #define RoSTy(rop) (RoST(rop)->y) #define RoSTdir(rop) (RoST(rop)->dir) -#define RoSTdirLEFT 0 -#define RoSTdirCENTER 1 -#define RoSTdirRIGHT 2 +#define RoSTdirLEFT 0x00 +#define RoSTdirCENTER 0x01 +#define RoSTdirRIGHT 0x02 +#define RoSTdirHPOS_mask 0x03 + +#define RoSTdirBOTTOM 0x00 +#define RoSTdirVCENTER 0x04 +#define RoSTdirTOP 0x08 +#define RoSTdirVPOS_mask 0x0c + +#define RoSTdirHGAP 0x10 +#define RoSTdirVGAP 0x20 + #define RoPTTpen(rop) (RoPTT(rop)->pen) #define RoLNTpen(rop) (RoLNT(rop)->pen) @@ -197,6 +207,12 @@ typedef struct RectObjPS { #define PLOT_POSTSCRIPT 0x80000 +#define RECT_CP_RELATIVE 0x1 +#define RECT_CP_NW 0x0 +#define RECT_CP_SW 0x2 +#define RECT_CP_SE 0x4 +#define RECT_CP_NE 0x6 + extern PariRect **rectgraph; extern long rectpoint_itype; extern long rectline_itype; @@ -204,6 +220,7 @@ extern long rectline_itype; /* plotport.c */ void initrect(long ne, long x, long y); +void initrect_gen(long ne, GEN x, GEN y, long flag); void killrect(long ne); void plot(entree *ep, GEN a, GEN b, char *ch, long prec); GEN ploth(entree *ep, GEN a, GEN b, char *ch, long prec, long flag, long numpoints); @@ -211,15 +228,19 @@ GEN ploth2(entree *ep, GEN a, GEN b, GEN plothmult(entree *ep, GEN a, GEN b, char *ch, long prec); GEN plothraw(GEN listx, GEN listy, long flag); GEN plothsizes(); +GEN plothsizes_flag(long flag); void postdraw(GEN list); +void postdraw_flag(GEN list, long flag); GEN postploth(entree *ep,GEN a,GEN b,char *ch,long prec,long flag,long numpoints); GEN postploth2(entree *ep,GEN a,GEN b,char *ch,long prec,long numpoints); GEN postplothraw(GEN listx, GEN listy, long flag); void rectbox(long ne, GEN gx2, GEN gy2); void rectcolor(long ne, long color); void rectcopy(long source, long dest, long xoff, long yoff); +void rectcopy_gen(long source, long dest, GEN xoff, GEN yoff, long flag); GEN rectcursor(long ne); void rectdraw(GEN list); +void rectdraw_flag(GEN list, long flag); void rectline(long ne, GEN gx2, GEN gy2); void rectlines(long ne, GEN listx, GEN listy, long flag); void rectlinetype(long ne, long t);