154 The returned font is not associated to a specific device" |
154 The returned font is not associated to a specific device" |
155 |
155 |
156 |proto| |
156 |proto| |
157 |
157 |
158 RecentlyUsedFonts notNil ifTrue:[ |
158 RecentlyUsedFonts notNil ifTrue:[ |
159 proto := RecentlyUsedFonts |
159 proto := RecentlyUsedFonts |
160 detect:[:fn | |
160 detect:[:fn | |
161 fn family = familyString |
161 fn sameFamily: familyString |
162 and:[ fn size = size and:[fn sizeUnit = sizeUnit |
162 face: faceString |
163 and:[ fn face = faceString |
163 style: styleString |
164 and:[ (fn style = styleString |
164 size: size |
165 or:[ (fn style = 'oblique' and:[styleString = 'italic']) |
165 unit: sizeUnit |
166 or:[ (fn style = 'italic' and:[styleString = 'oblique']) ]]) ]]]]] |
166 pixelSize: nil |
167 ifNone:nil. |
167 encoding: encoding] |
168 proto notNil ifTrue:[ |
168 ifNone:[ nil ]. |
169 ^ proto |
169 proto notNil ifTrue:[ |
170 ]. |
170 ^ proto |
|
171 ]. |
171 ]. |
172 ]. |
172 |
173 |
173 CachedFontList notNil ifTrue:[ |
174 CachedFontList notNil ifTrue:[ |
174 proto := CachedFontList |
175 proto := CachedFontList |
175 detect:[:fn | |
176 detect:[:fn | |
176 fn family = familyString |
177 fn sameFamily: familyString |
177 and:[ fn face = faceString |
178 face: faceString |
178 and:[ (fn style = styleString |
179 style: styleString |
179 or:[ (fn style = 'oblique' and:[styleString = 'italic']) |
180 size: size |
180 or:[ (fn style = 'italic' and:[styleString = 'oblique']) ]]) ]]] |
181 unit: sizeUnit |
181 ifNone:nil. |
182 pixelSize: nil |
182 proto notNil ifTrue:[ |
183 encoding: encoding] |
183 ^ (proto shallowCopy) |
184 ifNone:[ nil ]. |
184 setDevice: nil patternId: nil fontId: nil; |
185 proto notNil ifTrue:[ |
185 family:familyString face:faceString style:styleString size:size sizeUnit:sizeUnit encoding:encoding |
186 ^ (proto shallowCopy) |
186 ]. |
187 setDevice: nil patternId: nil fontId: nil; |
|
188 family:familyString face:faceString style:styleString size:size sizeUnit:sizeUnit encoding:encoding |
|
189 ]. |
187 ]. |
190 ]. |
188 ^ super |
191 ^ super |
189 family:familyString face:faceString style:styleString size:size sizeUnit:sizeUnit encoding:encoding |
192 family:familyString face:faceString style:styleString size:size sizeUnit:sizeUnit encoding:encoding |
|
193 |
|
194 "Modified: / 29-02-2016 / 08:34:41 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
190 ! |
195 ! |
191 |
196 |
192 for:aFontOrFontDescription |
197 for:aFontOrFontDescription |
193 ^ self |
198 ^ self |
194 family:aFontOrFontDescription family |
199 family:aFontOrFontDescription family |
750 |
747 |
751 onDevice:aGraphicsDevice |
748 onDevice:aGraphicsDevice |
752 "Create a new XftFont representing the closes font as |
749 "Create a new XftFont representing the closes font as |
753 myself on aDevice; if one already exists, return the one." |
750 myself on aDevice; if one already exists, return the one." |
754 |
751 |
|
752 ^ self onDevice: aGraphicsDevice ifAbsent: nil |
|
753 |
|
754 "Modified: / 14-04-1997 / 18:22:31 / cg" |
|
755 "Modified: / 29-02-2016 / 07:08:01 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
756 ! |
|
757 |
|
758 onDevice:aGraphicsDevice ifAbsent: aBlock |
|
759 "Create a new XftFont representing the closes font as |
|
760 myself on aDevice; if one already exists, return the one." |
|
761 |
755 | myPatternId closestPatternId1 closestPatternId2 newFontId | |
762 | myPatternId closestPatternId1 closestPatternId2 newFontId | |
756 |
763 |
757 "if I am already assigned to that device ..." |
764 (device == aGraphicsDevice) ifTrue:[ |
758 (device == aGraphicsDevice) ifTrue:[^ self]. |
765 "I am already assigned to that device ..." |
759 |
766 ^ self |
760 (aGraphicsDevice isNil and:[device notNil]) ifTrue:[ |
767 ]. |
761 ^ self |
768 aGraphicsDevice isNil ifTrue:[ |
|
769 ^ self |
762 ]. |
770 ]. |
763 aGraphicsDevice supportsXftFonts ifFalse:[ |
771 aGraphicsDevice supportsXftFonts ifFalse:[ |
764 ^ super onDevice:aGraphicsDevice |
772 ^ super onDevice:aGraphicsDevice ifAbsent:aBlock. |
765 ]. |
|
766 |
|
767 (closestFont notNil and:[closestFont graphicsDevice == aGraphicsDevice]) ifTrue:[ |
|
768 ^ closestFont onDevice: aGraphicsDevice. |
|
769 ]. |
773 ]. |
770 |
774 |
771 RecentlyUsedFonts isNil ifTrue:[ |
775 RecentlyUsedFonts isNil ifTrue:[ |
772 RecentlyUsedFonts := OrderedCollection new:10. |
776 RecentlyUsedFonts := OrderedCollection new:20. |
773 ]. |
777 ]. |
774 |
778 |
775 RecentlyUsedFonts keysAndValuesDo:[:index :aFont | |
779 RecentlyUsedFonts keysAndValuesDo:[:index :aFont | |
776 ((aFont class == self class) and:[(self sameDeviceFontAs:aFont) and:[aFont getFontId notNil]]) ifTrue:[ |
780 ((aFont class == self class) and:[(self sameDeviceFontAs:aFont)]) ifTrue:[ |
777 "/ Transcript showCR:'hit'. |
781 "/ Transcript showCR:'hit'. |
778 RecentlyUsedFonts removeIndex:index. |
782 RecentlyUsedFonts |
779 RecentlyUsedFonts addFirst:aFont. |
783 removeIndex:index; |
780 ^ aFont |
784 addFirst:aFont. |
781 ] |
785 ^ aFont |
782 ]. |
786 ] |
783 |
787 ]. |
784 RecentlyUsedFonts size > 20 ifTrue:[ |
788 |
785 RecentlyUsedFonts removeLast. |
789 RecentlyUsedFonts size >= 20 ifTrue:[ |
|
790 RecentlyUsedFonts removeLast. |
786 ]. |
791 ]. |
787 |
792 |
788 aGraphicsDevice deviceFonts do:[:aFont | |
793 aGraphicsDevice deviceFonts do:[:aFont | |
789 ((aFont class == self class) and:[self sameDeviceFontAs:aFont]) ifTrue:[ |
794 ((aFont class == self class) and:[self sameDeviceFontAs:aFont]) ifTrue:[ |
790 RecentlyUsedFonts addFirst:aFont. |
795 RecentlyUsedFonts addFirst:aFont. |
791 ^ aFont |
796 ^ aFont |
792 ]. |
797 ]. |
793 ]. |
798 ]. |
794 |
799 |
|
800 "/ Transcript show: 'XFT font not found in cache:'; showCR: self printString. |
795 [ |
801 [ |
796 Error handle:[:ex | |
802 myPatternId := FcPattern fromFontDescription: self. |
797 ex suspendedContext fullPrintAll. |
803 newFontId := self xftFontOpenPattern: aGraphicsDevice displayId pattern: myPatternId. |
798 ^ self asNonXftFont onDevice:aGraphicsDevice |
804 newFontId notNil ifTrue:[ |
799 ] do:[ |
805 "/ Good, this font exists!! |
800 myPatternId := FcPattern fromFontDescription: self. |
|
801 ]. |
|
802 |
|
803 newFontId := self xftFontOpenPattern: aGraphicsDevice displayId pattern: myPatternId. |
|
804 newFontId notNil ifTrue:[ |
|
805 "/ Good, this font exists!! |
|
806 myPatternId := nil. |
806 myPatternId := nil. |
807 fontId := newFontId. |
807 ] ifFalse:[ |
808 device := aGraphicsDevice. |
808 closestPatternId1 := self xftFontMatch: aGraphicsDevice displayId screen: aGraphicsDevice screen pattern: myPatternId. |
809 aGraphicsDevice registerFont:self. |
809 closestPatternId1 isNil ifTrue:[ |
810 RecentlyUsedFonts addFirst:self. |
810 self error: 'No font matches'. |
811 ^ self. |
811 ]. |
812 ] ifFalse:[ |
812 closestPatternId2 := closestPatternId1 copy. |
813 closestPatternId1 := self xftFontMatch: aGraphicsDevice displayId screen: aGraphicsDevice screen pattern: myPatternId. |
813 newFontId := self xftFontOpenPattern: aGraphicsDevice displayId pattern: closestPatternId1. |
814 closestPatternId1 isNil ifTrue:[ |
814 "/ !!!!!!!! closestPatternId is no longer valid !!!!!!!! |
815 self error: 'No font matches'. |
815 closestPatternId1 := nil. |
816 ]. |
816 newFontId isNil ifTrue:[ |
817 " |
817 ^ aBlock value |
818 closestPatternId at: 'family' |
818 ]. |
819 closestPatternId at: 'size' |
819 ]. |
820 " |
820 fontId := newFontId. |
821 closestPatternId2 := closestPatternId1 copy. |
821 device := aGraphicsDevice. |
822 newFontId := self xftFontOpenPattern: aGraphicsDevice displayId pattern: closestPatternId1. |
822 aGraphicsDevice registerFont:self. |
823 "/ !!!!!!!! closestPatternId is no longer valid !!!!!!!! |
823 RecentlyUsedFonts addFirst:self. |
824 closestPatternId1 := nil. |
824 myPatternId notNil ifTrue:[myPatternId release]. |
825 newFontId isNil ifTrue:[ |
825 closestPatternId1 notNil ifTrue:[closestPatternId1 release]. |
826 self error: 'Pattern matched, but font could not be opened (should not happen)'. |
826 closestPatternId2 notNil ifTrue:[closestPatternId2 release]. |
827 ]. |
827 ^ self. |
828 |
|
829 "/ Search for existing registered font. Note, that XftFont instances |
|
830 "/ are shared (and refcounted) so newFontId = aFont getFontId is enough |
|
831 "/ to check whether some other font instance represents the same font... |
|
832 aGraphicsDevice deviceFonts do:[:aFont | |
|
833 ((self class == aFont class) and:[newFontId = aFont getFontId]) ifTrue:[ |
|
834 closestFont := aFont. |
|
835 ^ closestFont |
|
836 ]. |
|
837 ]. |
|
838 |
|
839 closestFont := self shallowCopy |
|
840 setDevice: aGraphicsDevice patternId: closestPatternId2 fontId: newFontId; |
|
841 yourself. |
|
842 aGraphicsDevice registerFont: closestFont. |
|
843 RecentlyUsedFonts addFirst:closestFont. |
|
844 ^ closestFont |
|
845 ]. |
|
846 ] ensure:[ |
828 ] ensure:[ |
847 myPatternId notNil ifTrue:[myPatternId release]. |
829 myPatternId notNil ifTrue:[myPatternId release]. |
848 closestPatternId1 notNil ifTrue:[closestPatternId1 release]. |
830 closestPatternId1 notNil ifTrue:[closestPatternId1 release]. |
849 closestPatternId2 notNil ifTrue:[closestPatternId2 release]. |
831 closestPatternId2 notNil ifTrue:[closestPatternId2 release]. |
850 ]. |
832 ]. |
851 |
833 |
852 " |
834 " |
853 (XftFontDescription family:'monospace' size:16) onDevice:Screen current |
835 (XftFontDescription family:'monospace' size:16) onDevice:Screen current |
854 " |
836 " |
855 |
837 |
856 "Modified: / 14-04-1997 / 18:22:31 / cg" |
838 "Modified: / 29-02-2016 / 08:36:13 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
857 "Modified: / 02-01-2014 / 23:43:27 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
858 ! |
|
859 |
|
860 onDevice:aWorkstation ifAbsent:aBlock |
|
861 "Create a new XftFont representing the same font as |
|
862 myself on aWorkstation. This does NOT try to look for existing |
|
863 or replacement fonts (i.e. can be used to get physical fonts)." |
|
864 |
|
865 ^ self onDevice:aWorkstation |
|
866 |
|
867 "Modified: / 02-01-2014 / 23:15:27 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
868 "Modified (comment): / 04-01-2014 / 02:06:22 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
869 ! ! |
839 ! ! |
870 |
840 |
871 !XftFontDescription methodsFor:'initialization'! |
841 !XftFontDescription methodsFor:'initialization'! |
872 |
842 |
873 setDevice: deviceArg patternId: patternIdArg fontId: fontIdArg |
843 setDevice: deviceArg patternId: patternIdArg fontId: fontIdArg |