Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 182613 | Differences between
and this patch

Collapse All | Expand All

(-)cairo-1.4.8/src/cairo-ft-font.c.orig (-185 / +399 lines)
Lines 55-60 Link Here
55
#include FT_SYNTHESIS_H
55
#include FT_SYNTHESIS_H
56
#endif
56
#endif
57
57
58
#include FT_LCD_FILTER_H
59
58
#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
60
#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0))
59
#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
61
#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0)
60
#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
62
#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0))
Lines 701-723 Link Here
701
    return CAIRO_STATUS_SUCCESS;
703
    return CAIRO_STATUS_SUCCESS;
702
}
704
}
703
705
704
/* Empirically-derived subpixel filtering values thanks to Keith
706
/* we sometimes need to convert the glyph bitmap in a FT_GlyphSlot
705
 * Packard and libXft. */
707
 * into a different format. For example, we want to convert a
706
static const int    filters[3][3] = {
708
 * FT_PIXEL_MODE_LCD or FT_PIXEL_MODE_LCD_V bitmap into a 32-bit
707
    /* red */
709
 * ARGB or ABGR bitmap.
708
#if 0
710
 *
709
    {    65538*4/7,65538*2/7,65538*1/7 },
711
 * this function prepares a target descriptor for this operation.
710
    /* green */
712
 *
711
    {    65536*1/4, 65536*2/4, 65537*1/4 },
713
 * input :: target bitmap descriptor. The function will set its
712
    /* blue */
714
 *          'width', 'rows' and 'pitch' fields, and only these
713
    {    65538*1/7,65538*2/7,65538*4/7 },
715
 *
716
 * slot  :: the glyph slot containing the source bitmap. this
717
 *          function assumes that slot->format == FT_GLYPH_FORMAT_BITMAP
718
 *
719
 * mode  :: the requested final rendering mode. supported values are
720
 *          MONO, NORMAL (i.e. gray), LCD and LCD_V
721
 *
722
 * the function returns the size in bytes of the corresponding buffer,
723
 * it's up to the caller to allocate the corresponding memory block
724
 * before calling _fill_xrender_bitmap
725
 *
726
 * it also returns -1 in case of error (e.g. incompatible arguments,
727
 * like trying to convert a gray bitmap into a monochrome one)
728
 */
729
static int
730
_compute_xrender_bitmap_size( FT_Bitmap*      target,
731
                              FT_GlyphSlot    slot,
732
                              FT_Render_Mode  mode )
733
{
734
    FT_Bitmap*  ftbit;
735
    int         width, height, pitch;
736
737
    if ( slot->format != FT_GLYPH_FORMAT_BITMAP )
738
        return -1;
739
740
    // compute the size of the final bitmap
741
    ftbit  = &slot->bitmap;
742
743
    width  = ftbit->width;
744
    height = ftbit->rows;
745
    pitch  = (width+3) & ~3;
746
747
    switch ( ftbit->pixel_mode )
748
    {
749
    case FT_PIXEL_MODE_MONO:
750
        if ( mode == FT_RENDER_MODE_MONO )
751
        {
752
          pitch = (((width+31) & ~31) >> 3);
753
          break;
754
        }
755
        /* fall-through */
756
757
    case FT_PIXEL_MODE_GRAY:
758
        if ( mode == FT_RENDER_MODE_LCD   ||
759
            mode == FT_RENDER_MODE_LCD_V )
760
        {
761
            /* each pixel is replicated into a 32-bit ARGB value */
762
            pitch = width*4;
763
        }
764
        break;
765
766
    case FT_PIXEL_MODE_LCD:
767
        if ( mode != FT_RENDER_MODE_LCD )
768
            return -1;
769
770
      /* horz pixel triplets are packed into 32-bit ARGB values */
771
      width   /= 3;
772
      pitch    = width*4;
773
      break;
774
775
    case FT_PIXEL_MODE_LCD_V:
776
        if ( mode != FT_RENDER_MODE_LCD_V )
777
            return -1;
778
779
        /* vert pixel triplets are packed into 32-bit ARGB values */
780
        height  /= 3;
781
        pitch    = width*4;
782
        break;
783
784
    default:  /* unsupported source format */
785
        return -1;
786
    }
787
788
    target->width  = width;
789
    target->rows   = height;
790
    target->pitch  = pitch;
791
    target->buffer = NULL;
792
793
    return pitch * height;
794
}
795
796
/* this functions converts the glyph bitmap found in a FT_GlyphSlot
797
 * into a different format (see _compute_xrender_bitmap_size)
798
 *
799
 * you should call this function after _compute_xrender_bitmap_size
800
 *
801
 * target :: target bitmap descriptor. Note that its 'buffer' pointer
802
 *           must point to memory allocated by the caller
803
 *
804
 * slot   :: the glyph slot containing the source bitmap
805
 *
806
 * mode   :: the requested final rendering mode
807
 *
808
 * bgr    :: boolean, set if BGR or VBGR pixel ordering is needed
809
 */
810
static void
811
_fill_xrender_bitmap( FT_Bitmap*      target,
812
                      FT_GlyphSlot    slot,
813
                      FT_Render_Mode  mode,
814
                      int             bgr )
815
{
816
    FT_Bitmap*   ftbit = &slot->bitmap;
817
    unsigned char*   srcLine   = ftbit->buffer;
818
    unsigned char*   dstLine   = target->buffer;
819
    int              src_pitch = ftbit->pitch;
820
    int              width     = target->width;
821
    int              height    = target->rows;
822
    int              pitch     = target->pitch;
823
    int              subpixel;
824
    int              h;
825
826
    subpixel = ( mode == FT_RENDER_MODE_LCD ||
827
        mode == FT_RENDER_MODE_LCD_V );
828
829
    if ( src_pitch < 0 )
830
      srcLine -= src_pitch*(ftbit->rows-1);
831
832
    target->pixel_mode = ftbit->pixel_mode;
833
834
    switch ( ftbit->pixel_mode )
835
    {
836
    case FT_PIXEL_MODE_MONO:
837
        if ( subpixel )  /* convert mono to ARGB32 values */
838
        {
839
            for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
840
            {
841
                int  x;
842
843
                for ( x = 0; x < width; x++ )
844
                {
845
                    if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
846
                        ((unsigned int*)dstLine)[x] = 0xffffffffU;
847
                }
848
            }
849
            target->pixel_mode = FT_PIXEL_MODE_LCD;
850
        }
851
        else if ( mode == FT_RENDER_MODE_NORMAL )  /* convert mono to 8-bit gray */
852
        {
853
            for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
854
            {
855
                int  x;
856
857
                for ( x = 0; x < width; x++ )
858
                {
859
                    if ( srcLine[(x >> 3)] & (0x80 >> (x & 7)) )
860
                        dstLine[x] = 0xff;
861
                }
862
            }
863
            target->pixel_mode = FT_PIXEL_MODE_GRAY;
864
        }
865
        else  /* copy mono to mono */
866
        {
867
            int  bytes = (width+7) >> 3;
868
869
            for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
870
                memcpy( dstLine, srcLine, bytes );
871
        }
872
        break;
873
874
    case FT_PIXEL_MODE_GRAY:
875
        if ( subpixel )  /* convert gray to ARGB32 values */
876
        {
877
            for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
878
            {
879
                int            x;
880
                unsigned int*  dst = (unsigned int*)dstLine;
881
882
                for ( x = 0; x < width; x++ )
883
                {
884
                    unsigned int  pix = srcLine[x];
885
886
                    pix |= (pix << 8);
887
                    pix |= (pix << 16);
888
889
                    dst[x] = pix;
890
                }
891
            }
892
            target->pixel_mode = FT_PIXEL_MODE_LCD;
893
        }
894
        else  /* copy gray into gray */
895
        {
896
            for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
897
                memcpy( dstLine, srcLine, width );
898
        }
899
        break;
900
901
    case FT_PIXEL_MODE_LCD:
902
        if ( !bgr )
903
        {
904
            /* convert horizontal RGB into ARGB32 */
905
            for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
906
            {
907
                int            x;
908
                unsigned char* src = srcLine;
909
                unsigned int*  dst = (unsigned int*)dstLine;
910
911
                for ( x = 0; x < width; x++, src += 3 )
912
                {
913
                    unsigned int  pix;
914
915
                    pix = ((unsigned int)src[0] << 16) |
916
                          ((unsigned int)src[1] <<  8) |
917
                          ((unsigned int)src[2]      ) |
918
                          ((unsigned int)src[1] << 24) ;
919
920
                    dst[x] = pix;
921
                }
922
            }
923
        }
924
        else
925
        {
926
          /* convert horizontal BGR into ARGB32 */
927
          for ( h = height; h > 0; h--, srcLine += src_pitch, dstLine += pitch )
928
          {
929
              int            x;
930
              unsigned char* src = srcLine;
931
              unsigned int*  dst = (unsigned int*)dstLine;
932
933
              for ( x = 0; x < width; x++, src += 3 )
934
              {
935
                  unsigned int  pix;
936
937
                  pix = ((unsigned int)src[2] << 16) |
938
                        ((unsigned int)src[1] <<  8) |
939
                        ((unsigned int)src[0]      ) |
940
                        ((unsigned int)src[1] << 24) ;
941
942
                  dst[x] = pix;
943
              }
944
          }
945
        }
946
        break;
947
948
    default:  /* FT_PIXEL_MODE_LCD_V */
949
        /* convert vertical RGB into ARGB32 */
950
        if ( !bgr )
951
        {
952
            for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
953
            {
954
                int            x;
955
                unsigned char* src = srcLine;
956
                unsigned int*  dst = (unsigned int*)dstLine;
957
958
                for ( x = 0; x < width; x++, src += 1 )
959
                {
960
                    unsigned int  pix;
961
#if 1
962
                    pix = ((unsigned int)src[0]           << 16) |
963
                          ((unsigned int)src[src_pitch]   <<  8) |
964
                          ((unsigned int)src[src_pitch*2]      ) |
965
                          0xFF000000 ;
966
#else
967
                    pix = ((unsigned int)src[0]           << 16) |
968
                          ((unsigned int)src[src_pitch]   <<  8) |
969
                          ((unsigned int)src[src_pitch*2]      ) |
970
                          ((unsigned int)src[src_pitch]   << 24) ;
714
#endif
971
#endif
715
    {    65538*9/13,65538*3/13,65538*1/13 },
972
                    dst[x] = pix;
716
    /* green */
973
                }
717
    {    65538*1/6, 65538*4/6, 65538*1/6 },
974
            }
718
    /* blue */
975
        }
719
    {    65538*1/13,65538*3/13,65538*9/13 },
976
        else
720
};
977
        {
978
            for ( h = height; h > 0; h--, srcLine += 3*src_pitch, dstLine += pitch )
979
            {
980
                int            x;
981
                unsigned char* src = srcLine;
982
                unsigned int*  dst = (unsigned int*)dstLine;
983
984
                for ( x = 0; x < width; x++, src += 1 )
985
                {
986
                    unsigned int  pix;
987
988
                    pix = ((unsigned int)src[src_pitch*2] << 16) |
989
                        ((unsigned int)src[src_pitch]   <<  8) |
990
                        ((unsigned int)src[0]                ) |
991
                        ((unsigned int)src[src_pitch]   << 24) ;
992
993
                    dst[x] = pix;
994
                }
995
            }
996
        }
997
    }
998
}
999
721
1000
722
/* Fills in val->image with an image surface created from @bitmap
1001
/* Fills in val->image with an image surface created from @bitmap
723
 */
