[squeak-dev] The Trunk: TrueType-mt.81.mcz
commits at source.squeak.org
commits at source.squeak.org
Thu Mar 3 13:15:49 UTC 2022
Marcel Taeumel uploaded a new version of TrueType to project The Trunk:
http://source.squeak.org/trunk/TrueType-mt.81.mcz
==================== Summary ====================
Name: TrueType-mt.81
Author: mt
Time: 3 March 2022, 2:15:48.031142 pm
UUID: 46619d54-c342-e240-8224-44cee41f77ad
Ancestors: TrueType-dtl.80
Bugfixes:
- "Install & Load" will now configure the glyphTable with the correct fallback glyph; does not affect remote fonts
- kernPairs must keep their glyph indexes bc. multiple code points can map to the same glyph
Enhancements:
- Install "Unicode BMP" character mapping for our Bitstream Vera fonts bc. we have all the glyphs; limit #maxCodePoint to 255 until we have a better strategy for our glyph-form cache in TTCFont
- Increase robustness in TTFontFileHandle against whitespace-typos in family name; e.g., merge "OpenDyslexic 3" and "OpenDyslexic3" to bundle regular and bold face
- create a #cmapTable on-the-fly for TTFontDescription using glyphTable
- Adds a compression protocol to TTCharacterMappingTable
=============== Diff against TrueType-dtl.80 ===============
Item was added:
+ ----- Method: TTCharacterMappingTable class>>fromCompressedBytes:perElement: (in category 'instance creation') -----
+ fromCompressedBytes: bytes perElement: bytesPerElement
+
+ | cmap |
+ cmap := self new platformID: -1; "Squeak" yourself.
+ cmap setCharacterMapFromCompressedBytes: bytes perElement: bytesPerElement.
+ cmap encodingID: (cmap size caseOf: {
+ [256] -> [0 "Latin1"].
+ [65536] -> [2 "Unicode BMP"].
+ } otherwise: [3 "Unicode full -- wild guess"]).
+ ^ cmap!
Item was added:
+ ----- Method: TTCharacterMappingTable>>characterMapAsCompressedBytes (in category 'compressing') -----
+ characterMapAsCompressedBytes
+
+ | max |
+ ^ (max := characterMap max) > 16rFFFF
+ ifTrue: [self characterMapAsCompressedBytes: 4]
+ ifFalse: [max > 16rFF
+ ifTrue: [self characterMapAsCompressedBytes: 2]
+ ifFalse: [self characterMapAsCompressedBytes: 1]]!
Item was added:
+ ----- Method: TTCharacterMappingTable>>characterMapAsCompressedBytes: (in category 'compressing') -----
+ characterMapAsCompressedBytes: bytesPerElement
+
+ | bitmap |
+ bytesPerElement = 4 ifTrue: [
+ "Bitmap is a variable-word subclass, which means 4 bytes per element."
+ ^ (characterMap as: Bitmap) compressToByteArray].
+
+ bitmap := Bitmap new: (characterMap size asFloat / bytesPerElement) ceiling.
+ 1 to: bitmap size do: [:i |
+ | elements x |
+ elements := (1 to: 4 // bytesPerElement)
+ collect: [:j | characterMap at: ((i-1)*bytesPerElement)+j ifAbsent: [0 "bc. #ceiling"]].
+ x := 0.
+ 1 to: elements size do: [:e |
+ x := (x bitShift: bytesPerElement*8) + (elements at: e)].
+ bitmap at: i put: x].
+
+ ^ bitmap compressToByteArray!
Item was changed:
----- Method: TTCharacterMappingTable>>createGlyphTableFrom: (in category 'mapping') -----
createGlyphTableFrom: allGlyphsInGlyphIndexOrder
"Answer a table that can lookup TrueType glyphs by Unicode code point. Note that allGlyphs *must be* in glyphIndex order or otherwise the resulting table will be incorrect."
| mappedGlyphTable fallbackGlyph |
self
assert: [platformID = -1]
description: 'You must call #prepare first!!'.
+ fallbackGlyph := allGlyphsInGlyphIndexOrder first.
- fallbackGlyph := allGlyphsInGlyphIndexOrder.
mappedGlyphTable := encodingID = 0 "latin-1"
ifTrue: [Array new: 256 withAll: fallbackGlyph]
ifFalse: [SparseLargeTable new: characterMap size
chunkSize: 256 arrayClass: Array base: 1
defaultValue: fallbackGlyph].
1 to: characterMap size do:
[:i | | glyph glyphIndex |
glyphIndex := characterMap at: i.
glyph := allGlyphsInGlyphIndexOrder at: glyphIndex+1 ifAbsent: [fallbackGlyph].
mappedGlyphTable at: i put: glyph].
encodingID = 0 ifFalse: [mappedGlyphTable zapDefaultOnlyEntries].
self flag: #todo. "Discard unused glyphs such as ligatures etc. We do not support them."
^ mappedGlyphTable!
Item was added:
+ ----- Method: TTCharacterMappingTable>>setCharacterMapFromCompressedBytes:perElement: (in category 'compressing') -----
+ setCharacterMapFromCompressedBytes: bytes perElement: bytesPerElement
+
+ | bitmap numElements |
+ bitmap := Bitmap decompressFromByteArray: bytes.
+ numElements := bitmap size * (4 // bytesPerElement).
+
+ numElements = 256
+ ifTrue: [characterMap := Array new: numElements]
+ ifFalse: [characterMap := (SparseLargeTable new: numElements
+ chunkSize: 256 arrayClass: Array base: 1
+ defaultValue: 0)].
+
+ bytesPerElement = 4 ifTrue: [
+ characterMap fillFrom: bitmap with: [:glyphIndex | glyphIndex].
+ numElements = 256 ifFalse: [characterMap zapDefaultOnlyEntries].
+ ^ self].
+
+ 1 to: bitmap size do: [:i |
+ | elements mask x |
+ x := bitmap at: i.
+ elements := Array new: 4 // bytesPerElement.
+ mask := (1 << (bytesPerElement*8)) -1.
+ elements size to: 1 by: -1 do: [:j |
+ elements
+ at: (elements size - j + 1)
+ put: ((x bitShift: bytesPerElement * 8 * (j-1) * -1) bitAnd: mask)].
+ 1 to: elements size do: [:j |
+ characterMap
+ at: ((i-1)*bytesPerElement)+j
+ put: (elements at: j)]].
+
+ numElements = 256 ifFalse: [characterMap zapDefaultOnlyEntries].!
Item was changed:
+ ----- Method: TTFontDescription>>allGlyphs (in category 'accessing - debugging') -----
- ----- Method: TTFontDescription>>allGlyphs (in category 'accessing') -----
allGlyphs
^ glyphs!
Item was added:
+ ----- Method: TTFontDescription>>allKernPairs (in category 'accessing - debugging') -----
+ allKernPairs
+
+ ^ kernPairs!
Item was added:
+ ----- Method: TTFontDescription>>cmapTable (in category 'accessing') -----
+ cmapTable
+ "Construct on-the-fly from glyphTable. Maybe cache later? Maybe there is no need for glyphTable but only cmapTable like in TTRemoteFontDescription?"
+
+ ^ TTCharacterMappingTable new
+ platformID: -1; "Squeak"
+ encodingID: (glyphTable size caseOf: {
+ [256] -> [0 "Latin1"].
+ [65536] -> [2 "Unicode BMP"].
+ } otherwise: [3 "Unicode full -- wild guess"]);
+ characterMap: (glyphTable collect: [:glyph | glyph glyphIndex]);
+ yourself!
Item was changed:
+ ----- Method: TTFontDescription>>maxGlyphIndex (in category 'accessing - debugging') -----
- ----- Method: TTFontDescription>>maxGlyphIndex (in category 'accessing') -----
maxGlyphIndex
^ glyphs size - 1!
Item was changed:
----- Method: TTFontDescription>>size (in category 'accessing') -----
size
+ ^ maxCodePoint ifNil: [glyphTable size]!
- ^ glyphTable size.
- !
Item was changed:
----- Method: TTFontFileHandle class>>allHandlesFrom: (in category 'support') -----
allHandlesFrom: specs
| handles |
handles := Dictionary new. "Use family name as #key to accumulate families from files."
specs do: [:spec | | familyName subfamilyName fileName fileOffset familyHandle ttc |
familyName := spec at: 1.
subfamilyName := spec at: 2.
fileName := spec at: 3 ifAbsent: nil. "installed but unknown file"
fileOffset := spec at: 4 ifAbsent: nil. "installed but unknown file"
ttc := spec at: 5 ifAbsent: nil. "already parsed"
familyHandle := handles
+ at: (familyName copyWithout: Character space) "Robustness. Typos are possible"
- at: familyName
ifAbsentPut: [TTFontFileHandle new fontname: familyName; yourself].
subfamilyName
ifNil: [
familyHandle filename: fileName; fileoffset: fileOffset; setFontDescription: ttc]
ifNotNil: [ | subfamilyHandle |
subfamilyHandle := TTFontFileHandle new fontname: subfamilyName; yourself.
subfamilyHandle parent: familyHandle; filename: fileName; fileoffset: fileOffset; setFontDescription: ttc.
familyHandle addChild: subfamilyHandle]].
^ handles!
Item was changed:
----- Method: TTFontReader>>processKerningTable (in category 'reading - tables') -----
processKerningTable
self checkFontOffset.
self peekDuring: [
(self skipToTable: 'kern') ifFalse: [^ self "optional"].
(self peekDuring: [self readKerningTable])
ifFalse: [self readKerningTableForMacintosh]].
"Post-processing. Prefer only #kerning values for #horizontal text layout."
kernPairs := kernTables
detect: [:table | table first includesAllOf: #(horizontal kerning)]
ifFound: [:table | table second]
+ ifNone: [#()].!
- ifNone: [#()].
-
- "Map glyph index to a character to be used, e.g., in CharacterScanner."
- kernPairs do: [:kp |
- kp left: ((cmapTable mapIndex: kp left)
- ifNotNil: [:codePoint | Character value: codePoint]).
- kp right: ((cmapTable mapIndex: kp right)
- ifNotNil: [:codePoint | Character value: codePoint])].
-
- "Only work with kerning metrics for glyphs that are referenced in the cmap."
- kernPairs := kernPairs select: [:kp | kp left notNil and: [kp right notNil]].!
Item was changed:
+ ----- Method: TTRemoteFontDescription>>maxGlyphIndex (in category 'accessing - debugging') -----
- ----- Method: TTRemoteFontDescription>>maxGlyphIndex (in category 'accessing - glyphs') -----
maxGlyphIndex
^ numGlyphs-1!
Item was changed:
+ (PackageInfo named: 'TrueType') postscript: '"Repair all kern pairs. We must keep glyph indexes in there. TTFontReader was updated, too."
+ TTFontDescription allSubInstancesDo: [:ttc | | cmap |
+ cmap := ttc cmapTable.
+ ttc allKernPairs do: [:kp |
+ kp left isCharacter ifTrue: [
+ kp left: (cmap mapCode: kp left codePoint)].
+ kp right isCharacter ifTrue: [
+ kp right: (cmap mapCode: kp right codePoint)]] ].
+
+ "Install Unicode BMP character mapping for Bitstream Vera font families. But limit to maxCodePoint 255 until we find a better strategy for the glyph cache."
+ [ | cmap |
+ cmap := ''/wAAgABBAMMAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZ
+ ABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0
+ ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBP
+ AFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAABBAMMArACjAIQAhQC9AJYA
+ 5wCGAI4AiwCdAKkApAEAAIoA2QCDAJMA8QDyAI0AlwCIAMMA3QDwAJ4AqgDzAPQA9QCiAK0A
+ yQDHAK4AYgBjAJAAZADLAGUAyADKAM8AzADNAM4A6ABmANIA0ADRAK8AZwDvAJEA1QDTANQA
+ aADqAOwAiQBqAGkAawBtAGwAbgCgAG8AcQBwAHIAcwB1AHQAdgB3AOkAeAB6AHkAewB9AHwA
+ uAChAH8AfgCAAIEA6wDtALoNAAcA+wD8CQAPAP0A/gAAAAAAAAD/GQAHAPYA9yEABwD4ANYd
+ AAsAAADhAOIAAB0ABwCwALEVAAsA+QD6AOMA5C0AEwC7AAAAAAAAAAAA5QDmAAAlAAcApgAA
+ 4mUABwDXAOAhAA8A2gDbANwA3wDYAN7hlQAHAAAAny0ABwCbAAD/AAA4oQAvAAAAsgCzAAAA
+ AAAAALYAtwDEAAAAtAC1AMUAAACCAMIAhwAAAAAAAACrAAARAAcAxgAADQALAAAAvgC/AADg
+ 4QAHAQIAAODpAAcAjAAA4b0ADwCYAAAAAAAAAKgAAA0AJwAAAJoAAACZAO4AAAAAALwAAAAA
+ AAABAQClAAAAAAAAAJIAABUABwAAAJw5AAcApwAALQAPAI8AAAAAAAAAlACV5skABwC5AAD/
+ AAGqaQALAAAAwADBAADp+QA=''.
+ cmap := TTCharacterMappingTable
+ fromCompressedBytes: cmap base64Decoded asByteArray
+ perElement: 2.
+
+ (#(BitstreamVeraSans BitstreamVeraSansMono BitstreamVeraSerif)
+ gather: [:family | | font |
+ font := TTCFont familyName: family.
+ {font ttcDescription}, (font derivativeFonts
+ select: [:ea | ea isSynthetic not] thenCollect: [:ea | ea ttcDescription])])
+ do: [:ttc |
+ ttc
+ setGlyphs: ttc allGlyphs mapping: (cmap createGlyphTableFrom: ttc allGlyphs);
+ setMinCodePoint: 32 maxCodePoint: 255].
+ ] value.'!
- (PackageInfo named: 'TrueType') postscript: '#(
- BitstreamVeraSans 1.059 24 ''Bitstream Vera Sans For Squeak''
- BitstreamVeraSansMono 1.059 24 ''Bitstream Vera Sans Mono For Squeak''
- ) groupsDo: [:name :scale :gap :customName |
- (TextStyle named: name) asHandle
- rename: customName;
- ttExtraScale: scale; ttExtraGap: gap;
- installFont].'!
More information about the Squeak-dev
mailing list
|