updated on Wed Jan 25 00:20:47 UTC 2012
[aur-mirror.git] / libxft-newspr / lcd.patch
blob49e1c4de31367e4c724671a07de2ff334b63c86d
1 diff -urN src/xftfreetype.c.orig src/xftfreetype.c
2 --- src/xftfreetype.c.orig 2009-01-30 07:19:09.000000000 +0800
3 +++ src/xftfreetype.c 2009-10-12 10:18:34.000000000 +0800
4 @@ -584,38 +584,43 @@
6 #ifdef FC_HINT_STYLE
7 #ifdef FT_LOAD_TARGET_LIGHT
8 - if (FC_HINT_NONE < hint_style && hint_style < FC_HINT_FULL)
9 - {
10 - fi->load_flags |= FT_LOAD_TARGET_LIGHT;
11 - }
12 - else
13 -#endif
14 -#endif
15 - {
16 - /* autohinter will snap stems to integer widths, when
17 - * the LCD targets are used.
18 - */
19 - switch (fi->rgba) {
20 - case FC_RGBA_RGB:
21 - case FC_RGBA_BGR:
22 -#ifdef FT_LOAD_TARGET_LCD
23 - fi->load_flags |= FT_LOAD_TARGET_LCD;
24 + switch ( hint_style )
25 + {
26 + case FC_HINT_SLIGHT:
27 + fi->load_flags |= FT_LOAD_TARGET_LIGHT;
28 + break;
30 + case FC_HINT_FULL:
31 + switch (fi->rgba) {
32 + case FC_RGBA_RGB:
33 + case FC_RGBA_BGR:
34 + fi->load_flags |= FT_LOAD_TARGET_LCD;
35 + break;
36 + case FC_RGBA_VRGB:
37 + case FC_RGBA_VBGR:
38 + fi->load_flags |= FT_LOAD_TARGET_LCD_V;
39 + break;
41 + default:
42 + ;
43 + }
44 + break;
46 + default: /* FC_HINT_MEDIUM */
47 + ; /* nothing => FT_LOAD_TARGET_NORMAL */
48 + }
49 +#endif /* if FT_LOAD_TARGET_LIGHT isn't defined, you
50 + * have a *very* old version of FreeType that
51 + * doesn't support playing with the hinting
52 + * algorithm, nothing to do then...
53 + */
54 #endif
55 - break;
56 - case FC_RGBA_VRGB:
57 - case FC_RGBA_VBGR:
58 -#ifdef FT_LOAD_TARGET_LCD_V
59 - fi->load_flags |= FT_LOAD_TARGET_LCD_V;
60 -#endif
61 - break;
62 - }
63 - }
65 #ifdef FT_LOAD_TARGET_MONO
66 else
67 fi->load_flags |= FT_LOAD_TARGET_MONO;
68 #endif
71 /* set vertical layout if requested */
72 switch (FcPatternGetBool (pattern, FC_VERTICAL_LAYOUT, 0, &vertical_layout)) {
73 case FcResultNoMatch:
74 diff -urN src/xftglyphs.c.orig src/xftglyphs.c
75 --- src/xftglyphs.c.orig 2009-01-30 07:19:09.000000000 +0800
76 +++ src/xftglyphs.c 2009-10-12 10:21:40.000000000 +0800
77 @@ -27,6 +27,17 @@
78 #include <freetype/ftsynth.h>
79 #endif
81 +/* define the following macro if you want to use a small FIR filter to
82 + * reduce color fringes for LCD rendering. If undefined, the original
83 + * weird pixel-local color balancing algorithm will be used
84 + */
85 +#define FIR_FILTER
87 +#ifdef FIR_FILTER
88 +/* note: keep the filter symetric, or bad things will happen */
89 +static const int fir_filter[5] = { 0x10, 0x40, 0x70, 0x40, 0x10 };
91 +#else /* !FIR_FILTER */
92 static const int filters[3][3] = {
93 /* red */
94 #if 0
95 @@ -42,6 +53,7 @@
96 /* blue */
97 { 65538*1/13,65538*3/13,65538*9/13 },
99 +#endif /* !FIR_FILTER */
102 * Validate the memory info for a font
103 @@ -133,6 +145,10 @@
105 while (nglyph--)
107 +#ifdef FIR_FILTER
108 + int margin_top = 0, margin_left = 0;
109 +#endif
111 glyphindex = *glyphs++;
112 xftg = font->glyphs[glyphindex];
113 if (!xftg)
114 @@ -171,6 +187,17 @@
116 glyphslot = face->glyph;
118 + if (font->info.embolden &&
119 + glyphslot->format == ft_glyph_format_outline &&
120 + glyphslot->outline.n_points &&
121 + pub->height <= 18 &&
122 + !font->info.antialias &&
123 + !(font->info.load_flags & FT_LOAD_NO_HINTING)) {
124 + error = FT_Render_Glyph (glyphslot, FT_RENDER_MODE_MONO);
125 + if (error)
126 + continue;
129 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
131 * Embolden if required
132 @@ -181,7 +208,7 @@
134 * Compute glyph metrics from FreeType information
136 - if(font->info.transform && glyphslot->format != ft_glyph_format_bitmap)
137 + if(font->info.transform && glyphslot->format != FT_GLYPH_FORMAT_BITMAP)
140 * calculate the true width by transforming all four corners.
141 @@ -260,12 +287,41 @@
145 - if (font->info.antialias)
146 - pitch = (width * hmul + 3) & ~3;
147 - else
148 - pitch = ((width + 31) & ~31) >> 3;
150 - size = pitch * height * vmul;
151 + /* now we're going to adjust the margins of the glyph for LCD filtering */
152 + if (font->info.antialias) {
153 + switch (font->info.rgba) {
154 + case FC_RGBA_RGB:
155 + case FC_RGBA_BGR:
156 +#ifdef FIR_FILTER
157 + margin_left = 1;
158 + left -= 64;
159 + right += 64;
160 + width += 2;
161 +#endif /* FIR_FILTER */
162 + pitch = (width*3+3) & ~3;
163 + size = pitch*height;
164 + break;
166 + case FC_RGBA_VRGB:
167 + case FC_RGBA_VBGR:
168 +#ifdef FIR_FILTER
169 + margin_top = 0;
170 + top += 64;
171 + bottom -= 64;
172 + height += 2;
173 +#endif /* FIR_FILTER */
174 + pitch = (width+3) & ~3;
175 + size = pitch*height*3;
176 + break;
178 + default:
179 + pitch = (width+3) & ~3;
180 + size = pitch*height;
182 + } else {
183 + pitch = ((width+31) & ~31) >> 3;
184 + size = pitch*height;
187 xftg->metrics.width = width;
188 xftg->metrics.height = height;
189 @@ -325,8 +381,10 @@
190 if (bufBitmap != bufLocal)
191 free (bufBitmap);
192 bufBitmap = (unsigned char *) malloc (size);
193 - if (!bufBitmap)
194 + if (!bufBitmap) {
195 + bufBitmap = bufLocal; /* prevent free(NULL) later !! */
196 continue;
198 bufSize = size;
200 memset (bufBitmap, 0, size);
201 @@ -335,7 +393,7 @@
202 * Rasterize into the local buffer
204 switch (glyphslot->format) {
205 - case ft_glyph_format_outline:
206 + case FT_GLYPH_FORMAT_OUTLINE:
207 ftbit.width = width * hmul;
208 ftbit.rows = height * vmul;
209 ftbit.pitch = pitch;
210 @@ -353,35 +411,50 @@
212 FT_Outline_Get_Bitmap( _XftFTlibrary, &glyphslot->outline, &ftbit );
213 break;
214 - case ft_glyph_format_bitmap:
215 + case FT_GLYPH_FORMAT_BITMAP:
216 if (font->info.antialias)
218 unsigned char *srcLine, *dstLine;
219 int height;
220 + int width = glyphslot->bitmap.width;
221 int x;
222 - int h, v;
224 srcLine = glyphslot->bitmap.buffer;
225 - dstLine = bufBitmap;
226 + dstLine = bufBitmap + margin_left + margin_top*pitch;
227 height = glyphslot->bitmap.rows;
228 while (height--)
230 - for (x = 0; x < glyphslot->bitmap.width; x++)
231 + unsigned char* src = srcLine;
232 + unsigned char* dst = dstLine;
233 + unsigned int mask = 0x8080;
235 + for (x = 0; x < width; x++ )
237 - /* always MSB bitmaps */
238 - unsigned char a = ((srcLine[x >> 3] & (0x80 >> (x & 7))) ?
239 - 0xff : 0x00);
240 - if (subpixel)
242 - for (v = 0; v < vmul; v++)
243 - for (h = 0; h < hmul; h++)
244 - dstLine[v * pitch + x*hmul + h] = a;
246 - else
247 - dstLine[x] = a;
249 - dstLine += pitch * vmul;
250 - srcLine += glyphslot->bitmap.pitch;
251 + if ( (src[0] & mask) != 0 ) {
252 + dst[0] = 0xFF;
253 + if ( hmul == 3 ) {
254 + dst[1] = 0xFF;
255 + dst[2] = 0xFF;
259 + mask >>= 1;
260 + if ( (mask & 0x80) != 0 ) {
261 + mask = 0x8080;
262 + src += 1;
266 + if ( vmul == 3 ) {
267 + memcpy( dstLine + pitch, dstLine, width*3 );
268 + dstLine += pitch;
270 + memcpy( dstLine + pitch, dstLine, width*3 );
271 + dstLine += pitch;
274 + dstLine += pitch;
275 + srcLine += width;
278 else
279 @@ -457,74 +530,270 @@
281 if (subpixel)
283 - int x, y;
284 - unsigned char *in_line, *out_line, *in;
285 - unsigned int *out;
286 - unsigned int red, green, blue;
287 - int rf, gf, bf;
288 - int s;
289 - int o, os;
291 - /*
292 - * Filter the glyph to soften the color fringes
293 - */
294 - widthrgba = width;
295 - pitchrgba = (widthrgba * 4 + 3) & ~3;
296 - sizergba = pitchrgba * height;
298 - os = 1;
299 - switch (font->info.rgba) {
300 - case FC_RGBA_VRGB:
301 - os = pitch;
302 - case FC_RGBA_RGB:
303 - default:
304 - rf = 0;
305 - gf = 1;
306 - bf = 2;
307 - break;
308 - case FC_RGBA_VBGR:
309 - os = pitch;
310 - case FC_RGBA_BGR:
311 - bf = 0;
312 - gf = 1;
313 - rf = 2;
314 - break;
316 - if (sizergba > bufSizeRgba)
318 - if (bufBitmapRgba != bufLocalRgba)
319 - free (bufBitmapRgba);
320 - bufBitmapRgba = (unsigned char *) malloc (sizergba);
321 - if (!bufBitmapRgba)
322 - continue;
323 - bufSizeRgba = sizergba;
325 - memset (bufBitmapRgba, 0, sizergba);
326 - in_line = bufBitmap;
327 - out_line = bufBitmapRgba;
328 - for (y = 0; y < height; y++)
330 - in = in_line;
331 - out = (unsigned int *) out_line;
332 - in_line += pitch * vmul;
333 - out_line += pitchrgba;
334 - for (x = 0; x < width * hmul; x += hmul)
336 - red = green = blue = 0;
337 - o = 0;
338 - for (s = 0; s < 3; s++)
340 - red += filters[rf][s]*in[x+o];
341 - green += filters[gf][s]*in[x+o];
342 - blue += filters[bf][s]*in[x+o];
343 - o += os;
345 - red = red / 65536;
346 - green = green / 65536;
347 - blue = blue / 65536;
348 - *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
351 + widthrgba = width;
352 + pitchrgba = (widthrgba * 4 + 3) & ~3;
353 + sizergba = pitchrgba * height;
355 + if (sizergba > bufSizeRgba)
357 + if (bufBitmapRgba != bufLocalRgba)
358 + free (bufBitmapRgba);
359 + bufBitmapRgba = (unsigned char *) malloc (sizergba);
360 + if (!bufBitmapRgba) {
361 + bufBitmapRgba = bufLocalRgba; /* prevent free(NULL) later !! */
362 + continue;
364 + bufSizeRgba = sizergba;
366 + memset (bufBitmapRgba, 0, sizergba);
368 +#ifdef FIR_FILTER
370 + unsigned char* line;
372 + /* perform in-place FIR filtering in either the horizontal or
373 + * vertical direction
374 + */
375 + switch (font->info.rgba) {
376 + case FC_RGBA_RGB:
377 + case FC_RGBA_BGR:
379 + int h;
381 + line = bufBitmap;
382 + for ( h = height; h > 0; h--, line += pitch ) {
383 + int pix[6] = { 0, 0, 0, 0, 0, 0 };
384 + unsigned char* p = line;
385 + unsigned char* limit = line + width*3;
386 + int nn, val, val2;
388 + val = p[0];
389 + for (nn = 0; nn < 3; nn++)
390 + pix[2+nn] += val*fir_filter[nn];
392 + val = p[1];
393 + for (nn = 0; nn < 4; nn++)
394 + pix[1+nn] += val*fir_filter[nn];
396 + p += 2;
398 + for ( ; p < limit; p++ ) {
399 + val = p[0];
400 + for (nn = 0; nn < 5; nn++)
401 + pix[nn] += val*fir_filter[nn];
403 + val2 = pix[0]/255;
404 + if (val2 > 255) val2 = 255;
405 + p[-2] = (unsigned char)val2;
407 + for (nn = 0; nn < 5; nn++)
408 + pix[nn] = pix[nn+1];
410 + for (nn = 0; nn < 2; nn++ ) {
411 + val2 = pix[nn]/255;
412 + if (val2 > 255) val2 = 255;
413 + p[nn-2] = (unsigned char)val2;
417 + break;
419 + case FC_RGBA_VRGB:
420 + case FC_RGBA_VBGR:
422 + int w;
424 + for (w = 0; w < width; w++ ) {
425 + int pix[6] = { 0, 0, 0, 0, 0, 0 };
426 + unsigned char* p = bufBitmap + w;
427 + unsigned char* limit = bufBitmap + w + height*3*pitch;
428 + int nn, val, val2;
430 + val = p[0];
431 + for (nn = 0; nn < 3; nn++)
432 + pix[2+nn] += val*fir_filter[nn];
434 + val = p[pitch];
435 + for (nn = 0; nn < 4; nn++ )
436 + pix[1+nn] += val*fir_filter[nn];
438 + p += 2*pitch;
439 + for ( ; p < limit; p += pitch ) {
440 + val = p[0];
441 + for (nn = 0; nn < 5; nn++ )
442 + pix[nn] += val*fir_filter[nn];
444 + val2 = pix[0]/255;
445 + if (val2 > 255) val2 = 255;
446 + p[-2*pitch] = (unsigned char)val2;
448 + for (nn = 0; nn < 5; nn++)
449 + pix[nn] = pix[nn+1];
452 + for (nn = 0; nn < 2; nn++) {
453 + val2 = pix[nn]/255;
454 + if (val2 > 255) val2 = 255;
455 + p[(nn-2)*pitch] = (unsigned char)val2;
459 + break;
461 + default:
465 + /* now copy the resulting RGB graymap into an ARGB map */
467 + unsigned char* in_line = bufBitmap;
468 + unsigned char* out_line = bufBitmapRgba;
469 + int h;
471 + switch (font->info.rgba) {
472 + case FC_RGBA_RGB:
473 + for (h = height; h > 0; h--) {
474 + unsigned char* in = in_line;
475 + int* out = (int*)out_line;
476 + int w;
478 + for (w = width; w > 0; w--, in += 3, out += 1) {
479 + int r = in[0];
480 + int g = in[1];
481 + int b = in[2];
483 + out[0] = (g << 24) | (r << 16) | (g << 8) | (b);
486 + in_line += pitch;
487 + out_line += pitchrgba;
489 + break;
491 + case FC_RGBA_BGR:
492 + for (h = height; h > 0; h--) {
493 + unsigned char* in = in_line;
494 + int* out = (int*)out_line;
495 + int w;
497 + for (w = width; w > 0; w--, in += 3, out += 1) {
498 + int r = in[0];
499 + int g = in[1];
500 + int b = in[2];
502 + out[0] = (g << 24) | (b << 16) | (g << 8) | (r);
505 + in_line += pitch;
506 + out_line += pitchrgba;
508 + break;
510 + case FC_RGBA_VRGB:
511 + for (h = height; h > 0; h--) {
512 + unsigned char* in = in_line;
513 + unsigned char* out = out_line;
514 + int w;
516 + for (w = width; w > 0; w--, in += 1, out += 4) {
517 + int r = in[0*pitch];
518 + int g = in[1*pitch];
519 + int b = in[2*pitch];
521 + ((int*)out)[0] = (g << 24) | (r << 16) | (g << 8) | (b);
524 + in_line += 3*pitch;
525 + out_line += pitchrgba;
527 + break;
529 + case FC_RGBA_VBGR:
530 + for (h = height; h > 0; h--) {
531 + unsigned char* in = in_line;
532 + unsigned char* out = out_line;
533 + int w;
535 + for (w = width; w > 0; w--, in += 1, out += 4) {
536 + int r = in[0*pitch];
537 + int g = in[1*pitch];
538 + int b = in[2*pitch];
540 + ((int*)out)[0] = (g << 24) | (b << 16) | (g << 8) | (r);
543 + in_line += 3*pitch;
544 + out_line += pitchrgba;
546 + break;
548 + default:
553 +#else /* !FIR_FILTER */
555 + int x, y;
556 + unsigned char *in_line, *out_line, *in;
557 + unsigned int *out;
558 + unsigned int red, green, blue;
559 + int rf, gf, bf;
560 + int s;
561 + int o, os;
563 + /*
564 + * Filter the glyph to soften the color fringes
565 + */
566 + widthrgba = width;
567 + pitchrgba = (widthrgba * 4 + 3) & ~3;
568 + sizergba = pitchrgba * height;
570 + os = 1;
571 + switch (font->info.rgba) {
572 + case FC_RGBA_VRGB:
573 + os = pitch;
574 + case FC_RGBA_RGB:
575 + default:
576 + rf = 0;
577 + gf = 1;
578 + bf = 2;
579 + break;
580 + case FC_RGBA_VBGR:
581 + os = pitch;
582 + case FC_RGBA_BGR:
583 + bf = 0;
584 + gf = 1;
585 + rf = 2;
586 + break;
588 + in_line = bufBitmap;
589 + out_line = bufBitmapRgba;
590 + for (y = 0; y < height; y++)
592 + in = in_line;
593 + out = (unsigned int *) out_line;
594 + in_line += pitch * vmul;
595 + out_line += pitchrgba;
596 + for (x = 0; x < width * hmul; x += hmul)
598 + red = green = blue = 0;
599 + o = 0;
600 + for (s = 0; s < 3; s++)
602 + red += filters[rf][s]*in[x+o];
603 + green += filters[gf][s]*in[x+o];
604 + blue += filters[bf][s]*in[x+o];
605 + o += os;
607 + red = red / 65536;
608 + green = green / 65536;
609 + blue = blue / 65536;
610 + *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
614 +#endif /* !FIR_FILTER */
616 xftg->glyph_memory = sizergba + sizeof (XftGlyph);
617 if (font->format)