Silicon Graphics Indigo Magic Desktop icons are generated by compiling a file-type rules (FTR) file. Unlike most icons SGI icons are active objects, not passive bitmaps. An FTR file is used to define the behaviors that occur when an ICON is selected and manipulated. Each rule describes how a file of a particular type will appear within the Indigo Magic Desktop and defines what functions you can perform on the file by double-clicking on it or choosing menu items that manipulate it. A file-type rule also defines the method by which a file is given a type and how files of a particular type are to be printed.

What we are interested in here is that the icon geometry is VECTOR-based so that it can be easily scaled, and that the geometry descriptions are typically in a separate file that is included via an include directive in an FTR file. This permits the rules for the icon to be maintained separately from the geometry. This driver will generate the geometry section (an .fti file) of an FTR file.

The Indigo Magic User Interface Guidelines contains detailed instructions for creating icons. The following is a brief list of suggested style conventions to maintain when drawing icons:

Use the iconcolor, outlinecolor, and shadowcolor as your icons' typical colors. Be sparing with the use of other accenting colors. This will help preserve the impact of color when it is needed.

Create icons that maintain the overall 3-D feel that the basic Indigo Magic Desktop icons have. The Indigo Magic Desktop Integration Guide describes how to use iconsmith(1G) to draw icons in the proper perspective.

The generic executable and generic data file icons, supplied in /usr/lib/filetype/iconlib, establish extensible themes that you can work from to increase the user's ability to recognize your icons. Use ICON rules from the standard system and default FTR files as a background for your own unique representations.

SEE ALSO
This driver can be used to generate the file-type icon geometry files (*.fti). The SGI utility iconsmith(1) can subsequently be used to edit the files.

The following constants may be used in an icon description:

          true  false
The following icon color constants may be used in an icon description routine:
          iconcolor  outlinecolor  shadowcolor
These are standard colors used by the Indigo Magic Desktop for the icon, and their values change automatically depending on whether the icon is selected, opened, passed over by the mouse pointer (located), or otherwise manipulated. For example, iconcolor usually appears white onscreen. However, when the user selects an icon containing iconcolor, its iconcolor parts change from white to yellow. When some icon is dropped on an icon containing iconcolor, its iconcolor parts change from white to royal blue. Similarly, outlinecolor usually appears black and shadowcolor usually appears dark gray, but these colors change in response to the user's mouse events.

The icon description functions comprise, for the most part, a very restricted subset of the C-language version of the IRIS Graphics Library, modified for 2-D drawing. The valid icon description functions are:

Some empirical information from looking at example .fti files follow. Decimal numbers are expressed normally, but may not have a leading zero. The coordinates seem to be in the range 0-100 as decimals out to hundredths. Color values seem to range from 0 to 15, and then from -16 to -255.

