Support for Plot, Image and DrawChar in pylrs

This commit is contained in:
Kovid Goyal 2007-04-24 04:14:39 +00:00
parent 44c7b6af37
commit b3d7fd96f2
4 changed files with 152 additions and 18 deletions

View File

@ -44,5 +44,5 @@ def option_parser(usage):
def Book(font_delta=0, **settings):
return _Book(textstyledefault=dict(fontsize=100+font_delta*20), \
pagestyledefault=dict(textwidth=570, textheight=747), \
pagestyledefault=dict(textwidth=575, textheight=747), \
**settings)

View File

@ -309,11 +309,13 @@ TAG_INFO = dict(
EmpDotsEnd = (0xF5BE,),
EmpLine = (0xF5C1,),
EmpLineEnd = (0xF5C2,),
DrawChar = (0xF5C3, '<H'),
DrawCharEnd = (0xF5C4,),
Box = (0xF5C6, LINE_TYPE_ENCODING, writeWord),
BoxEnd = (0xF5C7,),
Space = (0xF5CA, writeSignedWord),
textstring = (0xF5CC, writeUnicode), # when is this used?
Plot = (0xF5D1, "<HHII"),
Plot = (0xF5D1, "<HHII"),
CR = (0xF5D2,),
RegisterFont = (0xF5D8, writeDWord),
setwaitprop = (0xF5DA, {'replay':1, 'noreplay':2}, writeWord),

View File

@ -1135,7 +1135,7 @@ class PageStyle(LrsStyle):
"""
baseDefaults = dict(
topmargin="20", headheight="0", headsep="0",
oddsidemargin="20", textheight="800", textwidth="600",
oddsidemargin="20", textheight="747", textwidth="575",
footspace="0", evensidemargin="20", footheight="0",
layout="LrTb", bgimagemode="fix", pageposition="any",
setwaitprop="noreplay", setemptyview="show")
@ -1446,7 +1446,7 @@ class Paragraph(LrsContainer):
explicit .append methods to build up the text stream.
"""
def __init__(self, text=None):
LrsContainer.__init__(self, [Text, CR, LrsDrawChar, CharButton,
LrsContainer.__init__(self, [Text, CR, DrawChar, CharButton,
LrsSimpleChar1, basestring])
if text is not None:
self.append(text)
@ -1517,10 +1517,70 @@ class LrsTextTag(LrsContainer):
class LrsSimpleChar1(object):
pass
class DrawChar(LrsTextTag):
def __init__(self, lines):
LrsTextTag.__init__(self, None, [Italic, Bold, Plot, CR, NoBR])
if int(lines) <= 0:
raise LrsError('A DrawChar must span at least one line.')
self.lines = int(lines)
def toElement(self, se):
elem = Element('DrawChar', line=str(self.lines))
appendTextElements(elem, self.contents, se)
return elem
def toLrfContainer(self, lrfWriter, parent):
parent.appendLrfTag(LrfTag('DrawChar', (int(self.lines),)))
class LrsDrawChar(LrsSimpleChar1):
for content in self.contents:
content.toLrfContainer(lrfWriter, parent)
parent.appendLrfTag(LrfTag("DrawCharEnd"))
class Button(object):
# TODO: Implement
pass
class Plot(LrsContainer):
ADJUSTMENT_VALUES = {'center':1, 'baseline':2, 'top':3, 'bottom':4}
def __init__(self, obj, xsize=0, ysize=0, adjustment=None):
LrsContainer.__init__(self, [])
if not isinstance(obj, (Image, Button)):
raise LrsError('Plot elements can only refer to Image or Button elements')
self.obj = obj
if xsize < 0 or ysize < 0:
raise LrsError('Sizes must be positive semi-definite')
self.xsize = int(xsize)
self.ysize = int(ysize)
if adjustment and adjustment not in Plot.ADJUSTMENT_VALUES.keys():
raise LrsError('adjustment must be one of' + Plot.ADJUSTMENT_VALUES.keys())
self.adjustment = adjustment
def getReferencedObjIds(self):
return [self.obj.objId]
def appendReferencedObjects(self, parent):
if self.obj.parent is None:
parent.append(self.obj)
def toElement(self, se):
elem = Element('Plot', xsize=str(self.xsize), ysize=str(self.ysize), \
refobj=str(self.obj.objId))
if self.adjustment:
elem.set('adjustment', self.adjustment)
return elem
def toLrfContainer(self, lrfWriter, parent):
adj = self.adjustment if self.adjustment else 'bottom'
params = (int(self.xsize), int(self.ysize), int(self.obj.objId), \
Plot.ADJUSTMENT_VALUES[adj])
parent.appendLrfTag(LrfTag("Plot", params))
class Text(LrsContainer):
""" A object that represents raw text. Does not have a toElement. """
@ -1534,7 +1594,7 @@ class Text(LrsContainer):
class CR(LrsDrawChar, LrsContainer):
class CR(LrsContainer):
"""
A line break (when appended to a Paragraph) or a paragraph break
(when appended to a TextBlock).
@ -1552,26 +1612,26 @@ class CR(LrsDrawChar, LrsContainer):
class Italic(LrsDrawChar, LrsTextTag):
class Italic(LrsTextTag):
def __init__(self, text=None):
LrsTextTag.__init__(self, text, [LrsDrawChar])
LrsTextTag.__init__(self, text, [DrawChar])
class Sub(LrsDrawChar, LrsTextTag):
class Sub(LrsTextTag):
def __init__(self, text=None):
LrsTextTag.__init__(self, text, [])
class Sup(LrsDrawChar, LrsTextTag):
class Sup(LrsTextTag):
def __init__(self, text=None):
LrsTextTag.__init__(self, text, [])
class NoBR(LrsDrawChar, LrsTextTag):
class NoBR(LrsTextTag):
def __init__(self, text=None):
LrsTextTag.__init__(self, text, [LrsSimpleChar1])
@ -1624,9 +1684,9 @@ class Box(LrsSimpleChar1, LrsContainer):
class Span(LrsDrawChar, LrsContainer):
class Span(LrsContainer):
def __init__(self, text=None, **attrs):
LrsContainer.__init__(self, [LrsDrawChar, Text, basestring])
LrsContainer.__init__(self, [DrawChar, Text, basestring])
if text is not None:
self.append(text)
@ -1721,7 +1781,7 @@ class BlockSpace(LrsContainer):
class CharButton(LrsDrawChar, LrsContainer):
class CharButton(DrawChar, LrsContainer):
"""
Define the text and target of a CharButton. Must be passed a
JumpButton that is the destination of the CharButton.
@ -1766,16 +1826,18 @@ class CharButton(LrsDrawChar, LrsContainer):
class Objects(LrsContainer):
def __init__(self):
LrsContainer.__init__(self, [JumpButton, TextBlock, HeaderOrFooter,
ImageStream])
ImageStream, Image])
self.appendJumpButton = self.appendTextBlock = self.appendHeader = \
self.appendFooter = self.appendImageStream = self.append
self.appendFooter = self.appendImageStream = \
self.appendImage = self.append
def getMethods(self):
return ["JumpButton", "appendJumpButton", "TextBlock",
"appendTextBlock", "Header", "appendHeader",
"Footer", "appendFooter",
"ImageStream", "appendImageStream"]
"ImageStream", "appendImageStream",
'Image','appendImage']
def getSettings(self):
@ -1812,6 +1874,10 @@ class Objects(LrsContainer):
self.append(i)
return i
def Image(self, *args, **kwargs):
i = Image(*args, **kwargs)
self.append(i)
return i
def toElement(self, se):
o = Element("Objects")
@ -2025,7 +2091,44 @@ class ImageStream(LrsObject, LrsContainer):
element.text = self.comment
return element
class Image(LrsObject, LrsContainer, LrsAttributes):
defaults = dict()
def __init__(self, refstream, x0=0, x1=0, \
y0=0, y1=0, xsize=0, ysize=0, **settings):
LrsObject.__init__(self)
LrsContainer.__init__(self, [])
LrsAttributes.__init__(self, self.defaults, settings)
self.x0, self.y0, self.x1, self.y1 = int(x0), int(y0), int(x1), int(y1)
self.xsize, self.ysize = int(xsize), int(ysize)
self.refstream = refstream
def appendReferencedObjects(self, parent):
if self.refstream.parent is None:
parent.append(self.refstream)
def getReferencedObjIds(self):
return [self.objId, self.refstream.objId]
def toElement(self, se):
element = self.lrsObjectElement("Image", **self.attrs)
element.set("refstream", str(self.refstream.objId))
for name in ["x0", "y0", "x1", "y1", "xsize", "ysize"]:
element.set(name, str(getattr(self, name)))
return element
def toLrf(self, lrfWriter):
ib = LrfObject("Image", self.objId)
ib.appendLrfTag(LrfTag("ImageRect",
(self.x0, self.y0, self.x1, self.y1)))
ib.appendLrfTag(LrfTag("ImageSize", (self.xsize, self.ysize)))
ib.appendLrfTag(LrfTag("RefObjId", self.refstream.objId))
lrfWriter.append(ib)
class ImageBlock(LrsObject, LrsContainer, LrsAttributes):
""" Create an image on a page. """

View File

@ -0,0 +1,29 @@
#!/usr/bin/python
#Read text streams from LRF files. Usage ./stream.py <myfile.lrf> <offset to beginning of stream object in hex>
import array, sys, struct, zlib
def descrambleBuf(buf, l, xorKey):
i = 0
a = array.array('B',buf)
while l>0:
a[i] ^= xorKey
i+=1
l-=1
return a.tostring()
f = open(sys.argv[1], 'rb')
f.seek(0x0a)
xorkey = struct.unpack('<H', f.read(2))[0]
f.seek(int(sys.argv[2], 16) + 0x10)
flags = struct.unpack('<H', f.read(2))[0]
f.read(2)
l = struct.unpack('<I', f.read(4))[0]
f.read(2)
raw = f.read(l)
key = (l % xorkey) + 0x0f
descrambled = descrambleBuf(raw, l, key) if (flags & 0x200) else raw
stream = zlib.decompress(descrambled[4:]) if (flags & 0x100) else descrambled
print stream