1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 12:28:22 +01:00

- added WMCopyFontWithChanges() a more generic and powerful function, meant

to replace WMNormalizeFont(), WMEmphasizeFont(), WMStrenghtenFont(),
  WMUnemphasizeFont() and WMUnstrenghtenFont() which are now obsolete and
  were removed.
This commit is contained in:
dan
2002-11-22 04:49:05 +00:00
parent 0bfa12a1fc
commit 18b3753227
4 changed files with 346 additions and 143 deletions

View File

@@ -36,6 +36,11 @@ Changes since wmaker 0.80.1:
The more generic WMCreateFont() or WMCreateFontWithFlags() should be used. The more generic WMCreateFont() or WMCreateFontWithFlags() should be used.
- Multibyte languages can now render antialiased text too (only tested on - Multibyte languages can now render antialiased text too (only tested on
russian since this is the only multibyte language I can test). russian since this is the only multibyte language I can test).
- Added WMCopyFontWithChanges(). This is a more generic and powerful function
meant to replaces the obsoleted WMEmphasizeFont(), WMNormalizeFont(),
WMStrenghtenFont() and the other similar functions. To get the same effect
you pass some predefined structs to it: WFANormal, WFABold, WFAEmphasized,
etc)
Changes since wmaker 0.80.0: Changes since wmaker 0.80.0:

View File