1002
 */
Lines 730-741 Link Here
730
    int width, height, stride;
1009
    int width, height, stride;
731
    unsigned char *data;
1010
    unsigned char *data;
732
    int format = CAIRO_FORMAT_A8;
1011
    int format = CAIRO_FORMAT_A8;
733
    cairo_bool_t subpixel = FALSE;
1012
    cairo_image_surface_t  *image;
734
1013
735
    width = bitmap->width;
1014
    width = bitmap->width;
736
    height = bitmap->rows;
1015
    height = bitmap->rows;
737
1016
738
    switch (bitmap->pixel_mode) {
1017
    {
1018
        switch (bitmap->pixel_mode)
1019
        {
739
    case FT_PIXEL_MODE_MONO:
1020
    case FT_PIXEL_MODE_MONO:
740
	stride = (((width + 31) & ~31) >> 3);
1021
	stride = (((width + 31) & ~31) >> 3);
741
	if (own_buffer) {
1022
	if (own_buffer) {
Lines 765-771 Link Here
765
		}
1046
		}
766
	    }
1047
	    }
767
	}
1048
	}
768
769
#ifndef WORDS_BIGENDIAN
1049
#ifndef WORDS_BIGENDIAN
770
	{
1050
	{
771
	    unsigned char   *d = data;
1051
	    unsigned char   *d = data;
Lines 777-793 Link Here
777
	    }
1057
	    }
