/* * fonts.c -- provide an interface for the user to pick and choose * between font families and styles known to XView. The program * provides several panel buttons to choose between font types, and * a canvas window in which the user can type. The characters typed * are printed in the current font. If a font "name" is specified, * then the family, style and size are ignored. Using the SELECT * button on the canvas window positions the current typing location * at the x,y coordinates of the button-down event. */ #include <ctype.h> #include <X11/X.h> #include <X11/Xlib.h> #include <xview/xview.h> #include <xview/panel.h> #include <xview/font.h> Display *dpy; GC gc; XFontStruct *cur_font; Panel_item family_item, style_item, scale_item, name_item; int canvas_width; main(argc, argv) int argc; char *argv[]; { Frame frame; Panel panel; Canvas canvas; XGCValues gcvalues; Xv_Font font; void change_font(); void my_event_proc(), my_resize_proc(); int change_font_by_name(); extern void exit(); xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL); frame = (Frame)xv_create(XV_NULL, FRAME, FRAME_LABEL, argv[0], FRAME_SHOW_FOOTER, TRUE, NULL); panel = (Panel)xv_create(frame, PANEL, PANEL_LAYOUT, PANEL_VERTICAL, NULL); (void) xv_create(panel, PANEL_BUTTON, PANEL_LABEL_STRING, "Quit", PANEL_NOTIFY_PROC, exit, NULL); family_item = (Panel_item)xv_create(panel, PANEL_CHOICE, PANEL_LABEL_STRING, "Family", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_DISPLAY_LEVEL, PANEL_CURRENT, PANEL_CHOICE_STRINGS, FONT_FAMILY_DEFAULT, FONT_FAMILY_DEFAULT_FIXEDWIDTH, FONT_FAMILY_LUCIDA, FONT_FAMILY_LUCIDA_FIXEDWIDTH, FONT_FAMILY_ROMAN, FONT_FAMILY_SERIF, FONT_FAMILY_COUR, FONT_FAMILY_CMR, FONT_FAMILY_GALLENT, FONT_FAMILY_OLGLYPH, FONT_FAMILY_OLCURSOR, NULL, PANEL_NOTIFY_PROC, change_font, NULL); style_item = (Panel_item)xv_create(panel, PANEL_CHOICE, PANEL_LABEL_STRING, "Style", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_DISPLAY_LEVEL, PANEL_CURRENT, PANEL_CHOICE_STRINGS, FONT_STYLE_DEFAULT, FONT_STYLE_NORMAL, FONT_STYLE_BOLD, FONT_STYLE_ITALIC, FONT_STYLE_BOLD_ITALIC, NULL, PANEL_NOTIFY_PROC, change_font, NULL); scale_item = (Panel_item)xv_create(panel, PANEL_CHOICE, PANEL_LABEL_STRING, "Scale", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_DISPLAY_LEVEL, PANEL_CURRENT, PANEL_CHOICE_STRINGS, "Small", "Medium", "Large", "X-Large", NULL, PANEL_NOTIFY_PROC, change_font, NULL); name_item = (Panel_item)xv_create(panel, PANEL_TEXT, PANEL_LABEL_STRING, "Font Name:", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_VALUE_DISPLAY_LENGTH, 20, PANEL_NOTIFY_PROC, change_font_by_name, NULL); window_fit(panel); canvas = (Canvas)xv_create(frame, CANVAS, XV_WIDTH, 400, XV_HEIGHT, 200, CANVAS_X_PAINT_WINDOW, TRUE, CANVAS_RESIZE_PROC, my_resize_proc, NULL); xv_set(canvas_paint_window(canvas), WIN_EVENT_PROC, my_event_proc, WIN_CONSUME_EVENT, LOC_WINENTER, NULL); window_fit(frame); dpy = (Display *)xv_get(frame, XV_DISPLAY); font = (Xv_Font)xv_get(frame, XV_FONT); cur_font = (XFontStruct *)xv_get(font, FONT_INFO); xv_set(frame, FRAME_LEFT_FOOTER, xv_get(font, FONT_NAME), NULL); gcvalues.font = cur_font->fid; gcvalues.foreground = BlackPixel(dpy, DefaultScreen(dpy)); gcvalues.background = WhitePixel(dpy, DefaultScreen(dpy)); gcvalues.graphics_exposures = False; gc = XCreateGC(dpy, RootWindow(dpy, DefaultScreen(dpy)), GCForeground | GCBackground | GCFont | GCGraphicsExposures, &gcvalues); xv_main_loop(frame); } void my_event_proc(win, event) Xv_Window win; Event *event; { static int x = 10, y = 10; Window xwin = (Window)xv_get(win, XV_XID); char c; if (event_is_up(event)) return; if (event_is_ascii(event)) { c = (char)event_action(event); XDrawString(dpy, xwin, gc, x, y, &c, 1); /* advance x to next position. If over edge, linewrap */ if ((x += XTextWidth(cur_font, &c, 1)) >= canvas_width) { y += cur_font->max_bounds.ascent + cur_font->max_bounds.descent; x = 10; } } else if (event_action(event) == ACTION_SELECT) { x = event_x(event); y = event_y(event); } else if (event_action(event) == LOC_WINENTER) win_set_kbd_focus(win, xwin); } /* * check resizing so we know how wide to allow the user to type. */ void my_resize_proc(canvas, width, height) Canvas canvas; int width, height; { canvas_width = width; } void change_font(item, value, event) Panel_item item; Event *event; { static int family, style, scale; char buf[128]; Frame frame; char *family_name; char *style_name; int scale_value; Xv_Font font; frame = (Frame)xv_get(xv_get(item, PANEL_PARENT_PANEL), XV_OWNER); family_name = (char *)xv_get(family_item, PANEL_CHOICE_STRING, xv_get(family_item, PANEL_VALUE)); style_name = (char *)xv_get(style_item, PANEL_CHOICE_STRING, xv_get(style_item, PANEL_VALUE)); scale_value = (int) xv_get(scale_item, PANEL_VALUE); xv_set(frame, FRAME_BUSY, TRUE, NULL); font = (Xv_Font)xv_find(frame, FONT, FONT_FAMILY, family_name, FONT_STYLE, style_name, /* scale_value happens to coincide with Window_rescale_state */ FONT_SCALE, scale_value, /* * If run on a server that cannot rescale fonts, only font * sizes that exist should be passed */ FONT_SIZES_FOR_SCALE, 12, 14, 16, 22, NULL); xv_set(frame, FRAME_BUSY, FALSE, NULL); if (!font) { if (item == family_item) { sprintf(buf, "cannot load '%s'", family_name); xv_set(family_item, PANEL_VALUE, family, NULL); } else if (item == style_item) { sprintf(buf, "cannot load '%s'", style_name); xv_set(style_item, PANEL_VALUE, style, NULL); } else { sprintf(buf, "Not available in %s scale.", xv_get(scale_item, PANEL_CHOICE_STRING, scale)); xv_set(scale_item, PANEL_VALUE, scale, NULL); } xv_set(frame, FRAME_RIGHT_FOOTER, buf, NULL); return; } if (item == family_item) family = value; else if (item == style_item) style = value; else scale = value; cur_font = (XFontStruct *)xv_get(font, FONT_INFO); XSetFont(dpy, gc, cur_font->fid); sprintf(buf, "Current font: %s", xv_get(font, FONT_NAME)); xv_set(frame, FRAME_LEFT_FOOTER, buf, NULL); } change_font_by_name(item, event) Panel_item item; Event *event; { char buf[128]; char *name = (char *)xv_get(item, PANEL_VALUE); Frame frame = (Frame)xv_get(xv_get(item, XV_OWNER), XV_OWNER); Xv_Font font; xv_set(frame, FRAME_BUSY, TRUE, NULL); font = (Xv_Font)xv_find(frame, FONT, FONT_NAME, name, NULL); xv_set(frame, FRAME_BUSY, FALSE, NULL); if (!font) { sprintf(buf, "cannot load '%s'", name); xv_set(frame, FRAME_RIGHT_FOOTER, buf, NULL); return PANEL_NONE; } cur_font = (XFontStruct *)xv_get(font, FONT_INFO); XSetFont(dpy, gc, cur_font->fid); sprintf(buf, "Current font: %s", xv_get(font, FONT_NAME)); xv_set(frame, FRAME_LEFT_FOOTER, buf, NULL); return PANEL_NONE; }