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

Ian reportlab-users@reportlab.com
Mon, 15 Mar 2004 22:36:20 -0000


Okay, here are the bugfixes / patch for the TextObject class as a diff.

Notes:
1. It is well commented (overly perhaps), so it should speak for itself.
2. It is still not perfect with respect to the cursor location matching
where text will be drawn. In particular it doesn't fix the problems with
setting different rise amounts, or using more complex text matrices.
3. I've tested it on all my reportlab applications, but it could benefit
from a wider testing, so feel free to run in against your stuff. Make sure
if it doesn't work, it isn't because your code was naturally working around
the bug (a couple of my code snippets were doing this).

61,62d57
<
<         # The current cursor position is at the text origin
65,68c60
<
<         # Keep track of the start of the current line
<         self._x0 = x
<         self._y0 = y
---
>         self._x0 = x #the margin
76,86c68,70
<
<         # The current cursor position is at the text origin Note that
<         # we aren't keeping track of all the transform on these
<         # coordinates: they are relative to the rotations/sheers
<         # defined in the matrix.
<         self._x = x
<         self._y = y
<
<         # Keep track of the start of the current line
<         self._x0 = x
<         self._y0 = y
---
>         #we only measure coords relative to present text matrix
>         self._x = e
>         self._y = f
89,98c73,75
<
<         """Starts a new line at an offset dx,dy from the start of the
<         current line. This does not move the cursor relative to the
<         current position, and it changes the current offset of every
<         future line drawn (i.e. if you next do a textLine() call, it
<         will move the cursor to a position one line lower than the
<         position specificied in this call.  """
<
<         # Check if we have a previous move cursor call, and combine
<         # them if possible.
---
>         """Moves to a point dx, dy away from the start of the
>         current line - NOT from the current point! So if
>         you call it in mid-sentence, watch out."""
105,120c82,83
<
<             # Work out the last movement
<             lastDx = float(L[-3])
<             lastDy = float(L[-2])
<
<             # Combine the two movement
<             dx = dx + lastDx
<             dy = dy - lastDy
<
<             # We will soon add the movement to the line origin, so if
<             # we've already done this for lastDx, lastDy, remove it
<             # first (so it will be right when added back again).
<             self._x0 -= lastDx
<             sefl._y0 -= lastDy
<
<         # Output the move text cursor call.
---
>             dx = dx + float(L[-3])
>             dy = dy - float(L[-2])
123,128d85
<         # Keep track of the new line offsets and the cursor position
<         self._x0 += dx
<         self._y0 += dy
<         self._x = self._x0
<         self._y = self._y0
<
130c87
<         """Starts a new line dx away from the start of the
---
>         """Moves to a point dx away from the start of the
317,318d273
<
<         # Update the coordinates of the cursor
324,329d278
<
<         # Update the location of the start of the line
<         # self._x0 is unchanged
<         self._y0 = self._y
<
<         # Output the text followed by a PDF newline command
349,350d297
<         # Output each line one at a time. This used to be a long-hand
<         # copy of the textLine code, now called as a method.
352c299,304
<             self.textLine(line)
---
>             self._code.append('%s T*' % self._formatText(line))
>             if self._canvas.bottomup:
>                 self._y = self._y - self._leading
>             else:
>                 self._y = self._y + self._leading
>         self._x = self._x0






----- Original Message ----- 
From: "Ian" <reportlab-user@agon.com>
To: <reportlab-users@reportlab.com>
Sent: Monday, March 15, 2004 9:33 PM
Subject: Re: [reportlab-users] A Bug in TextObject.moveCursor?


> Right, I've done some investigation and moveCursor is buggy (or at least
> incorrect)
>
> 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.
>
> Ian.
>
> _______________________________________________
> reportlab-users mailing list
> reportlab-users@reportlab.com
> http://two.pairlist.net/mailman/listinfo/reportlab-users
>