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

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

Return to bug 182613