Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37488373
en ru br
Репозитории ALT
S:2.3.7-alt1
5.1: 2.1.14-alt1
4.1: 2.1.13-alt0.M41.1
4.0: 2.1.12-alt2.M40.1
www.altlinux.org/Changes

Группа :: Система/Библиотеки
Пакет: libXft

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: libXft-2.1.14-alt1.patch
Скачать


 .gear/rules                                        |    2 +
 .../tags/a2b66ad582c78841c3a806b32e415fb8dbadc65b  |    6 +
 .gear/tags/list                                    |    1 +
 libXft.spec                                        |  114 ++++
 src/xftdpy.c                                       |   12 +
 src/xftfreetype.c                                  |   15 +
 src/xftglyphs.c                                    |  643 ++++++++++++--------
 src/xftint.h                                       |    1 +
 8 files changed, 537 insertions(+), 257 deletions(-)
diff --git a/.gear/rules b/.gear/rules
new file mode 100644
index 0000000..f78a96e
--- /dev/null
+++ b/.gear/rules
@@ -0,0 +1,2 @@
+tar: @name@-@version@:.
+diff: @name@-@version@:. .
diff --git a/.gear/tags/a2b66ad582c78841c3a806b32e415fb8dbadc65b b/.gear/tags/a2b66ad582c78841c3a806b32e415fb8dbadc65b
new file mode 100644
index 0000000..6cc82a0
--- /dev/null
+++ b/.gear/tags/a2b66ad582c78841c3a806b32e415fb8dbadc65b
@@ -0,0 +1,6 @@
+object fc248fb44413d11fed288793d0d8c2af76aeeb40
+type commit
+tag libXft-2.1.14
+tagger Alan Coopersmith <alan.coopersmith@sun.com> 1255131933 -0700
+
+libXft 2.1.14
diff --git a/.gear/tags/list b/.gear/tags/list
new file mode 100644
index 0000000..4143d65
--- /dev/null
+++ b/.gear/tags/list
@@ -0,0 +1 @@
+a2b66ad582c78841c3a806b32e415fb8dbadc65b libXft-2.1.14
diff --git a/libXft.spec b/libXft.spec
new file mode 100644
index 0000000..f9b3a1b
--- /dev/null
+++ b/libXft.spec
@@ -0,0 +1,114 @@
+Name: libXft
+Version: 2.1.14
+Release: alt1
+
+Summary: X FreeType Library
+License: MIT/X11
+Group: System/Libraries
+Url: http://xorg.freedesktop.org
+Packager: Valery Inozemtsev <shrek@altlinux.ru>
+
+Source: %name-%version.tar
+Patch: %name-%version-%release.patch
+
+BuildRequires: fontconfig-devel libXrender-devel libfreetype-devel xorg-util-macros
+
+%description
+X FreeType Library
+
+%package devel
+Summary: X FreeType Library and Header Files
+Group: Development/C
+Requires: %name = %version-%release
+Conflicts: XFree86-devel < 4.4 xorg-x11-devel <= 6.9.0
+
+%description devel
+%name-devel contains the libraries and header files needed to
+develop programs which make use of %name.
+
+%prep
+%setup -q
+%patch -p1
+
+%build
+%autoreconf
+%configure \
+	--disable-static
+%make_build
+
+%install
+%make DESTDIR=%buildroot install
+
+%files
+%_libdir/*.so.*
+
+%files devel
+%_bindir/*
+%_includedir/X11/Xft
+%_libdir/*.so
+%_pkgconfigdir/*.pc
+%_man1dir/*
+%_man3dir/*
+
+%changelog
+* Sat Oct 10 2009 Valery Inozemtsev <shrek@altlinux.ru> 2.1.14-alt1
+- 2.1.14
+
+* Sat Nov 22 2008 Valery Inozemtsev <shrek@altlinux.ru> 2.1.13-alt2
+- removed obsolete %%post_ldconfig/%%postun_ldconfig calls
+
+* Thu Jul 03 2008 Valery Inozemtsev <shrek@altlinux.ru> 2.1.13-alt1
+- 2.1.13
+
+* Mon May 05 2008 Valery Inozemtsev <shrek@altlinux.ru> 2.1.12-alt5
+- update lcd filter patch from ubuntu
+
+* Wed Apr 16 2008 Valery Inozemtsev <shrek@altlinux.ru> 2.1.12-alt4
+- reapply subpixel rendering patch
+
+* Sat Feb 02 2008 Valery Inozemtsev <shrek@altlinux.ru> 2.1.12-alt3
+- drop subpixel rendering patch
+
+* Wed Oct 30 2007 Valery Inozemtsev <shrek@altlinux.ru> 2.1.12-alt2
+- merged SuSE patches
+
+* Fri Dec 08 2006 Valery Inozemtsev <shrek@altlinux.ru> 2.1.12-alt1
+- 2.1.12:
+  + XftNameUnparse: re-export to public API
+
+* Sat Oct 14 2006 Valery Inozemtsev <shrek@altlinux.ru> 2.1.11-alt1
+- 2.1.11
+
+* Sun Sep 03 2006 Valery Inozemtsev <shrek@altlinux.ru> 2.1.10-alt1
+- 2.1.10
+
+* Mon Jul 17 2006 Valery Inozemtsev <shrek@altlinux.ru> 2.1.9-alt3
+- removed subpixel rendering patch
+
+* Thu Jul 13 2006 Valery Inozemtsev <shrek@altlinux.ru> 2.1.9-alt2
+- added libXft-2.1.9-git-coverity.patch
+
+* Sat Jun 03 2006 Valery Inozemtsev <shrek@altlinux.ru> 2.1.9-alt1
+- 2.1.9
+
+* Thu May 18 2006 Valery Inozemtsev <shrek@altlinux.ru> 2.1.8.2-alt5
+- added subpixel rendering patch
+
+* Wed Apr 26 2006 Valery Inozemtsev <shrek@altlinux.ru> 2.1.8.2-alt4
+- rebuild
+
+* Mon Jan 23 2006 Valery Inozemtsev <shrek@altlinux.ru> 2.1.8.2-alt3
+- added requires to %name-devel from buildrequires
+
+* Fri Jan 20 2006 Valery Inozemtsev <shrek@altlinux.ru> 2.1.8.2-alt2
+- fixed requires for %name-devel
+
+* Mon Dec 26 2005 Valery Inozemtsev <shrek@altlinux.ru> 2.1.8.2-alt1
+- Xorg-7.0
+
+* Sun Dec 04 2005 Valery Inozemtsev <shrek@altlinux.ru> 2.1.8.1-alt1
+- Xorg-7.0RC3
+
+* Mon Nov 21 2005 Valery Inozemtsev <shrek@altlinux.ru> 2.1.8-alt0.1
+- initial build
+
diff --git a/src/xftdpy.c b/src/xftdpy.c
index 0553515..64d3cb6 100644
--- a/src/xftdpy.c
+++ b/src/xftdpy.c
@@ -369,6 +369,10 @@ _XftDefaultInit (Display *dpy)
 	goto bail1;
     if (!_XftDefaultInitInteger (dpy, pat, FC_RGBA))
 	goto bail1;
+#ifdef FC_LCD_FILTER
+    if (!_XftDefaultInitInteger (dpy, pat, FC_LCD_FILTER))
+	goto bail1;
+#endif
     if (!_XftDefaultInitBool (dpy, pat, FC_ANTIALIAS))
 	goto bail1;
 #ifdef FC_EMBOLDEN
@@ -521,6 +525,14 @@ XftDefaultSubstitute (Display *dpy, int screen, FcPattern *pattern)
 			      XftDefaultGetInteger (dpy, FC_RGBA, screen, 
 						    subpixel));
     }
+#ifdef FC_LCD_FILTER
+    if (FcPatternGet (pattern, FC_LCD_FILTER, 0, &v) == FcResultNoMatch)
+    {
+	FcPatternAddInteger (pattern, FC_LCD_FILTER,
+			     XftDefaultGetInteger (dpy, FC_LCD_FILTER, screen,
+						   FC_LCD_DEFAULT));
+    }
+#endif
     if (FcPatternGet (pattern, FC_MINSPACE, 0, &v) == FcResultNoMatch)
     {
 	FcPatternAddBool (pattern, FC_MINSPACE,
diff --git a/src/xftfreetype.c b/src/xftfreetype.c
index 7238b82..d6cd875 100644
--- a/src/xftfreetype.c
+++ b/src/xftfreetype.c
@@ -469,6 +469,21 @@ XftFontInfoFill (Display *dpy, _Xconst FcPattern *pattern, XftFontInfo *fi)
 	goto bail1;
     }
     
+#ifdef FC_LCD_FILTER 
+    /*
+     * Get lcd_filter value
+     */
+    switch (FcPatternGetInteger (pattern, FC_LCD_FILTER, 0, &fi->lcd_filter)) {
+    case FcResultNoMatch:
+	fi->lcd_filter = FC_LCD_DEFAULT;
+	break;
+    case FcResultMatch:
+	break;
+    default:
+	goto bail1;
+    }
+#endif
+    
     /*
      * Get matrix and transform values
      */
