parent previous next question (Smalltalk Textbook 15)

FontDescription

This section describes 'FontDescription'. Inspect the following line to get an array of 'FontDescription' instances.

------------------------------------------------
Screen default defaultFontPolicy availableFonts
------------------------------------------------

Program 15-1 prints font name (family) and size (pixelSize) of these instances of 'FontDescription'. How many fonts do you have? These are all available for use in your Smalltalk environment.


Program-15-1: (Screen, FontPolicy, FontDescription; availableFonts, font
family, pixelSize)
-----------------------------------------------------------
Screen default defaultFontPolicy availableFonts
	do: 
		[:aFontDescription | 
		Transcript cr.
		Transcript show: aFontDescription family printString.
		Transcript space.
		Transcript show: aFontDescription pixelSize printString]
-----------------------------------------------------------

Program 15-1 shows font names with size as a pop up menu to select a font and size. This program uses stratified pop up menu I described before. If you select a font, the program returns an instance of 'FontDescription'. If you do not select anything, the program returns 'nil'. You can use this functionality in any of your programs.


Program-15-2: (Screen, FontPolicy, FontDescription, PopUpMenu, Dictionary,
SortedCollection; availableFonts, font family, pixelSize)
----------------------------------------------------------
| dictionary fonts labels values answer |
dictionary := Dictionary new.
fonts := Screen default defaultFontPolicy availableFonts.
fonts
	do: 
		[:font | 
		| family size |
		family := font family.
		size := font pixelSize.
		size > 0
			ifTrue:
				[(dictionary includesKey: family)
					ifFalse: [dictionary
							at: family
							put: OrderedCollection new].
				(dictionary at: family) add: size]].
labels := OrderedCollection new.
values := OrderedCollection new.
dictionary associations asSortedCollection
	do: 
		[:association | 
		| family strings answers menu |
		family := association key.
		strings := OrderedCollection new.
		answers := OrderedCollection new.
		association value
			do: 
				[:size | 
				strings add: size printString.
				answers add: family -> size].
		menu := PopUpMenu labelArray: strings values: answers.
		labels add: family.
		values add: menu].
answer := (PopUpMenu labelArray: labels values: values) startUp.
answer = 0 ifFalse: [fonts
		do: 
			[:font | 
			| family size |
			family := answer key.
			size := answer value.
			(font family = family and: [font pixelSize = size])
				ifTrue: 
					[answer := FontDescription new.
					answer family: family.
					answer pixelSize: size.
					^answer]]].
^nil
----------------------------------------------------------

Now let us apply fonts to 'ComposedText'. Program 15-3 creates 'ComposedText' using 'FontDescription'. The program specifies 'times' as 'family:' and 18 as 'pixelSize:'. If you do not have this font, change it to a font you have and 'do it'.


Program-15-3: (Screen, FontPolicy, FontDescription, CharacterAttributes,
TextAttributes, ComposedText; font family, pixelSize, setDefaultQuery:)
----------------------------------------------------------
| fontDescription characterAttributes textAttributes
  deviceFont composedText activeWindow |
fontDescription := FontDescription new.
fontDescription family: 'times'.
fontDescription pixelSize: 18.
characterAttributes := 
	CharacterAttributes newWithDefaultAttributes.
characterAttributes setDefaultQuery: fontDescription.
textAttributes := TextAttributes default.
textAttributes setCharacterAttributes: characterAttributes.
deviceFont := Screen default defaultFontPolicy
			findFont: textAttributes defaultFont.
textAttributes lineGrid: deviceFont height.
textAttributes baseline: deviceFont ascent.
composedText := ComposedText
			withText: 'Smalltalk' asText
			style: textAttributes.
activeWindow := ScheduledControllers activeController view.
activeWindow clear.
composedText displayOn: activeWindow graphicsContext.
activeWindow sensor waitClickButton.
activeWindow display
----------------------------------------------------------

Program 15-4 cycles through all of your fonts one by one; use control-C to abort.


Program-15-4: (Screen, FontPolicy, FontDescription, CharacterAttributes,
TextAttributes, ComposedText; font family, pixelSize, text attributes)
----------------------------------------------------------
| activeWindow activeSensor graphicsContext aString
  composedTextBlock displayBlock |
activeWindow := ScheduledControllers activeController view.
activeSensor := activeWindow sensor.
graphicsContext := activeWindow graphicsContext.
aString := 'Smalltalk Family
VisualWorks
ObjectWorks
Smalltalk/V
SmalltalkAgents
GNU Smalltalk'.
composedTextBlock := 
		[:family :size | 
		| fontDescription characterAttributes
		  textAttributes deviceFont |
		fontDescription := FontDescription new.
		fontDescription family: family.
		fontDescription pixelSize: size.
		characterAttributes := CharacterAttributes
						newWithDefaultAttributes.
		characterAttributes setDefaultQuery: fontDescription.
		textAttributes := TextAttributes default.
		textAttributes
			setCharacterAttributes: characterAttributes.
		deviceFont := Screen default defaultFontPolicy
					findFont: textAttributes defaultFont.
		textAttributes lineGrid: deviceFont height.
		textAttributes baseline: deviceFont ascent.
		ComposedText
			withText: aString asText
			style: textAttributes].
displayBlock := 
		[:family :size | 
		| composedText |
		Transcript cr.
		Transcript show: family printString.
		Transcript space.
		Transcript show: size printString.
		composedText := composedTextBlock
					value: family value: size.
		activeWindow clear.
		composedText displayOn: graphicsContext.
		graphicsContext
			displayRectangularBorder: composedText bounds].
Screen default defaultFontPolicy availableFonts
	do: 
		[:aFontDescription | 
		| family size |
		family := aFontDescription family.
		size := aFontDescription pixelSize.
		size > 0
			ifTrue: 
				[displayBlock value: family value: size.
				activeSensor waitClickButton]].
activeWindow display
----------------------------------------------------------

There are several things you need to watch out for when using fonts. First, you should not directly change the font (an instance of 'FontDescription') returned by evaluating 'Screen default defaultFontPolicy availableFonts'. Second you should not directly change the 'textAttributes' returned by 'TextAttributes default', because the copy is a shallow copy, meaning you're not getting a whole new object, but just a pointer to the existing 'CharacterAttributes' or 'FontDescription'. If you change it, the default 'textAttributes' of the whole system will be changed.


parent previous next question
Copyright (C) 1994-1996 by Atsushi Aoki
Translated by Kaoru Rin Hayashi & Brent N. Reeves