[ENH] Displaying undefined glyphs

Larry Trutter ltrutter at onemain.com
Tue Apr 12 03:22:12 UTC 2005


Thank you for your report.  I have transferred your report to Squeak's
Mantis Database and you can followup on the issue if desired by going to
http://bugs.impara.de/view.php?id=1062.

In the future please report new issues on Squeak's Mantis Database at
http://bugs.impara.de/ .

Thanks!


Andreas Raab wrote:

> Folks -
>
> It has annoyed me for a long time that MultiCharacters are often only 
> displayed as question marks which makes it very simple to confuse them 
> with a real question mark. The attached changes fix this so that e.g., 
> "Character value: 500" is printed as \u1F4. The attached images 
> illustrate the difference. How the undefined character is displayed 
> can be changed in Character>>asUndefinedGlyph (so if you prefer to 
> prefer <Character value: 500> instead you are free to do this ;-)
>
> Cheers,
>   - Andreas
>
>------------------------------------------------------------------------
>
>'From Squeak3.8gamma of ''24 November 2004'' [latest update: #6643] on 10 April 2005 at 3:34:54 am'!
>"Change Set:		DisplayUndefined
>Date:			10 April 2005
>Author:			Andreas Raab
>
>Change the display of undefined characters from a question mark to a \uXYZ format. E.g., instead of
>
>	Character value: 500 -> $?
>	Character value: 500 -> $\u1F4
>"!
>
>
>!AbstractFont methodsFor: 'measuring' stamp: 'ar 4/10/2005 03:14'!
>widthOf: aCharacter 
>	"Answer the width of the argument as a character in the receiver."
>	^self widthOf: aCharacter ifAbsent:[self widthOfString: aCharacter asUndefinedGlyph].! !
>
>!AbstractFont methodsFor: 'measuring' stamp: 'ar 4/10/2005 03:02'!
>widthOf: aCharacter ifAbsent: aBlock
>	"Return the width of the given character if defined in the font. 
>	If absent evaluate aBlock."
>	^self subclassResponsibility! !
>
>
>!Character methodsFor: 'printing' stamp: 'ar 4/10/2005 03:00'!
>asUndefinedGlyph
>	^'\u', (value printStringBase: 16)! !
>
>
>!FixedFaceFont methodsFor: 'measuring' stamp: 'ar 4/10/2005 03:03'!
>widthOf: aCharacter ifAbsent: aBlock
>	"Characters are always defined in a fixed face font"
>	^ baseFont widthOf: substitutionCharacter! !
>
>
>!StrikeFont methodsFor: 'accessing' stamp: 'ar 4/10/2005 03:04'!
>widthOf: aCharacter ifAbsent: aBlock
>	"Characters are always defined in a fixed face font"
>	| code |
>	code := aCharacter class == Character
>				ifTrue: [aCharacter asciiValue]
>				ifFalse: [aCharacter charCode].
>	((code < minAscii or: [maxAscii < code]) or: [(xTable at: code + 1) < 0])
>		ifTrue: [^aBlock value].
>	^(xTable at: code + 2) - (xTable at: code + 1)! !
>
>!StrikeFont methodsFor: 'displaying' stamp: 'ar 4/10/2005 03:20'!
>displayMultiString: aString on: aBitBlt from: startIndex to: stopIndex at: aPoint kern: kernDelta baselineY: baselineY
>
>	| destPoint leftX rightX glyphInfo char destY str |
>	destPoint _ aPoint.
>	charIndex _ startIndex.
>	glyphInfo _ Array new: 5.
>	[charIndex <= stopIndex] whileTrue: [
>		char _ aString at: charIndex.
>		(self hasGlyphOf: char) not ifTrue: [
>			str := char asUndefinedGlyph.
>			destPoint := self displayString: str on: aBitBlt from: 1 to: str size at: destPoint kern: kernDelta baselineY: baselineY.
>			charIndex _ charIndex + 1.
>		] ifFalse: [
>			self glyphInfoOf: char into: glyphInfo.
>			leftX _ glyphInfo second.
>			rightX _ glyphInfo third.
>			(glyphInfo fifth ~= aBitBlt lastFont) ifTrue: [
>				glyphInfo fifth installOn: aBitBlt.
>			].
>			aBitBlt sourceForm: glyphInfo first.
>			destY _ baselineY - glyphInfo fourth. 
>			aBitBlt destX: destPoint x.
>			aBitBlt destY: destY.
>			aBitBlt sourceOrigin: leftX @ 0.
>			aBitBlt width: rightX - leftX.
>			aBitBlt height: self height.
>			aBitBlt copyBits.
>			destPoint _ destPoint + (rightX - leftX + kernDelta @ 0).
>			charIndex _ charIndex + 1.
>		].
>	].
>	^destPoint.
>! !
>
>
>!StrikeFontSet methodsFor: 'accessing' stamp: 'ar 4/10/2005 03:09'!
>widthOf: aCharacter ifAbsent: aBlock
>	"Answer the width of the argument as a character in the receiver."
>	"1: optimizing"
>	| encoding f |
>	aCharacter class == Character
>		ifTrue: [^ (fontArray at: 1) widthOf: aCharacter].
>	"2: other case"
>	encoding := aCharacter leadingChar + 1.
>	f := ((((aCharacter isMemberOf: Character) not
>							and: [encoding > 1])
>						and: [encoding <= fontArray size])
>					and: [(fontArray at: encoding) notNil])
>				ifTrue: [fontArray at: encoding]
>				ifFalse: [^aBlock value].
>	^ f widthOf: aCharacter ifAbsent: aBlock! !
>
>!StrikeFontSet methodsFor: 'displaying' stamp: 'ar 4/10/2005 03:27'!
>displayString: aString on: aBitBlt from: startIndex to: stopIndex at: aPoint kern: kernDelta baselineY: baselineY
>
>	| destPoint leftX rightX glyphInfo g destY ch str |
>	destPoint _ aPoint.
>	glyphInfo _ Array new: 5.
>	startIndex to: stopIndex do: [:charIndex |
>		ch _ aString at: charIndex.
>		(self hasGlyphOf: ch) ifTrue:[
>			self glyphInfoOf: ch into: glyphInfo.
>			g _ glyphInfo first.
>			leftX _ glyphInfo second.
>			rightX _ glyphInfo third.
>			(glyphInfo fifth ~= aBitBlt lastFont) ifTrue: [
>				glyphInfo fifth installOn: aBitBlt.
>			].
>			aBitBlt sourceForm: g.
>			destY _ baselineY - glyphInfo fourth. 
>			aBitBlt destX: destPoint x.
>			aBitBlt destY: destY.
>			aBitBlt sourceOrigin: leftX @ 0.
>			aBitBlt width: rightX - leftX.
>			aBitBlt height: self height.
>			aBitBlt copyBits.
>			destPoint _ destPoint + (rightX - leftX + kernDelta @ 0).
>		] ifFalse:[
>			str _ ch asUndefinedGlyph.
>			destPoint _ self displayString: str on: aBitBlt from: 1 to: str size at: destPoint kern: kernDelta baselineY: baselineY.
>		].
>	].
>	^ destPoint.
>
>! !
>
>!StrikeFontSet methodsFor: 'private' stamp: 'ar 4/10/2005 03:26'!
>hasGlyphOf: aCharacter
>
>	| index f code leftX |
>	index _ aCharacter leadingChar + 1.
>	fontArray size < index ifTrue: [^false].
>	(f _ fontArray at: index) ifNil: [^false].
>
>	code _ aCharacter charCode.
>	((code between: f minAscii and: f maxAscii) not) ifTrue: [^false].
>	leftX _ f xTable at: code + 1.
>	leftX < 0 ifTrue: [^ false].
>	^true! !
>
>
>!TTCFont methodsFor: 'friend' stamp: 'ar 4/10/2005 03:28'!
>displayString: aString on: aBitBlt from: startIndex to: stopIndex at: aPoint kern: kernDelta baselineY: baselineY
>
>	| destPoint form glyphInfo destY ch str |
>	destPoint _ aPoint.
>	glyphInfo _ Array new: 5.
>	startIndex to: stopIndex do: [:charIndex |
>		ch _ aString at: charIndex.
>		(self hasGlyphOf: ch) ifTrue:[
>			self glyphInfoOf: ch into: glyphInfo.
>			form _ glyphInfo first.
>			(glyphInfo fifth ~= aBitBlt lastFont) ifTrue: [
>				glyphInfo fifth installOn: aBitBlt.
>			].
>			destY _ baselineY - glyphInfo fourth. 
>			aBitBlt sourceForm: form.
>			aBitBlt destX: destPoint x.
>			aBitBlt destY: destY.
>			aBitBlt sourceOrigin: (glyphInfo second) @ 0.
>			aBitBlt width: glyphInfo third - glyphInfo second.
>			aBitBlt height: form height.
>			aBitBlt copyBits.
>			destPoint _ destPoint + ((glyphInfo third - glyphInfo second) + kernDelta @ 0).
>		] ifFalse:[
>			str _ ch asUndefinedGlyph.
>			destPoint _ self displayString: str on: aBitBlt from: 1 to: str size at: destPoint kern: kernDelta baselineY: baselineY.
>		].
>	].
>	^ destPoint.
>! !
>
>!TTCFont methodsFor: 'public' stamp: 'ar 4/10/2005 03:11'!
>widthOf: aCharacter ifAbsent: aBlock
>
>	"This method cannot use #formOf: because formOf: discriminates the color and causes unnecessary bitmap creation."
>
>	| f assoc |
>	aCharacter charCode > 255 ifTrue: [^aBlock value].
>	assoc _ self cache at: (aCharacter charCode + 1).
>	assoc ifNotNil: [
>		^ assoc value width
>	].
>
>	f _ self computeForm: aCharacter.
>	self at: aCharacter charCode put: f.
>	^ f width.
>! !
>
>
>!MultiTTCFont methodsFor: 'as yet unclassified' stamp: 'ar 4/10/2005 03:13'!
>widthOf: aCharacter ifAbsent: aBlock
>	"ar 4/10/2005: This is odd - it looks like this assumes that all MultiTTCFonts define glyphs for all characters (which is rather unlikely...)"
>	"This method cannot use #formOf: because formOf: discriminates the color and causes unnecessary bitmap creation."
>
>	| newForm |
>	self hasCached: aCharacter ifTrue: [:form :index |
>		self access: aCharacter at: index.
>		^ form width.
>	].
>
>	newForm _ self computeForm: aCharacter.
>	self at: aCharacter put: newForm.
>	^ newForm width.
>
>! !
>
>
>!TTCFontSet methodsFor: 'as yet unclassified' stamp: 'ar 4/10/2005 03:30'!
>displayString: aString on: aBitBlt from: startIndex to: stopIndex at: aPoint kern: kernDelta baselineY: baselineY
>
>	| destPoint font form encoding glyphInfo char charCode destY str |
>	destPoint _ aPoint.
>	glyphInfo _ Array new: 5.
>	startIndex to: stopIndex do: [:charIndex |
>		char _ aString at: charIndex.
>		encoding _ char leadingChar + 1.
>		charCode _ char charCode.
>		font _ fontArray at: encoding.
>		((charCode between: font minAscii and: font maxAscii) not) 
>			ifTrue: [charCode _ nil].
>		charCode ifNil:[
>			str _ char asUndefinedGlyph.
>			destPoint _ self displayString: str on: aBitBlt from: 1 to: str size at: destPoint kern: kernDelta baselineY: baselineY.
>		] ifNotNil:[
>			self glyphInfoOf: char into: glyphInfo.
>			form _ glyphInfo first.
>			(glyphInfo fifth ~= aBitBlt lastFont) ifTrue: [
>				glyphInfo fifth installOn: aBitBlt.
>			].
>			destY _ baselineY - glyphInfo fourth. 
>			aBitBlt sourceForm: form.
>			aBitBlt destX: destPoint x.
>			aBitBlt destY: destY.
>			aBitBlt sourceOrigin: 0 @ 0.
>			aBitBlt width: form width.
>			aBitBlt height: form height.
>			aBitBlt copyBits.
>			destPoint _ destPoint + (form width + kernDelta @ 0).
>		].
>	].
>	^ destPoint.
>! !
>
>!TTCFontSet methodsFor: 'as yet unclassified' stamp: 'ar 4/10/2005 03:14'!
>widthOf: aCharacter ifAbsent: aBlock
>
>	| encoding |
>	encoding _ aCharacter leadingChar.
>	^ (fontArray at: encoding + 1) widthOf: aCharacter ifAbsent: aBlock! !
>
>TTCFontSet removeSelector: #widthOf:!
>MultiTTCFont removeSelector: #widthOf:!
>TTCFont removeSelector: #widthOf:!
>StrikeFontSet removeSelector: #widthOf:!
>StrikeFont removeSelector: #widthOf:!
>FixedFaceFont removeSelector: #widthOf:!
>  
>
>
> ------------------------------------------------------------------------
>
>
> ------------------------------------------------------------------------
>
>------------------------------------------------------------------------
>
>
>  
>




More information about the Squeak-dev mailing list