[squeak-dev] The Trunk: TrueType-mt.69.mcz

commits at source.squeak.org commits at source.squeak.org
Tue Feb 8 16:57:59 UTC 2022


Marcel Taeumel uploaded a new version of TrueType to project The Trunk:
http://source.squeak.org/trunk/TrueType-mt.69.mcz

==================== Summary ====================

Name: TrueType-mt.69
Author: mt
Time: 8 February 2022, 5:57:59.520958 pm
UUID: 47b962d5-9bc9-5941-ba02-418af3938f93
Ancestors: TrueType-mt.68

Adds implementation of cmap format 12. Thanks to Eric Grade (EG) for implementing it!

We can now load, for example, Unicode Cuneiform fonts: https://www.hethport.uni-wuerzburg.de/cuneifont/ :-)

| fontFile fontDescription font |
fontFile := '/Users/ecgade/Downloads/Santakku/SantakkuM.ttf'.
fontDescription := (TTFontReader parseFileNamed: fontFile) first.
font := TTCFont new ttcDescription: fontDescription; pointSize: 36.0; yourself.
font browseAllGlyphs.

=============== Diff against TrueType-mt.68 ===============

Item was removed:
- ----- Method: TTCharacterMappingTable>>isMacintosh (in category 'testing') -----
- isMacintosh
- 
- 	^ platformID = 1!

Item was added:
+ ----- Method: TTCharacterMappingTable>>isMacintoshPlatform (in category 'testing - platform') -----
+ isMacintoshPlatform
+ 
+ 	^ platformID = 1!

Item was changed:
  ----- Method: TTCharacterMappingTable>>isUnicode (in category 'testing') -----
  isUnicode
  
+ 	"A cmap is considered Unicode if either:
+ 	 a) the platformID is 0, ie the Unicode platform; or
+ 	 b) The platformID is Windows (3) and the encodingID is Unicode for Windows (10).
+ 	 See the 'cmap encoding subtables' section of https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html"
+ 	^ (platformID = 0) or: [
+ 		(platformID = 3 and: [ encodingID = 10 ])]!
- 	^ platformID = 0!

Item was added:
+ ----- Method: TTCharacterMappingTable>>isUnicodePlatform (in category 'testing - platform') -----
+ isUnicodePlatform
+ 
+ 	^ platformID = 0!

Item was removed:
- ----- Method: TTCharacterMappingTable>>isWindows (in category 'testing') -----
- isWindows
- 
- 	^ platformID = 3!

Item was added:
+ ----- Method: TTCharacterMappingTable>>isWindowsPlatform (in category 'testing - platform') -----
+ isWindowsPlatform
+ 
+ 	^ platformID = 3!

Item was changed:
  ----- Method: TTCharacterMappingTable>>map: (in category 'mapping') -----
  map: glyphs
  
+ 	self isUnicodePlatform ifTrue: [^ self mapFromUnicode: glyphs].
+ 	self isMacintoshPlatform ifTrue: [^ self mapFromMacintosh: glyphs].
+ 	self isWindowsPlatform ifTrue: [^ self mapFromWindows: glyphs].
- 	self isUnicode ifTrue: [^ self mapFromUnicode: glyphs].
- 	self isMacintosh ifTrue: [^ self mapFromMacintosh: glyphs].
- 	self isWindows ifTrue: [^ self mapFromWindows: glyphs].
  	
  	"Fallback"
  	self notify: 'Platform is not supported: ', self platformName.
  	^ Array new: 256 withAll: glyphs first!

Item was changed:
  ----- Method: TTCharacterMappingTable>>mapFromWindows: (in category 'mapping') -----
  mapFromWindows: glyphs
  
  	| charTable glyph |	
  	self