diff --git a/src/xftglyphs.c b/src/xftglyphs.c
index 10adb15..c068b84 100644
--- a/src/xftglyphs.c
+++ b/src/xftglyphs.c
@@ -1,4 +1,6 @@
 /*
+ * $Id$
+ *
  * Copyright б╘ 2000 Keith Packard
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
@@ -21,27 +23,18 @@
  */
 
 #include "xftint.h"
-#include <freetype/ftoutln.h>
 
-#if HAVE_FT_GLYPHSLOT_EMBOLDEN
-#include <freetype/ftsynth.h>
+#if FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH < 20202
+#  error  "FreeType 2.2.2 or later required to compile this version of libXft"
 #endif
 
-static const int    filters[3][3] = {
-    /* red */
-#if 0
-{    65538*4/7,65538*2/7,65538*1/7 },
-    /* green */
-{    65536*1/4, 65536*2/4, 65537*1/4 },
-    /* blue */
-{    65538*1/7,65538*2/7,65538*4/7 },
+#include FT_OUTLINE_H
+#include FT_LCD_FILTER_H
+#include FT_SYNTHESIS_H
+
+#if HAVE_FT_GLYPHSLOT_EMBOLDEN
+#include <freetype/ftsynth.h>
 #endif
-{    65538*9/13,65538*3/13,65538*1/13 },
-    /* green */
-{    65538*1/6, 65538*4/6, 65538*1/6 },
-    /* blue */
-{    65538*1/13,65538*3/13,65538*9/13 },
-};
 
 /*
  * Validate the memory info for a font
@@ -69,6 +62,295 @@ _XftFontValidateMemory (Display *dpy, XftFont *public)
 		font->glyph_memory, glyph_memory);
 }
 
+
+/* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot
+ * into a different format. For example, we want to convert a
+ * FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit
+ * ARGB or ABGR bitmap.
+ *
+ * this function prepares a target descriptor for this operation.
+ *
+ * input :: target bitmap descriptor. The function will set its
+ *          'width', 'rows' and 'pitch' fields, and only these
+ *
+ * slot  :: the glyph slot containing the source bitmap. this
+ *          function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP
+ *
+ * mode  :: the requested final rendering mode. supported values are
+ *          MONO, NORMAL (i.e. gray), LCD and LCD_V
+ *
+ * the function returns the size in bytes of the corresponding buffer,
+ * it's up to the caller to allocate the corresponding memory block
+ * before calling _fill_xrender_bitmap
+ *
+ * it also returns -1 in case of error (e.g. incompatible arguments,
+ * like trying to convert a gray bitmap into a monochrome one)
+ */
+static int
+_compute_xrender_bitmap_size( FT_Bitmap*      target,
+                              FT_GlyphSlot    slot,
+                              FT_Render_Mode  mode )
+{
+    FT_Bitmap*  ftbit;
+    int         width, height, pitch;
+
+    if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
+        return -1;
+
+    // compute the size of the final bitmap
+    ftbit  = &slot->bitmap;
+
+    width  = ftbit->width;
+    height = ftbit->rows;
+    pitch  = (width+3) & ~3;
+
+    switch ( ftbit->pixel_mode )
+    {
+    case FT_PIXEL_MODE_MONO:
+        if ( mode == FT_RENDER_MODE_MONO )
+        {
+            pitch = (((width+31) & ~31) >> 3);
+            break;
+        }
+        /* fall-through */
+
+    case FT_PIXEL_MODE_GRAY:
+        if ( mode == FT_RENDER_MODE_LCD   ||
+             mode == FT_RENDER_MODE_LCD_V )
+        {
+          /* each pixel is replicated into a 32-bit ARGB value */
+          pitch = width*4;
+        }
+        break;
+
+    case FT_PIXEL_MODE_LCD:
+        if ( mode != FT_RENDER_MODE_LCD )
+            return -1;
+
+        /* horz pixel triplets are packed into 32-bit ARGB values */
+        width   /= 3;
+        pitch    = width*4;
+        break;
+
+    case FT_PIXEL_MODE_LCD_V:
+        if ( mode != FT_RENDER_MODE_LCD_V )
+            return -1;
+
+        /* vert pixel triplets are packed into 32-bit ARGB values */
+        height  /= 3;
+        pitch    = width*4;
+        break;
+
+    default:  /* unsupported source format */
+        return -1;
+    }
+
+    target->width  = width;
+    target->rows   = height;
+    target->pitch  = pitch;
+    target->buffer = NULL;
+
+    return pitch * height;
+}
+
+/* this functions converts the glyph bitmap found in a FT_GlyphSlot
+ * into a different format (see _compute_xrender_bitmap_size)
+ *
+ * you should call this function after _compute_xrender_bitmap_size
+ *
+ * target :: target bitmap descriptor. Note that its 'buffer' pointer
+ *           must point to memory allocated by the caller
+ *
+ * slot   :: the glyph slot containing the source bitmap
+ *
+ * mode   :: the requested final rendering mode
+ *
+ * bgr    :: boolean, set if BGR or VBGR pixel ordering is needed
+ */
+static void
+_fill_xrender_bitmap( FT_Bitmap*      target,
+                      FT_GlyphSlot    slot,
+                      FT_Render_Mode  mode,
+                      int             bgr )
+{
+    FT_Bitmap*   ftbit = &slot->bitmap;
+
+    {
+        unsigned char*   srcLine   = ftbit->buffer;
+        unsigned char*   dstLine   = target->buffer;
+        int              src_pitch = ftbit->pitch;
+        int              width     = target->width;
+        int              height    = target->rows;
+        int              pitch     = target->pitch;
+        int              subpixel;
+        int              h;
+
+        subpixel = ( mode == FT_RENDER_MODE_LCD ||
+                     mode == FT_RENDER_MODE_LCD_V );
+
+        if ( src_pitch < 0 )
+          srcLine -= src_pitch*(ftbit->rows-1);
+
+        switch ( ftbit->pixel_mode )
+        {
+        case FT_PIXEL_MODE_MONO:
+            if ( subpixel )  /* convert mono to ARGB32 values */
+            {
+                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+                {
+                    int  x;
+
+                    for ( x = 0; x < width; x++ )
+                    {
+                        if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
+                            ((unsigned int*)dstLine)[x] = 0xffffffffU;
+                    }
+                }
+            }
+            else if ( mode == FT_RENDER_MODE_NORMAL )  /* convert mono to 8-bit gray */
+            {
+                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+                {
+                    int  x;
+
+                    for ( x = 0; x < width; x++ )
+                    {
+                        if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
+                            dstLine[x] = 0xff;
+                    }
+                }
+            }
+            else  /* copy mono to mono */
+            {
+                int  bytes = (width+7) >> 3;
+
+                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+                    memcpy( dstLine, srcLine, bytes );
+            }
+            break;
+
+        case FT_PIXEL_MODE_GRAY:
+            if ( subpixel )  /* convert gray to ARGB32 values */
+            {
+                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+                {
+                    int            x;
+                    unsigned int*  dst = (unsigned int*)dstLine;
+
+                    for ( x = 0; x < width; x++ )
+                    {
+                        unsigned int  pix = srcLine[x];
+
+                        pix |= (pix << 8);
+                        pix |= (pix << 16);
+
+                        dst[x] = pix;
+                    }
+                }
+            }
+            else  /* copy gray into gray */
+            {
+                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+                    memcpy( dstLine, srcLine, width );
+            }
+            break;
+
+        case FT_PIXEL_MODE_LCD:
+            if ( !bgr )
+            {
+                /* convert horizontal RGB into ARGB32 */
+                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+                {
+                    int            x;
+                    unsigned char* src = srcLine;
+                    unsigned int*  dst = (unsigned int*)dstLine;
+
+                    for ( x = 0; x < width; x++, src += 3 )
+                    {
+                        unsigned int  pix;
+
+                        pix = ((unsigned int)src[0] << 16) |
+                              ((unsigned int)src[1] <<  8) |
+                              ((unsigned int)src[2]      ) |
+                              ((unsigned int)src[1] << 24) ;
+
+                        dst[x] = pix;
+                    }
+                }
+            }
+            else
+            {
+                /* convert horizontal BGR into ARGB32 */
+                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
+                {
+                    int            x;
+                    unsigned char* src = srcLine;
+                    unsigned int*  dst = (unsigned int*)dstLine;
+
+                    for ( x = 0; x < width; x++, src += 3 )
+                    {
+                        unsigned int  pix;
+
+                        pix = ((unsigned int)src[2] << 16) |
+                              ((unsigned int)src[1] <<  8) |
+                              ((unsigned int)src[0]      ) |
+                              ((unsigned int)src[1] << 24) ;
+
+                        dst[x] = pix;
+                    }
+                }
+            }
+            break;
+
+        default:  /* FT_PIXEL_MODE_LCD_V */
+            /* convert vertical RGB into ARGB32 */
+            if ( !bgr )
+            {
+                for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
+                {
+                    int            x;
+                    unsigned char* src = srcLine;
+                    unsigned int*  dst = (unsigned int*)dstLine;
+
+                    for ( x = 0; x < width; x++, src += 1 )
+                    {
+                        unsigned int  pix;
+
+                        pix = ((unsigned int)src[0]           << 16) |
+                              ((unsigned int)src[src_pitch]   <<  8) |
+                              ((unsigned int)src[src_pitch*2]      ) |
+                              ((unsigned int)src[src_pitch]   << 24) ;
+
+                        dst[x] = pix;
+                    }
+                }
+            }
+            else
+            {
+                for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
+                {
+                    int            x;
+                    unsigned char* src = srcLine;
+                    unsigned int*  dst = (unsigned int*)dstLine;
+
+                    for ( x = 0; x < width; x++, src += 1 )
+                    {
+                        unsigned int  pix;
+
+                        pix = ((unsigned int)src[src_pitch*2] << 16) |
+                              ((unsigned int)src[src_pitch]   <<  8) |
+                              ((unsigned int)src[0]                ) |
+                              ((unsigned int)src[src_pitch]   << 24) ;
+
+                        dst[x] = pix;
+                    }
+                }
+            }
+        }
+    }
+}
+
+
 _X_EXPORT void
 XftFontLoadGlyphs (Display	    *dpy,
 		   XftFont	    *pub,
@@ -87,20 +369,14 @@ XftFontLoadGlyphs (Display	    *dpy,
     unsigned char   *bufBitmap = bufLocal;
     int		    bufSize = sizeof (bufLocal);
     int		    size, pitch;
-    unsigned char   bufLocalRgba[4096];
-    unsigned char   *bufBitmapRgba = bufLocalRgba;
-    int		    bufSizeRgba = sizeof (bufLocalRgba);
-    int		    sizergba, pitchrgba, widthrgba;
     int		    width;
     int		    height;
     int		    left, right, top, bottom;
-    int		    hmul = 1;
-    int		    vmul = 1;
-    FT_Bitmap	    ftbit;
-    FT_Matrix	    matrix;
+    FT_Bitmap*	    ftbit;
+    FT_Bitmap       local;
     FT_Vector	    vector;
-    Bool	    subpixel = False;
     FT_Face	    face;
+    FT_Render_Mode  mode = FT_RENDER_MODE_MONO;
 
     if (!info)
 	return;
@@ -110,24 +386,19 @@ XftFontLoadGlyphs (Display	    *dpy,
     if (!face)
 	return;
 
-    matrix.xx = matrix.yy = 0x10000L;
-    matrix.xy = matrix.yx = 0;
-
     if (font->info.antialias)
     {
 	switch (font->info.rgba) {
 	case FC_RGBA_RGB:
 	case FC_RGBA_BGR:
-	    matrix.xx *= 3;
-	    subpixel = True;
-	    hmul = 3;
+	    mode = FT_RENDER_MODE_LCD;
 	    break;
 	case FC_RGBA_VRGB:
 	case FC_RGBA_VBGR:
-	    matrix.yy *= 3;
-	    vmul = 3;
-	    subpixel = True;
+            mode = FT_RENDER_MODE_LCD_V;
 	    break;
+        default:
+            mode = FT_RENDER_MODE_NORMAL;
 	}
     }
 
@@ -148,7 +419,10 @@ XftFontLoadGlyphs (Display	    *dpy,
 	if (xftg->glyph_memory)
 	    continue;
 	
+        FT_Library_SetLcdFilter( _XftFTlibrary, font->info.lcd_filter);
+
 	error = FT_Load_Glyph (face, glyphindex, font->info.load_flags);
+
 	if (error)
 	{
 	    /*
@@ -181,7 +455,7 @@ XftFontLoadGlyphs (Display	    *dpy,
 	/*
 	 * Compute glyph metrics from FreeType information
 	 */
-	if(font->info.transform && glyphslot->format != ft_glyph_format_bitmap) 
+	if(font->info.transform && glyphslot->format != FT_GLYPH_FORMAT_BITMAP)
 	{
 	    /*
 	     * calculate the true width by transforming all four corners.
@@ -260,17 +534,14 @@ XftFontLoadGlyphs (Display	    *dpy,
 	    }
 	}
 
-	if (font->info.antialias)
-	    pitch = (width * hmul + 3) & ~3;
-	else
-	    pitch = ((width + 31) & ~31) >> 3;
-
-	size = pitch * height * vmul;
+        if ( glyphslot->format != FT_GLYPH_FORMAT_BITMAP )
+        {
+            error = FT_Render_Glyph( face->glyph, mode );
+            if (error)
+                continue;
+        }
 
-	xftg->metrics.width = width;
-	xftg->metrics.height = height;
-	xftg->metrics.x = -TRUNC(left);
-	xftg->metrics.y = TRUNC(top);
+        FT_Library_SetLcdFilter( _XftFTlibrary, FT_LCD_FILTER_NONE );
 
 	if (font->info.spacing >= FC_MONO)
 	{
@@ -310,103 +581,13 @@ XftFontLoadGlyphs (Display	    *dpy,
 	    xftg->metrics.yOff = -TRUNC(ROUND(glyphslot->advance.y));
 	}
 	
-	/*
-	 * If the glyph is relatively large (> 1% of server memory),
-	 * don't send it until necessary
-	 */
-	if (!need_bitmaps && size > info->max_glyph_memory / 100)
-	    continue;
 	
-	/*
-	 * Make sure there's enough buffer space for the glyph
-	 */
-	if (size > bufSize)
-	{
-	    if (bufBitmap != bufLocal)
-		free (bufBitmap);
-	    bufBitmap = (unsigned char *) malloc (size);
-	    if (!bufBitmap)
-		continue;
-	    bufSize = size;
-	}
-	memset (bufBitmap, 0, size);
-
-	/*
-	 * Rasterize into the local buffer
-	 */
-	switch (glyphslot->format) {
-	case ft_glyph_format_outline:
-	    ftbit.width      = width * hmul;
-	    ftbit.rows       = height * vmul;
-	    ftbit.pitch      = pitch;
-	    if (font->info.antialias)
-		ftbit.pixel_mode = ft_pixel_mode_grays;
-	    else
-		ftbit.pixel_mode = ft_pixel_mode_mono;
-	    
-	    ftbit.buffer     = bufBitmap;
-	    
-	    if (subpixel)
-		FT_Outline_Transform (&glyphslot->outline, &matrix);
+        // compute the size of the final bitmap
+        ftbit  = &glyphslot->bitmap;
 
-	    FT_Outline_Translate ( &glyphslot->outline, -left*hmul, -bottom*vmul );
-
-	    FT_Outline_Get_Bitmap( _XftFTlibrary, &glyphslot->outline, &ftbit );
-	    break;
-	case ft_glyph_format_bitmap:
-	    if (font->info.antialias)
-	    {
-		unsigned char	*srcLine, *dstLine;
-		int		height;
-		int		x;
-		int	    h, v;
-
-		srcLine = glyphslot->bitmap.buffer;
-		dstLine = bufBitmap;
-		height = glyphslot->bitmap.rows;
-		while (height--)
-		{
-		    for (x = 0; x < glyphslot->bitmap.width; x++)
-		    {
-			/* always MSB bitmaps */
-			unsigned char	a = ((srcLine[x >> 3] & (0x80 >> (x & 7))) ?
-					     0xff : 0x00);
-			if (subpixel)
-			{
-			    for (v = 0; v < vmul; v++)
-				for (h = 0; h < hmul; h++)
-				    dstLine[v * pitch + x*hmul + h] = a;
-			}
-			else
-			    dstLine[x] = a;
-		    }
-		    dstLine += pitch * vmul;
-		    srcLine += glyphslot->bitmap.pitch;
-		}
-	    }
-	    else
-	    {
-		unsigned char	*srcLine, *dstLine;
-		int		h, bytes;
-
-		srcLine = glyphslot->bitmap.buffer;
-		dstLine = bufBitmap;
-		h = glyphslot->bitmap.rows;
-		bytes = (glyphslot->bitmap.width + 7) >> 3;
-		while (h--)
-		{
-		    memcpy (dstLine, srcLine, bytes);
-		    dstLine += pitch;
-		    srcLine += glyphslot->bitmap.pitch;
-		}
-	    }
-	    break;
-	default:
-	    if (XftDebug() & XFT_DBG_GLYPH)
-		printf ("glyph %d is not in a usable format\n",
-			(int) glyphindex);
-	    continue;
-	}
+        width  = ftbit->width;
+        height = ftbit->rows;
+        pitch  = (width+3) & ~3;
 	
 	if (XftDebug() & XFT_DBG_GLYPH)
 	{
@@ -423,29 +604,72 @@ XftFontLoadGlyphs (Display	    *dpy,
 		int		x, y;
 		unsigned char	*line;
 
-		line = bufBitmap;
-		for (y = 0; y < height * vmul; y++)
+                line = ftbit->buffer;
+
+                if (ftbit->pitch < 0)
+                  line -= ftbit->pitch*(height-1);
+
+                for (y = 0; y < height; y++)
 		{
 		    if (font->info.antialias) 
 		    {
-			static char    den[] = { " .:;=+*#" };
-			for (x = 0; x < pitch; x++)
+                        static const char    den[] = { " .:;=+*#" };
+                        for (x = 0; x < width; x++)
 			    printf ("%c", den[line[x] >> 5]);
 		    }
 		    else
 		    {
-			for (x = 0; x < pitch * 8; x++)
+                        for (x = 0; x < width * 8; x++)
 			{
 			    printf ("%c", line[x>>3] & (1 << (x & 7)) ? '#' : ' ');
 			}
 		    }
 		    printf ("|\n");
-		    line += pitch;
+                    line += ftbit->pitch;
 		}
 		printf ("\n");
 	    }
 	}
 
+        size = _compute_xrender_bitmap_size( &local, glyphslot, mode );
+        if ( size < 0 )
+            continue;
+
+        xftg->metrics.width  = local.width;
+	xftg->metrics.height = local.rows;
+	xftg->metrics.x      = - glyphslot->bitmap_left;
+	xftg->metrics.y      =   glyphslot->bitmap_top;
+	    
+	    /*
+	 * If the glyph is relatively large (> 1% of server memory),
+	 * don't send it until necessary
+	     */
+	if (!need_bitmaps && size > info->max_glyph_memory / 100)
+	    continue;
+
+	/*
+	 * Make sure there's enough buffer space for the glyph
+	 */
+	if (size > bufSize)
+	    {
+	    if (bufBitmap != bufLocal)
+		free (bufBitmap);
+	    bufBitmap = (unsigned char *) malloc (size);
+	    if (!bufBitmap)
+		    continue;
+	    bufSize = size;
+	    }
+	memset (bufBitmap, 0, size);
+
+        local.buffer = bufBitmap;
+	    
+        _fill_xrender_bitmap( &local, glyphslot, mode,
+                              (font->info.rgba == FC_RGBA_BGR  ||
+                               font->info.rgba == FC_RGBA_VBGR ) );
+	/*
+	 * Copy or convert into local buffer
+	 */
+
 	/*
 	 * Use the glyph index as the wire encoding; it
 	 * might be more efficient for some locales to map
@@ -455,121 +679,24 @@ XftFontLoadGlyphs (Display	    *dpy,
 	 */
 	glyph = (Glyph) glyphindex;
 
-	if (subpixel)
-	{
-	    int		    x, y;
-	    unsigned char   *in_line, *out_line, *in;
-	    unsigned int    *out;
-	    unsigned int    red, green, blue;
-	    int		    rf, gf, bf;
-	    int		    s;
-	    int		    o, os;
-	    
-	    /*
-	     * Filter the glyph to soften the color fringes
-	     */
-	    widthrgba = width;
-	    pitchrgba = (widthrgba * 4 + 3) & ~3;
-	    sizergba = pitchrgba * height;
-
-	    os = 1;
-	    switch (font->info.rgba) {
-	    case FC_RGBA_VRGB:
-		os = pitch;
-	    case FC_RGBA_RGB:
-	    default:
-		rf = 0;
-		gf = 1;
-		bf = 2;
-		break;
-	    case FC_RGBA_VBGR:
-		os = pitch;
-	    case FC_RGBA_BGR:
-		bf = 0;
-		gf = 1;
-		rf = 2;
-		break;
-	    }
-	    if (sizergba > bufSizeRgba)
-	    {
-		if (bufBitmapRgba != bufLocalRgba)
-		    free (bufBitmapRgba);
-		bufBitmapRgba = (unsigned char *) malloc (sizergba);
-		if (!bufBitmapRgba)
-		    continue;
-		bufSizeRgba = sizergba;
-	    }
-	    memset (bufBitmapRgba, 0, sizergba);
-	    in_line = bufBitmap;
-	    out_line = bufBitmapRgba;
-	    for (y = 0; y < height; y++)
-	    {
-		in = in_line;
-		out = (unsigned int *) out_line;
-		in_line += pitch * vmul;
-		out_line += pitchrgba;
-		for (x = 0; x < width * hmul; x += hmul)
-		{
-		    red = green = blue = 0;
-		    o = 0;
-		    for (s = 0; s < 3; s++)
-		    {
-			red += filters[rf][s]*in[x+o];
-			green += filters[gf][s]*in[x+o];
-			blue += filters[bf][s]*in[x+o];
-			o += os;
-		    }
-		    red = red / 65536;
-		    green = green / 65536;
-		    blue = blue / 65536;
-		    *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
-		}
-	    }
-	    
-	    xftg->glyph_memory = sizergba + sizeof (XftGlyph);
+        xftg->glyph_memory = size + sizeof (XftGlyph);
 	    if (font->format)
 	    {
 		if (!font->glyphset)
 		    font->glyphset = XRenderCreateGlyphSet (dpy, font->format);
-		if (ImageByteOrder (dpy) != XftNativeByteOrder ())
-		    XftSwapCARD32 ((CARD32 *) bufBitmapRgba, sizergba >> 2);
-		XRenderAddGlyphs (dpy, font->glyphset, &glyph,
-				  &xftg->metrics, 1, 
-				  (char *) bufBitmapRgba, sizergba);
-	    }
-	    else
-	    {
-		if (sizergba)
-		{
-		    xftg->bitmap = malloc (sizergba);
-		    if (xftg->bitmap)
-			memcpy (xftg->bitmap, bufBitmapRgba, sizergba);
-		}
-		else
-		    xftg->bitmap = NULL;
-	    }
-	}
-	else
-	{
-	    xftg->glyph_memory = size + sizeof (XftGlyph);
-	    if (font->format)
-	    {
-		/*
-		 * swap bit order around; FreeType is always MSBFirst
-		 */
-		if (!font->info.antialias)
+
+            if ( mode == FT_RENDER_MODE_MONO )
 		{
+                /* swap bits in each byte */
 		    if (BitmapBitOrder (dpy) != MSBFirst)
 		    {
-			unsigned char   *line;
-			unsigned char   c;
-			int		    i;
+                    unsigned char   *line = (unsigned char*)bufBitmap;
+                    int             i = size;
 
-			line = (unsigned char *) bufBitmap;
-			i = size;
 			while (i--)
 			{
-			    c = *line;
+                        int  c = *line;
+
 			    c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
 			    c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
 			    c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
@@ -577,8 +704,12 @@ XftFontLoadGlyphs (Display	    *dpy,
 			}
 		    }
 		}
-		if (!font->glyphset)
-		    font->glyphset = XRenderCreateGlyphSet (dpy, font->format);
+            else if ( mode != FT_RENDER_MODE_NORMAL )
+            {
+                /* invert ARGB <=> BGRA */
+                if (ImageByteOrder (dpy) != XftNativeByteOrder ())
+                    XftSwapCARD32 ((CARD32 *) bufBitmap, size >> 2);
+            }
 		XRenderAddGlyphs (dpy, font->glyphset, &glyph,
 				  &xftg->metrics, 1, 
 				  (char *) bufBitmap, size);
@@ -594,7 +725,7 @@ XftFontLoadGlyphs (Display	    *dpy,
 		else
 		    xftg->bitmap = NULL;
 	    }
-	}
+
 	font->glyph_memory += xftg->glyph_memory;
 	info->glyph_memory += xftg->glyph_memory;
 	if (XftDebug() & XFT_DBG_CACHE)
@@ -605,8 +736,6 @@ XftFontLoadGlyphs (Display	    *dpy,
     }
     if (bufBitmap != bufLocal)
 	free (bufBitmap);
-    if (bufBitmapRgba != bufLocalRgba)
-	free (bufBitmapRgba);
     XftUnlockFace (&font->public);
 }
 
diff --git a/src/xftint.h b/src/xftint.h
index 3aafecf..a6d6db7 100644
--- a/src/xftint.h
+++ b/src/xftint.h
@@ -145,6 +145,7 @@ struct _XftFontInfo {
     FcBool		antialias;	/* doing antialiasing */
     FcBool		embolden;	/* force emboldening */
     int			rgba;		/* subpixel order */
+    int			lcd_filter;	/* lcd filter */
     FT_Matrix		matrix;		/* glyph transformation matrix */
     FcBool		transform;	/* non-identify matrix? */
     FT_Int		load_flags;	/* glyph load flags */
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin