[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
|