Merge lp:~drbild/inkscape/multilayer-pdf-latex-output into lp:~inkscape.dev/inkscape/trunk

Proposed by Martin Owens
Status: Merged
Approved by: Johan Engelen
Approved revision: 12489
Merged at revision: 12489
Proposed branch: lp:~drbild/inkscape/multilayer-pdf-latex-output
Merge into: lp:~inkscape.dev/inkscape/trunk
Diff against target: 366 lines (+114/-18)
8 files modified
src/extension/internal/cairo-ps-out.cpp (+1/-1)
src/extension/internal/cairo-render-context.cpp (+47/-2)
src/extension/internal/cairo-render-context.h (+17/-0)
src/extension/internal/cairo-renderer-pdf-out.cpp (+1/-1)
src/extension/internal/cairo-renderer.cpp (+0/-6)
src/extension/internal/cairo-renderer.h (+0/-4)
src/extension/internal/latex-text-renderer.cpp (+37/-4)
src/extension/internal/latex-text-renderer.h (+11/-0)
To merge this branch: bzr merge lp:~drbild/inkscape/multilayer-pdf-latex-output
Reviewer Review Type Date Requested Status
Johan Engelen Approve
Review via email: mp+183288@code.launchpad.net

Description of the change

Merge in, signed off by Johan Engelen

To post a comment you must log in.
12489. By David R. Bild <email address hidden>

use multiple graphic/text layers for pdf+latex output

