Beispiel #1
0
void DrawCharacters(Page *page)
{
    size_t start = page->start;
    size_t i;
    for (i = start; i < page->end; i++) {
        short x = character_positions[i].x;
        short y = character_positions[i].y;

        if (IsPrint(text[i])) {
draw:
            ;
            XChar2b font_code;
            XFontStruct *font = SelectFont(text[i], &font_code);
            GC gc = XCreateGC(disp, back_buffer, 0, NULL);
            XCopyGC(disp, default_gc, GCForeground | GCBackground, gc);
            XSetFont(disp, gc, font->fid);
            XDrawString16(disp, back_buffer, gc,
                          x, y + (font->ascent - default_font->ascent), &font_code, 1);
            XFreeGC(disp, gc);
        } else {
            if (EqAscii2b(text[i], '\n')) {
                // DOWNWARDS ARROW WITH TIP LEFTWARDS
                XChar2b symbol = { .byte1 = 0x21, .byte2 = 0xb2 };
                XDrawString16(disp, back_buffer, control_gc,
                              x, y,
                              &symbol, 1);
            } else if (EqAscii2b(text[i], '\t')) {
                ;
            } else {
                goto draw;
            }
        }
    }
Beispiel #2
0
void Fl_Device::transformed_draw(const char *str, int n, float x, float y)
{
    if (font_gc != fl_gc) {
        font_gc = fl_gc;
        XSetFont(fl_display, fl_gc, current_font->fid);
    }

    int X = int(floor(x+.5f));
    int Y = int(floor(y+.5f));

#if HAVE_XUTF8
    char glyph[2];       // byte1 and byte2 value of the UTF-8 char
    XChar2b buf[128];    // drawing buffer
    int pos = 0;         // position in buffer
    int  ulen;           // byte length of the UTF-8 char
    unsigned int ucs;    // Unicode value of the UTF-8 char
    unsigned int no_spc; // Spacing char equivalent of a non-spacing char

    while(n > 0) {

        if(pos>120) {
            XDrawString16(fl_display, fl_window, fl_gc, X, Y, buf, pos);
            X += XTextWidth16(current_font, buf, pos);
            pos = 0;
        }

        ulen = fl_fast_utf2ucs((unsigned char*)str, n, &ucs);
        if (ulen < 1) ulen = 1;
        no_spc = fl_nonspacing(ucs);
        if(no_spc) ucs = no_spc;

        if(fl_ucs2fontmap(glyph, ucs, fl_fontsize->encoding_num) < 0) {
            // the char is not valid in this encoding
            fl_ucs2fontmap(glyph, '?', fl_fontsize->encoding_num);
        }

        if(no_spc) {
            XDrawString16(fl_display, fl_window, fl_gc, X, Y, buf, pos);
            X += XTextWidth16(current_font, buf, pos);
            pos = 0;
            (*buf).byte1 = glyph[1];
            (*buf).byte2 = glyph[0];
            X -= XTextWidth16(current_font, buf, 1);
        } else {
            (*(buf + pos)).byte1 = glyph[1];
            (*(buf + pos)).byte2 = glyph[0];
        }

        pos++;
        str += ulen;
        n-=ulen;
    }
    if(pos>0)
        XDrawString16(fl_display, fl_window, fl_gc, X, Y, buf, pos);
#else
    XDrawString(fl_display, fl_window, fl_gc, X, Y, str, n);
#endif
}
Beispiel #3
0
void MCOldFontlist::ctxt_drawtext(MCX11Context *ctxt, int2 x, int2 y, const char *s, uint2 l, MCFontStruct *of, Boolean image, bool p_unicode_override)
{
	MCOldFontStruct *f;
	f = static_cast<MCOldFontStruct *>(of);

	bool useUnicode = (f->max_byte1 > 0 || f->unicode) || p_unicode_override;

	if ( useUnicode ) 
	{
		uint2 x_l ;
		XChar2b x_s[l / 2];

		x_l = (l + 1) / 2;
		for(int i = 0; i < x_l; ++i)
			x_s[i] . byte1 = s[i * 2 + 1], x_s[i] . byte2 = s[i * 2];

		if (image)
		{
			XDrawImageString16(ctxt -> m_display, ctxt -> m_layers -> surface, ctxt -> m_gc, x - ctxt -> m_layers -> origin . x , y - ctxt -> m_layers -> origin . y , (const XChar2b *)x_s,
							   x_l);
			XDrawImageString16(ctxt -> m_display,             ctxt -> m_mask, ctxt -> m_gc1, x - ctxt -> m_layers -> origin . x , y - ctxt -> m_layers -> origin . y , (const XChar2b *)x_s,
							   x_l);
		}
		else
		{
			XDrawString16(ctxt -> m_display, ctxt -> m_layers -> surface, ctxt -> m_gc, x - ctxt -> m_layers -> origin . x , y - ctxt -> m_layers -> origin . y , (const XChar2b *)x_s,
						  x_l);
			XDrawString16(ctxt -> m_display,             ctxt -> m_mask, ctxt -> m_gc1, x - ctxt -> m_layers -> origin . x , y - ctxt -> m_layers -> origin . y , (const XChar2b *)x_s,
						  x_l);
		}
	}
	else 
	{
		if (image)
		{
			XDrawImageString(ctxt -> m_display, ctxt -> m_layers -> surface, ctxt -> m_gc, x - ctxt -> m_layers -> origin . x , y - ctxt -> m_layers -> origin . y , s, l);
			XDrawImageString(ctxt -> m_display,              ctxt -> m_mask, ctxt -> m_gc1, x - ctxt -> m_layers -> origin . x , y - ctxt -> m_layers -> origin . y , s, l);
		}
		else
		{
			XDrawString(ctxt -> m_display, ctxt -> m_layers -> surface, ctxt -> m_gc, x - ctxt -> m_layers -> origin . x , y - ctxt -> m_layers -> origin . y , s, l);
			XDrawString(ctxt -> m_display,              ctxt -> m_mask, ctxt -> m_gc1, x - ctxt -> m_layers -> origin . x , y - ctxt -> m_layers -> origin . y , s, l);
		}
	}

	ctxt -> update_mask ( 0, 
				  ( y - ctxt -> m_layers -> origin . y )  - f -> ascent, 
				  ctxt -> m_layers -> clip . width,
				  f -> ascent + f -> descent ) ;
}
Beispiel #4
0
void
polytext16_test(void)
{
  int num_strings = 50;
  int i;
  long totaltime;
  char buf[80];

  num_strings *= X.percent;

  GC_change_font(unicode_font,FALSE);

  XSync(X.dpy,0);
  start_timer();
  for (i=0;i<num_strings;++i) {
    XDrawString16(X.dpy,X.win,X.gc,(i%2 ? i : num_strings - i),10*i,
		  string16,sizeof(string16)/sizeof(XChar2b));
  }
  XSync(X.dpy,0);
  totaltime = end_timer();

  GC_change_font(X.fontname,FALSE);

  snprintf(buf,sizeof buf,"%d strings in %.2f seconds.",num_strings,
	  (double) totaltime/1000000.);
  show_result(buf);
}
Beispiel #5
0
/** Render string of 16-bit \a chars (foreground only) in \a pDrawable
 *  on the back-end server associated with \a pDrawable's screen.  If
 *  the offscreen optimization is enabled, only draw when \a pDrawable
 *  is at least partially visible. */
int dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC,
		  int x, int y, int count, unsigned short *chars)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
    dmxGCPrivPtr   pGCPriv = DMX_GET_GC_PRIV(pGC);
    unsigned long  n, i;
    int            w;
    CharInfoPtr    charinfo[255];
    Drawable       draw;

    GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)chars,
	      (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
	      &n, charinfo);

    /* Calculate text width */
    w = 0;
    for (i = 0; i < n; i++) w += charinfo[i]->metrics.characterWidth;

    if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
	DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);

	XDrawString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
		      x, y, (XChar2b *)chars, count);
	dmxSync(dmxScreen, FALSE);
    }

    return x+w;
}
Beispiel #6
0
void
XftDrawStringUtf8 (XftDraw	*draw,
		   XftColor	*color,
		   XftFont	*font,
		   int		x,
		   int		y,
		   XftChar8	*string,
		   int		len)
{
    if (font->core)
    {
	XChar2b	    *xc;
	XChar2b	    xcloc[XFT_CORE_N16LOCAL];
	int	    n;
	
	XftDrawCorePrepare (draw, color, font);
	xc = XftCoreConvertUtf8 (string, len, xcloc, &n);
	if (xc)
	{
	    XDrawString16 (draw->dpy, draw->drawable, draw->core.draw_gc, x, y, 
			   xc, n);
	}
	if (xc != xcloc)
	    free (xc);
    }
#ifdef FREETYPE2
    else if (XftDrawRenderPrepare (draw, color, font, XFT_DRAW_SRC_TEXT))
    {
	XftRenderStringUtf8 (draw->dpy,
			     draw->render.src[XFT_DRAW_SRC_TEXT].pict, 
			     font->u.ft.font,
			     draw->render.pict, 0, 0, x, y, string, len);
    }
#endif
}
Beispiel #7
0
/*
 * Generate OpenGL-compatible bitmap.
 */
