Platforms to show: All Mac Windows Linux Cross-Platform

/MacCG/CoreText/CoreText Dynamic Text Height


Required plugins for this example: MBS MacBase Plugin, MBS MacCF Plugin, MBS MacCocoa Plugin, MBS MacCG Plugin, MBS Main Plugin

You find this example project in your Plugins Download as a Xojo project file within the examples folder: /MacCG/CoreText/CoreText Dynamic Text Height

This example is the version from Mon, 15th Nov 2015.

Project "CoreText Dynamic Text Height.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Löschen"
Const kFileQuit = "Beenden"
Const kFileQuitShortcut = ""
End Class
Class Window1 Inherits Window
Control Canvas1 Inherits Canvas
ControlInstance Canvas1 Inherits Canvas
EventHandler Sub Paint(g As Graphics, areas() As REALbasic.Rect) // create a font, quasi systemFontWithSize:24.0 dim sysUIFont as CTFontMBS = CTFontMBS.CreateUIFontForLanguage(CTFontMBS.kCTFontUIFontSystem, 18.0) // create a naked string dim text as string = "Edit Text and change Font size." // blue dim cgColor as CGColorMBS = CGColorMBS.CreateGenericRGB(0.0, 0.0, 1.0) // single underline dim underline as integer = CoreTextMBS.kCTUnderlineStyleSingle // pack it into attributes dictionary dim attributesDict as new Dictionary attributesDict.Value(CoreTextMBS.kCTFontAttributeName) = sysUIFont attributesDict.Value(CoreTextMBS.kCTForegroundColorAttributeName) = cgColor attributesDict.Value(CoreTextMBS.kCTUnderlineStyleAttributeName) = underline // make the attributed string dim cfDic as new CFDictionaryMBS(attributesDict) dim cfStr as new CFStringMBS(text) dim stringToDraw as CFAttributedStringMBS = CFAttributedStringMBS.Create( cfStr, cfDic) // now for the actual drawing dim CGContextHandle as integer = g.Handle(g.HandleTypeCGContextRef) dim CGContext as CGContextMBS = CGContextMBS.contextWithCGContext(CGContextHandle) CGContext.SaveGState // reset text matrix dim a as CGAffineTransformMBS = CGAffineTransformMBS.Identity CGContext.TextMatrix = a // draw dim line as CTLineMBS = CTLineMBS.CreateWithAttributedString(stringToDraw) dim x as integer = 10 dim y as integer = 10 // plus text height y = y + 24 // swap y y = g.Height - y CGContext.TextPosition = new CGPointMBS(x, y) line.Draw(CGContext) CGContext.RestoreGState CGContext.Flush // clean up End EventHandler
End Control
Control Timer1 Inherits Timer
ControlInstance Timer1 Inherits Timer
EventHandler Sub Action() Canvas1.Invalidate End EventHandler
End Control
Control Canvas2 Inherits Canvas
ControlInstance Canvas2 Inherits Canvas
EventHandler Sub Paint(g As Graphics, areas() As REALbasic.Rect) dim longText as string = TextArea1.Text dim s as new NSMutableAttributedStringMBS call s.initWithString(longText) Dim FontSize As Integer = Slider1.Value // setup font dim helvetica as CTFontMBS = CTFontMBS.CreateWithName("Helvetica", FontSize) dim r1 as new NSRangeMBS(0, s.Length) s.addattribute(CoreTextMBS.kCTFontAttributeName, helvetica, r1) // add some color dim greenColor as CGColorMBS = CGColorMBS.CreateGenericRGB(0.19, 0.56, 0.20) s.addattribute(CoreTextMBS.kCTForegroundColorAttributeName, greenColor, r1) // add color red to last three characters if s.Length > 2 then dim redColor as CGColorMBS = CGColorMBS.CreateGenericRGB(1, 0, 0) dim r2 as new NSRangeMBS(s.Length - 3, 3) s.addattribute(CoreTextMBS.kCTForegroundColorAttributeName, redColor, r2) end if // centre text dim p as NSParagraphStyleMBS = NSParagraphStyleMBS.defaultParagraphStyle dim p2 As NSMutableParagraphStyleMBS = p.mutableCopy p2.setAlignment NSParagraphStyleMBS.NSCenterTextAlignment s.addattribute(CoreTextMBS.kCTParagraphStyleAttributeName, p2, r1) // layout master dim cs as CFAttributedStringMBS = s.AsCFAttributedString dim framesetter as CTFramesetterMBS = CTFramesetterMBS.CreateWithAttributedString(cs) // calculate height required to display all text dim sizeOfWidth As CGSizeMBS = CGSizeMBS.Make(g.Width, 10000) // How do I set 'CGFloat_Max' instead of 10000? [Question] dim fitRangeLocation, fitRangeLength As Integer dim dEmpty As New Dictionary dim sizeOfFrame As CGSizeMBS = framesetter.SuggestFrameSizeWithConstraints(0, 0, dEmpty, sizeOfWidth, fitRangeLocation, fitRangeLength) // Resize height of window to fit all of text dim NewWinHeight As Integer = sizeOfFrame.Height + me.Top self.Height = NewWinHeight // create form dim ColumnPath as new CGMutablePathMBS dim Rect as new CGRectMBS(0, 0, g.Width, g.Height) ColumnPath.AddRect nil, Rect // create frame dim Frame as CTFrameMBS = framesetter.CreateFrame(0, 0, ColumnPath, nil) // get context dim CGContextHandle as integer = g.Handle(g.HandleTypeCGContextRef) dim CGContext as CGContextMBS = CGContextMBS.contextWithCGContext(CGContextHandle) CGContext.SaveGState // reset text matrix dim a as CGAffineTransformMBS = CGAffineTransformMBS.Identity CGContext.TextMatrix = a // draw frame Frame.Draw(CGContext) // cleanup CGContext.RestoreGState CGContext.Flush End EventHandler
End Control
Control TextArea1 Inherits TextArea
ControlInstance TextArea1 Inherits TextArea
EventHandler Sub TextChange() Canvas2.Invalidate End EventHandler
End Control
Control Slider1 Inherits Slider
ControlInstance Slider1 Inherits Slider
EventHandler Sub ValueChanged() Label2.Text = Str(me.value) Canvas2.Invalidate End EventHandler
End Control
Control Label1 Inherits Label
ControlInstance Label1 Inherits Label
End Control
Control Label2 Inherits Label
ControlInstance Label2 Inherits Label
End Control
Note "About"
Thanks to Mark Franken from Sounds In Sync for creating this example project. Shows how to correctly caluclate the text height.
End Class
MenuBar MenuBar1
MenuItem FileMenu = "&Ablage"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Bearbeiten"
MenuItem EditUndo = "&Rückgängig"
MenuItem UntitledMenu1 = "-"
MenuItem EditCut = "&Ausschneiden"
MenuItem EditCopy = "&Kopieren"
MenuItem EditPaste = "&Einfügen"
MenuItem EditClear = "#App.kEditClear"
MenuItem UntitledMenu0 = "-"
MenuItem EditSelectAll = "&Alles auswählen"
End MenuBar
End Project

See also:

The items on this page are in the following plugins: MBS MacCG Plugin.


The biggest plugin in space...