Mercurial > octave
comparison libinterp/corefcn/ft-text-renderer.cc @ 29470:2ae4764180c6
Initial implementation of a LaTeX interpreter (bug #59546).
* NEWS: Announce basic support for "latex" interpreter.
* plot.txi: Restructure the "Use of the interpreter Property" section to include
3 subsections, one for each interpreter type. In "Printing and Saving Plots"
describe the new behavior.
* print.m: Document new behavior.
* contributors.in: Add Andrej Lojdl, a former GSoC student that worked on this
subject. Even though there is not much left of his original work, it served
as a very useful starting point.
* base-text-renderer.h, base-text-renderer.cc: New enum to store symbolic
constants for rotation angles.
(base_text_renderer::rotate_pixels): New utility method. Code extracted
from ft_text_renderer::render.
(base_text_renderer::rotation_to_mode): Moved from ft_text_renderer class.
(base_text_renderer::fix_bbox_anchor): New utility method. Code extracted
from ft_text_renderer::text_to_pixels.
* ft_text_renderer.cc (ft_text_renderer::render,
ft_text_renderer::text_to_pixels): Make use of base class utility functions.
* gl2ps-print.cc: New counter variable m_svg_def_index for safe inclusion of
defs coming from dvisvgm.
(gl2ps_renderer::format_svg_element): New function to manipulate svg elements
obtained from dvisvgm so as to position them properly on the figure and
change their color.
(gl2ps_renderer::strlist_to_svg): If the str_list object returned from
text_to_strlist contains an svg element, use format_svg_element to handle
position and color and then return it. Otherwise, use <g> and <text> elements
rather than <text> and <tspan> elements which are not supported by Qt's svg
renderer (svg-tiny implementation).
(gl2ps_renderer::strlist_to_ps): If the str_list object returned from
text_to_strlist contains an svg element, raise a warning about the
necessity of using -svgconvert.
* latex-text-renderer.h, latex-text-renderer.cc: New files to hold the
latex_interpreter class.
* libinterp/corefcn/module.mk: Add new files to the build system.
* text-renderer.h, text-renderer.cc (text_renderer): New data member latex_rep
to hold a pointer to an instance of a latex_renderer.
(text_renderer::~text_renderer, get_extent, set_anti_aliasing, set_font,
set_color, text_to_pixels, text_to_strlist): Duplicate action of the
latex_rep.
(text_renderer::latex_ok): New method to test the usability of the
latex_renderer.
(text_renderer::string::svg_element, text_renderer::string::set_svg_element,
text_renderer::string::get_svg_element): New string data member to hold
preformated svg element. Provide accessor methods.
* acinclude.m4: Add QtSvg to the list of imported QT_MODULES.
* octave-svgconvert.cc: Overhaul program to make use of Qt's QSvgRenderer
when rendering to PDF.
author | Pantxo Diribarne <pantxo.diribarne@gmail.com> |
---|---|
date | Mon, 22 Mar 2021 21:32:54 +0100 |
parents | 7854d5752dd2 |
children | ee66869c30d6 |
comparison
equal
deleted
inserted
replaced
29468:46def32e6806 | 29470:2ae4764180c6 |
---|---|
446 { | 446 { |
447 MODE_BBOX = 0, | 447 MODE_BBOX = 0, |
448 MODE_RENDER = 1 | 448 MODE_RENDER = 1 |
449 }; | 449 }; |
450 | 450 |
451 enum | |
452 { | |
453 ROTATION_0 = 0, | |
454 ROTATION_90 = 1, | |
455 ROTATION_180 = 2, | |
456 ROTATION_270 = 3 | |
457 }; | |
458 | |
459 public: | 451 public: |
460 | 452 |
461 ft_text_renderer (void) | 453 ft_text_renderer (void) |
462 : base_text_renderer (), font (), bbox (1, 4, 0.0), halign (0), | 454 : base_text_renderer (), font (), bbox (1, 4, 0.0), halign (0), |
463 xoffset (0), line_yoffset (0), yoffset (0), mode (MODE_BBOX), | 455 xoffset (0), line_yoffset (0), yoffset (0), mode (MODE_BBOX), |
523 int halign, int valign, double rotation, | 515 int halign, int valign, double rotation, |
524 const caseless_str& interpreter, | 516 const caseless_str& interpreter, |
525 bool handle_rotation); | 517 bool handle_rotation); |
526 | 518 |
527 private: | 519 private: |
528 | |
529 int rotation_to_mode (double rotation) const; | |
530 | 520 |
531 // Class to hold information about fonts and a strong | 521 // Class to hold information about fonts and a strong |
532 // reference to the font objects loaded by FreeType. | 522 // reference to the font objects loaded by FreeType. |
533 | 523 |
534 class ft_font : public text_renderer::font | 524 class ft_font : public text_renderer::font |
1292 | 1282 |
1293 if (pixels.numel () > 0) | 1283 if (pixels.numel () > 0) |
1294 { | 1284 { |
1295 elt->accept (*this); | 1285 elt->accept (*this); |
1296 | 1286 |
1297 switch (rotation) | 1287 rotate_pixels (pixels, rotation); |
1298 { | |
1299 case ROTATION_0: | |
1300 break; | |
1301 | |
1302 case ROTATION_90: | |
1303 { | |
1304 Array<octave_idx_type> perm (dim_vector (3, 1)); | |
1305 perm(0) = 0; | |
1306 perm(1) = 2; | |
1307 perm(2) = 1; | |
1308 pixels = pixels.permute (perm); | |
1309 | |
1310 Array<idx_vector> idx (dim_vector (3, 1)); | |
1311 idx(0) = idx_vector (':'); | |
1312 idx(1) = idx_vector (pixels.dim2 ()-1, -1, -1); | |
1313 idx(2) = idx_vector (':'); | |
1314 pixels = uint8NDArray (pixels.index (idx)); | |
1315 } | |
1316 break; | |
1317 | |
1318 case ROTATION_180: | |
1319 { | |
1320 Array<idx_vector> idx (dim_vector (3, 1)); | |
1321 idx(0) = idx_vector (':'); | |
1322 idx(1) = idx_vector (pixels.dim2 ()-1, -1, -1); | |
1323 idx(2) = idx_vector (pixels.dim3 ()-1, -1, -1); | |
1324 pixels = uint8NDArray (pixels.index (idx)); | |
1325 } | |
1326 break; | |
1327 | |
1328 case ROTATION_270: | |
1329 { | |
1330 Array<octave_idx_type> perm (dim_vector (3, 1)); | |
1331 perm(0) = 0; | |
1332 perm(1) = 2; | |
1333 perm(2) = 1; | |
1334 pixels = pixels.permute (perm); | |
1335 | |
1336 Array<idx_vector> idx (dim_vector (3, 1)); | |
1337 idx(0) = idx_vector (':'); | |
1338 idx(1) = idx_vector (':'); | |
1339 idx(2) = idx_vector (pixels.dim3 ()-1, -1, -1); | |
1340 pixels = uint8NDArray (pixels.index (idx)); | |
1341 } | |
1342 break; | |
1343 } | |
1344 } | 1288 } |
1345 | 1289 |
1346 return pixels; | 1290 return pixels; |
1347 } | 1291 } |
1348 | 1292 |
1386 delete elt; | 1330 delete elt; |
1387 | 1331 |
1388 return extent; | 1332 return extent; |
1389 } | 1333 } |
1390 | 1334 |
1391 int | |
1392 ft_text_renderer::rotation_to_mode (double rotation) const | |
1393 { | |
1394 // Clip rotation to range [0, 360] | |
1395 while (rotation < 0) | |
1396 rotation += 360.0; | |
1397 while (rotation > 360.0) | |
1398 rotation -= 360.0; | |
1399 | |
1400 if (rotation == 0.0) | |
1401 return ROTATION_0; | |
1402 else if (rotation == 90.0) | |
1403 return ROTATION_90; | |
1404 else if (rotation == 180.0) | |
1405 return ROTATION_180; | |
1406 else if (rotation == 270.0) | |
1407 return ROTATION_270; | |
1408 else | |
1409 return ROTATION_0; | |
1410 } | |
1411 | |
1412 void | 1335 void |
1413 ft_text_renderer::text_to_pixels (const std::string& txt, | 1336 ft_text_renderer::text_to_pixels (const std::string& txt, |
1414 uint8NDArray& pxls, Matrix& box, | 1337 uint8NDArray& pxls, Matrix& box, |
1415 int _halign, int valign, double rotation, | 1338 int _halign, int valign, double rotation, |
1416 const caseless_str& interpreter, | 1339 const caseless_str& interpreter, |
1425 delete elt; | 1348 delete elt; |
1426 | 1349 |
1427 if (pxls.isempty ()) | 1350 if (pxls.isempty ()) |
1428 return; // nothing to render | 1351 return; // nothing to render |
1429 | 1352 |
1430 switch (halign) | 1353 // Move X0 and Y0 depending on alignments and eventually swap all values |
1431 { | 1354 // for text rotated 90° 180° or 270° |
1432 case 1: | 1355 fix_bbox_anchor (box, halign, valign, rot_mode, handle_rotation); |
1433 box(0) = -box(2)/2; | |
1434 break; | |
1435 | |
1436 case 2: | |
1437 box(0) = -box(2); | |
1438 break; | |
1439 | |
1440 default: | |
1441 box(0) = 0; | |
1442 break; | |
1443 } | |
1444 | |
1445 switch (valign) | |
1446 { | |
1447 case 1: | |
1448 box(1) = -box(3)/2; | |
1449 break; | |
1450 | |
1451 case 2: | |
1452 box(1) = -box(3); | |
1453 break; | |
1454 | |
1455 case 3: | |
1456 break; | |
1457 | |
1458 case 4: | |
1459 box(1) = -box(3)-box(1); | |
1460 break; | |
1461 | |
1462 default: | |
1463 box(1) = 0; | |
1464 break; | |
1465 } | |
1466 | |
1467 if (handle_rotation) | |
1468 { | |
1469 switch (rot_mode) | |
1470 { | |
1471 case ROTATION_90: | |
1472 std::swap (box(0), box(1)); | |
1473 std::swap (box(2), box(3)); | |
1474 box(0) = -box(0)-box(2); | |
1475 break; | |
1476 | |
1477 case ROTATION_180: | |
1478 box(0) = -box(0)-box(2); | |
1479 box(1) = -box(1)-box(3); | |
1480 break; | |
1481 | |
1482 case ROTATION_270: | |
1483 std::swap (box(0), box(1)); | |
1484 std::swap (box(2), box(3)); | |
1485 box(1) = -box(1)-box(3); | |
1486 break; | |
1487 } | |
1488 } | |
1489 } | 1356 } |
1490 | 1357 |
1491 ft_text_renderer::ft_font::ft_font (const ft_font& ft) | 1358 ft_text_renderer::ft_font::ft_font (const ft_font& ft) |
1492 : text_renderer::font (ft), face (nullptr) | 1359 : text_renderer::font (ft), face (nullptr) |
1493 { | 1360 { |