static void
fill_bitmap(Display * dpy, Window win, GC gc,
	    unsigned int width, unsigned int height,
	    int x0, int y0, unsigned int c, GLubyte * bitmap)
{
   XImage *image;
   unsigned int x, y;
   Pixmap pixmap;
   XChar2b char2b;

   pixmap = XCreatePixmap(dpy, win, 8 * width, height, 1);
   XSetForeground(dpy, gc, 0);
   XFillRectangle(dpy, pixmap, gc, 0, 0, 8 * width, height);
   XSetForeground(dpy, gc, 1);

   char2b.byte1 = (c >> 8) & 0xff;
   char2b.byte2 = (c & 0xff);

   XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1);

   image = XGetImage(dpy, pixmap, 0, 0, 8 * width, height, 1, XYPixmap);
   if (image) {
      /* Fill the bitmap (X11 and OpenGL are upside down wrt each other).  */
      for (y = 0; y < height; y++)
	 for (x = 0; x < 8 * width; x++)
	    if (XGetPixel(image, x, y))
	       bitmap[width * (height - y - 1) + x / 8] |=
		  (1 << (7 - (x % 8)));
      XDestroyImage(image);
   }

   XFreePixmap(dpy, pixmap);
}
Beispiel #8
0
void debrush_do_draw_string_default_bmf(
        DEBrush *brush,
        int x, int y, const char *str,
        int len, bool needfill,
        DEColourGroup *colours)
{
    GC gc=brush->d->normal_gc;

    if(brush->d->font==NULL)
        return;

    XSetForeground(ioncore_g.dpy, gc, PIXEL(colours->fg));

    if(!needfill){
        if(brush->d->font->fontset!=NULL){
#ifdef CF_DE_USE_XUTF8
            if(ioncore_g.enc_utf8)
                Xutf8DrawString(ioncore_g.dpy, brush->win,
                                brush->d->font->fontset,
                                gc, x, y, str, len);
            else
#endif
                XmbDrawString(ioncore_g.dpy, brush->win,
                              brush->d->font->fontset,
                              gc, x, y, str, len);
        }else if(brush->d->font->fontstruct!=NULL){
            if(ioncore_g.enc_utf8){
                XChar2b *str16; int len16=0;
                toucs(str, len, &str16, &len16);
                XDrawString16(ioncore_g.dpy, brush->win, gc, x, y, str16, len16);
                free(str16);
            }else{
                XDrawString(ioncore_g.dpy, brush->win, gc, x, y, str, len);
            }
        }
    }else{
        XSetBackground(ioncore_g.dpy, gc, PIXEL(colours->bg));
        if(brush->d->font->fontset!=NULL){
#ifdef CF_DE_USE_XUTF8
            if(ioncore_g.enc_utf8)
                Xutf8DrawImageString(ioncore_g.dpy, brush->win,
                                     brush->d->font->fontset,
                                     gc, x, y, str, len);
            else
#endif
                XmbDrawImageString(ioncore_g.dpy, brush->win,
                                   brush->d->font->fontset,
                                   gc, x, y, str, len);
        }else if(brush->d->font->fontstruct!=NULL){
            if(ioncore_g.enc_utf8){
                XChar2b *str16; int len16=0;
                toucs(str, len, &str16, &len16);
                XDrawImageString16(ioncore_g.dpy, brush->win, gc, x, y, str16, len16);
                free(str16);
            }else{
                XDrawImageString(ioncore_g.dpy, brush->win, gc, x, y, str, len);
            }
        }
    }
}
Beispiel #9
0
Datei: xfont.c Projekt: knaka/src
int
main(int argc, char *argv[])
{
    Display        *display;
    int             screen;
    GC              gc;
    Window          window;
    XWMHints        hints;
    Atom            protocols;
    XEvent          event;
    unsigned long   mask;
    Font            xfont1, xfont2;

    display = XOpenDisplay("");
    screen = DefaultScreen(display);
    gc = DefaultGC(display, screen);

    /*
     * Font names are hard-coded.
     */
    xfont1 = XLoadFont(display, "a14");
    xfont2 = XLoadFont(display, "k14");

    window = XCreateSimpleWindow(display, RootWindow(display, screen),
     0, 0, W_WIDTH, W_HEIGHT, 2,
     BlackPixel(display, screen), WhitePixel(display, screen));
    XStoreName(display, window, "XFontStruct demo");

    hints.flags = InputHint;
    hints.input = True;
    XSetWMHints(display, window, &hints);
    protocols = XInternAtom(display, "WM_DELETE_WINDOW", True);
    XSetWMProtocols(display, window, &protocols, 1);

    mask = ExposureMask;
    XSelectInput(display, window, mask);

    XMapWindow(display, window);

    for (;;) {
        XNextEvent(display, &event);
        if (XFilterEvent(&event, window) == True)
            continue;
        switch (event.type) {
            case Expose: {
                XSetFont(display, gc, xfont1);
                XDrawString(display, window, gc, 10, 50, "abcdef", 6);
                XSetFont(display, gc, xfont2);
                /* JIS */
                XDrawString16(display, window, gc, 10, 80,
                 (XChar2b *) "\x24\x22\x24\x24", 4);
                break;
            }
            default: {
                break;
            }
        }
    }
}
Beispiel #10
0
static void X11DRV_DrawString_normal( fontObject* pfo, Display* pdisp,
                                      Drawable d, GC gc, int x, int y,
                                      XChar2b* pstr, int count )
{
    wine_tsx11_lock();
    XDrawString16( pdisp, d, gc, x, y, pstr, count );
    wine_tsx11_unlock();
}
Beispiel #11
0
static void
_XawLabelDraw16(Display *dpy, Drawable d, GC gc, int x, int y,
		char *str, int n)
{
    int i;
    XChar2b *ptr;

    if (n > buf2blen) {
	buf2b = (XChar2b *)XtRealloc((char *)buf2b, n * sizeof(XChar2b));
	buf2blen = n;
    }
    for (ptr = buf2b, i = n; --i >= 0; ptr++) {
	ptr->byte1 = *str++;
	ptr->byte2 = *str++;
    }
    XDrawString16(dpy, d, gc, x, y, buf2b, n);
}
Beispiel #12
0
/* gdk_x11_draw_text
 *
 * Modified by Li-Da Lho to draw 16 bits and Multibyte strings
 *
 * Interface changed: add "GdkFont *font" to specify font or fontset explicitely
 */
