lib/browserGfx.c

Go to the documentation of this file.
00001 /* Browser graphics - stuff for drawing graphics displays that
00002  * are reasonably browser (human and intronerator) specific. */
00003 
00004 #include "common.h"
00005 #include "memgfx.h"
00006 #include "vGfx.h"
00007 #include "browserGfx.h"
00008 
00009 static char const rcsid[] = "$Id: browserGfx.c,v 1.8 2006/05/08 09:43:31 aamp Exp $";
00010 
00011 
00012 static long figureTickSpan(long totalLength, int maxNumTicks)
00013 /* Figure out whether ticks on ruler should be 1, 5, 10, 50, 100, 500, 
00014  * 1000, etc. units apart.  */
00015 {
00016 int roughTickLen = totalLength/maxNumTicks;
00017 int i;
00018 int tickLen = 1;
00019 
00020 for (i=0; i<9; ++i)
00021     {
00022     if (roughTickLen < tickLen)
00023         return tickLen;
00024     tickLen *= 5;
00025     if (roughTickLen < tickLen)
00026         return tickLen;
00027     tickLen *= 2;
00028     }
00029 return 1000000000;
00030 }
00031 
00032 static void numLabelString(int num, char *label)
00033 /* Returns a numerical labeling string. */
00034 {
00035 char *sign = "";
00036 if (num < 0)
00037     {
00038     num = -num;
00039     sign = "-";
00040     }
00041 sprintf(label, "%s%d", sign, num);
00042 }
00043 
00044 
00045 void vgDrawRulerBumpText(struct vGfx *vg, int xOff, int yOff, 
00046         int height, int width,
00047         Color color, MgFont *font,
00048         int startNum, int range, int bumpX, int bumpY)
00049 /* Draw a ruler inside the indicated part of mg with numbers that start at
00050  * startNum and span range.  Bump text positions slightly. */
00051 {
00052 int tickSpan;
00053 int tickPos;
00054 double scale;
00055 int firstTick;
00056 int remainder;
00057 int end = startNum + range;
00058 int x;
00059 char tbuf[14];
00060 int numWid;
00061 int goodNumTicks;
00062 int niceNumTicks = width/35;
00063 
00064 numLabelString(startNum+range, tbuf);
00065 numWid = mgFontStringWidth(font, tbuf)+4+bumpX;
00066 goodNumTicks = width/numWid;
00067 if (goodNumTicks < 1) goodNumTicks = 1;
00068 if (goodNumTicks > niceNumTicks) goodNumTicks = niceNumTicks;
00069 
00070 tickSpan = figureTickSpan(range, goodNumTicks);
00071 
00072 scale = (double)width / range;
00073 
00074 firstTick = startNum + tickSpan;
00075 remainder = firstTick % tickSpan;
00076 firstTick -= remainder;
00077 for (tickPos=firstTick; tickPos<end; tickPos += tickSpan)
00078     {
00079     numLabelString(tickPos, tbuf);
00080     numWid = mgFontStringWidth(font, tbuf)+4;
00081     x = (int)((tickPos-startNum) * scale) + xOff;
00082     vgBox(vg, x, yOff, 1, height, color);
00083     if (x - numWid >= xOff)
00084         {
00085         vgTextCentered(vg, x-numWid + bumpX, yOff + bumpY, numWid, 
00086             height, color, font, tbuf);
00087         }
00088     }
00089 }
00090 
00091 void vgDrawRuler(struct vGfx *vg, int xOff, int yOff, int height, int width,
00092         Color color, MgFont *font,
00093         int startNum, int range)
00094 /* Draw a ruler inside the indicated part of mg with numbers that start at
00095  * startNum and span range.  */
00096 {
00097 vgDrawRulerBumpText(vg, xOff, yOff, height, width, color, font,
00098     startNum, range, 0, 0);
00099 }
00100 
00101 
00102 void vgBarbedHorizontalLine(struct vGfx *vg, int x, int y, 
00103         int width, int barbHeight, int barbSpacing, int barbDir, Color color,
00104         boolean needDrawMiddle)
00105 /* Draw a horizontal line starting at xOff, yOff of given width.  Will
00106  * put barbs (successive arrowheads) to indicate direction of line.  
00107  * BarbDir of 1 points barbs to right, of -1 points them to left. */
00108 {
00109 int x1, x2;
00110 int yHi, yLo;
00111 int offset, startOffset, endOffset, barbAdd;
00112 int scrOff = (barbSpacing - 1) - (x % (barbSpacing));
00113 
00114 yHi = y + barbHeight;
00115 yLo = y - barbHeight;
00116 if (barbDir < 0)
00117     {
00118     startOffset = scrOff - barbHeight;
00119     startOffset = (startOffset >= 0) ?startOffset : 0;
00120     endOffset = width - barbHeight;
00121     barbAdd = barbHeight;
00122     }
00123 else
00124     {
00125     startOffset = scrOff + barbHeight;
00126     endOffset = width;
00127     barbAdd = -barbHeight;
00128     }
00129 
00130 for (offset = startOffset; offset < endOffset; offset += barbSpacing)
00131     {
00132     x1 = x + offset;
00133     x2 = x1 + barbAdd;
00134     vgLine(vg, x1, y, x2, yHi, color);
00135     vgLine(vg, x1, y, x2, yLo, color);
00136     }
00137 }
00138 
00139 void vgNextItemButton(struct vGfx *vg, int x, int y, int w, int h, 
00140                       Color color, Color bgColor, boolean nextItem)
00141 /* Draw a button that looks like a fast-forward or rewind button on */
00142 /* a remote control. If nextItem is TRUE, it points right, otherwise */
00143 /* left. color is the outline color, and bgColor is the fill color. */
00144 {
00145 struct gfxPoly *t1, *t2;
00146 /* Make the triangles */
00147 t1 = gfxPolyNew();
00148 t2 = gfxPolyNew();
00149 if (nextItem)
00150     /* point right. */
00151     {
00152     gfxPolyAddPoint(t1, x, y);
00153     gfxPolyAddPoint(t1, x+w/2, y+h/2);
00154     gfxPolyAddPoint(t1, x, y+h);
00155     gfxPolyAddPoint(t2, x+w/2, y);
00156     gfxPolyAddPoint(t2, x+w, y+h/2);
00157     gfxPolyAddPoint(t2, x+w/2, y+h);    
00158     }
00159 else
00160     /* point left. */
00161     {
00162     gfxPolyAddPoint(t1, x, y+h/2);
00163     gfxPolyAddPoint(t1, x+w/2, y);
00164     gfxPolyAddPoint(t1, x+w/2, y+h);
00165     gfxPolyAddPoint(t2, x+w/2, y+h/2);
00166     gfxPolyAddPoint(t2, x+w, y);
00167     gfxPolyAddPoint(t2, x+w, y+h);
00168     }
00169 /* The two filled triangles. */
00170 vgDrawPoly(vg, t1, bgColor, TRUE);
00171 vgDrawPoly(vg, t2, bgColor, TRUE);
00172 /* The two outline triangles. */
00173 vgDrawPoly(vg, t1, color, FALSE);
00174 vgDrawPoly(vg, t2, color, FALSE);
00175 gfxPolyFree(&t1);
00176 gfxPolyFree(&t2);
00177 }

Generated on Tue Dec 25 18:39:30 2007 for blat by  doxygen 1.5.2