View | Details | Raw Unified | Return to bug 14361
Collapse All | Expand All

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

Return to bug 14361