778
	}
1058
	}
779
#endif
1059
#endif
1060
780
	format = CAIRO_FORMAT_A1;
1061
	format = CAIRO_FORMAT_A1;
781
	break;
1062
	break;
782
1063
783
    case FT_PIXEL_MODE_LCD:
1064
    case FT_PIXEL_MODE_LCD:
784
    case FT_PIXEL_MODE_LCD_V:
1065
    case FT_PIXEL_MODE_LCD_V:
785
    case FT_PIXEL_MODE_GRAY:
1066
    case FT_PIXEL_MODE_GRAY:
786
	switch (font_options->antialias) {
1067
            if (font_options->antialias != CAIRO_ANTIALIAS_SUBPIXEL)
787
	case CAIRO_ANTIALIAS_DEFAULT:
1068
            {
788
	case CAIRO_ANTIALIAS_GRAY:
789
	case CAIRO_ANTIALIAS_NONE:
790
	default:
791
	    stride = bitmap->pitch;
1069
	    stride = bitmap->pitch;
792
	    if (own_buffer) {
1070
	    if (own_buffer) {
793
		data = bitmap->buffer;
1071
		data = bitmap->buffer;
Lines 800-906 Link Here
800
		memcpy (data, bitmap->buffer, stride * height);
1078
		memcpy (data, bitmap->buffer, stride * height);
801
	    }
1079
	    }
802
	    format = CAIRO_FORMAT_A8;
1080
	    format = CAIRO_FORMAT_A8;
803
	    break;
1081
            } else {
804
	case CAIRO_ANTIALIAS_SUBPIXEL: {
1082
                // if we get there, the  data from the source bitmap
805
	    int		    x, y;
1083
                // really comes from _fill_xrender_bitmap, and is
806
	    unsigned char   *in_line, *out_line, *in;
1084
                // made of 32-bit ARGB or ABGR values
807
	    unsigned int    *out;
1085
                assert(own_buffer != 0);
808
	    unsigned int    red, green, blue;
1086
                assert(bitmap->pixel_mode != FT_PIXEL_MODE_GRAY);
809
	    int		    rf, gf, bf;
810
	    int		    s;
811
	    int		    o, os;
812
	    unsigned char   *data_rgba;
813
	    unsigned int    width_rgba, stride_rgba;
814
	    int		    vmul = 1;
815
	    int		    hmul = 1;
816
817
	    switch (font_options->subpixel_order) {
818
	    case CAIRO_SUBPIXEL_ORDER_DEFAULT:
819
	    case CAIRO_SUBPIXEL_ORDER_RGB:
820
	    case CAIRO_SUBPIXEL_ORDER_BGR:
821
	    default:
822
		width /= 3;
823
		hmul = 3;
824
		break;
825
	    case CAIRO_SUBPIXEL_ORDER_VRGB:
826
	    case CAIRO_SUBPIXEL_ORDER_VBGR:
827
		vmul = 3;
828
		height /= 3;
829
		break;
830
	    }
831
	    /*
832
	     * Filter the glyph to soften the color fringes
833
	     */
834
	    width_rgba = width;
835
	    stride = bitmap->pitch;
836
	    stride_rgba = (width_rgba * 4 + 3) & ~3;
837
	    data_rgba = calloc (1, stride_rgba * height);
838
	    if (data_rgba == NULL) {
839
		if (own_buffer)
840
		    free (bitmap->buffer);
841
		_cairo_error (CAIRO_STATUS_NO_MEMORY);
842
		return CAIRO_STATUS_NO_MEMORY;
843
	    }
844
845
	    os = 1;
846
	    switch (font_options->subpixel_order) {
847
	    case CAIRO_SUBPIXEL_ORDER_VRGB:
848
		os = stride;
849
	    case CAIRO_SUBPIXEL_ORDER_DEFAULT:
850
	    case CAIRO_SUBPIXEL_ORDER_RGB:
851
	    default:
852
		rf = 0;
853
		gf = 1;
854
		bf = 2;
855
		break;
856
	    case CAIRO_SUBPIXEL_ORDER_VBGR:
857
		os = stride;
858
	    case CAIRO_SUBPIXEL_ORDER_BGR:
859
		bf = 0;
860
		gf = 1;
861
		rf = 2;
862
		break;
863
	    }
864
	    in_line = bitmap->buffer;
865
	    out_line = data_rgba;
866
	    for (y = 0; y < height; y++)
867
	    {
868
		in = in_line;
869
		out = (unsigned int *) out_line;
870
		in_line += stride * vmul;
871
		out_line += stride_rgba;
872
		for (x = 0; x < width * hmul; x += hmul)
873
		{
874
		    red = green = blue = 0;
875
		    o = 0;
876
		    for (s = 0; s < 3; s++)
877
		    {
878
			red += filters[rf][s]*in[x+o];
879
			green += filters[gf][s]*in[x+o];
880
			blue += filters[bf][s]*in[x+o];
881
			o += os;
882
		    }
883
		    red = red / 65536;
884
		    green = green / 65536;
885
		    blue = blue / 65536;
886
		    *out++ = (green << 24) | (red << 16) | (green << 8) | blue;
887
		}
888
	    }
889
1087
890
	    /* Images here are stored in native format. The
1088
                data   = bitmap->buffer;
891
	     * backend must convert to its own format as needed
1089
	    stride = bitmap->pitch;
892
	     */
893
894
	    if (own_buffer)
895
		free (bitmap->buffer);
896
	    data = data_rgba;
897
	    stride = stride_rgba;
898
	    format = CAIRO_FORMAT_ARGB32;
1090
	    format = CAIRO_FORMAT_ARGB32;
899
	    subpixel = TRUE;
900
	    break;
901
	}
902
	}
1091
	}