+ 		assert: [#(0 "Symbol"  1 "Unicode BMP"  10 "Unicode Full") includes: encodingID]
- 		assert: [#(0 1) includes: encodingID]
  		description: 'Encoding not supported: ', self encodingName.
  
  	charTable := characterMap size > 256
  		ifFalse: [Array new: 256 withAll: glyphs first]
  		ifTrue: [SparseLargeTable new: characterMap size
  			chunkSize: 256 arrayClass: Array base: 1
  			defaultValue: glyphs first].
  
  	1 to: (characterMap size min: charTable size) do: [:i |
  		| glyphIndex |
  		glyphIndex := characterMap at: i.
  		encodingID = 0 ifTrue: [ "symbol font"
  			glyphIndex := glyphIndex bitAnd: 16r00FF].
  		glyph := glyphs at: glyphIndex + 1 ifAbsent: [glyphs first].
  		charTable at: i put: glyph.
  		encodingID = 0 ifTrue: [ "symbol font" 
  			(i-1 between: 16rF020 and: 16rF0FF) ifTrue: [ "copy into ascii range"
  				charTable at: (i-1 bitAnd: 16r00FF)+1 put: glyph]]].
+ 	
+ 	characterMap size > 256 ifTrue: [charTable zapDefaultOnlyEntries].
+ 	
- 		
  	^ charTable!

Item was changed:
  ----- Method: TTCharacterMappingTable>>printOn: (in category 'printing') -----
  printOn: stream
  
  	stream
  		nextPutAll: 'cmap( ';
  		nextPutAll: self platformName;
  		nextPutAll: ' ; ';
  		nextPutAll: self encodingName.
  		
+ 	self isMacintoshPlatform ifTrue: [
- 	self isMacintosh ifTrue: [
  		stream
  			nextPut: $<;
  			nextPutAll: self macLanguageName;
  			nextPut: $>].
  		
  	stream
  		nextPutAll: ' ; ';
  		nextPutAll: (self characterMap ifNil: ['n/a'] ifNotNil: [:m | m size asString]);
  		nextPutAll: ' )'.!

Item was added:
+ ----- Method: TTFontReader>>decodeCmapFmtTable12: (in category 'private') -----
+ decodeCmapFmtTable12: entry
+ 	"Segmented coverage for supplementary range unicode chars.
+ 	See https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table"
+ 	| length language numGroups cmap groups |
+ 	entry nextUShort. "This is ignored, so we now align to 32-bit values"
+ 	length := entry nextULong.
+ 	language := entry nextULong.
+ 	numGroups := entry nextULong.
+ 	groups := Array new: numGroups.
+ 	
+ 	1 to: numGroups do: [ :num |
+ 		groups at: num put: {
+ 			entry nextULong. "startCharCode"
+ 			entry nextULong. "endCharCode"
+ 			entry nextULong. "startGlyphId"
+ 			0. "End glyph id will be calculated"}].
+ 		
+ 	"Groups are in order, so the last group's endCharcode is
+ 	the full size of the character map"
+ 	cmap := Array new: (groups last second + 1) withAll: 0.
+ 	
+ 	groups do: [ :groupData |
+ 		| codeStart codeEnd |
+ 		codeStart := groupData first.
+ 		codeEnd := groupData second.
+ 		codeStart to: codeEnd do: [ :index |
+ 			cmap at: (index + 1) put: (groupData third + (index - codeStart))]].
+ 
+ 	^ {language. cmap}
+ 	!

Item was changed:
  ----- Method: TTFontReader>>decodeCmapFmtTable: (in category 'private') -----
  decodeCmapFmtTable: entry
  	"Decode cmap table. Currently supports formats 0, 4, and 6
  	https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table"
  	
  	| cmapFmt |
  	^ (cmapFmt := entry nextUShort)
  		caseOf: {
  			[0] -> [self decodeCmapFmtTable0: entry].
  			[4] -> [self decodeCmapFmtTable4: entry].
  			[6] -> [self decodeCmapFmtTable6: entry].
+ 			[12] -> [self decodeCmapFmtTable12: entry].
  		} otherwise: [
  			Transcript showln: '[TTFontReader] Unsupported encoding of cmap: ', cmapFmt.
  			{nil.nil}]!

Item was changed:
  ----- Method: TTFontReader>>processCharMap: (in category 'processing - support') -----
  processCharMap: mappingTables
  	"Process the given character map. Prefer Unicode mappings"
+ 	"According to https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html
+ 	we should not only prefer Unicode cmaps, but should prioritize cmaps not restricted to BMP. Therefore
+ 	if there are multiple Unicode maps we need to select the first best option"
  
+ 	"^ mappingTables
- 	^ mappingTables
  		detect: [:ea | ea isUnicode]
  		ifFound: [:table | table map: glyphs]
+ 		ifNone: [mappingTables last map: glyphs]"
+ 	
+ 	| unicode result |
+ 	unicode := mappingTables select: [ :cmap | cmap isUnicode ].
+ 	unicode size = 1 ifTrue: [ ^ unicode first map: glyphs ].
+ 	unicode size = 0 ifTrue: [ ^ mappingTables last map: glyphs ].
+ 	
+ 	"Otherwise, we have multiple Unicode maps. In lieu of selecting
+ 	the one not restricted to BMP, we pick the one with the largest
+ 	character range. There might be a better way to handle this."
+ 	result := unicode first.
+ 	unicode do: [ :cmap |
+ 		cmap characterMap size > result characterMap size
+ 			ifTrue: [ result := cmap]].
+ 	^ result map: glyphs!
- 		ifNone: [mappingTables last map: glyphs]!



More information about the Squeak-dev mailing list