Dimitri Shlyakhtenko <[EMAIL PROTECTED]> writes:

| Hello all,
| 
| The patch below is a hack allowing lyx to use anti-aliased fonts (via
| libXft and the render extension in recent versions of XFree86).  The
| patch is against lyx-1.1.6fix2.
| 
| I am fully aware of the fact that this patch is not an elegant solution
| at all, and that one should (in principle) modify LyX's internal font
| handling to allocate and use XftFonts.  Unfortunately, I lack the
| knowledge for such an undertaking...  As a result, the enclosed solution
| is much less elegant and slower than it should be.  On the other hand, I
| used these modifications for a little while now, and am quite happy with
| the new fonts in LyX.  I hope it works for you!
| 
| Please look in the file README.render for more information on what I
| changed.

Ok, interesting. (but you diff do many files...)

You coding style is a bit too "C-like" for my taste.

- Use c++ style casts
- use bool
- use preincrement.

Also I belive that what you do could be better integrated into lyx,
I also thing the caches would benefit from stl.

| --- lyx-1.1.6fix2/config/lyxinclude.m4        Mon Mar  5 06:02:49 2001
| +++ lyx-1.1.6fix2-antialias/config/lyxinclude.m4      Sun Jul 15 08:51:49 2001
| @@ -556,6 +556,20 @@
|      fi
|  ])
|  
| +dnl Usage LYX_PATH_XFT: Checks for Xft library and header
| +AC_DEFUN(LYX_PATH_XFT,[
| +### Check for Xft library
| +AC_CHECK_LIB(Xft, XftDrawString8, LYX_LIBS="-lXft $LYX_LIBS",
| +        true, $LYX_LIBS)
| +
| +### Check for Xft headers
| +lyx_cv_xft_h_location="<Xft/Xft.h>"
| +AC_CHECK_HEADER(X11/Xft/Xft.h,[
| +   ac_cv_header_xft_h=yes
| +   lyx_cv_xft_h_location="<X11/Xft/Xft.h>"],[])
| + AC_DEFINE_UNQUOTED(XFT_H_LOCATION, $lyx_cv_xft_h_location)
| +])
| +
|  dnl Usage LYX_PATH_XPM: Checks for xpm library and header
|  AC_DEFUN(LYX_PATH_XPM,[

ok...

| diff -Pur lyx-1.1.6fix2/src/FontLoader.h lyx-1.1.6fix2-antialias/src/FontLoader.h
| --- lyx-1.1.6fix2/src/FontLoader.h    Mon Aug  7 13:58:21 2000
| +++ lyx-1.1.6fix2-antialias/src/FontLoader.h  Sun Jul 15 08:52:21 2001
| @@ -49,23 +49,23 @@
|               else
|                       return doLoad(family, series, shape, size);
|       };
| +     /// Array of font infos
| +     FontInfo * fontinfo[4][2][4];
| +
| +
| +     /// Get font info
| +     void getFontinfo(LyXFont::FONT_FAMILY family, 
| +                      LyXFont::FONT_SERIES series, 
| +                      LyXFont::FONT_SHAPE shape);
|  private:
|       /// Array of font structs
|       XFontStruct * fontstruct[4][2][4][10];
|  
| -     /// Array of font infos
| -     FontInfo * fontinfo[4][2][4];
| -
|       /// Reset font handler
|       void reset();
|  
|       /// Unload all fonts
|       void unload();
| -
| -     /// Get font info
| -     void getFontinfo(LyXFont::FONT_FAMILY family, 
| -                      LyXFont::FONT_SERIES series, 
| -                      LyXFont::FONT_SHAPE shape);
|  
|       /** Does the actual loading of a font. Updates fontstruct. */
|       XFontStruct * doLoad(LyXFont::FONT_FAMILY family, 

I wonder if this change is really needed.

| +}
| +
| +typedef struct _cache_entry {
| +  Colormap c;
| +  Drawable w;
| +  GC gc;
| +  string colorName;
| +
| +  XftDraw *draw;
| +  XftColor color;
| +} cache_entry;

This is C and not C++

struct cache_entry {
..
};

is better in C++.

| +#define MAXCACHE 90

int const MAXCACHE = 90;

| +PainterBase & Painter::XDrawString(Display *d, Drawable w, GC gc, int x,
| +               int y, char * const s, int sl, LyXFont const &f) {
| +#ifdef XFT_H_LOCATION
| +   
| +   static cache_entry cache[MAXCACHE+1];

a std::vector<cache_entry> cache;

| +   static int to_replace = 0;
| +   unsigned long foreground;
| +   XftFont *xftfont;
| +
| +   Visual *visual = XDefaultVisual(d, fl_screen);
| +   Colormap colormap = fl_state[fl_get_vclass()].colormap;
| +
| +   int i;
| +   int found = 0;

bool found = false;

| +   string str = lcolor.getX11Name(f.realColor());
| +   
| +
| +   for (i = 0; i < MAXCACHE && ! found && cache[i].draw; i++)  
| +      if (cache[i].c == colormap && cache[i].w == w &&
| +          cache[i].gc == gc && 
| +          cache[i].colorName == str)  found = 1;
| +   if (found) i--;

 --i;

| +   if (!found || ! cache[i].draw ) { 
| +      if (! cache[i].draw && i < MAXCACHE ) to_replace = i; 
| +      i = to_replace % MAXCACHE; to_replace++;
| +      cache[i].gc = gc;
| +      cache[i].c = colormap;
| +       cache[i].w = w;
| +      cache[i].colorName = str;

Could actually store this in a kind of "priority map" so that often
used items float to the beginning of the container.

| +      
| +      XftColorAllocName(d, visual, colormap, (char *)cache[i].colorName.c_str(),
| +          &(cache[i].color) );

static_cast<char*>(...) or more likely const_cast<char*>(..)

| +      cache[i].draw = XftDrawCreate(d, w, visual, colormap);
| +
| +
| + //     lyxerr << "Inserting into cache" << i << " " << str.c_str() << "\n";
| +   }
| +
| +   int fsize = int( (lyxrc.font_sizes[f.size()] * lyxrc.dpi *
| +                          (lyxrc.zoom/100.0) ) / 72.27 + 0.5 );
| +
| +   string font = fontloader.fontinfo[f.family()][f.series()][f.realShape()]->
| +         getFontname(fsize); 
| +      
| +//   lyxerr << font.c_str() << " " << fsize << "\n";
| +
| +   xftfont = getMatchingXftFont(d, fl_screen, font.c_str());
| +
| +   if (!xftfont) {
| +          lyxerr <<"Error: null font\n"  << i <<"\n";
| +          return *this;
| +   }
| +
| +   XftDrawString8(cache[i].draw, &(cache[i].color), 
| +                  xftfont, x, y, (XftChar8 *) s, sl);
| +#else
| +   return XDrawString(d, w, gc, x, y, s, sl);
| +#endif
|  }
|  
|  
| diff -Pur lyx-1.1.6fix2/src/Painter.h lyx-1.1.6fix2-antialias/src/Painter.h
| --- lyx-1.1.6fix2/src/Painter.h       Wed Nov 15 10:02:44 2000
| +++ lyx-1.1.6fix2-antialias/src/Painter.h     Sun Jul 15 08:53:01 2001
| @@ -100,6 +100,9 @@
|  private:
|       /// Check the font, and if set, draw an underline
|       void underline(LyXFont const & f, int x, int y, int width);
| +
| +        PainterBase & Painter::XDrawString(Display *d, Drawable w, GC gc, int x,
| +                  int y, char *  const s, int sl, LyXFont const &f);
|       
|       ///
|       Display * display;
| diff -Pur lyx-1.1.6fix2/src/config.h.in lyx-1.1.6fix2-antialias/src/config.h.in
| --- lyx-1.1.6fix2/src/config.h.in     Sun Jul 15 09:04:17 2001
| +++ lyx-1.1.6fix2-antialias/src/config.h.in   Sun Jul 15 09:04:15 2001
| @@ -135,6 +135,10 @@
|  #undef HAVE_STPCPY
|  
|  /* define this to the location of xpm.h to be used with #include,
| +  e.g. <xft.h> */
| +#undef XFT_H_LOCATION
| +
| +/* define this to the location of xpm.h to be used with #include,
|    e.g. <xpm.h> */
|  #undef XPM_H_LOCATION
|  
| diff -Pur lyx-1.1.6fix2/src/font.C lyx-1.1.6fix2-antialias/src/font.C
| --- lyx-1.1.6fix2/src/font.C  Mon Oct 30 13:53:28 2000
| +++ lyx-1.1.6fix2-antialias/src/font.C        Sun Jul 15 08:52:14 2001
| @@ -18,8 +18,12 @@
|  
|  #include "font.h"
|  #include "FontLoader.h"
| +#include "FontInfo.h"
|  #include "lyxrc.h"
|  #include "encoding.h"
| +#ifdef XFT_H_LOCATION
| +#include "xftfont.h"
| +#endif
|  
|  // namespace {
|  static inline
| @@ -131,7 +135,7 @@
|       }
|  
|       if (f.realShape() != LyXFont::SMALLCAPS_SHAPE) {
| -             return ::XTextWidth(getXFontstruct(f), s, n);
| +             return XTextWidth((f), s, n);
|       } else {
|               // emulate smallcaps since X doesn't support this
|               unsigned int result = 0;
| @@ -143,9 +147,9 @@
|                       // when islower is a macro, the cast is needed (JMarc)
|                       if (islower(static_cast<unsigned char>(c))) {
|                               c = toupper(c);
| -                             result += ::XTextWidth(getXFontstruct(smallfont), &c, 
|1);
| +                             result += XTextWidth((smallfont), &c, 1);
|                       } else {
| -                             result += ::XTextWidth(getXFontstruct(f), &c, 1);
| +                             result += XTextWidth((f), &c, 1);
|                       }
|               }
|               return result;
| @@ -189,9 +193,26 @@
|       }
|  }
|  
| -int lyxfont::XTextWidth(LyXFont const & f, char const * str, int count)
| -{
| -     return ::XTextWidth(getXFontstruct(f), str, count);
| +int lyxfont::XTextWidth(LyXFont const & f, char const * str, int count) {
| +
| +   int fsize = int( (lyxrc.font_sizes[f.size()] * lyxrc.dpi *
| +                          (lyxrc.zoom/100.0) ) / 72.27 + 0.5 );
| +
| +   fontloader.load(f.family(), f.series(), f.realShape(), f.size());
| +   string font = fontloader.fontinfo[f.family()][f.series()][f.realShape()]->
| +         getFontname(fsize);   
| +
| +#ifdef XFT_H_LOCATION
| +   XftFont * xftfont = getMatchingXftFont(fl_display, fl_screen, font.c_str());
| +
| +   XGlyphInfo extents;
| +
| +   XftTextExtents8(fl_display, xftfont, (XftChar8*) str, count, &extents);
| +
| +   return extents.xOff;
| +#else
| +   return ::XTextWidth(getXFontstruct(f), str, count);
| +#endif
|  }


| diff -Pur lyx-1.1.6fix2/src/xftfont.C lyx-1.1.6fix2-antialias/src/xftfont.C
| --- lyx-1.1.6fix2/src/xftfont.C       Wed Dec 31 16:00:00 1969
| +++ lyx-1.1.6fix2-antialias/src/xftfont.C     Sun Jul 15 08:52:26 2001
| @@ -0,0 +1,49 @@
| +#include <config.h>
| +#include <xftfont.h>
| +
| +#ifdef XFT_H_LOCATION
| +
| +typedef struct {
| +  char fontname[256];

string fontname;

| +  XftFont *xftfont;
| +} fontCacheEntry;
| +
| +#define MAXCACHE 50
| +
| +XftFont * getMatchingXftFont (Display *d, int s, const char
| +*fontname) {

use string.

| +
| +  static fontCacheEntry cache[MAXCACHE+1];
| +  static int to_replace = 0;
| +  static int initialized = 0;
| +  int i;
| +  int found = 0;

bool found = false;

| +
| +  if (! initialized ) {
| +     for (i = 0; i < MAXCACHE; i++) cache[i].xftfont = NULL;
| +     initialized = 1;
| +  }
| +
| +  i = 0;
| +  while (i < MAXCACHE && !found && cache[i].xftfont) {
| +     if ( 0 == strcmp(cache[i].fontname, fontname) ) found =1;

if (cache[i].fontname == fontname) found = true;
| +     i++;

++i;

| +  }

Here a std::map could be used. Would give O(log n) lookup.
| +
| +  if (found) i--;
| +
| +  if (! found || ! cache[i].xftfont ) {
| +    if (! cache[i].xftfont && (i < MAXCACHE) ) 
| +       to_replace = i; 
| +    else  
| +       XftFontClose(d, cache[i].xftfont);
| +    i = to_replace %MAXCACHE; to_replace ++;
| +
| +    cache[i].xftfont = XftFontOpenXlfd(d, s, fontname);
| +    strcpy(cache[i].fontname, fontname);
| +  }
| +
| +/*   printf("Requested %s\n   returning no. %d (%x), hit = %d\n", fontname, 
| +         i, cache[i].xftfont, found); */
| +  return cache[i].xftfont;
| +}
| +#endif
| diff -Pur lyx-1.1.6fix2/src/xftfont.h lyx-1.1.6fix2-antialias/src/xftfont.h
| --- lyx-1.1.6fix2/src/xftfont.h       Wed Dec 31 16:00:00 1969
| +++ lyx-1.1.6fix2-antialias/src/xftfont.h     Sun Jul 15 08:52:26 2001
| @@ -0,0 +1,8 @@
| +#ifdef XFT_H_LOCATION
| +#include "font.h"
| +
| +#include <config.h>
| +#include XFT_H_LOCATION
| +
| +XftFont * getMatchingXftFont (Display *d, int s, const char *fontname) ;
| +#endif

but I like it... it is simple... it just need to get C++ified and
LyXified.

-- 
        Lgb

Reply via email to