diff -ur notion-3-2015061300/de/brush.c notion-3-2015061300-PATCHED/de/brush.c --- notion-3-2015061300/de/brush.c 2015-06-13 10:37:26.000000000 -0400 +++ notion-3-2015061300-PATCHED/de/brush.c 2015-07-13 10:37:23.093298917 -0400 @@ -48,6 +48,9 @@ gr_stylespec_init(&brush->current_attr); +#ifdef XFT + brush->draw=NULL; +#endif /* XFT */ style->usecount++; if(!grbrush_init(&(brush->grbrush))){ @@ -128,6 +131,10 @@ { destyle_unref(brush->d); brush->d=NULL; +#ifdef XFT + if(brush->draw!=NULL) + XftDrawDestroy(brush->draw); +#endif /* XFT */ gr_stylespec_unalloc(&brush->current_attr); grbrush_deinit(&(brush->grbrush)); } @@ -139,6 +146,21 @@ } +#ifdef XFT +XftDraw *debrush_get_draw(DEBrush *brush, Drawable d) +{ + if(brush->draw==NULL) + brush->draw=XftDrawCreate(ioncore_g.dpy, d, + XftDEDefaultVisual(), + DefaultColormap(ioncore_g.dpy, + 0)); + else + XftDrawChange(brush->draw, d); + + return brush->draw; +} +#endif + /*}}}*/ diff -ur notion-3-2015061300/de/brush.h notion-3-2015061300-PATCHED/de/brush.h --- notion-3-2015061300/de/brush.h 2015-06-13 10:37:26.000000000 -0400 +++ notion-3-2015061300-PATCHED/de/brush.h 2015-07-13 10:37:23.096298747 -0400 @@ -15,6 +15,10 @@ #include #include +#ifdef XFT +#include +#endif /* XFT */ + INTRCLASS(DEBrush); #include "style.h" @@ -33,6 +37,9 @@ DECLCLASS(DEBrush){ GrBrush grbrush; DEStyle *d; +#ifdef XFT + XftDraw *draw; +#endif DEBrushExtrasFn *extras_fn; int indicator_w; Window win; @@ -108,5 +115,8 @@ extern void debrush_fill_area(DEBrush *brush, const WRectangle *geom); extern void debrush_clear_area(DEBrush *brush, const WRectangle *geom); +#ifdef XFT +XftDraw *debrush_get_draw(DEBrush *brush, Drawable d); +#endif #endif /* ION_DE_BRUSH_H */ diff -ur notion-3-2015061300/de/colour.c notion-3-2015061300-PATCHED/de/colour.c --- notion-3-2015061300/de/colour.c 2015-06-13 10:37:26.000000000 -0400 +++ notion-3-2015061300-PATCHED/de/colour.c 2015-07-13 10:37:23.098298633 -0400 @@ -12,9 +12,21 @@ bool de_alloc_colour(WRootWin *rootwin, DEColour *ret, const char *name) { +#ifndef XFT XColor c; bool ok=FALSE; +#else /* XFT */ + if(name==NULL) + return FALSE; + return XftColorAllocName( + ioncore_g.dpy, + XftDEDefaultVisual(), + rootwin->default_cmap, + name, + ret); +#endif /* XFT */ +#ifndef XFT if(name==NULL) return FALSE; @@ -25,11 +37,13 @@ } return ok; +#endif /* ! XFT */ } bool de_duplicate_colour(WRootWin *rootwin, DEColour in, DEColour *out) { +#ifndef XFT XColor c; c.pixel=in; XQueryColor(ioncore_g.dpy, rootwin->default_cmap, &c); @@ -38,11 +52,20 @@ return TRUE; } return FALSE; +#else /* XFT */ + return XftColorAllocName( + ioncore_g.dpy, + XftDEDefaultVisual(), + rootwin->default_cmap, + &(in.color), + out); +#endif /* XFT */ } void de_free_colour_group(WRootWin *rootwin, DEColourGroup *cg) { +#ifndef XFT DEColour pixels[5]; pixels[0]=cg->bg; @@ -54,15 +77,26 @@ XFreeColors(ioncore_g.dpy, rootwin->default_cmap, pixels, 5, 0); gr_stylespec_unalloc(&cg->spec); +#else /* XFT */ + de_free_colour(rootwin, cg->bg); + de_free_colour(rootwin, cg->fg); + de_free_colour(rootwin, cg->hl); + de_free_colour(rootwin, cg->sh); + de_free_colour(rootwin, cg->pad); +#endif /* XFT */ } void de_free_colour(WRootWin *rootwin, DEColour col) { +#ifndef XFT DEColour pixels[1]; pixels[0]=col; XFreeColors(ioncore_g.dpy, rootwin->default_cmap, pixels, 1, 0); +#else /* XFT */ + XftColorFree(ioncore_g.dpy, XftDEDefaultVisual(), rootwin->default_cmap, &col); +#endif /* XFT */ } diff -ur notion-3-2015061300/de/colour.h notion-3-2015061300-PATCHED/de/colour.h --- notion-3-2015061300/de/colour.h 2015-06-13 10:37:26.000000000 -0400 +++ notion-3-2015061300-PATCHED/de/colour.h 2015-07-13 10:37:23.099298576 -0400 @@ -12,12 +12,19 @@ #include #include #include +#ifdef XFT +#include +#endif /* XFT */ INTRSTRUCT(DEColourGroup); +#ifndef XFT typedef unsigned long DEColour; +#else /* XFT */ +typedef XftColor DEColour; +#endif /* XFT */ DECLSTRUCT(DEColourGroup){ @@ -34,5 +41,6 @@ bool de_duplicate_colour(WRootWin *rootwin, DEColour in, DEColour *out); void de_free_colour_group(WRootWin *rootwin, DEColourGroup *cg); void de_free_colour(WRootWin *rootwin, DEColour col); +#define XftDEDefaultVisual() DefaultVisual(ioncore_g.dpy, 0) #endif /* ION_DE_COLOUR_H */ diff -ur notion-3-2015061300/de/draw.c notion-3-2015061300-PATCHED/de/draw.c --- notion-3-2015061300/de/draw.c 2015-06-13 10:37:26.000000000 -0400 +++ notion-3-2015061300-PATCHED/de/draw.c 2015-07-13 10:37:23.109298008 -0400 @@ -20,6 +20,14 @@ #include +#ifndef XFT +#define PIXEL(x) x +#else /* XFT */ +#define PIXEL(x) x.pixel +#endif /* XFT */ + + + /*{{{ Colour group lookup */ @@ -84,8 +92,7 @@ w--; h--; - XSetForeground(ioncore_g.dpy, gc, tlc); - + XSetForeground(ioncore_g.dpy, gc, PIXEL(tlc)); a=(br!=0); b=0; @@ -104,7 +111,7 @@ } - XSetForeground(ioncore_g.dpy, gc, brc); + XSetForeground(ioncore_g.dpy, gc, PIXEL(brc)); a=(tl!=0); b=0; @@ -141,23 +148,23 @@ GrBorderLine line) { if(line==GR_BORDERLINE_LEFT && geom->h>0 && tl>0){ - XSetForeground(ioncore_g.dpy, gc, tlc); - XSetBackground(ioncore_g.dpy, gc, tlc); + XSetForeground(ioncore_g.dpy, gc, PIXEL(tlc)); + XSetBackground(ioncore_g.dpy, gc, PIXEL(tlc)); XFillRectangle(ioncore_g.dpy, win, gc, geom->x, geom->y, tl, geom->h); geom->x+=tl; }else if(line==GR_BORDERLINE_TOP && geom->w>0 && tl>0){ - XSetForeground(ioncore_g.dpy, gc, tlc); - XSetBackground(ioncore_g.dpy, gc, tlc); + XSetForeground(ioncore_g.dpy, gc, PIXEL(tlc)); + XSetBackground(ioncore_g.dpy, gc, PIXEL(tlc)); XFillRectangle(ioncore_g.dpy, win, gc, geom->x, geom->y, geom->w, tl); geom->y+=tl; }else if(line==GR_BORDERLINE_RIGHT && geom->h>0 && br>0){ - XSetForeground(ioncore_g.dpy, gc, brc); - XSetBackground(ioncore_g.dpy, gc, brc); + XSetForeground(ioncore_g.dpy, gc, PIXEL(brc)); + XSetBackground(ioncore_g.dpy, gc, PIXEL(brc)); XFillRectangle(ioncore_g.dpy, win, gc, geom->x+geom->w-br, geom->y, br, geom->h); geom->w-=br; }else if(line==GR_BORDERLINE_BOTTOM && geom->w>0 && br>0){ - XSetForeground(ioncore_g.dpy, gc, brc); - XSetBackground(ioncore_g.dpy, gc, brc); + XSetForeground(ioncore_g.dpy, gc, PIXEL(brc)); + XSetBackground(ioncore_g.dpy, gc, PIXEL(brc)); XFillRectangle(ioncore_g.dpy, win, gc, geom->x, geom->y+geom->h-br, geom->w, br); geom->h-=br; } @@ -388,7 +395,7 @@ } if(ISSET(a2, GR_ATTR(tagged)) || ISSET(a1, GR_ATTR(tagged))){ - XSetForeground(ioncore_g.dpy, d->copy_gc, cg->fg); + XSetForeground(ioncore_g.dpy, d->copy_gc, PIXEL(cg->fg)); copy_masked(brush, d->tag_pixmap, brush->win, 0, 0, d->tag_pixmap_w, d->tag_pixmap_h, @@ -437,7 +444,7 @@ GC gc=brush->d->normal_gc; if(TRUE/*needfill*/){ - XSetForeground(ioncore_g.dpy, gc, cg->bg); + XSetForeground(ioncore_g.dpy, gc, PIXEL(cg->bg)); XFillRectangle(ioncore_g.dpy, brush->win, gc, geom->x, geom->y, geom->w, geom->h); } @@ -605,7 +612,7 @@ attr.background_pixmap=ParentRelative; }else{ attrflags=CWBackPixel; - attr.background_pixel=brush->d->cgrp.bg; + attr.background_pixel=brush->d->PIXEL(cgrp.bg); } XChangeWindowAttributes(ioncore_g.dpy, brush->win, attrflags, &attr); @@ -621,7 +628,7 @@ if(cg==NULL) return; - XSetForeground(ioncore_g.dpy, gc, cg->bg); + XSetForeground(ioncore_g.dpy, gc, PIXEL(cg->bg)); XFillRectangle(ioncore_g.dpy, brush->win, gc, geom->x, geom->y, geom->w, geom->h); } diff -ur notion-3-2015061300/de/font.c notion-3-2015061300-PATCHED/de/font.c --- notion-3-2015061300/de/font.c 2015-06-13 10:37:26.000000000 -0400 +++ notion-3-2015061300-PATCHED/de/font.c 2015-07-13 10:37:23.118297497 -0400 @@ -13,7 +13,9 @@ #include #include #include "font.h" +#ifndef XFT #include "fontset.h" +#endif /* ! XFT */ #include "brush.h" #include "precompose.h" @@ -106,6 +108,9 @@ DEFont *de_load_font(const char *fontname) { +#ifdef XFT + XftFont *font; +#endif DEFont *fnt; XFontSet fontset=NULL; XFontStruct *fontstruct=NULL; @@ -120,7 +125,8 @@ return fnt; } } - + +#ifndef XFT if(ioncore_g.use_mb && !(ioncore_g.enc_utf8 && iso10646_font(fontname))){ LOG(DEBUG, FONT, "Loading fontset %s", fontname); fontset=de_create_font_set(fontname); @@ -149,13 +155,34 @@ return NULL; } +#else /* XFT */ + if(strncmp(fontname, "xft:", 4)==0){ + font=XftFontOpenName(ioncore_g.dpy, DefaultScreen(ioncore_g.dpy), + fontname+4); + }else{ + font=XftFontOpenXlfd(ioncore_g.dpy, DefaultScreen(ioncore_g.dpy), fontname); + } + + if(font==NULL){ + if(strcmp(fontname, CF_FALLBACK_FONT_NAME)!=0){ + warn(TR("Could not load font \"%s\", trying \"%s\""), + fontname, CF_FALLBACK_FONT_NAME); + return de_load_font(CF_FALLBACK_FONT_NAME); + } + return NULL; + } +#endif /* XFT */ fnt=ALLOC(DEFont); if(fnt==NULL) return NULL; +#ifndef XFT fnt->fontset=fontset; fnt->fontstruct=fontstruct; +#else + fnt->font=font; +#endif fnt->pattern=scopy(fontname); fnt->next=NULL; fnt->prev=NULL; @@ -175,11 +202,13 @@ style->font=font; font->refcount++; +#ifndef XFT if(style->font->fontstruct!=NULL){ XSetFont(ioncore_g.dpy, style->normal_gc, style->font->fontstruct->fid); } +#endif /* ! XFT */ return TRUE; } @@ -194,11 +223,13 @@ if(style->font==NULL) return FALSE; +#ifndef XFT if(style->font->fontstruct!=NULL){ XSetFont(ioncore_g.dpy, style->normal_gc, style->font->fontstruct->fid); } +#endif /* ! XFT */ return TRUE; } @@ -208,10 +239,15 @@ if(--font->refcount!=0) return; +#ifndef XFT if(font->fontset!=NULL) XFreeFontSet(ioncore_g.dpy, font->fontset); if(font->fontstruct!=NULL) XFreeFont(ioncore_g.dpy, font->fontstruct); +#else /* XFT */ + if(font->font!=NULL) + XftFontClose(ioncore_g.dpy, font->font); +#endif /* XFT */ if(font->pattern!=NULL) free(font->pattern); @@ -239,6 +275,7 @@ void defont_get_font_extents(DEFont *font, GrFontExtents *fnte) { +#ifndef XFT if(font->fontset!=NULL){ XFontSetExtents *ext=XExtentsOfFontSet(font->fontset); if(ext==NULL) @@ -254,7 +291,14 @@ fnte->baseline=fnt->ascent; return; } - +#else /* 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 /* XFT */ fail: DE_RESET_FONT_EXTENTS(fnte); } @@ -271,6 +315,7 @@ uint defont_get_text_width(DEFont *font, const char *text, uint len) { +#ifndef XFT if(font->fontset!=NULL){ XRectangle lext; #ifdef CF_DE_USE_XUTF8 @@ -298,6 +343,18 @@ }else{ return 0; } +#else /* XFT */ + if(font->font!=NULL){ + XGlyphInfo extents; + if(ioncore_g.enc_utf8) + XftTextExtentsUtf8(ioncore_g.dpy, font->font, (XftChar8 *)text, len, &extents); + else + XftTextExtents8(ioncore_g.dpy, font->font, (XftChar8 *)text, len, &extents); + return extents.xOff; + }else{ + return 0; + } +#endif /* XFT */ } @@ -307,6 +364,7 @@ /*{{{ String drawing */ +#ifndef XFT void debrush_do_draw_string_default(DEBrush *brush, int x, int y, const char *str, int len, bool needfill, DEColourGroup *colours) @@ -366,6 +424,43 @@ } } +#else /* XFT */ +void debrush_do_draw_string_default(DEBrush *brush, + int x, int y, const char *str, + int len, bool needfill, + DEColourGroup *colours) +{ + Window win = brush->win; + GC gc=brush->d->normal_gc; + XftDraw *draw; + XftFont *font; + + if(brush->d->font==NULL) + return; + + font=brush->d->font->font; + draw=debrush_get_draw(brush, win); + + if(needfill){ + XGlyphInfo extents; + if(ioncore_g.enc_utf8){ + XftTextExtentsUtf8(ioncore_g.dpy, font, (XftChar8 *)str, len, + &extents); + }else{ + XftTextExtents8(ioncore_g.dpy, font, (XftChar8 *)str, len, &extents); + XftDrawRect(draw, &(colours->bg), x-extents.x, y-extents.y, + extents.width+10, extents.height); + } + } + + if(ioncore_g.enc_utf8){ + XftDrawStringUtf8(draw, &(colours->fg), font, x, y, (XftChar8 *)str, + len); + }else{ + XftDrawString8(draw, &(colours->fg), font, x, y, (XftChar8 *)str, len); + } +} +#endif /* XFT */ void debrush_do_draw_string(DEBrush *brush, int x, int y, const char *str, int len, bool needfill, diff -ur notion-3-2015061300/de/font.h notion-3-2015061300-PATCHED/de/font.h --- notion-3-2015061300/de/font.h 2015-06-13 10:37:26.000000000 -0400 +++ notion-3-2015061300-PATCHED/de/font.h 2015-07-13 10:37:23.119297440 -0400 @@ -12,6 +12,9 @@ #include #include +#ifdef XFT +#include +#endif /* XFT */ INTRSTRUCT(DEFont); @@ -27,6 +30,9 @@ int refcount; XFontSet fontset; XFontStruct *fontstruct; +#ifdef XFT /* XFT */ + XftFont *font; +#endif /* XFT */ DEFont *next, *prev; }; diff -ur notion-3-2015061300/de/init.c notion-3-2015061300-PATCHED/de/init.c --- notion-3-2015061300/de/init.c 2015-06-13 10:37:26.000000000 -0400 +++ notion-3-2015061300-PATCHED/de/init.c 2015-07-13 10:37:23.122297270 -0400 @@ -165,17 +165,26 @@ { bool bgset; DEColour padinh; - + DEColour black, white; + +#ifdef XFT + de_alloc_colour(rootwin, &black, "black"); + de_alloc_colour(rootwin, &white, "white"); +#else + black=DE_BLACK(rootwin); + white=DE_WHITE(rootwin); +#endif + de_get_colour(rootwin, &(cg->hl), tab, "highlight_colour", - (based_on ? based_on->cgrp.hl : DE_WHITE(rootwin))); + (based_on ? based_on->cgrp.hl : white)); de_get_colour(rootwin, &(cg->sh), tab, "shadow_colour", - (based_on ? based_on->cgrp.sh : DE_WHITE(rootwin))); + (based_on ? based_on->cgrp.sh : white)); de_get_colour(rootwin, &(cg->fg), tab, "foreground_colour", - (based_on ? based_on->cgrp.fg : DE_WHITE(rootwin))); + (based_on ? based_on->cgrp.fg : white)); bgset=de_get_colour(rootwin, &(cg->bg), tab, "background_colour", - (based_on ? based_on->cgrp.bg : DE_BLACK(rootwin))); + (based_on ? based_on->cgrp.bg : black)); - padinh=(based_on ? based_on->cgrp.pad : DE_WHITE(rootwin)); + padinh=(based_on ? based_on->cgrp.pad : white); de_get_colour_(rootwin, &(cg->pad), tab, "padding_colour", (bgset ? cg->bg : padinh), padinh); diff -ur notion-3-2015061300/de/style.c notion-3-2015061300-PATCHED/de/style.c --- notion-3-2015061300/de/style.c 2015-06-13 10:37:26.000000000 -0400 +++ notion-3-2015061300-PATCHED/de/style.c 2015-07-13 10:37:23.128296929 -0400 @@ -70,10 +70,17 @@ /*gcv.function=GXclear;*/ gcv.stipple=stipple_pixmap; gcvmask=GCFillStyle|GCStipple/*|GCFunction*/; +#ifndef XFT if(style->font!=NULL && style->font->fontstruct!=NULL){ gcv.font=style->font->fontstruct->fid; gcvmask|=GCFont; } +#else /* XFT */ +// if(style->font!=NULL){ +// gcv.font=style->font; +// gcvmask|=GCFont; +// } +#endif /* XFT */ style->stipple_gc=XCreateGC(dpy, root, gcvmask, &gcv); XCopyGC(dpy, style->normal_gc, @@ -201,6 +208,14 @@ bool destyle_init(DEStyle *style, WRootWin *rootwin, const char *name) { + DEColour black, white; +#ifdef XFT + de_alloc_colour(rootwin, &black, "black"); + de_alloc_colour(rootwin, &white, "white"); +#else + black=DE_BLACK(rootwin); + white=DE_WHITE(rootwin); +#endif /* XFT */ if(!gr_stylespec_load(&style->spec, name)) return FALSE; @@ -223,11 +238,11 @@ style->textalign=DEALIGN_CENTER; style->cgrp_alloced=FALSE; - style->cgrp.bg=DE_BLACK(rootwin); - style->cgrp.pad=DE_BLACK(rootwin); - style->cgrp.fg=DE_WHITE(rootwin); - style->cgrp.hl=DE_WHITE(rootwin); - style->cgrp.sh=DE_WHITE(rootwin); + style->cgrp.bg=black; + style->cgrp.pad=black; + style->cgrp.fg=white; + style->cgrp.hl=white; + style->cgrp.sh=white; gr_stylespec_init(&style->cgrp.spec); style->font=NULL; diff -ur notion-3-2015061300/de/style.h notion-3-2015061300-PATCHED/de/style.h --- notion-3-2015061300/de/style.h 2015-06-13 10:37:26.000000000 -0400 +++ notion-3-2015061300-PATCHED/de/style.h 2015-07-13 10:37:23.130296815 -0400 @@ -80,6 +80,7 @@ Pixmap tag_pixmap; int tag_pixmap_w; int tag_pixmap_h; + int xft_style; DEStyle *next, *prev; }; diff -ur notion-3-2015061300/system-autodetect.mk notion-3-2015061300-PATCHED/system-autodetect.mk --- notion-3-2015061300/system-autodetect.mk 2015-06-13 10:37:26.000000000 -0400 +++ notion-3-2015061300-PATCHED/system-autodetect.mk 2015-07-13 10:38:14.921332013 -0400 @@ -103,6 +103,19 @@ ## +## Xft support +## + +USE_XFT=1 + +ifeq ($(USE_XFT),1) +EXTRA_INCLUDES += `pkg-config xft --cflags` +EXTRA_LIBS += `pkg-config xft --libs` +DEFINES += -DXFT -DCF_FALLBACK_FONT_NAME=\"Sans\" +endif + + +## ## Localisation ##