Lines 52-57
#if HAVE_FT_GLYPHSLOT_EMBOLDEN
Link Here
|
52 |
#include FT_SYNTHESIS_H |
52 |
#include FT_SYNTHESIS_H |
53 |
#endif |
53 |
#endif |
54 |
|
54 |
|
|
|
55 |
#define FIR_FILTER 1 |
56 |
|
55 |
#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0)) |
57 |
#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 64.0)) |
56 |
#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0) |
58 |
#define DOUBLE_FROM_26_6(t) ((double)(t) / 64.0) |
57 |
#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0)) |
59 |
#define DOUBLE_TO_16_16(d) ((FT_Fixed)((d) * 65536.0)) |
Lines 490-495
_cairo_ft_unscaled_font_destroy (void *a
Link Here
|
490 |
} |
492 |
} |
491 |
} |
493 |
} |
492 |
|
494 |
|
|
|
495 |
static const int fir_filter[5] = { 0x1C, 0x38, 0x55, 0x38, 0x1C }; |
496 |
|
493 |
static cairo_bool_t |
497 |
static cairo_bool_t |
494 |
_has_unlocked_face (void *entry) |
498 |
_has_unlocked_face (void *entry) |
495 |
{ |
499 |
{ |
Lines 776-782
#endif
Link Here
|
776 |
} |
780 |
} |
777 |
format = CAIRO_FORMAT_A8; |
781 |
format = CAIRO_FORMAT_A8; |
778 |
break; |
782 |
break; |
779 |
case CAIRO_ANTIALIAS_SUBPIXEL: { |
783 |
case CAIRO_ANTIALIAS_SUBPIXEL: |
|
|
784 |
#ifdef FIR_FILTER |
785 |
{ |
786 |
unsigned char* line; |
787 |
unsigned char* bufBitmap; |
788 |
int pitch; |
789 |
unsigned char *data_rgba; |
790 |
unsigned int width_rgba, stride_rgba; |
791 |
int vmul = 1; |
792 |
int hmul = 1; |
793 |
|
794 |
switch (font_options->subpixel_order) { |
795 |
case CAIRO_SUBPIXEL_ORDER_DEFAULT: |
796 |
case CAIRO_SUBPIXEL_ORDER_RGB: |
797 |
case CAIRO_SUBPIXEL_ORDER_BGR: |
798 |
default: |
799 |
width /= 3; |
800 |
hmul = 3; |
801 |
break; |
802 |
case CAIRO_SUBPIXEL_ORDER_VRGB: |
803 |
case CAIRO_SUBPIXEL_ORDER_VBGR: |
804 |
vmul = 3; |
805 |
height /= 3; |
806 |
break; |
807 |
} |
808 |
/* |
809 |
* Filter the glyph to soften the color fringes |
810 |
*/ |
811 |
width_rgba = width; |
812 |
stride = bitmap->pitch; |
813 |
stride_rgba = (width_rgba * 4 + 3) & ~3; |
814 |
data_rgba = calloc (1, stride_rgba * height); |
815 |
|
816 |
/* perform in-place FIR filtering in either the horizontal or |
817 |
* vertical direction. We're going to modify the RGB graymap, |
818 |
* but that's ok, because we either own it, or its part of |
819 |
* the FreeType glyph slot, which will not be used anymore. |
820 |
*/ |
821 |
pitch = bitmap->pitch; |
822 |
line = (unsigned char*)bitmap->buffer; |
823 |
if ( pitch < 0 ) |
824 |
line -= pitch*(height-1); |
825 |
|
826 |
bufBitmap = line; |
827 |
|
828 |
switch (font_options->subpixel_order) { |
829 |
case CAIRO_SUBPIXEL_ORDER_DEFAULT: |
830 |
case CAIRO_SUBPIXEL_ORDER_RGB: |
831 |
case CAIRO_SUBPIXEL_ORDER_BGR: |
832 |
{ |
833 |
int h; |
834 |
|
835 |
for ( h = height; h > 0; h--, line += pitch ) { |
836 |
int pix[6] = { 0, 0, 0, 0, 0, 0 }; |
837 |
unsigned char* p = line; |
838 |
unsigned char* limit = line + width*3; |
839 |
int nn, val, val2; |
840 |
|
841 |
val = p[0]; |
842 |
for (nn = 0; nn < 3; nn++) |
843 |
pix[2 + nn] += val * fir_filter[nn]; |
844 |
|
845 |
val = p[1]; |
846 |
for (nn = 0; nn < 4; nn++) |
847 |
pix[1 + nn] += val * fir_filter[nn]; |
848 |
|
849 |
p += 2; |
850 |
|
851 |
for ( ; p < limit; p++ ) { |
852 |
val = p[0]; |
853 |
for (nn = 0; nn < 5; nn++) |
854 |
pix[nn] += val * fir_filter[nn]; |
855 |
|
856 |
val2 = pix[0] / 256; |
857 |
val2 |= -(val2 >> 8); |
858 |
p[-2] = (unsigned char)val2; |
859 |
|
860 |
for (nn = 0; nn < 5; nn++) |
861 |
pix[nn] = pix[nn + 1]; |
862 |
} |
863 |
for (nn = 0; nn < 2; nn++ ) { |
864 |
val2 = pix[nn] / 256; |
865 |
val2 |= -(val2 >> 8); |
866 |
p[nn - 2] = (unsigned char)val2; |
867 |
} |
868 |
} |
869 |
} |
870 |
break; |
871 |
case CAIRO_SUBPIXEL_ORDER_VRGB: |
872 |
case CAIRO_SUBPIXEL_ORDER_VBGR: |
873 |
{ |
874 |
int w; |
875 |
|
876 |
for (w = 0; w < width; w++ ) { |
877 |
int pix[6] = { 0, 0, 0, 0, 0, 0 }; |
878 |
unsigned char* p = bufBitmap + w; |
879 |
unsigned char* limit = bufBitmap + w + height*3*pitch; |
880 |
int nn, val, val2; |
881 |
|
882 |
val = p[0]; |
883 |
for (nn = 0; nn < 3; nn++) |
884 |
pix[2 + nn] += val*fir_filter[nn]; |
885 |
|
886 |
val = p[pitch]; |
887 |
for (nn = 0; nn < 4; nn++ ) |
888 |
pix[1 + nn] += val * fir_filter[nn]; |
889 |
|
890 |
p += 2*pitch; |
891 |
for ( ; p < limit; p += pitch ) { |
892 |
val = p[0]; |
893 |
for (nn = 0; nn < 5; nn++ ) |
894 |
pix[nn] += val * fir_filter[nn]; |
895 |
|
896 |
val2 = pix[0] / 256; |
897 |
val2 |= -(val2 >> 8); |
898 |
p[-2 * pitch] = (unsigned char)val2; |
899 |
|
900 |
for (nn = 0; nn < 5; nn++) |
901 |
pix[nn] = pix[nn+1]; |
902 |
} |
903 |
|
904 |
for (nn = 0; nn < 2; nn++) { |
905 |
val2 = pix[nn] / 256; |
906 |
val2 |= -(val2 >> 8); |
907 |
p[(nn - 2) * pitch] = (unsigned char)val2; |
908 |
} |
909 |
} |
910 |
} |
911 |
break; |
912 |
default: /* shouldn't happen */ |
913 |
break; |
914 |
} |
915 |
|
916 |
/* now copy the resulting graymap into an ARGB32 image */ |
917 |
{ |
918 |
unsigned char* in_line = bufBitmap; |
919 |
unsigned char* out_line = data_rgba; |
920 |
int h = height; |
921 |
|
922 |
switch (font_options->subpixel_order) { |
923 |
case CAIRO_SUBPIXEL_ORDER_DEFAULT: |
924 |
case CAIRO_SUBPIXEL_ORDER_RGB: |
925 |
for ( ; h > 0; h--, in_line += pitch, out_line += stride_rgba) { |
926 |
unsigned char* in = in_line; |
927 |
int* out = (int*)out_line; |
928 |
int w; |
929 |
|
930 |
for (w = width; w > 0; w--, in += 3, out += 1) { |
931 |
int r = in[0]; |
932 |
int g = in[1]; |
933 |
int b = in[2]; |
934 |
|
935 |
out[0] = (g << 24) | (r << 16) | (g << 8) | b; |
936 |
} |
937 |
} |
938 |
break; |
939 |
case CAIRO_SUBPIXEL_ORDER_BGR: |
940 |
for ( ; h > 0; h--, in_line += pitch, out_line += stride_rgba) { |
941 |
unsigned char* in = in_line; |
942 |
int* out = (int*)out_line; |
943 |
int w; |
944 |
|
945 |
for (w = width; w > 0; w--, in += 3, out += 1) { |
946 |
int r = in[2]; |
947 |
int g = in[1]; |
948 |
int b = in[0]; |
949 |
|
950 |
out[0] = (g << 24) | (r << 16) | (g << 8) | b; |
951 |
} |
952 |
} |
953 |
break; |
954 |
case CAIRO_SUBPIXEL_ORDER_VRGB: |
955 |
for ( ; h > 0; h--, in_line += pitch*3, out_line += stride_rgba) { |
956 |
unsigned char* in = in_line; |
957 |
int* out = (int*)out_line; |
958 |
int w; |
959 |
|
960 |
for (w = width; w > 0; w--, in += 1, out += 1) { |
961 |
int r = in[0]; |
962 |
int g = in[pitch]; |
963 |
int b = in[pitch*2]; |
964 |
|
965 |
out[0] = (g << 24) | (r << 16) | (g << 8) | b; |
966 |
} |
967 |
} |
968 |
break; |
969 |
case CAIRO_SUBPIXEL_ORDER_VBGR: |
970 |
for ( ; h > 0; h--, in_line += pitch*3, out_line += stride_rgba) { |
971 |
unsigned char* in = in_line; |
972 |
int* out = (int*)out_line; |
973 |
int w; |
974 |
|
975 |
for (w = width; w > 0; w--, in += 1, out += 1) { |
976 |
int r = in[2*pitch]; |
977 |
int g = in[pitch]; |
978 |
int b = in[0]; |
979 |
|
980 |
out[0] = (g << 24) | (r << 16) | (g << 8) | b; |
981 |
} |
982 |
} |
983 |
break; |
984 |
} |
985 |
} |
986 |
|
987 |
if (own_buffer) |
988 |
free (bitmap->buffer); |
989 |
data = data_rgba; |
990 |
stride = stride_rgba; |
991 |
format = CAIRO_FORMAT_ARGB32; |
992 |
subpixel = TRUE; |
993 |
break; |
994 |
} |
995 |
#else /* !FIR_FILTER */ |
996 |
{ |
780 |
int x, y; |
997 |
int x, y; |
781 |
unsigned char *in_line, *out_line, *in; |
998 |
unsigned char *in_line, *out_line, *in; |
782 |
unsigned int *out; |
999 |
unsigned int *out; |
Lines 868-873
#endif
Link Here
|
868 |
subpixel = TRUE; |
1085 |
subpixel = TRUE; |
869 |
break; |
1086 |
break; |
870 |
} |
1087 |
} |
|
|
1088 |
#endif /* !FIR_FILTER */ |
871 |
} |
1089 |
} |
872 |
break; |
1090 |
break; |
873 |
case FT_PIXEL_MODE_GRAY2: |
1091 |
case FT_PIXEL_MODE_GRAY2: |
Lines 982-993
_render_glyph_outline (FT_Face
Link Here
|
982 |
matrix.xx *= 3; |
1200 |
matrix.xx *= 3; |
983 |
hmul = 3; |
1201 |
hmul = 3; |
984 |
subpixel = TRUE; |
1202 |
subpixel = TRUE; |
|
|
1203 |
#ifdef FIR_FILTER |
1204 |
cbox.xMin -= 64; |
1205 |
cbox.xMax += 64; |
1206 |
width += 2; |
1207 |
#endif |
985 |
break; |
1208 |
break; |
986 |
case CAIRO_SUBPIXEL_ORDER_VRGB: |
1209 |
case CAIRO_SUBPIXEL_ORDER_VRGB: |
987 |
case CAIRO_SUBPIXEL_ORDER_VBGR: |
1210 |
case CAIRO_SUBPIXEL_ORDER_VBGR: |
988 |
matrix.yy *= 3; |
1211 |
matrix.yy *= 3; |
989 |
vmul = 3; |
1212 |
vmul = 3; |
990 |
subpixel = TRUE; |
1213 |
subpixel = TRUE; |
|
|
1214 |
#ifdef FIR_FILTER |
1215 |
cbox.yMin -= 64; |
1216 |
cbox.yMax += 64; |
1217 |
height += 2; |
1218 |
#endif |
991 |
break; |
1219 |
break; |
992 |
} |
1220 |
} |
993 |
FT_Outline_Transform (outline, &matrix); |
1221 |
FT_Outline_Transform (outline, &matrix); |
994 |
- |
|
|