Patch by Adam Stein <adam@csh.rit.edu > - Continued work on "0002513: Using section/region on media_ref as thumbnail on reports" - add image cropping to Cairo documents
svn: r18097
This commit is contained in:
parent
85e803f5f6
commit
eb85361c7e
@ -180,6 +180,45 @@ def image_actual_size(x_cm, y_cm, x, y):
|
||||
|
||||
return (act_width, act_height)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# resize_to_buffer
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def resize_to_buffer(source, size, crop=None):
|
||||
"""
|
||||
Loads the image and resizes it. Instead of saving the file, the data
|
||||
is returned in a buffer.
|
||||
|
||||
:param source: source image file, in any format that gtk recognizes
|
||||
:type source: unicode
|
||||
:param size: desired size of the destination image ([width, height])
|
||||
:type size: list
|
||||
:param crop: cropping coordinates
|
||||
:type crop: array of integers ([start_x, start_y, end_x, end_y])
|
||||
:rtype: buffer of data
|
||||
:returns: raw data
|
||||
"""
|
||||
import gtk
|
||||
img = gtk.gdk.pixbuf_new_from_file(source)
|
||||
|
||||
if crop:
|
||||
# Gramps cropping coorinates are [0, 100], so we need to convert to pixels
|
||||
start_x = int((crop[0]/100.0)*img.get_width())
|
||||
start_y = int((crop[1]/100.0)*img.get_height())
|
||||
end_x = int((crop[2]/100.0)*img.get_width())
|
||||
end_y = int((crop[3]/100.0)*img.get_height())
|
||||
|
||||
img = img.subpixbuf(start_x, start_y, end_x-start_x, end_y-start_y)
|
||||
|
||||
# Need to keep the ratio intact, otherwise scaled images look stretched
|
||||
# if the dimensions aren't close in size
|
||||
(size[0], size[1]) = image_actual_size(size[0], size[1], img.get_width(), img.get_height())
|
||||
|
||||
scaled = img.scale_simple(int(size[0]), int(size[1]), gtk.gdk.INTERP_BILINEAR)
|
||||
|
||||
return scaled
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# resize_to_jpeg_buffer
|
||||
|
@ -46,6 +46,7 @@ from gen.plug.docgen import (BaseDoc, TextDoc, DrawDoc, ParagraphStyle,
|
||||
from gen.plug.report import utils as ReportUtils
|
||||
from Errors import PluginError
|
||||
from gen.plug.docbackend import CairoBackend
|
||||
import ImgManip
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
@ -894,11 +895,12 @@ class GtkDocPicture(GtkDocBaseElement):
|
||||
_type = 'IMAGE'
|
||||
_allowed_children = []
|
||||
|
||||
def __init__(self, style, filename, width, height):
|
||||
def __init__(self, style, filename, width, height, crop=None):
|
||||
GtkDocBaseElement.__init__(self, style)
|
||||
self._filename = filename
|
||||
self._width = width
|
||||
self._height = height
|
||||
self._crop = crop
|
||||
|
||||
def divide(self, layout, width, height, dpi_x, dpi_y):
|
||||
img_width = self._width * dpi_x / 2.54
|
||||
@ -923,7 +925,7 @@ class GtkDocPicture(GtkDocBaseElement):
|
||||
l_margin = 0
|
||||
|
||||
# load the image and get its extents
|
||||
pixbuf = gtk.gdk.pixbuf_new_from_file(self._filename)
|
||||
pixbuf = ImgManip.resize_to_buffer(self._filename, [img_width, img_height], self._crop)
|
||||
pixbuf_width = pixbuf.get_width()
|
||||
pixbuf_height = pixbuf.get_height()
|
||||
|
||||
@ -1227,6 +1229,7 @@ class CairoDoc(BaseDoc, TextDoc, DrawDoc):
|
||||
self._active_element = self._doc
|
||||
self._pages = []
|
||||
self._elements_to_paginate = []
|
||||
self._links_error = False
|
||||
|
||||
def close(self):
|
||||
self.run()
|
||||
@ -1300,11 +1303,12 @@ class CairoDoc(BaseDoc, TextDoc, DrawDoc):
|
||||
Convenience function to write a styledtext to the cairo doc.
|
||||
styledtext : assumed a StyledText object to write
|
||||
format : = 0 : Flowed, = 1 : Preformatted
|
||||
style_name : name of the style to use for default presentation
|
||||
contains_html: bool, the backend should not check if html is present.
|
||||
If contains_html=True, then the textdoc is free to handle that in
|
||||
some way. Eg, a textdoc could remove all tags, or could make sure
|
||||
style_name : name of the style to use for default presentation
|
||||
contains_html: bool, the backend should not check if html is present.
|
||||
If contains_html=True, then the textdoc is free to handle that in
|
||||
some way. Eg, a textdoc could remove all tags, or could make sure
|
||||
a link is clickable. CairoDoc does nothing different for html notes
|
||||
links: bool, true if URLs should be made clickable
|
||||
"""
|
||||
text = str(styledtext)
|
||||
|
||||
@ -1319,7 +1323,7 @@ class CairoDoc(BaseDoc, TextDoc, DrawDoc):
|
||||
#FIXME: following split should be regex to match \n\s*\n instead?
|
||||
for line in markuptext.split('\n\n'):
|
||||
self.start_paragraph(style_name)
|
||||
self.__write_text(line, markup=True)
|
||||
self.__write_text(line, markup=True, links=links)
|
||||
self.end_paragraph()
|
||||
elif format == 0:
|
||||
#flowed
|
||||
@ -1331,16 +1335,34 @@ class CairoDoc(BaseDoc, TextDoc, DrawDoc):
|
||||
newlines = []
|
||||
for singleline in lines:
|
||||
newlines.append(' '.join(singleline.split()))
|
||||
self.__write_text('\n'.join(newlines), markup=True)
|
||||
self.__write_text('\n'.join(newlines), markup=True, links=links)
|
||||
self.end_paragraph()
|
||||
|
||||
def __write_text(self, text, mark=None, markup=False):
|
||||
def __write_text(self, text, mark=None, markup=False, links=False):
|
||||
"""
|
||||
@param text: text to write.
|
||||
@param mark: IndexMark to use for indexing (if supported)
|
||||
@param markup: True if text already contains markup info.
|
||||
Then text will no longer be escaped
|
||||
@param links: True if URLs should be made clickable
|
||||
"""
|
||||
if links == True:
|
||||
import cairo
|
||||
|
||||
if cairo.cairo_version() < 11210 and self._links_error == False:
|
||||
# Cairo v1.12 is suppose to be the first version
|
||||
# that supports clickable links
|
||||
print """
|
||||
WARNING: This version of cairo (%s) does NOT support clickable links.
|
||||
The first version that is suppose to is v1.12. See the roadmap:
|
||||
|
||||
http://www.cairographics.org/roadmap/
|
||||
|
||||
The work around is to save to another format that supports clickable
|
||||
links (like ODF) and write PDF from that format.
|
||||
""" % cairo.version
|
||||
self._links_error = True
|
||||
|
||||
if not markup:
|
||||
# We need to escape the text here for later pango.Layout.set_markup
|
||||
# calls. This way we save the markup created by the report
|
||||
@ -1354,8 +1376,9 @@ class CairoDoc(BaseDoc, TextDoc, DrawDoc):
|
||||
present style
|
||||
@param text: text to write.
|
||||
@param mark: IndexMark to use for indexing (if supported)
|
||||
@param links: True if URLs should be made clickable
|
||||
"""
|
||||
self.__write_text(text, mark)
|
||||
self.__write_text(text, mark, links=links)
|
||||
|
||||
def write_markup(self, text, s_tags):
|
||||
"""
|
||||
@ -1371,9 +1394,23 @@ class CairoDoc(BaseDoc, TextDoc, DrawDoc):
|
||||
|
||||
def add_media_object(self, name, pos, x_cm, y_cm, alt='',
|
||||
style_name=None, crop=None):
|
||||
new_image = GtkDocPicture(pos, name, x_cm, y_cm)
|
||||
new_image = GtkDocPicture(pos, name, x_cm, y_cm, crop=crop)
|
||||
self._active_element.add_child(new_image)
|
||||
|
||||
if len(alt):
|
||||
style_sheet = self.get_style_sheet()
|
||||
|
||||
style = style_sheet.get_paragraph_style(style_name)
|
||||
style.set_alignment(PARA_ALIGN_CENTER)
|
||||
# Center the caption under the image
|
||||
if pos == "right":
|
||||
style.set_left_margin(self.get_usable_width() - new_image._width)
|
||||
else:
|
||||
style.set_right_margin(self.get_usable_width() - new_image._width)
|
||||
new_paragraph = GtkDocParagraph(style)
|
||||
new_paragraph.add_text(alt)
|
||||
self._active_element.add_child(new_paragraph)
|
||||
|
||||
# DrawDoc implementation
|
||||
|
||||
def start_page(self):
|
||||
|
Loading…
Reference in New Issue
Block a user