Lines 38-43
Link Here
|
38 |
#include FT_SIZES_H |
38 |
#include FT_SIZES_H |
39 |
#include FT_OUTLINE_H |
39 |
#include FT_OUTLINE_H |
40 |
#include FT_SYNTHESIS_H |
40 |
#include FT_SYNTHESIS_H |
|
|
41 |
#include FT_LCD_FILTER_H |
42 |
#include <fontconfig/fontconfig.h> |
41 |
|
43 |
|
42 |
#include "fontscaler.h" |
44 |
#include "fontscaler.h" |
43 |
|
45 |
|
Lines 692-697
Link Here
|
692 |
} |
694 |
} |
693 |
} |
695 |
} |
694 |
|
696 |
|
|
|
697 |
typedef struct { |
698 |
FT_Render_Mode ftRenderMode; |
699 |
int ftLoadFlags; |
700 |
FT_LcdFilter ftLcdFilter; |
701 |
} RenderingProperties; |
702 |
|
703 |
static FcPattern* matchedPattern(const FcChar8* family, double ptSize) { |
704 |
/* |
705 |
we will create pattern to find our family and size in |
706 |
fontconfig configuration, and then will return it's |
707 |
properties: |
708 |
*/ |
709 |
FcPattern* fcPattern = 0; |
710 |
fcPattern = FcPatternCreate(); |
711 |
FcValue fcValue; |
712 |
fcValue.type = FcTypeString; |
713 |
fcValue.u.s = family; |
714 |
FcPatternAdd(fcPattern, FC_FAMILY, fcValue, FcTrue); |
715 |
FcPatternAddBool(fcPattern, FC_SCALABLE, FcTrue); |
716 |
FcPatternAddDouble(fcPattern, FC_SIZE, ptSize); |
717 |
// TODO FcPatternAddInteger(pattern, FC_WEIGHT, weight_value); |
718 |
// TODO FcPatternAddInteger(pattern, FC_SLANT, slant_value); |
719 |
// TODO FcPatternAddDouble(pattern, FC_PIXEL_SIZE, size_value); |
720 |
// TODO FcPatternAddInteger(pattern, FC_WIDTH, stretch); 100 in most cases |
721 |
FcConfigSubstitute(0, fcPattern, FcMatchPattern); |
722 |
FcConfigSubstitute(0, fcPattern, FcMatchFont); |
723 |
FcDefaultSubstitute(fcPattern); |
724 |
FcResult res; |
725 |
|
726 |
FcPattern *pattern = 0; |
727 |
pattern = FcFontMatch(0, fcPattern, &res); |
728 |
FcPatternDestroy(fcPattern); |
729 |
return pattern; |
730 |
} |
731 |
|
732 |
static void readFontconfig(const FcChar8* family, double ptSize, jint aaType, RenderingProperties* rp) { |
733 |
|
734 |
FcPattern *pattern = matchedPattern(family, ptSize); |
735 |
|
736 |
int ftLoadFalgs = FT_LOAD_DEFAULT; |
737 |
FT_Render_Mode ftRenderMode; |
738 |
FT_LcdFilter ftLcdFilter; |
739 |
char horizontal = 1; |
740 |
FcBool b; |
741 |
|
742 |
// subpixel order: |
743 |
if (aaType == TEXT_AA_ON) |
744 |
ftRenderMode = FT_RENDER_MODE_NORMAL; |
745 |
else if (aaType == TEXT_AA_OFF) |
746 |
ftRenderMode = FT_RENDER_MODE_MONO; |
747 |
else if (FcPatternGetBool(pattern, FC_ANTIALIAS, 0, &b) == FcResultMatch) |
748 |
if (b) { |
749 |
int subpixel = FC_RGBA_UNKNOWN; |
750 |
FcPatternGetInteger(pattern, FC_RGBA, 0, &subpixel); |
751 |
if (subpixel == FC_RGBA_UNKNOWN) |
752 |
subpixel = FC_RGBA_NONE; |
753 |
switch (subpixel) { |
754 |
case FC_RGBA_NONE: |
755 |
ftRenderMode = FT_RENDER_MODE_NORMAL; |
756 |
break; |
757 |
case FC_RGBA_RGB: |
758 |
case FC_RGBA_BGR: |
759 |
ftRenderMode = FT_RENDER_MODE_LCD; |
760 |
horizontal = 1; |
761 |
break; |
762 |
case FC_RGBA_VRGB: |
763 |
case FC_RGBA_VBGR: |
764 |
ftRenderMode = FT_RENDER_MODE_LCD_V; |
765 |
horizontal = 0; |
766 |
break; |
767 |
default: |
768 |
break; |
769 |
} |
770 |
} else { |
771 |
ftRenderMode = FT_RENDER_MODE_NORMAL; |
772 |
} |
773 |
|
774 |
// loading mode: |
775 |
if (aaType == TEXT_AA_OFF) |
776 |
ftLoadFalgs |= FT_LOAD_TARGET_MONO; |
777 |
else { |
778 |
int hint_style = FC_HINT_NONE; |
779 |
FcPatternGetInteger(pattern, FC_HINT_STYLE, 0, &hint_style); |
780 |
switch (hint_style) { |
781 |
case FC_HINT_NONE: |
782 |
ftLoadFalgs |= FT_LOAD_NO_HINTING; |
783 |
break; |
784 |
case FC_HINT_SLIGHT: |
785 |
ftLoadFalgs |= FT_LOAD_TARGET_LIGHT; |
786 |
break; |
787 |
case FC_HINT_MEDIUM: |
788 |
ftLoadFalgs |= FT_LOAD_TARGET_NORMAL; |
789 |
break; |
790 |
case FC_HINT_FULL: |
791 |
if (aaType == TEXT_AA_ON) |
792 |
ftLoadFalgs |= FT_LOAD_TARGET_NORMAL; |
793 |
else |
794 |
ftLoadFalgs |= horizontal ? FT_LOAD_TARGET_LCD : FT_LOAD_TARGET_LCD_V; |
795 |
break; |
796 |
default: |
797 |
// what else to use as default? |
798 |
ftLoadFalgs |= FT_LOAD_TARGET_NORMAL; |
799 |
break; |
800 |
} |
801 |
} |
802 |
|
803 |
// autohinting: |
804 |
if (FcPatternGetBool(pattern, FC_AUTOHINT, 0, &b) == FcResultMatch) |
805 |
if (b) |
806 |
ftLoadFalgs |= FT_LOAD_FORCE_AUTOHINT; |
807 |
|
808 |
// LCD filter: |
809 |
int filter = FC_LCD_DEFAULT; |
810 |
FcPatternGetInteger(pattern, FC_LCD_FILTER, 0, &filter); |
811 |
switch (filter) { |
812 |
case FC_LCD_NONE: |
813 |
ftLcdFilter = FT_LCD_FILTER_NONE; |
814 |
break; |
815 |
case FC_LCD_DEFAULT: |
816 |
ftLcdFilter = FT_LCD_FILTER_DEFAULT; |
817 |
break; |
818 |
case FC_LCD_LIGHT: |
819 |
ftLcdFilter = FT_LCD_FILTER_LIGHT; |
820 |
break; |
821 |
case FC_LCD_LEGACY: |
822 |
ftLcdFilter = FT_LCD_FILTER_LEGACY; |
823 |
break; |
824 |
default: |
825 |
// new unknown lcd filter type?! will use default one: |
826 |
ftLcdFilter = FT_LCD_FILTER_DEFAULT; |
827 |
break; |
828 |
} |
829 |
|
830 |
FcPatternDestroy(pattern); |
831 |
|
832 |
rp->ftRenderMode = ftRenderMode; |
833 |
rp->ftLoadFlags = ftLoadFalgs; |
834 |
rp->ftLcdFilter = ftLcdFilter; |
835 |
} |
695 |
|
836 |
|
696 |
/* |
837 |
/* |
697 |
* Class: sun_font_FreetypeFontScaler |
838 |
* Class: sun_font_FreetypeFontScaler |
Lines 707-713
Link Here
|
707 |
UInt16 width, height; |
848 |
UInt16 width, height; |
708 |
GlyphInfo *glyphInfo; |
849 |
GlyphInfo *glyphInfo; |
709 |
int glyph_index; |
850 |
int glyph_index; |
710 |
int renderFlags = FT_LOAD_RENDER, target; |
|
|
711 |
FT_GlyphSlot ftglyph; |
851 |
FT_GlyphSlot ftglyph; |
712 |
|
852 |
|
713 |
FTScalerContext* context = |
853 |
FTScalerContext* context = |
Lines 725-756
Link Here
|
725 |
return ptr_to_jlong(getNullGlyphImage()); |
865 |
return ptr_to_jlong(getNullGlyphImage()); |
726 |
} |
866 |
} |
727 |
|
867 |
|
728 |
/* if algorithmic styling is required then we do not request bitmap */ |
868 |
RenderingProperties renderingProperties; |
729 |
if (context->doBold || context->doItalize) { |
869 |
readFontconfig((const FcChar8 *) scalerInfo->face->family_name, |
730 |
renderFlags = FT_LOAD_DEFAULT; |
870 |
context->ptsz, context->aaType, &renderingProperties); |
731 |
} |
|
|
732 |
|
733 |
/* NB: in case of non identity transform |
734 |
we might also prefer to disable transform before hinting, |
735 |
and apply it explicitly after hinting is performed. |
736 |
Or we can disable hinting. */ |
737 |
|
738 |
/* select appropriate hinting mode */ |
739 |
if (context->aaType == TEXT_AA_OFF) { |
740 |
target = FT_LOAD_TARGET_MONO; |
741 |
} else if (context->aaType == TEXT_AA_ON) { |
742 |
target = FT_LOAD_TARGET_NORMAL; |
743 |
} else if (context->aaType == TEXT_AA_LCD_HRGB || |
744 |
context->aaType == TEXT_AA_LCD_HBGR) { |
745 |
target = FT_LOAD_TARGET_LCD; |
746 |
} else { |
747 |
target = FT_LOAD_TARGET_LCD_V; |
748 |
} |
749 |
renderFlags |= target; |
750 |
|
871 |
|
751 |
glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode); |
872 |
glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode); |
752 |
|
873 |
|
753 |
error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags); |
874 |
FT_Library_SetLcdFilter(scalerInfo->library, renderingProperties.ftLcdFilter); |
|
|
875 |
|
876 |
error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderingProperties.ftLoadFlags); |
754 |
if (error) { |
877 |
if (error) { |
755 |
//do not destroy scaler yet. |
878 |
//do not destroy scaler yet. |
756 |
//this can be problem of particular context (e.g. with bad transform) |
879 |
//this can be problem of particular context (e.g. with bad transform) |
Lines 767-777
Link Here
|
767 |
FT_GlyphSlot_Oblique(ftglyph); |
890 |
FT_GlyphSlot_Oblique(ftglyph); |
768 |
} |
891 |
} |
769 |
|
892 |
|
770 |
/* generate bitmap if it is not done yet |
893 |
FT_Render_Glyph(ftglyph, renderingProperties.ftRenderMode); |
771 |
e.g. if algorithmic styling is performed and style was added to outline */ |
|
|
772 |
if (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE) { |
773 |
FT_Render_Glyph(ftglyph, FT_LOAD_TARGET_MODE(target)); |
774 |
} |
775 |
|
894 |
|
776 |
width = (UInt16) ftglyph->bitmap.width; |
895 |
width = (UInt16) ftglyph->bitmap.width; |
777 |
height = (UInt16) ftglyph->bitmap.rows; |
896 |
height = (UInt16) ftglyph->bitmap.rows; |
Lines 984-990
Link Here
|
984 |
static FT_Outline* getFTOutline(JNIEnv* env, jobject font2D, |
1103 |
static FT_Outline* getFTOutline(JNIEnv* env, jobject font2D, |
985 |
FTScalerContext *context, FTScalerInfo* scalerInfo, |
1104 |
FTScalerContext *context, FTScalerInfo* scalerInfo, |
986 |
jint glyphCode, jfloat xpos, jfloat ypos) { |
1105 |
jint glyphCode, jfloat xpos, jfloat ypos) { |
987 |
int renderFlags; |
|
|
988 |
int glyph_index; |
1106 |
int glyph_index; |
989 |
FT_Error error; |
1107 |
FT_Error error; |
990 |
FT_GlyphSlot ftglyph; |
1108 |
FT_GlyphSlot ftglyph; |
Lines 999-1009
Link Here
|
999 |
return NULL; |
1117 |
return NULL; |
1000 |
} |
1118 |
} |
1001 |
|
1119 |
|
1002 |
renderFlags = FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; |
1120 |
RenderingProperties renderingProperties; |
|
|
1121 |
readFontconfig((const FcChar8 *) scalerInfo->face->family_name, |
1122 |
context->ptsz, context->aaType, &renderingProperties); |
1003 |
|
1123 |
|
1004 |
glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode); |
1124 |
glyph_index = FT_Get_Char_Index(scalerInfo->face, glyphCode); |
1005 |
|
1125 |
|
1006 |
error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderFlags); |
1126 |
error = FT_Load_Glyph(scalerInfo->face, glyphCode, renderingProperties.ftLoadFlags); |
1007 |
if (error) { |
1127 |
if (error) { |
1008 |
return NULL; |
1128 |
return NULL; |
1009 |
} |
1129 |
} |