903
	break;
1092
	break;
1093
904
    case FT_PIXEL_MODE_GRAY2:
1094
    case FT_PIXEL_MODE_GRAY2:
905
    case FT_PIXEL_MODE_GRAY4:
1095
    case FT_PIXEL_MODE_GRAY4:
906
	/* These could be triggered by very rare types of TrueType fonts */
1096
	/* These could be triggered by very rare types of TrueType fonts */
Lines 911-930 Link Here
911
	return CAIRO_STATUS_NO_MEMORY;
1101
	return CAIRO_STATUS_NO_MEMORY;
912
    }
1102
    }
913
1103
914
    *surface = (cairo_image_surface_t *)
1104
        /* XXX */
1105
        *surface = image = (cairo_image_surface_t *)
915
	cairo_image_surface_create_for_data (data,
1106
	cairo_image_surface_create_for_data (data,
916
					     format,
1107
					     format,
917
					     width, height, stride);
1108
					     width, height, stride);
918
    if ((*surface)->base.status) {
1109
        if (image->base.status) {
919
	free (data);
1110
	free (data);
920
	return CAIRO_STATUS_NO_MEMORY;
1111
	return CAIRO_STATUS_NO_MEMORY;
921
    }
1112
    }
922
1113
923
    if (subpixel)
