24#include <glibmm/i18n.h>
25#include <glibmm/regex.h>
84 _omittext_state(EMPTY),
108 if (filename !=
nullptr) {
109 while (isspace(*filename)) filename += 1;
111 _filename = g_path_get_basename(filename);
113 gchar *filename_ext = g_strdup_printf(
"%s_tex", filename);
117 fprintf(stderr,
"inkscape: fopen(%s): %s\n", filename_ext, strerror(errno));
118 g_free(filename_ext);
122 g_free(filename_ext);
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);
132 g_warning(
"Error %d on LaTeX file output stream: %s", errno,
135 g_warning(
"Output to LaTeX file failed");
149"%% To include the image in your LaTeX document, write\n"
150"%% \\input{<filename>.pdf_tex}\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"
157"%% \\includegraphics[width=<desired width>]{<filename>.pdf}\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"
168"%% For more information, please see info/svg-inkscape on CTAN:\n"
169"%% http://tug.ctan.org/tex-archive/info/svg-inkscape\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"
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"
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";
202 std::vector<SPObject*> l = (group->
childList(
false));
204 auto item = cast<SPItem>(x);
213 bool translated =
false;
221 auto childItem = use->
child;
248 gchar
const *alignment =
nullptr;
249 gchar
const *aligntabular =
nullptr;
253 aligntabular =
"{l}";
257 aligntabular =
"{r}";
262 aligntabular =
"{c}";
268 if (baseline_anchor_point) {
269 anchor = (*baseline_anchor_point) *
transform();
271 g_warning(
"LaTeXTextRenderer::sp_text_render: baselineAnchorPoint unset, text position will be wrong. Please report the issue.");
275 if (style->
fill.set && style->
fill.isColor()) {
276 color = style->
fill.getColor();
278 }
else if (style->
stroke.set && style->
stroke.isColor()) {
279 color = style->
stroke.getColor();
302 os.
setf(std::ios::fixed);
304 os <<
" \\put(" << anchor[
Geom::X] <<
"," << anchor[
Geom::Y] <<
"){";
306 os <<
"\\color[rgb]{" << color[0] <<
"," << color[1] <<
"," << color[2] <<
"}";
308 os <<
"\\transparent{" << color.
getOpacity() <<
"}";
311 os <<
"\\rotatebox{" << degrees <<
"}{";
313 os <<
"\\makebox(0,0)" << alignment <<
"{";
314 if (line_height != 1) {
315 os <<
"\\lineheight{" << line_height <<
"}";
318 os <<
"\\begin{tabular}[t]" << aligntabular;
331 uspanstr = Glib::Regex::create(
"&")->replace_literal(uspanstr, 0,
"\\&", (Glib::Regex::MatchFlags)0);
333 uspanstr = Glib::Regex::create(
"%")->replace_literal(uspanstr, 0,
"\\%", (Glib::Regex::MatchFlags)0);
335 const gchar *spanstr = uspanstr.c_str();
340 bool is_bold =
false, is_italic =
false, is_oblique =
false, is_superscript =
false, is_subscript =
false;
343 if (g_strcmp0(spanstr,
"\n")) {
367 is_superscript =
true;
368 os <<
"\\textsuperscript{";
372 os <<
"\\textsubscript{";
377 gchar ** splitstr = g_strsplit(spanstr,
"\n", 2);
379 if (g_strv_length(splitstr) > 1)
383 g_strfreev(splitstr);
385 if (is_subscript) { os <<
"}"; }
386 if (is_superscript) { os <<
"}"; }
387 if (is_oblique) { os <<
"}"; }
388 if (is_italic) { os <<
"}"; }
389 if (is_bold) { os <<
"}"; }
392 os <<
"\\end{tabular}";
394 if (has_rotation) { os <<
"}"; }
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.");
427 gchar
const *alignment =
"[lt]";
428 gchar
const *justification =
"";
431 justification =
"\\raggedright ";
434 justification =
"\\raggedleft ";
437 justification =
"\\centering ";
449 bool has_color =
false;
450 bool has_transparency =
false;
454 float opacity = SP_SCALE24_TO_FLOAT(style->
opacity.value);
455 if (style->
fill.set && style->
fill.isColor()) {
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()) {
461 rgba = style->
stroke.getColor().toRGBA();
465 has_transparency =
true;
476 os.
setf(std::ios::fixed);
483 os <<
"\\transparent{" << opacity <<
"}";
486 os <<
"\\rotatebox{" << degrees <<
"}{";
488 os <<
"\\makebox(0,0)" << alignment <<
"{";
501 bool is_bold =
false, is_italic =
false, is_oblique =
false, is_superscript =
false, is_subscript =
false;
525 is_superscript =
true;
526 os <<
"\\textsuperscript{";
530 os <<
"\\textsubscript{";
536 const gchar *spanstr = uspanstr.c_str();
541 gchar ** splitstr = g_strsplit(spanstr,
"\n", -1);
542 gchar *spanstr_new = g_strjoinv(
"\\\\ ", splitstr);
544 g_strfreev(splitstr);
547 if (is_subscript) { os <<
"}"; }
548 if (is_superscript) { os <<
"}"; }
549 if (is_oblique) { os <<
"}"; }
550 if (is_italic) { os <<
"}"; }
551 if (is_bold) { os <<
"}"; }
554 os <<
"\\end{minipage}";
583 auto group = cast<SPGroup>(
item);
587 auto use = cast<SPUse>(
item);
591 auto text = cast<SPText>(
item);
595 auto flowtext = cast<SPFlowtext>(
item);
618 os.
setf(std::ios::fixed);
622 os <<
" \\put(0,0){\\includegraphics[width=\\unitlength,page=" <<
_omittext_page++ <<
"]{" <<
_filename <<
"}}%\n";
624 os <<
" \\put(0,0){\\includegraphics[width=\\unitlength]{" <<
_filename <<
"}}%\n";
646 os.
setf(std::ios::fixed);
649 os <<
" \\ifx\\svgwidth\\undefined%\n";
651 os <<
" \\ifx\\svgscale\\undefined%\n";
654 os <<
" \\setlength{\\unitlength}{\\unitlength * \\real{\\svgscale}}%\n";
657 os <<
" \\setlength{\\unitlength}{\\svgwidth}%\n";
659 os <<
" \\global\\let\\svgwidth\\undefined%\n";
660 os <<
" \\global\\let\\svgscale\\undefined%\n";
661 os <<
" \\makeatother%\n";
663 os <<
" \\begin{picture}(" << _width <<
"," << _height <<
")%\n";
667 os <<
" \\lineheight{1}%\n";
668 os <<
" \\setlength\\tabcolsep{0pt}%\n";
3x3 matrix representing an affine transformation.
Coord expansionX() const
Calculates the amount of x-scaling imparted by the Affine.
Affine withoutTranslation() const
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.
Axis aligned, non-empty rectangle.
bool convert(Color const &other)
Convert to the same format as the other color.
bool addOpacity(double opacity=1.0)
double getOpacity() const
Get the opacity in this color, if it's stored.
std::stack< Geom::Affine > _transform_stack
Geom::Affine const & transform()
bool setupDocument(SPDocument *doc, SPItem *base)
Initializes the LaTeXTextRenderer according to the specified SPDocument.
void sp_text_render(SPText *text)
virtual ~LaTeXTextRenderer()
void sp_root_render(SPRoot *item)
bool setTargetFile(gchar const *filename)
This should create the output LaTeX file, and assign it to _stream.
void sp_use_render(SPUse *use)
void sp_group_render(SPGroup *group)
LaTeXTextRenderer(bool pdflatex)
void renderItem(SPItem *item)
Traverses the object tree and invokes the render methods.
LaTeXOmitTextPageState _omittext_state
true if outputting for pdfLaTeX
void sp_item_invoke_render(SPItem *item)
void push_transform(Geom::Affine const &transform)
void sp_flowtext_render(SPFlowtext *flowtext)
std::ios::fmtflags setf(std::ios::fmtflags fmtfl)
Holds a position within the glyph output of Layout.
Generates the layout for either wrapped or non-wrapped text and stores the result.
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.
Typed SVG document implementation.
SPRoot * getRoot()
Returns our SPRoot.
Geom::Point getDimensions() const
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
SPItem * get_frame(SPItem const *after)
Base class for visual SVG elements.
Geom::Affine i2doc_affine() const
Returns the accumulated transformation of the item and all its ancestors, including root's viewport.
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,...
T< SPAttr::FONT_WEIGHT, SPIEnum< SPCSSFontWeight > > font_weight
Weight of the font.
T< SPAttr::FILL, SPIPaint > fill
fill
T< SPAttr::STROKE, SPIPaint > stroke
stroke
T< SPAttr::LINE_HEIGHT, SPILengthOrNormal > line_height
Line height (css2 10.8.1)
T< SPAttr::FILL_OPACITY, SPIScale24 > fill_opacity
fill-opacity
T< SPAttr::FONT_STYLE, SPIEnum< SPCSSFontStyle > > font_style
Font style.
T< SPAttr::STROKE_OPACITY, SPIScale24 > stroke_opacity
stroke-opacity
T< SPAttr::TEXT_ANCHOR, SPIEnum< SPTextAnchor > > text_anchor
Anchor of the text (svg1.1 10.9.1)
T< SPAttr::OPACITY, SPIScale24 > opacity
opacity
T< SPAttr::FONT_SIZE, SPIFontSize > font_size
Size of the font.
T< SPAttr::BASELINE_SHIFT, SPIBaselineShift > baseline_shift
Baseline shift (svg1.1 10.9.2)
Inkscape::Text::Layout layout
constexpr double SP_RGBA32_G_F(uint32_t v)
constexpr double SP_RGBA32_R_F(uint32_t v)
constexpr double SP_RGBA32_B_F(uint32_t v)
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.
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.
static char const preamble[]
static char const postamble[]
void dump_fopen_call(char const *utf8name, char const *id)
FILE * fopen_utf8name(char const *utf8name, char const *mode)
Open a file with g_fopen().
Helper class to stream background task notifications as a series of messages.
char const * version_string
full version string
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_FONT_STYLE_OBLIQUE
@ SP_CSS_FONT_STYLE_ITALIC
@ SP_CSS_FONT_WEIGHT_BOLD
@ SP_CSS_FONT_WEIGHT_BOLDER
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)