24 #include "openfontsprivate.h" |
24 #include "openfontsprivate.h" |
25 #include <linkedfonts.h> |
25 #include <linkedfonts.h> |
26 #include "linkedfontsprivate.h" |
26 #include "linkedfontsprivate.h" |
27 #include <graphics/openfontrasterizer.h> |
27 #include <graphics/openfontrasterizer.h> |
28 #include <graphics/gdi/glyphsample.h> |
28 #include <graphics/gdi/glyphsample.h> |
|
29 #include <e32math.h> |
|
30 |
|
31 #include "OstTraceDefinitions.h" |
|
32 #ifdef OST_TRACE_COMPILER_IN_USE |
|
33 #include "OPENFONTTraces.h" |
|
34 #endif |
|
35 |
29 |
36 |
30 const TInt KSessionCacheEntries = 512; |
37 const TInt KSessionCacheEntries = 512; |
31 const TInt KDefaultSlantFactor = 20480; |
38 const TInt KDefaultSlantFactor = 20480; |
32 const TInt KOneIn16Dot16FixedPointFormat = 65536; |
39 const TInt KOneIn16Dot16FixedPointFormat = 65536; |
33 |
40 |
784 void COpenFont::DeleteShaper() const |
793 void COpenFont::DeleteShaper() const |
785 { |
794 { |
786 delete iShaper; |
795 delete iShaper; |
787 } |
796 } |
788 |
797 |
|
798 TInt COpenFont::GetFontTable(TUint32 aTag, TAny*& aTableContent, TInt& aLength) |
|
799 { |
|
800 // get the extension API for GetTrueTypeTable() if available |
|
801 TAny* ext = NULL; |
|
802 ExtendedInterface(KUidOpenFontTrueTypeExtension, ext); |
|
803 MOpenFontTrueTypeExtension* extensionInterface = |
|
804 reinterpret_cast<MOpenFontTrueTypeExtension*>(ext); |
|
805 |
|
806 TInt ret = KErrNone; |
|
807 if (extensionInterface == NULL) |
|
808 { |
|
809 ret = KErrNotSupported; |
|
810 } |
|
811 else |
|
812 { |
|
813 TUint32 tag = aTag; |
|
814 TInt len = 0; |
|
815 aTableContent = extensionInterface->GetTrueTypeTable(ret, tag, &len); |
|
816 if (KErrNone == ret) |
|
817 { |
|
818 aLength = len; |
|
819 } |
|
820 } |
|
821 return ret; |
|
822 } |
|
823 |
|
824 TInt COpenFont::GetGlyphOutline(TUint aCode, |
|
825 TBool aHinted, TAny*& aOutline, TInt &aLength) |
|
826 { |
|
827 // get the extension API for GetTrueTypeTable() if available |
|
828 TAny* ext = NULL; |
|
829 ExtendedInterface(KUidOpenFontGlyphOutlineExtension, ext); |
|
830 MOpenFontGlyphOutlineExtension *extensionInterface = |
|
831 reinterpret_cast<MOpenFontGlyphOutlineExtension*>(ext); |
|
832 |
|
833 TInt ret = KErrNone; |
|
834 if (extensionInterface == NULL) |
|
835 { |
|
836 ret = KErrNotSupported; |
|
837 } |
|
838 else |
|
839 { |
|
840 ret = extensionInterface->GetGlyphOutline(aCode, ETrue, |
|
841 aHinted, aOutline, aLength); |
|
842 } |
|
843 return ret; |
|
844 } |
|
845 |
789 |
846 |
790 /** |
847 /** |
791 A constructor initialised with a TCharacterMetrics object. |
848 A constructor initialised with a TCharacterMetrics object. |
792 |
849 |
793 This is the old-style character metrics object. As for other T classes, there |
850 This is the old-style character metrics object. As for other T classes, there |
846 void COpenFont::OnFileDeleted() |
903 void COpenFont::OnFileDeleted() |
847 { |
904 { |
848 iFileOffset = 0; |
905 iFileOffset = 0; |
849 } |
906 } |
850 |
907 |
851 COpenFontGlyphCache* COpenFont::GetGlyphCache() |
908 COpenFontGlyphCache* COpenFont::GetGlyphCache() const |
852 { |
909 { |
853 if (iGlyphCacheOffset == 0) |
910 if (iGlyphCacheOffset == 0) |
854 { |
911 { |
855 return NULL; |
912 return NULL; |
856 } |
913 } |
857 return reinterpret_cast<COpenFontGlyphCache*>(PtrAdd(this, iGlyphCacheOffset)); |
914 return reinterpret_cast<COpenFontGlyphCache*>(PtrAdd(const_cast<COpenFont*>(this), iGlyphCacheOffset)); |
858 } |
915 } |
859 |
916 |
860 const COpenFontGlyph* COpenFont::Glyph(TInt aSessionHandle, TInt aCode) const |
917 const COpenFontGlyph* COpenFont::Glyph(TInt aSessionHandle, TInt aCode) const |
861 { |
918 { |
862 const COpenFontGlyph* glyph = const_cast<COpenFont*>(this)->FontCacheGlyph(aCode); |
919 const COpenFontGlyph* glyph = const_cast<COpenFont*>(this)->FontCacheGlyph(aCode); |
891 be resized - this is not allowed by the kernel. |
948 be resized - this is not allowed by the kernel. |
892 The cache is now created in COpenFont::Rasterize which can only be called within the context of FBSERV |
949 The cache is now created in COpenFont::Rasterize which can only be called within the context of FBSERV |
893 @param aCode The code for the glpyh to look for in the cache |
950 @param aCode The code for the glpyh to look for in the cache |
894 @return A pointer to the requested glyph if it was found in the glyph cache, NULL if it was not found. |
951 @return A pointer to the requested glyph if it was found in the glyph cache, NULL if it was not found. |
895 */ |
952 */ |
896 const COpenFontGlyph* COpenFont::FontCacheGlyph(TInt aCode) |
953 const COpenFontGlyph* COpenFont::FontCacheGlyph(TInt aCode) const |
897 { |
954 { |
898 if (COpenFontGlyphCache* glyphCache = GetGlyphCache()) |
955 if (COpenFontGlyphCache* glyphCache = GetGlyphCache()) |
899 { |
956 { |
900 if ((aCode & 0x80000000) != 0) |
957 if ((aCode & 0x80000000) != 0) |
901 { |
958 { |
1054 } |
1111 } |
1055 } |
1112 } |
1056 iEntryArray.Close(aHeap); |
1113 iEntryArray.Close(aHeap); |
1057 } |
1114 } |
1058 |
1115 |
1059 const COpenFontGlyph* COpenFontSessionCache::Glyph(const COpenFont* aFont, TInt aCode, TInt& aIndex) |
1116 const COpenFontGlyph* COpenFontSessionCache::Glyph(const COpenFont* aFont, TInt aCode, TInt& aIndex) const |
1060 { |
1117 { |
1061 aIndex = -1; |
1118 aIndex = -1; |
1062 TInt oldest = KMaxTInt; |
|
1063 TInt oldest_index = 0; |
|
1064 TInt numEntries = iEntryArray.Count(); |
1119 TInt numEntries = iEntryArray.Count(); |
1065 TInt index = GLYPH_CODE(aCode) % numEntries; // simple hash function to shorten searches |
1120 TInt index = GLYPH_CODE(aCode) % numEntries; // simple hash function to shorten searches |
1066 for (TInt i = 0; i < numEntries; ++i, ++index) |
1121 for (TInt i = 0; i < numEntries; ++i, ++index) |
1067 { |
1122 { |
1068 if (index >= numEntries) |
1123 if (index >= numEntries) |
|
1124 { |
1069 index = 0; |
1125 index = 0; |
1070 COpenFontSessionCacheEntry* entry = iEntryArray[index]; |
1126 } |
|
1127 const COpenFontSessionCacheEntry* entry = iEntryArray[index]; |
1071 if (entry == NULL) |
1128 if (entry == NULL) |
1072 { |
1129 { |
1073 if (aIndex == -1) |
1130 if (aIndex < 0) |
|
1131 { |
1074 aIndex = index; |
1132 aIndex = index; |
1075 } |
|
1076 else |
|
1077 { |
|
1078 if (entry->Font() == aFont && entry->iCode == aCode) |
|
1079 { |
|
1080 entry->iLastAccess = iLastAccess++; |
|
1081 return entry; |
|
1082 } |
|
1083 if (entry->iLastAccess < oldest) |
|
1084 { |
|
1085 oldest = entry->iLastAccess; |
|
1086 oldest_index = index; |
|
1087 } |
1133 } |
1088 } |
1134 } |
1089 } |
1135 else if (entry->Font() == aFont && entry->iCode == aCode) |
1090 if (aIndex == -1) |
1136 { |
1091 aIndex = oldest_index; |
1137 return entry; |
|
1138 } |
|
1139 } |
1092 return NULL; |
1140 return NULL; |
1093 } |
1141 } |
1094 |
1142 |
1095 |
1143 |
1096 void COpenFontSessionCache::Insert(RHeap* aHeap, COpenFontSessionCacheEntry* aEntry, TInt aIndex) |
1144 void COpenFontSessionCache::Insert(RHeap* aHeap, COpenFontSessionCacheEntry* aEntry, TInt aIndex) |
1097 { |
1145 { |
1098 if (aIndex < 0 || aIndex >= iEntryArray.Count()) |
1146 if (aIndex >= iEntryArray.Count()) |
1099 { |
1147 { |
1100 Panic(EFntSessionCacheIndexOutOfRange); |
1148 Panic(EFntSessionCacheIndexOutOfRange); |
1101 } |
1149 } |
|
1150 if (aIndex < 0) |
|
1151 { |
|
1152 aIndex = Math::Rand(iRandomSeed) % iEntryArray.Count(); |
|
1153 } |
1102 COpenFontSessionCacheEntry::Delete(aHeap, iEntryArray[aIndex]); |
1154 COpenFontSessionCacheEntry::Delete(aHeap, iEntryArray[aIndex]); |
1103 iEntryArray.SetAt(aIndex, aEntry); |
1155 iEntryArray.SetAt(aIndex, aEntry); |
1104 aEntry->iLastAccess = iLastAccess++; |
|
1105 } |
1156 } |
1106 |
1157 |
1107 COpenFontSessionCache::COpenFontSessionCache(TInt aSessionHandle): |
1158 COpenFontSessionCache::COpenFontSessionCache(TInt aSessionHandle): |
1108 iSessionHandle(aSessionHandle), |
1159 iSessionHandle(aSessionHandle), |
1109 iLastAccess(0) |
1160 iRandomSeed(0) |
1110 { |
1161 { |
1111 } |
1162 } |
1112 |
1163 |
1113 TInt COpenFontSessionCacheList::AddCache(COpenFontSessionCache* aCache) |
1164 TInt COpenFontSessionCacheList::AddCache(COpenFontSessionCache* aCache) |
1114 { |
1165 { |
1115 for (TInt index = 0; index < EMaxNumCaches; ++index) |
1166 for (TInt index = 0; index < EMaxNumCaches; ++index) |
1241 const TUint16 KSignBit = 1<<(KBitsForUnderline-1); //sign bit for the lower number, which can be signed |
1292 const TUint16 KSignBit = 1<<(KBitsForUnderline-1); //sign bit for the lower number, which can be signed |
1242 const TUint32 KTop16Of32Bits = 0xffff0000; |
1293 const TUint32 KTop16Of32Bits = 0xffff0000; |
1243 |
1294 |
1244 EXPORT_C void TOpenFontMetrics::SetBaselineCorrection(TInt aBaselineCorrection) |
1295 EXPORT_C void TOpenFontMetrics::SetBaselineCorrection(TInt aBaselineCorrection) |
1245 { |
1296 { |
1246 __ASSERT_DEBUG(aBaselineCorrection<(1<<(KBitsForUnderline-1)), Panic(EFntOverFlow)); |
1297 if (aBaselineCorrection >= (1<<(KBitsForUnderline-1))) |
1247 __ASSERT_DEBUG(aBaselineCorrection>(0-(1<<(KBitsForUnderline-1))), Panic(EFntOverFlow)); |
1298 { |
|
1299 OstTrace1( TRACE_FATAL, TOPENFONTMETRICS_SETBASELINECORRECTION, "aBaselineCorrection=%d, Panic(EFntOverFlow)", aBaselineCorrection ); |
|
1300 __ASSERT_DEBUG(0, Panic(EFntOverFlow)); |
|
1301 } |
|
1302 if (aBaselineCorrection <= (0-(1<<(KBitsForUnderline-1)))) |
|
1303 { |
|
1304 OstTrace1( TRACE_FATAL, DUP1_TOPENFONTMETRICS_SETBASELINECORRECTION, "aBaselineCorrection=%d, Panic(EFntOverFlow)", aBaselineCorrection ); |
|
1305 __ASSERT_DEBUG(0, Panic(EFntOverFlow)); |
|
1306 } |
1248 |
1307 |
1249 TUint16 value = iBaselineCorrection; |
1308 TUint16 value = iBaselineCorrection; |
1250 value &=~KMaskUnderline; //zero all the underline position bits |
1309 value &=~KMaskUnderline; //zero all the underline position bits |
1251 if (aBaselineCorrection<0) |
1310 if (aBaselineCorrection<0) |
1252 { |
1311 { |
1881 TBool TOpenFontSpec::ApplyRatio(TInt& aValue, TInt aNumerator, TInt aDenominator) |
1945 TBool TOpenFontSpec::ApplyRatio(TInt& aValue, TInt aNumerator, TInt aDenominator) |
1882 { |
1946 { |
1883 TInt64 value(aValue); |
1947 TInt64 value(aValue); |
1884 value = (value * aNumerator) / aDenominator; |
1948 value = (value * aNumerator) / aDenominator; |
1885 aValue = I64LOW(value); |
1949 aValue = I64LOW(value); |
1886 __ASSERT_DEBUG(I64HIGH(value) == 0, Panic(EFntOverFlow)); |
1950 if (I64HIGH(value) != 0) |
|
1951 { |
|
1952 OstTrace1( TRACE_FATAL, TOPENFONTSPEC_APPLYRATIO, "value=%ld, Panic(EFntOverFlow)", value ); |
|
1953 __ASSERT_DEBUG(0, Panic(EFntOverFlow)); |
|
1954 } |
1887 return I64HIGH(value) != 0; |
1955 return I64HIGH(value) != 0; |
1888 } |
1956 } |
1889 |
1957 |
1890 /** |
1958 /** |
1891 Same as above function but this takes a TInt32 not a TInt |
1959 Same as above function but this takes a TInt32 not a TInt |