1114
        if (font_options->antialias == CAIRO_ANTIALIAS_SUBPIXEL)
924
	pixman_image_set_component_alpha ((*surface)->pixman_image, TRUE);
1115
            pixman_image_set_component_alpha (image->pixman_image, TRUE);
925
926
    _cairo_image_surface_assume_ownership_of_data ((*surface));
927
1116
1117
        _cairo_image_surface_assume_ownership_of_data (image);
1118
    }
928
    return CAIRO_STATUS_SUCCESS;
1119
    return CAIRO_STATUS_SUCCESS;
929
}
1120
}
930
1121
Lines 948-963 Link Here
948
		       cairo_font_options_t	 *font_options,
1139
		       cairo_font_options_t	 *font_options,
949
		       cairo_image_surface_t	**surface)
1140
		       cairo_image_surface_t	**surface)
950
{
1141
{
1142
    int rgba = FC_RGBA_UNKNOWN;
951
    FT_GlyphSlot glyphslot = face->glyph;
1143
    FT_GlyphSlot glyphslot = face->glyph;
952
    FT_Outline *outline = &glyphslot->outline;
1144
    FT_Outline *outline = &glyphslot->outline;
953
    FT_Bitmap bitmap;
1145
    FT_Bitmap bitmap;
954
    FT_BBox cbox;
1146
    FT_BBox cbox;
955
    FT_Matrix matrix;
956
    int hmul = 1;
957
    int vmul = 1;
958
    unsigned int width, height, stride;
1147
    unsigned int width, height, stride;
959
    cairo_bool_t subpixel = FALSE;
1148
    cairo_format_t format;
960
    cairo_status_t status;
1149
    cairo_status_t status;
1150
    FT_Error  fterror;
1151
    FT_Library  library = glyphslot->library;
1152
    FT_Render_Mode  render_mode = FT_RENDER_MODE_NORMAL;
1153
1154
    switch (font_options->antialias)
1155
    {
1156
    case CAIRO_ANTIALIAS_NONE:
1157
        render_mode = FT_RENDER_MODE_MONO;
1158
        break;
1159
1160
    case CAIRO_ANTIALIAS_SUBPIXEL:
1161
        switch (font_options->subpixel_order)
1162
        {
1163
            case CAIRO_SUBPIXEL_ORDER_DEFAULT:
1164
            case CAIRO_SUBPIXEL_ORDER_RGB:
1165
            case CAIRO_SUBPIXEL_ORDER_BGR:
1166
                render_mode = FT_RENDER_MODE_LCD;
1167
                break;
1168
1169
            case CAIRO_SUBPIXEL_ORDER_VRGB:
1170
            case CAIRO_SUBPIXEL_ORDER_VBGR:
1171
                render_mode = FT_RENDER_MODE_LCD_V;
1172
                break;
1173
        }
1174
        break;
1175
1176
    case CAIRO_ANTIALIAS_DEFAULT:
1177
    case CAIRO_ANTIALIAS_GRAY:
1178
        render_mode = FT_RENDER_MODE_NORMAL;
1179
    }
961
1180
962
    FT_Outline_Get_CBox (outline, &cbox);
1181
    FT_Outline_Get_CBox (outline, &cbox);
963
1182
Lines 968-1067 Link Here
968
1187
969
    width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);
1188
    width = (unsigned int) ((cbox.xMax - cbox.xMin) >> 6);
970
    height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);
