Gemstone/S, Report4PDF + Unicode

Fixing Report4PDF under Gemstone/S to work with MultiByteStrings

Report4PDF and PDFTalkLibrary are the base of all reports I create within Gemstone/S in all our products/projects.

But I noticed problems in Report4PDF when using specific Unicode oriented strings – then R4PString crashes.

The problem comes up, if you have an Unicode string and it somehow gets an #asString (so it tries to convert itself) and the result gets its way into Report4PDF.

Gemstone/S tries to convert it into a single-byte string (if that works for all characters in the Unicode string) … if not possible, then you get a DoubleByteString instance.

And with instances of DoubleByteString Report4PDF does not work.

The problem is in the method 
R4PString instance
calculateNextLineAt: aPosition lineEnd: aLineEndIndex

| ... |

originalString := self string.
breakIndex := originalString
indexOfLastByte: Character space codePoint
startingAt: aLineEndIndex.
...

The problem here is the method indexOfLastByte:*, which is only defined for one-byte strings.

So, you should define a similiar method in the MultiByteString hierarchy … and then the stuff is working.

I defined a new method

breakIndex := 
originalString
mskIndexOfLastCharacter: Character space codePoint
startingAt: aLineEndIndex.

And here is the implementation for located in MultiByteString class:

mskIndexOfLastCharacter: codepoint startingAt: aLineEndIndex
| lastPosition |

lastPosition := 0.
self isEmpty ifTrue:[ ^lastPosition ].
[ lastPosition < aLineEndIndex ] whileTrue:[
| tmp |
"nichts gefunden - letzte Position zurückgeben"
(tmp := self
indexOf: codepoint
startingAt: lastPosition + 1) = 0
ifTrue:[ ^lastPosition ].
tmp > aLineEndIndex ifTrue:[ ^lastPosition ].
(tmp > 0 and:[ tmp <= aLineEndIndex ])
ifTrue:[ lastPosition := tmp ]
].
^lastPosition

Tags:

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.