In my app “RealCADD”, I add rich text feature via TextArea and StyledText.
All is good except the Font.Leading which is unknown for desktop app.
And I have some offsets between the text drawn and the text edited in a TextArea, example :
At the left, the text in a TextArea and at the right, the same text drawn.
You can see the 9) are not aligned.
How can I know the leading of the font for desktop app?
This feature is available for iOS.
graphics.TextHeight (the version for wrapped text) to find the height of the block and divide? It’s not perfect. If you have mixed fonts and font sizes, for example, you’ll have to calculate it for the one you are interested in.
It sounds like you want to control this, though, so I think you’ll need to draw each line separately rather than using a wrapped
DrawText(). This way you determine the leading by setting the baseline for drawing each line.
Thank you Matthew for your response but it is not what I want.
At the right of the picture above, it is what I draw with RealCADD.
And at the left, the same text in a TextArea.
There is a difference because I don’t know the leading used in the TextArea and, so, this value is missing in my drawing.
If this is macOS then you can probably do it by accessing the CoreText properties.
Here is a very basic example I created using the MBS plugins that should work when all text has the same style.
To use the example code:
• Add a TextArea named TextArea1 onto a window with some text that uses a single style. Make sure the text doesn’t soft wrap as the example code doesn’t handle it.
• Add a Canvas and put this example code into the Paint event.
Dim nsTextViewObj As NSTextViewMBS
Dim nsAttributedStringObj As NSAttributedStringMBS
Dim nsFontObj As NSFontMBS
Dim fontHeight As Double
Dim tempPicture As Picture
Dim stringHeight As Double
nsTextViewObj = TextArea1.NSTextViewMBS
nsAttributedStringObj = nsTextViewObj.layoutManager.attributedString
nsFontObj = nsAttributedStringObj.attributeAtIndex(NSAttributedStringMBS.NSFontAttributeName, 0)
fontHeight = nsFontObj.boundingRectForFont.Height
'determine the height of one line without spacing (for comparison)
tempPicture = New Picture(1, 1)
tempPicture.Graphics.TextFont = TextArea1.StyledText.Font(1, 1)
tempPicture.Graphics.TextSize = TextArea1.StyledText.Size(1, 1)
tempPicture.Graphics.Bold = TextArea1.StyledText.Bold(1, 1)
tempPicture.Graphics.Italic = TextArea1.StyledText.Italic(1, 1)
stringHeight = Ceil(tempPicture.Graphics.StringHeight(Mid(TextArea1.Text, 1, 1), 9999))
'draw each line
Dim i As Integer
Dim textLines(-1) As String
Dim y As Double
g.TextFont = TextArea1.StyledText.Font(1, 1)
g.TextSize = TextArea1.StyledText.Size(1, 1)
g.Bold = TextArea1.StyledText.Bold(1, 1)
g.Italic = TextArea1.StyledText.Italic(1, 1)
textLines = Split(TextArea1.Text, EndOfLine)
For i = 0 To UBound(textLines)
g.DrawString(textLines(i), 0, y + g.TextAscent)
y = y + fontHeight
Getting this to work for multiple styles will obviously be more complex. My gut feeling is that the spacing is based on the font and not a fixed value so you will have to handle different offsets on the same line. I’ll leave this to you how to work out.
What is Graphics.StringHeight?
Its the API 1 version of TextHeight. You probably also want to remove the Ceil() on there as well.
NOTE. That block of code is so that you can compare fontHeight with what Xojo returns but you don’t actually need it.
Oh, I understand now. The somewhat kludgy but relatively simple way without plugins or declares is to use the
TextArea.CharacterPosition(X,Y) method to “walk” vertically down the
TextArea (set X to 0 and increment Y). Every time the result changes, you are on a new line of text. You could use this for your use case, as I understand it. If you need more information about the text on each line, use the character position returned and interrogate the style runs.
NSAttributedStringMBS is macOS only and RealCADD is cross platform at least macOS and Windows.
As I mentioned in my original reply, the idea was for macOS only.
Have you checked to see if the same problem exists on MS-Windows as TextHeight might be good enough. If the problem does exist then I imagine you’ll have to interrogate the TextArea at a lower level using Declares (i’m sure its a Win32 RichEdit field).
Thank you Matthew!
There is still some differences but it is much better.
With some fonts, the value of leading is important.
New result :
What kind of result does TextArea1.drawinto give you?
I don’t tried TextArea.Drawinto because I read some posts talking about problems with it.
And I have to print the styled texts.
If you have the time, I would recommend trying it, you may need to set the background color to transparent and remove the border, but in theory it should give you identical results to what is displayed in the textarea and should be resolution less so it should work for printing also.
On the Mac (don’t know about Windows) I think the Text Area even has a built in print function that you should be able to access with a declare or two.
I think that I will not try Drawinto because now I have good results with my own method.