1189
    height = (unsigned int) ((cbox.yMax - cbox.yMin) >> 6);
971
    stride = (width * hmul + 3) & ~3;
1190
    stride = (width + 3) & ~3;
972
1191
973
    if (width * height == 0) {
1192
    if (width * height == 0) {
974
	cairo_format_t format;
975
	/* Looks like fb handles zero-sized images just fine */
1193
	/* Looks like fb handles zero-sized images just fine */
976
	switch (font_options->antialias) {
1194
        switch (render_mode)
977
	case CAIRO_ANTIALIAS_NONE:
1195
        {
1196
          case FT_RENDER_MODE_MONO:
978
	    format = CAIRO_FORMAT_A1;
1197
	    format = CAIRO_FORMAT_A1;
979
	    break;
1198
	    break;
980
	case CAIRO_ANTIALIAS_SUBPIXEL:
1199
          case FT_RENDER_MODE_LCD:
981
	    format= CAIRO_FORMAT_ARGB32;
1200
          case FT_RENDER_MODE_LCD_V:
1201
            format = CAIRO_FORMAT_ARGB32;
982
	    break;
1202
	    break;
983
	case CAIRO_ANTIALIAS_DEFAULT:
984
	case CAIRO_ANTIALIAS_GRAY:
985
	default:
1203
	default:
986
	    format = CAIRO_FORMAT_A8;
1204
	    format = CAIRO_FORMAT_A8;
987
	    break;
988
	}
1205
	}
989
1206
990
	(*surface) = (cairo_image_surface_t *)
1207
	(*surface) = (cairo_image_surface_t *)
991
	    cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
1208
	    cairo_image_surface_create_for_data (NULL, format, 0, 0, 0);
992
	if ((*surface)->base.status)
1209
	if ((*surface)->base.status)
993
	    return CAIRO_STATUS_NO_MEMORY;
1210
	    return CAIRO_STATUS_NO_MEMORY;
1211
994
    } else  {
1212
    } else  {
995
1213
996
	matrix.xx = matrix.yy = 0x10000L;
1214
        int  bitmap_size;
997
	matrix.xy = matrix.yx = 0;
998
1215
999
	switch (font_options->antialias) {
1216
        switch (render_mode)
1000
	case CAIRO_ANTIALIAS_NONE:
1217
        {
1001
	    bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
1218
        case FT_RENDER_MODE_LCD:
1002
	    bitmap.num_grays  = 1;
1219
            if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_BGR  ) {
1003
	    stride = ((width + 31) & -32) >> 3;
1220
                rgba = FC_RGBA_BGR;
1221
            } else {
1222
                rgba = FC_RGBA_RGB;
1223
            }
1004
	    break;
1224
	    break;
1005
	case CAIRO_ANTIALIAS_DEFAULT:
1225
1006
	case CAIRO_ANTIALIAS_GRAY:
1226
        case FT_RENDER_MODE_LCD_V:
1007
	    bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
1227
            if (font_options->subpixel_order == CAIRO_SUBPIXEL_ORDER_VBGR ) {
1008
	    bitmap.num_grays  = 256;
1228
                rgba = FC_RGBA_VBGR;
1009
	    stride = (width + 3) & -4;
1229
            } else {
1230
                rgba = FC_RGBA_VRGB;
1231
            }
1010
	    break;
1232
	    break;
1011
	case CAIRO_ANTIALIAS_SUBPIXEL:
1233
1012
	    switch (font_options->subpixel_order) {
1013
	    case CAIRO_SUBPIXEL_ORDER_RGB:
1014
	    case CAIRO_SUBPIXEL_ORDER_BGR:
1015
	    case CAIRO_SUBPIXEL_ORDER_DEFAULT:
1016
	    default:
1234
	    default:
1017
		matrix.xx *= 3;
1235
            ;
1018
		hmul = 3;
1019
		subpixel = TRUE;
1020
		break;
1021
	    case CAIRO_SUBPIXEL_ORDER_VRGB:
1022
	    case CAIRO_SUBPIXEL_ORDER_VBGR:
1023
		matrix.yy *= 3;
1024
		vmul = 3;
1025
		subpixel = TRUE;
1026
		break;
1027
	    }
1236
	    }
1028
	    FT_Outline_Transform (outline, &matrix);
1029
1237
1030
	    bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
1238
        FT_Library_SetLcdFilter( library, FT_LCD_FILTER_DEFAULT );
1031
	    bitmap.num_grays  = 256;
1032
	    stride = (width * hmul + 3) & -4;
1033
	}
1034
1239
1035
	bitmap.pitch = stride;
1240
        fterror = FT_Render_Glyph( face->glyph, render_mode );
1036
	bitmap.width = width * hmul;
1037
	bitmap.rows = height * vmul;
1038
	bitmap.buffer = calloc (1, stride * bitmap.rows);
1039
1241
1040
	if (bitmap.buffer == NULL) {
1242
        FT_Library_SetLcdFilter( library, FT_LCD_FILTER_NONE );
1243
1244
        if (fterror != 0) {
1041
	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
1245
	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
1042
	    return CAIRO_STATUS_NO_MEMORY;
1246
	    return CAIRO_STATUS_NO_MEMORY;
1043
	}
1247
	}
1044
1248
1045
	FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul);
