2860: Problem with det_ancestor report in PDF at page breaks
svn: r12521
This commit is contained in:
parent
177044c5db
commit
c980ef955a
@ -39,6 +39,7 @@ from xml.sax.saxutils import escape
|
|||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
import BaseDoc
|
import BaseDoc
|
||||||
from ReportBase import ReportUtils
|
from ReportBase import ReportUtils
|
||||||
|
from Errors import PluginError
|
||||||
|
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@ -399,10 +400,39 @@ class GtkDocParagraph(GtkDocBaseElement):
|
|||||||
else:
|
else:
|
||||||
self._text = ''
|
self._text = ''
|
||||||
|
|
||||||
|
self._plaintext = None
|
||||||
|
self._attrlist = None
|
||||||
|
|
||||||
def add_text(self, text):
|
def add_text(self, text):
|
||||||
|
if self._plaintext is not None:
|
||||||
|
raise PluginError('CairoDoc: text is already parsed.'
|
||||||
|
' You cannot add text anymore')
|
||||||
self._text = self._text + text
|
self._text = self._text + text
|
||||||
|
|
||||||
|
def __set_plaintext(self, plaintext):
|
||||||
|
"""
|
||||||
|
Internal method to allow for splitting of paragraphs
|
||||||
|
"""
|
||||||
|
self._plaintext = plaintext
|
||||||
|
|
||||||
|
def __set_attrlist(self, attrlist):
|
||||||
|
"""
|
||||||
|
Internal method to allow for splitting of paragraphs
|
||||||
|
"""
|
||||||
|
self._attrlist = attrlist
|
||||||
|
|
||||||
|
def __parse_text(self):
|
||||||
|
"""
|
||||||
|
Parse the markup text. This method will only do this if not
|
||||||
|
done already
|
||||||
|
"""
|
||||||
|
if self._plaintext is None:
|
||||||
|
self._attrlist, self._plaintext, dummy = \
|
||||||
|
pango.parse_markup(self._text)
|
||||||
|
|
||||||
def divide(self, layout, width, height, dpi_x, dpi_y):
|
def divide(self, layout, width, height, dpi_x, dpi_y):
|
||||||
|
self.__parse_text()
|
||||||
|
|
||||||
l_margin = self._style.get_left_margin() * dpi_x / 2.54
|
l_margin = self._style.get_left_margin() * dpi_x / 2.54
|
||||||
r_margin = self._style.get_right_margin() * dpi_x / 2.54
|
r_margin = self._style.get_right_margin() * dpi_x / 2.54
|
||||||
t_margin = self._style.get_top_margin() * dpi_y / 2.54
|
t_margin = self._style.get_top_margin() * dpi_y / 2.54
|
||||||
@ -437,41 +467,54 @@ class GtkDocParagraph(GtkDocBaseElement):
|
|||||||
#
|
#
|
||||||
font_style = self._style.get_font()
|
font_style = self._style.get_font()
|
||||||
layout.set_font_description(fontstyle_to_fontdescription(font_style))
|
layout.set_font_description(fontstyle_to_fontdescription(font_style))
|
||||||
|
|
||||||
# calculate the height of one line
|
|
||||||
# FIXME, we should do set_markup(self._text) and get height of entire
|
|
||||||
# block somehow, as with markup we allow for setting height
|
|
||||||
# of pieces of text ... only needed for styled notes though...
|
|
||||||
layout.set_text('Test')
|
|
||||||
layout_width, layout_height = layout.get_pixel_size()
|
|
||||||
line_height = layout_height + self.spacing
|
|
||||||
# and the number of lines fit on the available height
|
|
||||||
text_height = height - t_margin - 2 * v_padding
|
text_height = height - t_margin - 2 * v_padding
|
||||||
line_per_height = text_height / line_height
|
|
||||||
|
|
||||||
# if nothing fits return now with result
|
|
||||||
if line_per_height < 1:
|
|
||||||
return (None, self), 0
|
|
||||||
|
|
||||||
# calculate where to cut the paragraph
|
# calculate where to cut the paragraph
|
||||||
layout.set_markup(self._text)
|
layout.set_text(self._plaintext)
|
||||||
|
layout.set_attributes(self._attrlist)
|
||||||
layout_width, layout_height = layout.get_pixel_size()
|
layout_width, layout_height = layout.get_pixel_size()
|
||||||
line_count = layout.get_line_count()
|
line_count = layout.get_line_count()
|
||||||
|
|
||||||
# if all paragraph fits we don't need to cut
|
# if all paragraph fits we don't need to cut
|
||||||
if line_count <= line_per_height:
|
if layout_height <= text_height:
|
||||||
paragraph_height = (layout_height + t_margin + (2 * v_padding))
|
paragraph_height = layout_height + t_margin + (2 * v_padding)
|
||||||
if height - paragraph_height > b_margin:
|
if height - paragraph_height > b_margin:
|
||||||
paragraph_height += b_margin
|
paragraph_height += b_margin
|
||||||
return (self, None), paragraph_height
|
return (self, None), paragraph_height
|
||||||
|
|
||||||
# if paragraph part of a cell, we do not divide if only small part,
|
# we need to cut paragraph:
|
||||||
|
|
||||||
|
# 1. if paragraph part of a cell, we do not divide if only small part,
|
||||||
# of paragraph can be shown, instead move to next page
|
# of paragraph can be shown, instead move to next page
|
||||||
if line_per_height < line_count < 4 and self._parent._type == 'CELL':
|
if line_count < 4 and self._parent._type == 'CELL':
|
||||||
return (None, self), 0
|
return (None, self), 0
|
||||||
|
|
||||||
|
lineiter = layout.get_iter()
|
||||||
|
linenr = 0
|
||||||
|
linerange = lineiter.get_line_yrange()
|
||||||
|
# 2. if nothing fits, move to next page without split
|
||||||
|
if linerange[1] - linerange[0] > text_height * pango.SCALE:
|
||||||
|
return (None, self), 0
|
||||||
|
|
||||||
|
# 3. split the paragraph
|
||||||
|
startheight = linerange[0]
|
||||||
|
endheight = linerange[1]
|
||||||
|
splitline = -1
|
||||||
|
while not lineiter.at_last_line():
|
||||||
|
#go to next line, see if all fits, if not split
|
||||||
|
lineiter.next_line()
|
||||||
|
linenr += 1
|
||||||
|
linerange = lineiter.get_line_yrange()
|
||||||
|
if linerange[1] - startheight > text_height * pango.SCALE:
|
||||||
|
splitline = linenr
|
||||||
|
break
|
||||||
|
endheight = linerange[1]
|
||||||
|
if splitline == -1:
|
||||||
|
print 'CairoDoc STRANGE '
|
||||||
|
return (None, self), 0
|
||||||
|
#we split at splitline
|
||||||
# get index of first character which doesn't fit on available height
|
# get index of first character which doesn't fit on available height
|
||||||
layout_line = layout.get_line(int(line_per_height))
|
layout_line = layout.get_line(splitline)
|
||||||
index = layout_line.start_index
|
index = layout_line.start_index
|
||||||
# and divide the text, first create the second part
|
# and divide the text, first create the second part
|
||||||
new_style = BaseDoc.ParagraphStyle(self._style)
|
new_style = BaseDoc.ParagraphStyle(self._style)
|
||||||
@ -480,16 +523,41 @@ class GtkDocParagraph(GtkDocBaseElement):
|
|||||||
#as if the paragraph just continues from normal text
|
#as if the paragraph just continues from normal text
|
||||||
new_style.set_first_indent(0)
|
new_style.set_first_indent(0)
|
||||||
new_paragraph = GtkDocParagraph(new_style)
|
new_paragraph = GtkDocParagraph(new_style)
|
||||||
new_paragraph.add_text(self._text.encode('utf-8')[index:])
|
#index is in bytecode in the text..
|
||||||
|
new_paragraph.__set_plaintext(self._plaintext.encode('utf-8')[index:])
|
||||||
|
#now recalculate the attrilist:
|
||||||
|
newattrlist = layout.get_attributes().copy()
|
||||||
|
newattrlist.filter(self.filterattr, index)
|
||||||
|
oldattrlist = newattrlist.get_iterator()
|
||||||
|
while oldattrlist.next() :
|
||||||
|
vals = oldattrlist.get_attrs()
|
||||||
|
#print vals
|
||||||
|
for attr in vals:
|
||||||
|
newattr = attr.copy()
|
||||||
|
newattr.start_index -= index if newattr.start_index > index \
|
||||||
|
else 0
|
||||||
|
newattr.end_index -= index
|
||||||
|
newattrlist.insert(newattr)
|
||||||
|
new_paragraph.__set_attrlist(newattrlist)
|
||||||
|
|
||||||
# then update the first one
|
# then update the first one
|
||||||
self._text = self._text.encode('utf-8')[:index]
|
self.__set_plaintext(self._plaintext.encode('utf-8')[:index])
|
||||||
self._style.set_bottom_margin(0)
|
self._style.set_bottom_margin(0)
|
||||||
|
|
||||||
paragraph_height = line_height * line_count + t_margin + 2 * v_padding
|
paragraph_height = endheight - startheight + t_margin + 2 * v_padding
|
||||||
#paragraph_height = 0
|
|
||||||
return (self, new_paragraph), paragraph_height
|
return (self, new_paragraph), paragraph_height
|
||||||
|
|
||||||
|
def filterattr(self, attr, index):
|
||||||
|
"""callback to filter out attributes in the removed piece at beginning
|
||||||
|
"""
|
||||||
|
if attr.start_index > index or \
|
||||||
|
(attr.start_index < index and attr.end_index > index):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def draw(self, cr, layout, width, dpi_x, dpi_y):
|
def draw(self, cr, layout, width, dpi_x, dpi_y):
|
||||||
|
self.__parse_text()
|
||||||
|
|
||||||
l_margin = self._style.get_left_margin() * dpi_x / 2.54
|
l_margin = self._style.get_left_margin() * dpi_x / 2.54
|
||||||
r_margin = self._style.get_right_margin() * dpi_x / 2.54
|
r_margin = self._style.get_right_margin() * dpi_x / 2.54
|
||||||
t_margin = self._style.get_top_margin() * dpi_y / 2.54
|
t_margin = self._style.get_top_margin() * dpi_y / 2.54
|
||||||
@ -524,7 +592,8 @@ class GtkDocParagraph(GtkDocBaseElement):
|
|||||||
layout.set_font_description(fontstyle_to_fontdescription(font_style))
|
layout.set_font_description(fontstyle_to_fontdescription(font_style))
|
||||||
|
|
||||||
# layout the text
|
# layout the text
|
||||||
layout.set_markup(self._text)
|
layout.set_text(self._plaintext)
|
||||||
|
layout.set_attributes(self._attrlist)
|
||||||
layout_width, layout_height = layout.get_pixel_size()
|
layout_width, layout_height = layout.get_pixel_size()
|
||||||
|
|
||||||
# render the layout onto the cairo surface
|
# render the layout onto the cairo surface
|
||||||
|
Loading…
x
Reference in New Issue
Block a user