static XFont* font_create(Display *dpy, const char *name) { int n; char *def, **missing; XFont *font = (XFont*)xcalloc(1, sizeof(XFont)); font->set = XCreateFontSet(dpy, name, &missing, &n, &def); if(missing) { while(n--) fprintf(stderr, "missing fontset: %s\n", missing[n]); XFreeStringList(missing); } if(font->set) { XFontStruct **xfonts; char **font_names; XExtentsOfFontSet(font->set); n = XFontsOfFontSet(font->set, &xfonts, &font_names); while(n--) { font->ascent = MAX(font->ascent, (*xfonts)->ascent); font->descent = MAX(font->descent,(*xfonts)->descent); xfonts++; } } else { if(!(font->xfont = XLoadQueryFont(dpy, name)) && !(font->xfont = XLoadQueryFont(dpy, "fixed"))) die("error, cannot load font: '%s'\n", name); font->ascent = font->xfont->ascent; font->descent = font->xfont->descent; } font->height = font->ascent + font->descent; return font; }
void wmfs_init_font(char *font, struct theme *t) { XFontStruct **xfs = NULL; char **misschar, **names, *defstring; int d; if(!(t->font.fontset = XCreateFontSet(W->dpy, font, &misschar, &d, &defstring))) { warnxl("Can't load font '%s'", font); t->font.fontset = XCreateFontSet(W->dpy, "fixed", &misschar, &d, &defstring); } XExtentsOfFontSet(t->font.fontset); XFontsOfFontSet(t->font.fontset, &xfs, &names); t->font.as = xfs[0]->max_bounds.ascent; t->font.de = xfs[0]->max_bounds.descent; t->font.width = xfs[0]->max_bounds.width; t->font.height = t->font.as + t->font.de; if(misschar) XFreeStringList(misschar); }
/* Function Name: PaintText * Description: Actually paints the text into the windoe. * Arguments: w - the text widget. * gc - gc to paint text with. * x, y - location to paint the text. * buf, len - buffer and length of text to paint. * Returns: the width of the text painted, or 0. * * NOTE: If this string attempts to paint past the end of the window * then this function will return zero. */ static Dimension PaintText(Widget w, GC gc, Position x, Position y, wchar_t *buf, int len) { MultiSinkObject sink = (MultiSinkObject) w; TextWidget ctx = (TextWidget) XtParent(w); XFontSet fontset = sink->multi_sink.fontset; Position max_x; Dimension width = (Dimension) XwcTextEscapement(fontset, buf, len); XFontSetExtents *ext = XExtentsOfFontSet(fontset); max_x = (Position) ctx->core.width; if (((int) width) <= -x) /* Don't draw if we can't see it. */ return (width); XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx), fontset, gc, (int) x, (int) y, buf, len); if ((((Position) width + x) > max_x) && (ctx->text.margin.right != 0)) { x = (Position) (ctx->core.width - ctx->text.margin.right); width = (Dimension) ctx->text.margin.right; XFillRectangle(XtDisplay((Widget) ctx), XtWindow((Widget) ctx), sink->multi_sink.normgc, (int) x, (int) y - abs(ext->max_logical_extent.y), (unsigned int) width, (unsigned int) ext->max_logical_extent.height); return (0); } return (width); }
void SFinitFont() { #if ENABLE_NLS XFontSetExtents *fse = XExtentsOfFontSet(fontSet); SFcharWidth = fse->max_logical_extent.width; SFcharAscent = -fse->max_logical_extent.y; SFcharHeight = fse->max_logical_extent.height; #else TextData *data; data = XtNew(TextData); XtGetApplicationResources(selFileForm, (XtPointer) data, textResources, XtNumber(textResources), (Arg *) NULL, ZERO); SFfont = XLoadQueryFont(SFdisplay, data->fontname); if (!SFfont) { SFfont = XLoadQueryFont(SFdisplay, SF_DEFAULT_FONT); if (!SFfont) { char sbuf[256]; (void) sprintf(sbuf, "XsraSelFile: can't get font %s", SF_DEFAULT_FONT); XtAppError(SFapp, sbuf); } } SFcharWidth = (SFfont->max_bounds.width + SFfont->min_bounds.width) / 2; SFcharAscent = SFfont->max_bounds.ascent; SFcharHeight = SFcharAscent + SFfont->max_bounds.descent; #endif return; }
/*ARGSUSED*/ static void XawListInitialize(Widget temp1, Widget cnew, ArgList args, Cardinal *num_args) { ListWidget lw = (ListWidget)cnew; /* * Initialize all private resources */ /* record for posterity if we are free */ lw->list.freedoms = ((XtWidth(lw) != 0) * WidthLock + (XtHeight(lw) != 0) * HeightLock + (lw->list.longest != 0) * LongestLock); GetGCs(cnew); /* Set row height, based on font or fontset */ if (lw->simple.international == True) lw->list.row_height = XExtentsOfFontSet(lw->list.fontset)->max_ink_extent.height + lw->list.row_space; else lw->list.row_height = lw->list.font->max_bounds.ascent + lw->list.font->max_bounds.descent + lw->list.row_space; ResetList(cnew, WidthFree(lw), HeightFree(lw)); lw->list.highlight = lw->list.is_highlighted = NO_HIGHLIGHT; }
void defont_get_font_extents(DEFont *font, GrFontExtents *fnte) { #ifdef HAVE_X11_XFT if(font->font!=NULL){ fnte->max_height=font->font->ascent+font->font->descent; fnte->max_width=font->font->max_advance_width; fnte->baseline=font->font->ascent; return; } #endif /* HAVE_X11_XFT */ #ifdef HAVE_X11_BMF if(font->fontset!=NULL){ XFontSetExtents *ext=XExtentsOfFontSet(font->fontset); if(ext==NULL) goto fail; fnte->max_height=ext->max_logical_extent.height; fnte->max_width=ext->max_logical_extent.width; fnte->baseline=-ext->max_logical_extent.y; return; }else if(font->fontstruct!=NULL){ XFontStruct *fnt=font->fontstruct; fnte->max_height=fnt->ascent+fnt->descent; fnte->max_width=fnt->max_bounds.width; fnte->baseline=fnt->ascent; return; } fail: #endif /* HAVE_X11_BMF */ DE_RESET_FONT_EXTENTS(fnte); }
/* * Given two positions, find the distance between them. */ static void FindDistance( Widget w, XawTextPosition fromPos, /* First position. */ int fromx, /* Horizontal location of first position. */ XawTextPosition toPos, /* Second position. */ int *resWidth, /* Distance between fromPos and resPos. */ XawTextPosition * resPos, /* Actual second position used. */ int *resHeight) /* Height required. */ { MultiSinkObject sink = (MultiSinkObject) w; Widget source = XawTextGetSource(XtParent(w)); XawTextPosition inx, lastPos; wchar_t c; XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); XawTextBlock blk; /* we may not need this */ lastPos = GETLASTPOS; XawTextSourceRead(source, fromPos, &blk, (int) (toPos - fromPos)); *resWidth = 0; for (inx = fromPos; inx != toPos && inx < lastPos; inx++) { if (inx - blk.firstPos >= blk.length) XawTextSourceRead(source, inx, &blk, (int) (toPos - fromPos)); c = ((wchar_t *) blk.ptr)[inx - blk.firstPos]; *resWidth += CharWidth(w, fromx + *resWidth, c); if (c == _Xaw_atowc(XawLF)) { inx++; break; } } *resPos = inx; *resHeight = ext->max_logical_extent.height; }
static void FindPosition(Widget w, XawTextPosition fromPos, int fromx, int width, Bool stopAtWordBreak, XawTextPosition *resPos, int *resWidth, int *resHeight) { MultiSinkObject sink = (MultiSinkObject)w; TextWidget ctx = (TextWidget)XtParent(w); Widget source = ctx->text.source; XFontSet fontset = sink->multi_sink.fontset; XawTextPosition idx, pos, whiteSpacePosition = 0; int i, lastWidth, whiteSpaceWidth, rWidth; Boolean whiteSpaceSeen; wchar_t c; XFontSetExtents *ext = XExtentsOfFontSet(fontset); XawTextBlock blk; pos = XawTextSourceRead(source, fromPos, &blk, BUFSIZ); rWidth = lastWidth = whiteSpaceWidth = 0; whiteSpaceSeen = False; c = 0; for (i = 0, idx = fromPos; rWidth <= width; i++, idx++) { if (i >= blk.length) { i = 0; pos = XawTextSourceRead(source, pos, &blk, BUFSIZ); if (blk.length == 0) break; } c = ((wchar_t *)blk.ptr)[i]; lastWidth = rWidth; rWidth += CharWidth(sink, fontset, fromx + rWidth, c); if (c == _Xaw_atowc(XawLF)) { idx++; break; } else if ((c == _Xaw_atowc(XawSP) || c == _Xaw_atowc(XawTAB)) && rWidth <= width) { whiteSpaceSeen = True; whiteSpacePosition = idx; whiteSpaceWidth = rWidth; } } if (rWidth > width && idx > fromPos) { idx--; rWidth = lastWidth; if (stopAtWordBreak && whiteSpaceSeen) { idx = whiteSpacePosition + 1; rWidth = whiteSpaceWidth; } } if (idx >= ctx->text.lastPos && c != _Xaw_atowc(XawLF)) idx = ctx->text.lastPos + 1; *resPos = idx; *resWidth = rWidth; *resHeight = ext->max_logical_extent.height; }
static void FindPosition( Widget w, XawTextPosition fromPos, /* Starting position. */ int fromx, /* Horizontal location of starting position. */ int width, /* Desired width. */ Boolean stopAtWordBreak, /* Whether the resulting position should be at a word break. */ XawTextPosition * resPos, /* Resulting position. */ int *resWidth, /* Actual width used. */ int *resHeight) /* Height required. */ { MultiSinkObject sink = (MultiSinkObject) w; Widget source = XawTextGetSource(XtParent(w)); XawTextPosition lastPos, inx, whiteSpacePosition = 0; int lastWidth = 0, whiteSpaceWidth = 0; Boolean whiteSpaceSeen; wchar_t c; XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); XawTextBlock blk; lastPos = GETLASTPOS; XawTextSourceRead(source, fromPos, &blk, BUFSIZ); *resWidth = 0; whiteSpaceSeen = FALSE; c = 0; for (inx = fromPos; *resWidth <= width && inx < lastPos; inx++) { lastWidth = *resWidth; if (inx - blk.firstPos >= blk.length) XawTextSourceRead(source, inx, &blk, BUFSIZ); c = ((wchar_t *) blk.ptr)[inx - blk.firstPos]; *resWidth += CharWidth(w, fromx + *resWidth, c); if ((c == _Xaw_atowc(XawSP) || c == _Xaw_atowc(XawTAB)) && *resWidth <= width) { whiteSpaceSeen = TRUE; whiteSpacePosition = inx; whiteSpaceWidth = *resWidth; } if (c == _Xaw_atowc(XawLF)) { inx++; break; } } if (*resWidth > width && inx > fromPos) { *resWidth = lastWidth; inx--; if (stopAtWordBreak && whiteSpaceSeen) { inx = whiteSpacePosition + 1; *resWidth = whiteSpaceWidth; } } if (inx == lastPos && c != _Xaw_atowc(XawLF)) inx = lastPos + 1; *resPos = inx; *resHeight = ext->max_logical_extent.height; }
void win_init_font(Display *dpy, const char *fontstr) { int n; char *def, **missing; font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); if (missing) XFreeStringList(missing); if (font.set) { XFontStruct **xfonts; char **font_names; font.ascent = font.descent = 0; XExtentsOfFontSet(font.set); n = XFontsOfFontSet(font.set, &xfonts, &font_names); while (n--) { font.ascent = MAX(font.ascent, (*xfonts)->ascent); font.descent = MAX(font.descent,(*xfonts)->descent); xfonts++; } } else { if ((font.xfont = XLoadQueryFont(dpy, fontstr)) == NULL && (font.xfont = XLoadQueryFont(dpy, "fixed")) == NULL) { die("could not load font: %s", fontstr); } font.ascent = font.xfont->ascent; font.descent = font.xfont->descent; } fontheight = font.ascent + font.descent; barheight = fontheight + 2 * V_TEXT_PAD; }
/*----------------------------------------------------------------------------*/ void VKLoadXResource() { VKLocaleInit(); VKLoadPalette(); if( !vk_font_name ) vk_font_name = strdup(screen_width<=800 ? VK_FONT_SMALL : VK_FONT_LARGE); if( !vk_font_name ) error("Error: not enough memory!"); #ifdef USE_XFT vk_font = XftFontOpenName(display, 0, vk_font_name); if( !vk_font ) vk_font = XftFontOpenXlfd(display, 0, vk_font_name); #else vk_font = XLoadQueryFont(display, vk_font_name); if( !vk_font ) vk_font = XLoadQueryFont(display, screen_width<=800 ? VK_FONT_SMALL : VK_FONT_LARGE); VKFontSetInit(); #endif if( !vk_font ) error("Cannot load font %s\n", vk_font_name); vk_hand = XCreateFontCursor(display, XC_hand2); vk_cursor = XCreateFontCursor(display, XC_left_ptr); vk_attrib.override_redirect = True; #ifdef USE_XFT vk_text_height = vk_font->height; vk_text_ascent = vk_font->ascent; #else { XFontSetExtents *fse = XExtentsOfFontSet(vk_fontset); vk_text_height = fse->max_logical_extent.height + 4; vk_text_ascent = vk_font->ascent + 3; } #endif }
static void InsertCursor( Widget w, Position x, Position y, XawTextInsertState state) { MultiSinkObject sink = (MultiSinkObject) w; Widget text_widget = XtParent(w); XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); XRectangle rect; sink->multi_sink.cursor_x = x; sink->multi_sink.cursor_y = y; rect.width = (unsigned short) insertCursor_width; rect.height = (unsigned short) ext->max_logical_extent.height; rect.x = (short) (x - (rect.width / 2)); rect.y = (short) (y - rect.height); if (state != sink->multi_sink.laststate && XtIsRealized(text_widget)) { XDrawLine(XtDisplay(text_widget), XtWindow(text_widget), sink->multi_sink.xorgc, rect.x + rect.width / 2, rect.y, rect.x + rect.width / 2, rect.y + rect.height - 1); } sink->multi_sink.laststate = state; }
void CalFontExtents( Cal_Font *font, XFontSetExtents *fse) { if (font->cf_type == XmFONT_IS_FONT) { /* * These computations are stolen from _XsimlCreateFontSet() * in Xlib. */ fse->max_ink_extent.x = font->f.cf_font->min_bounds.lbearing; fse->max_ink_extent.y = - font->f.cf_font->max_bounds.ascent; fse->max_ink_extent.width = font->f.cf_font->min_bounds.width; fse->max_ink_extent.height = font->f.cf_font->max_bounds.ascent + font->f.cf_font->max_bounds.descent; fse->max_logical_extent.x = 0; fse->max_logical_extent.y = - font->f.cf_font->ascent; fse->max_logical_extent.width = font->f.cf_font->max_bounds.width; fse->max_logical_extent.height = font->f.cf_font->ascent + font->f.cf_font->descent; } else { *fse = *XExtentsOfFontSet(font->f.cf_fontset); } }
/*ARGSUSED*/ static int MaxHeight(Widget w, int lines) { MultiSinkObject sink = (MultiSinkObject)w; XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); return (lines * ext->max_logical_extent.height); }
/* ============================================================================== 指定したGdk_Fontにおける, 描画範囲(の最大)を得る ============================================================================== */ void VnXFont::GetFontRect(Gdk_Font& font, VnRect& rect) { XFontSetExtents* ext; ext = XExtentsOfFontSet((XFontSet) GDK_FONT_XFONT(font.gdkobj())); rect.x = ext->max_ink_extent.x; rect.y = ext->max_ink_extent.y; rect.width = ext->max_ink_extent.width; rect.height = ext->max_ink_extent.height; }
void _XawMultiSinkPosToXY(Widget w, XawTextPosition pos, Position *x, Position *y) { MultiSinkObject sink = (MultiSinkObject)((TextWidget)w)->text.sink; XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); _XawTextPosToXY(w, pos, x, y); *y += abs(ext->max_logical_extent.y); }
/*ARGSUSED*/ static int MaxLines(Widget w, unsigned int height) { MultiSinkObject sink = (MultiSinkObject)w; int font_height; XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); font_height = ext->max_logical_extent.height; return (height / font_height); }
/** Init the font */ static void init_font(void) { #ifdef HAVE_XFT if(conf.use_xft) { if(!(font.font = XftFontOpenName(dpy, SCREEN, conf.font))) { warnx("WMFS Error: Cannot initialize Xft font"); font.font = XftFontOpenName(dpy, SCREEN, "sans-10"); } font.de = font.font->descent; font.as = font.font->ascent; font.height = font.font->height; } else #endif /* HAVE_XFT */ { char **misschar, **names, *defstring; int d; XFontStruct **xfs = NULL; /* locale support */ setlocale(LC_CTYPE, ""); if(!conf.font) conf.font = xstrdup("fixed"); /* Using Font Set */ if(!(font.fontset = XCreateFontSet(dpy, conf.font, &misschar, &d, &defstring))) { warnx("Can't load font '%s'", conf.font); font.fontset = XCreateFontSet(dpy, "fixed", &misschar, &d, &defstring); } XExtentsOfFontSet(font.fontset); XFontsOfFontSet(font.fontset, &xfs, &names); font.as = xfs[0]->max_bounds.ascent; font.de = xfs[0]->max_bounds.descent; font.width = xfs[0]->max_bounds.width; font.height = font.as + font.de; if(misschar) XFreeStringList(misschar); } /* Set font in _WMFS_FONT for eventual status tools */ XChangeProperty(dpy, ROOT, net_atom[wmfs_font], net_atom[utf8_string], 8, PropModeReplace, (uchar*)conf.font, strlen(conf.font)); return; }
/* * Function: * GetCursorBounds * * Parameters: * w - text sink object * rect - X rectangle to return the cursor bounds * * Description: * Returns the size and location of the cursor. */ static void GetCursorBounds(Widget w, XRectangle *rect) { MultiSinkObject sink = (MultiSinkObject)w; rect->width = CharWidth(sink, sink->multi_sink.fontset, 0, _Xaw_atowc(XawSP)); rect->height = (XExtentsOfFontSet(sink->multi_sink.fontset) ->max_logical_extent.height); rect->x = sink->multi_sink.cursor_x; rect->y = sink->multi_sink.cursor_y - (short)rect->height; }
/**************************************************************************** Return the size of the given text in the given font. This size should include the ascent and descent of the text. Either of width or height may be NULL in which case those values simply shouldn't be filled out. ****************************************************************************/ void get_text_size(int *width, int *height, enum client_font font, const char *text) { if (width) { *width = XmbTextEscapement(*fonts[font], text, strlen(text)); } if (height) { /* ??? */ *height = XExtentsOfFontSet(*fonts[font])->max_logical_extent.height; } }
void setfont(const char *fontstr) { #ifndef DZEN_XFT char *def, **missing; int i, n; missing = NULL; if(dzen.font.set) XFreeFontSet(dzen.dpy, dzen.font.set); dzen.font.set = XCreateFontSet(dzen.dpy, fontstr, &missing, &n, &def); if(missing) XFreeStringList(missing); if(dzen.font.set) { XFontSetExtents *font_extents; XFontStruct **xfonts; char **font_names; dzen.font.ascent = dzen.font.descent = 0; font_extents = XExtentsOfFontSet(dzen.font.set); n = XFontsOfFontSet(dzen.font.set, &xfonts, &font_names); for(i = 0, dzen.font.ascent = 0, dzen.font.descent = 0; i < n; i++) { if(dzen.font.ascent < (*xfonts)->ascent) dzen.font.ascent = (*xfonts)->ascent; if(dzen.font.descent < (*xfonts)->descent) dzen.font.descent = (*xfonts)->descent; xfonts++; } } else { if(dzen.font.xfont) XFreeFont(dzen.dpy, dzen.font.xfont); dzen.font.xfont = NULL; if(!(dzen.font.xfont = XLoadQueryFont(dzen.dpy, fontstr))) eprint("dzen: error, cannot load font: '%s'\n", fontstr); dzen.font.ascent = dzen.font.xfont->ascent; dzen.font.descent = dzen.font.xfont->descent; } dzen.font.height = dzen.font.ascent + dzen.font.descent; #else if(dzen.font.xftfont) XftFontClose(dzen.dpy, dzen.font.xftfont); dzen.font.xftfont = XftFontOpenXlfd(dzen.dpy, dzen.screen, fontstr); if(!dzen.font.xftfont) dzen.font.xftfont = XftFontOpenName(dzen.dpy, dzen.screen, fontstr); if(!dzen.font.xftfont) eprint("error, cannot load font: '%s'\n", fontstr); dzen.font.extents = malloc(sizeof(XGlyphInfo)); XftTextExtentsUtf8(dzen.dpy, dzen.font.xftfont, (unsigned const char *) fontstr, strlen(fontstr), dzen.font.extents); dzen.font.height = dzen.font.xftfont->ascent + dzen.font.xftfont->descent; dzen.font.width = (dzen.font.extents->width)/strlen(fontstr); #endif }
/* Function Name: GetCursorBounds * Description: Returns the size and location of the cursor. * Arguments: w - the text object. * RETURNED rect - an X rectangle to return the cursor bounds in. * Returns: none. */ static void GetCursorBounds(Widget w, XRectangle * rect) { MultiSinkObject sink = (MultiSinkObject) w; XFontSetExtents *ext = XExtentsOfFontSet(sink->multi_sink.fontset); rect->width = (unsigned short) insertCursor_width; /* rect->height = (unsigned short) insertCursor_height; */ rect->height = ext->max_logical_extent.height; rect->x = (short) (sink->multi_sink.cursor_x - (rect->width / 2)); rect->y = (short) (sink->multi_sink.cursor_y - rect->height); }
/*************************************<->************************************* * * wspCharWidth (xmfl) * * * Description: * ----------- * Returns the max logical character width for this fontList * * * Inputs: * ------ * xmfl - XmFontList * * Returns: * ------- * max logical character width * * Comments: * --------- ******************************<->***********************************/ static Dimension wspCharWidth( XmFontList xmfl ) { XmFontContext fc; XmFontListEntry entry; Dimension dWidth, dTmpWidth; XtPointer pFont; XmFontType type; XFontSetExtents *pExtents; XmFontListInitFontContext ( &fc, xmfl); dWidth = 0; entry = XmFontListNextEntry (fc); while (entry) { pFont = XmFontListEntryGetFont (entry, &type); switch (type) { case XmFONT_IS_FONT: dTmpWidth = ((XFontStruct *)pFont)->max_bounds.rbearing - ((XFontStruct *)pFont)->min_bounds.lbearing; break; case XmFONT_IS_FONTSET: pExtents = XExtentsOfFontSet ((XFontSet) pFont); dTmpWidth = pExtents->max_logical_extent.width; break; default: dTmpWidth = 0; break; } if (dTmpWidth > dWidth) dWidth = dTmpWidth; entry = XmFontListNextEntry (fc); } XmFontListFreeFontContext (fc); return (dWidth); }
/************************************************************************** Draw at x = left of string, y = top of string. **************************************************************************/ static void draw_shadowed_string(struct canvas *pcanvas, XFontSet fontset, GC font_gc, struct color *foreground, struct color *shadow, int x, int y, const char *string) { size_t len = strlen(string); y -= XExtentsOfFontSet(fontset)->max_logical_extent.y; if (foreground->color.pixel != shadow->color.pixel) { XSetForeground(display, font_gc, shadow->color.pixel); XmbDrawString(display, pcanvas->pixmap, fontset, font_gc, x + 1, y + 1, string, len); } XSetForeground(display, font_gc, foreground->color.pixel); XmbDrawString(display, pcanvas->pixmap, fontset, font_gc, x, y, string, len); }
void defont_get_font_extents(DEFont *font, GrFontExtents *fnte) { if(font->fontset!=NULL){ XFontSetExtents *ext=XExtentsOfFontSet(font->fontset); if(ext==NULL) goto fail; fnte->max_height=ext->max_logical_extent.height; fnte->max_width=ext->max_logical_extent.width; fnte->baseline=-ext->max_logical_extent.y; return; }else if(font->fontstruct!=NULL){ XFontStruct *fnt=font->fontstruct; fnte->max_height=fnt->ascent+fnt->descent; fnte->max_width=fnt->max_bounds.width; fnte->baseline=fnt->ascent; return; } fail: DE_RESET_FONT_EXTENTS(fnte); }
static void x_preload(const char *fontstr, int p) { char *def, **missing; int i, n; missing = NULL; dzen.fnpl[p].set = XCreateFontSet(dzen.dpy, fontstr, &missing, &n, &def); if(missing) XFreeStringList(missing); if(dzen.fnpl[p].set) { XFontSetExtents *font_extents; XFontStruct **xfonts; char **font_names; dzen.fnpl[p].ascent = dzen.fnpl[p].descent = 0; font_extents = XExtentsOfFontSet(dzen.fnpl[p].set); n = XFontsOfFontSet(dzen.fnpl[p].set, &xfonts, &font_names); for(i = 0, dzen.fnpl[p].ascent = 0, dzen.fnpl[p].descent = 0; i < n; i++) { if(dzen.fnpl[p].ascent < (*xfonts)->ascent) dzen.fnpl[p].ascent = (*xfonts)->ascent; if(dzen.fnpl[p].descent < (*xfonts)->descent) dzen.fnpl[p].descent = (*xfonts)->descent; xfonts++; } } else { if(dzen.fnpl[p].xfont) XFreeFont(dzen.dpy, dzen.fnpl[p].xfont); dzen.fnpl[p].xfont = NULL; if(!(dzen.fnpl[p].xfont = XLoadQueryFont(dzen.dpy, fontstr))) eprint("dzen: error, cannot load font: '%s'\n", fontstr); dzen.fnpl[p].ascent = dzen.fnpl[p].xfont->ascent; dzen.fnpl[p].descent = dzen.fnpl[p].xfont->descent; } dzen.fnpl[p].height = dzen.fnpl[p].ascent + dzen.fnpl[p].descent; }
Fnt * draw_font_create(Draw *draw, const char *fontname) { Fnt *font; char *def, **missing; int n; if(!draw) return NULL; font = (Fnt *)calloc(1, sizeof(Fnt)); font->set = XCreateFontSet(draw->dpy, fontname, &missing, &n, &def); if(missing) { while(n--) fprintf(stderr, "draw: missing fontset: %s\n", missing[n]); XFreeStringList(missing); } if(font->set) { XFontStruct **xfonts; char **font_names; XExtentsOfFontSet(font->set); n = XFontsOfFontSet(font->set, &xfonts, &font_names); while(n--) { font->ascent = MAX(font->ascent, (*xfonts)->ascent); font->descent = MAX(font->descent,(*xfonts)->descent); xfonts++; } } else { if(!(font->xfont = XLoadQueryFont(draw->dpy, fontname)) && !(font->xfont = XLoadQueryFont(draw->dpy, "fixed"))) die("error, cannot load font: '%s'\n", fontname); font->ascent = font->xfont->ascent; font->descent = font->xfont->descent; } font->h = font->ascent + font->descent; return font; }
/* * Function: * PaintText * * Parameters: * w - text sink object * gc - gc to paint text * x - location to paint the text * y - "" * buf - buffer and length of text to paint * len - "" * clear_bg - clear background before drawing ? * * Description: * Actually paints the text into the window. * * Returns: * The width of the text painted */ static unsigned int PaintText(Widget w, GC gc, int x, int y, wchar_t *buf, int len, Bool clear_bg) { MultiSinkObject sink = (MultiSinkObject)w; TextWidget ctx = (TextWidget)XtParent(w); XFontSet fontset = sink->multi_sink.fontset; unsigned int width = XwcTextEscapement(fontset, buf, len); if (((int)width) <= -x) /* Don't draw if we can't see it */ return (width); if (clear_bg) { XFontSetExtents *ext = XExtentsOfFontSet(fontset); _XawTextSinkClearToBackground(w, x, y - abs(ext->max_logical_extent.y), width, ext->max_logical_extent.height); XwcDrawString(XtDisplay(ctx), XtWindow(ctx), fontset, gc, x, y, buf, len); } else XwcDrawImageString(XtDisplay(ctx), XtWindow(ctx), fontset, gc, x, y, buf, len); return (width); }
/* * Given two positions, find the distance between them */ static void FindDistance(Widget w, XawTextPosition fromPos, int fromx, XawTextPosition toPos, int *resWidth, XawTextPosition *resPos, int *resHeight) { MultiSinkObject sink = (MultiSinkObject)w; XFontSet fontset = sink->multi_sink.fontset; TextWidget ctx = (TextWidget)XtParent(w); Widget source = ctx->text.source; XawTextPosition idx, pos; wchar_t c; XFontSetExtents *ext = XExtentsOfFontSet(fontset); XawTextBlock blk; int i, rWidth; pos = XawTextSourceRead(source, fromPos, &blk, toPos - fromPos); rWidth = 0; for (i = 0, idx = fromPos; idx < toPos; i++, idx++) { if (i >= blk.length) { i = 0; XawTextSourceRead(source, pos, &blk, toPos - pos); if (blk.length == 0) break; } c = ((wchar_t *)blk.ptr)[i]; rWidth += CharWidth(sink, fontset, fromx + rWidth, c); if (c == _Xaw_atowc(XawLF)) { idx++; break; } } *resPos = idx; *resWidth = rWidth; *resHeight = ext->max_logical_extent.height; }
int main(int argc, char **argv) { Display *display; int screen_num; Window win; //窗口ID unsigned int width, height; //窗口尺寸 unsigned int border_width = 4; //边界空白 unsigned int display_width, display_height;//屏幕尺寸 XEvent report; GC gc; unsigned long valuemask = 0; XGCValues values; char *display_name = NULL; Atom protocols; //edit int len = 127; unsigned char string[128], s_tab[ROW][127]; KeySym keysym; int row = 0, col = 0; int i, count = 0; Status status; //字体集 XFontSet fontset; char **missing_charsets; int num_missing_charsets; char *default_string; XFontSetExtents *fs_ext; int dec; //XIM XIM im; XIC ic; //overspot XRectangle spot, s_rect; XVaNestedList preedit_attr, status_attr; //设置locale if((setlocale(LC_ALL, "")) == NULL){ printf("cannot set locale\n"); exit(1); } //判断X是否支持locale if(!XSupportsLocale()){ printf("X does not support current locale\n"); exit(1); } //设置locale修饰 if(XSetLocaleModifiers(NULL)){ printf("Cannot set locale modifiers\n"); exit(1); } // 和X 服务器连接 if ( (display=XOpenDisplay(display_name)) == NULL ) { printf("Cannot connect to X server %s\n", XDisplayName(display_name)); exit(-1); } //获得缺省的 screen_num screen_num = DefaultScreen(display); //获得屏幕的宽度和高度 display_width = DisplayWidth(display, screen_num); display_height = DisplayHeight(display, screen_num); //建立字体集 fontset = XCreateFontSet(display, "8x16,-*-song-medium-r-normal--16-*-*-*-*-*-gb2312.1980-0", &missing_charsets, &num_missing_charsets, &default_string); if(num_missing_charsets > 0){ int i; printf("Following charsets are missing:\n"); for(i=0; i<num_missing_charsets; i++){ printf("Missing %d: %s\n", i, missing_charsets[i]); } printf("\nDefault string:%s\n", default_string); XFreeStringList(missing_charsets); } //字体的Extents fs_ext = XExtentsOfFontSet(fontset); dec = fs_ext->max_logical_extent.height + fs_ext->max_logical_extent.y; width = W_WIDTH; height = W_HEIGHT + dec; //建立窗口 win = XCreateSimpleWindow(display, //display RootWindow(display,screen_num), //父窗口 0, 0, width, height, //位置和大小 border_width, //边界宽度 BlackPixel(display,screen_num), //前景色 WhitePixel(display,screen_num));//背景色 //选择窗口感兴趣的事件掩码 XSelectInput(display, win, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask); //建立GC gc = XCreateGC(display, win, valuemask, &values); protocols = XInternAtom(display, "WM_DELETE_WINDOW", True); XSetWMProtocols(display, win, &protocols, 1); //显示窗口 XMapWindow(display, win); //联接输入服务器 if((im = XOpenIM(display, NULL, NULL, NULL)) == NULL){ printf("Error : XOpenIM !\n"); exit(1); } //设置输入服务器的位置 spot.x = F_SIZE / 2 * col; spot.y = F_SIZE * (row + 1) - dec; preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, XNFontSet, fontset, NULL); s_rect.x = 0; s_rect.y = F_SIZE * ROW + dec + 2; s_rect.width = W_WIDTH; s_rect.height = F_SIZE; status_attr = XVaCreateNestedList(0, XNArea, &s_rect, XNFontSet, fontset, NULL); //建立IC if((ic = XCreateIC(im, XNInputStyle, XIMPreeditPosition | XIMStatusNothing, XNClientWindow, win, XNPreeditAttributes, preedit_attr, XNStatusAttributes, status_attr, NULL)) == NULL){ printf("Error : XCreateIC() ! \n"); XCloseIM(im); exit(0); } //释放内存 XFree(preedit_attr); XFree(status_attr); //写屏缓冲区初始化 for(i = 0; i < ROW; i++)s_tab[i][0] = 0; //进入事件循环 while (1) { //取得队列中的事件 XNextEvent(display, &report); //过滤事件 if(XFilterEvent(&report, None) == True) continue; switch (report.type) { //聚焦发声变化 case FocusIn: XSetICFocus(ic); break; case FocusOut: XUnsetICFocus(ic); break; //曝光事件, 窗口应重绘 case Expose: //取得最后一个曝光事件 if (report.xexpose.count != 0) break; for ( i=0; i < ROW; i++) XmbDrawString(display, win, fontset,gc, 0, F_SIZE * (i +1), s_tab[i], strlen(s_tab[i])); break; //窗口尺寸改变, 重新取得窗口的宽度和高度 case ConfigureNotify: width = report.xconfigure.width; height = report.xconfigure.height; break; //鼠标点击或有按键, 释放资源则退出 case KeyPress: count = XmbLookupString(ic, (XKeyPressedEvent *) &report, string, len, &keysym, &status); string[count] = 0; if (status == XLookupBoth&&keysym == XK_Return){ row = (++row) % ROW; col = 0; s_tab[row][0] = 0; XClearArea(display, win, 0, F_SIZE * row + dec, W_WIDTH, F_SIZE, False); } else if (status = XLookupChars || status == XLookupBoth){ XmbDrawString(display, win, fontset, gc, F_SIZE / 2 * col, F_SIZE * (row + 1), string, count); for (i = 0; i < count && col < len && string[i]; i++, col++) s_tab[row][col] = string[i]; s_tab[row][col] = 0; } //更新输入服务器位置 spot.x = F_SIZE / 2 * col; spot.y = F_SIZE * (row + 1); preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL); XSetICValues(ic, XNPreeditAttributes, preedit_attr, NULL); XFree(preedit_attr); break; case ClientMessage: if (report.xclient.data.l[0] == protocols) { XDestroyIC(ic); XCloseIM(im); XDestroyWindow(display, win); XCloseDisplay(display); exit(0); } break; default: break; } } }