#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Xm/XmAll.h>
#include <Xm/XmP.h>
#include <X11/Xft/Xft.h>
#include <fontconfig/fontconfig.h>
#include "nedit_malloc.h"
#include "misc.h"
#include "fontsel.h"
#define PREVIEW_STR "ABCDEFGHIJabcdefghijklmn[](){}.:,;-_$%&/\"''"
#define MONOSPACE_ONLY_DEFAULT 1
static XftColor default_fg_color;
static Pixel default_bg_pix;
static int default_colors_set =
0;
typedef struct FontSelector {
FcPattern *filter;
FcFontSet *list;
Widget pattern;
Widget fontlist;
Widget size;
Widget preview;
Widget name;
XftFont *font;
XftFont *bold;
XftFont *italic;
XftDraw *draw;
XftColor color;
Boolean enable_bg;
int selected_item;
int end;
int cancel;
} FontSelector;
static void UpdatePreview(FontSelector *sel,
const char *fontStr)
{
Display *dp = XtDisplay(sel->preview);
XftFont *font = XftFontOpenName(dp, DefaultScreen(dp), fontStr);
if(!font) {
return;
}
if(sel->font) {
XftFontClose(dp, sel->font);
}
size_t fontStrLen = strlen(fontStr);
char *boldFontStr = FontNameAddAttribute(fontStr, fontStrLen,
"weight",
"bold");
char *italicFontStr = FontNameAddAttribute(fontStr, fontStrLen,
"slant",
"italic");
XftFont *boldFont = XftFontOpenName(dp, DefaultScreen(dp), boldFontStr);
XftFont *italicFont = XftFontOpenName(dp, DefaultScreen(dp), italicFontStr);
NEditFree(boldFontStr);
NEditFree(italicFontStr);
if(sel->bold) {
XftFontClose(dp, sel->bold);
}
if(sel->italic) {
XftFontClose(dp, sel->italic);
}
sel->font = font;
sel->bold = boldFont;
sel->italic = italicFont;
}
static void InitXftDraw(FontSelector *sel)
{
if(sel->draw) {
return;
}
XWindowAttributes attributes;
XGetWindowAttributes(XtDisplay(sel->preview), XtWindow(sel->preview), &attributes);
Screen *screen = XtScreen(sel->preview);
Visual *visual = screen->root_visual;
Cardinal depth;
Colormap colormap;
XtVaGetValues(sel->preview, XtNdepth, &depth, XtNcolormap, &colormap,
NULL);
for(
int i=
0;i<screen->ndepths;i++) {
Depth d = screen->depths[i];
if(d.depth == depth) {
visual = d.visuals;
break;
}
}
Display *dp = XtDisplay(sel->preview);
sel->draw = XftDrawCreate(
dp,
XtWindow(sel->preview),
visual,
colormap);
Pixel previewFg;
XtVaGetValues(sel->preview, XmNforeground, &previewFg,
NULL);
XColor xcolor;
memset(&xcolor,
0,
sizeof(XColor));
xcolor.pixel = previewFg;
XQueryColor(XtDisplay(sel->preview), sel->preview->core.colormap, &xcolor);
sel->color.pixel = previewFg;
sel->color.color.red = xcolor.red;
sel->color.color.green = xcolor.green;
sel->color.color.blue = xcolor.blue;
sel->color.color.alpha = 0xFFFF;
if(default_colors_set) {
sel->color = default_fg_color;
sel->enable_bg = True;
XtVaSetValues(sel->preview, XmNbackground, default_bg_pix,
NULL);
}
}
static void exposeFontPreview(Widget w, FontSelector *sel, XtPointer data)
{
InitXftDraw(sel);
if(!sel->font) {
return;
}
Dimension width, height;
XtVaGetValues(
w,
XmNwidth,
&width,
XmNheight,
&height,
NULL);
XClearWindow(XtDisplay(w), XtWindow(w));
int fontHeight = sel->font->ascent + sel->font->descent;
int boldHeight =
0;
int italicHeight =
0;
int extraSpace =
0;
if(sel->bold) {
boldHeight = sel->bold->ascent + sel->bold->descent;
extraSpace +=
5;
}
if(sel->italic) {
italicHeight = sel->italic->ascent + sel->italic->descent;
extraSpace +=
5;
}
int space = height - fontHeight - boldHeight - italicHeight - extraSpace;
int y = space/
2;
XftDrawStringUtf8(
sel->draw,
&sel->color,
sel->font,
10,
y + sel->font->ascent,
(
unsigned char*)
PREVIEW_STR,
sizeof(
PREVIEW_STR)-
1);
y += fontHeight +
5;
if(sel->bold) {
XftDrawStringUtf8(
sel->draw,
&sel->color,
sel->bold,
10,
y + sel->bold->ascent,
(
unsigned char*)
PREVIEW_STR,
sizeof(
PREVIEW_STR)-
1);
y += boldHeight +
5;
}
if(sel->italic) {
XftDrawStringUtf8(
sel->draw,
&sel->color,
sel->italic,
10,
y + sel->italic->ascent,
(
unsigned char*)
PREVIEW_STR,
sizeof(
PREVIEW_STR)-
1);
}
}
static int compare_font(
const void *d1,
const void *d2) {
const FcPattern *f1 = *((
const FcPattern**)d1);
const FcPattern *f2 = *((
const FcPattern**)d2);
FcChar8 *name1 =
NULL;
FcChar8 *name2 =
NULL;
FcPatternGetString(f1,
FC_FULLNAME,
0, &name1);
FcPatternGetString(f2,
FC_FULLNAME,
0, &name2);
FcChar8 *family1 =
NULL;
FcChar8 *family2 =
NULL;
FcPatternGetString(f1,
FC_FAMILY,
0, &family1);
FcPatternGetString(f2,
FC_FAMILY,
0, &family2);
if(name1 && name2) {
return strcmp((
char*)name1, (
char*)name2);
}
else if(family1 && family2) {
return strcmp((
char*)family1, (
char*)family2);
}
else {
return 0;
}
}
static char* CreateFontName(FcChar8 *family, FcChar8 *style) {
size_t flen = family ? strlen((
char*)family) :
0;
size_t slen = style ? strlen((
char*)style) :
0;
size_t len = flen + slen +
4;
char *name = NEditMalloc(len);
if(!family) {
snprintf(name, len,
"-");
}
else if(style) {
snprintf(name, len,
"%s %s", (
char*)family, (
char*)style);
}
else {
snprintf(name, len,
"%s", (
char*)family);
}
return name;
}
static void UpdateFontList(FontSelector *sel,
const char *pattern)
{
XmStringTable items;
FcChar8 *name;
FcChar8 *family;
FcChar8 *style;
int nfonts, nfound;
if(pattern) {
if(sel->filter) {
FcPatternDestroy(sel->filter);
sel->filter =
NULL;
}
sel->filter = FcNameParse((FcChar8*)pattern);
}
if(!sel->filter) {
sel->filter = FcPatternCreate();
}
FcObjectSet *os = FcObjectSetCreate();
FcObjectSetAdd(os,
FC_FAMILY);
FcObjectSetAdd(os,
FC_STYLE);
FcObjectSetAdd(os,
FC_FULLNAME);
FcObjectSetAdd(os,
FC_SCALABLE);
FcObjectSetAdd(os,
FC_SPACING);
if(sel->list) {
FcFontSetDestroy(sel->list);
}
sel->list = FcFontList(
NULL, sel->filter, os);
FcObjectSetDestroy(os);
nfonts = sel->list->nfont;
nfound =
0;
qsort(sel->list->fonts, nfonts,
sizeof(FcPattern*), compare_font);
items = NEditCalloc(sel->list->nfont,
sizeof(XmString));
for(
int i=
0;i<nfonts;i++) {
FcBool scalable =
0;
FcPatternGetBool(sel->list->fonts[i],
FC_SCALABLE,
0, &scalable);
int spacing =
0;
FcPatternGetInteger(sel->list->fonts[i],
FC_SPACING,
0, &spacing);
name =
NULL;
FcPatternGetString(sel->list->fonts[i],
FC_FULLNAME,
0, &name);
family =
NULL;
FcPatternGetString(sel->list->fonts[i],
FC_FAMILY,
0, &family);
style =
NULL;
FcPatternGetString(sel->list->fonts[i],
FC_STYLE,
0, &style);
if(name) {
items[nfound] = XmStringCreateSimple((
char*)name);
}
else {
name = (FcChar8*)CreateFontName(family, style);
items[nfound] = XmStringCreateSimple((
char*)name);
NEditFree(name);
}
nfound++;
}
XtVaSetValues(sel->fontlist, XmNitems, items, XmNitemCount, nfound,
NULL);
for(
int i=
0;i<nfound;i++) {
XmStringFree(items[i]);
}
NEditFree(items);
}
static void MatchFont(
const char *name, XmString *retName, XmString *retSize)
{
*retName =
NULL;
*retSize =
NULL;
FcPattern* pat = FcNameParse((
const FcChar8*)name);
FcConfigSubstitute(
NULL, pat, FcMatchPattern);
FcDefaultSubstitute(pat);
FcResult result;
FcPattern* font = FcFontMatch(
NULL, pat, &result);
if(font) {
FcChar8* nameStr =
NULL;
FcChar8* familyStr =
NULL;
double fontSize =
0;
if (FcPatternGetString(font,
FC_FULLNAME,
0, &nameStr) == FcResultMatch) {
*retName = XmStringCreateSimple((
char*)nameStr);
}
else if (FcPatternGetString(font,
FC_FAMILY,
0, &familyStr) == FcResultMatch) {
FcChar8 *styleStr =
NULL;
FcPatternGetString(font,
FC_STYLE,
0, &styleStr);
if(styleStr) {
char *fontName = CreateFontName(familyStr, styleStr);
*retName = XmStringCreateSimple(fontName);
NEditFree(fontName);
}
}
if(FcPatternGetDouble(font,
FC_SIZE,
0, &fontSize) == FcResultMatch) {
char buf[
8];
snprintf(buf,
8,
"%d", (
int)fontSize);
*retSize = XmStringCreateSimple(buf);
}
FcPatternDestroy(font);
}
FcPatternDestroy(pat);
}
static void CreateSizeList(Widget w)
{
XmStringTable items = NEditCalloc(
30,
sizeof(XmString));
char buf[
8];
for(
int i=
0;i<
30;i++) {
snprintf(buf,
8,
"%d", i+
5);
items[i] = XmStringCreateSimple(buf);
}
XtVaSetValues(w, XmNitems, items, XmNitemCount,
30,
NULL);
for(
int i=
0;i<
30;i++) {
XmStringFree(items[i]);
}
NEditFree(items);
}
static char* GetFontString(FontSelector *sel)
{
XmStringTable table =
NULL;
int count =
0;
int i = sel->selected_item -
1;
char *font =
NULL;
char *style =
NULL;
char *size =
NULL;
size_t fontLen, styleLen, sizeLen, outLen;
char *out;
if(i <
0)
return NULL;
FcPatternGetString(sel->list->fonts[i],
FC_FAMILY,
0, (FcChar8**)&font);
FcPatternGetString(sel->list->fonts[i],
FC_STYLE,
0, (FcChar8**)&style);
XtVaGetValues(
sel->size,
XmNselectedItems,
&table,
XmNselectedItemCount,
&count,
NULL);
if(count >
0) {
XmStringGetLtoR(table[
0], XmFONTLIST_DEFAULT_TAG, &size);
}
if(style && !strcmp(style,
"Regular")) {
style =
NULL;
}
fontLen = font ? strlen(font) :
0;
styleLen = style ? strlen(style) :
0;
sizeLen = size ? strlen(size) :
0;
if(style && size) {
outLen = fontLen + styleLen + sizeLen +
16;
out = XtMalloc(outLen);
snprintf(out, outLen,
"%s:style=%s:size=%s", font, style, size);
XmTextSetString(sel->name, out);
XtFree(size);
return out;
}
else if(size) {
outLen = fontLen + sizeLen +
16;
out = XtMalloc(outLen);
snprintf(out, outLen,
"%s:size=%s", font, size);
XmTextSetString(sel->name, out);
XtFree(size);
return out;
}
else {
return font;
}
}
static void UpdateFontName(FontSelector *sel)
{
char *fontStr = GetFontString(sel);
if(fontStr) {
UpdatePreview(sel, fontStr);
exposeFontPreview(sel->preview, sel,
NULL);
XmTextSetString(sel->name, fontStr);
XtFree(fontStr);
}
}
static void fontlist_callback(Widget w, FontSelector *sel, XmListCallbackStruct *cb)
{
sel->selected_item = cb->item_position;
UpdateFontName(sel);
}
static void SetMonospaceFilter(FontSelector *sel, Boolean on)
{
if(sel->filter) {
FcPatternDestroy(sel->filter);
}
sel->filter = FcPatternCreate();
if(on) {
FcPatternAddInteger(sel->filter,
FC_SPACING,
FC_MONO);
}
}
void fontlist_toggle_monospace(Widget w, FontSelector *sel, XmToggleButtonCallbackStruct *cb)
{
SetMonospaceFilter(sel, cb->set);
UpdateFontList(sel,
NULL);
}
void size_callback (Widget w, FontSelector *sel, XtPointer data)
{
UpdateFontName(sel);
}
static void ok_callback(Widget w, FontSelector *sel, XtPointer data)
{
sel->end =
1;
}
static void cancel_callback(Widget w, FontSelector *sel, XtPointer data)
{
sel->end =
1;
sel->cancel =
1;
}
static void FreeFontSelector(FontSelector *sel)
{
FcPatternDestroy(sel->filter);
Display *dp = XtDisplay(sel->preview);
XftDrawDestroy(sel->draw);
if(sel->font) {
XftFontClose(dp, sel->font);
}
if(sel->bold) {
XftFontClose(dp, sel->bold);
}
if(sel->italic) {
XftFontClose(dp, sel->italic);
}
if(sel->list) {
FcFontSetDestroy(sel->list);
}
NEditFree(sel);
}
char *FontSel(Widget parent,
const char *curFont)
{
Arg args[
32];
int n =
0;
XmString str;
FontSelector *sel = NEditMalloc(
sizeof(FontSelector));
memset(sel,
0,
sizeof(FontSelector));
Widget dialog = CreateDialogShell(parent,
"Font Selector", args,
0);
AddMotifCloseCallback(dialog, (XtCallbackProc)cancel_callback, sel);
Widget form = XmCreateForm(dialog,
"form", args,
0);
n =
0;
str = XmStringCreateSimple(
"OK");
XtSetArg(args[n], XmNtopOffset,
2); n++;
XtSetArg(args[n], XmNleftOffset,
5); n++;
XtSetArg(args[n], XmNbottomOffset,
5); n++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNlabelString, str); n++;
Widget okButton = XmCreatePushButton(form,
"button", args, n);
XtManageChild(okButton);
XmStringFree(str);
XtAddCallback(
okButton,
XmNactivateCallback,
(XtCallbackProc)ok_callback,
sel);
n =
0;
str = XmStringCreateSimple(
"Cancel");
XtSetArg(args[n], XmNtopOffset,
2); n++;
XtSetArg(args[n], XmNrightOffset,
5); n++;
XtSetArg(args[n], XmNbottomOffset,
5); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNlabelString, str); n++;
Widget cancelButton = XmCreatePushButton(form,
"button", args, n);
XtManageChild(cancelButton);
XmStringFree(str);
XtAddCallback(
cancelButton,
XmNactivateCallback,
(XtCallbackProc)cancel_callback,
sel);
n =
0;
XtSetArg(args[n], XmNbottomOffset,
2); n++;
XtSetArg(args[n], XmNleftOffset,
5); n++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNleftOffset,
5); n++;
XtSetArg(args[n], XmNrightOffset,
5); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNwidth,
400); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNbottomWidget, okButton); n++;
sel->name = XmCreateText(form,
"fcname_textfield", args, n);
XtManageChild(sel->name);
n =
0;
str = XmStringCreateSimple(
"Font name:");
XtSetArg(args[n], XmNbottomOffset,
2); n++;
XtSetArg(args[n], XmNleftOffset,
5); n++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNlabelString, str); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNbottomWidget, sel->name); n++;
Widget fontNameLabel = XmCreateLabel(form,
"label", args, n);
XtManageChild(fontNameLabel);
XmStringFree(str);
n =
0;
XtSetArg(args[n], XmNbottomOffset,
2); n++;
XtSetArg(args[n], XmNleftOffset,
5); n++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNrightOffset,
5); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNbottomWidget, fontNameLabel); n++;
XtSetArg(args[n], XmNshadowType, XmSHADOW_IN); n++;
XtSetArg(args[n], XmNmarginWidth,
3); n++;
XtSetArg(args[n], XmNmarginHeight,
3); n++;
Widget previewFrame = XmCreateFrame(form,
"frame", args, n);
XtManageChild(previewFrame);
n =
0;
sel->preview = XmCreateDrawingArea(previewFrame,
"fontpreview", args, n);
Dimension w, h;
XtMakeResizeRequest(sel->preview,
450,
180, &w, &h);
XtManageChild(sel->preview);
XtAddCallback(
sel->preview,
XmNexposeCallback,
(XtCallbackProc)exposeFontPreview,
sel);
n =
0;
str = XmStringCreateSimple(
"Show only non-proportional fonts");
XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNtopOffset,
5); n++;
XtSetArg(args[n], XmNleftOffset,
5); n++;
XtSetArg(args[n], XmNlabelString, str); n++;
XtSetArg(args[n], XmNset,
MONOSPACE_ONLY_DEFAULT); n++;
Widget toggleMonospace = XmCreateToggleButton(form,
"toggle_monospace", args, n);
XtManageChild(toggleMonospace);
XmStringFree(str);
XtAddCallback(
toggleMonospace,
XmNvalueChangedCallback,
(XtCallbackProc)fontlist_toggle_monospace,
sel);
n =
0;
str = XmStringCreateSimple(
"Font:");
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNtopWidget, toggleMonospace); n++;
XtSetArg(args[n], XmNtopOffset,
5); n++;
XtSetArg(args[n], XmNleftOffset,
5); n++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNlabelString, str); n++;
Widget fontListLabel = XmCreateLabel(form,
"label", args, n);
XtManageChild(fontListLabel);
XmStringFree(str);
n =
0;
str = XmStringCreateSimple(
"Size:");
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNtopWidget, toggleMonospace); n++;
XtSetArg(args[n], XmNtopOffset,
5); n++;
XtSetArg(args[n], XmNrightOffset,
5); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNlabelString, str); n++;
Widget fontSizeLabel = XmCreateLabel(form,
"label", args, n);
XtManageChild(fontSizeLabel);
XmStringFree(str);
n =
0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNtopWidget, fontSizeLabel); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNrightOffset,
5); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNbottomWidget, previewFrame); n++;
XtSetArg(args[n], XmNleftOffset,
2); n++;
XtSetArg(args[n], XmNbottomOffset,
2); n++;
XtSetArg(args[n], XmNtopOffset,
2); n++;
sel->size = XmCreateScrolledList(form,
"sizelist", args, n);
CreateSizeList(sel->size);
XtAddCallback (sel->size, XmNbrowseSelectionCallback, (XtCallbackProc)size_callback, sel);
XmListSelectPos(sel->size,
6,
0);
XtManageChild(sel->size);
Dimension szListWidth;
XtVaGetValues(sel->size, XmNwidth, &szListWidth,
NULL);
if(szListWidth >
0 && szListWidth <
40) {
XtVaSetValues(sel->size, XmNwidth,
40,
NULL);
}
n =
0;
XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNtopWidget, fontListLabel); n++;
XtSetArg(args[n], XmNtopOffset,
2); n++;
XtSetArg(args[n], XmNbottomOffset,
2); n++;
XtSetArg(args[n], XmNleftOffset,
5); n++;
XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNrightWidget, sel->size); n++;
XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
XtSetArg(args[n], XmNbottomWidget, previewFrame); n++;
XtSetArg(args[n], XmNvisibleItemCount,
10); n++;
sel->fontlist = XmCreateScrolledList(form,
"fontlist", args, n);
AddMouseWheelSupport(sel->fontlist);
XtManageChild(sel->fontlist);
XtAddCallback(
sel->fontlist,
XmNbrowseSelectionCallback,
(XtCallbackProc)fontlist_callback,
sel);
UpdatePreview(sel, curFont);
SetMonospaceFilter(sel,
MONOSPACE_ONLY_DEFAULT);
UpdateFontList(sel,
NULL);
XmString fontSelection;
XmString sizeSelection;
MatchFont(curFont, &fontSelection, &sizeSelection);
if(fontSelection) {
XmListSelectItem(sel->fontlist, fontSelection,
0);
XmStringFree(fontSelection);
int *pos;
int selcount =
0;
if(XmListGetSelectedPos(sel->fontlist, &pos, &selcount)) {
sel->selected_item = pos[
0];
XtFree((
void*)pos);
}
}
if(sizeSelection) {
XmListSelectItem(sel->size, sizeSelection,
0);
XmStringFree(sizeSelection);
}
ManageDialogCenteredOnPointer(form);
XtAppContext app = XtWidgetToApplicationContext(dialog);
while(!sel->end && !XtAppGetExitFlag(app)) {
XEvent event;
XtAppNextEvent(app, &event);
XtDispatchEvent(&event);
}
XtDestroyWidget(dialog);
char *retStr =
NULL;
if(!sel->cancel) {
retStr = GetFontString(sel);
}
if(!retStr) {
retStr = NEditStrdup(curFont);
}
FreeFontSelector(sel);
return retStr;
}
char* FontNameAddAttribute(
const char *name,
size_t len,
const char *attribute,
const char *value)
{
size_t attributelen = strlen(attribute);
size_t valuelen = strlen(value);
size_t newlen = len + attributelen + valuelen +
4;
char *attr = NEditMalloc(attributelen+
3);
char *newfont = NEditMalloc(newlen);
char *oldattr;
int i = len;
int b =
0;
int e =
0;
attr[
0] =
':';
memcpy(attr+
1, attribute, attributelen);
attr[attributelen+
1] =
'=';
attr[attributelen+
2] =
'\0';
oldattr = strstr(name, attr);
if(oldattr) {
b = (
int)(oldattr - name)+
1;
e = len;
for(i=b;i<len;i++) {
if(name[i] ==
':') {
e = i;
break;
}
}
}
NEditFree(attr);
if(b < len) {
if(b >
0 && name[b-
1] ==
':') b--;
snprintf(newfont, newlen,
"%.*s%.*s:%s=%s", b, name, (
int)(len-e), name+e, attribute, value);
}
else {
snprintf(newfont, newlen,
"%s:%s=%s", name, attribute, value);
}
return newfont;
}
void FontSelSetColors(XftColor fg, Pixel bg) {
default_fg_color = fg;
default_bg_pix = bg;
default_colors_set =
1;
}