This seems to be a workable solution to loading and unloading StyledText in a form by using StyleRuns.
It uses UTF-8, which is the only way that seems to preserve all characters.
Using UTF-8 slowed creating a StyledText (3 minutes to display a large complex styled text area) until a change from
myStyledText = TextAreaFromRString(mySavedStyleRuns)
to
TextAreaFromRString(myStyledText, mySavedStyleRuns) makes the process very quick.
Also switched to using string rather than memoryblock, which feels more flexible and unexpectedly benchmarked almost twice as fast.
updated withmore efficient code:
=============================================
// Sample call to copy one TextArea to another
Var myCodedStyleRuns As String
myCodedStyleRuns=TextAreaToRString(TA1.StyledText)
TA2.Text=""
TextAreaFromRString(TA2.StyledText, myCodedStyleRuns)
=============================================
// TextAreaToRString - 2025.01
// Input: sta As StyledText, outString As String (pass "" To avoid appending)
// Build a string representing the StyleRuns of a StyledText
Var sr As StyleRun
Var i, Count As Integer
Var thisval As String = ""
Var delim As String = Chr(3)
Var repeatF As String = Chr(5)
Var lastTextColor As String = ""
Var lastFontName As String = ""
Count = sta.StyleRunCount ' Get the number of styles
Var runs() As String
runs.add("V1") ' leave space for a header or version
For i = 0 To Count - 1 ' send the StyleRuns to the array with some "compression" attempts
sr = sta.StyleRun(i)
runs.add(sr.Bold.ToString.Left(1)) // just store T or F
runs.add(sr.Italic.ToString.Left(1))
runs.add(sr.Underline.ToString.Left(1))
thisVal = sr.TextColor.ToString
If thisval = lastTextColor Then // store repeatF if the last used Color is the same
thisval=repeatF
Else
lastTextColor=thisval
End If
runs.add(thisval)
runs.add(sr.FontSize.ToString(Locale.Current, "####"))
thisVal = sr.FontName
If thisval = lastFontName Then // store repeatF if the last used Font is the same
thisval=repeatF
Else
lastFontName=thisval
End If
runs.add(thisval)
runs.add(sr.Text)
Next
Return String.FromArray(runs,delim) ' pack into a string
=============================================
// TextAreaFromRString - 2025.01
// Input: sta As StyledText, inString As string from the TextAreaToRString method
// Build a StyledText from a string of StyleRuns
Var sr As StyleRun
Var runs() As String
Var thisColorVal, thisFontNameVal As String = ""
Var delim As String = Chr(3)
Var repeatF As String = Chr(5)
Var lastTextColor As Color
Var lastFontName As String = ""
If inString <> "" Then
runs = inString.ToArray(delim)
If runs(0)="V1" Then
Var startF As Integer = 1
Var currentOffset As Integer = 0
sr = New StyleRun // moving this outside the loop speeds up x10
For i As Integer = 0 To runs.LastIndex-1 Step 7
currentOffset = startF + i
sr.Bold = (runs(currentOffset+0)="T")
sr.Italic = (runs(currentOffset+1)="T")
sr.Underline = (runs(currentOffset+2)="T")
thisColorVal= runs(currentOffset+3) // decide whether to use the last value
If thisColorVal <> repeatF Then
lastTextColor=Color.FromString(thisColorVal)
End If
sr.TextColor = lastTextColor
sr.FontSize = runs(currentOffset+4).ToInteger
thisFontNameVal= runs(currentOffset+5) // decide whether to use the last value
If thisFontNameVal <> repeatF Then
lastFontName=thisFontNameVal
End If
sr.FontName = lastFontName
sr.Text = runs(currentOffset+6).DefineEncoding(Encodings.UTF8)
sta.AddStyleRun(sr)
Next
End If
End If