1249
        bitmap_size = _compute_xrender_bitmap_size( &bitmap,
1250
                                                    face->glyph,
1251
                                                    render_mode );
1252
        if ( bitmap_size < 0 ) {
1253
	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
1254
            return CAIRO_STATUS_NO_MEMORY;
1255
	}
1046
1256
1047
	if (FT_Outline_Get_Bitmap (glyphslot->library, outline, &bitmap) != 0) {
1257
        bitmap.buffer = calloc(1, bitmap_size);
1048
	    free (bitmap.buffer);
1258
        if (bitmap.buffer == NULL) {
1049
	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
1259
	    _cairo_error (CAIRO_STATUS_NO_MEMORY);
1050
	    return CAIRO_STATUS_NO_MEMORY;
1260
	    return CAIRO_STATUS_NO_MEMORY;
1051
	}
1261
	}
1052
1262
1263
        _fill_xrender_bitmap( &bitmap, face->glyph, render_mode,
1264
                              (rgba == FC_RGBA_BGR || rgba == FC_RGBA_VBGR) );
1265
1266
        // NOTE: _get_bitmap_surface will free bitmap.buffer if there is an error
1053
	status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
1267
	status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
1054
	if (status)
1268
	if (status)
1055
	    return status;
1269
	    return status;
1056
    }
