FAQ : Smalltalk Programming Language : Q: Why can't I see all the text in my control when I change system fonts?
Q: Why can't I see all the text in my control when I change system fonts?
Problem
If you rely on Windows to determine the font used in your Smalltalk application, and the text in your control is not appropriately visible in your user interface components after you change the font or the size of the font, one of the following things may be happening:
1. Your Windows operating system may be using a bitmapped font.
2. Your Smalltalk interface component is specifying an absolute size rather than allowing relative resizing.
 
Solution
Bitmapped Font
Bitmapped fonts can be set at the time of Windows installation based on the default text size setting. However, if the default text size is later changed, the bitmapped fonts will not adapt to this change automatically.
Since bitmapped fonts do not scale well, best practice is to avoid them in favor of TrueType fonts. TrueType is an outlined font standard developed in the late 1980s by Apple and Microsoft which has been available on Windows since Win 3.1 released in 1992.
The Windows system registry controls the Windows system font. You can use it or the Windows control panel to determine your Windows system font.
Absolute component sizing
In order for user interface components to accommodate text using arbitrary fonts, the component size must be specified in a relative rather than an absolute manner. This will allow the component to resize based on the size of its textural content.
When you specify the screen real estate which your user interface component should occupy, you must constrain two sides of the widget and allow the other two sides to float. The size of the component will then change based on the font and the textual content. Components may also be attached to one another so that the entire layout can dynamically adjust as needed.
Examples of correct and incorrect sizing, widget and Part based.
VA Smalltalk enables you to use Abt parts or CW widgets to specify the application's user interface.
If you are using parts, the following shows a right and a wrong way to specify the size of a user interface component.
CORRECT:
The AbtLabelView below has a flexible height and width.
label1
framingSpec: (AbtViewAttachmentConstraint new
leftEdge: (AbtRunEdgeAttachmentConstraint new attachment: XmATTACHFORM; offset: 27);
rightEdge: (AbtRunEdgeAttachmentConstraint new attachment: XmATTACHNONE);
topEdge: (AbtRunEdgeAttachmentConstraint new attachment: XmATTACHFORM; offset: 25);
bottomEdge: (AbtRunEdgeAttachmentConstraint new attachment: XmATTACHNONE)).
The right/bottom edge could also be attached to the form the way the left/top edge is.
INCORRECT:
The AbtLabelView below has a fixed height and width.
label2
framingSpec: (AbtViewAttachmentConstraint new
leftEdge: (AbtRunEdgeAttachmentConstraint new attachment: XmATTACHFORM; offset: 27);
rightEdge: (AbtRunEdgeAttachmentConstraint new attachment: XmATTACHSELFOPPOSITE; offset: 48);
topEdge: (AbtRunEdgeAttachmentConstraint new attachment: XmATTACHFORM; offset: 94);
bottomEdge: (AbtRunEdgeAttachmentConstraint new attachment: XmATTACHPOSITION; position: 36)).
 
In the above example, XmATTACHSELFOPPOSITE asks the right edge to be attached to the left edge of the same control and to have a constant distance from that edge.
There are more right and wrong ways to make attachments, but this example is sufficient to focus your search.
If you are using CW widgets, the following shows a right and a wrong way to specify the size of a user interface component.
CORRECT:
If you code your user interface using WindowBuilder’s CW widget framework, WbApplicationFramework, the CwLabel below has a flexible height and width.
aCwLabel1
attachLeft: 16 relativeTo: XmATTACHFORM;
attachTop: 20 relativeTo: XmATTACHFORM;
yourself.
The right/bottom edge could also be attached to the form the way the left/top edge is.
INCORRECT:
If you code your user interface using WindowBuilder’s CW widget framework, WbApplicationFramework, the CwLabel below has a fixed height and width.
aCwLabel2
attachLeft: 19 relativeTo: XmATTACHFORM;
attachRight: 67 relativeTo: XmATTACHOPPOSITEFORM;
attachTop: 69 relativeTo: XmATTACHFORM;
attachBottom: 89 relativeTo: XmATTACHOPPOSITEFORM;
yourself.
In the above example, XmATTACHOPPOSITEFORM asks the right edge to be attached to the left edge of the same control and to have a constant distance from that edge. The same holds true for the bottom edge and its distance from the top edge of the CwLabel.
There are more right and wrong ways to make attachments, but this example is sufficient to start your search.
Damage Control
If there are too many user interface components which defer to Windows for their fonts and have absolute sides, the solution is either to specify the appropriate font for the size, or to extend VA Smalltalk to take into account the font when creating the OSWidget level of the UI component.
Approach 1: Modifications to base image
OSWidget does have a class variable, DefaultFont, which holds onto the default system font currently in effect in Windows. The problem is that this class variable is not used to set the fonts of individual widgets, so changing it will have no effect on them. It will affect the layout of certain windows that use that variable to gather metrics (width, height, etc.) of that font for dynamic layout purposes.
By modifying or overriding various base image methods, you could inject code that would forcibly set the font for every widget as it is created.
You will need to modify each widget class (or relevant widget hierarchy) so that it explicitly sets a font during its creation process. If you don't set a font, you will get the default system font as outlined above.
The approach you take would very much depend on whether you are using Abt parts or CW widgets. For example, to do this with the AbtLabelView hierarchy (labels and buttons), you could add the following override method
!AbtLabelView privateMethods !
initialize
super initialize.
“Use an 8 point ms sans serif font”
fontName = '--ms sans serif-medium-r-normal---80---p---'! !
At a common widgets level, the approach would have to be different since common widgets do not all inherit the fontName variable from one place.
Approach 2: Modifications to application framework
Alternatively, you could add code to your framework that would loop through all of the widgets in a window and set the font before the window is opened. If you don't want to modify or override any base image code, that would be a cleaner solution.
Last modified date: 05/08/2017