Mantis - Squeak
Viewing Issue Advanced Details
1781 Graphics feature always 09-11-05 06:48 09-04-13 00:07
Eddie Cottongim  
tim  
normal  
closed 3.9  
fixed  
none    
none 4.4  
0001781: BitBlt>>primDisplayString: is failing often
The primitive is failing in at least two instances.

The most important one is that it will always fail when trying to print a StrikeFontSet (which is very often). This is because StrikeFontSet has a nil glyphMap. It costs about 30-50% of printing performance.

The other is that the prim fails when called with a nil string. This is just a nuisance, but perhaps it should be caught further upstream.
This patch tries to fix the problem. It seems to work and provide a speedup. However, it is hardwired to use the latin1 encoding because I couldn't figure out the class well enough to understand what to do. Also I have no idea if a glyphMap is even appropriate for a StrikeFontSet. Oh for class comments. Anyway, maybe it will help someone start, because I won't have time to completely polish this.

Here is a semi useful benchmark. I got 1071 before, 772 after.

text := '012345678901234567890123456789'.
font := TextStyle default fontOfSize: 12.
width _ font widthOfStringOrText: text.
bb := (Form extent: width @ 30) getCanvas privatePort.
bb combinationRule: Form paint.

font installOn: bb foregroundColor: Color black backgroundColor: Color white.
    
Time millisecondsToRun:[
10000 timesRepeat: [
destPoint := font displayString: text on: bb from: 1 to: 30 at: 0@0 kern: 1.
].].
related to 0001650closed tim [BUG] CharacterScanner primitive is broken; char scanning generally in a mess 
has duplicate 0007338closed tim A little font rendering speedup 
 FontExperiment.2.cs [^] (1,007 bytes) 09-11-05 06:48

Notes
(0002640)
Eddie Cottongim   
09-11-05 20:45   
Correction, where i said nil string, I meant empty string ('').
(0002964)
andreas   
10-25-05 07:43   
I have changed this to a feature request. Primitives failing isn't a bug per se - it's perfectly expected behavior.
(0002973)
Eddie Cottongim   
10-25-05 16:34   
Fair enough. I think I had really meant it as a bug against StrikeFontSet which wasn't using BitBlt in such a way that it could ever succeed. Its not BitBlt's fault.
(0003258)
Eddie Cottongim   
12-10-05 07:33   
Update on this:

The attached code (FontExperiment2) no longer works as of 6705. It hangs the image.

The "issue" is still there though, and text scrolling suffers noticably for it.

I'm not sure what to do about this. Fonts need a major re-wacking, but I don't have time for that. I probably have time for a band-aid, but there are too many of those already.
(0014403)
tim   
07-22-13 02:08   
Eddie seems to be correct, so far as I can tell. Why doesn't StrikeFontSet return a plain characterToGlyphMap just like StrikeFont? After all, when in the ST backup code there is a reference to the font's height or glyphs then the height or glyphs of the first font in the font array is returned. Why not the relevant characterToGlyphMap?
(0014440)
tim   
09-03-13 23:54   
As it happens, StrikeFontSets appear to be pretty much unused in the 4.5 era image, so in a way this is a moot point. However, after digging into the insanity that is font handling I concluded that characterToGlyphMap should return the characterToGlyphMap of the font set's first contained font. This echoes the implementations of #ascent etc and furthermore the *only* usage outside StrikeFont internal methods is by primDisplayString:from:to:map:xTable: in the prim failure recovery code. By the time this is used we know that the string is a byteString and thus by following the workings of StrikeFontSet we can see that the first font must be the one used.

On a 3.4GHz/core i7 quad core iMac this improves the results of a slightly altered benchmark from 2436 to 1733, i.e. about 30%. Useful sort of improvement for slower machines.

The replacement test code is -
text := '012345678901234567890123456789'.
font := StrikeFontSet newFontArray: (TextStyle default fontArray).
width _ font widthOfStringOrText: text.
bb := (Form extent: width @ 30) getCanvas privatePort.
bb combinationRule: Form paint.

font installOn: bb foregroundColor: Color black backgroundColor: Color white.
    
Time millisecondsToRun:[
100000 timesRepeat: [
destPoint := font displayString: text on: bb from: 1 to: 30 at: 0@0 kern: 1.
].].
(0014441)
tim   
09-04-13 00:07   
(Actually fixed for 4.5 but you can't say that.)

Fixed the problem with a sensible implementation of characterToGlyphMap for StrikeFontSet; though they're not apparently used a great deal in current images. It makes a worthwhile 30%-ish improvement in rendering speed.

I'd like to thank the kind people that caused such a complicated mess of font related code to get into the image; without this sort of issue I'd never have had the chance to burn so many braincells in a single sitting.

See -
Graphics tpr.22
Multilingual tpr.167
TrueType tpr.26