<body><div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000;text-align: left" dir="ltr">
                                        Look okay. It's about browsing available fonts on your platform and installing them into the Squeak system. I would not mention that "delete font" thing as it is slightly misleading.<div><br></div><div>Best,</div><div>Marcel</div><div class="mb_sig"></div><blockquote class='history_container' type='cite' style='border-left-style:solid;border-width:1px; margin-top:20px; margin-left:0px;padding-left:10px;'>
                        <p style='color: #AAAAAA; margin-top: 10px;'>Am 06.04.2022 20:25:24 schrieb christoph.thiede@student.hpi.uni-potsdam.de <christoph.thiede@student.hpi.uni-potsdam.de>:</p><div style='font-family:Arial,Helvetica,sans-serif'>
Hi Marcel,<br>
<br>
is there a change log for this commit, I cannot find it? I'm not sure what I should write into the release notes for the font importer. For now, I just have:<br>
<br>
- overall refurbishing<br>
- browse font before installing it<br>
- delete font<br>
- apply font as default for everything or as fallback font<br>
<br>
Did I miss any other major features/changes? :-)<br>
<br>
Best,<br>
Christoph<br>
<br>
<span style="color: #808080">---<br>
</span><span style="color: #808080"><i>Sent from </i></span><span style="color: #808080"><i><a href="https://github.com/hpi-swa-lab/squeak-inbox-talk"><u><font color="#808080">Squeak Inbox Talk</font></u></a></i></span><br>
<br>
On 2022-03-01T16:38:51+00:00, commits@source.squeak.org wrote:<br>
<br>
> Marcel Taeumel uploaded a new version of Morphic to project The Trunk:<br>
> http://source.squeak.org/trunk/Morphic-mt.1917.mcz<br>
> <br>
> ==================== Summary ====================<br>
> <br>
> Name: Morphic-mt.1917<br>
> Author: mt<br>
> Time: 1 March 2022, 5:38:45.946136 pm<br>
> UUID: 7266c339-a1ef-904c-b634-0b4163950574<br>
> Ancestors: Morphic-mt.1916<br>
> <br>
> Next major iteration on the FontImporterTool.<br>
> <br>
> Needs TrueType-mt.78<br>
> <br>
> =============== Diff against Morphic-mt.1916 ===============<br>
> <br>
> Item was changed:<br>
> + SystemOrganization addCategory: #'Morphic-Balloon'!<br>
> + SystemOrganization addCategory: #'Morphic-Basic'!<br>
>   SystemOrganization addCategory: #'Morphic-Basic-NewCurve'!<br>
> + SystemOrganization addCategory: #'Morphic-Borders'!<br>
> - SystemOrganization addCategory: #'Morphic-Pluggable Widgets'!<br>
>   SystemOrganization addCategory: #'Morphic-Collections-Arrayed'!<br>
> + SystemOrganization addCategory: #'Morphic-Demo'!<br>
> + SystemOrganization addCategory: #'Morphic-Events'!<br>
> - SystemOrganization addCategory: #'Morphic-Widgets'!<br>
>   SystemOrganization addCategory: #'Morphic-Explorer'!<br>
> + SystemOrganization addCategory: #'Morphic-Kernel'!<br>
> + SystemOrganization addCategory: #'Morphic-Layouts'!<br>
> - SystemOrganization addCategory: #'Morphic-Borders'!<br>
> - SystemOrganization addCategory: #'Morphic-Menus-DockingBar'!<br>
>   SystemOrganization addCategory: #'Morphic-Menus'!<br>
> + SystemOrganization addCategory: #'Morphic-Menus-DockingBar'!<br>
> + SystemOrganization addCategory: #'Morphic-Pluggable Widgets'!<br>
> + SystemOrganization addCategory: #'Morphic-Sound-Synthesis'!<br>
>   SystemOrganization addCategory: #'Morphic-Support'!<br>
> + SystemOrganization addCategory: #'Morphic-Text Support'!<br>
>   SystemOrganization addCategory: #'Morphic-TrueType'!<br>
> + SystemOrganization addCategory: #'Morphic-Widgets'!<br>
> - SystemOrganization addCategory: #'Morphic-Basic'!<br>
> - SystemOrganization addCategory: #'Morphic-Demo'!<br>
>   SystemOrganization addCategory: #'Morphic-Windows'!<br>
> - SystemOrganization addCategory: #'Morphic-Balloon'!<br>
> - SystemOrganization addCategory: #'Morphic-Kernel'!<br>
> - SystemOrganization addCategory: #'Morphic-Sound-Synthesis'!<br>
>   SystemOrganization addCategory: #'Morphic-Worlds'!<br>
> - SystemOrganization addCategory: #'Morphic-Layouts'!<br>
> - SystemOrganization addCategory: #'Morphic-Text Support'!<br>
> - SystemOrganization addCategory: #'Morphic-Events'!<br>
> <br>
> Item was removed:<br>
> - Object subclass: #FontImporterFontDescription<br>
> -     instanceVariableNames: 'fontname filename children parent'<br>
> -     classVariableNames: ''<br>
> -     poolDictionaries: ''<br>
> -     category: 'Morphic-Support'!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>><= (in category 'comparing') -----<br>
> - <= other<br>
> - <br>
> -     ^ self fontname asString <= other fontname asString!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>>addChild: (in category 'accessing') -----<br>
> - addChild: aChild<br>
> - <br>
> -     ^ self children add: aChild!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>>allFilenames (in category 'accessing') -----<br>
> - allFilenames<br>
> - <br>
> -     ^ self filename<br>
> -         ifNil: [<br>
> -             (self children<br>
> -                 select: [:child | child filename notNil]<br>
> -                 thenCollect: [:child | child filename])<br>
> -             asSet asArray]<br>
> -         ifNotNil: [:f | {f}] !<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>>children (in category 'accessing') -----<br>
> - children<br>
> - <br>
> -     ^ children ifNil: [children := OrderedCollection new].!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>>children: (in category 'accessing') -----<br>
> - children: anObject<br>
> - <br>
> -     children := anObject!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>>filename (in category 'accessing') -----<br>
> - filename<br>
> - <br>
> -     ^ filename!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>>filename: (in category 'accessing') -----<br>
> - filename: anObject<br>
> - <br>
> -     filename := anObject!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>>fontname (in category 'accessing') -----<br>
> - fontname<br>
> - <br>
> -     ^ fontname!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>>fontname: (in category 'accessing') -----<br>
> - fontname: anObject<br>
> - <br>
> -     fontname := anObject!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>>hasChildren (in category 'testing') -----<br>
> - hasChildren<br>
> - <br>
> -     ^ self children notNil and: [self children notEmpty]!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>>normalize (in category 'actions') -----<br>
> - normalize<br>
> - <br>
> -     self children size = 1 ifTrue: [ | pseudoChild |<br>
> -         pseudoChild := self children removeFirst.<br>
> -         (self filename notNil and: [pseudoChild filename ~=  self filename])<br>
> -             ifTrue: [self error: 'Inconsistent state'].<br>
> -         self filename: pseudoChild filename]!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>>parent (in category 'accessing') -----<br>
> - parent<br>
> - <br>
> -     ^ parent!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>>parent: (in category 'accessing') -----<br>
> - parent: anObject<br>
> - <br>
> -     parent := anObject!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterFontDescription>>printOn: (in category 'printing') -----<br>
> - printOn: aStream<br>
> - <br>
> -     self parent ifNotNil: [:p | aStream nextPutAll: p fontname; nextPut: $ ].<br>
> -     aStream nextPutAll: self fontname.<br>
> -     self children notEmpty ifTrue: [aStream nextPut: $ ].<br>
> -     self children<br>
> -         do: [:subfont | aStream nextPutAll: subfont fontname]<br>
> -         separatedBy: [aStream nextPut: $/].<br>
> -     aStream nextPut: $ ; nextPut: $(.<br>
> -     self allFilenames<br>
> -         do: [:filename | aStream nextPutAll: filename]<br>
> -         separatedBy: [aStream nextPut: $,; nextPut: $ ].<br>
> -     aStream nextPut: $).<br>
> - !<br>
> <br>
> Item was changed:<br>
>   Model subclass: #FontImporterTool<br>
> +     instanceVariableNames: 'title allFonts currentSelection currentParent selectedFont previewTextSelector customPreviewText pointSize lineSpacing editModeWidgets'<br>
> +     classVariableNames: 'CustomPreviewTexts'<br>
> -     instanceVariableNames: 'title allFonts emphasis currentSelection currentParent warningSeen'<br>
> -     classVariableNames: ''<br>
>       poolDictionaries: ''<br>
>       category: 'Morphic-Support'!<br>
>   <br>
>   !FontImporterTool commentStamp: 'topa 3/9/2015 18:56' prior: 0!<br>
>   A tool to import platform (native) fonts into the image!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>aboutToStyle: (in category 'preview text - code styling') -----<br>
> + aboutToStyle: aStyler<br>
> + <br>
> +     previewTextSelector = #codeSample ifFalse: [^ false].<br>
> +     self customPreviewText ifNotEmpty: [^ false].<br>
> +     <br>
> +     aStyler parseAMethod: true. "See Text class >> #codeSample."<br>
> +     ^ true!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>acceptCustomPreviewText: (in category 'preview text - custom') -----<br>
> + acceptCustomPreviewText: aStringOrTextOrNil<br>
> +     "The user accepted (i.e. CMD+S or Return) the current input text, Now we store it in the list of custom texts so that it is retrievable via the preview button."<br>
> + <br>
> +     customPreviewText := aStringOrTextOrNil ifNotNil: [:value | value asString].<br>
> +     self changed: #customPreviewText.<br>
> +     <br>
> +     self customPreviewText ifNotEmpty: [:customText | <br>
> +         CustomPreviewTexts ifNil: [CustomPreviewTexts := OrderedCollection new].<br>
> +         (CustomPreviewTexts includes: customText)<br>
> +             ifFalse:[CustomPreviewTexts add: customText] ].<br>
> + <br>
> +     ^ true!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>adjustXHeight (in category 'edit mode - actions') -----<br>
> + adjustXHeight<br>
> + <br>
> +     self selectedFont adjustXHeight; adjustLineGapToGlyphScale.<br>
> +     <br>
> +     self currentSelection <br>
> +         ttExtraScale: self selectedFont extraGlyphScale;<br>
> +         ttExtraGap: self selectedFont extraLineGap.<br>
> +     <br>
> +     self changed: #objectChanged with: self currentSelection.<br>
> +     self changed: #selectedFontTextStyle.<br>
> +     <br>
> +     self changed: #pointSizeInput.<br>
> +     self changed: #lineSpacingInput.    <br>
> +     self changed: #ttExtraScaleInput.<br>
> +     self changed: #ttExtraGapInput.!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>allFonts (in category 'font list/tree') -----<br>
> - ----- Method: FontImporterTool>>allFonts (in category 'accessing') -----<br>
>   allFonts<br>
> -     ^ allFonts ifNil: [ | fonts |<br>
> -         fonts := Dictionary new.<br>
> -         Cursor wait showWhile: [<br>
> -             TTFileDescription fontPathsDo:[:path |<br>
> -                 TTFileDescription fontFilesIn: path do:[:font| | fontDesc filename fname |<br>
> -                     filename := path, FileDirectory slash, font fileName.<br>
> -                     fname := self textForFamily: font familyName subfamily: nil.<br>
> -                     fontDesc := fonts <br>
> -                         at: font familyName<br>
> -                         ifAbsentPut: (FontImporterFontDescription new fontname: fname; yourself).<br>
> -                     font subfamilyName<br>
> -                         ifNil: [fontDesc filename: filename]<br>
> -                         ifNotNil: [ |subfontDesc sname | <br>
> -                             sname := self textForFamily: font familyName subfamily: font subfamilyName.<br>
> -                             subfontDesc := FontImporterFontDescription new fontname: sname; yourself.<br>
> -                             subfontDesc<br>
> -                                 parent: fontDesc;<br>
> -                                 filename: filename.<br>
> -                             fontDesc addChild: subfontDesc]]]].<br>
> -         allFonts := fonts values sorted.<br>
> -         allFonts do: [:fontDesc | fontDesc normalize].<br>
> -         allFonts].<br>
>   <br>
> +     ^ allFonts ifNil: [Cursor wait showWhile: [allFonts := TTFontFileHandle allHandles values sorted]]!<br>
> -         !<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>allFonts: (in category 'font list/tree') -----<br>
> - ----- Method: FontImporterTool>>allFonts: (in category 'accessing') -----<br>
>   allFonts: anObject<br>
>   <br>
>       allFonts := anObject.<br>
>       self changed: #allFonts.!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>applyFont (in category 'actions') -----<br>
> + applyFont<br>
> + <br>
> +     | fontSymbols fontLabels choice |<br>
> +     fontSymbols := self fontSymbolsToUse.<br>
> +     fontLabels := fontSymbols collect: [:ea | (ea findFeatures joinSeparatedBy: ' ') capitalized].<br>
> +     choice := Project uiManager chooseFrom: fontLabels values: fontSymbols title: 'Apply font as...' translated.<br>
> +     choice ifNil: [^ self].<br>
> +     self applyFontTo: choice.!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>applyFontTo: (in category 'actions') -----<br>
> + applyFontTo: fontSymbol<br>
> + <br>
> +     self currentSelection isInstalled ifFalse: [self installFont].<br>
> +     <br>
> +     Cursor wait showWhile: [<br>
> +         UserInterfaceTheme setFont: fontSymbol to: self selectedFont].!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>browseFont (in category 'actions') -----<br>
> + browseFont<br>
> + <br>
> +     self selectedFont browseAllGlyphsByCategory.!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>browseImported (in category 'actions') -----<br>
> - browseImported<br>
> - <br>
> -     | filenames fonts ttcFonts |<br>
> -     fonts := self currentSelection.<br>
> -     filenames := fonts allFilenames.<br>
> -     <br>
> -     ttcFonts := (filenames gather: [:ea | TTFontReader parseFileNamed: ea])<br>
> -         collect: [:descr | TTCFont new ttcDescription: descr; pointSize: TextStyle defaultFont pointSize; yourself].<br>
> -     <br>
> -     ttcFonts do: [:ea | ea browseAllGlyphs; browseAllGlyphsByCategory].!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>browseLinked (in category 'actions') -----<br>
> - browseLinked<br>
> - <br>
> -     | filenames fonts ttcFonts |<br>
> -     fonts := self currentSelection.<br>
> -     filenames := fonts allFilenames.<br>
> -     <br>
> -     ttcFonts := filenames gather: [:ea | <br>
> -         (TTFileDescription readFontsFrom: ea)<br>
> -             collect: [:descr | TTCFont new ttcDescription: descr; pointSize: TextStyle defaultFont pointSize; yourself]].<br>
> -     <br>
> -     ttcFonts do: [:ea | ea browseAllGlyphs; browseAllGlyphsByCategory].!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>browseSystemFonts (in category 'actions') -----<br>
> + browseSystemFonts<br>
> +     "Open a workspace that shows the current preview text with the usual system fonts so that users can compare the font they want to import."<br>
> +     <br>
> +     | sample tmp fonts sorted contents preview |<br>
> +     previewTextSelector = #widgetSample<br>
> +         ifTrue: [ sample := [:font | self widgetSampleFor: font] ]<br>
> +         ifFalse: [<br>
> +             tmp := self previewText.<br>
> +             sample := [:font | tmp]].<br>
> +     (TextStyler for: #Smalltalk) ifNotNil: [:stylerClass |<br>
> +         | styler |<br>
> +         styler := stylerClass new.<br>
> +         (self aboutToStyle: styler)<br>
> +             ifTrue: [sample := [:font | styler styledTextFor: tmp asText]]].<br>
> +     <br>
> +     fonts := IdentityDictionary new.<br>
> +     self fontSymbolsToUse do: [:ea |<br>
> +         | font |<br>
> +         font := UserInterfaceTheme current get: ea.<br>
> +         (fonts at: font ifAbsentPut: [OrderedCollection new]) add: ea].<br>
> + <br>
> +     sorted := fonts keys sorted: [:a :b | <br>
> +         a familyName < b familyName or: [a familyName = b familyName and: [<br>
> +         a pointSize < b pointSize or: [a pointSize = b pointSize and: [<br>
> +         a emphasis < b emphasis]]]]].<br>
> + <br>
> +     contents := Text streamContents: [:s |<br>
> +         <br>
> +         sorted do: [:font |<br>
> +             preview := '{1} ({2} {3}pt)\    #{4}\\' withCRs asText format: {<br>
> +                 font familyName asText addAttribute: (PluggableTextAttribute evalBlock: [font explore]); yourself.<br>
> +                 font subfamilyName.<br>
> +                 font pointSize.<br>
> +                 (fonts at: font) joinSeparatedBy: '\    #' withCRs. }.<br>
> +             <br>
> +             preview := preview, (sample value: font).<br>
> +             preview := preview, String cr. "for the consistent line height at the end"        <br>
> + <br>
> +             s cr; nextPutAll: (preview asText addAttribute: (TextFontReference toFont: font); yourself); cr ]].<br>
> + <br>
> +     contents editWithLabel: 'Current system fonts'.!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>buildButtonBarWith: (in category 'ui - building') -----<br>
> - ----- Method: FontImporterTool>>buildButtonBarWith: (in category 'toolbuilder') -----<br>
>   buildButtonBarWith: builder<br>
>       "Build the button bar"<br>
>       | panelSpec |<br>
>       panelSpec := builder pluggablePanelSpec new.<br>
>       panelSpec<br>
>           layout: #horizontal;<br>
>           children: OrderedCollection new.<br>
>   <br>
>       {<br>
> +         #installButtonLabel.<br>
> +         #installButtonHelp.<br>
> +         #installButtonHit.<br>
> +         #installButtonColor.<br>
> +         #installButtonEnabled.<br>
> +         <br>
> +         'Apply...' translated.<br>
> +         'Apply the current font in the system. Assure that the font is installed.' translated.<br>
> +         #applyFont.<br>
> +         nil.<br>
> +         nil.<br>
> +         <br>
> +         "nil. nil. nil. nil."<br>
> +         <br>
>           'Browse' translated.<br>
> +         'Browse the glyphs. Do not install the font into the image.' translated.<br>
> +         #browseFont.<br>
> -         'Read the font data and browse the glyphs. Do not install the font into the image.' translated.<br>
> -         #browseImported.<br>
> -         'Install' translated.<br>
> -         'Include the font data in the image and provide a TextStyle for the font' translated.<br>
> -         #import.<br>
> -         'Close' translated.<br>
>           nil.<br>
> +         nil.<br>
> +         <br>
> +         'Explore' translated.<br>
> +         'Explore the font object.' translated.<br>
> +         #exploreFont.<br>
> +         nil.<br>
> +         nil.<br>
> +     } groupsDo: [:label :help :action :buttonColor :enabled |<br>
> +         | spec |<br>
> +         action<br>
> +             ifNil: [<br>
> +                 spec := builder pluggableSpacerSpec new]<br>
> +             ifNotNil: [<br>
> +                 spec := builder pluggableButtonSpec new<br>
> +                     model: self;<br>
> +                     label: label;<br>
> +                     color: buttonColor;<br>
> +                     help: help;<br>
> +                     action: action;<br>
> +                     enabled: enabled;<br>
> +                     yourself].<br>
> +         panelSpec children addLast: spec ].<br>
> -         #close.<br>
> -     } groupsDo: [:label :help :action |<br>
> -         | buttonSpec |<br>
> -         buttonSpec := builder pluggableButtonSpec new<br>
> -             model: self;<br>
> -             label: label;<br>
> -             help: help;<br>
> -             action: action;<br>
> -             yourself.<br>
> -         panelSpec children addLast: buttonSpec].<br>
>   <br>
>       ^panelSpec!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>buildFontListWith: (in category 'ui - building') -----<br>
> - ----- Method: FontImporterTool>>buildFontListWith: (in category 'toolbuilder') -----<br>
>   buildFontListWith: builder<br>
>       "Build the font choosers list of font names"<br>
>       <br>
>       ^ builder pluggableTreeSpec new<br>
>           model: self;<br>
>           roots: #allFonts; <br>
>           label: #labelOf: ;<br>
>           getChildren: #childrenOf: ;<br>
>           getSelected: #currentSelection;<br>
>           setSelected: #currentSelection:;<br>
>           setSelectedParent: #currentParent:;<br>
>           menu: #fontListMenu:;<br>
>           autoDeselect: false;<br>
>           yourself<br>
>   !<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>buildFontPanelWith: (in category 'ui - building') -----<br>
> + buildFontPanelWith: builder<br>
> +     "Build the main panel for the currently selected font (family). Includes a list of associated file names, an interactive preview panel and the copyright."<br>
> +     <br>
> +     ^ builder pluggablePanelSpec new<br>
> +         children: {<br>
> +             builder pluggableTextSpec new<br>
> +                 model: self;<br>
> +                 getText: #filename;<br>
> +                 readOnly: true;<br>
> +                 indicateUnacceptedChanges: false;<br>
> +                 font: self filenameFont;<br>
> +                 help: '<- Please select a font family';<br>
> +                 frame: (LayoutFrame <br>
> +                     fractions: (0 at 0 corner: 1 at 0)<br>
> +                     offsets: (0 at 0 corner: 0@ self filenameHeight));<br>
> +                 yourself.<br>
> + <br>
> +             (self buildPreviewPaneWith: builder)<br>
> +                 frame: (LayoutFrame <br>
> +                     fractions: (0 at 0 corner: 1 at 1)<br>
> +                     offsets: (0@ self filenameHeight corner: 0@ (self copyrightHeight negated)));<br>
> +                 yourself.<br>
> +             <br>
> +             builder pluggableTextSpec new<br>
> +                 model: self;<br>
> +                 getText: #copyright;<br>
> +                 font: self copyrightFont;<br>
> +                 readOnly: true;<br>
> +                 indicateUnacceptedChanges: false;<br>
> +                 frame: (LayoutFrame <br>
> +                     fractions: (0 at 1 corner: 1 at 1)<br>
> +                     offsets: (0 @ (self copyrightHeight negated) corner: 0 @ 0));<br>
> +                 yourself<br>
> +             <br>
> +         };<br>
> +         yourself!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>buildPreviewPaneWith: (in category 'ui - building') -----<br>
> - ----- Method: FontImporterTool>>buildPreviewPaneWith: (in category 'toolbuilder') -----<br>
>   buildPreviewPaneWith: builder<br>
> +     "Build the preview panel. Offer the user the change preview text through the default font, point size, extra (glyph) scale and extra (line) gap."<br>
> -     "Build the preview panel"<br>
>       <br>
>       ^ builder pluggablePanelSpec new<br>
>   "        wantsResizeHandles: true;"<br>
>           children: {<br>
> +             builder pluggablePanelSpec new<br>
> +                 children: {<br>
> +                     builder pluggableButtonSpec new<br>
> +                         model: self;<br>
> +                         help: #previewTextButtonHelp;<br>
> +                         label: #previewTextButtonLabel;<br>
> +                         action: #offerPreviewTextMenu;<br>
> +                         frame: (LayoutFrame fractions: (0 at 0 corner: 0.15 at 1));<br>
> +                         yourself.<br>
> +                         <br>
> +                     builder pluggableInputFieldSpec new<br>
> +                         model: self;<br>
> +                         help: 'Type custom preview text here...' translated;<br>
> +                         getText: #customPreviewText;<br>
> +                         setText: #acceptCustomPreviewText:;<br>
> +                         editText: #editCustomPreviewText:;<br>
> +                         plainTextOnly: true;<br>
> +                         frame: (LayoutFrame fractions: (0.15 at 0 corner: 0.85 at 1));<br>
> +                         yourself.<br>
> +                         <br>
> +                     builder pluggableButtonSpec new<br>
> +                         model: self;<br>
> +                         help: 'Click to see current preview text using the system''s current fonts for comparison' translated;<br>
> +                         label: 'Compare' translated;<br>
> +                         action: #browseSystemFonts;<br>
> +                         frame: (LayoutFrame fractions: (0.85 at 0 corner: 1 at 1));<br>
> +                         yourself };<br>
> +                 frame:  (LayoutFrame<br>
> -             builder pluggableTextSpec new<br>
> -                 model: self;<br>
> -                 getText: #filename;<br>
> -                 readOnly: true;<br>
> -                 indicateUnacceptedChanges: false;<br>
> -                 font: self filenameFont;<br>
> -                 frame: (LayoutFrame <br>
>                       fractions: (0 at 0 corner: 1 at 0)<br>
> +                     offsets: (0 at 0 corner: 0@ self customPreviewTextHeight));<br>
> -                     offsets: (0 at 0 corner: 0@ self filenameHeight));<br>
>                   yourself.<br>
> +                 <br>
> - <br>
>               builder pluggableTextSpec new<br>
>                   model: self;<br>
>                   getText: #previewText;<br>
>                   textStyle: #selectedFontTextStyle;<br>
>                   askBeforeDiscardingEdits: false;<br>
>                   indicateUnacceptedChanges: false;<br>
>                   softLineWrap: false;<br>
> +                 padding: self previewTextPadding;<br>
> +                 stylerClass: (TextStyler for: #Smalltalk);<br>
> +                 menu: #previewTextMenu:shifted:;<br>
> +                 frame: (LayoutFrame<br>
> -                 frame: (LayoutFrame <br>
>                       fractions: (0 at 0 corner: 1 at 1)<br>
> +                     offsets: (0 @ self customPreviewTextHeight corner: 0@ self configurationPanelHeight negated));<br>
> -                     offsets: (0@ self filenameHeight corner: 0@ (self copyrightHeight negated)));<br>
>                   yourself.<br>
>                   <br>
> +             builder pluggablePanelSpec new name: #configPanel; children: (Array streamContents: [:s | | n |<br>
> +                 n := 0.<br>
> +                 self fontConfigurationSpecs groupsDo: [:kind :get :help :label :group | | w |<br>
> +                     kind caseOf: {<br>
> +                         [#spacer] -> [<br>
> +                             w := builder pluggableSpacerSpec new fillSpaceHorizontally].<br>
> +                         [#button] -> [<br>
> +                             w := builder pluggableButtonSpec new<br>
> +                                 model: self; label: label; action: get; help: help; yourself].<br>
> +                         [#text] -> [<br>
> +                             w := builder pluggableInputFieldSpec new<br>
> +                                 model: self; getText: get; setText: get asSimpleSetter;<br>
> +                                 help: help; plainTextOnly: true; yourself].<br>
> +                     } otherwise: [ "Ignore" ].<br>
> +                     w ifNotNil: [ "Remember the group. See #toggleEditMode"<br>
> +                         w name: (group, (n := n + 1)) asSymbol.<br>
> +                         s nextPut: w] ]]);<br>
> +                 layout: #horizontal;<br>
> +                 frame: self configurationPanelFrame;<br>
> +                 yourself.<br>
> -             builder pluggableTextSpec new<br>
> -                 model: self;<br>
> -                 getText: #copyright;<br>
> -                 font: Preferences standardBalloonHelpFont; <br>
> -                 readOnly: true;<br>
> -                 indicateUnacceptedChanges: false;<br>
> -                 frame: (LayoutFrame <br>
> -                     fractions: (0 at 1 corner: 1 at 1)<br>
> -                     offsets: (0 @ (self copyrightHeight negated) corner: 0 @ 0));<br>
> -                 yourself<br>
> -             <br>
>           };<br>
>           yourself!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>buildWith: (in category 'ui - building') -----<br>
> - ----- Method: FontImporterTool>>buildWith: (in category 'toolbuilder') -----<br>
>   buildWith: builder<br>
>       "Create the ui for the browser"<br>
>       "ToolBuilder open: self"<br>
>       <br>
> +     | windowSpec window |<br>
> -     | windowSpec |<br>
>       windowSpec := self buildWindowWith: builder specs: {<br>
>           (self fontListFrame) -> [self buildFontListWith: builder].<br>
> +         (self fontPanelFrame) -> [self buildFontPanelWith: builder].<br>
> -         (self previewFrame) -> [self buildPreviewPaneWith: builder].<br>
>           (self buttonsFrame) -> [self buildButtonBarWith: builder].<br>
>       }.<br>
> +     window := builder build: windowSpec.<br>
> +     self prepareEditMode: (builder widgetAt: #configPanel).<br>
> +     ^ window!<br>
> -     ^ builder build: windowSpec!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>buttonHeight (in category 'ui - layout') -----<br>
> - ----- Method: FontImporterTool>>buttonHeight (in category 'layout') -----<br>
>   buttonHeight<br>
>   <br>
>       ^ ToolBuilder default buttonRowHeight!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>buttonsFrame (in category 'ui - layout') -----<br>
> - ----- Method: FontImporterTool>>buttonsFrame (in category 'layout') -----<br>
>   buttonsFrame<br>
>   <br>
>       ^ LayoutFrame<br>
>           fractions: (0 at 1 corner: 1 at 1)<br>
>           offsets: (0@ self buttonHeight negated corner: 0 at 0)<br>
>   !<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>childrenOf: (in category 'font list/tree') -----<br>
> - ----- Method: FontImporterTool>>childrenOf: (in category 'accessing') -----<br>
>   childrenOf: aFontDescription<br>
>   <br>
>       ^ aFontDescription children!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>close (in category 'actions') -----<br>
> - close<br>
> -     self changed: #close.!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>configurationPanelFrame (in category 'ui - layout') -----<br>
> + configurationPanelFrame<br>
> + <br>
> +     ^ LayoutFrame<br>
> +         fractions: (0 at 1 corner: 1 at 1)<br>
> +         offsets: (0 @ self configurationPanelHeight negated corner: 0 at 0)!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>configurationPanelHeight (in category 'ui - layout') -----<br>
> + configurationPanelHeight<br>
> + <br>
> +     ^ ToolBuilder default inputFieldHeight!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>copyright (in category 'accessing') -----<br>
> - ----- Method: FontImporterTool>>copyright (in category 'model access') -----<br>
>   copyright<br>
>       | f |<br>
>       f := self selectedFont ifNil:[^ ''].<br>
>       ^ f isTTCFont<br>
>           ifTrue: [f ttcDescription copyright ifNil: ['']]<br>
>           ifFalse: ['']!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>copyrightFont (in category 'ui - layout') -----<br>
> + copyrightFont<br>
> + <br>
> +     ^ Preferences standardBalloonHelpFont!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>copyrightHeight (in category 'ui - layout') -----<br>
> - ----- Method: FontImporterTool>>copyrightHeight (in category 'layout') -----<br>
>   copyrightHeight<br>
>   <br>
>       ^ ToolBuilder default helpFieldHeightFor: 3!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>currentParent (in category 'font list/tree') -----<br>
> - ----- Method: FontImporterTool>>currentParent (in category 'accessing') -----<br>
>   currentParent<br>
>   <br>
>       ^ currentParent!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>currentParent: (in category 'font list/tree') -----<br>
> - ----- Method: FontImporterTool>>currentParent: (in category 'accessing') -----<br>
>   currentParent: anObject<br>
>   <br>
>       anObject = currentParent ifTrue: [^ self].<br>
>       currentParent := anObject.<br>
>       self changed: #currentParent.<br>
>   !<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>currentSelection (in category 'font list/tree') -----<br>
> - ----- Method: FontImporterTool>>currentSelection (in category 'accessing') -----<br>
>   currentSelection<br>
>   <br>
>       ^ currentSelection!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>currentSelection: (in category 'font list/tree') -----<br>
> + currentSelection: fontHandleOrNil<br>
> - ----- Method: FontImporterTool>>currentSelection: (in category 'accessing') -----<br>
> - currentSelection: anObject<br>
>   <br>
> +     fontHandleOrNil = currentSelection ifTrue: [^ self].<br>
> +     currentSelection := fontHandleOrNil.<br>
> -     anObject = currentSelection ifTrue: [^ self].<br>
> -     currentSelection := anObject.<br>
>       self changed: #currentSelection.<br>
> +     <br>
> +     fontHandleOrNil<br>
> +         ifNotNil: [self editModeEnabled: self currentSelection isModified].<br>
> +     <br>
> +     self selectedFont: nil. "Refresh preview"!<br>
> - "    self changed: #previewText.<br>
> -     self changed: #selectedFontTextStyle."<br>
> -     self changed: #filename.<br>
> -     self changed: #copyright.!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>customPreviewText (in category 'preview text - custom') -----<br>
> + customPreviewText<br>
> + <br>
> +     ^ customPreviewText ifNil: ['']!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>customPreviewTextFont (in category 'ui - layout') -----<br>
> + customPreviewTextFont<br>
> + <br>
> +     ^ TextStyle defaultFont!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>customPreviewTextHeight (in category 'ui - layout') -----<br>
> + customPreviewTextHeight<br>
> + <br>
> +     ^ ToolBuilder default inputFieldHeight!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>defaultButtonColor (in category 'ui - colors') -----<br>
> + defaultButtonColor<br>
> + <br>
> +     ^ (UserInterfaceTheme current get: #color for: #PluggableButtonMorph) ifNil: [Color gray: 0.91]!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>delete (in category 'actions') -----<br>
> - delete<br>
> - <br>
> -     | font |<br>
> -     (font := self selectedFont) textStyleOrNil ifNotNil: [:style |<br>
> -         TextConstants removeKey: font familyName].<br>
> -     TTCFont registerAll.<br>
> -     TTFontDescription removeDescriptionNamed: font familyName.<br>
> -     self allFonts: nil. "force redraw"!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>discardCustomPreviewTexts (in category 'preview text - custom') -----<br>
> + discardCustomPreviewTexts<br>
> + <br>
> +     CustomPreviewTexts := nil.<br>
> +     self setCustomPreviewText: nil.!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>editButtonHelp (in category 'edit mode - ui') -----<br>
> + editButtonHelp<br>
> + <br>
> +     ^ 'Modify font properties such as <b>extra glyph scale</b> and <b>extra line gap</b>, which will be shared through all point sizes and text styles. Be careful.' translated asTextFromHtml!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>editCustomPreviewText: (in category 'preview text - custom') -----<br>
> + editCustomPreviewText: aStringOrTextOrNil<br>
> +     "The user typed something. Use it directly as a new preview text. Note that CMD+S (or Return) means that the user wants to save the text for later."<br>
> +     <br>
> +     customPreviewText := aStringOrTextOrNil ifNotNil: [:value | value asString].<br>
> +     self changed: #previewText.<br>
> +     self changed: #previewTextButtonLabel.!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>editModeEnabled (in category 'edit mode') -----<br>
> + editModeEnabled<br>
> + <br>
> +     ^ Project current isMorphic<br>
> +         ifFalse: [false]<br>
> +         ifTrue: [(editModeWidgets at: #on) first visible]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>editModeEnabled: (in category 'edit mode') -----<br>
> + editModeEnabled: showEditWidgets<br>
> + <br>
> +     Project current isMorphic ifFalse: [^ self].<br>
> + <br>
> +     showEditWidgets<br>
> +         ifFalse: [<br>
> +             (editModeWidgets at: #on) do: [:ea | ea hide; disableLayout: true].<br>
> +             (editModeWidgets at: #off) do: [:ea | ea show; disableLayout: false]]<br>
> +         ifTrue: [<br>
> +             (editModeWidgets at: #on) do: [:ea | ea show; disableLayout: false].<br>
> +             (editModeWidgets at: #off) do: [:ea | ea hide; disableLayout: true]].!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>exploreFont (in category 'actions') -----<br>
> + exploreFont<br>
> + <br>
> +     self selectedFont explore.!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>exploreImported (in category 'actions') -----<br>
> - exploreImported<br>
> - <br>
> -     | filenames fonts ttcFonts |<br>
> -     fonts := self currentSelection.<br>
> -     filenames := fonts allFilenames.<br>
> -     <br>
> -     ttcFonts := (filenames gather: [:ea | TTFontReader parseFileNamed: ea])<br>
> -         collect: [:descr | TTCFont new ttcDescription: descr; pointSize: TextStyle defaultFont pointSize; yourself].<br>
> -     <br>
> -     ttcFonts do: [:ea | ea explore].!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>exploreLinked (in category 'actions') -----<br>
> - exploreLinked<br>
> - <br>
> -     | filenames fonts ttcFonts |<br>
> -     fonts := self currentSelection.<br>
> -     filenames := fonts allFilenames.<br>
> -     <br>
> -     ttcFonts := filenames gather: [:ea | <br>
> -         (TTFileDescription readFontsFrom: ea)<br>
> -             collect: [:descr | TTCFont new ttcDescription: descr; pointSize: TextStyle defaultFont pointSize; yourself]].<br>
> -     <br>
> -     ttcFonts do: [:ea | ea explore].!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>filename (in category 'accessing') -----<br>
> - ----- Method: FontImporterTool>>filename (in category 'model access') -----<br>
>   filename<br>
>   <br>
>       ^ self currentSelection<br>
>           ifNil: ['']<br>
>           ifNotNil: [:sel |<br>
>               String streamContents: [:stream |<br>
> +                 (sel allFilenames ifEmpty: [{'(unknown file location; image only)' translated}])<br>
> -                 sel allFilenames<br>
>                       do: [:filename | stream nextPutAll: filename]<br>
>                       separatedBy: [stream cr ]]]!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>filenameFont (in category 'ui - layout') -----<br>
> - ----- Method: FontImporterTool>>filenameFont (in category 'toolbuilder') -----<br>
>   filenameFont<br>
> + <br>
> +     ^ Preferences standardBalloonHelpFont!<br>
> -     ^ Preferences standardDefaultTextFont!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>filenameHeight (in category 'ui - layout') -----<br>
> - ----- Method: FontImporterTool>>filenameHeight (in category 'layout') -----<br>
>   filenameHeight<br>
>   <br>
> +     ^ ToolBuilder default helpFieldHeightFor: 2 "lines"!<br>
> -     ^ ToolBuilder default inputFieldHeightFor: 3 "lines"!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>font:hasGlyphOf: (in category 'helper') -----<br>
> - font: f hasGlyphOf: aCharacter<br>
> - <br>
> -     | font |<br>
> -     font := f isFontSet ifTrue: [f fontArray first] ifFalse: [f].<br>
> -     ^ font hasGlyphOf: aCharacter!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>fontConfigurationSpecs (in category 'ui - building') -----<br>
> + fontConfigurationSpecs<br>
> + <br>
> +     ^ #(<br>
> +     text pointSizeInput pointSizeInputHelp nil preview<br>
> +     text lineSpacingInput lineSpacingInputHelp nil preview<br>
> +     spacer nil nil nil preview<br>
> +     button adjustXHeight 'Adjust the font''s x-height to match the system''s default font.' 'Adjust x' edit<br>
> +     text ttExtraScaleInput ttExtraScaleInputHelp nil edit<br>
> +     text ttExtraGapInput ttExtraGapInputHelp nil edit<br>
> +     button resetFontMetrics 'Reset all fields to their default value. Disable the edit mode.' 'Reset' edit<br>
> +     button toggleEditMode editButtonHelp 'Edit' toggle<br>
> +     )!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>fontFromFamily: (in category 'helper') -----<br>
> - fontFromFamily: aFamily<br>
> - <br>
> -     | readFonts | <br>
> -     aFamily ifNil: [^ TextStyle defaultFont].<br>
> -     readFonts := TTFileDescription readFontsFrom: aFamily allFilenames anyOne.<br>
> -     ^ (readFonts size > 1<br>
> -         ifTrue: [ <br>
> -             | ftArray |<br>
> -             " see TTCFontSet>>newTextStyleFromTT: "<br>
> -             ftArray := readFonts collect: [:ttc | |f|<br>
> -                 ttc ifNil: [nil] ifNotNil: [<br>
> -                     f := TTCFont new.<br>
> -                     f ttcDescription: ttc.<br>
> -                     f pointSize: TextStyle defaultFont pointSize.<br>
> -                     f]].<br>
> -             TTCFontSet newFontArray: ftArray]<br>
> -         ifFalse: [ |f|<br>
> -             f := TTCFont new.<br>
> -             f ttcDescription: readFonts anyOne.<br>
> -             f pointSize: TextStyle defaultFont pointSize.    <br>
> -             f])!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>fontListFrame (in category 'ui - layout') -----<br>
> - ----- Method: FontImporterTool>>fontListFrame (in category 'layout') -----<br>
>   fontListFrame<br>
>   <br>
>       ^ LayoutFrame<br>
> +         fractions: (0 at 0 corner: 0.25 at 1)<br>
> -         fractions: (0 at 0 corner: 0.4 at 1)<br>
>           offsets: (0 at 0 corner: 0@ self buttonHeight negated)!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>fontListMenu: (in category 'font list/tree') -----<br>
> - ----- Method: FontImporterTool>>fontListMenu: (in category 'font list') -----<br>
>   fontListMenu: aMenu<br>
>   <br>
>       ^ aMenu addTranslatedList: #(<br>
> +         ('Browse'    browseFont 'Browse all glyphs in the font')<br>
> +         ('Explore'    exploreFont 'Explore the font object')<br>
> -         ('Browse Font (imported)'    browseImported 'Import and browse all available glyphs')<br>
> -         ('Browse Font (linked)'    browseLinked 'Browse all available glyphs')<br>
>           -<br>
> +         ('Install'    installFont    'Make the font available in the environment but keep the glyph data outside the image')<br>
> +         ('Install & Load' installAndLoadFont 'Make the font available in the environment including all the glyph data to ensure portability of the image')<br>
> -         ('Explore Font (imported)'    exploreImported 'Import and explore the font object')<br>
> -         ('Explore Font (linked)'    exploreLinked 'Explore the font object')        <br>
> -         -<br>
> -         ('Install Font (imported)'    import    'Include the font data in the image and provide a TextStyle for the font')<br>
> -         ('Install Font (linked)'        link  'Install the font as a link to its file and provide a TextStyle for the referenced font')<br>
>           ), (self selectedFont textStyleOrNil ifNil: [#()] ifNotNil: [#(<br>
>               -<br>
> +             ('Uninstall'    uninstallFont    'Remove the font from the system')<br>
> -             ('Delete Font'    delete    'Remove imported font data or link to font from the system')<br>
>               )])<br>
>       yourself!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>fontPanelFrame (in category 'ui - layout') -----<br>
> + fontPanelFrame<br>
> + <br>
> +     ^ LayoutFrame<br>
> +         fractions: (0.25 at 0 corner: 1 at 1)<br>
> +         offsets: (0 at 0 corner: 0@ self buttonHeight negated)!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>fontSymbolsToUse (in category 'accessing') -----<br>
> + fontSymbolsToUse<br>
> + <br>
> +     ^ UserInterfaceTheme knownFontSymbols reject: [:ea | ea beginsWith: #wizard]!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>import (in category 'actions') -----<br>
> - import<br>
> -     | megaSize filenames fonts |<br>
> -     fonts := self currentSelection.<br>
> -     filenames := fonts allFilenames.<br>
> -     megaSize := ((filenames inject: 0 into: [ :sum :fn |<br>
> -         sum + (FileStream readOnlyFileNamed: fn do: [:file | file size])]) / (1024 * 1024)) asFloat.<br>
> -     (UIManager default confirm: (<br>
> - 'About to import {1}{2}.\\This is at least {3} MB of space required in the image.\<br>
> - Please respect the copyright and embedding restrictions of the font.\<br>
> - Proceed?' <br>
> -         translated withCRs format: {<br>
> -             self currentParent <br>
> -                 ifNotNil: [:p| p fontname, ' ', self currentSelection fontname]<br>
> -                 ifNil: [self currentSelection fontname].<br>
> -             filenames size > 1 ifTrue: [' ({1} font files)' translated format: {filenames size}] ifFalse: [''].<br>
> -             megaSize printShowingDecimalPlaces: 2}))<br>
> -         ifTrue: [ <br>
> -             filenames do: [:filename | | readFonts |<br>
> -                 readFonts := TTFontDescription addFromTTFile: filename.<br>
> -                 readFonts isCollection<br>
> -                     ifFalse: [TTCFont newTextStyleFromTT: readFonts]<br>
> -                     ifTrue: [self importFontFamily: readFonts]]].<br>
> -     self allFonts: nil. "force redraw"<br>
> -     TTCFont registerAll.!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>importFontFamily: (in category 'helper') -----<br>
> - importFontFamily: readFonts<br>
> - <br>
> -     |r rest array |<br>
> -     r := readFonts detect: [:f | <br>
> -         [f isRegular] on: Error do: [false] "hack for unknown emphases"<br>
> -     ] ifNone: [^ TTCFont newTextStyleFromTT: readFonts first].<br>
> -     rest := readFonts copyWithout: r.<br>
> -     array :=TTCFont pointSizes collect: [:pt | | f | <br>
> -         f := TTCFont new ttcDescription: r; pointSize: pt; yourself.<br>
> -         rest do: [:rf |<br>
> -             (self isStyleNameSupported: rf subfamilyName)<br>
> -                 ifTrue: [f derivativeFont: (TTCFont new ttcDescription: rf; pointSize: pt; yourself)]<br>
> -                 ifFalse: [<br>
> -                     Transcript show: 'Cannot import unknown style ', rf subfamilyName, ' from Font family ', f name]]. <br>
> -         f].<br>
> -     ^ TTCFont reorganizeForNewFontArray: array name: array first name asSymbol.!<br>
> <br>
> Item was changed:<br>
>   ----- Method: FontImporterTool>>initialExtent (in category 'initialize') -----<br>
>   initialExtent<br>
>   <br>
> +     ^ 670 at 500!<br>
> -     ^ 600 at 400.!<br>
> <br>
> Item was changed:<br>
>   ----- Method: FontImporterTool>>initialize (in category 'initialize') -----<br>
>   initialize<br>
>   <br>
>       super initialize.<br>
> + <br>
> +     previewTextSelector := #textSample.!<br>
> -     emphasis := 0.<br>
> - !<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>installAndLoadFont (in category 'actions') -----<br>
> + installAndLoadFont<br>
> + <br>
> +     self installFont ifTrue: [<br>
> +         self selectedFont becomeLocalFont.<br>
> +         self currentSelection parent ifNotNil: [:p | self currentSelection: p].<br>
> +         self changed: #objectChanged with: self currentSelection].<br>
> +     <br>
> +     self flag: #todo. "mt: Warn the user about space constraints!!"!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>installButtonColor (in category 'ui - installation') -----<br>
> + installButtonColor<br>
> + <br>
> +     self currentSelection ifNil: [^ self defaultButtonColor].<br>
> + <br>
> +     ^ self currentSelection isFullyInstalled<br>
> +         ifTrue: [self uninstallColor]<br>
> +         ifFalse: [self installColor]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>installButtonEnabled (in category 'ui - installation') -----<br>
> + installButtonEnabled<br>
> + <br>
> +     ^ self currentSelection<br>
> +         ifNil: [false]<br>
> +         ifNotNil: [:handle | handle isProtected not]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>installButtonHelp (in category 'ui - installation') -----<br>
> + installButtonHelp<br>
> + <br>
> +     self currentSelection ifNil: [^ ''].<br>
> + <br>
> +     ^ self currentSelection isInstalled<br>
> +         ifTrue: ['Remove all font data from the image. Note that existing texts or text styles may still refer to it for a while longer.' translated]<br>
> +         ifFalse: ['Include the font data in the image and provide a TextStyle for the font' translated].!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>installButtonHit (in category 'ui - installation') -----<br>
> + installButtonHit<br>
> + <br>
> +     self currentSelection ifNil: [^ self].<br>
> +     <br>
> +     self currentSelection isFullyInstalled<br>
> +         ifTrue: [self uninstallFont]<br>
> +         ifFalse: [self installFont].<br>
> +         <br>
> +     self changed: #installButtonLabel.<br>
> +     self changed: #installButtonColor.!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>installButtonLabel (in category 'ui - installation') -----<br>
> + installButtonLabel<br>
> + <br>
> +     self currentSelection ifNil: [^ 'Install' translated].<br>
> + <br>
> +     ^ self currentSelection isFullyInstalled<br>
> +         ifTrue: ['Uninstall' translated]<br>
> +         ifFalse: [<br>
> +             self currentSelection isInstalled<br>
> +                 ifTrue: ['Update' translated]<br>
> +                 ifFalse: ['Install' translated] ]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>installColor (in category 'ui - colors') -----<br>
> + installColor<br>
> + <br>
> +     ^ (UserInterfaceTheme current get: #okColor for: #ListChooser) ifNil: [Color r: 0.49 g: 0.749 b: 0.49]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>installFont (in category 'actions') -----<br>
> + installFont<br>
> +     "Install the selected font. Inform tha user that a modification is best reflected with a custom font name so that it is possible to also install the font with its original parameters."<br>
> +     <br>
> +     | handle wasRenamed |<br>
> +     handle := self currentSelection.<br>
> +     wasRenamed := false.<br>
> + <br>
> +     (handle isModified and: [handle hasModifiedName not]) ifTrue: [<br>
> +         (Project uiManager<br>
> +             request: 'You modified the selected font.\Please choose a new name:' translated withCRs<br>
> +             initialAnswer: 'My ', handle familyName)<br>
> +                 ifEmpty: [^ false]<br>
> +                 ifNotEmpty: [:answer |<br>
> +                     wasRenamed := true.<br>
> +                     handle fontname: answer]].<br>
> + <br>
> +     self currentSelection installFont.<br>
> +     self selectedFont: nil. "New identity from the handle"<br>
> +     <br>
> +     wasRenamed ifTrue: [<br>
> +         "New child in the tree. So refresh everything."<br>
> +         allFonts := nil. self changed: #allFonts. ^ true].<br>
> + <br>
> +     self currentSelection parent ifNotNil: [:p | self currentSelection: p].<br>
> +     self changed: #objectChanged with: self currentSelection.<br>
> +     <br>
> +     ^ true!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>isStyleNameSupported: (in category 'helper') -----<br>
> - isStyleNameSupported: subfamilyName<br>
> - <br>
> -     ^ (TextStyle decodeStyleName: subfamilyName) second isEmpty!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>labelOf: (in category 'font list/tree') -----<br>
> + labelOf: aHandle<br>
> - ----- Method: FontImporterTool>>labelOf: (in category 'model access') -----<br>
> - labelOf: aFontDescription<br>
>   <br>
> +     | label numSubfamilies|<br>
> +     self flag: #performance. "mt: Cache labels?"<br>
> +     <br>
> +     label := aHandle fontname.<br>
> +     <br>
> +     aHandle isLocalFont ifTrue: [label := '[', label, ']'].<br>
> +     (aHandle hasChildren and: [(numSubfamilies := aHandle children size) > 1])<br>
> +         ifTrue: [label := label, ' (', numSubfamilies, ')'].<br>
> +     aHandle isModified ifTrue: [label := label, ' *'].<br>
> +     label := label asText.<br>
> +     aHandle isFullyInstalled<br>
> +         ifTrue: [label addAttribute: TextEmphasis underlined]<br>
> +         ifFalse: [aHandle isInstalled ifTrue: [<br>
> +             label := '!! ' asText, label ]].<br>
> +     aHandle isSubfamilySupported<br>
> +         ifFalse: [label addAttribute: TextColor gray].<br>
> +     ^ label!<br>
> -     ^ aFontDescription fontname<br>
> - <br>
> -     !<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>lineSpacing (in category 'preview text - ui') -----<br>
> + lineSpacing<br>
> + <br>
> +     ^ lineSpacing ifNil: [0.0]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>lineSpacingInput (in category 'preview text - ui') -----<br>
> + lineSpacingInput<br>
> +     "Redirect through #selectedFontTextStyle to get automatic suggestions e.g., for symbol fonts."<br>
> +     <br>
> +     ^ (lineSpacing ifNil: [self selectedFontTextStyle lineSpacing]) asString!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>lineSpacingInput: (in category 'preview text - ui') -----<br>
> + lineSpacingInput: anObject<br>
> + <br>
> +     self currentSelection ifNil: [^ false].<br>
> +     <br>
> +     lineSpacing := [anObject asNumber] on: NumberParserError do: [nil].<br>
> +     self changed: #lineSpacingInput.<br>
> +     self changed: #selectedFontTextStyle.<br>
> +     <br>
> +     ^ true!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>lineSpacingInputHelp (in category 'preview text - ui') -----<br>
> + lineSpacingInputHelp<br>
> + <br>
> +     self editModeEnabled ifFalse: [<br>
> +         ^ 'Line spacing in the preview box' translated].<br>
> + <br>
> +     ^ '<b>Line spacing</b> in the preview box. A factor of 0.0 means no extra spacing while 1.0 means to double the current line height, which is based on the fonts within each line. The value may be negative.<br><br>Note that line spacing is application-specific and can thus be different for any <b>text style</b> (or text field). You can tweak the font itself through <b>extra line gap</b> to affect all its uses.<br><br>Make empty to reset to default value.' translated asTextFromHtml!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>link (in category 'actions') -----<br>
> - link<br>
> -     | filenames fonts |<br>
> -     fonts := self currentSelection.<br>
> -     self warningSeen ifFalse: [<br>
> -         (Project uiManager confirm: (<br>
> - 'Note that linking a font instead of importing may make the<br>
> - image un-portable, since the linked font must be present on<br>
> - the system the next time the image is run.<br>
> - <br>
> - This warning is only shown once per session.' translated) trueChoice: 'Proceed' translated falseChoice: 'Cancel' translated)<br>
> -         ifFalse: [^ self].<br>
> -         self warningSeen: true]..<br>
> -     filenames := fonts allFilenames.<br>
> -     filenames do: [:filename | | readFonts |<br>
> -         readFonts := TTFileDescription readFontsFrom: filename.<br>
> -         readFonts isCollection<br>
> -                     ifFalse: [TTCFont newTextStyleFromTT: readFonts]<br>
> -                     ifTrue: [self importFontFamily: readFonts]].<br>
> -     self allFonts: nil. "force redraw"<br>
> -     TTCFont registerAll.!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>offerPreviewTextMenu (in category 'preview text') -----<br>
> + offerPreviewTextMenu<br>
> + <br>
> +     | builder menuSpec |<br>
> +     builder := ToolBuilder default.<br>
> +     menuSpec := builder pluggableMenuSpec new.<br>
> +     <br>
> +     #(textSample codeSample widgetSample nil forssmanSample melvilleSample fontSample) do: [:selector |<br>
> +         selector ifNil: [menuSpec addLine] ifNotNil: [<br>
> +             | item marker |<br>
> +             marker := (customPreviewText isEmptyOrNil and: [previewTextSelector = selector])<br>
> +                 ifTrue: ['<yes>'] ifFalse: ['<no>'].<br>
> +             item := menuSpec<br>
> +                 add: marker, (self previewTextSelectorLabelFor: selector)<br>
> +                 target: self<br>
> +                 selector: #setPreviewTextSelector:<br>
> +                 argumentList: {selector}.<br>
> +             item help: (self previewTextSelectorHelpFor: selector)]].<br>
> +     menuSpec addLine.<br>
> +     <br>
> +     (CustomPreviewTexts ifNil: [CustomPreviewTexts := OrderedCollection new])<br>
> +         do: [:text | | marker |<br>
> +             marker := customPreviewText = text ifTrue: ['<yes>'] ifFalse: ['<no>'].<br>
> +             menuSpec<br>
> +                 add: marker, (text contractTo: 40)<br>
> +                 target: self<br>
> +                 selector: #setCustomPreviewText:<br>
> +                 argumentList: {text}].<br>
> +     CustomPreviewTexts ifNotEmpty: [menuSpec addLine].<br>
> +     <br>
> +     menuSpec<br>
> +         add: 'Discard custom texts' translated<br>
> +         target: self<br>
> +         selector: #discardCustomPreviewTexts<br>
> +         argumentList: #().<br>
> + <br>
> +     builder runModal: (builder open: menuSpec).!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>okToClose (in category 'ui - building') -----<br>
> + okToClose<br>
> +     "Check for modifications to not installed fonts. Ask the user if those modifications should be discarded. Not that modifications to installed fonts were already applied."<br>
> +     <br>
> +     | modifiedFonts |<br>
> +     modifiedFonts := self allFonts "top level" select: [:ea | ea isModified and: [ea isInstalled not]].<br>
> +     ^ (super okToClose and: [modifiedFonts isEmpty])<br>
> +         ifTrue: [true]<br>
> +         ifFalse: [Project uiManager<br>
> +             confirm: ('You modified the following fonts:\\' translated,<br>
> +                 (modifiedFonts inject: '' into: [:list :each | list, '    ', each fontname, '\']),<br>
> +                 '\These fonts are not yet installed. Do\you want to discard your changes?' translated) withCRs<br>
> +             title: 'Discard Changes' translated]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>pointSize (in category 'preview text - ui') -----<br>
> + pointSize<br>
> + <br>
> +     ^ pointSize ifNil: [TextStyle defaultFont pointSize]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>pointSizeInput (in category 'preview text - ui') -----<br>
> + pointSizeInput<br>
> + <br>
> +     ^ self pointSize asString!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>pointSizeInput: (in category 'preview text - ui') -----<br>
> + pointSizeInput: anObject<br>
> + <br>
> +     self currentSelection ifNil: [^ false].<br>
> + <br>
> +     pointSize := [anObject asNumber roundTo: 0.5] on: NumberParserError do: [TextStyle defaultFont pointSize].<br>
> +     pointSize := pointSize max: 1.0.<br>
> +     self changed: #pointSizeInput.<br>
> +     self selectedFont: nil.<br>
> +     <br>
> +     ^ true!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>pointSizeInputHelp (in category 'preview text - ui') -----<br>
> + pointSizeInputHelp<br>
> + <br>
> +     self editModeEnabled ifFalse: [<br>
> +         ^ 'Point size in the preview box' translated].<br>
> + <br>
> +     ^ ('<b>Point size</b> in the preview box. The system''s default is currently <b>{1}</b> points. It is recommended to adjust the font''s <b>extra glyph scale</b> and <b>extra line gap</b> using the default point size. Look at other text in the system to assess whether this font would integrate nicely.<br><br>Make empty to reset to default value.' translated<br>
> +         format: {TextStyle defaultFont pointSize}) asTextFromHtml!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>prepareEditMode: (in category 'edit mode') -----<br>
> + prepareEditMode: container<br>
> + <br>
> +     Project current isMorphic ifFalse: [^ self].<br>
> +     <br>
> +     editModeWidgets := Dictionary new<br>
> +         at: #on put: OrderedCollection new;<br>
> +         at: #off put: OrderedCollection new;<br>
> +         yourself.<br>
> +         <br>
> +     container allMorphsDo: [:m |<br>
> +         ((m knownName ifNil: ['']) beginsWith: 'edit')<br>
> +             ifTrue: [(editModeWidgets at: #on) add: m]<br>
> +             ifFalse: [((m knownName ifNil: ['']) beginsWith: 'toggle')<br>
> +                 ifTrue: [(editModeWidgets at: #off) add: m]]].<br>
> +         <br>
> +     self toggleEditMode. "Turn it off"!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>previewFrame (in category 'layout') -----<br>
> - previewFrame<br>
> - <br>
> -     ^ LayoutFrame<br>
> -         fractions: (0.4 at 0 corner: 1 at 1)<br>
> -         offsets: (0 at 0 corner: 0@ self buttonHeight negated)!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>previewText (in category 'preview text') -----<br>
> - ----- Method: FontImporterTool>>previewText (in category 'model access') -----<br>
>   previewText<br>
> +     "Answer the current preview text. Avoid using a text with font-reference attributes so that any not-yet-installed font does not get spreaded across the system. See #selectedFontTextStyle to learn how the preview is rendered using the selected font."<br>
>   <br>
> +     self selectedFont ifNil: [^ ''].<br>
> +     self customPreviewText ifNotEmpty: [:text | ^ text withCRs].<br>
> +     <br>
> +     previewTextSelector = #fontSample ifTrue: [<br>
> +         ^ self selectedFont ttcDescription sampleText<br>
> +             ifEmpty: ['This font does not provide a sample text.' translated]].<br>
> + <br>
> +     (previewTextSelector ~= #textSample and: [self selectedFont isSymbolFont])<br>
> +         ifTrue: [^ 'This symbol font does not support the preview text.\Please use ''Text/Symbol'' or type a custom text.' translated withCRs asText addAttribute: (TextFontReference toFont: TextStyle defaultFont); yourself].<br>
> + <br>
> +     self selectedFont isSymbolFont<br>
> +         ifTrue: [^ self selectedFont symbolSample asString].<br>
> +     (Text respondsTo: previewTextSelector)<br>
> +         ifTrue: [^ (Text perform: previewTextSelector) asString].<br>
> +     previewTextSelector = #widgetSample<br>
> +         ifTrue: [^ self widgetSample].<br>
> +         <br>
> +     ^ ''!<br>
> -     ^ self selectedFont<br>
> -         ifNil: [Text new]<br>
> -         ifNotNil: [:font | font sampleText]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>previewTextButtonHelp (in category 'preview text') -----<br>
> + previewTextButtonHelp<br>
> + <br>
> +     ^ self customPreviewText<br>
> +         ifNotEmpty: [^ 'Custom ->' "The arrow points to the input field in the UI."]<br>
> +         ifEmpty: [self previewTextSelectorHelpFor: previewTextSelector]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>previewTextButtonLabel (in category 'preview text') -----<br>
> + previewTextButtonLabel<br>
> + <br>
> +     ^ self customPreviewText<br>
> +         ifNotEmpty: ['Custom ->']<br>
> +         ifEmpty: [self previewTextSelectorLabelFor: previewTextSelector]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>previewTextMenu:shifted: (in category 'preview text') -----<br>
> + previewTextMenu: aMenu shifted: shifted<br>
> +     <previewTextMenu><br>
> +     "See commentary in StringHolder >> #mainCodePaneMenu:shifted:."<br>
> +     <br>
> +     ^ StringHolder codePaneMenu: aMenu shifted: shifted!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>previewTextPadding (in category 'preview text') -----<br>
> + previewTextPadding<br>
> +     "Static. Give a little bit more space so that the user can focus on the font, not the window ui. For UI themes that use bitmap fonts (i.e., the default 75%, 100%, 125%, and 150% scale factor) use the current font metrics. Otherwise, just use a font-agnostic measure in points. Maybe we can make text-field margins more dynamic (and per-font) in the future."<br>
> +     <br>
> +     ^ UserInterfaceTheme current isTTCBased<br>
> +         ifTrue: [(TextStyle pointsToPixels: 16 "pt" @20 "pt") truncated]<br>
> +         ifFalse: [(TextStyle defaultFont widthOf: $m) @ TextStyle defaultFont lineGrid]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>previewTextSelectorHelpFor: (in category 'preview text') -----<br>
> + previewTextSelectorHelpFor: symbol<br>
> + <br>
> +     ^ symbol caseOf: {<br>
> +         [#textSample] -> ['See the font''s alphabet as a dummy text. For symbol fonts, show a selection of symbols.' translated].<br>
> +         [#codeSample] -> ['See how the font would render some Smalltalk source code.' translated].<br>
> +         [#forssmanSample] -> ['See an example of ragged text used in the book "Detailtypografie" by Friedrich Forssman and Ralf de Jong.' translated].<br>
> +         [#melvilleSample] -> ['See the first two paragraphs of "Moby Dick" by Herman Melville.' translated].<br>
> +         [#fontSample] -> ['See the example text that was provided by the font designer in the font description itself.' translated asTextFromHtml].<br>
> +         [#widgetSample] -> ['See how the font would look in a list, tree, or menu widget.' translated].<br>
> +     } otherwise: [ '' ]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>previewTextSelectorLabelFor: (in category 'preview text') -----<br>
> + previewTextSelectorLabelFor: symbol<br>
> + <br>
> +     ^ symbol caseOf: {<br>
> +         [#textSample] -> ['Text/Symbols'].<br>
> +         [#codeSample] -> ['Source code'].<br>
> +         [#widgetSample] -> ['Widgets'].    <br>
> +         [#forssmanSample] -> ['Forssman'].<br>
> +         [#melvilleSample] -> ['Melville'].<br>
> +         [#fontSample] -> ['Font sample'].<br>
> +     } otherwise: [ '???' ]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>resetFontMetrics (in category 'edit mode - actions') -----<br>
> + resetFontMetrics<br>
> + <br>
> +     self selectedFont familyName = TextStyle defaultTTFont familyName<br>
> +         ifTrue: [^ self inform: 'You should not reset the font that is used as\reference for x-height adjustment. Please\change manually if at all.' translated withCRs].<br>
> + <br>
> +     self toggleEditMode.<br>
> + <br>
> +     pointSize := nil.<br>
> +     lineSpacing := nil.<br>
> +     <br>
> +     self currentSelection ifNotNil: [:fontDescr |<br>
> +         fontDescr ttExtraScale: nil.<br>
> +         fontDescr ttExtraGap: nil].<br>
> +     <br>
> +     self changed: #objectChanged with: self currentSelection.<br>
> +     self selectedFont: nil. !<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>selectedFont (in category 'accessing') -----<br>
> - ----- Method: FontImporterTool>>selectedFont (in category 'font list') -----<br>
>   selectedFont<br>
> +     <br>
> +     ^ selectedFont ifNil: [selectedFont := self currentSelection<br>
> +         ifNil: [TextStyle defaultFont]<br>
> +         ifNotNil: [:o | o fontOfPointSize: self pointSize] ]!<br>
> -     | fontDesc font |<br>
> -     fontDesc := self currentSelection.<br>
> -     font := self fontFromFamily: fontDesc.<br>
> -     font isFontSet ifTrue: [<br>
> -         font := (self currentParent isNil or: [self currentParent = self currentSelection])<br>
> -             ifTrue: [font fontArray anyOne]<br>
> -             ifFalse: [ "we have selected a leaf  "<br>
> -                 font fontArray<br>
> -                     detect: [:subfont | subfont subfamilyName = fontDesc fontname]<br>
> -                     ifNone: [font]]].<br>
> -     ^font emphasized: emphasis!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>selectedFont: (in category 'accessing') -----<br>
> + selectedFont: aTTCFont<br>
> + <br>
> +     selectedFont := aTTCFont.<br>
> +     <br>
> +     self changed: #previewText.<br>
> +     self changed: #selectedFontTextStyle.<br>
> +     <br>
> +     self changed: #filename.<br>
> +     self changed: #copyright.<br>
> +     <br>
> +     self changed: #pointSizeInput.<br>
> +     self changed: #lineSpacingInput.    <br>
> +     self changed: #ttExtraScaleInput.<br>
> +     self changed: #ttExtraGapInput.<br>
> +     <br>
> +     self changed: #installButtonColor.<br>
> +     self changed: #installButtonLabel.<br>
> +     self changed: #installButtonEnabled.<br>
> +     <br>
> +     self changed: #windowTitle.!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>selectedFontTextStyle (in category 'accessing') -----<br>
> - ----- Method: FontImporterTool>>selectedFontTextStyle (in category 'font list') -----<br>
>   selectedFontTextStyle<br>
> +     "Construct a new text style from the #selectedFont."<br>
> +     <br>
> +     ^ (TextStyle fontArray: {self selectedFont})<br>
> +         lineSpacing: ((lineSpacing isNil and: [self selectedFont isSymbolFont])<br>
> +             ifTrue: [ 0.3 ]<br>
> +             ifFalse: [ self lineSpacing ]);<br>
> +         yourself<br>
> +         <br>
> +         !<br>
> - <br>
> -     | font |<br>
> -     ^ (font := self selectedFont) isSymbolFont<br>
> -         ifFalse: [TextStyle fontArray: {font}]<br>
> -         ifTrue: [TextStyle default copy]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>setCustomPreviewText: (in category 'preview text - custom') -----<br>
> + setCustomPreviewText: aString<br>
> + <br>
> +     self editCustomPreviewText: aString.<br>
> +     self changed: #customPreviewText.!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>setPreviewTextSelector: (in category 'preview text') -----<br>
> + setPreviewTextSelector: symbol<br>
> + <br>
> +     previewTextSelector := symbol.<br>
> +     self setCustomPreviewText: nil.!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>textForFamily:subfamily: (in category 'helper') -----<br>
> - textForFamily: familyName subfamily: subfamilyName<br>
> - <br>
> -     subfamilyName ifNil: [<br>
> -         ^ (TextStyle named: (familyName copyWithout: Character space))<br>
> -             ifNil: [familyName]<br>
> -             ifNotNil: [:style | style isTTCStyle<br>
> -                 ifTrue: ["we are already present "<br>
> -                     Text string: familyName attribute: TextEmphasis underlined]<br>
> -                 ifFalse: [familyName]]].<br>
> -         <br>
> -     " frome here on it is only about subfamilies"<br>
> -     <br>
> -     (self isStyleNameSupported: subfamilyName)<br>
> -         ifFalse: [^ Text string: subfamilyName attribute: TextColor gray].<br>
> - <br>
> -     ^ (TextStyle named: familyName)<br>
> -         ifNil: ["importable" subfamilyName]<br>
> -         ifNotNil: [:style |<br>
> -             (style isTTCStyle and: [ | regular emph |<br>
> -                     regular  := style fonts anyOne.<br>
> -                     emph := TTCFont indexOfSubfamilyName: subfamilyName.<br>
> -                     " detect if this style is already imported "<br>
> -                     regular emphasis = emph or: [(regular emphasis: emph) ~= regular]])<br>
> -                 ifFalse: ["again importable" subfamilyName]<br>
> -                 ifTrue: [Text string: subfamilyName attribute: TextEmphasis underlined]]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>toggleEditMode (in category 'edit mode') -----<br>
> + toggleEditMode<br>
> + <br>
> +     self editModeEnabled: self editModeEnabled not.!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>ttExtraGapInput (in category 'edit mode - ui') -----<br>
> + ttExtraGapInput<br>
> + <br>
> +     ^ (self currentSelection<br>
> +         ifNil: [0]<br>
> +         ifNotNil: [:handle | handle ttExtraGap]) asString!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>ttExtraGapInput: (in category 'edit mode - ui') -----<br>
> + ttExtraGapInput: anObject<br>
> + <br>
> +     self currentSelection ifNil: [^ false].<br>
> + <br>
> +     self currentSelection ttExtraGap: ([anObject asNumber truncated] on: NumberParserError do: [nil]).<br>
> +     self changed: #ttExtraGapInput.<br>
> +     self changed: #objectChanged with: self currentSelection.<br>
> +     <br>
> +     self selectedFont: nil.<br>
> +     <br>
> +     ^ true!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>ttExtraGapInputHelp (in category 'edit mode - ui') -----<br>
> + ttExtraGapInputHelp<br>
> + <br>
> +     | tt |<br>
> +     tt := self selectedFont ifNotNil: [:f | f isTTCFont ifTrue: [ f ttcDescription ] ].<br>
> +     ^ ('<b>Extra line gap</b> in font measures. This font''s own value is <b>{1}</b> with units-per-em (UPM) being <b>{2}</b>. Adjust to change the font''s line grid (or "height") to compensate for <b>extra glyph scale</b>. The value may be negative.<br><br>Note that there is also <b>line spacing</b>, which is not per font but per <b>text style</b> and thus application-specific.<br><br>Make empty to reset to default value.' translated<br>
> +         format: { <br>
> +             tt ifNil: ['?'] ifNotNil: [tt typographicLineGap].<br>
> +             tt ifNil: ['?'] ifNotNil: [tt unitsPerEm].<br>
> +          }) asTextFromHtml!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>ttExtraScaleInput (in category 'edit mode - ui') -----<br>
> + ttExtraScaleInput<br>
> + <br>
> +     ^ (self currentSelection<br>
> +         ifNil: [1.0]<br>
> +         ifNotNil: [:handle | handle ttExtraScale]) printShowingDecimalPlaces: 3!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>ttExtraScaleInput: (in category 'edit mode - ui') -----<br>
> + ttExtraScaleInput: anObject<br>
> + <br>
> +     self currentSelection ifNil: [^ false].<br>
> +     <br>
> +     self currentSelection ttExtraScale: ([anObject asNumber] on: NumberParserError do: [nil]).<br>
> +     self changed: #ttExtraScaleInput.<br>
> +     self changed: #objectChanged with: self currentSelection.<br>
> +     <br>
> +     self selectedFont: nil.<br>
> +     <br>
> +     ^ true!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>ttExtraScaleInputHelp (in category 'edit mode - ui') -----<br>
> + ttExtraScaleInputHelp<br>
> + <br>
> +     (self selectedFont isNil or: [self selectedFont isTTCFont not])<br>
> +         ifTrue: [ ^ ''].<br>
> +         <br>
> +     ^ ('<b>Extra glyph scale</b> to accommodate varying heights when using different fonts side-by-side. This font has a relative x-height of <b>{1}</b> while the system''s reference is <b>{2}</b>. You can only use values greater than 0.0.<br><br>Note that this does not change the font''s "pixel height" and is thus unrelated to the system''s overall <b>UI scale factor</b>. You may want to adjust <b>extra line gap</b> as well to retain the font''s aesthetics.<br><br>Make empty to reset to default value.' translated<br>
> +         format: {<br>
> +             self selectedFont xHeightFraction printShowingDecimalPlaces: 3.<br>
> +             TextStyle defaultTTFont xHeightFraction printShowingDecimalPlaces: 3 }) asTextFromHtml!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>uninstallColor (in category 'ui - colors') -----<br>
> + uninstallColor<br>
> + <br>
> +     ^ (UserInterfaceTheme current get: #cancel for: #ListChooser) ifNil: [Color r: 1 g: 0.6 b: 0.588]!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>uninstallFont (in category 'actions') -----<br>
> + uninstallFont<br>
> + <br>
> +     (Project uiManager<br>
> +         confirm: ('Do you want to uninstall the following font?\\    ' translated,<br>
> +             self currentSelection familyName,<br>
> +             '\\(There may be references left to this font\in text attributes and text styles.)' translated) withCRs<br>
> +         title: 'Uninstall Font' translated) ifFalse: [^ false].<br>
> + <br>
> +     self currentSelection uninstallFont.<br>
> +     <br>
> +     self currentSelection parent ifNotNil: [:p | self currentSelection: p].<br>
> +     self changed: #objectChanged with: self currentSelection.<br>
> +         <br>
> +     ^ true!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>warningSeen (in category 'accessing') -----<br>
> - warningSeen<br>
> - <br>
> -     ^ warningSeen ifNil: [false]!<br>
> <br>
> Item was removed:<br>
> - ----- Method: FontImporterTool>>warningSeen: (in category 'accessing') -----<br>
> - warningSeen: anObject<br>
> - <br>
> -     warningSeen := anObject!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>widgetSample (in category 'preview text') -----<br>
> + widgetSample<br>
> + <br>
> +     ^ self widgetSampleFor: self selectedFont!<br>
> <br>
> Item was added:<br>
> + ----- Method: FontImporterTool>>widgetSampleFor: (in category 'preview text') -----<br>
> + widgetSampleFor: font<br>
> + <br>
> +     | widgets data preferredWidth |<br>
> +     data := ChronologyConstants classPool at: #MonthNames.<br>
> +     widgets := OrderedCollection new.<br>
> +     preferredWidth := ((font widthOfString: (data detectMax: [:ea | ea size])) * 1.3) truncated.<br>
> +     <br>
> +     "1) List morph"<br>
> +     widgets add: ((PluggableListMorph on: data list: #value selected: nil changeSelected: nil) vResizing: #shrinkWrap; width: preferredWidth; font: font; yourself).<br>
> +             <br>
> +     "2) Menu morph"<br>
> +     widgets add: (MenuMorph new in: [:menu | data do: [:o | menu add: o action: #yourself. menu lastItem font: font]. menu]).<br>
> +     <br>
> +     "3) Buttons"<br>
> +     widgets add: (Morph new color: Color transparent; changeTableLayout; listDirection: #topToBottom; vResizing: #shrinkWrap; cellGap: (font widthOf: Character space); width: preferredWidth; addAllMorphs: (data collect: [:ea | (PluggableButtonMorph on: ea getState: nil action: #yourself label: #yourself) hResizing: #spaceFill; font: font; fullBounds; in: [:button | MorphicProject useCompactButtons ifFalse: [button vResizing: #rigid; height: button height * 1.6; flag: #magicNumber]]; yourself ])).<br>
> + <br>
> +     ^ Text streamContents: [:sample |<br>
> +         widgets<br>
> +             do: [:widget |<br>
> +                 widget textAnchorProperties verticalAlignment: #top.<br>
> +                 sample nextPutAll: (<br>
> +                     Text<br>
> +                         string: Character startOfHeader asString<br>
> +                         attribute: widget asTextAnchor)]<br>
> +             separatedBy: [sample space: 5]]!<br>
> <br>
> Item was changed:<br>
> + ----- Method: FontImporterTool>>windowTitle (in category 'ui - building') -----<br>
> - ----- Method: FontImporterTool>>windowTitle (in category 'toolbuilder') -----<br>
>   windowTitle<br>
>   <br>
> +     ^ 'Font Importer', (self currentSelection<br>
> +         ifNil: ['']<br>
> +         ifNotNil: [:desc | ': ', desc familyName])!<br>
> -     ^'Choose a Font to import' translated!<br>
> <br>
> Item was changed:<br>
>   ----- Method: TTFontDescription>>asMorph (in category '*Morphic-TrueType') -----<br>
>   asMorph<br>
> +     <br>
> +     ^ self asHandle font<br>
> +         browseAllGlyphs;<br>
> +         browseAllGlyphsByCategory;<br>
> +         browseAllSymbols;<br>
> +         yourself.<br>
> +     <br>
> +     "^TTSampleFontMorph font: self"!<br>
> -     ^TTSampleFontMorph font: self!<br>
> <br>

</div></blockquote>
                                        </div></body>