void XmLStringDraw(Widget w, XmString string, XmStringDirection stringDir, XmFontList fontList, unsigned char alignment, GC gc, XRectangle *rect, XRectangle *clipRect) { Display *dpy; Window win; Dimension width, height; int x, y, drawType; unsigned char strAlignment; if (!string) return; dpy = XtDisplay(w); win = XtWindow(w); XmStringExtent(fontList, string, &width, &height); drawType = XmLDrawCalc(w, width, height, alignment, rect, clipRect, &x, &y); if (drawType == XmLDrawNODRAW) return; x = rect->x + 2; if (alignment == XmALIGNMENT_LEFT || alignment == XmALIGNMENT_TOP_LEFT || alignment == XmALIGNMENT_BOTTOM_LEFT) strAlignment = XmALIGNMENT_BEGINNING; else if (alignment == XmALIGNMENT_CENTER || alignment == XmALIGNMENT_TOP || alignment == XmALIGNMENT_BOTTOM) if (width <= rect->width - 4) strAlignment = XmALIGNMENT_CENTER; else strAlignment = XmALIGNMENT_BEGINNING; else strAlignment = XmALIGNMENT_END; /* XmStringDraw clipping doesnt work in all cases so we use a clip region for clipping */ if (drawType == XmLDrawCLIPPED) XSetClipRectangles(dpy, gc, 0, 0, clipRect, 1, Unsorted); XmStringDraw(dpy, win, fontList, string, gc, x, y, rect->width - 4, strAlignment, stringDir, clipRect); if (drawType == XmLDrawCLIPPED) XSetClipMask(dpy, gc, None); }
void Container::UpdateAreaMessage(Widget widget, XtPointer client_data, XEvent * /*event*/, Boolean * /*continued*/) { unsigned char direction; XGCValues values; XtGCMask valueMask; Dimension width, height; Dimension w, h; int x, y; static GC gc = (GC) NULL; Container *container = (Container *) client_data; if (!container->_xm_update_message) return; if (!gc) { XtVaGetValues(widget, XmNforeground, &values.foreground, NULL); if (container->font) valueMask = GCFont | GCForeground; else valueMask = GCForeground; values.font = container->font; gc = XCreateGC(display, root, valueMask, &values); } XClearArea(display, XtWindow(widget), 0, 0, 0, 0, FALSE); XtVaGetValues(widget, XmNwidth, &width, XmNheight, &height, NULL); XtVaGetValues(container->_workArea, XmNstringDirection, &direction, NULL); XmStringExtent(container->userFont, container->_xm_update_message, &w, &h); x = (Dimension)(width - w) / 2; y = (Dimension)(height - h) / 2; XmStringDraw(display, XtWindow(widget), container->userFont, container->_xm_update_message, gc, x, y, w, XmALIGNMENT_CENTER, direction, NULL); }
void XmLStringDrawDirection(Display *dpy, Window win, XmFontList fontlist, XmString string, GC gc, int x, int y, Dimension width, unsigned char alignment, unsigned char layout_direction, unsigned char drawing_direction) { Screen *screen; XFontStruct *fontStruct; XImage *sourceImage, *destImage; Pixmap pixmap; GC pixmapGC; /* int sourceWidth, sourceHeight;*/ int destWidth, destHeight; int stringWidth, stringHeight; int i, j, bytesPerLine; Dimension dW, dH; char *data; screen = DefaultScreenOfDisplay(dpy); XmStringExtent(fontlist, string, &dW, &dH); stringWidth = (int)dW; stringHeight = (int)dH; if (!stringWidth || !stringHeight) return; /* draw string into 1 bit deep pixmap */ pixmap = XCreatePixmap(dpy, win, stringWidth, stringHeight, 1); pixmapGC = XCreateGC(dpy, pixmap, 0, NULL); fontStruct = XLoadQueryFont(dpy, "fixed"); if (!fontStruct) { fprintf(stderr, "XmLStringDrawDirection: error - "); fprintf(stderr, "can't load fixed font\n"); return; } XSetFont(dpy, pixmapGC, fontStruct->fid); XSetBackground(dpy, pixmapGC, 0L); XSetForeground(dpy, pixmapGC, 0L); XFillRectangle(dpy, pixmap, pixmapGC, 0, 0, stringWidth, stringHeight); XSetForeground(dpy, pixmapGC, 1L); XmStringDraw(dpy, pixmap, fontlist, string, pixmapGC, 0, 0, stringWidth, XmALIGNMENT_BEGINNING, layout_direction, 0); XFreeFont(dpy, fontStruct); /* copy 1 bit deep pixmap into source image */ sourceImage = XGetImage(dpy, pixmap, 0, 0, stringWidth, stringHeight, 1, XYPixmap); XFreePixmap(dpy, pixmap); /* draw rotated text into destination image */ if (drawing_direction == XmSTRING_UP || drawing_direction == XmSTRING_DOWN) { destWidth = stringHeight; destHeight = stringWidth; } else { destWidth = stringWidth; destHeight = stringHeight; } bytesPerLine = (destWidth - 1) / 8 + 1; data = (char *)malloc(bytesPerLine * destHeight); destImage = XCreateImage(dpy, DefaultVisualOfScreen(screen), 1, XYBitmap, 0, data, destWidth, destHeight, 8, 0); for (i = 0; i < stringWidth; i++) for (j = 0; j < stringHeight; j++) { if (drawing_direction == XmSTRING_UP) XPutPixel(destImage, j, i, XGetPixel(sourceImage, stringWidth - i - 1, j)); else if (drawing_direction == XmSTRING_DOWN) XPutPixel(destImage, stringHeight - j - 1, stringWidth - i - 1, XGetPixel(sourceImage, stringWidth - i - 1, j)); else if (drawing_direction == XmSTRING_LEFT) XPutPixel(destImage, i, stringHeight - j - 1, XGetPixel(sourceImage, stringWidth - i - 1, j)); else XPutPixel(destImage, i, j, XGetPixel(sourceImage, i, j)); } XDestroyImage(sourceImage); /* copy rotated image into 1 bit deep pixmap */ pixmap = XCreatePixmap(dpy, win, destWidth, destHeight, 1); XPutImage(dpy, pixmap, pixmapGC, destImage, 0, 0, 0, 0, destWidth, destHeight); XDestroyImage(destImage); XFreeGC(dpy, pixmapGC); /* adjust position for alignment */ if (drawing_direction == XmSTRING_UP || drawing_direction == XmSTRING_DOWN) { if (alignment == XmALIGNMENT_BEGINNING) ; else if (alignment == XmALIGNMENT_CENTER) y += width / 2 - stringWidth / 2; else if (alignment == XmALIGNMENT_END) y += (int)width - stringWidth; } else { if (alignment == XmALIGNMENT_BEGINNING) ; else if (alignment == XmALIGNMENT_CENTER) x += width / 2 - stringWidth / 2; else if (alignment == XmALIGNMENT_END) x += (int)width - stringWidth; } /* draw the pixmap as a stipple in the window */ XSetStipple(dpy, gc, pixmap); XSetFillStyle(dpy, gc, FillStippled); XSetTSOrigin(dpy, gc, x % destWidth, y % destHeight); XFillRectangle(dpy, win, gc, x, y, destWidth, destHeight); XFreePixmap(dpy, pixmap); XSetFillStyle(dpy, gc, FillSolid); }
static void da_expose(Widget w, XtPointer client_data, XtPointer call_data) { XExposeEvent *e = &((XmDrawingAreaCallbackStruct *) call_data) ->event->xexpose; XmString *items, *selected_items, out_string, tmp_string; Boolean underline; int item_count, selected_count; Widget list = (Widget) client_data; Dimension width, height, extent, item_extent, string_height; int i; XmFontList font_list; XRectangle clip; /* Extract items, selected items and font from XmList */ XtVaGetValues(list, XmNitems, &items, XmNitemCount, &item_count, XmNselectedItems, &selected_items, XmNselectedItemCount, &selected_count, XmNfontList, &font_list, NULL); XtVaGetValues(w, XmNwidth, &width, XmNheight, &height, NULL); underline = (selected_count > 0); create_gc(w); extent = 0; out_string = NULL; /* * Form list items into a single compound string, inserting * separators where needed to avoid drawing outside the XmDrawingArea */ for (i = 0; i < item_count; i++) { item_extent = XmStringWidth(font_list, items[i]); if (out_string != NULL && (extent + item_extent > width)) { extent = 0; out_string = string_append(out_string, XmStringSeparatorCreate()); } tmp_string = XmStringConcat(out_string, items[i]); XmStringFree(out_string); out_string = tmp_string; extent = extent + item_extent; } string_height = XmStringHeight(font_list, out_string); clip.x = e->x; clip.y = e->y; clip.width = e->width; clip.height = e->height; XSetClipRectangles(XtDisplay(w), gc, 0, 0, &clip, 1, YXBanded); /* Draw compound string, underlining the selected item if any */ if (underline) XmStringDrawUnderline(XtDisplay(w), XtWindow(w), font_list, out_string, gc, 0, (height - string_height) / 2, width, XmALIGNMENT_CENTER, XmSTRING_DIRECTION_L_TO_R, NULL, selected_items[0]); else XmStringDraw(XtDisplay(w), XtWindow(w), font_list, out_string, gc, 0, (height - string_height) / 2, width, XmALIGNMENT_CENTER, XmSTRING_DIRECTION_L_TO_R, NULL); XmStringFree(out_string); }