49 return (
'"' + str +
'"');
59 : m_fontsize (10.0), m_fontname (
"cmr"), m_tmp_dir (),
60 m_color (
dim_vector (1, 3), 0), m_latex_binary (
"latex"),
61 m_dvipng_binary (
"dvipng"), m_dvisvg_binary (
"dvisvgm"),
62 m_debug (false), m_testing (true)
64 std::string bin = sys::env::getenv (
"OCTAVE_LATEX_BINARY");
68 bin = sys::env::getenv (
"OCTAVE_DVIPNG_BINARY");
72 bin = sys::env::getenv (
"OCTAVE_DVISVG_BINARY");
76 m_debug = ! sys::env::getenv (
"OCTAVE_LATEX_DEBUG_FLAG").empty ();
79 OCTAVE_DISABLE_COPY_MOVE (latex_renderer)
83 if (! m_tmp_dir.empty () && ! m_debug)
87 void set_font (
const std::string& ,
const std::string& ,
88 const std::string& ,
double size)
93 void set_color (
const Matrix& c)
97 m_color(0) =
static_cast<uint8_t
> (c (0) * 255);
98 m_color(1) =
static_cast<uint8_t
> (c (1) * 255);
99 m_color(2) =
static_cast<uint8_t
> (c (2) * 255);
105 return Matrix (1, 2, 0.0);
108 Matrix get_extent (
const std::string& txt,
double rotation,
114 text_to_pixels (txt, pixels, bbox, 0, 0, rotation,
interpreter,
false);
119 void text_to_strlist (
const std::string& txt,
120 std::list<text_renderer::string>& lst,
121 Matrix& bbox,
int halign,
int valign,
double rotation,
125 text_to_pixels (txt, pixels, bbox, halign, valign, rotation,
130 str.set_color (m_color);
136 str.set_svg_element (ldata.second);
141 void text_to_pixels (
const std::string& txt,
uint8NDArray& pxls,
142 Matrix& bbox,
int halign,
int valign,
double rotation,
144 bool handle_rotation);
146 void set_anti_aliasing (
bool ) { }
154 std::string key (
const std::string& txt,
int halign)
157 + std::to_string (m_fontsize) +
":"
158 + std::to_string (halign) +
":"
159 + std::to_string (m_color(0)) +
":"
160 + std::to_string (m_color(1)) +
":"
161 + std::to_string (m_color(2)));
164 void warn_helper (std::string caller, std::string txt, std::string cmd,
167 uint8NDArray render (
const std::string& txt,
int halign = 0);
169 bool read_image (
const std::string& png_file,
uint8NDArray& data)
const;
171 std::string write_tex_file (
const std::string& txt,
int halign);
175 std::string m_fontname;
176 std::string m_tmp_dir;
178 std::string m_latex_binary;
179 std::string m_dvipng_binary;
180 std::string m_dvisvg_binary;
187 latex_renderer::ok ()
190 static bool tested =
false;
192 static bool isok =
false;
205 "latex_renderer: a run-time test failed and the 'latex' interpreter has been disabled.");
214 latex_renderer::write_tex_file (
const std::string& txt,
int halign)
216 if (m_tmp_dir.empty ())
219 #if defined (OCTAVE_USE_WINDOWS_API)
220 static std::string base_tmp_dir;
222 if (base_tmp_dir.empty ())
224 base_tmp_dir = sys::env::get_temp_directory ();
229 if (base_tmp_dir.find (
'~') != std::string::npos)
241 "latex_renderer: unable to create temp directory");
242 return std::string ();
246 std::string base_file_name
251 std::string latex_txt (txt);
256 pos = txt.find_first_of (
"\n", pos);
258 if (pos == std::string::npos)
261 latex_txt.replace (pos, 1,
"\n\n");
266 std::string
env (
"flushleft");
269 else if (halign == 2)
272 latex_txt = std::string (
"\\begin{" ) +
env +
"}\n"
274 +
"\\end{" +
env +
"}\n";
278 file.open (base_file_name +
".tex");
279 file <<
"\\documentclass[10pt, varwidth]{standalone}\n"
280 <<
"\\usepackage{amsmath}\n"
281 <<
"\\usepackage[utf8]{inputenc}\n"
282 <<
"\\begin{document}\n"
284 <<
"\\end{document}";
287 return base_file_name;
291 latex_renderer::read_image (
const std::string& png_file,
305 = retval(0).xscalar_map_value (
"latex_renderer::read_image: "
306 "Wrong type for info");
318 alpha = retval(2).xuint8_array_value (
"latex_renderer::read_image: "
319 "Wrong type for alpha");
324 "latex_renderer:: failed to read png data. %s",
325 ee.message ().c_str ());
335 static_cast<uint8_t
> (0));
337 for (
int i = 0; i < height; i++)
339 for (
int j = 0; j < width; j++)
341 data(0, j, i) = m_color(0);
342 data(1, j, i) = m_color(1);
343 data(2, j, i) = m_color(2);
344 data(3, j, i) = alpha(height-i-1, j);
352 latex_renderer::warn_helper (std::string caller, std::string txt,
355 if (m_testing && ! m_debug)
360 "latex_renderer: unable to compile \"%s\"",
364 "latex_renderer: %s failed for string \"%s\"\n\
365 * Command:\n\t%s\n\n* Error:\n%s\n\n* Stdout:\n%s",
366 caller.c_str (), txt.c_str (), cmd.c_str (),
372 latex_renderer::render (
const std::string& txt,
int halign)
379 if (! ldata.first.isempty ())
385 std::string base_file_name = write_tex_file (txt, halign);
387 if (base_file_name.empty ())
391 std::string tex_file =
quote_string (base_file_name +
".tex");
392 std::string dvi_file =
quote_string (base_file_name +
".dvi");
393 std::string log_file =
quote_string (base_file_name +
".log");
396 std::string cmd = (m_latex_binary +
" -interaction=nonstopmode "
400 #if defined (OCTAVE_USE_WINDOWS_API)
408 warn_helper (
"latex", txt, cmd, result);
412 write_tex_file (
"?", halign);
422 double size_factor = m_fontsize / 10.0;
427 std::string svg_file = base_file_name +
".svg";
429 cmd = (m_dvisvg_binary +
" -n "
430 +
"-TS" + std::to_string (size_factor) +
" "
434 #if defined (OCTAVE_USE_WINDOWS_API)
442 warn_helper (
"dvisvg", txt, cmd, result);
447 std::string svg_string;
448 svg_string.assign (std::istreambuf_iterator<char> (svg_stream),
449 std::istreambuf_iterator<char> ());
453 std::string png_file = base_file_name +
".png";
455 cmd = (m_dvipng_binary +
" " + dvi_file +
" "
457 +
"-bg Transparent -D "
458 + std::to_string (
std::floor (72.0 * size_factor)));
460 #if defined (OCTAVE_USE_WINDOWS_API)
468 warn_helper (
"dvipng", txt, cmd, result);
472 if (! read_image (png_file, data))
477 ldata.second = svg_string;
482 std::cout <<
"* Caching " << key (txt, halign) << std::endl;
488 latex_renderer::text_to_pixels (
const std::string& txt,
uint8NDArray& pixels,
489 Matrix& bbox,
int halign,
int valign,
492 bool handle_rotation)
497 bbox =
Matrix (1, 4, 0.0);
502 pixels = render (txt, halign);
510 bbox =
Matrix (1, 4, 0.0);
511 bbox (2) = pixels.
dim2 ();
512 bbox (3) = pixels.
dim3 ();
515 int rot_mode = rotation_to_mode (rotation);
518 rotate_pixels (pixels, rot_mode);
522 fix_bbox_anchor (bbox, halign, valign, rot_mode, handle_rotation);
528 latex_renderer *renderer =
new latex_renderer ();
533 OCTAVE_END_NAMESPACE(
octave)
ComplexNDArray concat(NDArray &ra, ComplexNDArray &rb, const Array< octave_idx_type > &ra_idx)
octave_value_list F__magick_ping__(const octave_value_list &=octave_value_list(), int=0)
octave_value_list F__magick_read__(const octave_value_list &=octave_value_list(), int=0)
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
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,...)
gh_manager & __get_gh_manager__()
interpreter & __get_interpreter__()
base_text_renderer * make_latex_text_renderer()
std::complex< T > floor(const std::complex< T > &x)
std::ofstream ofstream(const std::string &filename, const std::ios::openmode mode)
std::ifstream ifstream(const std::string &filename, const std::ios::openmode mode)
std::string tempnam(const std::string &dir, const std::string &pfx)
int mkdir(const std::string &nm, mode_t md)
std::string canonicalize_file_name(const std::string &name)
int recursive_rmdir(const std::string &name)
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