updated on Sat Jan 21 20:03:50 UTC 2012
[aur-mirror.git] / lib32-libxft-lcd / xorg-lib-libXft-lcd-filter.patch
blobe27ecd4f6976abbabf520471ef2556a7130a4c92
1 diff -Naur libXft-2.1.14.orig/src/xftglyphs.c libXft-2.1.14/src/xftglyphs.c
2 --- libXft-2.1.14.orig/src/xftglyphs.c 2009-01-29 21:19:09.000000000 -0200
3 +++ libXft-2.1.14/src/xftglyphs.c 2009-11-01 08:03:09.102347757 -0200
4 @@ -21,27 +21,18 @@
5 */
7 #include "xftint.h"
8 -#include <freetype/ftoutln.h>
10 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
11 #include <freetype/ftsynth.h>
12 #endif
14 -static const int filters[3][3] = {
15 - /* red */
16 -#if 0
17 -{ 65538*4/7,65538*2/7,65538*1/7 },
18 - /* green */
19 -{ 65536*1/4, 65536*2/4, 65537*1/4 },
20 - /* blue */
21 -{ 65538*1/7,65538*2/7,65538*4/7 },
22 +#if FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH < 20202
23 +# error "FreeType 2.2.2 or later required to compile this version of libXft"
24 #endif
25 -{ 65538*9/13,65538*3/13,65538*1/13 },
26 - /* green */
27 -{ 65538*1/6, 65538*4/6, 65538*1/6 },
28 - /* blue */
29 -{ 65538*1/13,65538*3/13,65538*9/13 },
30 -};
32 +#include FT_OUTLINE_H
33 +#include FT_LCD_FILTER_H
34 +#include FT_SYNTHESIS_H
37 * Validate the memory info for a font
38 @@ -69,6 +60,295 @@
39 font->glyph_memory, glyph_memory);
43 +/* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot
44 + * into a different format. For example, we want to convert a
45 + * FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit
46 + * ARGB or ABGR bitmap.
47 + *
48 + * this function prepares a target descriptor for this operation.
49 + *
50 + * input :: target bitmap descriptor. The function will set its
51 + * 'width', 'rows' and 'pitch' fields, and only these
52 + *
53 + * slot :: the glyph slot containing the source bitmap. this
54 + * function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP
55 + *
56 + * mode :: the requested final rendering mode. supported values are
57 + * MONO, NORMAL (i.e. gray), LCD and LCD_V
58 + *
59 + * the function returns the size in bytes of the corresponding buffer,
60 + * it's up to the caller to allocate the corresponding memory block
61 + * before calling _fill_xrender_bitmap
62 + *
63 + * it also returns -1 in case of error (e.g. incompatible arguments,
64 + * like trying to convert a gray bitmap into a monochrome one)
65 + */
66 +static int
67 +_compute_xrender_bitmap_size( FT_Bitmap* target,
68 + FT_GlyphSlot slot,
69 + FT_Render_Mode mode )
71 + FT_Bitmap* ftbit;
72 + int width, height, pitch;
74 + if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
75 + return -1;
77 + // compute the size of the final bitmap
78 + ftbit = &slot->bitmap;
80 + width = ftbit->width;
81 + height = ftbit->rows;
82 + pitch = (width+3) & ~3;
84 + switch ( ftbit->pixel_mode )
85 + {
86 + case FT_PIXEL_MODE_MONO:
87 + if ( mode == FT_RENDER_MODE_MONO )
88 + {
89 + pitch = (((width+31) & ~31) >> 3);
90 + break;
91 + }
92 + /* fall-through */
94 + case FT_PIXEL_MODE_GRAY:
95 + if ( mode == FT_RENDER_MODE_LCD ||
96 + mode == FT_RENDER_MODE_LCD_V )
97 + {
98 + /* each pixel is replicated into a 32-bit ARGB value */
99 + pitch = width*4;
101 + break;
103 + case FT_PIXEL_MODE_LCD:
104 + if ( mode != FT_RENDER_MODE_LCD )
105 + return -1;
107 + /* horz pixel triplets are packed into 32-bit ARGB values */
108 + width /= 3;
109 + pitch = width*4;
110 + break;
112 + case FT_PIXEL_MODE_LCD_V:
113 + if ( mode != FT_RENDER_MODE_LCD_V )
114 + return -1;
116 + /* vert pixel triplets are packed into 32-bit ARGB values */
117 + height /= 3;
118 + pitch = width*4;
119 + break;
121 + default: /* unsupported source format */
122 + return -1;
125 + target->width = width;
126 + target->rows = height;
127 + target->pitch = pitch;
128 + target->buffer = NULL;
130 + return pitch * height;
133 +/* this functions converts the glyph bitmap found in a FT_GlyphSlot
134 + * into a different format (see _compute_xrender_bitmap_size)
136 + * you should call this function after _compute_xrender_bitmap_size
138 + * target :: target bitmap descriptor. Note that its 'buffer' pointer
139 + * must point to memory allocated by the caller
141 + * slot :: the glyph slot containing the source bitmap
143 + * mode :: the requested final rendering mode
145 + * bgr :: boolean, set if BGR or VBGR pixel ordering is needed
146 + */
147 +static void
148 +_fill_xrender_bitmap( FT_Bitmap* target,
149 + FT_GlyphSlot slot,
150 + FT_Render_Mode mode,
151 + int bgr )
153 + FT_Bitmap* ftbit = &slot->bitmap;
156 + unsigned char* srcLine = ftbit->buffer;
157 + unsigned char* dstLine = target->buffer;
158 + int src_pitch = ftbit->pitch;
159 + int width = target->width;
160 + int height = target->rows;
161 + int pitch = target->pitch;
162 + int subpixel;
163 + int h;
165 + subpixel = ( mode == FT_RENDER_MODE_LCD ||
166 + mode == FT_RENDER_MODE_LCD_V );
168 + if ( src_pitch < 0 )
169 + srcLine -= src_pitch*(ftbit->rows-1);
171 + switch ( ftbit->pixel_mode )
173 + case FT_PIXEL_MODE_MONO:
174 + if ( subpixel ) /* convert mono to ARGB32 values */
176 + for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
178 + int x;
180 + for ( x = 0; x < width; x++ )
182 + if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
183 + ((unsigned int*)dstLine)[x] = 0xffffffffU;
187 + else if ( mode == FT_RENDER_MODE_NORMAL ) /* convert mono to 8-bit gray */
189 + for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
191 + int x;
193 + for ( x = 0; x < width; x++ )
195 + if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
196 + dstLine[x] = 0xff;
200 + else /* copy mono to mono */
202 + int bytes = (width+7) >> 3;
204 + for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
205 + memcpy( dstLine, srcLine, bytes );
207 + break;
209 + case FT_PIXEL_MODE_GRAY:
210 + if ( subpixel ) /* convert gray to ARGB32 values */
212 + for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
214 + int x;
215 + unsigned int* dst = (unsigned int*)dstLine;
217 + for ( x = 0; x < width; x++ )
219 + unsigned int pix = srcLine[x];
221 + pix |= (pix << 8);
222 + pix |= (pix << 16);
224 + dst[x] = pix;
228 + else /* copy gray into gray */
230 + for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
231 + memcpy( dstLine, srcLine, width );
233 + break;
235 + case FT_PIXEL_MODE_LCD:
236 + if ( !bgr )
238 + /* convert horizontal RGB into ARGB32 */
239 + for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
241 + int x;
242 + unsigned char* src = srcLine;
243 + unsigned int* dst = (unsigned int*)dstLine;
245 + for ( x = 0; x < width; x++, src += 3 )
247 + unsigned int pix;
249 + pix = ((unsigned int)src[0] << 16) |
250 + ((unsigned int)src[1] << 8) |
251 + ((unsigned int)src[2] ) |
252 + ((unsigned int)src[1] << 24) ;
254 + dst[x] = pix;
258 + else
260 + /* convert horizontal BGR into ARGB32 */
261 + for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
263 + int x;
264 + unsigned char* src = srcLine;
265 + unsigned int* dst = (unsigned int*)dstLine;
267 + for ( x = 0; x < width; x++, src += 3 )
269 + unsigned int pix;
271 + pix = ((unsigned int)src[2] << 16) |
272 + ((unsigned int)src[1] << 8) |
273 + ((unsigned int)src[0] ) |
274 + ((unsigned int)src[1] << 24) ;
276 + dst[x] = pix;
280 + break;
282 + default: /* FT_PIXEL_MODE_LCD_V */
283 + /* convert vertical RGB into ARGB32 */
284 + if ( !bgr )
286 + for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
288 + int x;
289 + unsigned char* src = srcLine;
290 + unsigned int* dst = (unsigned int*)dstLine;
292 + for ( x = 0; x < width; x++, src += 1 )
294 + unsigned int pix;
296 + pix = ((unsigned int)src[0] << 16) |
297 + ((unsigned int)src[src_pitch] << 8) |
298 + ((unsigned int)src[src_pitch*2] ) |
299 + ((unsigned int)src[src_pitch] << 24) ;
301 + dst[x] = pix;
305 + else
307 + for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
309 + int x;
310 + unsigned char* src = srcLine;
311 + unsigned int* dst = (unsigned int*)dstLine;
313 + for ( x = 0; x < width; x++, src += 1 )
315 + unsigned int pix;
317 + pix = ((unsigned int)src[src_pitch*2] << 16) |
318 + ((unsigned int)src[src_pitch] << 8) |
319 + ((unsigned int)src[0] ) |
320 + ((unsigned int)src[src_pitch] << 24) ;
322 + dst[x] = pix;
331 _X_EXPORT void
332 XftFontLoadGlyphs (Display *dpy,
333 XftFont *pub,
334 @@ -87,20 +367,14 @@
335 unsigned char *bufBitmap = bufLocal;
336 int bufSize = sizeof (bufLocal);
337 int size, pitch;
338 - unsigned char bufLocalRgba[4096];
339 - unsigned char *bufBitmapRgba = bufLocalRgba;
340 - int bufSizeRgba = sizeof (bufLocalRgba);
341 - int sizergba, pitchrgba, widthrgba;
342 int width;
343 int height;
344 int left, right, top, bottom;
345 - int hmul = 1;
346 - int vmul = 1;
347 - FT_Bitmap ftbit;
348 - FT_Matrix matrix;
349 + FT_Bitmap* ftbit;
350 + FT_Bitmap local;
351 FT_Vector vector;
352 - Bool subpixel = False;
353 FT_Face face;
354 + FT_Render_Mode mode = FT_RENDER_MODE_MONO;
356 if (!info)
357 return;
358 @@ -110,24 +384,19 @@
359 if (!face)
360 return;
362 - matrix.xx = matrix.yy = 0x10000L;
363 - matrix.xy = matrix.yx = 0;
365 if (font->info.antialias)
367 switch (font->info.rgba) {
368 case FC_RGBA_RGB:
369 case FC_RGBA_BGR:
370 - matrix.xx *= 3;
371 - subpixel = True;
372 - hmul = 3;
373 + mode = FT_RENDER_MODE_LCD;
374 break;
375 case FC_RGBA_VRGB:
376 case FC_RGBA_VBGR:
377 - matrix.yy *= 3;
378 - vmul = 3;
379 - subpixel = True;
380 + mode = FT_RENDER_MODE_LCD_V;
381 break;
382 + default:
383 + mode = FT_RENDER_MODE_NORMAL;
387 @@ -148,7 +417,10 @@
388 if (xftg->glyph_memory)
389 continue;
391 + FT_Library_SetLcdFilter( _XftFTlibrary, FT_LCD_FILTER_DEFAULT );
393 error = FT_Load_Glyph (face, glyphindex, font->info.load_flags);
395 if (error)
398 @@ -181,7 +453,7 @@
400 * Compute glyph metrics from FreeType information
402 - if(font->info.transform && glyphslot->format != ft_glyph_format_bitmap)
403 + if(font->info.transform && glyphslot->format != FT_GLYPH_FORMAT_BITMAP)
406 * calculate the true width by transforming all four corners.
407 @@ -260,17 +532,14 @@
411 - if (font->info.antialias)
412 - pitch = (width * hmul + 3) & ~3;
413 - else
414 - pitch = ((width + 31) & ~31) >> 3;
416 - size = pitch * height * vmul;
417 + if ( glyphslot->format != FT_GLYPH_FORMAT_BITMAP )
419 + error = FT_Render_Glyph( face->glyph, mode );
420 + if (error)
421 + continue;
424 - xftg->metrics.width = width;
425 - xftg->metrics.height = height;
426 - xftg->metrics.x = -TRUNC(left);
427 - xftg->metrics.y = TRUNC(top);
428 + FT_Library_SetLcdFilter( _XftFTlibrary, FT_LCD_FILTER_NONE );
430 if (font->info.spacing >= FC_MONO)
432 @@ -310,103 +579,13 @@
433 xftg->metrics.yOff = -TRUNC(ROUND(glyphslot->advance.y));
436 - /*
437 - * If the glyph is relatively large (> 1% of server memory),
438 - * don't send it until necessary
439 - */
440 - if (!need_bitmaps && size > info->max_glyph_memory / 100)
441 - continue;
443 - /*
444 - * Make sure there's enough buffer space for the glyph
445 - */
446 - if (size > bufSize)
448 - if (bufBitmap != bufLocal)
449 - free (bufBitmap);
450 - bufBitmap = (unsigned char *) malloc (size);
451 - if (!bufBitmap)
452 - continue;
453 - bufSize = size;
455 - memset (bufBitmap, 0, size);
457 - /*
458 - * Rasterize into the local buffer
459 - */
460 - switch (glyphslot->format) {
461 - case ft_glyph_format_outline:
462 - ftbit.width = width * hmul;
463 - ftbit.rows = height * vmul;
464 - ftbit.pitch = pitch;
465 - if (font->info.antialias)
466 - ftbit.pixel_mode = ft_pixel_mode_grays;
467 - else
468 - ftbit.pixel_mode = ft_pixel_mode_mono;
470 - ftbit.buffer = bufBitmap;
472 - if (subpixel)
473 - FT_Outline_Transform (&glyphslot->outline, &matrix);
475 - FT_Outline_Translate ( &glyphslot->outline, -left*hmul, -bottom*vmul );
476 + // compute the size of the final bitmap
477 + ftbit = &glyphslot->bitmap;
479 - FT_Outline_Get_Bitmap( _XftFTlibrary, &glyphslot->outline, &ftbit );
480 - break;
481 - case ft_glyph_format_bitmap:
482 - if (font->info.antialias)
484 - unsigned char *srcLine, *dstLine;
485 - int height;
486 - int x;
487 - int h, v;
489 - srcLine = glyphslot->bitmap.buffer;
490 - dstLine = bufBitmap;
491 - height = glyphslot->bitmap.rows;
492 - while (height--)
494 - for (x = 0; x < glyphslot->bitmap.width; x++)
496 - /* always MSB bitmaps */
497 - unsigned char a = ((srcLine[x >> 3] & (0x80 >> (x & 7))) ?
498 - 0xff : 0x00);
499 - if (subpixel)
501 - for (v = 0; v < vmul; v++)
502 - for (h = 0; h < hmul; h++)
503 - dstLine[v * pitch + x*hmul + h] = a;
505 - else
506 - dstLine[x] = a;
508 - dstLine += pitch * vmul;
509 - srcLine += glyphslot->bitmap.pitch;
512 - else
514 - unsigned char *srcLine, *dstLine;
515 - int h, bytes;
517 - srcLine = glyphslot->bitmap.buffer;
518 - dstLine = bufBitmap;
519 - h = glyphslot->bitmap.rows;
520 - bytes = (glyphslot->bitmap.width + 7) >> 3;
521 - while (h--)
523 - memcpy (dstLine, srcLine, bytes);
524 - dstLine += pitch;
525 - srcLine += glyphslot->bitmap.pitch;
528 - break;
529 - default:
530 - if (XftDebug() & XFT_DBG_GLYPH)
531 - printf ("glyph %d is not in a usable format\n",
532 - (int) glyphindex);
533 - continue;
535 + width = ftbit->width;
536 + height = ftbit->rows;
537 + pitch = (width+3) & ~3;
539 if (XftDebug() & XFT_DBG_GLYPH)
541 @@ -423,29 +602,72 @@
542 int x, y;
543 unsigned char *line;
545 - line = bufBitmap;
546 - for (y = 0; y < height * vmul; y++)
547 + line = ftbit->buffer;
549 + if (ftbit->pitch < 0)
550 + line -= ftbit->pitch*(height-1);
552 + for (y = 0; y < height; y++)
554 if (font->info.antialias)
556 - static char den[] = { " .:;=+*#" };
557 - for (x = 0; x < pitch; x++)
558 + static const char den[] = { " .:;=+*#" };
559 + for (x = 0; x < width; x++)
560 printf ("%c", den[line[x] >> 5]);
562 else
564 - for (x = 0; x < pitch * 8; x++)
565 + for (x = 0; x < width * 8; x++)
567 printf ("%c", line[x>>3] & (1 << (x & 7)) ? '#' : ' ');
570 printf ("|\n");
571 - line += pitch;
572 + line += ftbit->pitch;
574 printf ("\n");
578 + size = _compute_xrender_bitmap_size( &local, glyphslot, mode );
579 + if ( size < 0 )
580 + continue;
582 + xftg->metrics.width = local.width;
583 + xftg->metrics.height = local.rows;
584 + xftg->metrics.x = - glyphslot->bitmap_left;
585 + xftg->metrics.y = glyphslot->bitmap_top;
587 + /*
588 + * If the glyph is relatively large (> 1% of server memory),
589 + * don't send it until necessary
590 + */
591 + if (!need_bitmaps && size > info->max_glyph_memory / 100)
592 + continue;
594 + /*
595 + * Make sure there's enough buffer space for the glyph
596 + */
597 + if (size > bufSize)
599 + if (bufBitmap != bufLocal)
600 + free (bufBitmap);
601 + bufBitmap = (unsigned char *) malloc (size);
602 + if (!bufBitmap)
603 + continue;
604 + bufSize = size;
606 + memset (bufBitmap, 0, size);
608 + local.buffer = bufBitmap;
610 + _fill_xrender_bitmap( &local, glyphslot, mode,
611 + (font->info.rgba == FC_RGBA_BGR ||
612 + font->info.rgba == FC_RGBA_VBGR ) );
613 + /*
614 + * Copy or convert into local buffer
615 + */
618 * Use the glyph index as the wire encoding; it
619 * might be more efficient for some locales to map
620 @@ -455,121 +677,23 @@
622 glyph = (Glyph) glyphindex;
624 - if (subpixel)
626 - int x, y;
627 - unsigned char *in_line, *out_line, *in;
628 - unsigned int *out;
629 - unsigned int red, green, blue;
630 - int rf, gf, bf;
631 - int s;
632 - int o, os;
634 - /*
635 - * Filter the glyph to soften the color fringes
636 - */
637 - widthrgba = width;
638 - pitchrgba = (widthrgba * 4 + 3) & ~3;
639 - sizergba = pitchrgba * height;
641 - os = 1;
642 - switch (font->info.rgba) {
643 - case FC_RGBA_VRGB:
644 - os = pitch;
645 - case FC_RGBA_RGB:
646 - default:
647 - rf = 0;
648 - gf = 1;
649 - bf = 2;
650 - break;
651 - case FC_RGBA_VBGR:
652 - os = pitch;
653 - case FC_RGBA_BGR:
654 - bf = 0;
655 - gf = 1;
656 - rf = 2;
657 - break;
659 - if (sizergba > bufSizeRgba)
661 - if (bufBitmapRgba != bufLocalRgba)
662 - free (bufBitmapRgba);
663 - bufBitmapRgba = (unsigned char *) malloc (sizergba);
664 - if (!bufBitmapRgba)
665 - continue;
666 - bufSizeRgba = sizergba;
668 - memset (bufBitmapRgba, 0, sizergba);
669 - in_line = bufBitmap;
670 - out_line = bufBitmapRgba;
671 - for (y = 0; y < height; y++)
673 - in = in_line;
674 - out = (unsigned int *) out_line;
675 - in_line += pitch * vmul;
676 - out_line += pitchrgba;
677 - for (x = 0; x < width * hmul; x += hmul)
679 - red = green = blue = 0;
680 - o = 0;
681 - for (s = 0; s < 3; s++)
683 - red += filters[rf][s]*in[x+o];
684 - green += filters[gf][s]*in[x+o];
685 - blue += filters[bf][s]*in[x+o];
686 - o += os;
688 - red = red / 65536;
689 - green = green / 65536;
690 - blue = blue / 65536;
691 - *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
695 - xftg->glyph_memory = sizergba + sizeof (XftGlyph);
696 + xftg->glyph_memory = size + sizeof (XftGlyph);
698 if (font->format)
700 if (!font->glyphset)
701 font->glyphset = XRenderCreateGlyphSet (dpy, font->format);
702 - if (ImageByteOrder (dpy) != XftNativeByteOrder ())
703 - XftSwapCARD32 ((CARD32 *) bufBitmapRgba, sizergba >> 2);
704 - XRenderAddGlyphs (dpy, font->glyphset, &glyph,
705 - &xftg->metrics, 1,
706 - (char *) bufBitmapRgba, sizergba);
708 - else
710 - if (sizergba)
712 - xftg->bitmap = malloc (sizergba);
713 - if (xftg->bitmap)
714 - memcpy (xftg->bitmap, bufBitmapRgba, sizergba);
716 - else
717 - xftg->bitmap = NULL;
720 - else
722 - xftg->glyph_memory = size + sizeof (XftGlyph);
723 - if (font->format)
725 - /*
726 - * swap bit order around; FreeType is always MSBFirst
727 - */
728 - if (!font->info.antialias)
729 + if ( mode == FT_RENDER_MODE_MONO )
731 + /* swap bits in each byte */
732 if (BitmapBitOrder (dpy) != MSBFirst)
734 - unsigned char *line;
735 - unsigned char c;
736 - int i;
737 + unsigned char *line = (unsigned char*)bufBitmap;
738 + int i = size;
740 - line = (unsigned char *) bufBitmap;
741 - i = size;
742 while (i--)
744 - c = *line;
745 + int c = *line;
746 c = ((c << 1) & 0xaa) | ((c >> 1) & 0x55);
747 c = ((c << 2) & 0xcc) | ((c >> 2) & 0x33);
748 c = ((c << 4) & 0xf0) | ((c >> 4) & 0x0f);
749 @@ -577,8 +701,12 @@
753 - if (!font->glyphset)
754 - font->glyphset = XRenderCreateGlyphSet (dpy, font->format);
755 + else if ( mode != FT_RENDER_MODE_NORMAL )
757 + /* invert ARGB <=> BGRA */
758 + if (ImageByteOrder (dpy) != XftNativeByteOrder ())
759 + XftSwapCARD32 ((CARD32 *) bufBitmap, size >> 2);
761 XRenderAddGlyphs (dpy, font->glyphset, &glyph,
762 &xftg->metrics, 1,
763 (char *) bufBitmap, size);
764 @@ -594,7 +722,7 @@
765 else
766 xftg->bitmap = NULL;
770 font->glyph_memory += xftg->glyph_memory;
771 info->glyph_memory += xftg->glyph_memory;
772 if (XftDebug() & XFT_DBG_CACHE)
773 @@ -605,8 +733,6 @@
775 if (bufBitmap != bufLocal)
776 free (bufBitmap);
777 - if (bufBitmapRgba != bufLocalRgba)
778 - free (bufBitmapRgba);
779 XftUnlockFace (&font->public);