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.
- Multibyte languages can now render antialiased text too (only tested on
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:

View File

@@ -604,6 +604,16 @@ testText(WMScreen *scr)
WMSetTextHasVerticalScroller(text, True);
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) {
char buf[1024];
@@ -1295,6 +1305,7 @@ main(int argc, char **argv)
testFontPanel(scr);
#if 0
testColorPanel(scr);
testScrollView(scr);

View File

@@ -117,15 +117,6 @@ typedef enum {
} WMFontFlags;
/* Font copy masks */
typedef enum {
WFMUnchanged = 0,
WFMMediumWeight = 1,
WFMNormalWeight = 2,
WFMRegularWeight = 3
} WMCopyFontMask;
/* Use default system font size in system font name */
enum {
WFDefaultSize = -1
@@ -441,8 +432,6 @@ typedef struct WMGenericPanel {
} WMGenericPanel;
typedef struct WMInputPanel {
WMWindow *win; /* window */
WMButton *defBtn; /* default button */
@@ -454,6 +443,34 @@ typedef struct 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: */
typedef struct {
WMArray *tabs; /* a growable array of tabstops */
@@ -736,7 +753,11 @@ WMFont* WMCreateAntialiasedFontSet(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);
@@ -767,16 +788,6 @@ WMFont* WMBoldSystemFontOfSize(WMScreen *scrPtr, int size);
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);

View File

@@ -12,6 +12,8 @@
#include <assert.h>
#include <X11/Xlocale.h>
#include <wchar.h>
static char *makeFontSetOfSize(char *fontset, int size);
@@ -181,7 +183,7 @@ WMCreateFontSet(WMScreen *scrPtr, char *fontName)
&nmissing, &defaultString);
if (nmissing > 0 && font->font.set) {
int i;
wwarning(_("the following character sets are missing in %s:"), fname);
for (i = 0; i < nmissing; i++) {
wwarning(missing[i]);
@@ -196,9 +198,9 @@ WMCreateFontSet(WMScreen *scrPtr, char *fontName)
wfree(fname);
return NULL;
}
extents = XExtentsOfFontSet(font->font.set);
font->height = extents->max_logical_extent.height;
font->y = font->height - (font->height + extents->max_logical_extent.y);
@@ -471,7 +473,7 @@ WMRetainFont(WMFont *font)
}
void
void
WMReleaseFont(WMFont *font)
{
wassertr(font!=NULL);
@@ -672,22 +674,24 @@ WMWidthOfString(WMFont *font, char *text, int length)
if (!font->notFontSet) {
wchar_t *wtext;
char *mtext;
int len;
/* Use mtext instead of text, because mbstrtowcs() alters it */
mtext = text;
wtext = (wchar_t *)wmalloc(4*length+4);
// pass a real ps instead of NULL below? for multithread safety as
// from manual
if (mbsrtowcs(wtext, &mtext, length, NULL)==length) {
/* pass a real ps instead of NULL below? for multithread safety
* as from manual page */
len = mbsrtowcs(wtext, (const char **) &mtext, length, NULL);
if (len>0) {
XftTextExtents32(font->screen->display, font->font.xft,
(XftChar32 *)wtext, length, &extents);
(XftChar32 *)wtext, len, &extents);
} else {
// - should rather say that conversion to widechar failed?
// - use mtext instead of text so that the position of the
// invalid sequence is shown?
wwarning(_("Invalid multibyte sequence: '%s'\n"), text);
XftTextExtents8(font->screen->display, font->font.xft,
(XftChar8 *)text, length, &extents);
if (len==-1) {
wwarning(_("Conversion to widechar failed (possible "
"invalid multibyte sequence): '%s':(pos %d)\n"),
text, mtext-text+1);
}
extents.xOff = 0;
}
wfree(wtext);
} else {
@@ -734,20 +738,23 @@ WMDrawString(WMScreen *scr, Drawable d, WMColor *color, WMFont *font,
if (!font->notFontSet) {
wchar_t *wtext;
char *mtext;
int len;
/* Use mtext instead of text, because mbstrtowcs() alters it */
mtext = text;
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,
x, y + font->y, (XftChar32*)wtext, length);
} else {
// - should rather say that conversion to widechar failed?
// - use mtext instead of text so that the position of the
// invalid sequence is shown?
wwarning(_("Invalid multibyte sequence: '%s'\n"), text);
XftDrawString8(scr->xftdraw, &xftcolor, font->font.xft,
x, y + font->y, (XftChar8*)text, length);
x, y + font->y, (XftChar32*)wtext, len);
} else if (len==-1) {
wwarning(_("Conversion to widechar failed (possible invalid "
"multibyte sequence): '%s':(pos %d)\n"),
text, mtext-text+1);
/* we can draw normal text, or we can draw as much widechar
* text as was already converted until the error. go figure */
/*XftDrawString8(scr->xftdraw, &xftcolor, font->font.xft,
x, y + font->y, (XftChar8*)text, length);*/
}
wfree(wtext);
} else {
@@ -802,20 +809,23 @@ WMDrawImageString(WMScreen *scr, Drawable d, WMColor *color, WMColor *background
if (!font->notFontSet) {
wchar_t *wtext;
char *mtext;
int len;
/* Use mtext instead of text, because mbstrtowcs() alters it */
mtext = text;
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,
x, y + font->y, (XftChar32*)wtext, length);
} else {
// - should rather say that conversion to widechar failed?
// - use mtext instead of text so that the position of the
// invalid sequence is shown?
wwarning(_("Invalid multibyte sequence: '%s'\n"), text);
XftDrawString8(scr->xftdraw, &textColor, font->font.xft,
x, y + font->y, (XftChar8*)text, length);
x, y + font->y, (XftChar32*)wtext, len);
} else if (len==-1) {
wwarning(_("Conversion to widechar failed (possible invalid "
"multibyte sequence): '%s':(pos %d)\n"),
text, mtext-text+1);
/* we can draw normal text, or we can draw as much widechar
* text as was already converted until the error. go figure */
/*XftDrawString8(scr->xftdraw, &textColor, font->font.xft,
x, y + font->y, (XftChar8*)text, length);*/
}
wfree(wtext);
} else {
@@ -892,119 +902,285 @@ makeFontSetOfSize(char *fontset, int size)
}
#define FONT_PROPS 14
typedef struct {
char *props[FONT_PROPS];
} W_FontAttributes;
static void
changeFontProp(char *fname, char *newprop, int which)
changeFontProp(char *buf, char *newprop, int position)
{
char before[128], prop[128], after[128];
char *ptr, *bptr;
int part=0;
char buf2[512];
char *ptr, *pptr, *rptr;
int count;
if (!fname || !prop)
if (buf[0]!='-') {
// remove warning later. or maybe not
wwarning(_("Invalid font specification: '%s'\n"), buf);
return;
}
ptr = fname;
bptr = before;
while (*ptr) {
if(*ptr == '-') {
*bptr = 0;
if (part==which)
bptr = prop;
else if (part==which+1)
bptr = after;
*bptr++ = *ptr;
part++;
} else {
*bptr++ = *ptr;
ptr = pptr = rptr = buf;
count = 0;
while (*ptr && *ptr!=',') {
if (*ptr == '-') {
count++;
if (count-1==position+1) {
rptr = ptr;
break;
}
if (count-1==position) {
pptr = ptr+1;
}
}
ptr++;
}
*bptr = 0;
snprintf(fname, 255, "%s-%s%s", before, newprop, after);
if (position==FONT_PROPS-1) {
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*
WMNormalizeFont(WMScreen *scr, WMFont *font)
WMCopyFontWithChanges(WMScreen *scrPtr, WMFont *font,
const WMFontAttributes *changes)
{
char fname[256];
WMFontFlags flag;
int index[FONT_PROPS], count[FONT_PROPS];
int totalProps, i, j, carry;
char fname[512];
WMFontFlags fFlags;
WMBag *props;
WMArray *options;
WMFont *result;
char *prop;
if (!scr || !font)
return NULL;
snprintf(fname, 512, "%s", font->name);
snprintf(fname, 255, "%s", font->name);
changeFontProp(fname, "medium", 2);
changeFontProp(fname, "r", 3);
flag = (font->antialiased ? WFAntialiased : WFNotAntialiased);
return WMCreateFontWithFlags(scr, fname, flag);
fFlags = (font->antialiased ? WFAntialiased : WFNotAntialiased);
fFlags |= (font->notFontSet ? WFNormalFont : WFFontSet);
props = WMCreateBagWithDestructor(1, (WMFreeDataProc*)WMFreeArray);
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)
return NULL;
snprintf(fname, 255, "%s", font->name);
changeFontProp(fname, "bold", 2);
flag = (font->antialiased ? WFAntialiased : WFNotAntialiased);
return WMCreateFontWithFlags(scr, fname, flag);
}
static const WMFontAttributes W_FANormal = {
WFAUnchanged,
WFAUnchanged,
"medium,normal,regular",
"r",
"normal", /* not sure about this */
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged
};
WMFont*
WMUnstrengthenFont(WMScreen *scr, WMFont *font)
{
char fname[256];
WMFontFlags flag;
if (!scr || !font)
return NULL;
snprintf(fname, 255, "%s", font->name);
changeFontProp(fname, "medium", 2);
flag = (font->antialiased ? WFAntialiased : WFNotAntialiased);
return WMCreateFontWithFlags(scr, fname, flag);
}
static const WMFontAttributes W_FABold = {
WFAUnchanged,
WFAUnchanged,
"bold",
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged
};
WMFont*
WMEmphasizeFont(WMScreen *scr, WMFont *font)
{
char fname[256];
WMFontFlags flag;
if (!scr || !font)
return NULL;
snprintf(fname, 255, "%s", font->name);
if (font->antialiased)
changeFontProp(fname, "i", 3);
else
changeFontProp(fname, "o", 3);
flag = (font->antialiased ? WFAntialiased : WFNotAntialiased);
return WMCreateFontWithFlags(scr, fname, flag);
}
static const WMFontAttributes W_FANonBold = {
WFAUnchanged,
WFAUnchanged,
"medium,normal,regular",
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged
};
WMFont*
WMUnemphasizeFont(WMScreen *scr, WMFont *font)
{
char fname[256];
WMFontFlags flag;
if (!scr || !font)
return NULL;
snprintf(fname, 255, "%s", font->name);
changeFontProp(fname, "r", 3);
flag = (font->antialiased ? WFAntialiased : WFNotAntialiased);
return WMCreateFontWithFlags(scr, fname, flag);
}
static const WMFontAttributes W_FAEmphasized = {
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
"o,i",
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
WFAUnchanged,
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;