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_FLAG").empty ();
77 OCTAVE_DISABLE_COPY_MOVE (latex_renderer)
81 if (! m_tmp_dir.empty () && ! m_debug)
82 sys::recursive_rmdir (m_tmp_dir);
85 void set_font (
const std::string& ,
const std::string& ,
86 const std::string& ,
double size)
95 m_color(0) =
static_cast<uint8_t
> (c (0) * 255);
96 m_color(1) =
static_cast<uint8_t
> (c (1) * 255);
97 m_color(2) =
static_cast<uint8_t
> (c (2) * 255);
103 return Matrix (1, 2, 0.0);
118 std::list<text_renderer::string>& lst,
119 Matrix& bbox,
int halign,
int valign,
double rotation,
128 str.set_color (m_color);
130 gh_manager& gh_mgr = octave::__get_gh_manager__ ();
134 str.set_svg_element (ldata.second);
140 Matrix& bbox,
int halign,
int valign,
double rotation,
142 bool handle_rotation);
152 std::string key (
const std::string& txt,
int halign)
155 + std::to_string (m_fontsize) +
":"
156 + std::to_string (halign) +
":"
157 + std::to_string (m_color(0)) +
":"
158 + std::to_string (m_color(1)) +
":"
159 + std::to_string (m_color(2)));
162 void warn_helper (std::string caller, std::string txt, std::string cmd,
165 uint8NDArray render (
const std::string& txt,
int halign = 0);
167 bool read_image (
const std::string& png_file,
uint8NDArray& data)
const;
169 std::string write_tex_file (
const std::string& txt,
int halign);
173 std::string m_fontname;
174 std::string m_tmp_dir;
176 std::string m_latex_binary;
177 std::string m_dvipng_binary;
178 std::string m_dvisvg_binary;
188 static bool tested =
false;
190 static bool isok =
false;
203 "latex_renderer: a run-time test failed and the 'latex' interpreter has been disabled.");
212latex_renderer::write_tex_file (
const std::string& txt,
int halign)
214 if (m_tmp_dir.empty ())
217#if defined (OCTAVE_USE_WINDOWS_API)
218 static std::string base_tmp_dir;
220 if (base_tmp_dir.empty ())
222 base_tmp_dir = sys::env::get_temp_directory ();
227 if (base_tmp_dir.find (
'~') != std::string::npos)
228 base_tmp_dir = sys::canonicalize_file_name (base_tmp_dir);
231 m_tmp_dir = sys::tempnam (base_tmp_dir,
"latex");
233 m_tmp_dir = sys::tempnam (
"",
"latex");
236 if (sys::mkdir (m_tmp_dir, 0700) != 0)
239 "latex_renderer: unable to create temp directory");
240 return std::string ();
244 std::string base_file_name
245 = sys::file_ops::concat (m_tmp_dir,
"default");
249 std::string latex_txt (txt);
254 pos = txt.find_first_of (
"\n", pos);
256 if (pos == std::string::npos)
259 latex_txt.replace (pos, 1,
"\n\n");
264 std::string
env (
"flushleft");
267 else if (halign == 2)
270 latex_txt = std::string (
"\\begin{" ) +
env +
"}\n"
272 +
"\\end{" +
env +
"}\n";
276 file.open (base_file_name +
".tex");
277 file <<
"\\documentclass[10pt, varwidth]{standalone}\n"
278 <<
"\\usepackage{amsmath}\n"
279 <<
"\\usepackage[utf8]{inputenc}\n"
280 <<
"\\begin{document}\n"
282 <<
"\\end{document}";
285 return base_file_name;
289latex_renderer::read_image (
const std::string& png_file,
303 = retval(0).xscalar_map_value (
"latex_renderer::read_image: "
304 "Wrong type for info");
316 alpha = retval(2).xuint8_array_value (
"latex_renderer::read_image: "
317 "Wrong type for alpha");
322 "latex_renderer:: failed to read png data. %s",
323 ee.message ().c_str ());
333 static_cast<uint8_t
> (0));
335 for (
int i = 0; i < height; i++)
337 for (
int j = 0; j < width; j++)
339 data(0, j, i) = m_color(0);
340 data(1, j, i) = m_color(1);
341 data(2, j, i) = m_color(2);
342 data(3, j, i) = alpha(height-i-1, j);
350latex_renderer::warn_helper (std::string caller, std::string txt,
353 if (m_testing && ! m_debug)
358 "latex_renderer: unable to compile \"%s\"",
362 "latex_renderer: %s failed for string \"%s\"\n\
363* Command:\n\t%s\n\n* Error:\n%s\n\n* Stdout:\n%s",
364 caller.c_str (), txt.c_str (), cmd.c_str (),
370latex_renderer::render (
const std::string& txt,
int halign)
373 gh_manager& gh_mgr = octave::__get_gh_manager__ ();
377 if (! ldata.first.isempty ())
383 std::string base_file_name = write_tex_file (txt, halign);
385 if (base_file_name.empty ())
389 std::string tex_file =
quote_string (base_file_name +
".tex");
390 std::string dvi_file =
quote_string (base_file_name +
".dvi");
391 std::string log_file =
quote_string (base_file_name +
".log");
394 std::string cmd = (m_latex_binary +
" -interaction=nonstopmode "
398#if defined (OCTAVE_USE_WINDOWS_API)
406 warn_helper (
"latex", txt, cmd, result);
410 write_tex_file (
"?", halign);
420 double size_factor = m_fontsize / 10.0;
425 std::string svg_file = base_file_name +
".svg";
427 cmd = (m_dvisvg_binary +
" -n "
428 +
"-TS" + std::to_string (size_factor) +
" "
432#if defined (OCTAVE_USE_WINDOWS_API)
440 warn_helper (
"dvisvg", txt, cmd, result);
444 std::ifstream svg_stream (svg_file);
445 std::string svg_string;
446 svg_string.assign (std::istreambuf_iterator<char> (svg_stream),
447 std::istreambuf_iterator<char> ());
451 std::string png_file = base_file_name +
".png";
453 cmd = (m_dvipng_binary +
" " + dvi_file +
" "
455 +
"-bg Transparent -D "
456 + std::to_string (std::floor (72.0 * size_factor)));
458#if defined (OCTAVE_USE_WINDOWS_API)
466 warn_helper (
"dvipng", txt, cmd, result);
470 if (! read_image (png_file, data))
475 ldata.second = svg_string;
480 std::cout <<
"* Caching " << key (txt, halign) << std::endl;
486latex_renderer::text_to_pixels (
const std::string& txt,
uint8NDArray& pixels,
487 Matrix& bbox,
int halign,
int valign,
490 bool handle_rotation)
495 bbox =
Matrix (1, 4, 0.0);
500 pixels = render (txt, halign);
508 bbox =
Matrix (1, 4, 0.0);
509 bbox (2) = pixels.
dim2 ();
510 bbox (3) = pixels.
dim3 ();
513 int rot_mode = rotation_to_mode (rotation);
516 rotate_pixels (pixels, rot_mode);
520 fix_bbox_anchor (bbox, halign, valign, rot_mode, handle_rotation);
526 latex_renderer *renderer =
new latex_renderer ();
531OCTAVE_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_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