summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:53 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:53 +0000
commit961d4493f519b5b093581e111997f894b1675d48 (patch)
treea1aca760da761709d3cc83c37db8e9f3128d2e93
R6.6 is the Xorg base-lineXORG-MAINXORG-STABLE
-rw-r--r--Xfd.ad29
-rw-r--r--grid.c555
-rw-r--r--grid.h85
-rw-r--r--gridP.h83
-rw-r--r--xfd.c402
-rw-r--r--xfd.man187
6 files changed, 1341 insertions, 0 deletions
diff --git a/Xfd.ad b/Xfd.ad
new file mode 100644
index 0000000..b90c5c2
--- /dev/null
+++ b/Xfd.ad
@@ -0,0 +1,29 @@
+! $Xorg: Xfd.ad,v 1.3 2000/08/17 19:54:18 cpqbld Exp $
+*internalBorderWidth: 0
+*showGrip: false
+
+*grid.borderWidth: 0
+
+*quit.Label: Quit
+*prev.Label: Prev Page
+*next.Label: Next Page
+
+*select.Label: Select a character
+*metrics.Label:
+*select.Justify: center
+*metrics.Justify: center
+*range.Justify: left
+*start.Justify: left
+
+*quit.Translations: #override \
+ <Btn1Down>,<Btn1Up>: Quit() unset()
+*next.Translations: #override \
+ <Btn1Down>,<Btn1Up>: Next() unset()
+*prev.Translations: #override \
+ <Btn1Down>,<Btn1Up>: Prev() unset()
+
+*Translations: #override \n\
+<Key>q: Quit()\n\
+Ctrl <Key>n: Next()\n\
+Ctrl <Key>p: Prev()
+
diff --git a/grid.c b/grid.c
new file mode 100644
index 0000000..7d41f3d
--- /dev/null
+++ b/grid.c
@@ -0,0 +1,555 @@
+/*
+ * $Xorg: grid.c,v 1.4 2001/02/09 02:05:41 xorgcvs Exp $
+ *
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * *
+ * Author: Jim Fulton, MIT X Consortium
+ */
+
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/Xaw/SimpleP.h>
+#include <X11/Xmu/Converters.h>
+#include "gridP.h"
+
+#ifdef XKB
+#include <X11/extensions/XKBbells.h>
+#else
+#define XkbBI_MinorError 2
+#define XkbBI_Ignore 11
+#endif
+
+#ifdef XKB
+#define Bell(w,n) XkbStdBell(XtDisplay(w), XtWindow(w), 50, n)
+#else
+#define Bell(w,n) XBell(XtDisplay(w), 0)
+#endif
+
+
+static void ClassInitialize(), Initialize(), Realize(), Redisplay(), Notify();
+static void Destroy(), Resize(), paint_grid();
+static Boolean SetValues();
+
+#define Offset(field) XtOffsetOf(FontGridRec, fontgrid.field)
+
+static XtResource resources[] = {
+ { XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
+ Offset(text_font), XtRString, (XtPointer) NULL },
+ { XtNcellColumns, XtCCellColumns, XtRInt, sizeof(int),
+ Offset(cell_cols), XtRImmediate, (XtPointer) 0 },
+ { XtNcellRows, XtCCellRows, XtRInt, sizeof(int),
+ Offset(cell_rows), XtRImmediate, (XtPointer) 0 },
+ { XtNcellWidth, XtCCellWidth, XtRInt, sizeof(int),
+ Offset(cell_width), XtRImmediate, (XtPointer) 0 },
+ { XtNcellHeight, XtCCellHeight, XtRInt, sizeof(int),
+ Offset(cell_height), XtRImmediate, (XtPointer) 0 },
+ { XtNstartChar, XtCStartChar, XtRDimension, sizeof(Dimension),
+ Offset(start_char), XtRImmediate, (XtPointer) 0xffff },
+ { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
+ Offset(foreground_pixel), XtRString, (XtPointer) XtDefaultForeground },
+ { XtNcenterChars, XtCCenterChars, XtRBoolean, sizeof(Boolean),
+ Offset(center_chars), XtRImmediate, (XtPointer) FALSE },
+ { XtNboxChars, XtCBoxChars, XtRBoolean, sizeof(Boolean),
+ Offset(box_chars), XtRImmediate, (XtPointer) FALSE },
+ { XtNboxColor, XtCForeground, XtRPixel, sizeof(Pixel),
+ Offset(box_pixel), XtRString, (XtPointer) XtDefaultForeground },
+ { XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
+ Offset(callbacks), XtRCallback, (XtPointer) NULL },
+ { XtNinternalPad, XtCInternalPad, XtRInt, sizeof(int),
+ Offset(internal_pad), XtRImmediate, (XtPointer) 4 },
+ { XtNgridWidth, XtCGridWidth, XtRInt, sizeof(int),
+ Offset(grid_width), XtRImmediate, (XtPointer) 1 },
+};
+
+#undef Offset
+
+static char defaultTranslations[] =
+ "<ButtonPress>: notify()";
+
+static XtActionsRec actions_list[] = {
+ { "notify", Notify },
+};
+
+FontGridClassRec fontgridClassRec = {
+ { /* core fields */
+ /* superclass */ (WidgetClass) &simpleClassRec,
+ /* class_name */ "FontGrid",
+ /* widget_size */ sizeof(FontGridRec),
+ /* class_initialize */ ClassInitialize,
+ /* class_part_initialize */ NULL,
+ /* class_inited */ FALSE,
+ /* initialize */ Initialize,
+ /* initialize_hook */ NULL,
+ /* realize */ Realize,
+ /* actions */ actions_list,
+ /* num_actions */ XtNumber(actions_list),
+ /* resources */ resources,
+ /* num_resources */ XtNumber(resources),
+ /* xrm_class */ NULLQUARK,
+ /* compress_motion */ TRUE,
+ /* compress_exposure */ TRUE,
+ /* compress_enterleave */ TRUE,
+ /* visible_interest */ FALSE,
+ /* destroy */ Destroy,
+ /* resize */ Resize,
+ /* expose */ Redisplay,
+ /* set_values */ SetValues,
+ /* set_values_hook */ NULL,
+ /* set_values_almost */ XtInheritSetValuesAlmost,
+ /* get_values_hook */ NULL,
+ /* accept_focus */ NULL,
+ /* version */ XtVersion,
+ /* callback_private */ NULL,
+ /* tm_table */ defaultTranslations,
+ /* query_geometry */ XtInheritQueryGeometry,
+ /* display_accelerator */ XtInheritDisplayAccelerator,
+ /* extension */ NULL
+ },
+ { /* simple fields */
+ /* change_sensitive */ XtInheritChangeSensitive
+ }
+};
+
+WidgetClass fontgridWidgetClass = (WidgetClass) &fontgridClassRec;
+
+
+/*
+ * public routines
+ */
+
+void GetFontGridCellDimensions (w, startp, ncolsp, nrowsp)
+ Widget w;
+ Dimension *startp;
+ int *ncolsp, *nrowsp;
+{
+ FontGridWidget fgw = (FontGridWidget) w;
+ *startp = (long)fgw->fontgrid.start_char;
+ *ncolsp = fgw->fontgrid.cell_cols;
+ *nrowsp = fgw->fontgrid.cell_rows;
+}
+
+
+void GetPrevNextStates (w, prevvalidp, nextvalidp)
+ Widget w;
+ Bool *prevvalidp, *nextvalidp;
+{
+ FontGridWidget fgw = (FontGridWidget) w;
+
+ XFontStruct *fs = fgw->fontgrid.text_font;
+ long minn = (long) ((fs->min_byte1 << 0) | fs->min_char_or_byte2);
+ long maxn = (long) ((fs->max_byte1 << 8) | fs->max_char_or_byte2);
+
+ *prevvalidp = ((long)fgw->fontgrid.start_char > minn);
+ *nextvalidp = (((long)fgw->fontgrid.start_char +
+ (fgw->fontgrid.cell_cols * fgw->fontgrid.cell_rows))
+ < maxn);
+}
+
+
+
+/*
+ * private routines and methods
+ */
+
+
+static GC get_gc (fgw, fore)
+ FontGridWidget fgw;
+ Pixel fore;
+{
+ XtGCMask mask;
+ XGCValues gcv;
+
+ mask = (GCForeground | GCBackground | GCFunction | GCFont);
+ gcv.foreground = fore;
+ gcv.background = fgw->core.background_pixel;
+ gcv.function = GXcopy;
+ gcv.font = fgw->fontgrid.text_font->fid;
+ gcv.cap_style = CapProjecting;
+ mask |= GCCapStyle;
+ if (fgw->fontgrid.grid_width > 0) {
+ mask |= GCLineWidth;
+ gcv.line_width = ((fgw->fontgrid.grid_width < 2) ? 0 :
+ fgw->fontgrid.grid_width);
+ }
+ return (XtGetGC ((Widget) fgw, mask, &gcv));
+}
+
+
+static void ClassInitialize ()
+{
+ XtAddConverter (XtRString, XtRLong, XmuCvtStringToLong, NULL, 0);
+}
+
+
+static void Initialize (request, new, args, num_args)
+ Widget request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ FontGridWidget reqfg = (FontGridWidget) request;
+ FontGridWidget newfg = (FontGridWidget) new;
+ XFontStruct *fs = newfg->fontgrid.text_font;
+ unsigned maxn;
+
+ if (reqfg->fontgrid.cell_cols <= 0)
+ newfg->fontgrid.cell_cols = 16;
+
+ if (reqfg->fontgrid.cell_rows <= 0) {
+ if (fs && fs->max_byte1 == 0) {
+ newfg->fontgrid.cell_rows = (fs->max_char_or_byte2 /
+ newfg->fontgrid.cell_cols) + 1;
+ if (newfg->fontgrid.cell_rows > 16)
+ newfg->fontgrid.cell_rows = 16;
+ } else
+ newfg->fontgrid.cell_rows = 16;
+ }
+
+ if (reqfg->fontgrid.cell_width <= 0)
+ newfg->fontgrid.cell_width = (fs ? DefaultCellWidth (newfg) : 1);
+ if (reqfg->fontgrid.cell_height <= 0)
+ newfg->fontgrid.cell_height = (fs ? DefaultCellHeight (newfg) : 1);
+
+ /* give a nice size that fits one screen full */
+ if (newfg->core.width == 0)
+ newfg->core.width = (newfg->fontgrid.cell_width *
+ newfg->fontgrid.cell_cols +
+ newfg->fontgrid.grid_width *
+ (newfg->fontgrid.cell_cols + 1));
+
+ if (newfg->core.height == 0)
+ newfg->core.height = (newfg->fontgrid.cell_height *
+ newfg->fontgrid.cell_rows +
+ newfg->fontgrid.grid_width *
+ (newfg->fontgrid.cell_rows + 1));
+
+ /*
+ * select the first character
+ */
+
+ if (newfg->fontgrid.start_char == 0xffff) {
+ newfg->fontgrid.start_char = (fs ? (unsigned)(fs->min_byte1 << 8) : 0);
+ }
+ if (fs) {
+ maxn = ((fs->max_byte1 << 8) | fs->max_char_or_byte2);
+ if (newfg->fontgrid.start_char > maxn)
+ newfg->fontgrid.start_char = (maxn + 1 -
+ (newfg->fontgrid.cell_cols *
+ newfg->fontgrid.cell_rows));
+ }
+}
+
+static void Realize (gw, valueMask, attributes)
+ Widget gw;
+ Mask *valueMask;
+ XSetWindowAttributes *attributes;
+{
+ FontGridWidget fgw = (FontGridWidget) gw;
+ FontGridPart *p = &fgw->fontgrid;
+
+ p->text_gc = get_gc (fgw, p->foreground_pixel);
+ p->box_gc = get_gc (fgw, p->box_pixel);
+ Resize (gw);
+
+ (*(XtSuperclass(gw)->core_class.realize)) (gw, valueMask, attributes);
+ return;
+}
+
+
+
+static void Destroy (gw)
+ Widget gw;
+{
+ FontGridWidget fgw = (FontGridWidget) gw;
+
+ XtReleaseGC (gw, fgw->fontgrid.text_gc);
+ XtReleaseGC (gw, fgw->fontgrid.box_gc);
+}
+
+
+static void Resize (gw)
+ Widget gw;
+{
+ FontGridWidget fgw = (FontGridWidget) gw;
+
+ /* recompute in case we've changed size */
+ fgw->fontgrid.cell_width = CellWidth (fgw);
+ if (fgw->fontgrid.cell_width <= 0)
+ fgw->fontgrid.cell_width = 1;
+ fgw->fontgrid.cell_height = CellHeight (fgw);
+ if (fgw->fontgrid.cell_height <= 0)
+ fgw->fontgrid.cell_height = 1;
+ fgw->fontgrid.xoff = (fgw->fontgrid.cell_width -
+ DefaultCellWidth (fgw)) / 2;
+ fgw->fontgrid.yoff = (fgw->fontgrid.cell_height -
+ DefaultCellHeight (fgw)) / 2;
+
+}
+
+
+/* ARGSUSED */
+static void Redisplay (gw, event, region)
+ Widget gw;
+ XEvent *event;
+ Region region;
+{
+ FontGridWidget fgw = (FontGridWidget) gw;
+ XRectangle rect; /* bounding rect for region */
+ int left, right, top, bottom; /* which cells were damaged */
+ int cw, ch; /* cell size */
+
+ if (!fgw->fontgrid.text_font) {
+ Bell (gw, XkbBI_BadValue);
+ return;
+ }
+
+ /*
+ * compute the left, right, top, and bottom cells that were damaged
+ */
+ XClipBox (region, &rect);
+ cw = fgw->fontgrid.cell_width + fgw->fontgrid.grid_width;
+ ch = fgw->fontgrid.cell_height + fgw->fontgrid.grid_width;
+ if ((left = (((int) rect.x) / cw)) < 0) left = 0;
+ right = (((int) (rect.x + rect.width - 1)) / cw);
+ if ((top = (((int) rect.y) / ch)) < 0) top = 0;
+ bottom = (((int) (rect.y + rect.height - 1)) / ch);
+
+ paint_grid (fgw, left, top, right - left + 1, bottom - top + 1);
+}
+
+
+static void paint_grid (fgw, col, row, ncols, nrows)
+ FontGridWidget fgw; /* widget in which to draw */
+ int col, row; /* where to start */
+ int ncols, nrows; /* number of cells */
+{
+ FontGridPart *p = &fgw->fontgrid;
+ int i, j;
+ Display *dpy = XtDisplay(fgw);
+ Window wind = XtWindow(fgw);
+ int cw = p->cell_width + p->grid_width;
+ int ch = p->cell_height + p->grid_width;
+ int tcols = p->cell_cols;
+ int trows = p->cell_rows;
+ int x1, y1, x2, y2, x, y;
+ unsigned maxn = ((p->text_font->max_byte1 << 8) |
+ p->text_font->max_char_or_byte2);
+ unsigned n, prevn;
+ int startx;
+
+ if (col + ncols >= tcols) {
+ ncols = tcols - col;
+ if (ncols < 1) return;
+ }
+
+ if (row + nrows >= trows) {
+ nrows = trows - row;
+ if (nrows < 1) return;
+ }
+
+ /*
+ * paint the grid lines for the indicated rows
+ */
+ if (p->grid_width > 0) {
+ int half_grid_width = p->grid_width >> 1;
+ x1 = col * cw + half_grid_width;
+ y1 = row * ch + half_grid_width;
+ x2 = x1 + ncols * cw;
+ y2 = y1 + nrows * ch;
+ for (i = 0, x = x1; i <= ncols; i++, x += cw) {
+ XDrawLine (dpy, wind, p->box_gc, x, y1, x, y2);
+ }
+ for (i = 0, y = y1; i <= nrows; i++, y += ch) {
+ XDrawLine (dpy, wind, p->box_gc, x1, y, x2, y);
+ }
+ }
+
+
+ /*
+ * Draw a character in every box; treat all fonts as if they were 16bit
+ * fonts. Store the high eight bits in byte1 and the low eight bits in
+ * byte2.
+ */
+ prevn = p->start_char + col + row * tcols;
+ startx = col * cw + p->internal_pad + p->grid_width;
+ for (j = 0,
+ y = row * ch + p->internal_pad + p->grid_width + p->text_font->ascent;
+ j < nrows; j++, y += ch) {
+ n = prevn;
+ for (i = 0, x = startx; i < ncols; i++, x += cw) {
+ XChar2b thechar;
+ int xoff = p->xoff, yoff = p->yoff;
+
+ if (n > maxn) goto done; /* no break out of nested */
+
+ thechar.byte1 = (n >> 8); /* high eight bits */
+ thechar.byte2 = (n & 255); /* low eight bits */
+ if (p->box_chars || p->center_chars) {
+ XCharStruct metrics;
+ int direction, fontascent, fontdescent;
+
+ XTextExtents16 (p->text_font, &thechar, 1, &direction,
+ &fontascent, &fontdescent, &metrics);
+
+ if (p->center_chars) {
+ /*
+ * We want to move the origin by enough to center the ink
+ * within the cell. The left edge will then be at
+ * (cell_width - (rbearing - lbearing)) / 2; so we subtract
+ * the lbearing to find the origin. Ditto for vertical.
+ */
+ xoff = (((p->cell_width -
+ (metrics.rbearing - metrics.lbearing)) / 2) -
+ p->internal_pad - metrics.lbearing);
+ yoff = (((p->cell_height -
+ (metrics.descent + metrics.ascent)) / 2) -
+ p->internal_pad -
+ p->text_font->ascent + metrics.ascent);
+ }
+ if (p->box_chars) {
+ XDrawRectangle (dpy, wind, p->box_gc,
+ x + xoff, y + yoff - p->text_font->ascent,
+ metrics.width - 1,
+ fontascent + fontdescent - 1);
+ }
+ }
+ XDrawString16 (dpy, wind, p->text_gc, x + xoff, y + yoff,
+ &thechar, 1);
+ n++;
+ }
+ prevn += tcols;
+ }
+
+ done:
+ return;
+}
+
+/*ARGSUSED*/
+static Boolean SetValues (current, request, new, args, num_args)
+ Widget current, request, new;
+ ArgList args;
+ Cardinal *num_args;
+{
+ FontGridWidget curfg = (FontGridWidget) current;
+ FontGridWidget newfg = (FontGridWidget) new;
+ Boolean redisplay = FALSE;
+
+ if (curfg->fontgrid.text_font != newfg->fontgrid.text_font ||
+ curfg->fontgrid.internal_pad != newfg->fontgrid.internal_pad) {
+ newfg->fontgrid.cell_width = DefaultCellWidth (newfg);
+ newfg->fontgrid.cell_height = DefaultCellHeight (newfg);
+ redisplay = TRUE;
+ }
+
+ if (curfg->fontgrid.foreground_pixel != newfg->fontgrid.foreground_pixel) {
+ XtReleaseGC (new, curfg->fontgrid.text_gc);
+ newfg->fontgrid.text_gc = get_gc (newfg,
+ newfg->fontgrid.foreground_pixel);
+ redisplay = TRUE;
+ }
+
+ if (curfg->fontgrid.box_pixel != newfg->fontgrid.box_pixel) {
+ XtReleaseGC (new, curfg->fontgrid.text_gc);
+ newfg->fontgrid.box_gc = get_gc (newfg, newfg->fontgrid.box_pixel);
+ redisplay = TRUE;
+ }
+
+ if (curfg->fontgrid.center_chars != newfg->fontgrid.center_chars ||
+ curfg->fontgrid.box_chars != newfg->fontgrid.box_chars)
+ redisplay = TRUE;
+
+ if (curfg->fontgrid.start_char != newfg->fontgrid.start_char) {
+ XFontStruct *fs = newfg->fontgrid.text_font;
+ unsigned maxn = ((fs->max_byte1 << 8) | fs->max_char_or_byte2);
+
+ if (newfg->fontgrid.start_char > maxn)
+ newfg->fontgrid.start_char = (maxn + 1 -
+ (newfg->fontgrid.cell_cols *
+ newfg->fontgrid.cell_rows));
+
+ redisplay = (curfg->fontgrid.start_char != newfg->fontgrid.start_char);
+ }
+
+ return redisplay;
+}
+
+
+/* ARGSUSED */
+static void Notify (gw, event, params, nparams)
+ Widget gw;
+ XEvent *event;
+ String *params;
+ Cardinal *nparams;
+{
+ FontGridWidget fgw = (FontGridWidget) gw;
+ int x, y; /* where the event happened */
+ FontGridCharRec rec; /* callback data */
+
+ /*
+ * only allow events with (x,y)
+ */
+ switch (event->type) {
+ case KeyPress:
+ case KeyRelease:
+ x = event->xkey.x;
+ y = event->xkey.y;
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ x = event->xbutton.x;
+ y = event->xbutton.y;
+ break;
+ case MotionNotify:
+ x = event->xmotion.x;
+ y = event->xmotion.y;
+ break;
+ default:
+ Bell (gw, XkbBI_Ignore);
+ return;
+ }
+
+ /*
+ * compute the callback data
+ */
+ {
+ int cw = fgw->fontgrid.cell_width + fgw->fontgrid.grid_width;
+ int ch = fgw->fontgrid.cell_height + fgw->fontgrid.grid_width;
+ unsigned n;
+
+ if (x > (fgw->fontgrid.cell_cols * cw)) {
+ Bell (gw, XkbBI_InvalidLocation);
+ return;
+ }
+
+ n= (fgw->fontgrid.start_char +
+ ((y / ch) * fgw->fontgrid.cell_cols) + (x / cw));
+
+ rec.thefont = fgw->fontgrid.text_font;
+ rec.thechar.byte1 = (n >> 8);
+ rec.thechar.byte2 = (n & 255);
+ }
+
+ XtCallCallbacks (gw, XtNcallback, (XtPointer) &rec);
+}
+
diff --git a/grid.h b/grid.h
new file mode 100644
index 0000000..8cadafc
--- /dev/null
+++ b/grid.h
@@ -0,0 +1,85 @@
+/* $Xorg: grid.h,v 1.4 2001/02/09 02:05:41 xorgcvs Exp $ */
+/*
+
+Copyright 1993, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#ifndef _FontGrid_h_
+#define _FontGrid_h_
+
+typedef struct _FontGridRec *FontGridWidget;
+extern WidgetClass fontgridWidgetClass;
+
+#define XtNcellRows "cellRows"
+#define XtCCellRows "CellRows"
+#define XtNcellColumns "cellColumns"
+#define XtCCellColumns "CellColumns"
+#define XtNcellWidth "cellWidth"
+#define XtCCellWidth "CellWidth"
+#define XtNcellHeight "cellHeight"
+#define XtCCellHeight "CellHeight"
+
+#define XtNcenterChars "centerChars"
+#define XtCCenterChars "CenterChars"
+
+#define XtNboxChars "boxChars"
+#define XtCBoxChars "BoxChars"
+
+#define XtNboxColor "boxColor"
+#define XtCBoxColor "BoxColor"
+
+#define XtNstartChar "startChar"
+#define XtCStartChar "StartChar"
+
+#define XtNinternalPad "internalPad"
+#define XtCInternalPad "InternalPad"
+
+#define XtNgridWidth "gridWidth"
+#define XtCGridWidth "GridWidth"
+
+typedef struct _FontGridCharRec {
+ XFontStruct * thefont;
+ XChar2b thechar;
+} FontGridCharRec;
+
+extern void GetFontGridCellDimensions(
+#if NeedFunctionPrototypes
+ Widget,
+ Dimension *,
+ int *,
+ int *
+#endif
+);
+
+extern void GetPrevNextStates(
+#if NeedFunctionPrototypes
+ Widget,
+ Bool *,
+ Bool *
+#endif
+);
+
+#endif /* _FontGrid_h_ */
diff --git a/gridP.h b/gridP.h
new file mode 100644
index 0000000..9a4b8cb
--- /dev/null
+++ b/gridP.h
@@ -0,0 +1,83 @@
+/* $Xorg: gridP.h,v 1.4 2001/02/09 02:05:41 xorgcvs Exp $ */
+/*
+
+Copyright 1993, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+
+#ifndef _FontGridP_h_
+#define _FontGridP_h_
+
+#include "grid.h"
+
+typedef struct _FontGridClassPart { int dummy; } FontGridClassPart;
+
+typedef struct _FontGridClassRec {
+ CoreClassPart core_class;
+ SimpleClassPart simple_class;
+ FontGridClassPart grid_class;
+} FontGridClassRec;
+extern FontGridClassRec fontgridClassRec;
+
+typedef struct _FontGridPart {
+ XFontStruct * text_font; /* font to display */
+ int cell_cols, cell_rows; /* number of cells */
+ int cell_width, cell_height; /* size of cell */
+ Pixel foreground_pixel; /* color of text */
+ Pixel box_pixel; /* for box_chars */
+ Boolean center_chars; /* center characters in grid */
+ Boolean box_chars; /* put box around logical width */
+ XtCallbackList callbacks; /* for notifying caller */
+ int internal_pad; /* extra padding inside grid */
+ Dimension start_char; /* first character of grid */
+ int grid_width; /* width of grid lines */
+ /* private data */
+ GC text_gc; /* printing text */
+ GC box_gc; /* for box_chars */
+ int xoff, yoff; /* extra offsets within grid */
+} FontGridPart;
+
+typedef struct _FontGridRec {
+ CorePart core;
+ SimplePart simple;
+ FontGridPart fontgrid;
+} FontGridRec;
+
+#define DefaultCellWidth(fgw) (((fgw)->fontgrid.text_font->max_bounds.width) \
+ + ((fgw)->fontgrid.internal_pad * 2))
+#define DefaultCellHeight(fgw) ((fgw)->fontgrid.text_font->ascent + \
+ (fgw)->fontgrid.text_font->descent + \
+ ((fgw)->fontgrid.internal_pad * 2))
+
+
+#define CellWidth(fgw) (((int)(fgw)->core.width - (fgw)->fontgrid.grid_width) \
+ / (fgw)->fontgrid.cell_cols \
+ - (fgw)->fontgrid.grid_width)
+#define CellHeight(fgw) (((int)(fgw)->core.height - (fgw)->fontgrid.grid_width)\
+ / (fgw)->fontgrid.cell_rows \
+ - (fgw)->fontgrid.grid_width)
+
+#endif /* !_FontGridP_h_ */
diff --git a/xfd.c b/xfd.c
new file mode 100644
index 0000000..27eb0c0
--- /dev/null
+++ b/xfd.c
@@ -0,0 +1,402 @@
+/*
+ * $Xorg: xfd.c,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $
+ *
+ *
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * *
+ * Author: Jim Fulton, MIT X Consortium
+ */
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+#include <X11/Shell.h>
+#include <X11/Xaw/Cardinals.h>
+#include <X11/Xaw/Paned.h>
+#include <X11/Xaw/Box.h>
+#include <X11/Xaw/Form.h>
+#include <X11/Xaw/Command.h>
+#include <stdio.h>
+#include "grid.h"
+
+char *ProgramName;
+
+static XrmOptionDescRec xfd_options[] = {
+{"-fn", "*grid.font", XrmoptionSepArg, (caddr_t) NULL },
+{"-start", "*startChar", XrmoptionSepArg, (caddr_t) NULL },
+{"-box", "*grid.boxChars", XrmoptionNoArg, (caddr_t) "on" },
+{"-bc", "*grid.boxColor", XrmoptionSepArg, (caddr_t) NULL },
+{"-center", "*grid.centerChars", XrmoptionNoArg, (caddr_t) "on" },
+{"-rows", "*grid.cellRows", XrmoptionSepArg, (caddr_t) NULL },
+{"-columns", "*grid.cellColumns", XrmoptionSepArg, (caddr_t) NULL },
+};
+
+static void do_quit(), do_next(), do_prev();
+static void change_page (), set_button_state ();
+static char *get_font_name();
+static void SelectChar();
+
+static XtActionsRec xfd_actions[] = {
+ { "Quit", do_quit },
+ { "Prev", do_prev },
+ { "Next", do_next },
+};
+
+static Atom wm_delete_window;
+
+Widget quitButton, prevButton, nextButton;
+
+
+#define DEF_SELECT_FORMAT "character 0x%02x%02x (%u,%u) (%#o,%#o)"
+#define DEF_METRICS_FORMAT "width %d; left %d, right %d; ascent %d, descent %d (font %d, %d)"
+#define DEF_RANGE_FORMAT "range: 0x%02x%02x (%u,%u) thru 0x%02x%02x (%u,%u)"
+#define DEF_START_FORMAT "upper left: 0x%04x (%d,%d)"
+#define DEF_NOCHAR_FORMAT "no such character 0x%02x%02x (%u,%u) (%#o,%#o)"
+
+static struct _xfd_resources {
+ char *select_format;
+ char *metrics_format;
+ char *range_format;
+ char *start_format;
+ char *nochar_format;
+} xfd_resources;
+
+#define Offset(field) XtOffsetOf(struct _xfd_resources, field)
+
+static XtResource Resources[] = {
+ { "selectFormat", "SelectFormat", XtRString, sizeof(char *),
+ Offset(select_format), XtRString, DEF_SELECT_FORMAT },
+ { "metricsFormat", "MetricsFormat", XtRString, sizeof(char *),
+ Offset(metrics_format), XtRString, DEF_METRICS_FORMAT },
+ { "rangeFormat", "RangeFormat", XtRString, sizeof(char *),
+ Offset(range_format), XtRString, DEF_RANGE_FORMAT },
+ { "startFormat", "StartFormat", XtRString, sizeof(char *),
+ Offset(start_format), XtRString, DEF_START_FORMAT },
+ { "nocharFormat", "NocharFormat", XtRString, sizeof(char *),
+ Offset(nochar_format), XtRString, DEF_NOCHAR_FORMAT },
+};
+
+#undef Offset
+
+usage()
+{
+ fprintf (stderr, "usage: %s [-options ...] -fn font\n\n", ProgramName);
+ fprintf (stderr, "where options include:\n");
+ fprintf (stderr,
+ " -display dpy X server to contact\n");
+ fprintf (stderr,
+ " -geometry geom size and location of window\n");
+ fprintf (stderr,
+ " -start num first character to show\n");
+ fprintf (stderr,
+ " -box show a box around each character\n");
+ fprintf (stderr,
+ " -center center each character inside its grid\n");
+ fprintf (stderr,
+ " -rows number number of rows in grid\n");
+ fprintf (stderr,
+ " -columns number number of columns in grid\n");
+ fprintf (stderr, "\n");
+ exit (1);
+}
+
+
+static Widget selectLabel, metricsLabel, rangeLabel, startLabel, fontGrid;
+
+static Boolean fontConversionFailed = False;
+static void (*oldWarningHandler)();
+static void CatchFontConversionWarning();
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ XtAppContext xtcontext;
+ Widget toplevel, pane, toplabel, box, form;
+ char buf[256];
+ Arg av[10];
+ Cardinal i;
+ static XtCallbackRec cb[2] = { { SelectChar, NULL }, { NULL, NULL } };
+ XFontStruct *fs;
+ char *fontname;
+
+ ProgramName = argv[0];
+
+ toplevel = XtAppInitialize (&xtcontext, "Xfd",
+ xfd_options, XtNumber(xfd_options),
+ &argc, argv, NULL, NULL, 0);
+ if (argc != 1) usage ();
+ XtAppAddActions (xtcontext, xfd_actions, XtNumber (xfd_actions));
+ XtOverrideTranslations
+ (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
+
+ XtGetApplicationResources (toplevel, (XtPointer) &xfd_resources, Resources,
+ XtNumber (Resources), NULL, ZERO);
+
+
+ /* pane wrapping everything */
+ pane = XtCreateManagedWidget ("pane", panedWidgetClass, toplevel,
+ NULL, ZERO);
+
+ /* font name */
+ toplabel = XtCreateManagedWidget ("fontname", labelWidgetClass, pane,
+ NULL, ZERO);
+
+ /* button box */
+ box = XtCreateManagedWidget ("box", boxWidgetClass, pane, NULL, ZERO);
+ quitButton = XtCreateManagedWidget ("quit", commandWidgetClass, box,
+ NULL, ZERO);
+ prevButton = XtCreateManagedWidget ("prev", commandWidgetClass, box,
+ NULL, ZERO);
+ nextButton = XtCreateManagedWidget ("next", commandWidgetClass, box,
+ NULL, ZERO);
+
+
+ /* and labels in which to put information */
+ selectLabel = XtCreateManagedWidget ("select", labelWidgetClass,
+ pane, NULL, ZERO);
+
+ metricsLabel = XtCreateManagedWidget ("metrics", labelWidgetClass,
+ pane, NULL, ZERO);
+
+ rangeLabel = XtCreateManagedWidget ("range", labelWidgetClass, pane,
+ NULL, ZERO);
+
+ startLabel = XtCreateManagedWidget ("start", labelWidgetClass, pane,
+ NULL, ZERO);
+
+ /* form in which to draw */
+ form = XtCreateManagedWidget ("form", formWidgetClass, pane, NULL, ZERO);
+
+ i = 0;
+ XtSetArg (av[i], XtNtop, XtChainTop); i++;
+ XtSetArg (av[i], XtNbottom, XtChainBottom); i++;
+ XtSetArg (av[i], XtNleft, XtChainLeft); i++;
+ XtSetArg (av[i], XtNright, XtChainRight); i++;
+ XtSetArg (av[i], XtNcallback, cb); i++;
+
+ oldWarningHandler = XtAppSetWarningMsgHandler(xtcontext,
+ CatchFontConversionWarning);
+
+ fontGrid = XtCreateManagedWidget ("grid", fontgridWidgetClass, form,
+ av, i);
+
+ XtAppSetWarningMsgHandler(xtcontext, oldWarningHandler);
+
+ /* set the label at the top to tell us which font this is */
+ i = 0;
+ XtSetArg (av[i], XtNfont, &fs); i++;
+ XtGetValues (fontGrid, av, i);
+ if (!fs || fontConversionFailed) {
+ fprintf (stderr, "%s: no font to display\n", ProgramName);
+ exit (1);
+ }
+ fontname = get_font_name (XtDisplay(toplevel), fs);
+ if (!fontname) fontname = "unknown font!";
+ i = 0;
+ XtSetArg (av[i], XtNlabel, fontname); i++;
+ XtSetValues (toplabel, av, i);
+
+ i = 0;
+ XtSetArg (av[i], XtNlabel, buf); i++;
+ sprintf (buf, xfd_resources.range_format,
+ fs->min_byte1, fs->min_char_or_byte2,
+ fs->min_byte1, fs->min_char_or_byte2,
+ fs->max_byte1, fs->max_char_or_byte2,
+ fs->max_byte1, fs->max_char_or_byte2);
+ XtSetValues (rangeLabel, av, i);
+
+ XtRealizeWidget (toplevel);
+
+ wm_delete_window = XInternAtom(XtDisplay(toplevel), "WM_DELETE_WINDOW",
+ False);
+ (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel),
+ &wm_delete_window, 1);
+
+ change_page (0);
+ XtAppMainLoop (xtcontext);
+}
+
+/*ARGSUSED*/
+static void SelectChar (w, closure, data)
+ Widget w;
+ XtPointer closure, data;
+{
+ FontGridCharRec *p = (FontGridCharRec *) data;
+ XFontStruct *fs = p->thefont;
+ unsigned n = ((((unsigned) p->thechar.byte1) << 8) |
+ ((unsigned) p->thechar.byte2));
+ int direction, fontascent, fontdescent;
+ XCharStruct metrics;
+ char buf[256];
+ Arg arg;
+
+ XtSetArg (arg, XtNlabel, buf);
+
+ if ((!fs->min_byte1 && !fs->max_byte1) ?
+ (n < fs->min_char_or_byte2 || n > fs->max_char_or_byte2) :
+ (p->thechar.byte1 < fs->min_byte1 || p->thechar.byte1 > fs->max_byte1 ||
+ p->thechar.byte2 < fs->min_char_or_byte2 ||
+ p->thechar.byte2 > fs->max_char_or_byte2)) {
+ sprintf (buf, xfd_resources.nochar_format,
+ (unsigned) p->thechar.byte1, (unsigned) p->thechar.byte2,
+ (unsigned) p->thechar.byte1, (unsigned) p->thechar.byte2,
+ (unsigned) p->thechar.byte1, (unsigned) p->thechar.byte2);
+ XtSetValues (selectLabel, &arg, ONE);
+ buf[0] = '\0';
+ XtSetValues (metricsLabel, &arg, ONE);
+ return;
+ }
+
+ XTextExtents16 (fs, &p->thechar, 1, &direction, &fontascent, &fontdescent,
+ &metrics);
+ sprintf (buf, xfd_resources.select_format,
+ (unsigned) p->thechar.byte1, (unsigned) p->thechar.byte2,
+ (unsigned) p->thechar.byte1, (unsigned) p->thechar.byte2,
+ (unsigned) p->thechar.byte1, (unsigned) p->thechar.byte2);
+ XtSetValues (selectLabel, &arg, ONE);
+
+ sprintf (buf, xfd_resources.metrics_format,
+ metrics.width, metrics.lbearing, metrics.rbearing,
+ metrics.ascent, metrics.descent, fontascent, fontdescent);
+ XtSetValues (metricsLabel, &arg, ONE);
+
+ return;
+}
+
+
+/*ARGSUSED*/
+static void do_quit (w, event, params, num_params)
+ Widget w;
+ XEvent *event;
+ String *params;
+ Cardinal *num_params;
+{
+ exit (0);
+}
+
+static void change_page (page)
+ int page;
+{
+ Dimension oldstart, newstart;
+ int ncols, nrows;
+ char buf[256];
+ Arg arg;
+
+ arg.name = XtNstartChar;
+ GetFontGridCellDimensions (fontGrid, &oldstart, &ncols, &nrows);
+
+ if (page) {
+ Dimension start = (oldstart +
+ ((long) ncols) * ((long) nrows) * ((long) page));
+
+ arg.value = (XtArgVal) start;
+ XtSetValues (fontGrid, &arg, ONE);
+ }
+
+ /* find out what it got set to */
+ arg.value = (XtArgVal) &newstart;
+ XtGetValues (fontGrid, &arg, ONE);
+
+ /* if not paging, then initialize it, else only do it actually changed */
+ if (!page || newstart != oldstart) {
+ unsigned int row = (unsigned int) ((newstart >> 8) & 0xff);
+ unsigned int col = (unsigned int) (newstart & 0xff);
+
+ XtSetArg (arg, XtNlabel, buf);
+ sprintf (buf, xfd_resources.start_format, newstart, row, col);
+ XtSetValues (startLabel, &arg, ONE);
+ }
+
+ set_button_state ();
+
+ return;
+}
+
+
+static void set_button_state ()
+{
+ Bool prevvalid, nextvalid;
+ Arg arg;
+
+ GetPrevNextStates (fontGrid, &prevvalid, &nextvalid);
+ arg.name = XtNsensitive;
+ arg.value = (XtArgVal) (prevvalid ? TRUE : FALSE);
+ XtSetValues (prevButton, &arg, ONE);
+ arg.value = (XtArgVal) (nextvalid ? TRUE : FALSE);
+ XtSetValues (nextButton, &arg, ONE);
+}
+
+
+/* ARGSUSED */
+static void do_prev (w, event, params, num_params)
+ Widget w;
+ XEvent *event;
+ String *params;
+ Cardinal *num_params;
+{
+ change_page (-1);
+}
+
+
+/* ARGSUSED */
+static void do_next (w, event, params, num_params)
+ Widget w;
+ XEvent *event;
+ String *params;
+ Cardinal *num_params;
+{
+ change_page (1);
+}
+
+
+static char *get_font_name (dpy, fs)
+ Display *dpy;
+ XFontStruct *fs;
+{
+ register XFontProp *fp;
+ register int i;
+ Atom fontatom = XInternAtom (dpy, "FONT", False);
+
+ for (i = 0, fp = fs->properties; i < fs->n_properties; i++, fp++) {
+ if (fp->name == fontatom) {
+ return (XGetAtomName (dpy, fp->card32));
+ }
+ }
+ return NULL;
+}
+
+
+static void CatchFontConversionWarning(name, type, class, defaultp, params, np)
+ String name, type, class, defaultp, *params;
+ Cardinal *np;
+{
+ if (np && *np > 1 &
+ strcmp(name, "conversionError") == 0 &&
+ strcmp(type, "string") == 0 &&
+ strcmp(class, "XtToolkitError") == 0 &&
+ strcmp(params[1], "FontStruct") == 0) fontConversionFailed = True;
+
+ (*oldWarningHandler)(name, type, class, defaultp, params, np);
+}
diff --git a/xfd.man b/xfd.man
new file mode 100644
index 0000000..7c8d4d3
--- /dev/null
+++ b/xfd.man
@@ -0,0 +1,187 @@
+.\" $Xorg: xfd.man,v 1.4 2001/02/09 02:05:42 xorgcvs Exp $
+.\" Copyright 1989, 1994, 1998 The Open Group
+.\"
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation.
+.\"
+.\" The above copyright notice and this permission notice shall be included
+.\" in all copies or substantial portions of the Software.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+.\" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+.\" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+.\" IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+.\" OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+.\" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+.\" OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\" Except as contained in this notice, the name of The Open Group shall
+.\" not be used in advertising or otherwise to promote the sale, use or
+.\" other dealings in this Software without prior written authorization
+.\" from The Open Group.
+.TH XFD 1 "Release 6.4" "X Version 11"
+.SH NAME
+xfd \- display all the characters in an X font
+.SH SYNOPSIS
+.B xfd
+[\-options ...] \fB\-fn\fP \fIfontname\fP
+.SH DESCRIPTION
+The \fIxfd\fP utility creates a window containing the name of the font being
+displayed, a row of command buttons, several lines of text for displaying
+character metrics, and a grid containing one glyph per cell. The
+characters are shown in increasing order from left to right, top to
+bottom. The first character displayed at the top left will be character
+number 0 unless the \fB\-start\fP option has been supplied in which case the
+character with the number given in the \fB\-start\fP option will be used.
+.PP
+The characters are displayed in a grid of boxes, each large enough to hold
+any single character in the font. Each character glyph is drawn using
+the PolyText16 request (used by the \fIXlib\fP routine \fBXDrawString16\fP).
+If the \fB\-box\fP option is given, a rectangle will be drawn around each
+character, showing where an ImageText16 request (used by the \fIXlib\fP
+routine \fBXDrawImageString16\fP) would cause background color to be displayed.
+.PP
+The origin of each glyph is normally set so that the character is drawn in
+the upper left hand corner of the grid cell. However, if a glyph has a
+negative left bearing or an unusually large ascent, descent, or right bearing
+(as is the case with \fIcursor\fP font), some character may not appear in their
+own grid cells. The \fB\-center\fP option may be used to force all glyphs to
+be centered in their respective cells.
+.PP
+All the characters in the font may not fit in the window at once.
+To see the next page of glyphs, press the \fINext\fP button at the top
+of the window. To see the previous page, press \fIPrev\fP. To exit \fIxfd\fP,
+press \fIQuit\fP.
+.PP
+Individual character metrics (index, width, bearings, ascent and descent) can
+be displayed at the top of the window by clicking on the desired character.
+.PP
+The font name displayed at the top of the window is the full name of the
+font, as determined by the server. See \fIxlsfonts\fP for ways to generate
+lists of fonts, as well as more detailed summaries of their metrics and
+properties.
+.SH "OPTIONS"
+.PP
+.I xfd
+accepts all of the standard toolkit command line options along with
+the additional options listed below:
+.TP 8
+.B \-fn \fIfont\fP
+This option specifies the font to be displayed. This can also be set with
+the FontGrid \fBfont\fP resource. A font must be specified.
+.TP 8
+.B \-box
+This option indicates that a box should be displayed outlining the area
+that would be filled with background color by an ImageText request.
+This can also be set with
+the FontGrid \fBboxChars\fP resource. The default is False.
+.TP 8
+.B \-center
+This option indicates that each glyph should be centered in its grid.
+This can also be set with
+the FontGrid \fBcenterChars\fP resource. The default is False.
+.TP 8
+.B \-start \fInumber\fP
+This option specifies the glyph index of the upper left hand corner of the
+grid. This is used to view characters at arbitrary locations in the font.
+This can also be set with
+the FontGrid \fBstartChar\fP resource. The default is 0.
+.TP 8
+.B \-bc \fIcolor\fP
+This option specifies the color to be used if ImageText boxes are drawn.
+This can also be set with
+the FontGrid \fBboxColor\fP resource.
+.TP 8
+.B \-rows \fInumrows\fP
+This option specifies the number of rows in the grid.
+This can also be set with
+the FontGrid \fBcellRows\fP resource.
+.TP 8
+.B \-columns \fInumcols\fP
+This option specifies the number of columns in the grid.
+This can also be set with
+the FontGrid \fBcellColumns\fP resource.
+.SH WIDGETS
+In order to specify resources, it is useful to know the
+widgets which compose \fIxfd\fR. In the notation below, indentation
+indicates hierarchical structure. The widget class name is given first,
+followed by the widget instance name.
+The application class name is Xfd.
+.sp
+.nf
+.ta .5i 1.0i 1.5i 2.0i 2.5i 3.0i 3.5i 4.0i 4.5i 5.0i 5.5i 6.0i 6.5i 7.0i
+Xfd xfd
+ Paned pane
+ Label fontname
+ Box box
+ Command quit
+ Command prev
+ Command next
+ Label select
+ Label metrics
+ Label range
+ Label start
+ Form form
+ FontGrid grid
+.fi
+.SH FONTGRID RESOURCES
+The FontGrid widget is an application-specific widget, and a subclass
+of the Simple widget in the Athena widget set. The effects and
+instance names of this widget's resources are given in the
+\fBOPTIONS\fP section. Capitalize the first letter of the resource
+instance name to get the corresponding class name.
+.SH APPLICATION SPECIFIC RESOURCES
+The instance names of the application specific resources
+are given below. Capitalize the first letter of the resource
+instance name to get the corresponding class name.
+These resources are unlikely to be interesting unless you are localizing
+xfd for a different language.
+.TP 8
+.B selectFormat
+Specifies a printf-style format string used to display information
+about the selected character. The default is "character 0x%02x%02x
+(%u,%u) (%#o,%#o)". The arguments that will come after the format string are
+char.byte1, char.byte2, char.byte1, char.byte2, char.byte1, char.byte2.
+char.byte1 is byte 1 of the selected character.
+char.byte2 is byte 2 of the selected character.
+.TP 8
+.B metricsFormat
+Specifies a printf-style format string used to display character
+metrics. The default is "width %d; left %d, right %d; ascent %d,
+descent %d (font %d, %d)". The arguments that will come after the
+format string are the character metrics width, lbearing, rbearing,
+character ascent, character descent, font ascent, and font descent.
+.TP 8
+.B rangeFormat
+Specifies a printf-style format string used to display the range of
+characters currently being displayed. The default is "range:
+0x%02x%02x (%u,%u) thru 0x%02x%02x (%u,%u)". The arguments that will
+come after the format string are the following fields from the
+XFontStruct that is returned from opening the font:
+min_byte1, min_char_or_byte2, min_byte1, min_char_or_byte2,
+max_byte1, max_char_or_byte2, max_byte1, max_char_or_byte2.
+.TP 8
+.B startFormat
+Specifies a printf-style format string used to display information
+about the character at the upper left corner of the font grid. The
+default is "upper left: 0x%04x (%d,%d)". The arguments that will come
+after the format string are the new character, the high byte of the new
+character, and the low byte of the new character.
+.TP 8
+.B nocharFormat
+Specifies a printf-style format string to display when the selected
+character does not exist. The default is "no such character
+0x%02x%02x (%u,%u) (%#o,%#o)". The arguments that will come after the
+format string are the same as for the \fBselectFormat\fP resource.
+.SH "SEE ALSO"
+X(1), xlsfonts(1), xrdb(1), xfontsel(1),
+.I "X Logical Font Description Conventions"
+.SH "BUGS"
+The program should skip over pages full of non-existent characters.
+.SH AUTHOR
+Jim Fulton, MIT X Consortium; previous program of the same name by
+Mark Lillibridge, MIT Project Athena.
+