Marcel Taeumel uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-mt.1326.mcz
==================== Summary ====================
Name: System-mt.1326
Author: mt
Time: 16 March 2022, 3:09:31.524608 pm
UUID: 4abf5e25-04e4-ef45-bff2-fe94bc13c45a
Ancestors: System-mt.1325
Warn the user if they try to install a font as code font that cannot display latin-1. Complements TrueType-mt.90
=============== Diff against System-mt.1325 ===============
Item was changed:
----- Method: UserInterfaceTheme class>>setFont:to: (in category 'tools - fonts') -----
setFont: symbolicName to: aFont
"Set symbolicName to aFont in all known UI themes. If aFont is a TrueType font, transform all themes into TTC-based ones."
(symbolicName = #standardSystemFont and: [aFont isTTCFont])
ifTrue: [self makeAllTTCBased].
+ symbolicName = #standardCodeFont
+ ifTrue: [ "Source code is mostly single-byte strings. Verify that this font can render those so that we can implement fast paths. See #displayByteString:on:from:to:at:kern:baselineY:."
+ (aFont minCodePoint <= 16r20 "space" and: [aFont maxCodePoint >= 16rFF])
+ ifFalse: [self notify: 'The standard code font should support latin-1 encoding but this one does not!! For performance reasons, there is no support for fallback fonts in single-byte strings. Please choose a different font as code font.' translated]].
self allThemes do: [:uit |
uit setFont: symbolicName to: aFont].!
Marcel Taeumel uploaded a new version of TrueType to project The Trunk:
http://source.squeak.org/trunk/TrueType-mt.90.mcz
==================== Summary ====================
Name: TrueType-mt.90
Author: mt
Time: 16 March 2022, 3:07:34.672608 pm
UUID: ca5aebaf-2eb7-124d-ad9b-a83c58d9718c
Ancestors: TrueType-mt.89
Speed up text composition and display for TrueType fonts. Extra speed-up for single-byte strings.
Using "Text melvilleSample," composition time changed from roughly 1000 microseconds to 90 microseconds. Display speed is roughly the same but less pressure on the GC. Might be more noticeable on slower machines.
The three optimization strategies are:
1. Avoid expensive fail of primitive 103 in CharacterScanner.
2. Avoid extra #hasGlyphOf: checks when possible.
3. Do not support #fallbackFont in single-byte strings, i.e., latin-1 (or ascii).
=============== Diff against TrueType-mt.89 ===============
Item was changed:
----- Method: TTCFont>>basicHasGlyphOf: (in category 'private') -----
basicHasGlyphOf: aCharacter
"Answer whether this font includes a glyph for the given character"
+ "^ self hasGlyphForCode: (self codeForCharacter: aCharacter)"
+ ^ self hasGlyphForCode: aCharacter charCode!
- ^ self hasGlyphForCode: (self codeForCharacter: aCharacter)!
Item was changed:
----- Method: TTCFont>>characterFormAt: (in category 'character shapes') -----
+ characterFormAt: aCharacter
- characterFormAt: character
- "Answer a Form copied out of the glyphs for the argument,
- character. Use a cached copy if possible."
+ cache ifNil: [self foregroundColor: Color black]. "make sure we have a cache"
+ "^ self characterFormAtCode: (self codeForCharacter: aCharacter)"
+ ^ self characterFormAtCode: aCharacter charCode!
- ^self formOf: character!
Item was added:
+ ----- Method: TTCFont>>characterFormAtCode: (in category 'character shapes') -----
+ characterFormAtCode: characterCode
+ "Answer a Form copied out of the glyphs for the argument,
+ character. Use a cached copy if possible."
+
+ | form |
+ cache ifNil: [self foregroundColor: Color black]. "make sure we have a cache"
+
+ form := cache at: (characterCode + 1).
+
+ form ifNil: [
+ form := self computeForm: characterCode.
+ form ifNil:[^nil].
+ cache at: characterCode+1 put: form.
+ GlyphCacheData at: (GlyphCacheIndex := GlyphCacheIndex \\ GlyphCacheSize + 1) put: form.
+ ].
+ ^form
+ !
Item was added:
+ ----- Method: TTCFont>>displayByteString:on:from:to:at:kern:baselineY: (in category 'displaying') -----
+ displayByteString: aByteString on: aBitBlt from: startIndex to: stopIndex at: aPoint kern: kernDelta baselineY: baselineY
+ "Optimized path for rendering single-byte strings (i.e. ascii or latin-1) without support for fallback fonts. Which means that if you try to render a single-byte string with a font that does not support latin-1, you will get an unpleasant surprise. See #widthOfByteCharacter:."
+
+ | form code destX destY offsetX |
+ destX := aPoint x.
+ destY := baselineY - self ascent.
+ aBitBlt sourceX: 0; sourceY: 0.
+ startIndex to: stopIndex do: [:charIndex |
+ code := (aByteString at: charIndex) asInteger. "Must be <= 16rFF !!!!"
+ form := self characterFormAtCode: code.
+ offsetX := form advanceWidth.
+ aBitBlt sourceForm: form.
+ aBitBlt destX: destX + form offset x.
+ aBitBlt destY: destY + form offset y.
+ aBitBlt width: form width.
+ aBitBlt height: form height.
+ aBitBlt copyBits.
+ destX := destX + offsetX + kernDelta].
+ ^ destX @ destY
+ !
Item was added:
+ ----- Method: TTCFont>>displayMultiString:on:from:to:at:kern:baselineY: (in category 'displaying') -----
+ displayMultiString: aString on: aBitBlt from: startIndex to: stopIndex at: aPoint kern: kernDelta baselineY: baselineY
+
+ | form glyphInfo destX destY hereX nextX actualFont |
+ destX := aPoint x.
+ glyphInfo := Array new: 5. "Cached across fallback lookup."
+ startIndex to: stopIndex do: [:charIndex |
+ self flag: #fallbackFont.
+ self glyphInfoOf: (aString at: charIndex) into: glyphInfo.
+ form := glyphInfo at: 1.
+ hereX := glyphInfo at: 2.
+ nextX := glyphInfo at: 3.
+ self flag: #fallbackFont.
+ (actualFont := glyphInfo at: 5) == aBitBlt lastFont
+ ifFalse: [actualFont installOn: aBitBlt].
+ destY := baselineY - (glyphInfo at: 4).
+ aBitBlt sourceForm: form.
+ aBitBlt destX: destX + form offset x.
+ aBitBlt destY: destY + form offset y.
+ aBitBlt sourceX: hereX; sourceY: 0.
+ aBitBlt width: form width.
+ aBitBlt height: form height.
+ aBitBlt copyBits.
+ destX := destX + (nextX - hereX) + kernDelta.
+ ].
+ ^ destX @ destY
+ !
Item was added:
+ ----- Method: TTCFont>>scanByteCharactersFrom:to:in:with:rightX: (in category 'character scanning') -----
+ scanByteCharactersFrom: startIndex to: stopIndex in: aByteString
+ with: aCharacterScanner rightX: rightX
+ "Overwritten to avoid primitive 103 for faster text composition bc. primitive-fail is too slow."
+
+ ^ aCharacterScanner
+ basicScanByteCharactersFrom: startIndex to: stopIndex
+ in: aByteString rightX: rightX!
Item was added:
+ ----- Method: TTCFont>>widthOfByteCharacter: (in category 'measuring') -----
+ widthOfByteCharacter: aCharacter
+ "Optimized path for composing single-byte strings (i.e. ascii or latin-1) without support for fallback fonts. Which means that if you try to compose a single-byte string with a font that does not support latin-1, you will get an unpleasant surprise. See #displayByteString:on:from:to:at:kern:baselineY:."
+
+ ^(self characterFormAtCode: aCharacter asInteger "<= 16rFF !!") advanceWidth!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1942.mcz
==================== Summary ====================
Name: Morphic-mt.1942
Author: mt
Time: 16 March 2022, 9:08:04.25415 am
UUID: bdbb3cf7-5899-8046-b07a-996d8188c27c
Ancestors: Morphic-mt.1941
Add commentary about the 900-character compromise in dialog messages.
=============== Diff against Morphic-mt.1941 ===============
Item was changed:
----- Method: DialogWindow>>message: (in category 'accessing') -----
message: aStringOrText
+ aStringOrText size > 900 ifTrue: [
+ "NOTE THAT this is an awkward compromise for clients misusing the medium of a dialog window. Because of a dialog's rather short lifespan, users should only be presented with compact content and a concise message. If you notice that your dialog is getting too tall or -- in this case -- wider than usual, please consider rewriting its message."
+ self messageMorph numCharactersPerLine: 65].
+
- aStringOrText size > 900
- ifTrue: [self messageMorph numCharactersPerLine: 65].
messageMorph contents: aStringOrText.
self setMessageParameters.!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1941.mcz
==================== Summary ====================
Name: Morphic-mt.1941
Author: mt
Time: 15 March 2022, 2:53:46.850959 pm
UUID: b0648cc0-8e62-9d42-be6d-03e117333c05
Ancestors: Morphic-mt.1940
Okay, for unusually long dialog texts, we go for 65 characters per line (on average), not just the default 45.
Here is an example:
CodeHolder new informPossiblyCorruptSource.
Again, see commentary in TextStyle >> #compositionWidthForNumChars
=============== Diff against Morphic-mt.1940 ===============
Item was changed:
----- Method: DialogWindow>>message: (in category 'accessing') -----
message: aStringOrText
+ aStringOrText size > 900
+ ifTrue: [self messageMorph numCharactersPerLine: 65].
messageMorph contents: aStringOrText.
self setMessageParameters.!
Marcel Taeumel uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-mt.1143.mcz
==================== Summary ====================
Name: Tools-mt.1143
Author: mt
Time: 15 March 2022, 2:51:11.166959 pm
UUID: 3ef730f5-b20c-4b46-af3e-ee656552cd9f
Ancestors: Tools-mt.1142
Remove manual line breaks in dialog texts. Keep double-breaks (i.e., '\\' or '<br><br>') as visual gap.
=============== Diff against Tools-mt.1142 ===============
Item was changed:
----- Method: CodeHolder>>informPossiblyCorruptSource (in category 'misc') -----
informPossiblyCorruptSource
| sourcesName |
sourcesName := FileDirectory localNameFor: Smalltalk sourcesName.
+ self inform: ('There may be a problem with your sources file!!
- self inform: 'There may be a problem with your sources file!!
+ The source code for every method should (usually) start with the method selector but this is not the case with this method!! You may proceed with caution but it is recommended that you get a new source file.
- The source code for every method should (usually) start with the
- method selector but this is not the case with this method!! You may
- proceed with caution but it is recommended that you get a new source file.
+ This can happen if you download the "{1}" file, or the ".changes" file you use, as TEXT. It must be transfered in BINARY mode, even if it looks like a text file, to preserve the CR line ends.
- This can happen if you download the "' , sourcesName , '" file,
- or the ".changes" file you use, as TEXT. It must be transfered
- in BINARY mode, even if it looks like a text file,
- to preserve the CR line ends.
+ Mac users: This may have been caused by Stuffit Expander. To prevent the files above to be converted to Mac line ends when they are expanded, do this: Start the program, then from Preferences... in the File menu, choose the Cross Platform panel, then select "Never" and press OK. Then expand the compressed archive again.
- Mac users: This may have been caused by Stuffit Expander.
- To prevent the files above to be converted to Mac line ends
- when they are expanded, do this: Start the program, then
- from Preferences... in the File menu, choose the Cross
- Platform panel, then select "Never" and press OK.
- Then expand the compressed archive again.
+ (Occasionally, the source code for a method may legitimately start with a non-alphabetic character -- for example, Behavior
+ method #formalHeaderPartsFor:. In such rare cases, you can happily disregard this warning.)' translated format: {sourcesName})!
- (Occasionally, the source code for a method may legitimately
- start with a non-alphabetic character -- for example, Behavior
- method #formalHeaderPartsFor:. In such rare cases, you can
- happily disregard this warning.)'!
Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
http://source.squeak.org/trunk/Morphic-mt.1940.mcz
==================== Summary ====================
Name: Morphic-mt.1940
Author: mt
Time: 15 March 2022, 2:21:48.695853 pm
UUID: 4b118d5c-7149-4bc9-aaea-19a8d8e80d5d
Ancestors: Morphic-mt.1939
Fixes minor regression in FontImporterTool where the input box for line-spacing did not update.
(That recent try of mine to be unnecessarily clever here and avoid extra UI updates turned out to be fruitless.)
=============== Diff against Morphic-mt.1939 ===============
Item was changed:
----- Method: FontImporterTool>>selectedFont: (in category 'accessing') -----
selectedFont: aTTCFont
selectedFont := aTTCFont.
self changed: #previewText.
self changed: #selectedFontTextStyle.
self changed: #filename.
self changed: #copyright.
self changed: #pointSizeInput.
+ self changed: #lineSpacingInput.
- "self changed: #lineSpacingInput. -- already via #selectedFontTextStyle"
self changed: #ttExtraScaleInput.
self changed: #ttExtraGapInput.
self changed: #installButtonColor.
self changed: #installButtonLabel.
self changed: #installButtonEnabled.
self changed: #windowTitle.!
Marcel Taeumel uploaded a new version of TrueType to project The Trunk:
http://source.squeak.org/trunk/TrueType-mt.89.mcz
==================== Summary ====================
Name: TrueType-mt.89
Author: mt
Time: 15 March 2022, 2:19:39.426851 pm
UUID: 463bce88-f370-4ebd-9281-4ce1814f54cc
Ancestors: TrueType-mt.88
Fixes robustness when facing fonts with 'CFF ' table or fully unknown subfamily names.
=============== Diff against TrueType-mt.88 ===============
Item was changed:
----- Method: TTFontFileHandle>>fontOfPointSize: (in category 'building') -----
fontOfPointSize: pointSize
"Answers a font that represents the receiver. For top-level descriptions, that font can have derivative for different emphases. NOTE THAT the resulting font is not necessarily installed in the system!!"
| handles head tail font |
self isInstalled ifTrue: [
^ ((TextStyle named: self textStyleName) defaultFont
emphasized: self emphasisCode)
asPointSize: pointSize].
+ self hasChildren ifFalse: [
+ "I represent only a single subfamily, which must be supported.
+ See #isSubfamilySupported."
+ ^ self fontDescription
+ ifNil: [
+ TextStyle defaultTTFont
+ asPointSize: pointSize]
+ ifNotNil: [:tt |
+ TTCFont new
+ ttcDescription: tt;
+ setPointSize: pointSize familyName: self familyNameAsIs
+ extraGlyphScale: ttExtraScale extraLineGap: ttExtraGap;
+ yourself]].
- self hasChildren ifFalse: ["I represent only a single subfamily"
- ^ TTCFont new
- ttcDescription: self fontDescription;
- setPointSize: pointSize familyName: self familyNameAsIs extraGlyphScale: ttExtraScale extraLineGap: ttExtraGap;
- yourself].
handles := self children select: [:ea | ea isSubfamilySupported].
+ handles ifEmpty: [^ self children anyOne fontOfPointSize: pointSize].
+ head := handles detect: [:ea | ea isRegular] ifNone: [handles anyOne].
- head := handles detect: [:ea | ea isRegular].
tail := handles copyWithout: head.
head := head fontOfPointSize: pointSize.
tail := tail collect: [:ea | ea fontOfPointSize: pointSize].
font := head.
tail do: [:ea | font derivativeFont: ea].
^ font!
Item was changed:
----- Method: TTFontReader>>checkIntegrity (in category 'reading - support') -----
checkIntegrity
+ (self hasTable: 'CFF ') ifTrue: [
- (self hasTable: 'CFF') ifTrue: [
"Some TTC fonts may actually be collection of PostScript-Based OpenType fonts"
^ self error: 'Type 1 fonts are not supported'].
#(
'cmap' #noCharacterMappingTableFound
'head' #noHeaderTableFound
'hhea' #noHorizontalHeaderTableFound
'hmtx' #noHorizontalMetricsTableFound
'maxp' #noMaximumProfileTableFound
'name' #noNamingTableFound
"OS/2 -- optional in Squeak"
"kern -- optional in Squeak"
'loca' #noRelocationTableFound
'glyf' #noGlyphDataTableFound
) pairsDo: [:tag :errorMessage |
(self hasTable: tag) ifFalse: [
^ self error: errorMessage]].
^ true "Everything is okay."!
Item was changed:
----- Method: TTFontReader>>readNextName (in category 'reading - family name (fast)') -----
readNextName
"Answer the next quad of #(familyName subfamilyName fileName fileOffset). Optimized for speed. Does crazy stuff if there is no 'name' table. Also does crazy stuff if there is not at least a single English entry in the naming table"
+ | data fontOffset tableName nameOffset storageOffset numRecords i record |
- | data fontOffset nameOffset storageOffset numRecords i record |
fontOffset := self offset.
+
+ "1) Find offset of 'name' table. See #checkIntegrity and #readTableDictionary for more details."
-
- "1) Find offset of 'name' table. See #readTableDictionary for more details."
self skip: 12. "count??"
+ [(tableName := self next: 4) = #[67 70 70 32] "CFF " ifTrue: [^ nil].
+ tableName = #[110 97 109 101] "name"] whileFalse: [self skip: 12].
- [(self next: 4) = #[110 97 109 101] "name"] whileFalse: [self skip: 12].
self skipLong.
nameOffset := self nextUnsignedLong.
"2) Find the English version of familyName and subfamilyName. See #readNamingTable for more details."
self offset: nameOffset.
self nextUnsignedShort = 0 "Support only format 1 naming tables"
ifFalse: [self offset: fontOffset+1. ^ nil].
numRecords := self nextUnsignedShort.
storageOffset := self nextUnsignedShort + nameOffset.
i := 0.
data := Array new: 4.
[data first notNil and: [data second notNil]] whileFalse: [
(i := i + 1) > numRecords ifTrue: [self offset: fontOffset+1. ^ nil "Nothing found :("].
record := self
readNamingTableRecordWith: storageOffset
select: [:platformID :languageID :nameID |
(nameID = 1 "familyName" or: [nameID = 2 "subfamilyName" ]) and: [
platformID = 0 "Unicode -- Always English by default?"
or: [platformID = 3 "Windows" and: [(languageID bitAnd: 16r00FF) = 9]]
or: [platformID = 1 "Macintosh" and: [languageID = 1]] ]].
record ifNotNil: [data at: record nameID put: record contents]].
data at: 3 put: self fileName.
data at: 4 put: fontOffset.
self offset: fontOffset+1. "Ready for next call to #nextName"
^ data!
Marcel Taeumel uploaded a new version of Graphics to project The Trunk:
http://source.squeak.org/trunk/Graphics-mt.500.mcz
==================== Summary ====================
Name: Graphics-mt.500
Author: mt
Time: 15 March 2022, 10:25:00.646283 am
UUID: 24f9d780-c835-1445-a447-80097ee72a15
Ancestors: Graphics-mt.499
When installing a font family as fallback, to not instantiate arbitrary point sizes but rely on lazy init via #fallbackFont. This way, you can save a lot of space allocated to each instance's glyph-form cache.
See TTCFont >> #createCache for the construction site. :-)
=============== Diff against Graphics-mt.499 ===============
Item was changed:
----- Method: AbstractFont>>fallbackFont (in category 'accessing') -----
fallbackFont
+ "Answers the fallbackFont for the receiver. Try to use the #defaultFallback but for itself use a synthetic font that maps all characters to question marks."
- "Answers the fallbackFont for the receiver. The fallback font must be some derivative of the receiver since it will not be asked to install itself properly on the target BitBlt so rendering a completely different font here is simply not possible. The default implementation uses a synthetic font that maps all characters to question marks."
+ ^ TextStyle defaultFallback textStyleName = self textStyleName
+ ifTrue: [
+ FixedFaceFont new errorFont baseFont: self]
+ ifFalse: [
+ (TextStyle defaultFallbackFont
+ emphasized: self emphasis)
+ asPointSize: self pointSize]!
- ^ FixedFaceFont new errorFont baseFont: self!
Item was changed:
----- Method: AbstractFont>>privateFallbackTextStyle: (in category 'initialize-release') -----
privateFallbackTextStyle: aTextStyleOrNil
+ self fallbackFont: nil. "Rely on lazy initialization of #fallbackFont."!
- self fallbackFont: (aTextStyleOrNil ifNotNil: [:ts | ts addNewFontSize: self pointSize]).!
Item was added:
+ ----- Method: TextStyle>>textStyleName (in category 'accessing - default font') -----
+ textStyleName
+ ^ self defaultFont textStyleName!