static void
gdk_x11_draw_text (GdkDrawable *drawable,
		   GdkFont     *font,
		   GdkGC       *gc,
		   gint         x,
		   gint         y,
		   const gchar *text,
		   gint         text_length)
{
  GdkDrawableImplX11 *impl;
  Display *xdisplay;

  impl = GDK_DRAWABLE_IMPL_X11 (drawable);
  xdisplay = GDK_SCREEN_XDISPLAY (impl->screen);
  
  if (font->type == GDK_FONT_FONT)
    {
      XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT (font);
      XSetFont(xdisplay, GDK_GC_GET_XGC (gc), xfont->fid);
      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
	{
	  XDrawString (xdisplay, impl->xid,
		       GDK_GC_GET_XGC (gc), x, y, text, text_length);
	}
      else
	{
	  XDrawString16 (xdisplay, impl->xid,
			 GDK_GC_GET_XGC (gc), x, y, (XChar2b *) text, text_length / 2);
	}
    }
  else if (font->type == GDK_FONT_FONTSET)
    {
      XFontSet fontset = (XFontSet) GDK_FONT_XFONT (font);
      XmbDrawString (xdisplay, impl->xid,
		     fontset, GDK_GC_GET_XGC (gc), x, y, text, text_length);
    }
  else
    g_error("undefined font type\n");
}
Beispiel #13
0
/*ARGSUSED*/
static void
XawLabelRedisplay(Widget gw, XEvent *event, Region region)
{
    LabelWidget w = (LabelWidget)gw;
    GC gc;

    if (*Superclass->core_class.expose != NULL)
	(*Superclass->core_class.expose)(gw, event, region);

    gc = XtIsSensitive(gw) ? w->label.normal_GC : w->label.gray_GC;
#ifdef notdef
    if (region != NULL)
	XSetRegion(XtDisplay(gw), gc, region);
#endif /*notdef*/

    if (w->label.pixmap == None) {
	int len = w->label.label_len;
	char *label = w->label.label;
	Position y = w->label.label_y + w->label.font->max_bounds.ascent;
	Position ksy = w->label.label_y;

	/* display left bitmap */
	if (w->label.left_bitmap && w->label.lbm_width != 0)
	    XCopyPlane (XtDisplay(gw), w->label.left_bitmap, XtWindow(gw), gc,
			0, 0, w->label.lbm_width, w->label.lbm_height,
			w->label.internal_width,
			w->label.internal_height + w->label.lbm_y, 1L);

	if (w->simple.international == True) {
	    XFontSetExtents *ext = XExtentsOfFontSet(w->label.fontset);

	    ksy += XawAbs(ext->max_ink_extent.y);

	    if (len == MULTI_LINE_LABEL) {
		char *nl;

		while ((nl = index(label, '\n')) != NULL) {
		    XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset,
				  gc, w->label.label_x, ksy, label,
				  (int)(nl - label));
		    ksy += ext->max_ink_extent.height;
		    label = nl + 1;
		}
		len = strlen(label);
	    }
	    if (len)
		XmbDrawString(XtDisplay(w), XtWindow(w), w->label.fontset, gc,
			      w->label.label_x, ksy, label, len);
	}
	else {
	    if (len == MULTI_LINE_LABEL) {
		char *nl;

		while ((nl = index(label, '\n')) != NULL) {
		    if (w->label.encoding)
			XDrawString16(XtDisplay(gw), XtWindow(gw), gc,
				      w->label.label_x, y,
				      (XChar2b *)label, (int)(nl - label) / 2);
		    else
			XDrawString(XtDisplay(gw), XtWindow(gw), gc,
				    w->label.label_x, y, label, (int)(nl - label));
		    y += w->label.font->max_bounds.ascent +
			 w->label.font->max_bounds.descent;
		    label = nl + 1;
		}
		len = strlen(label);
	    }
	    if (len) {
		if (w->label.encoding)
		    XDrawString16(XtDisplay(gw), XtWindow(gw), gc,
				  w->label.label_x, y, (XChar2b *)label, len / 2);
		else
		    XDrawString(XtDisplay(gw), XtWindow(gw), gc,
				w->label.label_x, y, label, len);
	    }
	}
    }
    else if (w->label.label_len == 1)
	XCopyPlane(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc,
		   0, 0, w->label.label_width, w->label.label_height,
		   w->label.label_x, w->label.label_y, 1L);
    else
	XCopyArea(XtDisplay(gw), w->label.pixmap, XtWindow(gw), gc,
		  0, 0, w->label.label_width, w->label.label_height,
		  w->label.label_x, w->label.label_y);