1057
1270
1058
    /*
1271
    /*
1059
     * Note: the font's coordinate system is upside down from ours, so the
1272
     * Note: the font's coordinate system is upside down from ours, so the
1060
     * Y coordinate of the control box needs to be negated.
1273
     * Y coordinate of the control box needs to be negated.
1061
     */
1274
     */
1062
    cairo_surface_set_device_offset (&(*surface)->base,
1275
    cairo_surface_set_device_offset (&(*surface)->base,
1063
				     floor ((double) cbox.xMin / 64.0),
1276
                                         (double) glyphslot->bitmap_left,
1064
				     floor (-(double) cbox.yMax / 64.0));
1277
                                         (double)-glyphslot->bitmap_top);
1278
    }
1065
1279
1066
    return CAIRO_STATUS_SUCCESS;
1280
    return CAIRO_STATUS_SUCCESS;
1067
}
1281
}
Lines 1433-1443 Link Here
1433
		case CAIRO_SUBPIXEL_ORDER_DEFAULT:
1647
		case CAIRO_SUBPIXEL_ORDER_DEFAULT:
1434
		case CAIRO_SUBPIXEL_ORDER_RGB:
1648
		case CAIRO_SUBPIXEL_ORDER_RGB:
1435
		case CAIRO_SUBPIXEL_ORDER_BGR:
1649
		case CAIRO_SUBPIXEL_ORDER_BGR:
1436
		    load_target |= FT_LOAD_TARGET_LCD;
1650
		    load_target = FT_LOAD_TARGET_LCD;
1437
		    break;
1651
		    break;
1438
		case CAIRO_SUBPIXEL_ORDER_VRGB:
1652
		case CAIRO_SUBPIXEL_ORDER_VRGB:
1439
		case CAIRO_SUBPIXEL_ORDER_VBGR:
1653
		case CAIRO_SUBPIXEL_ORDER_VBGR:
1440
		    load_target |= FT_LOAD_TARGET_LCD_V;
1654
		    load_target = FT_LOAD_TARGET_LCD_V;
1441
		break;
1655
		break;
1442
		}
1656
		}
1443
	    }
1657
	    }

Return to bug 182613