Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: src/ports/SkFontHost_FreeType.cpp

Issue 213153006: Fix size of rotated text with FreeType. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « include/core/SkFloatingPoint.h ('k') | src/ports/SkFontHost_win.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkAdvancedTypefaceMetrics.h" 9 #include "SkAdvancedTypefaceMetrics.h"
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
11 #include "SkCanvas.h" 11 #include "SkCanvas.h"
12 #include "SkColorPriv.h" 12 #include "SkColorPriv.h"
13 #include "SkDescriptor.h" 13 #include "SkDescriptor.h"
14 #include "SkFDot6.h" 14 #include "SkFDot6.h"
15 #include "SkFloatingPoint.h" 15 #include "SkFloatingPoint.h"
16 #include "SkFontHost.h" 16 #include "SkFontHost.h"
17 #include "SkFontHost_FreeType_common.h" 17 #include "SkFontHost_FreeType_common.h"
18 #include "SkGlyph.h" 18 #include "SkGlyph.h"
19 #include "SkMask.h" 19 #include "SkMask.h"
20 #include "SkMaskGamma.h" 20 #include "SkMaskGamma.h"
21 #include "SkMatrix22.h"
21 #include "SkOTUtils.h" 22 #include "SkOTUtils.h"
22 #include "SkOnce.h" 23 #include "SkOnce.h"
23 #include "SkScalerContext.h" 24 #include "SkScalerContext.h"
24 #include "SkStream.h" 25 #include "SkStream.h"
25 #include "SkString.h" 26 #include "SkString.h"
26 #include "SkTemplates.h" 27 #include "SkTemplates.h"
27 #include "SkThread.h" 28 #include "SkThread.h"
28 29
29 #if defined(SK_CAN_USE_DLOPEN) 30 #if defined(SK_CAN_USE_DLOPEN)
30 #include <dlfcn.h> 31 #include <dlfcn.h>
31 #endif 32 #endif
32 #include <ft2build.h> 33 #include <ft2build.h>
33 #include FT_FREETYPE_H 34 #include FT_FREETYPE_H
34 #include FT_OUTLINE_H 35 #include FT_OUTLINE_H
35 #include FT_SIZES_H 36 #include FT_SIZES_H
36 #include FT_TRUETYPE_TABLES_H 37 #include FT_TRUETYPE_TABLES_H
37 #include FT_TYPE1_TABLES_H 38 #include FT_TYPE1_TABLES_H
38 #include FT_BITMAP_H 39 #include FT_BITMAP_H
39 // In the past, FT_GlyphSlot_Own_Bitmap was defined in this header file. 40 // In the past, FT_GlyphSlot_Own_Bitmap was defined in this header file.
40 #include FT_SYNTHESIS_H 41 #include FT_SYNTHESIS_H
41 #include FT_XFREE86_H 42 #include FT_XFREE86_H
42 #ifdef FT_LCD_FILTER_H 43 #ifdef FT_LCD_FILTER_H
43 #include FT_LCD_FILTER_H 44 #include FT_LCD_FILTER_H
44 #endif 45 #endif
45 46
47 // Defined in FreeType 2.3.8 and later.
48 // This is a silly build time check, we would need a runtime check if we really cared.
46 #ifdef FT_ADVANCES_H 49 #ifdef FT_ADVANCES_H
47 #include FT_ADVANCES_H 50 #include FT_ADVANCES_H
48 #endif 51 #endif
49 52
50 #if 0 53 #if 0
51 // Also include the files by name for build tools which require this. 54 // Also include the files by name for build tools which require this.
52 #include <freetype/freetype.h> 55 #include <freetype/freetype.h>
53 #include <freetype/ftoutln.h> 56 #include <freetype/ftoutln.h>
54 #include <freetype/ftsizes.h> 57 #include <freetype/ftsizes.h>
55 #include <freetype/tttables.h> 58 #include <freetype/tttables.h>
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 689
687 if (!canEmbed(face)) 690 if (!canEmbed(face))
688 info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font; 691 info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
689 692
690 return info; 693 return info;
691 #endif 694 #endif
692 } 695 }
693 696
694 /////////////////////////////////////////////////////////////////////////// 697 ///////////////////////////////////////////////////////////////////////////
695 698
696 #define BLACK_LUMINANCE_LIMIT 0x40
697 #define WHITE_LUMINANCE_LIMIT 0xA0
698
699 static bool bothZero(SkScalar a, SkScalar b) { 699 static bool bothZero(SkScalar a, SkScalar b) {
700 return 0 == a && 0 == b; 700 return 0 == a && 0 == b;
701 } 701 }
702 702
703 // returns false if there is any non-90-rotation or skew 703 // returns false if there is any non-90-rotation or skew
704 static bool isAxisAligned(const SkScalerContext::Rec& rec) { 704 static bool isAxisAligned(const SkScalerContext::Rec& rec) {
705 return 0 == rec.fPreSkewX && 705 return 0 == rec.fPreSkewX &&
706 (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) || 706 (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) ||
707 bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1])); 707 bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1]));
708 } 708 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 // load the font file 842 // load the font file
843 fStrikeIndex = -1; 843 fStrikeIndex = -1;
844 fFTSize = NULL; 844 fFTSize = NULL;
845 fFace = NULL; 845 fFace = NULL;
846 fFaceRec = ref_ft_face(typeface); 846 fFaceRec = ref_ft_face(typeface);
847 if (NULL == fFaceRec) { 847 if (NULL == fFaceRec) {
848 return; 848 return;
849 } 849 }
850 fFace = fFaceRec->fFace; 850 fFace = fFaceRec->fFace;
851 851
852 // compute our factors from the record 852 // A is the total matrix.
853 SkMatrix A;
854 fRec.getSingleMatrix(&A);
853 855
854 SkMatrix m; 856 SkScalar sx = A.getScaleX();
855 857 SkScalar sy = A.getScaleY();
856 fRec.getSingleMatrix(&m);
857
858 #ifdef DUMP_STRIKE_CREATION
859 SkString keyString;
860 SkFontHost::GetDescriptorKeyString(desc, &keyString);
861 printf("========== strike [%g %g %g] [%g %g %g %g] hints %d format %d %s\n", SkScalarToFloat(fRec.fTextSize),
862 SkScalarToFloat(fRec.fPreScaleX), SkScalarToFloat(fRec.fPreSkewX),
863 SkScalarToFloat(fRec.fPost2x2[0][0]), SkScalarToFloat(fRec.fPost2x2[0 ][1]),
864 SkScalarToFloat(fRec.fPost2x2[1][0]), SkScalarToFloat(fRec.fPost2x2[1 ][1]),
865 fRec.getHinting(), fRec.fMaskFormat, keyString.c_str());
866 #endif
867
868 // now compute our scale factors
869 SkScalar sx = m.getScaleX();
870 SkScalar sy = m.getScaleY();
871
872 fMatrix22Scalar.reset(); 858 fMatrix22Scalar.reset();
873 859
874 if (m.getSkewX() || m.getSkewY() || sx < 0 || sy < 0) { 860 //#define SK_IGNORE_FREETYPE_ROTATION_FIX
861 #ifdef SK_IGNORE_FREETYPE_ROTATION_FIX
862 if (A.getSkewX() || A.getSkewY() || sx < 0 || sy < 0) {
875 // sort of give up on hinting 863 // sort of give up on hinting
876 sx = SkMaxScalar(SkScalarAbs(sx), SkScalarAbs(m.getSkewX())); 864 sx = SkMaxScalar(SkScalarAbs(sx), SkScalarAbs(A.getSkewX()));
877 sy = SkMaxScalar(SkScalarAbs(m.getSkewY()), SkScalarAbs(sy)); 865 sy = SkMaxScalar(SkScalarAbs(A.getSkewY()), SkScalarAbs(sy));
878 sx = sy = SkScalarAve(sx, sy); 866 sx = sy = SkScalarAve(sx, sy);
879 867
880 SkScalar inv = SkScalarInvert(sx); 868 SkScalar inv = SkScalarInvert(sx);
881 869
882 // flip the skew elements to go from our Y-down system to FreeType's 870 // flip the skew elements to go from our Y-down system to FreeType's
883 fMatrix22.xx = SkScalarToFixed(SkScalarMul(m.getScaleX(), inv)); 871 fMatrix22.xx = SkScalarToFixed(SkScalarMul(A.getScaleX(), inv));
884 fMatrix22.xy = -SkScalarToFixed(SkScalarMul(m.getSkewX(), inv)); 872 fMatrix22.xy = -SkScalarToFixed(SkScalarMul(A.getSkewX(), inv));
885 fMatrix22.yx = -SkScalarToFixed(SkScalarMul(m.getSkewY(), inv)); 873 fMatrix22.yx = -SkScalarToFixed(SkScalarMul(A.getSkewY(), inv));
886 fMatrix22.yy = SkScalarToFixed(SkScalarMul(m.getScaleY(), inv)); 874 fMatrix22.yy = SkScalarToFixed(SkScalarMul(A.getScaleY(), inv));
887 875
888 fMatrix22Scalar.setScaleX(SkScalarMul(m.getScaleX(), inv)); 876 fMatrix22Scalar.setScaleX(SkScalarMul(A.getScaleX(), inv));
889 fMatrix22Scalar.setSkewX(-SkScalarMul(m.getSkewX(), inv)); 877 fMatrix22Scalar.setSkewX(-SkScalarMul(A.getSkewX(), inv));
890 fMatrix22Scalar.setSkewY(-SkScalarMul(m.getSkewY(), inv)); 878 fMatrix22Scalar.setSkewY(-SkScalarMul(A.getSkewY(), inv));
891 fMatrix22Scalar.setScaleY(SkScalarMul(m.getScaleY(), inv)); 879 fMatrix22Scalar.setScaleY(SkScalarMul(A.getScaleY(), inv));
892 } else { 880 } else {
893 fMatrix22.xx = fMatrix22.yy = SK_Fixed1; 881 fMatrix22.xx = fMatrix22.yy = SK_Fixed1;
894 fMatrix22.xy = fMatrix22.yx = 0; 882 fMatrix22.xy = fMatrix22.yx = 0;
895 } 883 }
896 fScale.set(sx, sy); 884 fScale.set(sx, sy);
897 fScaleX = SkScalarToFixed(sx); 885 fScaleX = SkScalarToFixed(sx);
898 fScaleY = SkScalarToFixed(sy); 886 fScaleY = SkScalarToFixed(sy);
887 #else
888 // In GDI, the hinter is aware of the current transformation
889 // (the transform is in some sense applied before/with the hinting).
890 // The bytecode can then test if it is rotated or stretched and decide
891 // to apply instructions or not.
892 //
893 // FreeType, however, always does the transformation strictly after hinting.
894 // It just sets 'rotated' and 'stretched' to false and only applies the
895 // size before hinting.
896 //
897 // Also, FreeType respects the head::flags::IntegerScaling flag,
898 // (although this is patched out on most major distros)
899 // so it is critical to get the size correct on the request.
900 //
901 // This also gets us the actual closest size on bitmap fonts as well.
902 if (A.getSkewX() || A.getSkewY() || sx < 0 || sy < 0) {
903 // h is where A maps the horizontal baseline.
904 SkPoint h = SkPoint::Make(SK_Scalar1, 0);
905 A.mapPoints(&h, 1);
906
907 // G is the Givens Matrix for A (rotational matrix where GA[0][1] == 0).
908 SkMatrix G;
909 SkComputeGivensRotation(h, &G);
910
911 // GA is the matrix A with rotation removed.
912 SkMatrix GA(G);
913 GA.preConcat(A);
914
915 sx = SkScalarAbs(GA.get(SkMatrix::kMScaleX));
916 sy = SkScalarAbs(GA.get(SkMatrix::kMScaleY));
917
918 // sA is the total matrix A without the text scale.
919 SkMatrix sA(A);
920 sA.preScale(SkScalarInvert(sx), SkScalarInvert(sy)); //remove text size
921
922 fMatrix22Scalar.setScaleX(sA.getScaleX());
923 fMatrix22Scalar.setSkewX(-sA.getSkewX());
924 fMatrix22Scalar.setSkewY(-sA.getSkewY());
925 fMatrix22Scalar.setScaleY(sA.getScaleY());
926 }
927 fScale.set(sx, sy);
928 fScaleX = SkScalarToFixed(sx);
929 fScaleY = SkScalarToFixed(sy);
930 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX());
931 fMatrix22.xy = SkScalarToFixed(fMatrix22Scalar.getSkewX());
932 fMatrix22.yx = SkScalarToFixed(fMatrix22Scalar.getSkewY());
933 fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY());
934 #endif
899 935
900 fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag); 936 fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
901 937
902 // compute the flags we send to Load_Glyph 938 // compute the flags we send to Load_Glyph
903 bool linearMetrics = SkToBool(fRec.fFlags & SkScalerContext::kSubpixelPositi oning_Flag); 939 bool linearMetrics = SkToBool(fRec.fFlags & SkScalerContext::kSubpixelPositi oning_Flag);
904 { 940 {
905 FT_Int32 loadFlags = FT_LOAD_DEFAULT; 941 FT_Int32 loadFlags = FT_LOAD_DEFAULT;
906 942
907 if (SkMask::kBW_Format == fRec.fMaskFormat) { 943 if (SkMask::kBW_Format == fRec.fMaskFormat) {
908 // See http://code.google.com/p/chromium/issues/detail?id=43252#c24 944 // See http://code.google.com/p/chromium/issues/detail?id=43252#c24
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after
1720 *style = (SkTypeface::Style) tempStyle; 1756 *style = (SkTypeface::Style) tempStyle;
1721 } 1757 }
1722 if (isFixedPitch) { 1758 if (isFixedPitch) {
1723 *isFixedPitch = FT_IS_FIXED_WIDTH(face); 1759 *isFixedPitch = FT_IS_FIXED_WIDTH(face);
1724 } 1760 }
1725 1761
1726 FT_Done_Face(face); 1762 FT_Done_Face(face);
1727 FT_Done_FreeType(library); 1763 FT_Done_FreeType(library);
1728 return true; 1764 return true;
1729 } 1765 }
OLDNEW
« no previous file with comments | « include/core/SkFloatingPoint.h ('k') | src/ports/SkFontHost_win.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698