]> git.pld-linux.org Git - packages/cairo.git/blame - cairo-1.2.4-lcd-filter-1.patch
- release 2
[packages/cairo.git] / cairo-1.2.4-lcd-filter-1.patch
CommitLineData
33282416
JB
1--- cairo-1.4.12/src/cairo-ft-font.c.orig 2007-11-27 07:20:12.000000000 +0100
2+++ cairo-1.4.12/src/cairo-ft-font.c 2007-11-28 19:54:09.894901361 +0100
bc624305 3@@ -55,6 +55,8 @@
6e13550b 4 #include FT_SYNTHESIS_H
5 #endif
6
7+#include FT_LCD_FILTER_H
8+
9 #define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
10 #define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
11 #define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
33282416 12@@ -702,23 +704,300 @@
bc624305 13 return CAIRO_STATUS_SUCCESS;
6e13550b 14 }
15
16-/* Empirically-derived subpixel filtering values thanks to Keith
17- * Packard and libXft. */
18-static const int filters[3][3] = {
19- /* red */
20-#if 0
21- { 65538*4/7,65538*2/7,65538*1/7 },
22- /* green */
23- { 65536*1/4, 65536*2/4, 65537*1/4 },
24- /* blue */
25- { 65538*1/7,65538*2/7,65538*4/7 },
26+/* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot
27+ * into a different format. For example, we want to convert a
28+ * FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit
29+ * ARGB or ABGR bitmap.
30+ *
31+ * this function prepares a target descriptor for this operation.
32+ *
33+ * input :: target bitmap descriptor. The function will set its
34+ * 'width', 'rows' and 'pitch' fields, and only these
35+ *
36+ * slot :: the glyph slot containing the source bitmap. this
37+ * function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP
38+ *
39+ * mode :: the requested final rendering mode. supported values are
40+ * MONO, NORMAL (i.e. gray), LCD and LCD_V
41+ *
42+ * the function returns the size in bytes of the corresponding buffer,
43+ * it's up to the caller to allocate the corresponding memory block
44+ * before calling _fill_xrender_bitmap
45+ *
46+ * it also returns -1 in case of error (e.g. incompatible arguments,
47+ * like trying to convert a gray bitmap into a monochrome one)
48+ */
49+static int
50+_compute_xrender_bitmap_size( FT_Bitmap* target,
51+ FT_GlyphSlot slot,
52+ FT_Render_Mode mode )
53+{
54+ FT_Bitmap* ftbit;
55+ int width, height, pitch;
56+
57+ if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
58+ return -1;
59+
60+ // compute the size of the final bitmap
61+ ftbit = &slot->bitmap;
62+
63+ width = ftbit->width;
64+ height = ftbit->rows;
65+ pitch = (width+3) & ~3;
66+
67+ switch ( ftbit->pixel_mode )
68+ {
69+ case FT_PIXEL_MODE_MONO:
70+ if ( mode == FT_RENDER_MODE_MONO )
71+ {
72+ pitch = (((width+31) & ~31) >> 3);
73+ break;
74+ }
75+ /* fall-through */
76+
77+ case FT_PIXEL_MODE_GRAY:
78+ if ( mode == FT_RENDER_MODE_LCD ||
79+ mode == FT_RENDER_MODE_LCD_V )
80+ {
81+ /* each pixel is replicated into a 32-bit ARGB value */
82+ pitch = width*4;
83+ }
84+ break;
85+
86+ case FT_PIXEL_MODE_LCD:
87+ if ( mode != FT_RENDER_MODE_LCD )
88+ return -1;
89+
90+ /* horz pixel triplets are packed into 32-bit ARGB values */
91+ width /= 3;
92+ pitch = width*4;
93+ break;
94+
95+ case FT_PIXEL_MODE_LCD_V:
96+ if ( mode != FT_RENDER_MODE_LCD_V )
97+ return -1;
98+
99+ /* vert pixel triplets are packed into 32-bit ARGB values */
100+ height /= 3;
101+ pitch = width*4;
102+ break;
103+
104+ default: /* unsupported source format */
105+ return -1;
106+ }
107+
108+ target->width = width;
109+ target->rows = height;
110+ target->pitch = pitch;
111+ target->buffer = NULL;
112+
113+ return pitch * height;
114+}
115+
116+/* this functions converts the glyph bitmap found in a FT_GlyphSlot
117+ * into a different format (see _compute_xrender_bitmap_size)
118+ *
119+ * you should call this function after _compute_xrender_bitmap_size
120+ *
121+ * target :: target bitmap descriptor. Note that its 'buffer' pointer
122+ * must point to memory allocated by the caller
123+ *
124+ * slot :: the glyph slot containing the source bitmap
125+ *
126+ * mode :: the requested final rendering mode
127+ *
128+ * bgr :: boolean, set if BGR or VBGR pixel ordering is needed
129+ */
130+static void
131+_fill_xrender_bitmap( FT_Bitmap* target,
132+ FT_GlyphSlot slot,
133+ FT_Render_Mode mode,
134+ int bgr )
135+{
136+ FT_Bitmap* ftbit = &slot->bitmap;
137+ unsigned char* srcLine = ftbit->buffer;
138+ unsigned char* dstLine = target->buffer;
139+ int src_pitch = ftbit->pitch;
140+ int width = target->width;
141+ int height = target->rows;
142+ int pitch = target->pitch;
143+ int subpixel;
144+ int h;
145+
146+ subpixel = ( mode == FT_RENDER_MODE_LCD ||
147+ mode == FT_RENDER_MODE_LCD_V );
148+
149+ if ( src_pitch < 0 )
150+ srcLine -= src_pitch*(ftbit->rows-1);
151+
152+ target->pixel_mode = ftbit->pixel_mode;
153+
154+ switch ( ftbit->pixel_mode )
155+ {
156+ case FT_PIXEL_MODE_MONO:
157+ if ( subpixel ) /* convert mono to ARGB32 values */
158+ {
159+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
160+ {
161+ int x;
162+
163+ for ( x = 0; x < width; x++ )
164+ {
165+ if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
166+ ((unsigned int*)dstLine)[x] = 0xffffffffU;
167+ }
168+ }
169+ target->pixel_mode = FT_PIXEL_MODE_LCD;
170+ }
171+ else if ( mode == FT_RENDER_MODE_NORMAL ) /* convert mono to 8-bit gray */
172+ {
173+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
174+ {
175+ int x;
176+
177+ for ( x = 0; x < width; x++ )
178+ {
179+ if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
180+ dstLine[x] = 0xff;
181+ }
182+ }
183+ target->pixel_mode = FT_PIXEL_MODE_GRAY;
184+ }
185+ else /* copy mono to mono */
186+ {
187+ int bytes = (width+7) >> 3;
188+
189+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
190+ memcpy( dstLine, srcLine, bytes );
191+ }
192+ break;
193+
194+ case FT_PIXEL_MODE_GRAY:
195+ if ( subpixel ) /* convert gray to ARGB32 values */
196+ {
197+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
198+ {
199+ int x;
200+ unsigned int* dst = (unsigned int*)dstLine;
201+
202+ for ( x = 0; x < width; x++ )
203+ {
204+ unsigned int pix = srcLine[x];
205+
206+ pix |= (pix << 8);
207+ pix |= (pix << 16);
208+
209+ dst[x] = pix;
210+ }
211+ }
212+ target->pixel_mode = FT_PIXEL_MODE_LCD;
213+ }
214+ else /* copy gray into gray */
215+ {
216+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
217+ memcpy( dstLine, srcLine, width );
218+ }
219+ break;
220+
221+ case FT_PIXEL_MODE_LCD:
222+ if ( !bgr )
223+ {
224+ /* convert horizontal RGB into ARGB32 */
225+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
226+ {
227+ int x;
228+ unsigned char* src = srcLine;
229+ unsigned int* dst = (unsigned int*)dstLine;
230+
231+ for ( x = 0; x < width; x++, src += 3 )
232+ {
233+ unsigned int pix;
234+
235+ pix = ((unsigned int)src[0] << 16) |
236+ ((unsigned int)src[1] << 8) |
237+ ((unsigned int)src[2] ) |
238+ ((unsigned int)src[1] << 24) ;
239+
240+ dst[x] = pix;
241+ }
242+ }
243+ }
244+ else
245+ {
246+ /* convert horizontal BGR into ARGB32 */
247+ for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
248+ {
249+ int x;
250+ unsigned char* src = srcLine;
251+ unsigned int* dst = (unsigned int*)dstLine;
252+
253+ for ( x = 0; x < width; x++, src += 3 )
254+ {
255+ unsigned int pix;
256+
257+ pix = ((unsigned int)src[2] << 16) |
258+ ((unsigned int)src[1] << 8) |
259+ ((unsigned int)src[0] ) |
260+ ((unsigned int)src[1] << 24) ;
261+
262+ dst[x] = pix;
263+ }
264+ }
265+ }
266+ break;
267+
268+ default: /* FT_PIXEL_MODE_LCD_V */
269+ /* convert vertical RGB into ARGB32 */
270+ if ( !bgr )
271+ {
272+ for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
273+ {
274+ int x;
275+ unsigned char* src = srcLine;
276+ unsigned int* dst = (unsigned int*)dstLine;
277+
278+ for ( x = 0; x < width; x++, src += 1 )
279+ {
280+ unsigned int pix;
281+#if 1
282+ pix = ((unsigned int)src[0] << 16) |
283+ ((unsigned int)src[src_pitch] << 8) |
284+ ((unsigned int)src[src_pitch*2] ) |
285+ 0xFF000000 ;
286+#else
287+ pix = ((unsigned int)src[0] << 16) |
288+ ((unsigned int)src[src_pitch] << 8) |
289+ ((unsigned int)src[src_pitch*2] ) |
290+ ((unsigned int)src[src_pitch] << 24) ;
291 #endif
292- { 65538*9/13,65538*3/13,65538*1/13 },
293- /* green */
294- { 65538*1/6, 65538*4/6, 65538*1/6 },
295- /* blue */
296- { 65538*1/13,65538*3/13,65538*9/13 },
297-};
298+ dst[x] = pix;
299+ }
300+ }
301+ }
302+ else
303+ {
304+ for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
305+ {
306+ int x;
307+ unsigned char* src = srcLine;
308+ unsigned int* dst = (unsigned int*)dstLine;
309+
310+ for ( x = 0; x < width; x++, src += 1 )
311+ {
312+ unsigned int pix;
313+
314+ pix = ((unsigned int)src[src_pitch*2] << 16) |
315+ ((unsigned int)src[src_pitch] << 8) |
316+ ((unsigned int)src[0] ) |
317+ ((unsigned int)src[src_pitch] << 24) ;
318+
319+ dst[x] = pix;
320+ }
321+ }
322+ }
323+ }
324+}
325+
326
327 /* Fills in val->image with an image surface created from @bitmap
328 */
33282416 329@@ -731,7 +1010,7 @@
6e13550b 330 int width, height, stride;
331 unsigned char *data;
332 int format = CAIRO_FORMAT_A8;
333- cairo_bool_t subpixel = FALSE;
334+ cairo_image_surface_t *image;
335
336 width = bitmap->width;
337 height = bitmap->rows;
33282416 338@@ -772,7 +1051,6 @@
6e13550b 339 }
340 }
341 }
342-
343 #ifndef WORDS_BIGENDIAN
344 {
345 unsigned char *d = data;
33282416 346@@ -784,17 +1062,15 @@
6e13550b 347 }
348 }
349 #endif
350+
351 format = CAIRO_FORMAT_A1;
352 break;
353
354 case FT_PIXEL_MODE_LCD:
355 case FT_PIXEL_MODE_LCD_V:
356 case FT_PIXEL_MODE_GRAY:
357- switch (font_options->antialias) {
358- case CAIRO_ANTIALIAS_DEFAULT:
359- case CAIRO_ANTIALIAS_GRAY:
360- case CAIRO_ANTIALIAS_NONE:
361- default:
362+ if (font_options->antialias != CAIRO_ANTIALIAS_SUBPIXEL)
363+ {
364 stride = bitmap->pitch;
365 if (own_buffer) {
366 data = bitmap->buffer;
33282416 367@@ -807,105 +1083,16 @@
6e13550b 368 memcpy (data, bitmap->buffer, stride * height);
369 }
370 format = CAIRO_FORMAT_A8;
371- break;
372- case CAIRO_ANTIALIAS_SUBPIXEL: {
373- int x, y;
374- unsigned char *in_line, *out_line, *in;
375- unsigned int *out;
376- unsigned int red, green, blue;
377- int rf, gf, bf;
378- int s;
379- int o, os;
380- unsigned char *data_rgba;
381- unsigned int width_rgba, stride_rgba;
382- int vmul = 1;
383- int hmul = 1;
96b7cd00 384-
6e13550b 385- switch (font_options->subpixel_order) {
386- case CAIRO_SUBPIXEL_ORDER_DEFAULT:
387- case CAIRO_SUBPIXEL_ORDER_RGB:
388- case CAIRO_SUBPIXEL_ORDER_BGR:
389- default:
390- width /= 3;
391- hmul = 3;
392- break;
393- case CAIRO_SUBPIXEL_ORDER_VRGB:
394- case CAIRO_SUBPIXEL_ORDER_VBGR:
395- vmul = 3;
396- height /= 3;
397- break;
398- }
399- /*
400- * Filter the glyph to soften the color fringes
401- */
402- width_rgba = width;
bc624305 403- stride = bitmap->pitch;
6e13550b 404- stride_rgba = (width_rgba * 4 + 3) & ~3;
33282416 405- data_rgba = calloc (stride_rgba, height);
96b7cd00
AM
406- if (data_rgba == NULL) {
407- if (own_buffer)
408- free (bitmap->buffer);
bc624305 409- _cairo_error (CAIRO_STATUS_NO_MEMORY);
96b7cd00
AM
410- return CAIRO_STATUS_NO_MEMORY;
411- }
33282416
JB
412+ } else {
413+ // if we get there, the data from the source bitmap
414+ // really comes from _fill_xrender_bitmap, and is
415+ // made of 32-bit ARGB or ABGR values
416+ assert(own_buffer != 0);
417+ assert(bitmap->pixel_mode != FT_PIXEL_MODE_GRAY);
418
6e13550b 419- os = 1;
420- switch (font_options->subpixel_order) {
421- case CAIRO_SUBPIXEL_ORDER_VRGB:
422- os = stride;
423- case CAIRO_SUBPIXEL_ORDER_DEFAULT:
424- case CAIRO_SUBPIXEL_ORDER_RGB:
425- default:
426- rf = 0;
427- gf = 1;
428- bf = 2;
429- break;
430- case CAIRO_SUBPIXEL_ORDER_VBGR:
431- os = stride;
432- case CAIRO_SUBPIXEL_ORDER_BGR:
433- bf = 0;
434- gf = 1;
435- rf = 2;
436- break;
437- }
438- in_line = bitmap->buffer;
439- out_line = data_rgba;
440- for (y = 0; y < height; y++)
441- {
442- in = in_line;
443- out = (unsigned int *) out_line;
444- in_line += stride * vmul;
445- out_line += stride_rgba;
446- for (x = 0; x < width * hmul; x += hmul)
447- {
448- red = green = blue = 0;
449- o = 0;
450- for (s = 0; s < 3; s++)
451- {
452- red += filters[rf][s]*in[x+o];
453- green += filters[gf][s]*in[x+o];
454- blue += filters[bf][s]*in[x+o];
455- o += os;
456- }
457- red = red / 65536;
458- green = green / 65536;
459- blue = blue / 65536;
460- *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
461- }
462- }
33282416 463-
6e13550b 464- /* Images here are stored in native format. The
465- * backend must convert to its own format as needed
466- */
467-
468- if (own_buffer)
469- free (bitmap->buffer);
470- data = data_rgba;
471- stride = stride_rgba;
bc624305
JB
472+ data = bitmap->buffer;
473+ stride = bitmap->pitch;
6e13550b 474 format = CAIRO_FORMAT_ARGB32;
475- subpixel = TRUE;
476- break;
477- }
478 }
479 break;
6e13550b 480 case FT_PIXEL_MODE_GRAY2:
33282416 481@@ -918,19 +1105,20 @@
6e13550b 482 return CAIRO_STATUS_NO_MEMORY;
483 }
484
485- *surface = (cairo_image_surface_t *)
486+ /* XXX */
487+ *surface = image = (cairo_image_surface_t *)
488 cairo_image_surface_create_for_data (data,
489 format,
490 width, height, stride);
491- if ((*surface)->base.status) {
492+ if (image->base.status) {
493 free (data);
494 return CAIRO_STATUS_NO_MEMORY;
495 }
496
497- if (subpixel)
498- pixman_image_set_component_alpha ((*surface)->pixman_image, TRUE);
6e13550b 499+ if (font_options->antialias == CAIRO_ANTIALIAS_SUBPIXEL)
500+ pixman_image_set_component_alpha (image->pixman_image, TRUE);
501
33282416 502- _cairo_image_surface_assume_ownership_of_data ((*surface));
6e13550b 503+ _cairo_image_surface_assume_ownership_of_data (image);
33282416 504
6e13550b 505 return CAIRO_STATUS_SUCCESS;
506 }
33282416 507@@ -955,16 +1143,44 @@
6e13550b 508 cairo_font_options_t *font_options,
509 cairo_image_surface_t **surface)
510 {
511+ int rgba = FC_RGBA_UNKNOWN;
512 FT_GlyphSlot glyphslot = face->glyph;
513 FT_Outline *outline = &glyphslot->outline;
514 FT_Bitmap bitmap;
515 FT_BBox cbox;
516- FT_Matrix matrix;
517- int hmul = 1;
518- int vmul = 1;
519 unsigned int width, height, stride;
520- cairo_bool_t subpixel = FALSE;
521+ cairo_format_t format;
522 cairo_status_t status;
523+ FT_Error fterror;
524+ FT_Library library = glyphslot->library;
525+ FT_Render_Mode render_mode = FT_RENDER_MODE_NORMAL;
526+
527+ switch (font_options->antialias)
528+ {
529+ case CAIRO_ANTIALIAS_NONE:
530+ render_mode = FT_RENDER_MODE_MONO;
531+ break;
532+
533+ case CAIRO_ANTIALIAS_SUBPIXEL:
534+ switch (font_options->subpixel_order)
535+ {
536+ case CAIRO_SUBPIXEL_ORDER_DEFAULT:
537+ case CAIRO_SUBPIXEL_ORDER_RGB:
538+ case CAIRO_SUBPIXEL_ORDER_BGR:
539+ render_mode = FT_RENDER_MODE_LCD;
540+ break;
541+
542+ case CAIRO_SUBPIXEL_ORDER_VRGB:
543+ case CAIRO_SUBPIXEL_ORDER_VBGR:
544+ render_mode = FT_RENDER_MODE_LCD_V;
545+ break;
546+ }
547+ break;
548+
549+ case CAIRO_ANTIALIAS_DEFAULT:
550+ case CAIRO_ANTIALIAS_GRAY:
551+ render_mode = FT_RENDER_MODE_NORMAL;
552+ }
553
554 FT_Outline_Get_CBox (outline, &cbox);
555
33282416 556@@ -975,20 +1191,19 @@
6e13550b 557
558 width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);
559 height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);
560- stride = (width * hmul + 3) & ~3;
561+ stride = (width + 3) & ~3;
562
563 if (width * height == 0) {
564- cairo_format_t format;
565 /* Looks like fb handles zero-sized images just fine */
566- switch (font_options->antialias) {
567- case CAIRO_ANTIALIAS_NONE:
568+ switch (render_mode)
569+ {
570+ case FT_RENDER_MODE_MONO:
571 format = CAIRO_FORMAT_A1;
572 break;
573- case CAIRO_ANTIALIAS_SUBPIXEL:
574- format= CAIRO_FORMAT_ARGB32;
575+ case FT_RENDER_MODE_LCD:
576+ case FT_RENDER_MODE_LCD_V:
577+ format = CAIRO_FORMAT_ARGB32;
578 break;
579- case CAIRO_ANTIALIAS_DEFAULT:
580- case CAIRO_ANTIALIAS_GRAY:
581 default:
582 format = CAIRO_FORMAT_A8;
33282416
JB
583 break;
584@@ -1000,75 +1215,70 @@
6e13550b 585 return CAIRO_STATUS_NO_MEMORY;
6e13550b 586 } else {
587
588- matrix.xx = matrix.yy = 0x10000L;
589- matrix.xy = matrix.yx = 0;
590+ int bitmap_size;
591
592- switch (font_options->antialias) {
593- case CAIRO_ANTIALIAS_NONE:
594- bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
595- bitmap.num_grays = 1;
596- stride = ((width + 31) & -32) >> 3;
597+ switch (render_mode)
598+ {
599+ case FT_RENDER_MODE_LCD:
600+ if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_BGR ) {
601+ rgba = FC_RGBA_BGR;
602+ } else {
603+ rgba = FC_RGBA_RGB;
604+ }
605 break;
606- case CAIRO_ANTIALIAS_DEFAULT:
607- case CAIRO_ANTIALIAS_GRAY:
608- bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
609- bitmap.num_grays = 256;
610- stride = (width + 3) & -4;
6e13550b 611+ case FT_RENDER_MODE_LCD_V:
612+ if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_VBGR ) {
613+ rgba = FC_RGBA_VBGR;
614+ } else {
615+ rgba = FC_RGBA_VRGB;
616+ }
617 break;
618- case CAIRO_ANTIALIAS_SUBPIXEL:
619- switch (font_options->subpixel_order) {
620- case CAIRO_SUBPIXEL_ORDER_RGB:
621- case CAIRO_SUBPIXEL_ORDER_BGR:
622- case CAIRO_SUBPIXEL_ORDER_DEFAULT:
6e13550b 623 default:
624- matrix.xx *= 3;
625- hmul = 3;
626- subpixel = TRUE;
33282416 627 break;
6e13550b 628- case CAIRO_SUBPIXEL_ORDER_VRGB:
629- case CAIRO_SUBPIXEL_ORDER_VBGR:
630- matrix.yy *= 3;
631- vmul = 3;
632- subpixel = TRUE;
633- break;
33282416 634- }
6e13550b 635- FT_Outline_Transform (outline, &matrix);
33282416 636-
6e13550b 637- bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
638- bitmap.num_grays = 256;
639- stride = (width * hmul + 3) & -4;
33282416 640 }
6e13550b 641
642- bitmap.pitch = stride;
643- bitmap.width = width * hmul;
644- bitmap.rows = height * vmul;
33282416
JB
645- bitmap.buffer = calloc (stride, bitmap.rows);
646+ FT_Library_SetLcdFilter( library, FT_LCD_FILTER_DEFAULT );
647+
6e13550b 648+ fterror = FT_Render_Glyph( face->glyph, render_mode );
649
650- if (bitmap.buffer == NULL) {
651+ FT_Library_SetLcdFilter( library, FT_LCD_FILTER_NONE );
652+
bc624305
JB
653+ if (fterror != 0) {
654 _cairo_error (CAIRO_STATUS_NO_MEMORY);
6e13550b 655 return CAIRO_STATUS_NO_MEMORY;
bc624305 656 }
6e13550b 657
658- FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);
659+ bitmap_size = _compute_xrender_bitmap_size( &bitmap,
660+ face->glyph,
661+ render_mode );
bc624305
JB
662+ if ( bitmap_size < 0 ) {
663+ _cairo_error (CAIRO_STATUS_NO_MEMORY);
6e13550b 664+ return CAIRO_STATUS_NO_MEMORY;
bc624305 665+ }
6e13550b 666
667- if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) {
6e13550b 668+ bitmap.buffer = calloc(1, bitmap_size);
669+ if (bitmap.buffer == NULL) {
33282416 670 free (bitmap.buffer);
bc624305 671 _cairo_error (CAIRO_STATUS_NO_MEMORY);
6e13550b 672 return CAIRO_STATUS_NO_MEMORY;
673 }
674
675+ _fill_xrender_bitmap( &bitmap, face->glyph, render_mode,
676+ (rgba == FC_RGBA_BGR || rgba == FC_RGBA_VBGR) );
677+
678+ // NOTE: _get_bitmap_surface will free bitmap.buffer if there is an error
679 status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
680 if (status)
681 return status;
682- }
683
684 /*
685 * Note: the font's coordinate system is upside down from ours, so the
686 * Y coordinate of the control box needs to be negated.
687 */
688 cairo_surface_set_device_offset (&(*surface)->base,
689- floor ((double) cbox.xMin / 64.0),
690- floor (-(double) cbox.yMax / 64.0));
691+ (double) glyphslot->bitmap_left,
692+ (double)-glyphslot->bitmap_top);
693+ }
694
695 return CAIRO_STATUS_SUCCESS;
696 }
33282416 697@@ -1442,11 +1652,11 @@
6e13550b 698 case CAIRO_SUBPIXEL_ORDER_DEFAULT:
699 case CAIRO_SUBPIXEL_ORDER_RGB:
700 case CAIRO_SUBPIXEL_ORDER_BGR:
701- load_target |= FT_LOAD_TARGET_LCD;
702+ load_target = FT_LOAD_TARGET_LCD;
703 break;
704 case CAIRO_SUBPIXEL_ORDER_VRGB:
705 case CAIRO_SUBPIXEL_ORDER_VBGR:
706- load_target |= FT_LOAD_TARGET_LCD_V;
707+ load_target = FT_LOAD_TARGET_LCD_V;
708 break;
709 }
710 }
This page took 0.139652 seconds and 4 git commands to generate.