diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-17 19:03:47 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-17 19:03:47 +0000 |
commit | 1c20e3f37a2359a11ec7cccfe740b4a39d4decf1 (patch) | |
tree | d941faa69a7da1ac3eff60f02f35e770aad60b73 /grid.c | |
parent | 961d4493f519b5b093581e111997f894b1675d48 (diff) |
merge XFree86 4.3.0.1 to -CURRENT
Diffstat (limited to 'grid.c')
-rw-r--r-- | grid.c | 619 |
1 files changed, 533 insertions, 86 deletions
@@ -26,6 +26,7 @@ in this Software without prior written authorization from The Open Group. * * * Author: Jim Fulton, MIT X Consortium */ +/* $XFree86: xc/programs/xfd/grid.c,v 1.9 2002/07/06 00:46:42 keithp Exp $ */ #include <X11/IntrinsicP.h> @@ -47,10 +48,21 @@ in this Software without prior written authorization from The Open Group. #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(); +static GC get_gc(FontGridWidget fgw, Pixel fore); +static void ClassInitialize(void); +static void Initialize(Widget request, Widget new, ArgList args, + Cardinal *num_args); +static void Realize(Widget gw, Mask *valueMask, + XSetWindowAttributes *attributes); +static void Destroy(Widget gw); +static void Resize(Widget gw); +static void Redisplay(Widget gw, XEvent *event, Region region); +static void paint_grid(FontGridWidget fgw, int col, int row, + int ncols, int nrows); +static Boolean SetValues(Widget current, Widget request, Widget new, + ArgList args, Cardinal *num_args); +static void Notify(Widget gw, XEvent *event, String *params, + Cardinal *nparams); #define Offset(field) XtOffsetOf(FontGridRec, fontgrid.field) @@ -65,10 +77,12 @@ static XtResource resources[] = { 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 }, + { XtNstartChar, XtCStartChar, XtRLong, sizeof(long), + Offset(start_char), XtRImmediate, (XtPointer) 0xffffffff }, +#ifndef XRENDER { XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel), Offset(foreground_pixel), XtRString, (XtPointer) XtDefaultForeground }, +#endif { XtNcenterChars, XtCCenterChars, XtRBoolean, sizeof(Boolean), Offset(center_chars), XtRImmediate, (XtPointer) FALSE }, { XtNboxChars, XtCBoxChars, XtRBoolean, sizeof(Boolean), @@ -81,6 +95,12 @@ static XtResource resources[] = { Offset(internal_pad), XtRImmediate, (XtPointer) 4 }, { XtNgridWidth, XtCGridWidth, XtRInt, sizeof(int), Offset(grid_width), XtRImmediate, (XtPointer) 1 }, +#ifdef XRENDER + {XtNforeground, XtCForeground, XtRXftColor, sizeof(XftColor), + Offset(fg_color), XtRString, XtDefaultForeground}, + {XtNface, XtCFace, XtRXftFont, sizeof (XftFont *), + Offset (text_face), XtRString, 0}, +#endif }; #undef Offset @@ -135,34 +155,193 @@ FontGridClassRec fontgridClassRec = { WidgetClass fontgridWidgetClass = (WidgetClass) &fontgridClassRec; +long +GridFirstChar (Widget w) +{ + FontGridWidget fgw = (FontGridWidget) w; + XFontStruct *fs = fgw->fontgrid.text_font; +#ifdef XRENDER + XftFont *xft = fgw->fontgrid.text_face; + if (xft) + { + FcChar32 map[FC_CHARSET_MAP_SIZE]; + FcChar32 next; + FcChar32 first; + int i; + + first = FcCharSetFirstPage (xft->charset, map, &next); + for (i = 0; i < FC_CHARSET_MAP_SIZE; i++) + if (map[i]) + { + FcChar32 bits = map[i]; + first += i * 32; + while (!(bits & 0x1)) + { + bits >>= 1; + first++; + } + break; + } + return first; + } + else +#endif + if (fs) + { + return (fs->min_byte1 << 8) | (fs->min_char_or_byte2); + } + else + return 0; +} + +long +GridLastChar (Widget w) +{ + FontGridWidget fgw = (FontGridWidget) w; + XFontStruct *fs = fgw->fontgrid.text_font; +#ifdef XRENDER + XftFont *xft = fgw->fontgrid.text_face; + if (xft) + { + FcChar32 this, last, next; + FcChar32 map[FC_CHARSET_MAP_SIZE]; + int i; + last = FcCharSetFirstPage (xft->charset, map, &next); + while ((this = FcCharSetNextPage (xft->charset, map, &next)) != FC_CHARSET_DONE) + last = this; + last &= ~0xff; + for (i = FC_CHARSET_MAP_SIZE - 1; i >= 0; i--) + if (map[i]) + { + FcChar32 bits = map[i]; + last += i * 32 + 31; + while (!(bits & 0x80000000)) + { + last--; + bits <<= 1; + } + break; + } + return (long) last; + } + else +#endif + if (fs) + { + return (fs->max_byte1 << 8) | (fs->max_char_or_byte2); + } + else + return 0; +} + +/* + * CI_GET_CHAR_INFO_1D - return the charinfo struct for the indicated 8bit + * character. If the character is in the column and exists, then return the + * appropriate metrics (note that fonts with common per-character metrics will + * return min_bounds). + */ + +#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \ + (((cs)->rbearing|(cs)->lbearing| \ + (cs)->ascent|(cs)->descent) == 0)) + +#define CI_GET_CHAR_INFO_1D(fs,col,cs) \ +{ \ + cs = 0; \ + if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ + if (fs->per_char == NULL) { \ + cs = &fs->min_bounds; \ + } else { \ + cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \ + } \ + if (CI_NONEXISTCHAR(cs)) \ + cs = 0; \ + } \ +} + +/* + * CI_GET_CHAR_INFO_2D - return the charinfo struct for the indicated row and + * column. This is used for fonts that have more than row zero. + */ +#define CI_GET_CHAR_INFO_2D(fs,row,col,cs) \ +{ \ + cs = 0; \ + if (row >= fs->min_byte1 && row <= fs->max_byte1 && \ + col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ + if (fs->per_char == NULL) { \ + cs = &fs->min_bounds; \ + } else { \ + cs = &fs->per_char[((row - fs->min_byte1) * \ + (fs->max_char_or_byte2 - \ + fs->min_char_or_byte2 + 1)) + \ + (col - fs->min_char_or_byte2)]; \ + } \ + if (CI_NONEXISTCHAR(cs)) \ + cs = 0; \ + } \ +} + +static Boolean +GridHasChar (Widget w, long ch) +{ + FontGridWidget fgw = (FontGridWidget) w; +#ifdef XRENDER + XftFont *xft = fgw->fontgrid.text_face; + if (xft) + { + return FcCharSetHasChar (xft->charset, (FcChar32) ch); + } + else +#endif + { + XFontStruct *fs = fgw->fontgrid.text_font; + XCharStruct *cs; + + if (!fs) + return False; + if (fs->max_byte1 == 0) + { + CI_GET_CHAR_INFO_1D (fs, ch, cs); + } + else + { + unsigned int r = (ch >> 8); + unsigned int c = (ch & 0xff); + CI_GET_CHAR_INFO_2D (fs, r, c, cs); + } + return cs != 0; + } +} + /* * public routines */ -void GetFontGridCellDimensions (w, startp, ncolsp, nrowsp) - Widget w; - Dimension *startp; - int *ncolsp, *nrowsp; +void +GetFontGridCellDimensions(Widget w, long *startp, + int *ncolsp, int *nrowsp) { FontGridWidget fgw = (FontGridWidget) w; - *startp = (long)fgw->fontgrid.start_char; + *startp = fgw->fontgrid.start_char; *ncolsp = fgw->fontgrid.cell_cols; *nrowsp = fgw->fontgrid.cell_rows; } -void GetPrevNextStates (w, prevvalidp, nextvalidp) - Widget w; - Bool *prevvalidp, *nextvalidp; +void +GetPrevNextStates(Widget w, Bool *prevvalidp, Bool *nextvalidp, + Bool *prev16validp, Bool *next16validp) { FontGridWidget fgw = (FontGridWidget) w; + long minn = (long) GridFirstChar (w); + long maxn = (long) GridLastChar (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 + + *prev16validp = (fgw->fontgrid.start_char - 0xf00 > minn); + *prevvalidp = (fgw->fontgrid.start_char > minn); + *nextvalidp = (fgw->fontgrid.start_char + + (fgw->fontgrid.cell_cols * fgw->fontgrid.cell_rows) + < maxn); + *next16validp =((fgw->fontgrid.start_char + 0xf00 + (fgw->fontgrid.cell_cols * fgw->fontgrid.cell_rows)) < maxn); } @@ -174,18 +353,21 @@ void GetPrevNextStates (w, prevvalidp, nextvalidp) */ -static GC get_gc (fgw, fore) - FontGridWidget fgw; - Pixel fore; +static GC +get_gc(FontGridWidget fgw, Pixel fore) { XtGCMask mask; XGCValues gcv; - mask = (GCForeground | GCBackground | GCFunction | GCFont); + mask = (GCForeground | GCBackground | GCFunction); gcv.foreground = fore; gcv.background = fgw->core.background_pixel; gcv.function = GXcopy; - gcv.font = fgw->fontgrid.text_font->fid; + if (fgw->fontgrid.text_font) + { + mask |= GCFont; + gcv.font = fgw->fontgrid.text_font->fid; + } gcv.cap_style = CapProjecting; mask |= GCCapStyle; if (fgw->fontgrid.grid_width > 0) { @@ -197,26 +379,219 @@ static GC get_gc (fgw, fore) } -static void ClassInitialize () +#ifdef XRENDER +XtConvertArgRec xftColorConvertArgs[] = { + {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen), + sizeof(Screen *)}, + {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap), + sizeof(Colormap)} +}; + +#define donestr(type, value, tstr) \ + { \ + if (toVal->addr != NULL) { \ + if (toVal->size < sizeof(type)) { \ + toVal->size = sizeof(type); \ + XtDisplayStringConversionWarning(dpy, \ + (char*) fromVal->addr, tstr); \ + return False; \ + } \ + *(type*)(toVal->addr) = (value); \ + } \ + else { \ + static type static_val; \ + static_val = (value); \ + toVal->addr = (XPointer)&static_val; \ + } \ + toVal->size = sizeof(type); \ + return True; \ + } + +static void +XmuFreeXftColor (XtAppContext app, XrmValuePtr toVal, XtPointer closure, + XrmValuePtr args, Cardinal *num_args) +{ + Screen *screen; + Colormap colormap; + XftColor *color; + + if (*num_args != 2) + { + XtAppErrorMsg (app, + "freeXftColor", "wrongParameters", + "XtToolkitError", + "Freeing an XftColor requires screen and colormap arguments", + (String *) NULL, (Cardinal *)NULL); + return; + } + + screen = *((Screen **) args[0].addr); + colormap = *((Colormap *) args[1].addr); + color = (XftColor *) toVal->addr; + XftColorFree (DisplayOfScreen (screen), + DefaultVisual (DisplayOfScreen (screen), + XScreenNumberOfScreen (screen)), + colormap, color); +} + +static Boolean +XmuCvtStringToXftColor(Display *dpy, + XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + char *spec; + XRenderColor renderColor; + XftColor xftColor; + Screen *screen; + Colormap colormap; + + if (*num_args != 2) + { + XtAppErrorMsg (XtDisplayToApplicationContext (dpy), + "cvtStringToXftColor", "wrongParameters", + "XtToolkitError", + "String to render color conversion needs screen and colormap arguments", + (String *) NULL, (Cardinal *)NULL); + return False; + } + + screen = *((Screen **) args[0].addr); + colormap = *((Colormap *) args[1].addr); + + spec = (char *) fromVal->addr; + if (strcasecmp (spec, XtDefaultForeground) == 0) + { + renderColor.red = 0; + renderColor.green = 0; + renderColor.blue = 0; + renderColor.alpha = 0xffff; + } + else if (strcasecmp (spec, XtDefaultBackground) == 0) + { + renderColor.red = 0xffff; + renderColor.green = 0xffff; + renderColor.blue = 0xffff; + renderColor.alpha = 0xffff; + } + else if (!XRenderParseColor (dpy, spec, &renderColor)) + return False; + if (!XftColorAllocValue (dpy, + DefaultVisual (dpy, + XScreenNumberOfScreen (screen)), + colormap, + &renderColor, + &xftColor)) + return False; + + donestr (XftColor, xftColor, XtRXftColor); +} + +static void +XmuFreeXftFont (XtAppContext app, XrmValuePtr toVal, XtPointer closure, + XrmValuePtr args, Cardinal *num_args) +{ + Screen *screen; + XftFont *font; + + if (*num_args != 1) + { + XtAppErrorMsg (app, + "freeXftFont", "wrongParameters", + "XtToolkitError", + "Freeing an XftFont requires screen argument", + (String *) NULL, (Cardinal *)NULL); + return; + } + + screen = *((Screen **) args[0].addr); + font = *((XftFont **) toVal->addr); + if (font) + XftFontClose (DisplayOfScreen (screen), font); +} + +static Boolean +XmuCvtStringToXftFont(Display *dpy, + XrmValue *args, Cardinal *num_args, + XrmValue *fromVal, XrmValue *toVal, + XtPointer *converter_data) +{ + char *name; + XftFont *font; + Screen *screen; + + if (*num_args != 1) + { + XtAppErrorMsg (XtDisplayToApplicationContext (dpy), + "cvtStringToXftFont", "wrongParameters", + "XtToolkitError", + "String to XftFont conversion needs screen argument", + (String *) NULL, (Cardinal *)NULL); + return False; + } + + screen = *((Screen **) args[0].addr); + name = (char *) fromVal->addr; + + font = 0; + if (name) + { + font = XftFontOpenName (dpy, + XScreenNumberOfScreen (screen), + name); + if (!font) + { + XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr, XtRXftFont); + return False; + } + } + donestr (XftFont *, font, XtRXftFont); +} + +static XtConvertArgRec xftFontConvertArgs[] = { + {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen), + sizeof(Screen *)}, +}; + +#endif + +static void +ClassInitialize(void) { XtAddConverter (XtRString, XtRLong, XmuCvtStringToLong, NULL, 0); +#ifdef XRENDER + XtSetTypeConverter (XtRString, XtRXftColor, + XmuCvtStringToXftColor, + xftColorConvertArgs, XtNumber(xftColorConvertArgs), + XtCacheByDisplay, XmuFreeXftColor); + XtSetTypeConverter (XtRString, XtRXftFont, + XmuCvtStringToXftFont, + xftFontConvertArgs, XtNumber(xftFontConvertArgs), + XtCacheByDisplay, XmuFreeXftFont); +#endif } -static void Initialize (request, new, args, num_args) - Widget request, new; - ArgList args; - Cardinal *num_args; +static void +Initialize(Widget request, Widget new, ArgList args, Cardinal *num_args) { FontGridWidget reqfg = (FontGridWidget) request; FontGridWidget newfg = (FontGridWidget) new; XFontStruct *fs = newfg->fontgrid.text_font; +#ifdef XRENDER + XftFont *xft = newfg->fontgrid.text_face; +#endif unsigned maxn; if (reqfg->fontgrid.cell_cols <= 0) newfg->fontgrid.cell_cols = 16; if (reqfg->fontgrid.cell_rows <= 0) { +#ifdef XRENDER + if (xft) + newfg->fontgrid.cell_rows = 16; + else +#endif if (fs && fs->max_byte1 == 0) { newfg->fontgrid.cell_rows = (fs->max_char_or_byte2 / newfg->fontgrid.cell_cols) + 1; @@ -227,9 +602,9 @@ static void Initialize (request, new, args, num_args) } if (reqfg->fontgrid.cell_width <= 0) - newfg->fontgrid.cell_width = (fs ? DefaultCellWidth (newfg) : 1); + newfg->fontgrid.cell_width = DefaultCellWidth (newfg); if (reqfg->fontgrid.cell_height <= 0) - newfg->fontgrid.cell_height = (fs ? DefaultCellHeight (newfg) : 1); + newfg->fontgrid.cell_height = DefaultCellHeight (newfg); /* give a nice size that fits one screen full */ if (newfg->core.width == 0) @@ -248,38 +623,39 @@ static void Initialize (request, new, args, num_args) * 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)); - } + if (newfg->fontgrid.start_char == 0xffffffff) + newfg->fontgrid.start_char = GridFirstChar(new) & ~0xff; + maxn = GridLastChar (new); + 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; +static void +Realize(Widget gw, Mask *valueMask, XSetWindowAttributes *attributes) { FontGridWidget fgw = (FontGridWidget) gw; FontGridPart *p = &fgw->fontgrid; - p->text_gc = get_gc (fgw, p->foreground_pixel); + p->text_gc = get_gc (fgw, GridForeground (fgw)); p->box_gc = get_gc (fgw, p->box_pixel); Resize (gw); (*(XtSuperclass(gw)->core_class.realize)) (gw, valueMask, attributes); +#ifdef XRENDER + p->draw = XftDrawCreate (XtDisplay (gw), XtWindow (gw), + DefaultVisual (XtDisplay (gw), + DefaultScreen(XtDisplay (gw))), + fgw->core.colormap); +#endif return; } -static void Destroy (gw) - Widget gw; +static void +Destroy(Widget gw) { FontGridWidget fgw = (FontGridWidget) gw; @@ -288,8 +664,8 @@ static void Destroy (gw) } -static void Resize (gw) - Widget gw; +static void +Resize(Widget gw) { FontGridWidget fgw = (FontGridWidget) gw; @@ -309,16 +685,17 @@ static void Resize (gw) /* ARGSUSED */ -static void Redisplay (gw, event, region) - Widget gw; - XEvent *event; - Region region; +static void +Redisplay(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 */ +#ifdef XRENDER + if (!fgw->fontgrid.text_face) +#endif if (!fgw->fontgrid.text_font) { Bell (gw, XkbBI_BadValue); return; @@ -339,10 +716,10 @@ static void Redisplay (gw, event, region) } -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 */ +static void +paint_grid(FontGridWidget fgw, /* widget in which to draw */ + int col, int row, /* where to start */ + int ncols, int nrows) /* number of cells */ { FontGridPart *p = &fgw->fontgrid; int i, j; @@ -353,8 +730,7 @@ static void paint_grid (fgw, col, row, ncols, nrows) 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 maxn = GridLastChar ((Widget) fgw); unsigned n, prevn; int startx; @@ -384,8 +760,6 @@ static void paint_grid (fgw, col, row, ncols, nrows) 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 @@ -394,15 +768,45 @@ static void paint_grid (fgw, col, row, ncols, nrows) 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; + y = row * ch + p->internal_pad + p->grid_width + GridFontAscent (fgw); 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 */ +#ifdef XRENDER + if (fgw->fontgrid.text_face) + { + XftFont *xft = p->text_face; + FcChar32 c = n; + XGlyphInfo extents; + XftTextExtents32 (dpy, xft, &c, 1, &extents); + if (p->center_chars) + { + xoff = (p->cell_width - extents.width) / 2 - extents.x; + yoff = (p->cell_height - extents.height) / 2 - extents.y; + } + if (extents.width && extents.height) + { + XClearArea (dpy, wind, x + xoff - extents.x, + y + yoff - extents.y, + extents.width, extents.height, False); + if (p->box_chars) + XDrawRectangle (dpy, wind, p->box_gc, + x + xoff - extents.x, + y + yoff - extents.y, + extents.width - 1, + extents.height - 1); + } + XftDrawString32 (p->draw, &p->fg_color, xft, + x + xoff, y + yoff, &c, 1); + } + else +#endif + { + XChar2b thechar; + thechar.byte1 = (n >> 8); /* high eight bits */ thechar.byte2 = (n & 255); /* low eight bits */ if (p->box_chars || p->center_chars) { @@ -436,20 +840,50 @@ static void paint_grid (fgw, col, row, ncols, nrows) } XDrawString16 (dpy, wind, p->text_gc, x + xoff, y + yoff, &thechar, 1); + } n++; } prevn += tcols; } done: + /* + * 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); + } + } + + return; } +static Boolean +PageBlank (Widget w, long first, long last) +{ + while (first <= last) + { + if (GridHasChar (w, first)) + return False; + first++; + } + return True; +} + /*ARGSUSED*/ -static Boolean SetValues (current, request, new, args, num_args) - Widget current, request, new; - ArgList args; - Cardinal *num_args; +static Boolean +SetValues(Widget current, Widget request, Widget new, + ArgList args, Cardinal *num_args) { FontGridWidget curfg = (FontGridWidget) current; FontGridWidget newfg = (FontGridWidget) new; @@ -462,10 +896,9 @@ static Boolean SetValues (current, request, new, args, num_args) redisplay = TRUE; } - if (curfg->fontgrid.foreground_pixel != newfg->fontgrid.foreground_pixel) { + if (GridForeground(curfg) != GridForeground (newfg)) { XtReleaseGC (new, curfg->fontgrid.text_gc); - newfg->fontgrid.text_gc = get_gc (newfg, - newfg->fontgrid.foreground_pixel); + newfg->fontgrid.text_gc = get_gc (newfg, GridForeground (newfg)); redisplay = TRUE; } @@ -480,14 +913,29 @@ static Boolean SetValues (current, request, new, args, num_args) 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); + long maxn = GridLastChar (new); + long page = newfg->fontgrid.cell_cols * newfg->fontgrid.cell_rows; + long dir = page; + long start = newfg->fontgrid.start_char; + + if (start < curfg->fontgrid.start_char) + dir = -page; + + if (start < 0) + start = 0; + if (start > maxn) + start = (maxn / page) * page; + + while (PageBlank (new, start, start + page - 1)) + { + long next = start + dir; - if (newfg->fontgrid.start_char > maxn) - newfg->fontgrid.start_char = (maxn + 1 - - (newfg->fontgrid.cell_cols * - newfg->fontgrid.cell_rows)); + if (next < 0 || maxn < next) + break; + start = next; + } + newfg->fontgrid.start_char = start; redisplay = (curfg->fontgrid.start_char != newfg->fontgrid.start_char); } @@ -496,11 +944,8 @@ static Boolean SetValues (current, request, new, args, num_args) /* ARGSUSED */ -static void Notify (gw, event, params, nparams) - Widget gw; - XEvent *event; - String *params; - Cardinal *nparams; +static void +Notify(Widget gw, XEvent *event, String *params, Cardinal *nparams) { FontGridWidget fgw = (FontGridWidget) gw; int x, y; /* where the event happened */ @@ -546,8 +991,10 @@ static void Notify (gw, event, params, nparams) ((y / ch) * fgw->fontgrid.cell_cols) + (x / cw)); rec.thefont = fgw->fontgrid.text_font; - rec.thechar.byte1 = (n >> 8); - rec.thechar.byte2 = (n & 255); +#ifdef XRENDER + rec.theface = fgw->fontgrid.text_face; +#endif + rec.thechar = n; } XtCallCallbacks (gw, XtNcallback, (XtPointer) &rec); |