Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions NEWS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
======


Version 2.0, not released yet
=============================
Version 1.0.23, not released yet
================================

* Make text selectable on generated PDF files
* Fix markers
* Fix URL/id handling
* Test CairoSVG with Travis
Expand Down
3 changes: 3 additions & 0 deletions cairosvg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ def main():
option_parser.add_option(
"-o", "--output",
default="", help="output filename")
option_parser.add_option(
"--text-as-text", action="store_true",
help="saves text in PDF as text instead of paths")
options, args = option_parser.parse_args()

# Print help if no argument is given
Expand Down
24 changes: 20 additions & 4 deletions cairosvg/surface/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,10 @@ class Surface(object):

# Subclasses must either define this or override _create_surface()
surface_class = None
draw_text_as_text = False

@classmethod
def convert(cls, bytestring=None, **kwargs):
def convert(cls, bytestring=None, draw_text_as_text=None, **kwargs):
"""Convert a SVG document to the format for this class.

Specify the input by passing one of these:
Expand All @@ -90,6 +91,9 @@ def convert(cls, bytestring=None, **kwargs):

:param write_to: The filename of file-like object where to write the
output. If None or not provided, return a byte string.
:param draw_text_as_text: Draw text as text, instead of paths, reducing
the file size in PDFs and allowing text selection. May
not support some path clipping operations.

Only ``source`` can be passed as a positional argument, other
parameters are keyword-only.
Expand All @@ -105,12 +109,14 @@ def convert(cls, bytestring=None, **kwargs):
output = io.BytesIO()
else:
output = write_to
cls(tree, output, dpi, None, parent_width, parent_height).finish()
cls(tree, output, dpi, None, parent_width, parent_height,
draw_text_as_text).finish()
if write_to is None:
return output.getvalue()

def __init__(self, tree, output, dpi, parent_surface=None,
parent_width=None, parent_height=None):
parent_width=None, parent_height=None,
draw_text_as_text=None):
"""Create the surface from a filename or a file-like object.

The rendered content is written to ``output`` which can be a filename,
Expand Down Expand Up @@ -144,6 +150,8 @@ def __init__(self, tree, output, dpi, parent_surface=None,
self._old_parent_node = self.parent_node = None
self.output = output
self.dpi = dpi
if draw_text_as_text is not None:
self.draw_text_as_text = draw_text_as_text
self.font_size = size(self, "12pt")
self.stroke_and_fill = True
width, height, viewbox = node_format(self, tree)
Expand Down Expand Up @@ -323,6 +331,9 @@ def draw(self, node):
self.context.clip()
self.context.set_fill_rule(cairo.FILL_RULE_WINDING)

save_cursor = (self.cursor_position, self.cursor_d_position,
self.text_path_width)

if node.tag in TAGS:
try:
TAGS[node.tag](self, node)
Expand Down Expand Up @@ -362,7 +373,12 @@ def draw(self, node):
if node.get("fill-rule") == "evenodd":
self.context.set_fill_rule(cairo.FILL_RULE_EVEN_ODD)
self.context.set_source_rgba(*color(paint_color, fill_opacity))
self.context.fill_preserve()
if self.draw_text_as_text and TAGS[node.tag] == text:
self.cursor_position, self.cursor_d_position, \
self.text_path_width = save_cursor
text(self, node)
else:
self.context.fill_preserve()
self.context.restore()

# Stroke
Expand Down
7 changes: 6 additions & 1 deletion cairosvg/surface/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,12 @@ def text(surface, node):
surface.context.rel_move_to(-x_align, y_align)
surface.context.rotate(last_r if r is None else r)

surface.context.text_path(letter)
# Only draw characters with 'content' (workaround for bug in cairo)
if not letter.isspace():
if surface.draw_text_as_text:
surface.context.show_text(letter)
else:
surface.context.text_path(letter)
surface.context.restore()
if not text_path:
surface.cursor_position = cursor_position
Expand Down