2007-08-12 Zsolt Foldvari <zfoldvar@users.sourceforge.net>

* src/docgen/GtkPrint.py: More work in progress.



svn: r8813
This commit is contained in:
Zsolt Foldvari 2007-08-12 10:37:11 +00:00
parent 61aa7a9f38
commit 1efee294a7
2 changed files with 167 additions and 33 deletions

View File

@ -1,3 +1,6 @@
2007-08-12 Zsolt Foldvari <zfoldvar@users.sourceforge.net>
* src/docgen/GtkPrint.py: More work in progress.
2007-08-11 Brian Matherly <brian@gramps-project.org>
* src/plugins/FamilyGroup.py: Add attributes

View File

@ -57,6 +57,7 @@ log = logging.getLogger(".GtkDoc")
import gtk
import cairo
import pango
import pangocairo
if gtk.pygtk_version < (2,10,0):
raise Errors.UnavailableError(
@ -240,10 +241,12 @@ def paperstyle_to_pagesetup(paper_style):
if gramps_to_gtk.has_key(gramps_paper_name):
paper_size = gtk.PaperSize(gramps_to_gtk[gramps_paper_name])
elif gramps_paper_name == "Custom Size":
paper_width = gramps_paper_size.get_width() * 10
paper_height = gramps_paper_size.get_height() * 10
paper_size = gtk.paper_size_new_custom("custom",
"Custom Size",
gramps_paper_size.get_width()*10,
gramps_paper_size.get_height()*10,
paper_width,
paper_height,
gtk.UNIT_MM)
else:
def_paper_size_name = gtk.paper_size_get_default()
@ -263,10 +266,14 @@ def paperstyle_to_pagesetup(paper_style):
# gtk.PageSize provides default margins for the standard papers.
# Anyhow, we overwrite those with the settings from Gramps,
# though at the moment all of them are fixed at 1 inch.
page_setup.set_top_margin(paper_style.get_top_margin()*10, gtk.UNIT_MM)
page_setup.set_bottom_margin(paper_style.get_bottom_margin()*10, gtk.UNIT_MM)
page_setup.set_left_margin(paper_style.get_left_margin()*10, gtk.UNIT_MM)
page_setup.set_right_margin(paper_style.get_right_margin()*10, gtk.UNIT_MM)
page_setup.set_top_margin(paper_style.get_top_margin() * 10,
gtk.UNIT_MM)
page_setup.set_bottom_margin(paper_style.get_bottom_margin() * 10,
gtk.UNIT_MM)
page_setup.set_left_margin(paper_style.get_left_margin() * 10,
gtk.UNIT_MM)
page_setup.set_right_margin(paper_style.get_right_margin() * 10,
gtk.UNIT_MM)
return page_setup
@ -278,26 +285,26 @@ def fontstyle_to_fontdescription(font_style):
"""
if font_style.face == BaseDoc.FONT_SERIF:
font_family = 'serif'
f_family = 'serif'
elif font_style.face == BaseDoc.FONT_SANS_SERIF:
font_family = 'sans serif'
f_family = 'sans serif'
else:
font_family = 'monospace'
f_family = 'monospace'
if font_style.get_bold():
font_weight = pango.WEIGHT_BOLD
f_weight = pango.WEIGHT_BOLD
else:
font_weight = pango.WEIGHT_NORMAL
f_weight = pango.WEIGHT_NORMAL
if font_style.get_italic():
font_style = pango.STYLE_ITALIC
f_style = pango.STYLE_ITALIC
else:
font_style = pango.STYLE_NORMAL
f_style = pango.STYLE_NORMAL
font_description = pango.FontDescription(font_family)
font_description = pango.FontDescription(f_family)
font_description.set_size(font_style.get_size() * pango.SCALE)
font_description.set_weight(font_weight)
font_description.set_style(font_style)
font_description.set_weight(f_weight)
font_description.set_style(f_style)
return font_description
@ -467,35 +474,65 @@ class GtkDocBaseElement(object):
"""
return self._children
def divide(self, width, height):
"""Divide the element into two.
def divide(self, layout, width, height):
"""Divide the element into two depending on available space.
@param layout: pango layout to write on
@param type: pango.Layout
@param width: width of available space for this element
@param type: device points
@param height: height of available space for this element
@param type: device points
@return: the divided element, and the height of the first part
@rtype: (GtkDocXXX-1, GtkDocXXX-2), device points
"""
raise NotImplementedError
def draw(self, pages):
"""Draw itself onto the received page(s).
def draw(self, width, height):
"""Draw itself onto a cairo surface with the given size.
Must be implemented in the subclasses.
@param width: width of available space for this element
@param type: device points
@param height: height of available space for this element
@param type: device points
@param pages: class handling the pages
@param type: CairoPages()
@return: drawing of this element on a cairo surface
@rtype: cairo.ImageSurface
"""
raise NotImplementedError
class GtkDocDocument(GtkDocBaseElement):
"""The whole document.
"""The whole document or a page.
"""
_type = 'DOCUMENT'
_allowed_children = ['PARAGRAPH', 'PAGEBREAK', 'TABLE', 'MEDIA']
def draw(self, width, height):
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
cr = cairo.Context(surface)
x = y = 0
for elem in self._children:
elem_surface, elem_height = elem.draw(width, height)
cr.set_source_surface(elem_surface, x, y)
cr.rectangle(x, y, x + width, y + elem_height)
cr.fill()
y += elem_height
return surface, y
class GtkDocPagebreak(GtkDocBaseElement):
"""Implement a page break.
"""
_type = 'PAGEBREAK'
_allowed_children = None
def divide(self, width, height):
def divide(self, layout, width, height):
return (None, None), 0
class GtkDocParagraph(GtkDocBaseElement):
@ -504,6 +541,8 @@ class GtkDocParagraph(GtkDocBaseElement):
_type = 'PARAGRAPH'
_allowed_children = None
spacing = 2.0
def __init__(self, style, text):
GtkDocBaseElement.__init__(self)
self._style = style
@ -514,11 +553,94 @@ class GtkDocParagraph(GtkDocBaseElement):
def add_text(self, text):
self._text = self._text + text
def divide(self, width, height):
return (self, None), 0
def divide(self, layout, width, height):
# calculate real width (margins, padding cm->pango)
text_width = width
layout.set_width(text_width * pango.SCALE)
# set paragraph properties
layout.set_wrap(pango.WRAP_WORD_CHAR)
layout.set_spacing(self.spacing * pango.SCALE)
font_style = self._style.get_font()
layout.set_font_description(fontstyle_to_fontdescription(font_style))
# FIXME set alignment and first indent too
# calculate the height of one line
layout.set_text('Test')
layout_width, layout_height = layout.get_size()
line_height = layout_height / pango.SCALE + self.spacing
# and the number of lines fit on the available height
line_per_height = height / line_height
# if nothing fits
if line_per_height < 1:
return (None, self), 0
# calculate where to cut the paragraph
layout.set_markup(self._text)
layout_width, layout_height = layout.get_size()
line_count = layout.get_line_count()
if line_count <= line_per_height:
# FIXME return proper paragraph height
return (self, None), layout_height / pango.SCALE
# get index of first character which doesn't fit on available height
layout_line = layout.get_line(line_per_height)
index = layout_line.start_index
# and divide the text
# FIXME new paragraph's style has to be modified
new_paragraph = GtkDocParagraph(self._style)
new_paragraph.add_text(self._text[index:])
# FIXME own style should be modified to
self._text = self._text[:index]
# FIXME return proper paragraph height
return (self, new_paragraph), line_height * line_count
def draw(self, pages):
pass
def draw(self, width, height):
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
cr = pangocairo.CairoContext(cairo.Context(surface))
layout = cr.create_layout()
# calculate real width (margins, padding cm->pango)
text_width = width
layout.set_width(text_width * pango.SCALE)
# set paragraph properties
layout.set_wrap(pango.WRAP_WORD_CHAR)
layout.set_spacing(self.spacing * pango.SCALE)
font_style = self._style.get_font()
layout.set_font_description(fontstyle_to_fontdescription(font_style))
# FIXME set alignment and first indent too
layout.set_markup(self._text)
layout_width, layout_height = layout.get_size()
# FIXME move to the proper position (margin, padding)
cr.move_to(0, 0)
cr.show_layout(layout)
# draw the borders
if self._style.get_top_border():
cr.move_to(0, 0)
cr.line(width, 0)
if self._style.get_right_border():
cr.move_to(width, 0)
cr.line(width, height)
if self._style.get_bottom_border():
cr.move_to(0, height)
cr.line(width, height)
if self._style.get_left_border():
cr.move_to(0, 0)
cr.line(0, height)
cr.set_line_width(0.1)
cr.set_source_rgb(0, 0, 0)
cr.stroke()
return surface, layout_height / pango.SCALE
#------------------------------------------------------------------------
#
@ -708,15 +830,19 @@ class GtkPrint(CairoDoc):
in the "begin-print" handler, and set the number of pages from there.
"""
layout = context.create_pango_layout()
# try to fit the next element to current page, divide it if needed
elem = self.elements_to_paginate.pop(0)
(e1, e2), e1_h = elem.divide(self.page_width, self.available_height)
(e1, e2), e1_h = elem.divide(layout,
self.page_width,
self.available_height)
# if (part of) it fits on current page add it
if e1 is not None:
self._pages[len(self._pages) - 1].add_child(e1)
# if elem was divided rememeber the second half to be processed
# if elem was divided remember the second half to be processed
if e2 is not None:
self.elements_to_paginate.insert(0, e2)
@ -749,7 +875,12 @@ class GtkPrint(CairoDoc):
to your needs.
"""
pass
page_surface, real_height = self._pages[page_nr].draw(self.page_width,
self.page_height)
cr = context.get_cairo_context()
cr.set_source_surface(page_surface, 0, 0)
cr.rectangle(0, 0, self.page_width, real_height)
cr.fill()
#def on_preview(self, operation, preview, context, parent, dummy=None):
#"""
@ -771,7 +902,7 @@ class GtkPrint(CairoDoc):
# Register the document generator with the GRAMPS plugin system
#
#------------------------------------------------------------------------
raise Errors.UnavailableError("Work in progress...")
register_text_doc(_('Print... (Gtk+)'), GtkPrint, 1, 1, 1, "", None)
##register_draw_doc(_('GtkPrint'), GtkPrint, 1, 1, "", None)
##register_book_doc(_("GtkPrint"), GtkPrint, 1, 1, 1, "", None)
raise Errors.UnavailableError("Work in progress...")