Nekochan Net

Official Chat Channel: #nekochan // irc.nekochan.net
It is currently Mon Sep 01, 2014 5:44 am

All times are UTC - 8 hours


Forum rules


Any posts concerning pirated software or offering to buy/sell/trade commercial software are subject to removal.



Post new topic Reply to topic  [ 5 posts ] 
Author Message
Unread postPosted: Mon Jan 23, 2006 10:33 am 
Offline
Moderator
Moderator
User avatar

Joined: Fri May 09, 2003 5:10 am
Posts: 2931
Location: Maryland, USA
I finally found a sliver of time to do something I've been itchin' to try. I wrote a very small app that uses libXft and freetype2 to draw anti-aliased text in a X window. It is pure X and doesn't require Xt or any toolkit like Motif, GTK+ or Qt. Basically, Keith Packard has replaced the core X font calls with equivalents. Here's the little app, which I post here because there doesn't seem to be anything like it on the web. The closest is here: http://www.keithp.com/~keithp/render/Xft.tutorial

xfthello.c
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifdef HAVE_XFT
#include <Xft/Xft.h>
#endif

#define DEFAULT_BDWIDTH 1 /* border width */

#ifdef HAVE_XFT
char *text = "Hello Xft";
#else
char *text = "Hello X11";
#endif

Display *dpy;

int main( int argc, char *argv[] )
{
   int                     ytext, wtext, htext, gravity, geo_mask;
   int                     Done = 0, highlight = 0, force_expose = 0;
   XSizeHints              xsh;
   XWMHints                xwmh;
   unsigned long           fgpix, bgpix;
   Window                  mainW;
   XSetWindowAttributes    xswa;
#ifdef HAVE_XFT
   XftFont                 *font;
   XftDraw                 *xftdraw;
   XRenderColor            xrcolor;
   XftColor                xftcolor, hlcolor;
   XGlyphInfo              extents;
#else
   GC                      gc;
   XGCValues               gcvals;
   XFontStruct             *font;
#endif
   XEvent                  event;
   char                    user_geo[80];
   
   /* open connection to X display */
   dpy = XOpenDisplay( NULL );
   
   /* set up font */
#ifdef HAVE_XFT
   font = XftFontOpenName( dpy, DefaultScreen( dpy ), "morpheus-18" );
#else   
   font = XLoadQueryFont( dpy, "-*-helvetica-medium-r-normal--20-*-*-*-p-100-iso8859-1" );
#endif
   
   /* colors */
   fgpix = BlackPixel( dpy, DefaultScreen( dpy ) );
   bgpix = WhitePixel( dpy, DefaultScreen( dpy ) );
   
   /* position and size of top window (XSizeHints) */
#ifdef HAVE_XFT
   XftTextExtents8( dpy, font, (XftChar8 *)text, strlen(text), &extents );
   ytext = extents.height - extents.y;
   wtext = extents.width - extents.x;
#else   
   ytext = font->max_bounds.ascent + font->max_bounds.descent;
   wtext = font->max_bounds.width / 2 + XTextWidth( font, text, strlen(text) + 4 );
#endif   
   htext = ytext + 4;   
   xsh.flags = ( PPosition | PSize | PMinSize );
   xsh.height = htext + 10;
   xsh.min_height = xsh.height;
   xsh.width = wtext;
   xsh.min_width = xsh.width;
   xsh.x = 50;
   xsh.y = 50;
   
   /* construct a geometry string */
   sprintf( user_geo, "%dx%d+%d+%d", xsh.width, xsh.height, xsh.x, xsh.y );
   
   /* process geometry specification */
   geo_mask = XWMGeometry( dpy, DefaultScreen(dpy), user_geo, NULL/*def_geo*/,
                  DEFAULT_BDWIDTH, &xsh, &xsh.x, &xsh.y, &xsh.width, &xsh.height,
                  &gravity );
   
   /* check geometry bitmask and set size hints */
   if ( geo_mask & (XValue|YValue) ) xsh.flags |= USPosition;
   if ( geo_mask & (WidthValue|HeightValue) ) xsh.flags |= USSize;
   
   /* create top level window */
   mainW = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), xsh.x, xsh.y,
               xsh.width, xsh.height, DEFAULT_BDWIDTH, fgpix, bgpix );
   
   /* set window manager properties */
   XSetStandardProperties( dpy, mainW, "xhello", "xhello", None, argv, argc, &xsh );
   
   /* set window manager hints */
   xwmh.flags = (InputHint|StateHint);
   xwmh.input = False;
   xwmh.initial_state = NormalState;
   XSetWMHints( dpy, mainW, &xwmh );

