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 {