#ifdef notdef
    if (region != NULL)
	XSetClipMask(XtDisplay(gw), gc, (Pixmap)None);
#endif /* notdef */
}
Beispiel #14
0
void
my_gdk_draw_text(GdkDrawable *drawable,
                 GdkFont     *font,
                 GdkGC       *gc,
                 gint         x,
                 gint         y,
                 const gchar *text,
                 gint         text_length)
{
#ifdef MOZ_WIDGET_GTK
  GdkWindowPrivate *drawable_private;
  GdkFontPrivate *font_private;
  GdkGCPrivate *gc_private;
#endif /* MOZ_WIDGET_GTK */

  g_return_if_fail (drawable != NULL);
  g_return_if_fail (font != NULL);
  g_return_if_fail (gc != NULL);
  g_return_if_fail (text != NULL);

#ifdef MOZ_WIDGET_GTK
  drawable_private = (GdkWindowPrivate*) drawable;
  if (drawable_private->destroyed)
    return;

  gc_private = (GdkGCPrivate*) gc;
  font_private = (GdkFontPrivate*) font;
#endif /* MOZ_WIDGET_GTK */
#ifdef MOZ_WIDGET_GTK2
  if (GDK_IS_WINDOW(drawable) && GDK_WINDOW_OBJECT(drawable)->destroyed)
    return;
#endif /* MOZ_WIDGET_GTK2 */

  if (font->type == GDK_FONT_FONT)
  {
#ifdef MOZ_WIDGET_GTK
    XFontStruct *xfont = (XFontStruct *) font_private->xfont;
#endif /* MOZ_WIDGET_GTK */
#ifdef MOZ_WIDGET_GTK2
    XFontStruct *xfont = (XFontStruct *) GDK_FONT_XFONT(font);
#endif /* MOZ_WIDGET_GTK2 */

    // gdk does this... we don't need it..
    //    XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid);

    // We clamp the sizes down to 32768 which is the maximum width of
    // a window.  Even if a font was 1 pixel high and started at the
    // left, the maximum size of a draw request could only be 32k.

    if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
    {
#ifdef MOZ_WIDGET_GTK
      XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
                   gc_private->xgc, x, y, text, MIN(text_length, 32768));
#endif /* MOZ_WIDGET_GTK */
#ifdef MOZ_WIDGET_GTK2
      XDrawString (GDK_WINDOW_XDISPLAY(drawable), GDK_DRAWABLE_XID(drawable),
                   GDK_GC_XGC(gc), x, y, text, MIN(text_length, 32768));
#endif /* MOZ_WIDGET_GTK2 */
    }
    else
    {
#ifdef MOZ_WIDGET_GTK
      XDrawString16 (drawable_private->xdisplay, drawable_private->xwindow,
                     gc_private->xgc, x, y, (XChar2b *) text, 
                     MIN((text_length / 2), 32768));
#endif /* MOZ_WIDGET_GTK */
#ifdef MOZ_WIDGET_GTK2
      XDrawString16 (GDK_WINDOW_XDISPLAY(drawable), GDK_DRAWABLE_XID(drawable),
                     GDK_GC_XGC(gc), x, y, (XChar2b *) text, 
                     MIN((text_length / 2), 32768));
#endif /* MOZ_WIDGET_GTK2 */
    }
  }
  else if (font->type == GDK_FONT_FONTSET)
  {
#ifdef MOZ_WIDGET_GTK
    XFontSet fontset = (XFontSet) font_private->xfont;
    XmbDrawString (drawable_private->xdisplay, drawable_private->xwindow,
                   fontset, gc_private->xgc, x, y, text, text_length);
#endif /* MOZ_WIDGET_GTK */
#ifdef MOZ_WIDGET_GTK2
    XFontSet fontset = (XFontSet) GDK_FONT_XFONT(font);
    XmbDrawString (GDK_WINDOW_XDISPLAY(drawable), GDK_DRAWABLE_XID(drawable),
                   fontset, GDK_GC_XGC(gc), x, y, text, text_length);
#endif /* MOZ_WIDGET_GTK2 */
  }
  else
    g_error("undefined font type\n");
}
Beispiel #15
0
void
captureXFont(Display * dpy, Font font, char *xfont, char *name)
{
  int first, last, count;
  int cnt, len;
  Pixmap offscreen;
  Window drawable;
  XFontStruct *fontinfo;
  XImage *image;
  GC xgc;
  XGCValues values;
  int width, height;
  int i, j, k;
  XCharStruct *charinfo;
  XChar2b character;
  GLubyte *bitmapData;
  int x, y;
  int spanLength;
  int charWidth, charHeight, maxSpanLength, pixwidth;
  int grabList[MAX_GLYPHS_PER_GRAB];
  int glyphsPerGrab = MAX_GLYPHS_PER_GRAB;
  int numToGrab;
  int rows, pages, byte1, byte2, index;
  int nullBitmap;

  drawable = RootWindow(dpy, DefaultScreen(dpy));

  fontinfo = XQueryFont(dpy, font);
  pages = fontinfo->max_char_or_byte2 - fontinfo->min_char_or_byte2 + 1;
  first = (fontinfo->min_byte1 << 8) + fontinfo->min_char_or_byte2;
  last = (fontinfo->max_byte1 << 8) + fontinfo->max_char_or_byte2;
  count = last - first + 1;

  width = fontinfo->max_bounds.rbearing -
    fontinfo->min_bounds.lbearing;
  height = fontinfo->max_bounds.ascent +
    fontinfo->max_bounds.descent;
  /* 16-bit fonts have more than one row; indexing into
     per_char is trickier. */
  rows = fontinfo->max_byte1 - fontinfo->min_byte1 + 1;

  maxSpanLength = (width + 7) / 8;
  /* For portability reasons we don't use alloca for
     bitmapData, but we could. */
  bitmapData = malloc(height * maxSpanLength);
  /* Be careful determining the width of the pixmap; the X
     protocol allows pixmaps of width 2^16-1 (unsigned short
     size) but drawing coordinates max out at 2^15-1 (signed
     short size).  If the width is too large, we need to limit
     the glyphs per grab. */
  if ((glyphsPerGrab * 8 * maxSpanLength) >= (1 << 15)) {
    glyphsPerGrab = (1 << 15) / (8 * maxSpanLength);
  }
  pixwidth = glyphsPerGrab * 8 * maxSpanLength;
  offscreen = XCreatePixmap(dpy, drawable, pixwidth, height, 1);

  values.font = font;
  values.background = 0;
  values.foreground = 0;
  xgc = XCreateGC(dpy, offscreen,
    GCFont | GCBackground | GCForeground, &values);
  XFillRectangle(dpy, offscreen, xgc, 0, 0,
    8 * maxSpanLength * glyphsPerGrab, height);
  XSetForeground(dpy, xgc, 1);

  numToGrab = 0;
  if (fontinfo->per_char == NULL) {
    charinfo = &(fontinfo->min_bounds);
    charWidth = charinfo->rbearing - charinfo->lbearing;
    charHeight = charinfo->ascent + charinfo->descent;
    spanLength = (charWidth + 7) / 8;
  }
  printf("\n/* GENERATED FILE -- DO NOT MODIFY */\n\n");
  printf("#include \"glutbitmap.h\"\n\n");
  for (i = first; count; i++, count--) {
    int undefined;
    if (rows == 1) {
      undefined = (fontinfo->min_char_or_byte2 > i ||
        fontinfo->max_char_or_byte2 < i);
    } else {
      byte2 = i & 0xff;
      byte1 = i >> 8;
      undefined = (fontinfo->min_char_or_byte2 > byte2 ||
        fontinfo->max_char_or_byte2 < byte2 ||
        fontinfo->min_byte1 > byte1 ||
        fontinfo->max_byte1 < byte1);

    }
    if (undefined) {
      goto PossiblyDoGrab;
    }
    if (fontinfo->per_char != NULL) {
      if (rows == 1) {
        index = i - fontinfo->min_char_or_byte2;
      } else {
        byte2 = i & 0xff;
        byte1 = i >> 8;
        index =
          (byte1 - fontinfo->min_byte1) * pages +
          (byte2 - fontinfo->min_char_or_byte2);
      }
      charinfo = &(fontinfo->per_char[index]);
      charWidth = charinfo->rbearing - charinfo->lbearing;
      charHeight = charinfo->ascent + charinfo->descent;
      if (charWidth == 0 || charHeight == 0) {
        if (charinfo->width != 0) {
          /* Still must move raster pos even if empty character 

           */
          outputChar(i, 0, 0, 0, 0, charinfo->width, 0);
        }
        goto PossiblyDoGrab;
      }
    }
    grabList[numToGrab] = i;
    character.byte2 = i & 255;
    character.byte1 = i >> 8;

    /* XXX We could use XDrawImageString16 which would also
       paint the backing rectangle but X server bugs in some
       scalable font rasterizers makes it more effective to do
       XFillRectangles to clear the pixmap and then
       XDrawImage16 for the text.  */
    XDrawString16(dpy, offscreen, xgc,
      -charinfo->lbearing + 8 * maxSpanLength * numToGrab,
      charinfo->ascent, &character, 1);

    numToGrab++;

  PossiblyDoGrab:

    if (numToGrab >= glyphsPerGrab || count == 1) {
      image = XGetImage(dpy, offscreen,
        0, 0, pixwidth, height, 1, XYPixmap);
      for (j = numToGrab - 1; j >= 0; j--) {
        if (fontinfo->per_char != NULL) {
          byte2 = grabList[j] & 0xff;
          byte1 = grabList[j] >> 8;
          index =
            (byte1 - fontinfo->min_byte1) * pages +
            (byte2 - fontinfo->min_char_or_byte2);
          charinfo = &(fontinfo->per_char[index]);
          charWidth = charinfo->rbearing - charinfo->lbearing;
          charHeight = charinfo->ascent + charinfo->descent;
          spanLength = (charWidth + 7) / 8;
        }
        memset(bitmapData, 0, height * spanLength);
        for (y = 0; y < charHeight; y++) {
          for (x = 0; x < charWidth; x++) {
            if (XGetPixel(image, j * maxSpanLength * 8 + x,
                charHeight - 1 - y)) {
              /* Little endian machines (such as DEC Alpha)
                 could  benefit from reversing the bit order
                 here and changing the GL_UNPACK_LSB_FIRST
                 parameter in glutBitmapCharacter to GL_TRUE. */
              bitmapData[y * spanLength + x / 8] |=
                (1 << (7 - (x & 7)));
            }
          }
        }
        if (PRINTABLE(grabList[j])) {
          printf("/* char: 0x%x '%c' */\n\n",
            grabList[j], grabList[j]);
        } else {
          printf("/* char: 0x%x */\n\n", grabList[j]);
        }

        /* Determine if the bitmap is null. */
        nullBitmap = 1;
        len = (charinfo->ascent + charinfo->descent) *
          ((charinfo->rbearing - charinfo->lbearing + 7) / 8);
        cnt = 0;
        while (cnt < len) {
          for (k = 0; k < 16 && cnt < len; k++, cnt++) {
            if (bitmapData[cnt] != 0) {
              nullBitmap = 0;
            }
          }
        }

        if (!nullBitmap) {
          printf("static const GLubyte ch%ddata[] = {\n", grabList[j]);
          len = (charinfo->ascent + charinfo->descent) *
            ((charinfo->rbearing - charinfo->lbearing + 7) / 8);
          cnt = 0;
          while (cnt < len) {
            for (k = 0; k < 16 && cnt < len; k++, cnt++) {
              printf("0x%x,", bitmapData[cnt]);
            }
            printf("\n");
          }
          printf("};\n\n");
        } else {
          charWidth = 0;
          charHeight = 0;
        }

        outputChar(grabList[j], charWidth, charHeight,
          -charinfo->lbearing, charinfo->descent,
          charinfo->width, !nullBitmap);
      }
      XDestroyImage(image);
      numToGrab = 0;
      if (count > 0) {
        XSetForeground(dpy, xgc, 0);
        XFillRectangle(dpy, offscreen, xgc, 0, 0,
          8 * maxSpanLength * glyphsPerGrab, height);
        XSetForeground(dpy, xgc, 1);
      }
    }
Beispiel #16
0
// 次のページの開始位置、あるいは文書の終端 (== text_length) を返す。
size_t FillPage(size_t start, Page *page, bool draw)
{
    XWindowAttributes attrs;
    XGetWindowAttributes(disp, win, &attrs);

    // ページのサイズ。
    const int LEFT_MARGIN	= 50;
    const int RIGHT_MARGIN	= attrs.width - LEFT_MARGIN;
    const int TOP_MARGIN	= 50;
    const int BOTTOM_MARGIN	= attrs.height - TOP_MARGIN;

    const XChar2b sp = { 0x00, 0x21 };
    const int EM = GetCharWidth(sp);

    // 行の高さ。
    const int LINE_HEIGHT = 22;

    // 現在の文字の描画位置。
    int x = LEFT_MARGIN, y = TOP_MARGIN + font->ascent;

    size_t i;
    for (i = start; i < text_length; i++) {
	// カーソルの描画
	if (draw && i == cursor_position) {
	    XFillRectangle(disp, win, cursor_gc,
			   x, y - font->ascent,
			   CURSOR_WIDTH, font->ascent + font->descent);
	}

	if (IsPrint(text[i])) {
	    // 印字可能文字の場合。

	    int width = GetCharWidth(text[i]);

	    // この文字を描画すると右マージンにかかるようなら改行する。
	    // ただし、行頭に居る場合は改行しない。
	    if ( x + width > RIGHT_MARGIN &&
		 !ForbiddenAtStart(text[i]) && // 行頭禁止文字ならばぶらさげる
		 x != LEFT_MARGIN ) {
		y += LINE_HEIGHT;
		x = LEFT_MARGIN;

		// ページにも収まらない場合、この位置で終了する。
		if (y + font->descent > BOTTOM_MARGIN) {
		    page->start = start;
		    page->end = i;
		    return i;
		}
	    }

	    if (draw) XDrawString16(disp, win, gc,
				    x, y,
				    &text[i], 1);
	    x += width;
	} else {
	    // ラインフィードで改行する。
	    if (EqAscii2b(text[i], '\n')) {
		if (draw) {
		    // DOWNWARDS ARROW WITH TIP LEFTWARDS
		    XChar2b symbol = { .byte1 = 0x21, .byte2 = 0xb2 };
		    XDrawString16(disp, win, control_gc,
				  x, y,
				  &symbol, 1);
		}
		y += LINE_HEIGHT;
		x = LEFT_MARGIN;

		// ページにも収まらない場合、次の位置で終了する。
		// ページ区切り位置での改行は持ち越さない。
		if (y + font->descent > BOTTOM_MARGIN) {
		    page->start = start;
		    page->end = i + 1;
		    return i + 1;
		}
	    } else if (EqAscii2b(text[i], '\t')) {
		int tab = EM * 8;
		x = LEFT_MARGIN + (((x - LEFT_MARGIN) / tab) + 1) * tab;
	    }
	}
    }
    if (draw && i == cursor_position) {
	XFillRectangle(disp, win, cursor_gc,
		       x, y - font->ascent,
		       CURSOR_WIDTH, font->ascent + font->descent);
    }
    if (draw) XDrawString(disp, win, control_gc,
			  x, y,
			  "[EOF]", 5);
    // 全てのテキストを配置した。
    page->start = start;
    page->end = text_length;
    return text_length;
}
Beispiel #17
0
/**
 * Generate OpenGL-compatible bitmap by drawing an X character glyph
 * to an off-screen pixmap, then getting the image and testing pixels.
 * \param width  bitmap width in pixels
 * \param height  bitmap height in pixels
 */
static void
fill_bitmap(Display *dpy, Pixmap pixmap, GC gc,
	    unsigned int bitmapWidth, unsigned int bitmapHeight,
            unsigned int charWidth, unsigned int charHeight,
	    int xPos, int yPos, unsigned int c, GLubyte * bitmap,
            int rotation)
{
   const int bytesPerRow = (bitmapWidth + 7) / 8;
   XImage *image;
   XChar2b char2b;

   /* clear pixmap to 0 */
   XSetForeground(dpy, gc, 0);
   XFillRectangle(dpy, pixmap, gc, 0, 0, charWidth, charHeight);

   /* The glyph is drawn snug up against the left/top edges of the pixmap */
   XSetForeground(dpy, gc, 1);
   char2b.byte1 = (c >> 8) & 0xff;
   char2b.byte2 = (c & 0xff);
   XDrawString16(dpy, pixmap, gc, xPos, yPos, &char2b, 1);

   /* initialize GL bitmap */
   memset(bitmap, 0, bytesPerRow * bitmapHeight);

   image = XGetImage(dpy, pixmap, 0, 0, charWidth, charHeight, 1, XYPixmap);
   if (image) {
      /* Set appropriate bits in the GL bitmap.
       * Note: X11 and OpenGL are upside down wrt each other).
       */
      unsigned int x, y;
      if (rotation == 0) {
         for (y = 0; y < charHeight; y++) {
            for (x = 0; x < charWidth; x++) {
               if (XGetPixel(image, x, y)) {
                  int y2 = bitmapHeight - y - 1;
                  bitmap[bytesPerRow * y2 + x / 8] |= (1 << (7 - (x % 8)));
               }
            }
         }
      }
      else if (rotation == 90) {
         for (y = 0; y < charHeight; y++) {
            for (x = 0; x < charWidth; x++) {
               if (XGetPixel(image, x, y)) {
                  int x2 = y;
                  int y2 = x;
                  bitmap[bytesPerRow * y2 + x2 / 8] |= (1 << (7 - (x2 % 8)));
               }
            }
         }
      }
      else if (rotation == 180) {
         for (y = 0; y < charHeight; y++) {
            for (x = 0; x < charWidth; x++) {
               if (XGetPixel(image, x, y)) {
                  int x2 = charWidth - x - 1;
                  bitmap[bytesPerRow * y + x2 / 8] |= (1 << (7 - (x2 % 8)));
               }
            }
         }
      }
      else {
         for (y = 0; y < charHeight; y++) {
            for (x = 0; x < charWidth; x++) {
               if (XGetPixel(image, x, y)) {
                  int x2 = charHeight - y - 1;
                  int y2 = charWidth - x - 1;
                  bitmap[bytesPerRow * y2 + x2 / 8] |= (1 << (7 - (x2 % 8)));
               }
            }
         }
      }
      XDestroyImage(image);
   }
}
Beispiel #18
0
FontInfoPtr
SuckGlyphsFromServer(Display * dpy, Font font)
{
    Pixmap          offscreen;
    XFontStruct    *fontinfo;
    XImage         *image;
    GC              xgc;
    XGCValues       values;
    int             numchars;
    int             width, height, pixwidth;
    int             i, j;
    XCharStruct    *charinfo;
    XChar2b         character;
    char           *bitmapData;
    int             x, y;
    int             spanLength;
    int             charWidth, charHeight, maxSpanLength;
    int             grabList[MAX_GLYPHS_PER_GRAB];
    int             glyphsPerGrab = MAX_GLYPHS_PER_GRAB;
    int             numToGrab, thisglyph;
    FontInfoPtr     myfontinfo;

    fontinfo = XQueryFont(dpy, font);
    if (!fontinfo)
	return NULL;

    numchars = fontinfo->max_char_or_byte2 - fontinfo->min_char_or_byte2 + 1;
    if (numchars < 1)
	return NULL;

    myfontinfo = (FontInfoPtr) malloc(sizeof(FontInfo) + (numchars - 1) * sizeof(PerCharInfo));
    if (!myfontinfo)
	return NULL;

    myfontinfo->min_char = fontinfo->min_char_or_byte2;
    myfontinfo->max_char = fontinfo->max_char_or_byte2;
    myfontinfo->max_ascent = fontinfo->max_bounds.ascent;
    myfontinfo->max_descent = fontinfo->max_bounds.descent;
    myfontinfo->dlist_base = 0;

    width = fontinfo->max_bounds.rbearing - fontinfo->min_bounds.lbearing;
    height = fontinfo->max_bounds.ascent + fontinfo->max_bounds.descent;

    maxSpanLength = (width + 7) / 8;
    /*
     * Be careful determining the width of the pixmap; the X protocol allows
     * pixmaps of width 2^16-1 (unsigned short size) but drawing coordinates
     * max out at 2^15-1 (signed short size).  If the width is too large,
     * we need to limit the glyphs per grab.
     */
    if ((glyphsPerGrab * 8 * maxSpanLength) >= (1 << 15)) {
	glyphsPerGrab = (1 << 15) / (8 * maxSpanLength);
    }
    pixwidth = glyphsPerGrab * 8 * maxSpanLength;
    offscreen = XCreatePixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)),
			      pixwidth, height, 1);

    values.font = font;
    values.background = 0;
    values.foreground = 0;
    xgc = XCreateGC(dpy, offscreen, GCFont | GCBackground | GCForeground, &values);

    XFillRectangle(dpy, offscreen, xgc, 0, 0, 8 * maxSpanLength * glyphsPerGrab, height);
    XSetForeground(dpy, xgc, 1);

    numToGrab = 0;
    if (fontinfo->per_char == NULL) {
	charinfo = &(fontinfo->min_bounds);
	charWidth = charinfo->rbearing - charinfo->lbearing;
	charHeight = charinfo->ascent + charinfo->descent;
	spanLength = (charWidth + 7) / 8;
    }
    for (i = 0; i < numchars; i++) {
	if (fontinfo->per_char != NULL) {
	    charinfo = &(fontinfo->per_char[i]);
	    charWidth = charinfo->rbearing - charinfo->lbearing;
	    charHeight = charinfo->ascent + charinfo->descent;
	    if (charWidth == 0 || charHeight == 0) {
		/* Still must move raster pos even if empty character */
		myfontinfo->glyph[i].width = 0;
		myfontinfo->glyph[i].height = 0;
		myfontinfo->glyph[i].xoffset = 0;
		myfontinfo->glyph[i].yoffset = 0;
		myfontinfo->glyph[i].advance = charinfo->width;
		myfontinfo->glyph[i].bitmap = NULL;
		goto PossiblyDoGrab;
	    }
	}
	grabList[numToGrab] = i;

	/* XXX is this right for large fonts? */
	character.byte2 = (i + fontinfo->min_char_or_byte2) & 255;
	character.byte1 = (i + fontinfo->min_char_or_byte2) >> 8;

	/*
	 * XXX we could use XDrawImageString16 which would also paint the
	 * backing rectangle but X server bugs in some scalable font
	 * rasterizers makes it more effective to do XFillRectangles to clear
	 * the pixmap and XDrawImage16 for the text.
	 */
	XDrawString16(dpy, offscreen, xgc,
		      -charinfo->lbearing + 8 * maxSpanLength * numToGrab,
		      charinfo->ascent, &character, 1);

	numToGrab++;

      PossiblyDoGrab:

	if (numToGrab >= glyphsPerGrab || i == numchars - 1) {
	    image = XGetImage(dpy, offscreen,
		  0, 0, pixwidth, height, 1, XYPixmap);
	    for (j = 0; j < numToGrab; j++) {
		thisglyph = grabList[j];
		if (fontinfo->per_char != NULL) {
		    charinfo = &(fontinfo->per_char[thisglyph]);
		    charWidth = charinfo->rbearing - charinfo->lbearing;
		    charHeight = charinfo->ascent + charinfo->descent;
		    spanLength = (charWidth + 7) / 8;
		}
		bitmapData = calloc(height * spanLength, sizeof(char));
		if (!bitmapData)
		    goto FreeFontAndReturn;
                DEBUG_GLYPH4("index %d, glyph %d (%d by %d)\n",
		    j, thisglyph + fontinfo->min_char_or_byte2, charWidth, charHeight);
		for (y = 0; y < charHeight; y++) {
		    for (x = 0; x < charWidth; x++) {
			/*
			 * XXX The algorithm used to suck across the font ensures
			 * that each glyph begins on a byte boundary.  In theory
			 * this would make it convienent to copy the glyph into
			 * a byte oriented bitmap.  We actually use the XGetPixel
			 * function to extract each pixel from the image which is
			 * not that efficient.  We could either do tighter packing
			 * in the pixmap or more efficient extraction from the
			 * image.  Oh well.
			 */
			if (XGetPixel(image, j * maxSpanLength * 8 + x, charHeight - 1 - y)) {
			    DEBUG_GLYPH("x");
			    bitmapData[y * spanLength + x / 8] |= (1 << (x & 7));
			} else {
			    DEBUG_GLYPH(" ");
			}
		    }
		    DEBUG_GLYPH("\n");
		}
		myfontinfo->glyph[thisglyph].width = charWidth;
		myfontinfo->glyph[thisglyph].height = charHeight;
		myfontinfo->glyph[thisglyph].xoffset = -charinfo->lbearing;
		myfontinfo->glyph[thisglyph].yoffset = charinfo->descent;
		myfontinfo->glyph[thisglyph].advance = charinfo->width;
		myfontinfo->glyph[thisglyph].bitmap = bitmapData;
	    }
	    XDestroyImage(image);
	    numToGrab = 0;
	    /* do we need to clear the offscreen pixmap to get more? */
	    if (i < numchars - 1) {
		XSetForeground(dpy, xgc, 0);
		XFillRectangle(dpy, offscreen, xgc, 0, 0, 8 * maxSpanLength * glyphsPerGrab, height);
		XSetForeground(dpy, xgc, 1);
	    }
	}
    }
    XFreeGC(dpy, xgc);
    XFreePixmap(dpy, offscreen);
    return myfontinfo;

  FreeFontAndReturn:
    XDestroyImage(image);
    XFreeGC(dpy, xgc);
    XFreePixmap(dpy, offscreen);
    for (j = i - 1; j >= 0; j--) {
	if (myfontinfo->glyph[j].bitmap)
	    free(myfontinfo->glyph[j].bitmap);
    }
    free(myfontinfo);
    return NULL;
}
Beispiel #19
0
void 
XUtf8DrawString(
	Display 	*display, 
	Drawable 	d,
        XUtf8FontStruct 	*font_set, 
	GC 		gc, 
	int 		x, 
	int 		y, 
	const char	*string,
        int 		num_bytes)
{
	int 		*encodings; /* encodings array */
	XFontStruct 	**fonts; /* fonts array */
	XChar2b 	buf[128]; /* drawing buffer */
	int 		fnum; /* index of the current font in the fonts array*/
	int 		i; /* current byte in the XChar2b buffer */
	int 		first; /* first valid font index */
	int 		last_fnum; /* font index of the previous char */
	int 		nb_font;  /* quantity of fonts in the font array */
	char 		glyph[2]; /* byte1 and byte1 value of the UTF-8 char */
	int		*ranges; /* sub range of iso10646 */

	nb_font = font_set->nb_font;

	if (nb_font < 1) {
		/* there is no font in the font_set :-( */
		return;
	}
	ranges = font_set->ranges;
	fonts = font_set->fonts;
	encodings = font_set->encodings;
	i = 0;
	fnum = 0;
	
	while(fnum < nb_font && !fonts[fnum]) fnum++;
	if (fnum >= nb_font) {
		/* there is no valid font for the X server */
		return;
	}

	first = fnum;
	last_fnum = fnum;

	while (num_bytes > 0) {
		int 		ulen; /* byte length of the UTF-8 char */
		unsigned int 	ucs;  /* Unicode value of the UTF-8 char */
		unsigned int	no_spc; /* Spacing char equivalent of a 
					   non-spacing char */

		if (i > 120) {
			/*** draw the buffer **/
			XSetFont(display, gc, fonts[fnum]->fid);
			XDrawString16(display, d, gc, x, y, buf, i);
			x += XTextWidth16(fonts[fnum], buf, i);
			i = 0;
		}

		ulen = XFastConvertUtf8ToUcs((unsigned char*)string, 
				num_bytes, &ucs); 

		if (ulen < 1) ulen = 1; 

		no_spc = XUtf8IsNonSpacing(ucs);
		if (no_spc) ucs = no_spc; 

		/* 
		 * find the first encoding which can be used to 	
		 * draw the glyph 				
		 */
		fnum = first;
		while (fnum < nb_font) {
			if (fonts[fnum] && 
				ucs2fontmap(glyph, ucs, encodings[fnum]) >= 0) 
			{
				if (encodings[fnum] != 0 || 
					(ucs >= ranges[fnum * 2] &&
					ucs <= ranges[fnum * 2 + 1]))
				{
					break;
				}
			}
			fnum++;
		}
		if (fnum == nb_font) {
			/** the char is not valid in all encodings ->
			  * draw it using the first font :-( **/
			fnum = first;
			ucs2fontmap(glyph, '?', encodings[fnum]);
		}

		if (last_fnum != fnum || no_spc) {
			XSetFont(display, gc, fonts[last_fnum]->fid);
			XDrawString16(display, d, gc, x, y, buf, i);
			x += XTextWidth16(fonts[last_fnum], buf, i);
			i = 0;
			(*buf).byte1 = glyph[0];
			(*buf).byte2 = glyph[1];
			if (no_spc) {
				x -= XTextWidth16(fonts[fnum], buf, 1);
			}
		} else {
			(*(buf + i)).byte1 = glyph[0];
			(*(buf + i)).byte2 = glyph[1];
		}
		last_fnum = fnum;
		i++;
		string += ulen;
		num_bytes -= ulen;
	}

	XSetFont(display, gc, fonts[fnum]->fid);
	XDrawString16(display, d, gc, x, y, buf, i);
}