#ifdef HAVE_XFT
   /* Xft draw context */
   xftdraw = XftDrawCreate( dpy, mainW, DefaultVisual(dpy,DefaultScreen(dpy)),
               DefaultColormap( dpy, DefaultScreen(dpy) ) );
   /* Xft text color */
   xrcolor.red = 0x0;
   xrcolor.green = 0x0;
   xrcolor.blue = 0x0;
   xrcolor.alpha = 0xffff;
   XftColorAllocValue( dpy, DefaultVisual(dpy,DefaultScreen(dpy)),
               DefaultColormap( dpy, DefaultScreen(dpy) ), &xrcolor, &xftcolor );
   /* Xft highlight color */
   xrcolor.red = 0xafff;
   xrcolor.green = 0xafff;
   xrcolor.blue = 0xffff;
   xrcolor.alpha = 0xffff;
   XftColorAllocValue( dpy, DefaultVisual(dpy,DefaultScreen(dpy)),
               DefaultColormap( dpy, DefaultScreen(dpy) ), &xrcolor, &hlcolor );
#else                 
   /* create graphics context */
   gcvals.font = font->fid;
   gcvals.foreground = fgpix;
   gcvals.background = bgpix;
   gc = XCreateGC( dpy, mainW, (GCFont|GCForeground|GCBackground), &gcvals );
#endif   
   
   /* set window attributes */
   xswa.colormap = DefaultColormap( dpy, DefaultScreen(dpy) );
   xswa.bit_gravity = CenterGravity;
   XChangeWindowAttributes( dpy, mainW, (CWColormap|CWBitGravity), &xswa );
   
   /* select inputs */
   XSelectInput( dpy, mainW, ExposureMask|ButtonPressMask|EnterWindowMask|LeaveWindowMask );
   
   /* make window visible */
   XMapWindow( dpy, mainW );
   printf("click on the window to exit\n");
   
   /* retrieve and process events */
   while ( !Done ) {
      XNextEvent( dpy, &event );
      if ( event.xany.window == mainW ) {
         switch ( event.type ) {
            case EnterNotify:
            case LeaveNotify:
               if ( event.type==EnterNotify) highlight = 1;
               else highlight = 0;
               force_expose = 1;
            case Expose:
               if ( event.xexpose.count == 0 || force_expose ) {
                  int            x, y, itmp;
                  unsigned int   w, h, utmp;
                  Window         wtmp;

                  if ( XGetGeometry( dpy, mainW, &wtmp, &itmp, &itmp, &w, &h, &utmp, &utmp )==0 )
                     break;
                  XClearWindow( dpy, mainW );
#ifdef HAVE_XFT
                  x = ( w - extents.width ) / 2;
                  y = htext + ( h - htext + extents.height )/2;
                  if (highlight) XftDrawRect( xftdraw, &hlcolor, x, y-extents.height, wtext, extents.height  );
                  XftDrawString8( xftdraw, &xftcolor, font, x, y, (XftChar8 *)text, strlen(text) );
#else
                  x = ( w - XTextWidth( font, text, strlen(text) ) ) / 2;
                  y = htext + ( h - htext + font->max_bounds.ascent - font->max_bounds.descent )/2;
                  XDrawString( dpy, mainW, gc, x, y, text, strlen(text) );
#endif           
                  force_expose = 0;
               }
               break;
            case ButtonPress:
               Done = 1;
               printf("good-bye!\n");
               break;
            default:
               break;
         }
      }
   }

   /* close connection to display */
#ifdef HAVE_XFT
   XftDrawDestroy( xftdraw );
   XftColorFree( dpy, DefaultVisual(dpy,DefaultScreen(dpy)),
               DefaultColormap( dpy, DefaultScreen(dpy) ), &xftcolor );
   XftColorFree( dpy, DefaultVisual(dpy,DefaultScreen(dpy)),
               DefaultColormap( dpy, DefaultScreen(dpy) ), &hlcolor );
#else
   XFreeGC( dpy, gc );
#endif
   XDestroyWindow( dpy, mainW );
   XCloseDisplay( dpy );
             
   return(0);
}



and the (GNU) Makefile that will built it.

Code:
SHELL = /bin/sh

CFLAGS = -O0 -g -Wall
CPPFLAGS = -I. -I/usr/X11R6/include -L/usr/X11R6/lib
XFTFLAGS = -DHAVE_XFT -I/usr/nekoware/include -I/usr/nekoware/include/freetype2 -I/usr/nekoware/include/X11 -L/usr/nekoware/lib -Wl,-rpath -Wl,/usr/nekoware/lib

# uncomment for Apple OS X
#XFTFLAGS = -DHAVE_XFT -I/usr/X11R6/include/X11 -I/usr/X11R6/include/freetype2

LDFLAGS =  -L.  -L..
LIBS = -lX11
XFTLIBS = -lXft
 
