1 diff -uNr libXft-2.1.14-orig/src/xftfreetype.c libXft-2.1.14/src/xftfreetype.c
2 --- libXft-2.1.14-orig/src/xftfreetype.c 2009-01-30 00:19:09.000000000 +0100
3 +++ libXft-2.1.14/src/xftfreetype.c 2009-10-23 00:31:07.688061451 +0200
7 #ifdef FT_LOAD_TARGET_LIGHT
8 - if (FC_HINT_NONE < hint_style && hint_style < FC_HINT_FULL)
10 - fi->load_flags |= FT_LOAD_TARGET_LIGHT;
16 - /* autohinter will snap stems to integer widths, when
17 - * the LCD targets are used.
22 -#ifdef FT_LOAD_TARGET_LCD
23 - fi->load_flags |= FT_LOAD_TARGET_LCD;
24 + switch ( hint_style )
26 + case FC_HINT_SLIGHT:
27 + fi->load_flags |= FT_LOAD_TARGET_LIGHT;
34 + fi->load_flags |= FT_LOAD_TARGET_LCD;
38 + fi->load_flags |= FT_LOAD_TARGET_LCD_V;
46 + default: /* FC_HINT_MEDIUM */
47 + ; /* nothing => FT_LOAD_TARGET_NORMAL */
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...
58 -#ifdef FT_LOAD_TARGET_LCD_V
59 - fi->load_flags |= FT_LOAD_TARGET_LCD_V;
65 #ifdef FT_LOAD_TARGET_MONO
67 fi->load_flags |= FT_LOAD_TARGET_MONO;
71 /* set vertical layout if requested */
72 switch (FcPatternGetBool (pattern, FC_VERTICAL_LAYOUT, 0, &vertical_layout)) {
74 diff -uNr libXft-2.1.14-orig/src/xftglyphs.c libXft-2.1.14/src/xftglyphs.c
75 --- libXft-2.1.14-orig/src/xftglyphs.c 2009-01-30 00:19:09.000000000 +0100
76 +++ libXft-2.1.14/src/xftglyphs.c 2009-10-23 00:31:07.688061451 +0200
78 #include <freetype/ftsynth.h>
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
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] = {
97 { 65538*1/13,65538*3/13,65538*9/13 },
99 +#endif /* !FIR_FILTER */
102 * Validate the memory info for a font
108 + int margin_top = 0, margin_left = 0;
111 glyphindex = *glyphs++;
112 xftg = font->glyphs[glyphindex];
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);
129 #if HAVE_FT_GLYPHSLOT_EMBOLDEN
131 * Embolden if required
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;
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) {
161 +#endif /* FIR_FILTER */
162 + pitch = (width*3+3) & ~3;
163 + size = pitch*height;
173 +#endif /* FIR_FILTER */
174 + pitch = (width+3) & ~3;
175 + size = pitch*height*3;
179 + pitch = (width+3) & ~3;
180 + size = pitch*height;
183 + pitch = ((width+31) & ~31) >> 3;
184 + size = pitch*height;
187 xftg->metrics.width = width;
188 xftg->metrics.height = height;
190 if (bufBitmap != bufLocal)
192 bufBitmap = (unsigned char *) malloc (size);
195 + bufBitmap = bufLocal; /* prevent free(NULL) later !! */
200 memset (bufBitmap, 0, size);
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;
210 @@ -353,35 +411,50 @@
212 FT_Outline_Get_Bitmap( _XftFTlibrary, &glyphslot->outline, &ftbit );
214 - case ft_glyph_format_bitmap:
215 + case FT_GLYPH_FORMAT_BITMAP:
216 if (font->info.antialias)
218 unsigned char *srcLine, *dstLine;
220 + int width = glyphslot->bitmap.width;
224 srcLine = glyphslot->bitmap.buffer;
225 - dstLine = bufBitmap;
226 + dstLine = bufBitmap + margin_left + margin_top*pitch;
227 height = glyphslot->bitmap.rows;
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))) ?
242 - for (v = 0; v < vmul; v++)
243 - for (h = 0; h < hmul; h++)
244 - dstLine[v * pitch + x*hmul + h] = a;
249 - dstLine += pitch * vmul;
250 - srcLine += glyphslot->bitmap.pitch;
251 + if ( (src[0] & mask) != 0 ) {
260 + if ( (mask & 0x80) != 0 ) {
267 + memcpy( dstLine + pitch, dstLine, width*3 );
270 + memcpy( dstLine + pitch, dstLine, width*3 );
279 @@ -457,74 +530,270 @@
284 - unsigned char *in_line, *out_line, *in;
286 - unsigned int red, green, blue;
292 - * Filter the glyph to soften the color fringes
295 - pitchrgba = (widthrgba * 4 + 3) & ~3;
296 - sizergba = pitchrgba * height;
299 - switch (font->info.rgba) {
316 - if (sizergba > bufSizeRgba)
318 - if (bufBitmapRgba != bufLocalRgba)
319 - free (bufBitmapRgba);
320 - bufBitmapRgba = (unsigned char *) malloc (sizergba);
321 - if (!bufBitmapRgba)
323 - bufSizeRgba = sizergba;
325 - memset (bufBitmapRgba, 0, sizergba);
326 - in_line = bufBitmap;
327 - out_line = bufBitmapRgba;
328 - for (y = 0; y < height; y++)
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;
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];
346 - green = green / 65536;
347 - blue = blue / 65536;
348 - *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
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 !! */
364 + bufSizeRgba = sizergba;
366 + memset (bufBitmapRgba, 0, sizergba);
370 + unsigned char* line;
372 + /* perform in-place FIR filtering in either the horizontal or
373 + * vertical direction
375 + switch (font->info.rgba) {
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;
389 + for (nn = 0; nn < 3; nn++)
390 + pix[2+nn] += val*fir_filter[nn];
393 + for (nn = 0; nn < 4; nn++)
394 + pix[1+nn] += val*fir_filter[nn];
398 + for ( ; p < limit; p++ ) {
400 + for (nn = 0; nn < 5; nn++)
401 + pix[nn] += val*fir_filter[nn];
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;
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;
431 + for (nn = 0; nn < 3; nn++)
432 + pix[2+nn] += val*fir_filter[nn];
435 + for (nn = 0; nn < 4; nn++ )
436 + pix[1+nn] += val*fir_filter[nn];
439 + for ( ; p < limit; p += pitch ) {
441 + for (nn = 0; nn < 5; nn++ )
442 + pix[nn] += val*fir_filter[nn];
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;
465 + /* now copy the resulting RGB graymap into an ARGB map */
467 + unsigned char* in_line = bufBitmap;
468 + unsigned char* out_line = bufBitmapRgba;
471 + switch (font->info.rgba) {
473 + for (h = height; h > 0; h--) {
474 + unsigned char* in = in_line;
475 + int* out = (int*)out_line;
478 + for (w = width; w > 0; w--, in += 3, out += 1) {
483 + out[0] = (g << 24) | (r << 16) | (g << 8) | (b);
487 + out_line += pitchrgba;
492 + for (h = height; h > 0; h--) {
493 + unsigned char* in = in_line;
494 + int* out = (int*)out_line;
497 + for (w = width; w > 0; w--, in += 3, out += 1) {
502 + out[0] = (g << 24) | (b << 16) | (g << 8) | (r);
506 + out_line += pitchrgba;
511 + for (h = height; h > 0; h--) {
512 + unsigned char* in = in_line;
513 + unsigned char* out = out_line;
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;
530 + for (h = height; h > 0; h--) {
531 + unsigned char* in = in_line;
532 + unsigned char* out = out_line;
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;
553 +#else /* !FIR_FILTER */
556 + unsigned char *in_line, *out_line, *in;
558 + unsigned int red, green, blue;
564 + * Filter the glyph to soften the color fringes
567 + pitchrgba = (widthrgba * 4 + 3) & ~3;
568 + sizergba = pitchrgba * height;
571 + switch (font->info.rgba) {
588 + in_line = bufBitmap;
589 + out_line = bufBitmapRgba;
590 + for (y = 0; y < height; y++)
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;
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];
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);