[reportlab-users] A Bug in TextObject.moveCursor?

Ian reportlab-users@reportlab.com
Mon, 15 Mar 2004 21:33:15 -0000

Right, I've done some investigation and moveCursor is buggy (or at least

A. The bug in moveCursor

moveCursor appears to do two things:
1. It checks if the previous command was also a move cursor ('Td' in PDF),
if so it combines the two commands into one (which it SHOULDN'T DO, if the
move cursor is relative to the start of the line! - coimbining two calls
both relative to the start of the line, is equivalent to ignoring the first
call all together - BUT see part B of this mail).
2. It outputs the 'Td' command into PDF.

Nowhere does it change the cursor position: _x and _y members of the
TextObject class. As the following interactive session shows:

>>> to = c.beginText()
>>> to.setTextOrigin(100,500)
>>> to.textOut('hello')
>>> to.getCursor()
(124.0, 500)
>>> to.moveCursor(100,0)
>>> to.getCursor()
(124.0, 500) <-- should be (200,500)
>>> to.textOut('there')
>>> to.getCursor()
(147.988, 500) <-- should be (223.988,500)

So at the very least, it needs to be updated to add the lines:
_x = _xo + dx
_y = _y + dy

But this alone won't work if the setRise function is used mid-line and not
reset before the moveCursor is used.

B. The problem with multiple moveCursor calls

This still doesn't solve the problem of multiple moveCursor calls not
working properly on the same line.

That problem is to do with the Td operator in PDF. Td, according to 5.3.1 of
the PDF specification, should "Move to the start of the next line, offset
from the start of the current line by (tx , ty )." Which means that multiple
calls are effectively resetting the line offsets each time, So the
moveCursor call is offsetting relative to the 'start of the line, OR the
last moveCursor command on this line.' (hence why my example worked the
first time).

All this means that, with my suggested change in A above, I can get my
application working. But it does mean that the documentation for moveCursor
is flawed. I would suggest that it is either updated, or a new method is
added that does a slightly more logical cursor movement operation.

Either way something needs to be done to stop getCursor reporting the wrong
position after any moveCursor command.