Git init
[framework/uifw/xorg/lib/libxft.git] / debian / patches / 100-libXft-2.1.10-lcd-filter-3.patch
1 --- a/src/xftdpy.c
2 +++ b/src/xftdpy.c
3 @@ -369,6 +369,10 @@
4         goto bail1;
5      if (!_XftDefaultInitInteger (dpy, pat, FC_RGBA))
6         goto bail1;
7 +#ifdef FC_LCD_FILTER
8 +    if (!_XftDefaultInitInteger (dpy, pat, FC_LCD_FILTER))
9 +       goto bail1;
10 +#endif
11      if (!_XftDefaultInitBool (dpy, pat, FC_ANTIALIAS))
12         goto bail1;
13  #ifdef FC_EMBOLDEN
14 @@ -521,6 +525,14 @@
15                               XftDefaultGetInteger (dpy, FC_RGBA, screen, 
16                                                     subpixel));
17      }
18 +#ifdef FC_LCD_FILTER
19 +    if (FcPatternGet (pattern, FC_LCD_FILTER, 0, &v) == FcResultNoMatch)
20 +    {
21 +       FcPatternAddInteger (pattern, FC_LCD_FILTER,
22 +                            XftDefaultGetInteger (dpy, FC_LCD_FILTER, screen,
23 +                                                  FC_LCD_DEFAULT));
24 +    }
25 +#endif
26      if (FcPatternGet (pattern, FC_MINSPACE, 0, &v) == FcResultNoMatch)
27      {
28         FcPatternAddBool (pattern, FC_MINSPACE,
29 --- a/src/xftfreetype.c
30 +++ b/src/xftfreetype.c
31 @@ -469,6 +469,21 @@
32         goto bail1;
33      }
34      
35 +#ifdef FC_LCD_FILTER 
36 +    /*
37 +     * Get lcd_filter value
38 +     */
39 +    switch (FcPatternGetInteger (pattern, FC_LCD_FILTER, 0, &fi->lcd_filter)) {
40 +    case FcResultNoMatch:
41 +       fi->lcd_filter = FC_LCD_DEFAULT;
42 +       break;
43 +    case FcResultMatch:
44 +       break;
45 +    default:
46 +       goto bail1;
47 +    }
48 +#endif
49 +    
50      /*
51       * Get matrix and transform values
52       */
53 --- a/src/xftglyphs.c
54 +++ b/src/xftglyphs.c
55 @@ -21,27 +21,18 @@
56   */
57  
58  #include "xftint.h"
59 -#include <freetype/ftoutln.h>
60  
61  #if HAVE_FT_GLYPHSLOT_EMBOLDEN
62  #include <freetype/ftsynth.h>
63  #endif
64  
65 -static const int    filters[3][3] = {
66 -    /* red */
67 -#if 0
68 -{    65538*4/7,65538*2/7,65538*1/7 },
69 -    /* green */
70 -{    65536*1/4, 65536*2/4, 65537*1/4 },
71 -    /* blue */
72 -{    65538*1/7,65538*2/7,65538*4/7 },
73 +#if FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH < 20202
74 +#  error  "FreeType 2.2.2 or later required to compile this version of libXft"
75  #endif
76 -{    65538*9/13,65538*3/13,65538*1/13 },
77 -    /* green */
78 -{    65538*1/6, 65538*4/6, 65538*1/6 },
79 -    /* blue */
80 -{    65538*1/13,65538*3/13,65538*9/13 },
81 -};
82 +
83 +#include FT_OUTLINE_H
84 +#include FT_LCD_FILTER_H
85 +#include FT_SYNTHESIS_H
86  
87  /*
88   * Validate the memory info for a font
89 @@ -69,6 +60,295 @@
90                 font->glyph_memory, glyph_memory);
91  }
92  
93 +
94 +/* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot
95 + * into a different format. For example, we want to convert a
96 + * FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit
97 + * ARGB or ABGR bitmap.
98 + *
99 + * this function prepares a target descriptor for this operation.
100 + *
101 + * input :: target bitmap descriptor. The function will set its
102 + *          'width', 'rows' and 'pitch' fields, and only these
103 + *
104 + * slot  :: the glyph slot containing the source bitmap. this
105 + *          function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP
106 + *
107 + * mode  :: the requested final rendering mode. supported values are
108 + *          MONO, NORMAL (i.e. gray), LCD and LCD_V
109 + *
110 + * the function returns the size in bytes of the corresponding buffer,
111 + * it's up to the caller to allocate the corresponding memory block
112 + * before calling _fill_xrender_bitmap
113 + *
114 + * it also returns -1 in case of error (e.g. incompatible arguments,
115 + * like trying to convert a gray bitmap into a monochrome one)
116 + */
117 +static int
118 +_compute_xrender_bitmap_size( FT_Bitmap*      target,
119 +                              FT_GlyphSlot    slot,
120 +                              FT_Render_Mode  mode )
121 +{
122 +    FT_Bitmap*  ftbit;
123 +    int         width, height, pitch;
124 +
125 +    if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
126 +        return -1;
127 +
128 +    // compute the size of the final bitmap
129 +    ftbit  = &slot->bitmap;
130 +
131 +    width  = ftbit->width;
132 +    height = ftbit->rows;
133 +    pitch  = (width+3) & ~3;
134 +
135 +    switch ( ftbit->pixel_mode )
136 +    {
137 +    case FT_PIXEL_MODE_MONO:
138 +        if ( mode == FT_RENDER_MODE_MONO )
139 +        {
140 +            pitch = (((width+31) & ~31) >> 3);
141 +            break;
142 +        }
143 +        /* fall-through */
144 +
145 +    case FT_PIXEL_MODE_GRAY:
146 +        if ( mode == FT_RENDER_MODE_LCD   ||
147 +             mode == FT_RENDER_MODE_LCD_V )
148 +        {
149 +          /* each pixel is replicated into a 32-bit ARGB value */
150 +          pitch = width*4;
151 +        }
152 +        break;
153 +
154 +    case FT_PIXEL_MODE_LCD:
155 +        if ( mode != FT_RENDER_MODE_LCD )
156 +            return -1;
157 +
158 +        /* horz pixel triplets are packed into 32-bit ARGB values */
159 +        width   /= 3;
160 +        pitch    = width*4;
161 +        break;
162 +
163 +    case FT_PIXEL_MODE_LCD_V:
164 +        if ( mode != FT_RENDER_MODE_LCD_V )
165 +            return -1;
166 +
167 +        /* vert pixel triplets are packed into 32-bit ARGB values */
168 +        height  /= 3;
169 +        pitch    = width*4;
170 +        break;
171 +
172 +    default:  /* unsupported source format */
173 +        return -1;
174 +    }
175 +
176 +    target->width  = width;
177 +    target->rows   = height;
178 +    target->pitch  = pitch;
179 +    target->buffer = NULL;
180 +
181 +    return pitch * height;
182 +}
183 +
184 +/* this functions converts the glyph bitmap found in a FT_GlyphSlot
185 + * into a different format (see _compute_xrender_bitmap_size)
186 + *
187 + * you should call this function after _compute_xrender_bitmap_size
188 + *
189 + * target :: target bitmap descriptor. Note that its 'buffer' pointer
190 + *           must point to memory allocated by the caller
191 + *
192 + * slot   :: the glyph slot containing the source bitmap
193 + *
194 + * mode   :: the requested final rendering mode
195 + *
196 + * bgr    :: boolean, set if BGR or VBGR pixel ordering is needed
197 + */
198 +static void
199 +_fill_xrender_bitmap( FT_Bitmap*      target,
200 +                      FT_GlyphSlot    slot,
201 +                      FT_Render_Mode  mode,
202 +                      int             bgr )
203 +{
204 +    FT_Bitmap*   ftbit = &slot->bitmap;
205 +
206 +    {
207 +        unsigned char*   srcLine   = ftbit->buffer;
208 +        unsigned char*   dstLine   = target->buffer;
209 +        int              src_pitch = ftbit->pitch;
210 +        int              width     = target->width;
211 +        int              height    = target->rows;
212 +        int              pitch     = target->pitch;
213 +        int              subpixel;
214 +        int              h;
215 +
216 +        subpixel = ( mode == FT_RENDER_MODE_LCD ||
217 +                     mode == FT_RENDER_MODE_LCD_V );
218 +
219 +        if ( src_pitch < 0 )
220 +          srcLine -= src_pitch*(ftbit->rows-1);
221 +
222 +        switch ( ftbit->pixel_mode )
223 +        {
224 +        case FT_PIXEL_MODE_MONO:
225 +            if ( subpixel )  /* convert mono to ARGB32 values */
226 +            {
227 +                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
228 +                {
229 +                    int  x;
230 +
231 +                    for ( x = 0; x < width; x++ )
232 +                    {
233 +                        if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
234 +                            ((unsigned int*)dstLine)[x] = 0xffffffffU;
235 +                    }
236 +                }
237 +            }
238 +            else if ( mode == FT_RENDER_MODE_NORMAL )  /* convert mono to 8-bit gray */
239 +            {
240 +                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
241 +                {
242 +                    int  x;
243 +
244 +                    for ( x = 0; x < width; x++ )
245 +                    {
246 +                        if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
247 +                            dstLine[x] = 0xff;
248 +                    }
249 +                }
250 +            }
251 +            else  /* copy mono to mono */
252 +            {
253 +                int  bytes = (width+7) >> 3;
254 +
255 +                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
256 +                    memcpy( dstLine, srcLine, bytes );
257 +            }
258 +            break;
259 +
260 +        case FT_PIXEL_MODE_GRAY:
261 +            if ( subpixel )  /* convert gray to ARGB32 values */
262 +            {
263 +                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
264 +                {
265 +                    int            x;
266 +                    unsigned int*  dst = (unsigned int*)dstLine;
267 +
268 +                    for ( x = 0; x < width; x++ )
269 +                    {
270 +                        unsigned int  pix = srcLine[x];
271 +
272 +                        pix |= (pix << 8);
273 +                        pix |= (pix << 16);
274 +
275 +                        dst[x] = pix;
276 +                    }
277 +                }
278 +            }
279 +            else  /* copy gray into gray */
280 +            {
281 +                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
282 +                    memcpy( dstLine, srcLine, width );
283 +            }
284 +            break;
285 +
286 +        case FT_PIXEL_MODE_LCD:
287 +            if ( !bgr )
288 +            {
289 +                /* convert horizontal RGB into ARGB32 */
290 +                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
291 +                {
292 +                    int            x;
293 +                    unsigned char* src = srcLine;
294 +                    unsigned int*  dst = (unsigned int*)dstLine;
295 +
296 +                    for ( x = 0; x < width; x++, src += 3 )
297 +                    {
298 +                        unsigned int  pix;
299 +
300 +                        pix = ((unsigned int)src[0] << 16) |
301 +                              ((unsigned int)src[1] <<  8) |
302 +                              ((unsigned int)src[2]      ) |
303 +                              ((unsigned int)src[1] << 24) ;
304 +
305 +                        dst[x] = pix;
306 +                    }
307 +                }
308 +            }
309 +            else
310 +            {
311 +                /* convert horizontal BGR into ARGB32 */
312 +                for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
313 +                {
314 +                    int            x;
315 +                    unsigned char* src = srcLine;
316 +                    unsigned int*  dst = (unsigned int*)dstLine;
317 +
318 +                    for ( x = 0; x < width; x++, src += 3 )
319 +                    {
320 +                        unsigned int  pix;
321 +
322 +                        pix = ((unsigned int)src[2] << 16) |
323 +                              ((unsigned int)src[1] <<  8) |
324 +                              ((unsigned int)src[0]      ) |
325 +                              ((unsigned int)src[1] << 24) ;
326 +
327 +                        dst[x] = pix;
328 +                    }
329 +                }
330 +            }
331 +            break;
332 +
333 +        default:  /* FT_PIXEL_MODE_LCD_V */
334 +            /* convert vertical RGB into ARGB32 */
335 +            if ( !bgr )
336 +            {
337 +                for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
338 +                {
339 +                    int            x;
340 +                    unsigned char* src = srcLine;
341 +                    unsigned int*  dst = (unsigned int*)dstLine;
342 +
343 +                    for ( x = 0; x < width; x++, src += 1 )
344 +                    {
345 +                        unsigned int  pix;
346 +
347 +                        pix = ((unsigned int)src[0]           << 16) |
348 +                              ((unsigned int)src[src_pitch]   <<  8) |
349 +                              ((unsigned int)src[src_pitch*2]      ) |
350 +                              ((unsigned int)src[src_pitch]   << 24) ;
351 +
352 +                        dst[x] = pix;
353 +                    }
354 +                }
355 +            }
356 +            else
357 +            {
358 +                for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
359 +                {
360 +                    int            x;
361 +                    unsigned char* src = srcLine;
362 +                    unsigned int*  dst = (unsigned int*)dstLine;
363 +
364 +                    for ( x = 0; x < width; x++, src += 1 )
365 +                    {
366 +                        unsigned int  pix;
367 +
368 +                        pix = ((unsigned int)src[src_pitch*2] << 16) |
369 +                              ((unsigned int)src[src_pitch]   <<  8) |
370 +                              ((unsigned int)src[0]                ) |
371 +                              ((unsigned int)src[src_pitch]   << 24) ;
372 +
373 +                        dst[x] = pix;
374 +                    }
375 +                }
376 +            }
377 +        }
378 +    }
379 +}
380 +
381 +
382  _X_EXPORT void
383  XftFontLoadGlyphs (Display         *dpy,
384                    XftFont          *pub,
385 @@ -87,20 +367,14 @@
386      unsigned char   *bufBitmap = bufLocal;
387      int                    bufSize = sizeof (bufLocal);
388      int                    size, pitch;
389 -    unsigned char   bufLocalRgba[4096];
390 -    unsigned char   *bufBitmapRgba = bufLocalRgba;
391 -    int                    bufSizeRgba = sizeof (bufLocalRgba);
392 -    int                    sizergba, pitchrgba, widthrgba;
393      int                    width;
394      int                    height;
395      int                    left, right, top, bottom;
396 -    int                    hmul = 1;
397 -    int                    vmul = 1;
398 -    FT_Bitmap      ftbit;
399 -    FT_Matrix      matrix;
400 +    FT_Bitmap*     ftbit;
401 +    FT_Bitmap       local;
402      FT_Vector      vector;
403 -    Bool           subpixel = False;
404      FT_Face        face;
405 +    FT_Render_Mode  mode = FT_RENDER_MODE_MONO;
406  
407      if (!info)
408         return;
409 @@ -110,24 +384,19 @@
410      if (!face)
411         return;
412  
413 -    matrix.xx = matrix.yy = 0x10000L;
414 -    matrix.xy = matrix.yx = 0;
415 -
416      if (font->info.antialias)
417      {
418         switch (font->info.rgba) {
419         case FC_RGBA_RGB:
420         case FC_RGBA_BGR:
421 -           matrix.xx *= 3;
422 -           subpixel = True;
423 -           hmul = 3;
424 +           mode = FT_RENDER_MODE_LCD;
425             break;
426         case FC_RGBA_VRGB:
427         case FC_RGBA_VBGR:
428 -           matrix.yy *= 3;
429 -           vmul = 3;
430 -           subpixel = True;
431 +            mode = FT_RENDER_MODE_LCD_V;
432             break;
433 +        default:
434 +            mode = FT_RENDER_MODE_NORMAL;
435         }
436      }
437  
438 @@ -148,7 +417,10 @@
439         if (xftg->glyph_memory)
440             continue;
441         
442 +        FT_Library_SetLcdFilter( _XftFTlibrary, font->info.lcd_filter);
443 +
444         error = FT_Load_Glyph (face, glyphindex, font->info.load_flags);
445 +
446         if (error)
447         {
448             /*
449 @@ -181,7 +453,7 @@
450         /*
451          * Compute glyph metrics from FreeType information
452          */
453 -       if(font->info.transform && glyphslot->format != ft_glyph_format_bitmap) 
454 +       if(font->info.transform && glyphslot->format != FT_GLYPH_FORMAT_BITMAP)
455         {
456             /*
457              * calculate the true width by transforming all four corners.
458 @@ -260,17 +532,14 @@
459             }
460         }
461  
462 -       if (font->info.antialias)
463 -           pitch = (width * hmul + 3) & ~3;
464 -       else
465 -           pitch = ((width + 31) & ~31) >> 3;
466 -
467 -       size = pitch * height * vmul;
468 +        if ( glyphslot->format != FT_GLYPH_FORMAT_BITMAP )
469 +        {
470 +            error = FT_Render_Glyph( face->glyph, mode );
471 +            if (error)
472 +                continue;
473 +        }
474  
475 -       xftg->metrics.width = width;
476 -       xftg->metrics.height = height;
477 -       xftg->metrics.x = -TRUNC(left);
478 -       xftg->metrics.y = TRUNC(top);
479 +        FT_Library_SetLcdFilter( _XftFTlibrary, FT_LCD_FILTER_NONE );
480  
481         if (font->info.spacing >= FC_MONO)
482         {
483 @@ -310,103 +579,13 @@
484             xftg->metrics.yOff = -TRUNC(ROUND(glyphslot->advance.y));
485         }
486         
487 -       /*
488 -        * If the glyph is relatively large (> 1% of server memory),
489 -        * don't send it until necessary
490 -        */
491 -       if (!need_bitmaps && size > info->max_glyph_memory / 100)
492 -           continue;
493         
494 -       /*
495 -        * Make sure there's enough buffer space for the glyph
496 -        */
497 -       if (size > bufSize)
498 -       {
499 -           if (bufBitmap != bufLocal)
500 -               free (bufBitmap);
501 -           bufBitmap = (unsigned char *) malloc (size);
502 -           if (!bufBitmap)
503 -               continue;
504 -           bufSize = size;
505 -       }
506 -       memset (bufBitmap, 0, size);
507 -
508 -       /*
509 -        * Rasterize into the local buffer
510 -        */
511 -       switch (glyphslot->format) {
512 -       case ft_glyph_format_outline:
513 -           ftbit.width      = width * hmul;
514 -           ftbit.rows       = height * vmul;
515 -           ftbit.pitch      = pitch;
516 -           if (font->info.antialias)
517 -               ftbit.pixel_mode = ft_pixel_mode_grays;
518 -           else
519 -               ftbit.pixel_mode = ft_pixel_mode_mono;
520 -           
521 -           ftbit.buffer     = bufBitmap;
522 -           
523 -           if (subpixel)
524 -               FT_Outline_Transform (&glyphslot->outline, &matrix);
525 +        // compute the size of the final bitmap
526 +        ftbit  = &glyphslot->bitmap;
527  
528 -           FT_Outline_Translate ( &glyphslot->outline, -left*hmul, -bottom*vmul );
529 -
530 -           FT_Outline_Get_Bitmap( _XftFTlibrary, &glyphslot->outline, &ftbit );
531 -           break;
532 -       case ft_glyph_format_bitmap:
533 -           if (font->info.antialias)
534 -           {
535 -               unsigned char   *srcLine, *dstLine;
536 -               int             height;
537 -               int             x;
538 -               int         h, v;
539 -
540 -               srcLine = glyphslot->bitmap.buffer;
541 -               dstLine = bufBitmap;
542 -               height = glyphslot->bitmap.rows;
543 -               while (height--)
544 -               {
545 -                   for (x = 0; x < glyphslot->bitmap.width; x++)
546 -                   {
547 -                       /* always MSB bitmaps */
548 -                       unsigned char   a = ((srcLine[x >> 3] & (0x80 >> (x & 7))) ?
549 -                                            0xff : 0x00);
550 -                       if (subpixel)
551 -                       {
552 -                           for (v = 0; v < vmul; v++)
553 -                               for (h = 0; h < hmul; h++)
554 -                                   dstLine[v * pitch + x*hmul + h] = a;
555 -                       }
556 -                       else
557 -                           dstLine[x] = a;
558 -                   }
559 -                   dstLine += pitch * vmul;
560 -                   srcLine += glyphslot->bitmap.pitch;
561 -               }
562 -           }
563 -           else
564 -           {
565 -               unsigned char   *srcLine, *dstLine;
566 -               int             h, bytes;
567 -
568 -               srcLine = glyphslot->bitmap.buffer;
569 -               dstLine = bufBitmap;
570 -               h = glyphslot->bitmap.rows;
571 -               bytes = (glyphslot->bitmap.width + 7) >> 3;
572 -               while (h--)
573 -               {
574 -                   memcpy (dstLine, srcLine, bytes);
575 -                   dstLine += pitch;
576 -                   srcLine += glyphslot->bitmap.pitch;
577 -               }
578 -           }
579 -           break;
580 -       default:
581 -           if (XftDebug() & XFT_DBG_GLYPH)
582 -               printf ("glyph %d is not in a usable format\n",
583 -                       (int) glyphindex);
584 -           continue;
585 -       }
586 +        width  = ftbit->width;
587 +        height = ftbit->rows;
588 +        pitch  = (width+3) & ~3;
589         
590         if (XftDebug() & XFT_DBG_GLYPH)
591         {
592 @@ -423,29 +602,72 @@
593                 int             x, y;
594                 unsigned char   *line;
595  
596 -               line = bufBitmap;
597 -               for (y = 0; y < height * vmul; y++)
598 +                line = ftbit->buffer;
599 +
600 +                if (ftbit->pitch < 0)
601 +                  line -= ftbit->pitch*(height-1);
602 +
603 +                for (y = 0; y < height; y++)
604                 {
605                     if (font->info.antialias) 
606                     {
607 -                       static char    den[] = { " .:;=+*#" };
608 -                       for (x = 0; x < pitch; x++)
609 +                        static const char    den[] = { " .:;=+*#" };
610 +                        for (x = 0; x < width; x++)
611                             printf ("%c", den[line[x] >> 5]);
612                     }
613                     else
614                     {
615 -                       for (x = 0; x < pitch * 8; x++)
616 +                        for (x = 0; x < width * 8; x++)
617                         {
618                             printf ("%c", line[x>>3] & (1 << (x & 7)) ? '#' : ' ');
619                         }
620                     }
621                     printf ("|\n");
622 -                   line += pitch;
623 +                    line += ftbit->pitch;
624                 }
625                 printf ("\n");
626             }
627         }
628  
629 +        size = _compute_xrender_bitmap_size( &local, glyphslot, mode );
630 +        if ( size < 0 )
631 +            continue;
632 +
633 +        xftg->metrics.width  = local.width;
634 +       xftg->metrics.height = local.rows;
635 +       xftg->metrics.x      = - glyphslot->bitmap_left;
636 +       xftg->metrics.y      =   glyphslot->bitmap_top;
637 +           
638 +           /*
639 +        * If the glyph is relatively large (> 1% of server memory),
640 +        * don't send it until necessary
641 +            */
642 +       if (!need_bitmaps && size > info->max_glyph_memory / 100)
643 +           continue;
644 +
645 +       /*
646 +        * Make sure there's enough buffer space for the glyph
647 +        */
648 +       if (size > bufSize)
649 +           {
650 +           if (bufBitmap != bufLocal)
651 +               free (bufBitmap);
652 +           bufBitmap = (unsigned char *) malloc (size);
653 +           if (!bufBitmap)
654 +                   continue;
655 +           bufSize = size;
656 +           }
657 +       memset (bufBitmap, 0, size);
658 +
659 +        local.buffer = bufBitmap;
660 +           
661 +        _fill_xrender_bitmap( &local, glyphslot, mode,
662 +                              (font->info.rgba == FC_RGBA_BGR  ||
663 +                               font->info.rgba == FC_RGBA_VBGR ) );
664 +       /*
665 +        * Copy or convert into local buffer
666 +        */
667 +
668         /*
669          * Use the glyph index as the wire encoding; it
670          * might be more efficient for some locales to map
671 @@ -455,121 +677,23 @@
672          */
673         glyph = (Glyph) glyphindex;
674  
675 -       if (subpixel)
676 -       {
677 -           int             x, y;
678 -           unsigned char   *in_line, *out_line, *in;
679 -           unsigned int    *out;
680 -           unsigned int    red, green, blue;
681 -           int             rf, gf, bf;
682 -           int             s;
683 -           int             o, os;
684 -           
685 -           /*
686 -            * Filter the glyph to soften the color fringes
687 -            */
688 -           widthrgba = width;
689 -           pitchrgba = (widthrgba * 4 + 3) & ~3;
690 -           sizergba = pitchrgba * height;
691 -
692 -           os = 1;
693 -           switch (font->info.rgba) {
694 -           case FC_RGBA_VRGB:
695 -               os = pitch;
696 -           case FC_RGBA_RGB:
697 -           default:
698 -               rf = 0;
699 -               gf = 1;
700 -               bf = 2;
701 -               break;
702 -           case FC_RGBA_VBGR:
703 -               os = pitch;
704 -           case FC_RGBA_BGR:
705 -               bf = 0;
706 -               gf = 1;
707 -               rf = 2;
708 -               break;
709 -           }
710 -           if (sizergba > bufSizeRgba)
711 -           {
712 -               if (bufBitmapRgba != bufLocalRgba)
713 -                   free (bufBitmapRgba);
714 -               bufBitmapRgba = (unsigned char *) malloc (sizergba);
715 -               if (!bufBitmapRgba)
716 -                   continue;
717 -               bufSizeRgba = sizergba;
718 -           }
719 -           memset (bufBitmapRgba, 0, sizergba);
720 -           in_line = bufBitmap;
721 -           out_line = bufBitmapRgba;
722 -           for (y = 0; y < height; y++)
723 -           {
724 -               in = in_line;
725 -               out = (unsigned int *) out_line;
726 -               in_line += pitch * vmul;
727 -               out_line += pitchrgba;
728 -               for (x = 0; x < width * hmul; x += hmul)
729 -               {
730 -                   red = green = blue = 0;
731 -                   o = 0;
732 -                   for (s = 0; s < 3; s++)
733 -                   {
734 -                       red += filters[rf][s]*in[x+o];
735 -                       green += filters[gf][s]*in[x+o];
736 -                       blue += filters[bf][s]*in[x+o];
737 -                       o += os;
738 -                   }
739 -                   red = red / 65536;
740 -                   green = green / 65536;
741 -                   blue = blue / 65536;
742 -                   *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
743 -               }
744 -           }
745 -           
746 -           xftg->glyph_memory = sizergba + sizeof (XftGlyph);
747 -           if (font->format)
748 +       xftg->glyph_memory = size + sizeof (XftGlyph);
749 +           if (font->format)
750             {
751                 if (!font->glyphset)
752                     font->glyphset = XRenderCreateGlyphSet (dpy, font->format);
753 -               if (ImageByteOrder (dpy) != XftNativeByteOrder ())
754 -                   XftSwapCARD32 ((CARD32 *) bufBitmapRgba, sizergba >> 2);
755 -               XRenderAddGlyphs (dpy, font->glyphset, &glyph,
756 -                                 &xftg->metrics, 1, 
757 -                                 (char *) bufBitmapRgba, sizergba);
758 -           }
759 -           else
760 -           {
761 -               if (sizergba)
762 -               {
763 -                   xftg->bitmap = malloc (sizergba);
764 -                   if (xftg->bitmap)
765 -                       memcpy (xftg->bitmap, bufBitmapRgba, sizergba);
766 -               }
767 -               else
768 -                   xftg->bitmap = NULL;
769 -           }
770 -       }
771 -       else
772 -       {
773 -           xftg->glyph_memory = size + sizeof (XftGlyph);
774 -           if (font->format)
775 -           {
776 -               /*
777 -                * swap bit order around; FreeType is always MSBFirst
778 -                */
779 -               if (!font->info.antialias)
780 +           if ( mode == FT_RENDER_MODE_MONO )
781                 {
782 +                 /* swap bits in each byte */
783                     if (BitmapBitOrder (dpy) != MSBFirst)
784                     {
785 -                       unsigned char   *line;
786 -                       unsigned char   c;
787 -                       int                 i;
788 +                     unsigned char   *line = (unsigned char*)bufBitmap;
789 +                     int             i = size;
790  
791 -                       line = (unsigned char *) bufBitmap;
792 -                       i = size;
793                         while (i--)
794                         {
795 -                           c = *line;
796 +                         int  c = *line;
797 +
798                             c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
799                             c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
800                             c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
801 @@ -577,8 +701,12 @@
802                         }
803                     }
804                 }
805 -               if (!font->glyphset)
806 -                   font->glyphset = XRenderCreateGlyphSet (dpy, font->format);
807 +            else if ( mode != FT_RENDER_MODE_NORMAL )
808 +            {
809 +                /* invert ARGB <=> BGRA */
810 +                if (ImageByteOrder (dpy) != XftNativeByteOrder ())
811 +                    XftSwapCARD32 ((CARD32 *) bufBitmap, size >> 2);
812 +            }
813                 XRenderAddGlyphs (dpy, font->glyphset, &glyph,
814                                   &xftg->metrics, 1, 
815                                   (char *) bufBitmap, size);
816 @@ -594,7 +722,7 @@
817                 else
818                     xftg->bitmap = NULL;
819             }
820 -       }
821 +
822         font->glyph_memory += xftg->glyph_memory;
823         info->glyph_memory += xftg->glyph_memory;
824         if (XftDebug() & XFT_DBG_CACHE)
825 @@ -605,8 +733,6 @@
826      }
827      if (bufBitmap != bufLocal)
828         free (bufBitmap);
829 -    if (bufBitmapRgba != bufLocalRgba)
830 -       free (bufBitmapRgba);
831      XftUnlockFace (&font->public);
832  }
833  
834 --- a/src/xftint.h
835 +++ b/src/xftint.h
836 @@ -145,6 +145,7 @@
837      FcBool             antialias;      /* doing antialiasing */
838      FcBool             embolden;       /* force emboldening */
839      int                        rgba;           /* subpixel order */
840 +    int                        lcd_filter;     /* lcd filter */
841      FT_Matrix          matrix;         /* glyph transformation matrix */
842      FcBool             transform;      /* non-identify matrix? */
843      FT_Int             load_flags;     /* glyph load flags */