%.o: %.c
   $(CC) -c $(CFLAGS) $(CPPFLAGS) $(XM) -o $@ $<

.PHONY: all
all: xhello xfthello

xhello: $(OBJS) xhello.c
   $(CC) $(CFLAGS) $(CPPFLAGS) xhello.c -o xhello $(LDFLAGS) $(LIBS);   

xfthello: $(OBJS) xhello.c
   $(CC) $(CFLAGS) $(CPPFLAGS) $(XFTFLAGS) xhello.c -o xfthello  $(LDFLAGS) $(XFTLIBS) $(LIBS);   

.PHONY: clean 
clean:
   rm -f ./*.o; rm -f ./xhello ./xfthello;


Note: you have to uncomment one line if you want to build it on the Mac. Also, it builds two versions. The old X11 style fonts (xhello) and the new Xft anti-alised fonts (xfthello). Have a peek at the results.

Image

What am I going to do with this newly acquired knowledge?....Only time will let! :twisted:

Cheers!


Top
 Profile  
 
 Post subject:
Unread postPosted: Tue Jan 24, 2006 8:54 am 
Offline
User avatar

Joined: Tue Nov 01, 2005 11:35 am
Posts: 326
Location: california
Nice! Works under linux too :).

Back when I first started my djv project, I had a couple alpha versions just using raw xlib and freetype for fonts. Lot's of fun. For various reasons I ended up going with qt, but more than once have regretted that decision :).


Top
 Profile  
 
Unread postPosted: Mon Jan 09, 2012 4:11 am 
Offline
Moderator
Moderator
User avatar

Joined: Fri May 09, 2003 5:10 am
Posts: 2931
Location: Maryland, USA
I just googled my own post to try and remember how I did this. :)


Top
 Profile  
 
Unread postPosted: Mon Jan 09, 2012 10:55 am 
Offline
User avatar

Joined: Tue Jul 15, 2008 4:48 pm
Posts: 1887
Location: P.O. Box 121, Pymble, Sydney, NSW 2073, Australia.
Douglas A Young was an SGI employee who wrote a few books on Xt, Motif, etc programming, his code has always compiled on IRIX.

http://www.amazon.com/Douglas-A.-Young/ ... 187&sr=8-3

I have this book and the source code built on one of my machines here.. somewhere.

There is more example in IRIX itself in insight and those soft copy Oreilly books optional installs in IRIX 6.5... Volume 6B, etc...

You might want to change the file name to xhello.c or change the target and remember to put tabs not spaces before the $(CC) and rm lines...

R.

_________________
死の神はりんごだけ食べる

開いた括弧は必ず閉じる -- あるプログラマー

:Tezro: :Tezro: :Onyx2R: :Onyx2RE: :Onyx2: :O3x04R: :O3x0: :O200: :Octane: :Octane2: :O2: :O2: :Indigo2IMP: :PI: :PI: :1600SW: :1600SW: :Indy: :Indy: :Indy: :Indy: :Indy:
:hpserv: J5600, 2 x Mac, 3 x SUN, Alpha DS20E, Alpha 800 5/550, 3 x RS/6000, Amiga 4000 VideoToaster, Amiga4000 -030, 733MHz Sam440 AmigaOS 4.1 update 1.

Sold: :Indy: :Indy: :Indy: :Indigo: Tandem Himalaya S-Series Nonstop S72000 ServerNet.

@PymbleSoftware
Current Apps -> https://itunes.apple.com/au/artist/pymb ... d553990081
Cortex ---> http://www.facebook.com/pages/Cortex-th ... 11?sk=info
Minnie ---> http://www.facebook.com/pages/Minnie-th ... 02?sk=info
Github ---> https://github.com/pymblesoftware
Visit http://www.pymblesoftware.com
Search for "Pymble", "InstaElf", "CryWhy" or "Cricket Score Sheet" in the iPad App store or search for "Pymble" or "CryWhy" in the iPhone App store.


Top
 Profile  
 
Unread postPosted: Tue Jan 10, 2012 2:21 pm 
Offline
User avatar

Joined: Mon Nov 12, 2007 7:54 pm
Posts: 1283
Location: Berkeley, CA, USA, NA, Earth, Sol
squeen wrote:
I just googled my own post to try and remember how I did this. :)
Those are the times when I'm glad I try to capture/document things as I go. :D Or, all too often, they are the times I wail and lament that I'm not more consistent in capturing/documenting things as I go...

_________________
Then? :IRIS3130: ... Now? :O3x02L: :A3504L:- :A3502L: :1600SW:+MLA :Fuel: :Octane2: :Octane: :Indigo2IMP: ... Other: DEC :BA213: :BA123: Sun, DG AViiON, NeXT :Cube:


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC - 8 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group