Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
latex-text-renderer.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
7/*
8 * Authors:
9 * Johan Engelen <goejendaagh@zonnet.nl>
10 * Miklos Erdelyi <erdelyim@gmail.com>
11 * Jon A. Cruz <jon@joncruz.org>
12 * Abhishek Sharma
13 *
14 * Copyright (C) 2006-2011 Authors
15 *
16 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
17 */
18
19#include "latex-text-renderer.h"
20
21#include <csignal>
22#include <cerrno>
23
24#include <glibmm/i18n.h>
25#include <glibmm/regex.h>
26
28#include <2geom/transforms.h>
29#include <2geom/rect.h>
30
31#include "colors/color.h"
32#include "colors/manager.h"
33#include "object/sp-item.h"
35#include "object/sp-root.h"
36#include "object/sp-use.h"
37#include "object/sp-text.h"
38#include "object/sp-flowtext.h"
39#include "object/sp-rect.h"
40#include "style.h"
41
42#include "text-editing.h"
43
44#include "util/units.h"
45
46#include "extension/output.h"
47#include "extension/system.h"
48
49#include "inkscape-version.h"
50#include "io/sys.h"
51#include "document.h"
52
53namespace Inkscape {
54namespace Extension {
55namespace Internal {
56
61bool
63 bool pdflatex)
64{
65 doc->ensureUpToDate();
66
67 SPRoot *root = doc->getRoot();
68 if (!root)
69 return false;
70
71 LaTeXTextRenderer renderer = LaTeXTextRenderer(pdflatex);
72
73 if (renderer.setTargetFile(filename) && renderer.setupDocument(doc, root)) {
74 renderer.renderItem(root);
75 return true;
76 }
77 return false;
78}
79
81 : _stream(nullptr),
82 _filename(nullptr),
83 _pdflatex(pdflatex),
84 _omittext_state(EMPTY),
85 _omittext_page(1)
86{
88}
89
91{
92 if (_stream) {
94
95 fclose(_stream);
96 }
97
98 if (_filename) {
99 g_free(_filename);
100 }
101}
102
106bool
107LaTeXTextRenderer::setTargetFile(gchar const *filename) {
108 if (filename != nullptr) {
109 while (isspace(*filename)) filename += 1;
110
111 _filename = g_path_get_basename(filename);
112
113 gchar *filename_ext = g_strdup_printf("%s_tex", filename);
114 Inkscape::IO::dump_fopen_call(filename_ext, "K");
115 FILE *osf = Inkscape::IO::fopen_utf8name(filename_ext, "w+");
116 if (!osf) {
117 fprintf(stderr, "inkscape: fopen(%s): %s\n", filename_ext, strerror(errno));
118 g_free(filename_ext);
119 return false;
120 }
121 _stream = osf;
122 g_free(filename_ext);
123 }
124
125 fprintf(_stream, "%%%% Creator: Inkscape %s, www.inkscape.org\n", Inkscape::version_string);
126 fprintf(_stream, "%%%% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010\n");
127 fprintf(_stream, "%%%% Accompanies image file '%s' (pdf, eps, ps)\n", _filename);
128 fprintf(_stream, "%%%%\n");
129 /* flush this to test output stream as early as possible */
130 if (fflush(_stream)) {
131 if (ferror(_stream)) {
132 g_warning("Error %d on LaTeX file output stream: %s", errno,
133 g_strerror(errno));
134 }
135 g_warning("Output to LaTeX file failed");
136 /* fixme: should use pclose() for pipes */
137 fclose(_stream);
138 _stream = nullptr;
139 fflush(stdout);
140 return false;
141 }
142
144
145 return true;
146}
147
148static char const preamble[] =
149"%% To include the image in your LaTeX document, write\n"
150"%% \\input{<filename>.pdf_tex}\n"
151"%% instead of\n"
152"%% \\includegraphics{<filename>.pdf}\n"
153"%% To scale the image, write\n"
154"%% \\def\\svgwidth{<desired width>}\n"
155"%% \\input{<filename>.pdf_tex}\n"
156"%% instead of\n"
157"%% \\includegraphics[width=<desired width>]{<filename>.pdf}\n"
158"%%\n"
159"%% Images with a different path to the parent latex file can\n"
160"%% be accessed with the `import' package (which may need to be\n"
161"%% installed) using\n"
162"%% \\usepackage{import}\n"
163"%% in the preamble, and then including the image with\n"
164"%% \\import{<path to file>}{<filename>.pdf_tex}\n"
165"%% Alternatively, one can specify\n"
166"%% \\graphicspath{{<path to file>/}}\n"
167"%% \n"
168"%% For more information, please see info/svg-inkscape on CTAN:\n"
169"%% http://tug.ctan.org/tex-archive/info/svg-inkscape\n"
170"%%\n"
171"\\begingroup%\n"
172" \\makeatletter%\n"
173" \\providecommand\\color[2][]{%\n"
174" \\errmessage{(Inkscape) Color is used for the text in Inkscape, but the package \'color.sty\' is not loaded}%\n"
175" \\renewcommand\\color[2][]{}%\n"
176" }%\n"
177" \\providecommand\\transparent[1]{%\n"
178" \\errmessage{(Inkscape) Transparency is used (non-zero) for the text in Inkscape, but the package \'transparent.sty\' is not loaded}%\n"
179" \\renewcommand\\transparent[1]{}%\n"
180" }%\n"
181" \\providecommand\\rotatebox[2]{#2}%\n"
182" \\newcommand*\\fsize{\\dimexpr\\f@size pt\\relax}%\n"
183" \\newcommand*\\lineheight[1]{\\fontsize{\\fsize}{#1\\fsize}\\selectfont}%\n";
184
185static char const postamble[] =
186" \\end{picture}%\n"
187"\\endgroup%\n";
188
189void
191{
192 fprintf(_stream, "%s", preamble);
193}
194void
196{
197 fprintf(_stream, "%s", postamble);
198}
199
201{
202 std::vector<SPObject*> l = (group->childList(false));
203 for(auto x : l){
204 auto item = cast<SPItem>(x);
205 if (item) {
207 }
208 }
209}
210
212{
213 bool translated = false;
214
215 if ((use->x._set && use->x.computed != 0) || (use->y._set && use->y.computed != 0)) {
217 push_transform(tp);
218 translated = true;
219 }
220
221 auto childItem = use->child;
222 if (childItem) {
223 renderItem(childItem);
224 }
225
226 if (translated) {
228 }
229}
230
232{
233 // Nothing to do here... (so don't emit an empty box)
234 // Also avoids falling out of sync with the CairoRenderer (which won't render anything in this case either)
235 if (textobj->layout.getActualLength() == 0)
236 return;
237
238 // Only PDFLaTeX supports importing a single page of a graphics file,
239 // so only PDF backend gets interleaved text/graphics
242
243 SPStyle *style = textobj->style;
244
245 // get position and alignment
246 // Align vertically on the baseline of the font (retrieved from the anchor point)
247 // Align horizontally on anchorpoint
248 gchar const *alignment = nullptr;
249 gchar const *aligntabular = nullptr;
250 switch (style->text_anchor.computed) {
252 alignment = "[lt]";
253 aligntabular = "{l}";
254 break;
256 alignment = "[rt]";
257 aligntabular = "{r}";
258 break;
260 default:
261 alignment = "[t]";
262 aligntabular = "{c}";
263 break;
264 }
265
266 Geom::Point anchor;
267 const auto baseline_anchor_point = textobj->layout.baselineAnchorPoint();
268 if (baseline_anchor_point) {
269 anchor = (*baseline_anchor_point) * transform();
270 } else {
271 g_warning("LaTeXTextRenderer::sp_text_render: baselineAnchorPoint unset, text position will be wrong. Please report the issue.");
272 }
273
274 Inkscape::Colors::Color color(0x0);
275 if (style->fill.set && style->fill.isColor()) {
276 color = style->fill.getColor();
277 color.addOpacity(style->fill_opacity);
278 } else if (style->stroke.set && style->stroke.isColor()) {
279 color = style->stroke.getColor();
280 color.addOpacity(style->stroke_opacity);
281 }
282 color.addOpacity(style->opacity);
283
284 // get rotation
285 Geom::Affine i2doc = textobj->i2doc_affine();
286 Geom::Affine wotransl = i2doc.withoutTranslation();
287 double degrees = -180/M_PI * Geom::atan2(wotransl.xAxis());
288 bool has_rotation = !Geom::are_near(degrees,0.);
289
290 // get line-height
291 float line_height;
292 if (style->line_height.unit == SP_CSS_UNIT_NONE) {
293 // unitless 'line-height' (use as-is, computed value is relative value)
294 line_height = style->line_height.computed;
295 } else {
296 // 'line-height' with unit (make relative, computed value is absolute value)
297 line_height = style->line_height.computed / style->font_size.computed;
298 }
299
300 // write to LaTeX
302 os.setf(std::ios::fixed); // don't use scientific notation
303
304 os << " \\put(" << anchor[Geom::X] << "," << anchor[Geom::Y] << "){";
306 os << "\\color[rgb]{" << color[0] << "," << color[1] << "," << color[2] << "}";
307 if (_pdflatex && color.getOpacity() < 1.0) {
308 os << "\\transparent{" << color.getOpacity() << "}";
309 }
310 if (has_rotation) {
311 os << "\\rotatebox{" << degrees << "}{";
312 }
313 os << "\\makebox(0,0)" << alignment << "{";
314 if (line_height != 1) {
315 os << "\\lineheight{" << line_height << "}";
316 }
317 os << "\\smash{";
318 os << "\\begin{tabular}[t]" << aligntabular;
319
320 // Walk through all spans in the text object.
321 // Write span strings to LaTeX, associated with font weight and style.
322 Inkscape::Text::Layout const &layout = *(te_get_layout (textobj));
323 for (Inkscape::Text::Layout::iterator li = layout.begin(), le = layout.end();
324 li != le; li.nextStartOfSpan())
325 {
327 ln.nextStartOfSpan();
328 Glib::ustring uspanstr = sp_te_get_string_multiline (textobj, li, ln);
329
330 // escape ampersands
331 uspanstr = Glib::Regex::create("&")->replace_literal(uspanstr, 0, "\\&", (Glib::Regex::MatchFlags)0);
332 // escape percent
333 uspanstr = Glib::Regex::create("%")->replace_literal(uspanstr, 0, "\\%", (Glib::Regex::MatchFlags)0);
334
335 const gchar *spanstr = uspanstr.c_str();
336 if (!spanstr) {
337 continue;
338 }
339
340 bool is_bold = false, is_italic = false, is_oblique = false, is_superscript = false, is_subscript = false;
341
342 // newline character only -> don't attempt to add style (will break compilation in LaTeX)
343 if (g_strcmp0(spanstr, "\n")) {
344 SPStyle const &spanstyle = *(sp_te_style_at_position (textobj, li));
345 if (spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_500 ||
346 spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_600 ||
347 spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_700 ||
348 spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_800 ||
349 spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_900 ||
350 spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLD ||
351 spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLDER)
352 {
353 is_bold = true;
354 os << "\\textbf{";
355 }
356 if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_ITALIC)
357 {
358 is_italic = true;
359 os << "\\textit{";
360 }
361 if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_OBLIQUE)
362 {
363 is_oblique = true;
364 os << "\\textsl{"; // this is an accurate choice if the LaTeX chosen font matches the font in Inkscape. Gives bad results when it is not so...
365 }
366 if (spanstyle.baseline_shift.computed > 0) { // superscript
367 is_superscript = true;
368 os << "\\textsuperscript{";
369 }
370 if (spanstyle.baseline_shift.computed < 0) {
371 is_subscript = true;
372 os << "\\textsubscript{";
373 }
374 }
375
376 // replace carriage return with double slash
377 gchar ** splitstr = g_strsplit(spanstr, "\n", 2);
378 os << splitstr[0];
379 if (g_strv_length(splitstr) > 1)
380 {
381 os << "\\\\";
382 }
383 g_strfreev(splitstr);
384
385 if (is_subscript) { os << "}"; } // subscript end
386 if (is_superscript) { os << "}"; } // superscript end
387 if (is_oblique) { os << "}"; } // oblique end
388 if (is_italic) { os << "}"; } // italic end
389 if (is_bold) { os << "}"; } // bold end
390 }
391
392 os << "\\end{tabular}"; // tabular end
393 os << "}"; // smash end
394 if (has_rotation) { os << "}"; } // rotatebox end
395 os << "}"; //makebox end
396 os << "}%\n"; // put end
397
398 fprintf(_stream, "%s", os.str().c_str());
399}
400
402{
403/*
404Flowtext is possible by using a minipage! :)
405Flowing in rectangle is possible, not in arb shape.
406*/
407
408 // Only PDFLaTeX supports importing a single page of a graphics file,
409 // so only PDF backend gets interleaved text/graphics
412
413 SPStyle *style = flowtext->style;
414
415 SPItem *frame_item = flowtext->get_frame(nullptr);
416 auto frame = cast<SPRect>(frame_item);
417 if (!frame_item || !frame) {
418 g_warning("LaTeX export: non-rectangular flowed text shapes are not supported, skipping text.");
419 return; // don't know how to handle non-rect frames yet. is quite uncommon for latex users i think
420 }
421
422 // We will transform the coordinates
423 Geom::Rect framebox = frame->getRect();
424
425 // get position and alignment
426 // Align on topleft corner.
427 gchar const *alignment = "[lt]";
428 gchar const *justification = "";
429 switch (flowtext->layout.paragraphAlignment(flowtext->layout.begin())) {
431 justification = "\\raggedright ";
432 break;
434 justification = "\\raggedleft ";
435 break;
437 justification = "\\centering ";
439 default:
440 // no need to add LaTeX code for standard justified output :)
441 break;
442 }
443
444 // The topleft Corner was calculated after rotating the text which results in a wrong Coordinate.
445 // Now, the topleft Corner is rotated after calculating it
446 Geom::Point pos(framebox.corner(0) * transform()); //topleft corner
447
448 // determine color and transparency (for now, use rgb color model as it is most native to Inkscape)
449 bool has_color = false; // if the item has no color set, don't force black color
450 bool has_transparency = false;
451 // TODO: how to handle ICC colors?
452 // give priority to fill color
453 guint32 rgba = 0;
454 float opacity = SP_SCALE24_TO_FLOAT(style->opacity.value);
455 if (style->fill.set && style->fill.isColor()) {
456 has_color = true;
457 rgba = style->fill.getColor().toRGBA();
458 opacity *= SP_SCALE24_TO_FLOAT(style->fill_opacity.value);
459 } else if (style->stroke.set && style->stroke.isColor()) {
460 has_color = true;
461 rgba = style->stroke.getColor().toRGBA();
462 opacity *= SP_SCALE24_TO_FLOAT(style->stroke_opacity.value);
463 }
464 if (opacity < 1.0) {
465 has_transparency = true;
466 }
467
468 // get rotation
469 Geom::Affine i2doc = flowtext->i2doc_affine();
470 Geom::Affine wotransl = i2doc.withoutTranslation();
471 double degrees = -180/M_PI * Geom::atan2(wotransl.xAxis());
472 bool has_rotation = !Geom::are_near(degrees,0.);
473
474 // write to LaTeX
476 os.setf(std::ios::fixed); // don't use scientific notation
477
478 os << " \\put(" << pos[Geom::X] << "," << pos[Geom::Y] << "){";
479 if (has_color) {
480 os << "\\color[rgb]{" << SP_RGBA32_R_F(rgba) << "," << SP_RGBA32_G_F(rgba) << "," << SP_RGBA32_B_F(rgba) << "}";
481 }
482 if (_pdflatex && has_transparency) {
483 os << "\\transparent{" << opacity << "}";
484 }
485 if (has_rotation) {
486 os << "\\rotatebox{" << degrees << "}{";
487 }
488 os << "\\makebox(0,0)" << alignment << "{";
489
490 // Scale the x width correctly
491 os << "\\begin{minipage}{" << framebox.width() * transform().expansionX() << "\\unitlength}";
492 os << justification;
493
494 // Walk through all spans in the text object.
495 // Write span strings to LaTeX, associated with font weight and style.
496 Inkscape::Text::Layout const &layout = *(te_get_layout(flowtext));
497 for (Inkscape::Text::Layout::iterator li = layout.begin(), le = layout.end();
498 li != le; li.nextStartOfSpan())
499 {
500 SPStyle const &spanstyle = *(sp_te_style_at_position(flowtext, li));
501 bool is_bold = false, is_italic = false, is_oblique = false, is_superscript = false, is_subscript = false;
502
503 if (spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_500 ||
504 spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_600 ||
505 spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_700 ||
506 spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_800 ||
507 spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_900 ||
508 spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLD ||
509 spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLDER)
510 {
511 is_bold = true;
512 os << "\\textbf{";
513 }
514 if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_ITALIC)
515 {
516 is_italic = true;
517 os << "\\textit{";
518 }
519 if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_OBLIQUE)
520 {
521 is_oblique = true;
522 os << "\\textsl{"; // this is an accurate choice if the LaTeX chosen font matches the font in Inkscape. Gives bad results when it is not so...
523 }
524 if (spanstyle.baseline_shift.computed > 0) { // superscript
525 is_superscript = true;
526 os << "\\textsuperscript{";
527 }
528 if (spanstyle.baseline_shift.computed < 0) {
529 is_subscript = true;
530 os << "\\textsubscript{";
531 }
532
534 ln.nextStartOfSpan();
535 Glib::ustring uspanstr = sp_te_get_string_multiline(flowtext, li, ln);
536 const gchar *spanstr = uspanstr.c_str();
537 if (!spanstr) {
538 continue;
539 }
540 // replace carriage return with double slash
541 gchar ** splitstr = g_strsplit(spanstr, "\n", -1);
542 gchar *spanstr_new = g_strjoinv("\\\\ ", splitstr);
543 os << spanstr_new;
544 g_strfreev(splitstr);
545 g_free(spanstr_new);
546
547 if (is_subscript) { os << "}"; } // subscript end
548 if (is_superscript) { os << "}"; } // superscript end
549 if (is_oblique) { os << "}"; } // oblique end
550 if (is_italic) { os << "}"; } // italic end
551 if (is_bold) { os << "}"; } // bold end
552 }
553
554 os << "\\end{minipage}";
555 if (has_rotation) {
556 os << "}"; // rotatebox end
557 }
558 os << "}"; //makebox end
559 os << "}%\n"; // put end
560
561 fprintf(_stream, "%s", os.str().c_str());
562}
563
570
571void
573{
574 // Check item's visibility
575 if (item->isHidden()) {
576 return;
577 }
578
579 auto root = cast<SPRoot>(item);
580 if (root) {
581 return sp_root_render(root);
582 }
583 auto group = cast<SPGroup>(item);
584 if (group) {
585 return sp_group_render(group);
586 }
587 auto use = cast<SPUse>(item);
588 if (use) {
589 return sp_use_render(use);
590 }
591 auto text = cast<SPText>(item);
592 if (text) {
593 return sp_text_render(text);
594 }
595 auto flowtext = cast<SPFlowtext>(item);
596 if (flowtext) {
597 return sp_flowtext_render(flowtext);
598 }
599 // Only PDFLaTeX supports importing a single page of a graphics file,
600 // so only PDF backend gets interleaved text/graphics
603 }
605}
606
607void
614
615void
618 os.setf(std::ios::fixed); // no scientific notation
619
620 // strip pathname, as it is probably desired. Having a specific path in the TeX file is not convenient.
621 if (_pdflatex)
622 os << " \\put(0,0){\\includegraphics[width=\\unitlength,page=" << _omittext_page++ << "]{" << _filename << "}}%\n";
623 else
624 os << " \\put(0,0){\\includegraphics[width=\\unitlength]{" << _filename << "}}%\n";
625
626 fprintf(_stream, "%s", os.str().c_str());
627}
628
629bool
631{
632 if (!base) {
633 base = doc->getRoot();
634 }
635
637
638 // scale all coordinates, such that the width of the image is 1, this is convenient for scaling the image in LaTeX
639 double scale = 1/(d.width());
640 double _width = d.width() * scale;
641 double _height = d.height() * scale;
643
644 // write the info to LaTeX
646 os.setf(std::ios::fixed); // no scientific notation
647
648 // scaling of the image when including it in LaTeX
649 os << " \\ifx\\svgwidth\\undefined%\n";
650 os << " \\setlength{\\unitlength}{" << Inkscape::Util::Quantity::convert(d.width(), "px", "pt") << "bp}%\n"; // note: 'bp' is the Postscript pt unit in LaTeX, see LP bug #792384
651 os << " \\ifx\\svgscale\\undefined%\n";
652 os << " \\relax%\n";
653 os << " \\else%\n";
654 os << " \\setlength{\\unitlength}{\\unitlength * \\real{\\svgscale}}%\n";
655 os << " \\fi%\n";
656 os << " \\else%\n";
657 os << " \\setlength{\\unitlength}{\\svgwidth}%\n";
658 os << " \\fi%\n";
659 os << " \\global\\let\\svgwidth\\undefined%\n";
660 os << " \\global\\let\\svgscale\\undefined%\n";
661 os << " \\makeatother%\n";
662
663 os << " \\begin{picture}(" << _width << "," << _height << ")%\n";
664
665 // set \baselineskip equal to fontsize (the closest we can seem to get to CSS "line-height: 1;")
666 // and remove column spacing from tabular
667 os << " \\lineheight{1}%\n";
668 os << " \\setlength\\tabcolsep{0pt}%\n";
669
670 fprintf(_stream, "%s", os.str().c_str());
671
672 if (!_pdflatex)
674
675 return true;
676}
677
678Geom::Affine const &
680{
681 return _transform_stack.top();
682}
683
684void
686{
687 if(!_transform_stack.empty()){
688 Geom::Affine tr_top = _transform_stack.top();
689 _transform_stack.push(tr * tr_top);
690 } else {
691 _transform_stack.push(tr);
692 }
693}
694
695void
700
701} /* namespace Internal */
702} /* namespace Extension */
703} /* namespace Inkscape */
704
705/*
706 Local Variables:
707 mode:c++
708 c-file-style:"stroustrup"
709 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
710 indent-tabs-mode:nil
711 fill-column:99
712 End:
713*/
714// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
double scale
Definition aa.cpp:228
3x3 matrix representing an affine transformation.
Definition affine.h:70
Coord expansionX() const
Calculates the amount of x-scaling imparted by the Affine.
Definition affine.cpp:64
Point xAxis() const
Definition affine.cpp:32
Affine withoutTranslation() const
Definition affine.h:169
static CRect from_xywh(Coord x, Coord y, Coord w, Coord h)
Create rectangle from origin and dimensions.
C height() const
Get the vertical extent of the rectangle.
C width() const
Get the horizontal extent of the rectangle.
CPoint corner(unsigned i) const
Return the n-th corner of the rectangle.
Two-dimensional point that doubles as a vector.
Definition point.h:66
Axis aligned, non-empty rectangle.
Definition rect.h:92
Scaling from the origin.
Definition transforms.h:150
Translation by a vector.
Definition transforms.h:115
bool convert(Color const &other)
Convert to the same format as the other color.
Definition color.cpp:145
bool addOpacity(double opacity=1.0)
Definition color.h:56
double getOpacity() const
Get the opacity in this color, if it's stored.
Definition color.cpp:407
bool setupDocument(SPDocument *doc, SPItem *base)
Initializes the LaTeXTextRenderer according to the specified SPDocument.
bool setTargetFile(gchar const *filename)
This should create the output LaTeX file, and assign it to _stream.
void renderItem(SPItem *item)
Traverses the object tree and invokes the render methods.
LaTeXOmitTextPageState _omittext_state
true if outputting for pdfLaTeX
void push_transform(Geom::Affine const &transform)
std::string str() const
std::ios::fmtflags setf(std::ios::fmtflags fmtfl)
Holds a position within the glyph output of Layout.
Definition Layout-TNG.h:973
Generates the layout for either wrapped or non-wrapped text and stores the result.
Definition Layout-TNG.h:144
std::optional< Geom::Point > baselineAnchorPoint() const
For left aligned text, the leftmost end of the baseline For rightmost text, the rightmost....
iterator end() const
Returns an iterator pointing just past the end of the last glyph, which is also just past the end of ...
double getActualLength() const
Get actual length of layout, by summing span lengths.
Alignment paragraphAlignment(iterator const &it) const
Returns the actual alignment used for the paragraph containing the character pointed to by it.
iterator begin() const
Returns an iterator pointing at the first glyph of the flowed output.
static double convert(double from_dist, Unit const *from, Unit const *to)
Convert distances.
Definition units.cpp:525
SVGLength y
SVGLength x
Typed SVG document implementation.
Definition document.h:103
SPRoot * getRoot()
Returns our SPRoot.
Definition document.h:202
Geom::Point getDimensions() const
Definition document.cpp:973
int ensureUpToDate(unsigned int object_modified_tag=0)
Repeatedly works on getting the document updated, since sometimes it takes more than one pass to get ...
Inkscape::Text::Layout layout
Definition sp-flowtext.h:56
SPItem * get_frame(SPItem const *after)
Base class for visual SVG elements.
Definition sp-item.h:109
bool isHidden() const
Definition sp-item.cpp:235
Geom::Affine transform
Definition sp-item.h:138
Geom::Affine i2doc_affine() const
Returns the accumulated transformation of the item and all its ancestors, including root's viewport.
Definition sp-item.cpp:1816
std::vector< SPObject * > childList(bool add_ref, Action action=ActionGeneral)
Retrieves the children as a std vector object, optionally ref'ing the children in the process,...
SPStyle * style
Represents the style properties, whether from presentation attributes, the style attribute,...
Definition sp-object.h:248
<svg> element
Definition sp-root.h:33
An SVG style object.
Definition style.h:45
T< SPAttr::FONT_WEIGHT, SPIEnum< SPCSSFontWeight > > font_weight
Weight of the font.
Definition style.h:112
T< SPAttr::FILL, SPIPaint > fill
fill
Definition style.h:240
T< SPAttr::STROKE, SPIPaint > stroke
stroke
Definition style.h:247
T< SPAttr::LINE_HEIGHT, SPILengthOrNormal > line_height
Line height (css2 10.8.1)
Definition style.h:118
T< SPAttr::FILL_OPACITY, SPIScale24 > fill_opacity
fill-opacity
Definition style.h:242
T< SPAttr::FONT_STYLE, SPIEnum< SPCSSFontStyle > > font_style
Font style.
Definition style.h:108
T< SPAttr::STROKE_OPACITY, SPIScale24 > stroke_opacity
stroke-opacity
Definition style.h:261
T< SPAttr::TEXT_ANCHOR, SPIEnum< SPTextAnchor > > text_anchor
Anchor of the text (svg1.1 10.9.1)
Definition style.h:173
T< SPAttr::OPACITY, SPIScale24 > opacity
opacity
Definition style.h:216
T< SPAttr::FONT_SIZE, SPIFontSize > font_size
Size of the font.
Definition style.h:116
T< SPAttr::BASELINE_SHIFT, SPIBaselineShift > baseline_shift
Baseline shift (svg1.1 10.9.2)
Definition style.h:169
Inkscape::Text::Layout layout
Definition sp-text.h:52
Definition sp-use.h:25
SPItem * child
Definition sp-use.h:33
bool _set
Definition svg-length.h:41
float computed
Definition svg-length.h:50
constexpr double SP_RGBA32_G_F(uint32_t v)
Definition utils.h:47
constexpr double SP_RGBA32_R_F(uint32_t v)
Definition utils.h:43
constexpr double SP_RGBA32_B_F(uint32_t v)
Definition utils.h:51
RootCluster root
unsigned int guint32
@ Y
Definition coord.h:48
@ X
Definition coord.h:48
SPItem * item
Mini static library that contains the version of Inkscape.
Declaration of LaTeXTextRenderer, used for rendering the accompanying LaTeX file when exporting to PD...
double atan2(Point const &p)
Affine identity()
Create an identity matrix.
Definition affine.h:210
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
bool latex_render_document_text_to_file(SPDocument *doc, gchar const *filename, bool pdflatex)
This method is called by the PDF, EPS and PS output extensions.
void dump_fopen_call(char const *utf8name, char const *id)
Definition sys.cpp:37
FILE * fopen_utf8name(char const *utf8name, char const *mode)
Open a file with g_fopen().
Definition sys.cpp:72
Helper class to stream background task notifications as a series of messages.
char const * version_string
full version string
Axis-aligned rectangle.
TODO: insert short description here.
Some things pertinent to all visible shapes: SPItem, SPItemView, SPItemCtx.
SPRoot: SVG <svg> implementation.
@ SP_CSS_TEXT_ANCHOR_MIDDLE
@ SP_CSS_TEXT_ANCHOR_START
@ SP_CSS_TEXT_ANCHOR_END
@ SP_CSS_FONT_STYLE_OBLIQUE
Definition style-enums.h:63
@ SP_CSS_FONT_STYLE_ITALIC
Definition style-enums.h:62
@ SP_CSS_FONT_WEIGHT_BOLD
Definition style-enums.h:82
@ SP_CSS_FONT_WEIGHT_900
Definition style-enums.h:80
@ SP_CSS_FONT_WEIGHT_700
Definition style-enums.h:78
@ SP_CSS_FONT_WEIGHT_800
Definition style-enums.h:79
@ SP_CSS_FONT_WEIGHT_500
Definition style-enums.h:76
@ SP_CSS_FONT_WEIGHT_BOLDER
Definition style-enums.h:84
@ SP_CSS_FONT_WEIGHT_600
Definition style-enums.h:77
@ SP_CSS_UNIT_NONE
SPStyle - a style object for SPItem objects.
SPStyle const * sp_te_style_at_position(SPItem const *text, Inkscape::Text::Layout::iterator const &position)
Glib::ustring sp_te_get_string_multiline(SPItem const *text)
Gets a text-only representation of the given text or flowroot object, replacing line break elements w...
Inkscape::Text::Layout const * te_get_layout(SPItem const *item)
Affine transformation classes.