Revision history for this message
Johan Engelen (johanengelen) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/extension/internal/cairo-ps-out.cpp'
--- src/extension/internal/cairo-ps-out.cpp 2013-08-05 21:07:35 +0000
+++ src/extension/internal/cairo-ps-out.cpp 2013-08-30 22:23:52 +0000
@@ -97,7 +97,7 @@
97 ctx->setPSLevel(level);97 ctx->setPSLevel(level);
98 ctx->setEPS(eps);98 ctx->setEPS(eps);
99 ctx->setTextToPath(texttopath);99 ctx->setTextToPath(texttopath);
100 renderer->_omitText = omittext;100 ctx->setOmitText(omittext);
101 ctx->setFilterToBitmap(filtertobitmap);101 ctx->setFilterToBitmap(filtertobitmap);
102 ctx->setBitmapResolution(resolution);102 ctx->setBitmapResolution(resolution);
103103
104104
=== modified file 'src/extension/internal/cairo-render-context.cpp'
--- src/extension/internal/cairo-render-context.cpp 2013-08-06 18:54:40 +0000
+++ src/extension/internal/cairo-render-context.cpp 2013-08-30 22:23:52 +0000
@@ -6,6 +6,7 @@
6 * Miklos Erdelyi <erdelyim@gmail.com>6 * Miklos Erdelyi <erdelyim@gmail.com>
7 * Jon A. Cruz <jon@joncruz.org>7 * Jon A. Cruz <jon@joncruz.org>
8 * Abhishek Sharma8 * Abhishek Sharma
9 * David R. Bild <drbild@umich.edu>
9 *10 *
10 * Copyright (C) 2006 Miklos Erdelyi11 * Copyright (C) 2006 Miklos Erdelyi
11 *12 *
@@ -111,6 +112,7 @@
111 _ps_level(1),112 _ps_level(1),
112 _eps(false),113 _eps(false),
113 _is_texttopath(FALSE),114 _is_texttopath(FALSE),
115 _is_omittext(FALSE),
114 _is_filtertobitmap(FALSE),116 _is_filtertobitmap(FALSE),
115 _bitmapresolution(72),117 _bitmapresolution(72),
116 _stream(NULL),118 _stream(NULL),
@@ -124,7 +126,8 @@
124 _state(NULL),126 _state(NULL),
125 _renderer(parent),127 _renderer(parent),
126 _render_mode(RENDER_MODE_NORMAL),128 _render_mode(RENDER_MODE_NORMAL),
127 _clip_mode(CLIP_MODE_MASK)129 _clip_mode(CLIP_MODE_MASK),
130 _omittext_state(EMPTY)
128{131{
129 font_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, font_data_free);132 font_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, font_data_free);
130}133}
@@ -426,6 +429,16 @@
426 _is_texttopath = texttopath;429 _is_texttopath = texttopath;
427}430}
428431
432void CairoRenderContext::setOmitText(bool omittext)
433{
434 _is_omittext = omittext;
435}
436
437bool CairoRenderContext::getOmitText(void)
438{
439 return _is_omittext;
440}
441
429void CairoRenderContext::setFilterToBitmap(bool filtertobitmap)442void CairoRenderContext::setFilterToBitmap(bool filtertobitmap)
430{443{
431 _is_filtertobitmap = filtertobitmap;444 _is_filtertobitmap = filtertobitmap;
@@ -1331,11 +1344,36 @@
1331 cairo_set_miter_limit(_cr, MAX(1, style->stroke_miterlimit.value));1344 cairo_set_miter_limit(_cr, MAX(1, style->stroke_miterlimit.value));
1332}1345}
13331346
1347void
1348CairoRenderContext::_prepareRenderGraphic()
1349{
1350 // Only PDFLaTeX supports importing a single page of a graphics file,
1351 // so only PDF backend gets interleaved text/graphics
1352 if (_is_omittext && _target == CAIRO_SURFACE_TYPE_PDF) {
1353 if (_omittext_state == NEW_PAGE_ON_GRAPHIC)
1354 cairo_show_page(_cr);
1355 _omittext_state = GRAPHIC_ON_TOP;
1356 }
1357}
1358
1359void
1360CairoRenderContext::_prepareRenderText()
1361{
1362 // Only PDFLaTeX supports importing a single page of a graphics file,
1363 // so only PDF backend gets interleaved text/graphics
1364 if (_is_omittext && _target == CAIRO_SURFACE_TYPE_PDF) {
1365 if (_omittext_state == GRAPHIC_ON_TOP)
1366 _omittext_state = NEW_PAGE_ON_GRAPHIC;
1367 }
1368}
1369
1334bool1370bool
1335CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle const *style, Geom::OptRect const &pbox)1371CairoRenderContext::renderPathVector(Geom::PathVector const & pathv, SPStyle const *style, Geom::OptRect const &pbox)
1336{1372{
1337 g_assert( _is_valid );1373 g_assert( _is_valid );
13381374
1375 _prepareRenderGraphic();
1376
1339 if (_render_mode == RENDER_MODE_CLIP) {1377 if (_render_mode == RENDER_MODE_CLIP) {
1340 if (_clip_mode == CLIP_MODE_PATH) {1378 if (_clip_mode == CLIP_MODE_PATH) {
1341 addClipPath(pathv, &style->fill_rule);1379 addClipPath(pathv, &style->fill_rule);
@@ -1408,6 +1446,8 @@
1408 return true;1446 return true;
1409 }1447 }
14101448
1449 _prepareRenderGraphic();
1450
1411 int w = gdk_pixbuf_get_width (pb);1451 int w = gdk_pixbuf_get_width (pb);
1412 int h = gdk_pixbuf_get_height (pb);1452 int h = gdk_pixbuf_get_height (pb);
14131453
@@ -1489,7 +1529,12 @@
1489bool1529bool
1490CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Affine const &font_matrix,1530CairoRenderContext::renderGlyphtext(PangoFont *font, Geom::Affine const &font_matrix,
1491 std::vector<CairoGlyphInfo> const &glyphtext, SPStyle const *style)1531 std::vector<CairoGlyphInfo> const &glyphtext, SPStyle const *style)
1492{1532{
1533
1534 _prepareRenderText();
1535 if (_is_omittext)
1536 return true;
1537
1493 // create a cairo_font_face from PangoFont1538 // create a cairo_font_face from PangoFont
1494 double size = style->font_size.computed; /// \fixme why is this variable never used?1539 double size = style->font_size.computed; /// \fixme why is this variable never used?
1495 gpointer fonthash = (gpointer)font;1540 gpointer fonthash = (gpointer)font;
14961541
=== modified file 'src/extension/internal/cairo-render-context.h'
--- src/extension/internal/cairo-render-context.h 2013-03-15 00:39:02 +0000
+++ src/extension/internal/cairo-render-context.h 2013-08-30 22:23:52 +0000
@@ -94,6 +94,8 @@
94 void setPDFLevel(unsigned int level);94 void setPDFLevel(unsigned int level);
95 void setTextToPath(bool texttopath);95 void setTextToPath(bool texttopath);
96 bool getTextToPath(void);96 bool getTextToPath(void);
97 void setOmitText(bool omittext);
98 bool getOmitText(void);
97 void setFilterToBitmap(bool filtertobitmap);99 void setFilterToBitmap(bool filtertobitmap);
98 bool getFilterToBitmap(void);100 bool getFilterToBitmap(void);
99 void setBitmapResolution(int resolution);101 void setBitmapResolution(int resolution);
@@ -109,6 +111,9 @@
109 /** Saves the contents of the context to a PNG file. */111 /** Saves the contents of the context to a PNG file. */
110 bool saveAsPng(const char *file_name);112 bool saveAsPng(const char *file_name);
111113
114 /** On targets supporting multiple pages, sends subsequent rendering to a new page*/
115 void newPage(void);
116
112 /* Render/clip mode setting/query */117 /* Render/clip mode setting/query */
113 void setRenderMode(CairoRenderMode mode);118 void setRenderMode(CairoRenderMode mode);
114 CairoRenderMode getRenderMode(void) const;119 CairoRenderMode getRenderMode(void) const;
@@ -150,6 +155,12 @@
150 CairoRenderContext(CairoRenderer *renderer);155 CairoRenderContext(CairoRenderer *renderer);
151 virtual ~CairoRenderContext(void);156 virtual ~CairoRenderContext(void);
152157
158 enum CairoOmitTextPageState {
159 EMPTY,
160 GRAPHIC_ON_TOP,
161 NEW_PAGE_ON_GRAPHIC
162 };
163
153 float _width;164 float _width;
154 float _height;165 float _height;
155 unsigned short _dpi;166 unsigned short _dpi;
@@ -157,6 +168,7 @@
157 unsigned int _ps_level;168 unsigned int _ps_level;
158 bool _eps;169 bool _eps;
159 bool _is_texttopath;170 bool _is_texttopath;
171 bool _is_omittext;
160 bool _is_filtertobitmap;172 bool _is_filtertobitmap;
161 int _bitmapresolution;173 int _bitmapresolution;
162174
@@ -182,6 +194,8 @@
182 CairoRenderMode _render_mode;194 CairoRenderMode _render_mode;
183 CairoClipMode _clip_mode;195 CairoClipMode _clip_mode;
184196
197 CairoOmitTextPageState _omittext_state;
198
185 cairo_pattern_t *_createPatternForPaintServer(SPPaintServer const *const paintserver,199 cairo_pattern_t *_createPatternForPaintServer(SPPaintServer const *const paintserver,
186 Geom::OptRect const &pbox, float alpha);200 Geom::OptRect const &pbox, float alpha);
187 cairo_pattern_t *_createPatternPainter(SPPaintServer const *const paintserver, Geom::OptRect const &pbox);201 cairo_pattern_t *_createPatternPainter(SPPaintServer const *const paintserver, Geom::OptRect const &pbox);
@@ -196,6 +210,9 @@
196 void _concatTransform(cairo_t *cr, double xx, double yx, double xy, double yy, double x0, double y0);210 void _concatTransform(cairo_t *cr, double xx, double yx, double xy, double yy, double x0, double y0);
197 void _concatTransform(cairo_t *cr, Geom::Affine const &transform);211 void _concatTransform(cairo_t *cr, Geom::Affine const &transform);
198212
213 void _prepareRenderGraphic(void);
214 void _prepareRenderText(void);
215
199 GHashTable *font_table;216 GHashTable *font_table;
200 static void font_data_free(gpointer data);217 static void font_data_free(gpointer data);
201218
202219
=== modified file 'src/extension/internal/cairo-renderer-pdf-out.cpp'
--- src/extension/internal/cairo-renderer-pdf-out.cpp 2013-08-06 18:54:40 +0000
+++ src/extension/internal/cairo-renderer-pdf-out.cpp 2013-08-30 22:23:52 +0000
@@ -94,7 +94,7 @@
94 CairoRenderContext *ctx = renderer->createContext();94 CairoRenderContext *ctx = renderer->createContext();
95 ctx->setPDFLevel(level);95 ctx->setPDFLevel(level);
96 ctx->setTextToPath(texttopath);96 ctx->setTextToPath(texttopath);
97 renderer->_omitText = omittext;97 ctx->setOmitText(omittext);
98 ctx->setFilterToBitmap(filtertobitmap);98 ctx->setFilterToBitmap(filtertobitmap);
99 ctx->setBitmapResolution(resolution);99 ctx->setBitmapResolution(resolution);
100100
101101
=== modified file 'src/extension/internal/cairo-renderer.cpp'
--- src/extension/internal/cairo-renderer.cpp 2013-07-31 22:33:03 +0000
+++ src/extension/internal/cairo-renderer.cpp 2013-08-30 22:23:52 +0000
@@ -101,7 +101,6 @@
101namespace Internal {101namespace Internal {
102102
103CairoRenderer::CairoRenderer(void)103CairoRenderer::CairoRenderer(void)
104 : _omitText(false)
105{}104{}
106105
107CairoRenderer::~CairoRenderer(void)106CairoRenderer::~CairoRenderer(void)
@@ -578,11 +577,6 @@
578// TODO change this to accept a const SPItem:577// TODO change this to accept a const SPItem:
579void CairoRenderer::renderItem(CairoRenderContext *ctx, SPItem *item)578void CairoRenderer::renderItem(CairoRenderContext *ctx, SPItem *item)
580{579{
581 if ( _omitText && (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) ) {
582 // skip text if _omitText is true
583 return;
584 }
585
586 ctx->pushState();580 ctx->pushState();
587 setStateForItem(ctx, item);581 setStateForItem(ctx, item);
588582
589583
=== modified file 'src/extension/internal/cairo-renderer.h'
--- src/extension/internal/cairo-renderer.h 2013-03-15 00:39:02 +0000
+++ src/extension/internal/cairo-renderer.h 2013-08-30 22:23:52 +0000
@@ -57,10 +57,6 @@
5757
58 /** Traverses the object tree and invokes the render methods. */58 /** Traverses the object tree and invokes the render methods. */
59 void renderItem(CairoRenderContext *ctx, SPItem *item);59 void renderItem(CairoRenderContext *ctx, SPItem *item);
60
61 /** If _omitText is true, no text will be output to the PDF document.
62 The PDF will be exactly the same as if the text was written to it and then erased. */
63 bool _omitText;
64};60};
6561
66// FIXME: this should be a static method of CairoRenderer62// FIXME: this should be a static method of CairoRenderer
6763
=== modified file 'src/extension/internal/latex-text-renderer.cpp'
--- src/extension/internal/latex-text-renderer.cpp 2013-07-31 22:33:03 +0000
+++ src/extension/internal/latex-text-renderer.cpp 2013-08-30 22:23:52 +0000
@@ -9,6 +9,7 @@
9 * Miklos Erdelyi <erdelyim@gmail.com>9 * Miklos Erdelyi <erdelyim@gmail.com>
10 * Jon A. Cruz <jon@joncruz.org>10 * Jon A. Cruz <jon@joncruz.org>
11 * Abhishek Sharma11 * Abhishek Sharma
12 * David R. Bild <drbild@umich.edu>
12 *13 *
13 * Copyright (C) 2006-2011 Authors14 * Copyright (C) 2006-2011 Authors
14 *15 *
@@ -98,7 +99,9 @@
98LaTeXTextRenderer::LaTeXTextRenderer(bool pdflatex)99LaTeXTextRenderer::LaTeXTextRenderer(bool pdflatex)
99 : _stream(NULL),100 : _stream(NULL),
100 _filename(NULL),101 _filename(NULL),
101 _pdflatex(pdflatex)102 _pdflatex(pdflatex),
103 _omittext_state(EMPTY),
104 _omittext_page(1)
102{105{
103 push_transform(Geom::identity());106 push_transform(Geom::identity());
104}107}
@@ -262,6 +265,11 @@
262void265void
263LaTeXTextRenderer::sp_text_render(SPItem *item)266LaTeXTextRenderer::sp_text_render(SPItem *item)
264{267{
268 // Only PDFLaTeX supports importing a single page of a graphics file,
269 // so only PDF backend gets interleaved text/graphics
270 if (_pdflatex && _omittext_state == GRAPHIC_ON_TOP)
271 _omittext_state = NEW_PAGE_ON_GRAPHIC;
272
265 SPText *textobj = SP_TEXT (item);273 SPText *textobj = SP_TEXT (item);
266 SPStyle *style = item->style;274 SPStyle *style = item->style;
267275
@@ -395,6 +403,11 @@
395Flowing in rectangle is possible, not in arb shape.403Flowing in rectangle is possible, not in arb shape.
396*/404*/
397405
406 // Only PDFLaTeX supports importing a single page of a graphics file,
407 // so only PDF backend gets interleaved text/graphics
408 if (_pdflatex && _omittext_state == GRAPHIC_ON_TOP)
409 _omittext_state = NEW_PAGE_ON_GRAPHIC;
410
398 SPFlowtext *flowtext = SP_FLOWTEXT(item);411 SPFlowtext *flowtext = SP_FLOWTEXT(item);
399 SPStyle *style = item->style;412 SPStyle *style = item->style;
400413
@@ -556,8 +569,13 @@
556 return sp_text_render(item);569 return sp_text_render(item);
557 } else if (SP_IS_FLOWTEXT(item)) {570 } else if (SP_IS_FLOWTEXT(item)) {
558 return sp_flowtext_render(item);571 return sp_flowtext_render(item);
572 } else {
573 // Only PDFLaTeX supports importing a single page of a graphics file,
574 // so only PDF backend gets interleaved text/graphics
575 if (_pdflatex && (_omittext_state == EMPTY || _omittext_state == NEW_PAGE_ON_GRAPHIC))
576 writeGraphicPage();
577 _omittext_state = GRAPHIC_ON_TOP;
559 }578 }
560 // We are not interested in writing the other SPItem types to LaTeX
561}579}
562580
563void581void
@@ -568,6 +586,20 @@
568 pop_transform();586 pop_transform();
569}587}
570588
589void
590LaTeXTextRenderer::writeGraphicPage(void) {
591 Inkscape::SVGOStringStream os;
592 os.setf(std::ios::fixed); // no scientific notation
593
594 // strip pathname, as it is probably desired. Having a specific path in the TeX file is not convenient.
595 if (_pdflatex)
596 os << " \\put(0,0){\\includegraphics[width=\\unitlength,page=" << _omittext_page++ << "]{" << _filename << "}}%\n";
597 else
598 os << " \\put(0,0){\\includegraphics[width=\\unitlength]{" << _filename << "}}%\n";
599
600 fprintf(_stream, "%s", os.str().c_str());
601}
602
571bool603bool
572LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, float bleedmargin_px, SPItem *base)604LaTeXTextRenderer::setupDocument(SPDocument *doc, bool pageBoundingBox, float bleedmargin_px, SPItem *base)
573{605{
@@ -625,11 +657,12 @@
625 os << " \\makeatother%\n";657 os << " \\makeatother%\n";
626658
627 os << " \\begin{picture}(" << _width << "," << _height << ")%\n";659 os << " \\begin{picture}(" << _width << "," << _height << ")%\n";
628 // strip pathname, as it is probably desired. Having a specific path in the TeX file is not convenient.
629 os << " \\put(0,0){\\includegraphics[width=\\unitlength]{" << _filename << "}}%\n";
630660
631 fprintf(_stream, "%s", os.str().c_str());661 fprintf(_stream, "%s", os.str().c_str());
632662
663 if (!_pdflatex)
664 writeGraphicPage();
665
633 return true;666 return true;
634}667}
635668
636669
=== modified file 'src/extension/internal/latex-text-renderer.h'
--- src/extension/internal/latex-text-renderer.h 2012-10-28 14:10:22 +0000
+++ src/extension/internal/latex-text-renderer.h 2013-08-30 22:23:52 +0000
@@ -47,11 +47,20 @@
47 void renderItem(SPItem *item);47 void renderItem(SPItem *item);
4848
49protected:49protected:
50 enum LaTeXOmitTextPageState {
51 EMPTY,
52 GRAPHIC_ON_TOP,
53 NEW_PAGE_ON_GRAPHIC
54 };
55
50 FILE * _stream;56 FILE * _stream;
51 gchar * _filename;57 gchar * _filename;
5258
53 bool _pdflatex; /** true if ouputting for pdfLaTeX*/59 bool _pdflatex; /** true if ouputting for pdfLaTeX*/
5460
61 LaTeXOmitTextPageState _omittext_state;
62 gulong _omittext_page;
63
55 void push_transform(Geom::Affine const &transform);64 void push_transform(Geom::Affine const &transform);
56 Geom::Affine const & transform();65 Geom::Affine const & transform();
57 void pop_transform();66 void pop_transform();
@@ -60,6 +69,8 @@
60 void writePreamble();69 void writePreamble();
61 void writePostamble();70 void writePostamble();
6271
72 void writeGraphicPage();
73
63 void sp_item_invoke_render(SPItem *item);74 void sp_item_invoke_render(SPItem *item);
64 void sp_root_render(SPRoot *item);75 void sp_root_render(SPRoot *item);
65 void sp_group_render(SPItem *item);76 void sp_group_render(SPItem *item);