@@ -604,6 +604,16 @@ testText(WMScreen *scr)
WMSetTextHasVerticalScroller(text, True); WMSetTextHasVerticalScroller(text, True);
WMSetTextEditable(text, False); WMSetTextEditable(text, False);
if (1) {
WMFont *font, *ifont;
font = WMDefaultSystemFont(scr);
ifont = WMCopyFontWithChanges(scr, font, WFAEmphasized);
WMSetTextDefaultFont(text, ifont);
WMReleaseFont(font);
WMReleaseFont(ifont);
}
if(file) { if(file) {
char buf[1024]; char buf[1024];
@@ -1295,6 +1305,7 @@ main(int argc, char **argv)
testFontPanel(scr); testFontPanel(scr);
#if 0 #if 0
testColorPanel(scr); testColorPanel(scr);
testScrollView(scr); testScrollView(scr);

View File

@@ -117,15 +117,6 @@ typedef enum {
} WMFontFlags; } WMFontFlags;
/* Font copy masks */
typedef enum {
WFMUnchanged = 0,
WFMMediumWeight = 1,
WFMNormalWeight = 2,
WFMRegularWeight = 3
} WMCopyFontMask;
/* Use default system font size in system font name */ /* Use default system font size in system font name */
enum { enum {
WFDefaultSize = -1 WFDefaultSize = -1
@@ -441,8 +432,6 @@ typedef struct WMGenericPanel {
} WMGenericPanel; } WMGenericPanel;
typedef struct WMInputPanel { typedef struct WMInputPanel {
WMWindow *win; /* window */ WMWindow *win; /* window */
WMButton *defBtn; /* default button */ WMButton *defBtn; /* default button */
@@ -454,6 +443,34 @@ typedef struct WMInputPanel {
} WMInputPanel; } WMInputPanel;
#define WFAUnchanged (NULL)
/* Struct for font change operations */
typedef struct WMFontAttributes {
char *foundry;
char *family;
char *weight;
char *slant;
char *setWidth;
char *addStyle;
char *pixelSize;
char *pointSize;
char *resolutionX;
char *resolutionY;
char *spacing;
char *averageWidth;
char *registry;
char *encoding;
} WMFontAttributes;
extern const WMFontAttributes *WFANormal;
extern const WMFontAttributes *WFABold;
extern const WMFontAttributes *WFANonBold;
extern const WMFontAttributes *WFAEmphasized;
extern const WMFontAttributes *WFANonEmphasized;
extern const WMFontAttributes *WFABoldEmphasized;
/* WMRuler: */ /* WMRuler: */
typedef struct { typedef struct {
WMArray *tabs; /* a growable array of tabstops */ WMArray *tabs; /* a growable array of tabstops */
@@ -736,7 +753,11 @@ WMFont* WMCreateAntialiasedFontSet(WMScreen *scrPtr, char *fontName);
WMFont* WMCreateFont(WMScreen *scrPtr, char *fontName); WMFont* WMCreateFont(WMScreen *scrPtr, char *fontName);
WMFont* WMCreateFontWithFlags(WMScreen *scrPtr, char *fontName, WMFontFlags flags); WMFont* WMCreateFontWithFlags(WMScreen *scrPtr, char *fontName,
WMFontFlags flags);
WMFont* WMCopyFontWithChanges(WMScreen *scrPtr, WMFont *font,
const WMFontAttributes *changes);
WMFont* WMRetainFont(WMFont *font); WMFont* WMRetainFont(WMFont *font);
@@ -767,16 +788,6 @@ WMFont* WMBoldSystemFontOfSize(WMScreen *scrPtr, int size);
XFontSet WMGetFontFontSet(WMFont *font); XFontSet WMGetFontFontSet(WMFont *font);
WMFont* WMNormalizeFont(WMScreen *scr, WMFont *font);
WMFont* WMStrengthenFont(WMScreen *scr, WMFont *font);
WMFont* WMUnstrengthenFont(WMScreen *scr, WMFont *font);
WMFont* WMEmphasizeFont(WMScreen *scr, WMFont *font);
WMFont* WMUnemphasizeFont(WMScreen *scr, WMFont *font);
/* ....................................................................... */ /* ....................................................................... */
WMPixmap* WMRetainPixmap(WMPixmap *pixmap); WMPixmap* WMRetainPixmap(WMPixmap *pixmap);

View File

@@ -12,6 +12,8 @@
#include <assert.h> #include <assert.h>
#include <X11/Xlocale.h> #include <X11/Xlocale.h>
#include <wchar.h>
static char *makeFontSetOfSize(char *fontset, int size); static char *makeFontSetOfSize(char *fontset, int size);
@@ -672,22 +674,24 @@ WMWidthOfString(WMFont *font, char *text, int length)
if (!font->notFontSet) { if (!font->notFontSet) {
wchar_t *wtext; wchar_t *wtext;
char *mtext; char *mtext;
int len;
/* Use mtext instead of text, because mbstrtowcs() alters it */ /* Use mtext instead of text, because mbstrtowcs() alters it */
mtext = text; mtext = text;
wtext = (wchar_t *)wmalloc(4*length+4); wtext = (wchar_t *)wmalloc(4*length+4);
// pass a real ps instead of NULL below? for multithread safety as /* pass a real ps instead of NULL below? for multithread safety
// from manual * as from manual page */
if (mbsrtowcs(wtext, &mtext, length, NULL)==length) { len = mbsrtowcs(wtext, (const char **) &mtext, length, NULL);
if (len>0) {
XftTextExtents32(font->screen->display, font->font.xft, XftTextExtents32(font->screen->display, font->font.xft,
(XftChar32 *)wtext, length, &extents); (XftChar32 *)wtext, len, &extents);
} else { } else {
// - should rather say that conversion to widechar failed? if (len==-1) {
// - use mtext instead of text so that the position of the wwarning(_("Conversion to widechar failed (possible "
// invalid sequence is shown? "invalid multibyte sequence): '%s':(pos %d)\n"),
wwarning(_("Invalid multibyte sequence: '%s'\n"), text); text, mtext-text+1);
XftTextExtents8(font->screen->display, font->font.xft, }
(XftChar8 *)text, length, &extents); extents.xOff = 0;
} }
wfree(wtext); wfree(wtext);
} else { } else {
@@ -734,20 +738,23 @@ WMDrawString(WMScreen *scr, Drawable d, WMColor *color, WMFont *font,
if (!font->notFontSet) { if (!font->notFontSet) {
wchar_t *wtext; wchar_t *wtext;
char *mtext; char *mtext;
int len;
/* Use mtext instead of text, because mbstrtowcs() alters it */ /* Use mtext instead of text, because mbstrtowcs() alters it */
mtext = text; mtext = text;
wtext = (wchar_t *)wmalloc(4*length+4); wtext = (wchar_t *)wmalloc(4*length+4);
if (mbsrtowcs(wtext, &mtext, length, NULL)==length) { len = mbsrtowcs(wtext, (const char **) &mtext, length, NULL);
if (len>0) {
XftDrawString32(scr->xftdraw, &xftcolor, font->font.xft, XftDrawString32(scr->xftdraw, &xftcolor, font->font.xft,
x, y + font->y, (XftChar32*)wtext, length); x, y + font->y, (XftChar32*)wtext, len);
} else { } else if (len==-1) {
// - should rather say that conversion to widechar failed? wwarning(_("Conversion to widechar failed (possible invalid "
// - use mtext instead of text so that the position of the "multibyte sequence): '%s':(pos %d)\n"),
// invalid sequence is shown? text, mtext-text+1);
wwarning(_("Invalid multibyte sequence: '%s'\n"), text); /* we can draw normal text, or we can draw as much widechar
XftDrawString8(scr->xftdraw, &xftcolor, font->font.xft, * text as was already converted until the error. go figure */
x, y + font->y, (XftChar8*)text, length); /*XftDrawString8(scr->xftdraw, &xftcolor, font->font.xft,
x, y + font->y, (XftChar8*)text, length);*/
} }
wfree(wtext); wfree(wtext);
} else { } else {
@@ -802,20 +809,23 @@ WMDrawImageString(WMScreen *scr, Drawable d, WMColor *color, WMColor *background
if (!font->notFontSet) { if (!font->notFontSet) {
wchar_t *wtext; wchar_t *wtext;
char *mtext; char *mtext;
int len;
/* Use mtext instead of text, because mbstrtowcs() alters it */ /* Use mtext instead of text, because mbstrtowcs() alters it */
mtext = text; mtext = text;
wtext = (wchar_t *)wmalloc(4*length+4); wtext = (wchar_t *)wmalloc(4*length+4);
if (mbsrtowcs(wtext, &mtext, length, NULL)==length) { len = mbsrtowcs(wtext, (const char **) &mtext, length, NULL);
if (len>0) {
XftDrawString32(scr->xftdraw, &textColor, font->font.xft, XftDrawString32(scr->xftdraw, &textColor, font->font.xft,
x, y + font->y, (XftChar32*)wtext, length); x, y + font->y, (XftChar32*)wtext, len);
} else { } else if (len==-1) {
// - should rather say that conversion to widechar failed? wwarning(_("Conversion to widechar failed (possible invalid "
// - use mtext instead of text so that the position of the "multibyte sequence): '%s':(pos %d)\n"),
// invalid sequence is shown? text, mtext-text+1);
wwarning(_("Invalid multibyte sequence: '%s'\n"), text); /* we can draw normal text, or we can draw as much widechar
XftDrawString8(scr->xftdraw, &textColor, font->font.xft, * text as was already converted until the error. go figure */
x, y + font->y, (XftChar8*)text, length); /*XftDrawString8(scr->xftdraw, &textColor, font->font.xft,
x, y + font->y, (XftChar8*)text, length);*/
} }
wfree(wtext); wfree(wtext);
} else { } else {
@@ -892,119 +902,285 @@ makeFontSetOfSize(char *fontset, int size)
} }
#define FONT_PROPS 14
typedef struct {
char *props[FONT_PROPS];
} W_FontAttributes;
static void static void
changeFontProp(char *fname, char *newprop, int which) changeFontProp(char *buf, char *newprop, int position)
{ {
char before[128], prop[128], after[128]; char buf2[512];
char *ptr, *bptr; char *ptr, *pptr, *rptr;
int part=0; int count;
if (!fname || !prop) if (buf[0]!='-') {
// remove warning later. or maybe not
wwarning(_("Invalid font specification: '%s'\n"), buf);
return; return;
}
ptr = fname; ptr = pptr = rptr = buf;
bptr = before; count = 0;
while (*ptr) { while (*ptr && *ptr!=',') {
if(*ptr == '-') { if (*ptr == '-') {
*bptr = 0; count++;
if (part==which) if (count-1==position+1) {
bptr = prop; rptr = ptr;
else if (part==which+1) break;
bptr = after; }
*bptr++ = *ptr; if (count-1==position) {
part++; pptr = ptr+1;
} else { }
*bptr++ = *ptr;
} }
ptr++; ptr++;
} }
*bptr = 0; if (position==FONT_PROPS-1) {
snprintf(fname, 255, "%s-%s%s", before, newprop, after); rptr = ptr;
}
*pptr = 0;
snprintf(buf2, 512, "%s%s%s", buf, newprop, rptr);
strcpy(buf, buf2);
}
static WMArray*
getOptions(char *options)
{
char *ptr, *ptr2, *str;
WMArray *result;
int count;
result = WMCreateArrayWithDestructor(2, (WMFreeDataProc*)wfree);
ptr = options;
while (1) {
ptr2 = strchr(ptr, ',');
if (!ptr2) {
WMAddToArray(result, wstrdup(ptr));
break;
} else {
count = ptr2 - ptr;
str = wmalloc(count+1);
memcpy(str, ptr, count);
str[count] = 0;
WMAddToArray(result, str);
ptr = ptr2 + 1;
}
}
return result;
} }
WMFont* WMFont*
WMNormalizeFont(WMScreen *scr, WMFont *font) WMCopyFontWithChanges(WMScreen *scrPtr, WMFont *font,
const WMFontAttributes *changes)
{ {
char fname[256]; int index[FONT_PROPS], count[FONT_PROPS];
WMFontFlags flag; int totalProps, i, j, carry;
char fname[512];
WMFontFlags fFlags;
WMBag *props;
WMArray *options;
WMFont *result;
char *prop;
if (!scr || !font) snprintf(fname, 512, "%s", font->name);
return NULL;
snprintf(fname, 255, "%s", font->name); fFlags = (font->antialiased ? WFAntialiased : WFNotAntialiased);
changeFontProp(fname, "medium", 2); fFlags |= (font->notFontSet ? WFNormalFont : WFFontSet);
changeFontProp(fname, "r", 3);
flag = (font->antialiased ? WFAntialiased : WFNotAntialiased); props = WMCreateBagWithDestructor(1, (WMFreeDataProc*)WMFreeArray);
return WMCreateFontWithFlags(scr, fname, flag);
totalProps = 0;
for (i=0; i<FONT_PROPS; i++) {
prop = ((W_FontAttributes*)changes)->props[i];
count[i] = index[i] = 0;
if (!prop) {
/* No change for this property */
continue;
} else if (strchr(prop, ',')==NULL) {
/* Simple option */
changeFontProp(fname, prop, i);
} else {
/* Option with fallback alternatives */
if ((changes==WFAEmphasized || changes==WFABoldEmphasized) &&
font->antialiased && strcmp(prop, "o,i")==0) {
options = getOptions("i,o");
} else {
options = getOptions(prop);
}
WMInsertInBag(props, i, options);
count[i] = WMGetArrayItemCount(options);
if (totalProps==0)
totalProps = 1;
totalProps = totalProps * count[i];
}
}
if (totalProps == 0) {
/* No options with fallback alternatives at all */
WMFreeBag(props);
//printf("try: '%s'\n '%s'\n", font->name, fname);
return WMCreateFontWithFlags(scrPtr, fname, fFlags);
}
for (i=0; i<totalProps; i++) {
for (j=0; j<FONT_PROPS; j++) {
if (count[j]!=0) {
options = WMGetFromBag(props, j);
prop = WMGetFromArray(options, index[j]);
if (prop) {
changeFontProp(fname, prop, j);
}
}
}
result = WMCreateFontWithFlags(scrPtr, fname, fFlags);
//printf("try: '%s'\n '%s'\n", font->name, fname);
if (result) {
WMFreeBag(props);
return result;
}
for (j=FONT_PROPS-1, carry=1; j>=0; j--) {
if (count[j]!=0) {
index[j] += carry;
carry = (index[j]==count[j]);
index[j] %= count[j];
}
}
}
WMFreeBag(props);
return NULL;
} }
WMFont*
WMStrengthenFont(WMScreen *scr, WMFont *font)
{
char fname[256];
WMFontFlags flag;
if (!scr || !font) static const WMFontAttributes W_FANormal = {
return NULL; WFAUnchanged,
WFAUnchanged,
snprintf(fname, 255, "%s", font->name); "medium,normal,regular",
changeFontProp(fname, "bold", 2); "r",
flag = (font->antialiased ? WFAntialiased : WFNotAntialiased); "normal", /* not sure about this */
return WMCreateFontWithFlags(scr, fname, flag); WFAUnchanged,
} WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged
};
WMFont* static const WMFontAttributes W_FABold = {
WMUnstrengthenFont(WMScreen *scr, WMFont *font) WFAUnchanged,
{ WFAUnchanged,
char fname[256]; "bold",
WMFontFlags flag; WFAUnchanged,
WFAUnchanged,
if (!scr || !font) WFAUnchanged,
return NULL; WFAUnchanged,
WFAUnchanged,
snprintf(fname, 255, "%s", font->name); WFAUnchanged,
changeFontProp(fname, "medium", 2); WFAUnchanged,
flag = (font->antialiased ? WFAntialiased : WFNotAntialiased); WFAUnchanged,
return WMCreateFontWithFlags(scr, fname, flag); WFAUnchanged,
} WFAUnchanged,
WFAUnchanged
};
WMFont* static const WMFontAttributes W_FANonBold = {
WMEmphasizeFont(WMScreen *scr, WMFont *font) WFAUnchanged,
{ WFAUnchanged,
char fname[256]; "medium,normal,regular",
WMFontFlags flag; WFAUnchanged,
WFAUnchanged,
if (!scr || !font) WFAUnchanged,
return NULL; WFAUnchanged,
WFAUnchanged,
snprintf(fname, 255, "%s", font->name); WFAUnchanged,
if (font->antialiased) WFAUnchanged,
changeFontProp(fname, "i", 3); WFAUnchanged,
else WFAUnchanged,
changeFontProp(fname, "o", 3); WFAUnchanged,
WFAUnchanged
flag = (font->antialiased ? WFAntialiased : WFNotAntialiased); };
return WMCreateFontWithFlags(scr, fname, flag);
}
WMFont* static const WMFontAttributes W_FAEmphasized = {
WMUnemphasizeFont(WMScreen *scr, WMFont *font) WFAUnchanged,
{ WFAUnchanged,
char fname[256]; WFAUnchanged,
WMFontFlags flag; "o,i",
WFAUnchanged,
if (!scr || !font) WFAUnchanged,
return NULL; WFAUnchanged,
WFAUnchanged,
snprintf(fname, 255, "%s", font->name); WFAUnchanged,
changeFontProp(fname, "r", 3); WFAUnchanged,
flag = (font->antialiased ? WFAntialiased : WFNotAntialiased); WFAUnchanged,
return WMCreateFontWithFlags(scr, fname, flag); WFAUnchanged,
} WFAUnchanged,
WFAUnchanged
};
static const WMFontAttributes W_FANonEmphasized = {
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
"r",
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged
};
static const WMFontAttributes W_FABoldEmphasized = {
WFAUnchanged,
WFAUnchanged,
"bold",
"o,i",
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged
};
// by exposing a ptr to them we can allow one to alter their content
// const doesn't prevent this effectively.
// altering the content doesn't effectively work because it will core dump
// if one tries, but still is not clean.
// however passing the whole struct to the function instead of just the
// pointer means passing a strcut with 14 pointers to char*
//
const WMFontAttributes *WFANormal = &W_FANormal;
const WMFontAttributes *WFABold = &W_FABold;
const WMFontAttributes *WFANonBold = &W_FANonBold;
const WMFontAttributes *WFAEmphasized = &W_FAEmphasized;
const WMFontAttributes *WFANonEmphasized = &W_FANonEmphasized;
const WMFontAttributes *WFABoldEmphasized = &W_FABoldEmphasized;