arc(x,y,r,startang,endang)
Draw an arc starting at icon coordinates x,y, radius r, starting at angle startang, ending at angle endang. Angle measures are in tenths of degrees.
arcf(x,y,r,startang,endang)
Like arc, but filled with the current pen color.
bclos(color)
Like pclos (see below) but uses color for the border (outline) color of the polygon.
bgnclosedline()
Begin drawing a closed, unfilled figure drawn in the current pen color. Used in conjunction with vertex and endclosedline.
bgnline()
Like bgnclosedline, except the figure is not closed. Used in conjunction with vertex and endline.
bgnoutlinepolygon()
Begin drawing a polygon filled with the current pen color. The polygon is outlined with a color specified by endoutlinepolygon. Also used in conjunction with vertex.
bgnpoint()
Begin drawing a series of unconnected points defined using calls to vertex. Used in conjunction with vertex and endpoint.
bgnpolygon()
Like bgnoutlinepolygon except the polygon is not outlined. Used in conjunction with vertex and endpolygon.
color(n) Set the current pen color index to n.
draw(x,y)
Draw a line in the current color from the current pen location to x,y.
endclosedline()
Finishes a closed, unfilled figure started with bgnclosedline.
endline()
Finishes an open, unfilled figure started with bgnline.
endoutlinepolygon(color)
Finishes a filled polygon started with bgnoutlinepolygon and outlines it with color.
endpoint()
Finishes a series of points started with bgnpoint.
endpolygon()
Finishes a filled, unoutlined polygon started with bgnpolygon.
for(assignment;expr;assignment)
Standard C-language for-loop.
if(expr) expr [ else expr ]
Standard C-language if statement.
move(x,y) Move the current pen location to x,y.
pclos()
Draw a line in the current pen color that closes the current polygon, and fill the polygon with the current color.
pdr(x,y)
Draw the side of a filled polygon in the current pen color, from the current pen location to x,y.
pmv(x,y)
Begin a filled polygon at location x,y.
print(expr or string)
Print the value of the expression expr or string to stdout. Used for debugging icon programs.
vertex(x,y)
Specifies a coordinate used for drawing points, lines, and polygons by bgnpoint, bgnline, bgnpolygon, etc.
#ident "@(#)VOGLE:driver/fti.c - VOGLE driver for Silicon Graphics icon geometries ((.fti files)" #ident "@(#)VOGLE:author - John S. Urban" #ident "@(#)VOGLE:version - 1.0, Aug 1997" /* fti driver for vogle; Version 1.0, John S. Urban, Aug 1997 Please pass any upgrades or comments back to me if you get a chance. *-----------------------------------*-----------------------------* | Cray Research | urban@cray.com | | Silicon Graphics, Incorporated | urban@sgi.com | *-----------------------------------*-----------------------------* Next time in: o gather lines into polylines o option to have if between pages or put each page to a new file o maybe clear screen to current color should fill in a polygon background o maybe initialize with a standard template */ /******************************************************************************/ #include <stdio.h> #include <math.h> #include <stdlib.h> #include <string.h> #include "vogle.h" extern FILE *_voutfile(); extern FILE *fp; #define ABS(x) ((x) < 0 ? -(x) : (x)) #define MIN(x, y) ((x) < (y) ? (x) : (y)) static int GLOBAL_color = 0; static int GLOBAL_lastx = -1111111; static int GLOBAL_lasty = -1111111; /******************************************************************************/ static int FTI_color(int col){ /* change the current color */ /* Empirically found that color is from 0 to 15 inclusive else a negative value from -16 to -255 */ int icol; GLOBAL_color = ABS(col % 256) ; if(GLOBAL_color > 15 ){ icol=-GLOBAL_color; } else{ icol=GLOBAL_color; } switch(icol) { case 0: fprintf(fp,"color(iconcolor);\n"); break; case 7: fprintf(fp,"color(outlinecolor);\n"); break; default: fprintf(fp,"color(%d);\n",icol); /* Set current pen color index to n. */ } return(0); } /******************************************************************************/ static int FTI_init(void) { vdevice.sizeSy = 1000; vdevice.sizeSx = 1000; vdevice.sizeX = vdevice.sizeY = MIN(vdevice.sizeSy,vdevice.sizeSx); vdevice.depth = 1; fp = _voutfile(); GLOBAL_lastx = -1111111; GLOBAL_lasty = -1111111; (void) fprintf(fp,"#FTI\n"); /* magic number of a clear text FTI file */ (void) fprintf(fp,"# CREATOR: VOGLE FTI driver; version 1.0 1997/08/02\n"); /* FTI file can contain comment lines*/ (void) fprintf(fp,"# Version 1: 19970802, Author: John S. Urban\n"); fprintf(fp,"color(outlinecolor);\n"); return(1); } /******************************************************************************/ static int FTI_fill(int n, int x[], int y[]){ /* "fill" a polygon */ int i; fprintf(fp,"bgnpolygon();\n"); /* begin polygon */ for (i = 0; i < n; i++){ fprintf(fp," vertex(%f,%f);\n",x[i]/10.0,y[i]/10.0); /* draw outline across graphics array */ } fprintf(fp,"endpolygon();\n"); /* end polygon */ /* update current position */ GLOBAL_lastx = vdevice.cpVx = x[n - 1]; GLOBAL_lasty = vdevice.cpVy = y[n - 1]; return(UNUSED); } /******************************************************************************/ static int FTI_draw(int x,int y){ /* print the commands to draw a line from the current graphics position to (x, y). */ if (GLOBAL_lastx != vdevice.cpVx || GLOBAL_lasty != vdevice.cpVy){ GLOBAL_lastx=vdevice.cpVx; GLOBAL_lasty=vdevice.cpVy; fprintf(fp,"move(%f,%f);\n",GLOBAL_lastx/10.0,GLOBAL_lasty/10.0); } fprintf(fp,"draw(%f,%f);\n",x/10.0,y/10.0); return(UNUSED); } /*******************************************************************************/ static int FTI_exit(void){ /* exit from vogle printing the command to flush the buffer. */ fflush(fp); /* flush the output file */ if (fp != stdout && fp != stderr ){ (void) fprintf(fp,"# End of FTI File\n"); fflush(fp); if(vdevice.writestoprocess == 2){ pclose(fp); }else{ fclose(fp); } } return(UNUSED); } /*******************************************************************************/ static int FTI_clear(void){ /* flush current page and clear graphics array */ (void) fprintf(fp,"# End of FTI Page\n"); return(UNUSED); } /******************************************************************************/ static int FTI_font(char *font){ /* load in large or small */ fprintf(stderr, "error: NO HARDWARE FONT\n"); if (strcmp(font, "small") == 0) { vdevice.hwidth = 97.01; /* Size in plotter resolution units */ vdevice.hheight = vdevice.hwidth * 2.0; } else if (strcmp(font, "large") == 0) { vdevice.hwidth = 145.5; vdevice.hheight = vdevice.hwidth * 2.0; } else return(0); return(1); } /******************************************************************************/ static int FTI_string(char *s){ /* output a string. */ if (GLOBAL_lastx != vdevice.cpVx || GLOBAL_lasty != vdevice.cpVy){ GLOBAL_lastx=vdevice.cpVx; GLOBAL_lasty=vdevice.cpVy; } fprintf(fp,"# %s\n",s); GLOBAL_lastx = GLOBAL_lasty = -1111111; /* undefine current position because used hardware text ?*/ return(UNUSED); } /******************************************************************************/ int FTI_char(char c){ /* output a character */ char s[2]; s[0] = c; s[1]='\0'; FTI_string(s); return(UNUSED); } /******************************************************************************/ /* no operations - do nothing but return -1 */ static int noop(void) { return(-1); } static int noop1(int x) { return(-1); } static int noop2(int *x, int *y) { return(-1); } static int noop4(int a, int b, int c, int d) { return(-1); } /******************************************************************************/ static DevEntry FTIdev = { "FTI", /* name of device */ "large", /* name of large font */ "small", /* name of small font */ noop, /* Set drawing in back buffer */ FTI_char, /* Draw a hardware character */ noop, /* Check if a key was hit */ FTI_clear, /* Clear the screen to current color */ FTI_color, /* Set current color */ FTI_draw, /* Draw a line */ FTI_exit, /* Exit graphics */ FTI_fill, /* Fill a polygon */ FTI_font, /* Set hardware font */ noop, /* Set drawing in front buffer */ noop, /* Wait for and get the next key hit */ FTI_init, /* Initialize the device */ noop2, /* Get mouse/cross hair position */ noop4, /* Set color indices */ noop1, /* Set line thickness */ FTI_string, /* Draw a hardware string */ noop, /* Swap front and back buffers */ noop /* Syncronize the display */ }; /******************************************************************************/ int _FTI_devcpy(void) { vdevice.dev = FTIdev; vdevice.dev.Vinit = FTI_init; return(UNUSED); } /******************************************************************************/