I need to programmatically (basic, macro) determine the metric length of formatted text.
Thanks for any thoughts.
You tagged common
. Do you want to do that in Writer, Calc, Draw and Impress? Or only one of them. Edit and retag your question to give additional info. Don’t forget your (OS and) LO version since programming may differ between versions.
This depends on the definition of “formatted”. If you mean “a text with arbitrary formatted parts (different font/size/style/sub/superscript/kerning/…), like possible in Writer’s paragraph”, then @Lupp’ solution is likely the only possible.
For simpler cases, however, where “formatted” means “this text string in this specific font (with constant size/style etc.)”, there’s an XTextLayout interface, providing queryTextBounds
method. An instance of such interface may be obtained e.g. using XCanvasFont::createTextLayout; and you may obtain XCanvasFont if you have a canvas.
Thank you all for your attention and I will try to make the issue clearer.
- Firstly
Text with a formatted font, especially designer fonts, has both a width and a height different from monospaced. It is interesting to be able to programmatically determine the length of such text formatting.
- Second
I did not find a solution on my own, so I put the tag common
, not Writer
, Calc
, Draw
or Impress
. If this is possible for one of the lists, then I can use the solution for another.
Thanks to @mikekaganski . I didn’t know the XTextLayout interface yet when I answered.
Though I never used it, I knew the XFont interface (offering getStringWidth e…g ), but judged it to not be adequate in the case because it only accepts a string, and can therefore not regard any internal fprmatting. Even probably needed replacements for missing glyphs may cause problems.
Had I known XTextLayout with its poweful methods I surely would have pointed to it as a probably superior alternative.
I Would suggest @mikekaganski post the information he gave as an answer, and to include hints how to use that interface. This way it would be much more likely found by users looking for it.
@Lupp: unfortunately I have no spare cycles to make that a proper answer - that’s why it’s a comment in the first place. I know of the interfaces; but I’d need much experimentation to make examples and explanations. That’s up to an interested party.
I don’t know services or whatever giving direct access to such information.
The following is not a solution, but just a hint how I might start if i needed this.
Anyway it gave me the correct result for a printout in a test.
Sub printLengthOfSingleSelectedTextRangeIfInsideOneLine()
REM VERY raw!
doc = ThisComponent
cCtrl = doc.CurrentController
rgs = doc.CurrentSelection
If NOT rgs.supportsService("com.sun.star.text.TextRanges") OR (rgs.Count<>1) Then Exit Sub
rg = rgs(0)
tx = rg.Text
tc = tx.createTextCursorByRange(rg.Start)
cCtrl.select(tc)
vc = cCtrl.ViewCursor
x1 = vc.Position.X : y1 = vc.Position.Y
tc.gotoRange(rg.End, False)
cCtrl.select(tc)
vc = cCtrl.ViewCursor
x2 = vc.Position.X : y2 = vc.Position.Y
cCtrl.select(rgs)
If y2=y1 Then
Print "x2-x1 = " & (x2-x1) & " * 0.01 mm supposedly in printer metric."
Else
Print "Start and end of the text don't seem to be in the same line."
End If
End Sub
Thank you.
I will try to use this code to solve this problem.