26#if defined (HAVE_CONFIG_H)
34#include "builtin-defun-decls.h"
49 return (
'"' + str +
'"');
57 : m_fontsize (10.0), m_fontname (
"cmr"), m_tmp_dir (),
58 m_color (
dim_vector (1, 3), 0), m_latex_binary (
"latex"),
59 m_dvipng_binary (
"dvipng"), m_dvisvg_binary (
"dvisvgm"),
60 m_debug (false), m_testing (true)
62 std::string bin = sys::env::getenv (
"OCTAVE_LATEX_BINARY");
66 bin = sys::env::getenv (
"OCTAVE_DVIPNG_BINARY");
70 bin = sys::env::getenv (
"OCTAVE_DVISVG_BINARY");
74 m_debug = ! sys::env::getenv (
"OCTAVE_LATEX_DEBUG").empty ();
76 if (! sys::env::getenv (
"OCTAVE_LATEX_DEBUG_FLAG").empty ())
80 static bool warned =
false;
83 warning (
"The environment variable OCTAVE_LATEX_DEBUG_FLAG is deprecated and will be removed from a future version of Octave, please use OCTAVE_LATEX_DEBUG instead\n");
89 OCTAVE_DISABLE_COPY_MOVE (latex_renderer)
93 if (! m_tmp_dir.empty () && ! m_debug)
94 sys::recursive_rmdir (m_tmp_dir);
97 void set_font (
const std::string& ,
const std::string& ,
98 const std::string& ,
double size)
107 m_color(0) =
static_cast<uint8_t
> (c (0) * 255);
108 m_color(1) =
static_cast<uint8_t
> (c (1) * 255);
109 m_color(2) =
static_cast<uint8_t
> (c (2) * 255);
115 return Matrix (1, 2, 0.0);
130 std::list<text_renderer::string>& lst,
131 Matrix& bbox,
int halign,
int valign,
double rotation,
140 str.set_color (m_color);
142 gh_manager& gh_mgr = octave::__get_gh_manager__ ();
146 str.set_svg_element (ldata.second);
152 Matrix& bbox,
int halign,
int valign,
double rotation,
154 bool handle_rotation);
164 std::string key (
const std::string& txt,
int halign)
167 + std::to_string (m_fontsize) +
":"
168 + std::to_string (halign) +
":"
169 + std::to_string (m_color(0)) +
":"
170 + std::to_string (m_color(1)) +
":"
171 + std::to_string (m_color(2)));
174 void warn_helper (std::string caller, std::string txt, std::string cmd,
177 uint8NDArray render (
const std::string& txt,
int halign = 0);
179 bool read_image (
const std::string& png_file,
uint8NDArray& data)
const;
181 std::string write_tex_file (
const std::string& txt,
int halign);
185 std::string m_fontname;
186 std::string m_tmp_dir;
188 std::string m_latex_binary;
189 std::string m_dvipng_binary;
190 std::string m_dvisvg_binary;
200 static bool tested =
false;
202 static bool isok =
false;
215 "latex_renderer: a run-time test failed and the 'latex' interpreter has been disabled.");
224latex_renderer::write_tex_file (
const std::string& txt,
int halign)
226 if (m_tmp_dir.empty ())
229#if defined (OCTAVE_USE_WINDOWS_API)
230 static std::string base_tmp_dir;
232 if (base_tmp_dir.empty ())
234 base_tmp_dir = sys::env::get_temp_directory ();
239 if (base_tmp_dir.find (
'~') != std::string::npos)
240 base_tmp_dir = sys::canonicalize_file_name (base_tmp_dir);
243 m_tmp_dir = sys::tempnam (base_tmp_dir,
"latex");
245 m_tmp_dir = sys::tempnam (
"",
"latex");
248 if (sys::mkdir (m_tmp_dir, 0700) != 0)
251 "latex_renderer: unable to create temp directory");
252 return std::string ();
256 std::string base_file_name
257 = sys::file_ops::concat (m_tmp_dir,
"default");
261 std::string latex_txt (txt);
266 pos = txt.find_first_of (
"\n", pos);
268 if (pos == std::string::npos)
271 latex_txt.replace (pos, 1,
"\n\n");
276 std::string
env (
"flushleft");
279 else if (halign == 2)
282 latex_txt = std::string (
"\\begin{" ) +
env +
"}\n"
284 +
"\\end{" +
env +
"}\n";
288 file.open (base_file_name +
".tex");
289 file <<
"\\documentclass[10pt, varwidth]{standalone}\n"
290 <<
"\\usepackage{amsmath}\n"
291 <<
"\\usepackage[utf8]{inputenc}\n"
292 <<
"\\begin{document}\n"
294 <<
"\\end{document}";
297 return base_file_name;
301latex_renderer::read_image (
const std::string& png_file,
315 = retval(0).xscalar_map_value (
"latex_renderer::read_image: "
316 "Wrong type for info");
328 alpha = retval(2).xuint8_array_value (
"latex_renderer::read_image: "
329 "Wrong type for alpha");
334 "latex_renderer:: failed to read png data. %s",
335 ee.message ().c_str ());
345 static_cast<uint8_t
> (0));
347 for (
int i = 0; i < height; i++)
349 for (
int j = 0; j < width; j++)
351 data(0, j, i) = m_color(0);
352 data(1, j, i) = m_color(1);
353 data(2, j, i) = m_color(2);
354 data(3, j, i) = alpha(height-i-1, j);
362latex_renderer::warn_helper (std::string caller, std::string txt,
365 if (m_testing && ! m_debug)
370 "latex_renderer: unable to compile \"%s\"",
374 "latex_renderer: %s failed for string \"%s\"\n\
375* Command:\n\t%s\n\n* Error:\n%s\n\n* Stdout:\n%s",
376 caller.c_str (), txt.c_str (), cmd.c_str (),
382latex_renderer::render (
const std::string& txt,
int halign)
385 gh_manager& gh_mgr = octave::__get_gh_manager__ ();
389 if (! ldata.first.isempty ())
395 std::string base_file_name = write_tex_file (txt, halign);
397 if (base_file_name.empty ())
401 std::string tex_file =
quote_string (base_file_name +
".tex");
402 std::string dvi_file =
quote_string (base_file_name +
".dvi");
403 std::string log_file =
quote_string (base_file_name +
".log");
406 std::string cmd = (m_latex_binary +
" -interaction=nonstopmode "
410#if defined (OCTAVE_USE_WINDOWS_API)
418 warn_helper (
"latex", txt, cmd, result);
422 write_tex_file (
"?", halign);
432 double size_factor = m_fontsize / 10.0;
437 std::string svg_file = base_file_name +
".svg";
439 cmd = (m_dvisvg_binary +
" -n "
440 +
"-TS" + std::to_string (size_factor) +
" "
444#if defined (OCTAVE_USE_WINDOWS_API)
452 warn_helper (
"dvisvg", txt, cmd, result);
456 std::ifstream svg_stream (svg_file);
457 std::string svg_string;
458 svg_string.assign (std::istreambuf_iterator<char> (svg_stream),
459 std::istreambuf_iterator<char> ());
463 std::string png_file = base_file_name +
".png";
465 cmd = (m_dvipng_binary +
" " + dvi_file +
" "
467 +
"-bg Transparent -D "
468 + std::to_string (std::floor (72.0 * size_factor)));
470#if defined (OCTAVE_USE_WINDOWS_API)
478 warn_helper (
"dvipng", txt, cmd, result);
482 if (! read_image (png_file, data))
487 ldata.second = svg_string;
492 std::cout <<
"* Caching " << key (txt, halign) << std::endl;
498latex_renderer::text_to_pixels (
const std::string& txt,
uint8NDArray& pixels,
499 Matrix& bbox,
int halign,
int valign,
502 bool handle_rotation)
507 bbox =
Matrix (1, 4, 0.0);
512 pixels = render (txt, halign);
520 bbox =
Matrix (1, 4, 0.0);
521 bbox (2) = pixels.
dim2 ();
522 bbox (3) = pixels.
dim3 ();
525 int rot_mode = rotation_to_mode (rotation);
528 rotate_pixels (pixels, rot_mode);
532 fix_bbox_anchor (bbox, halign, valign, rot_mode, handle_rotation);
538 latex_renderer *renderer =
new latex_renderer ();
543OCTAVE_END_NAMESPACE(octave)
octave_value_list F__magick_ping__(const octave_value_list &args, int)
octave_value_list F__magick_read__(const octave_value_list &args, int nargout)
octave_idx_type dim3() const
Size of the specified dimension.
int ndims() const
Size of the specified dimension.
octave_idx_type dim2() const
bool isempty() const
Size of the specified dimension.
octave_idx_type numel() const
Number of elements in the array.
Matrix extract_n(octave_idx_type r1, octave_idx_type c1, octave_idx_type nr, octave_idx_type nc) const
virtual Matrix get_extent(text_element *elt, double rotation)=0
virtual void text_to_pixels(const std::string &txt, uint8NDArray &pxls, Matrix &bbox, int halign, int valign, double rotation, const caseless_str &interpreter, bool handle_rotation)=0
virtual void text_to_strlist(const std::string &txt, std::list< text_renderer::string > &lst, Matrix &box, int halign, int valign, double rotation, const caseless_str &interpreter="tex")=0
virtual void set_color(const Matrix &c)=0
virtual void set_anti_aliasing(bool val)=0
virtual octave_map get_system_fonts()=0
virtual void set_font(const std::string &name, const std::string &weight, const std::string &angle, double size)=0
Vector representing the dimensions (size) of an Array.
latex_data get_latex_data(const std::string &key) const
std::pair< uint8NDArray, std::string > latex_data
void set_latex_data(const std::string &key, latex_data val)
void recover_from_exception()
void setfield(const std::string &key, const octave_value &val)
octave_value getfield(const std::string &key) const
int int_value(bool req_int=false, bool frc_str_conv=false) const
std::string stdout_output() const
std::string err_msg() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void warning(const char *fmt,...)
void warning_with_id(const char *id, const char *fmt,...)
interpreter & __get_interpreter__()
base_text_renderer * make_latex_text_renderer()
std::string quote_string(std::string str)
process_execution_result run_command_and_return_output(const std::string &cmd_str)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
intNDArray< octave_uint8 > uint8NDArray