I'm using TCPDF 6.3 and when printing I can't get the same result as on screen for my SVG. On the screen, the nested tspans are organized natively in inline-block, so they remain well aligned and placed one after the other regardless of the value of the text-anchor (start, middle, end). The problem is that when printing the PDF, if text-anchor is set to "middle" the nested tspans overlap each other because they inherit the x attribute from the containing tspan. How do I make them stay aligned in the PDF? Here is the code:
<? xml version = "1.0" encoding = "utf-8" ?>< !DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"[
< !ENTITY classLigne1H "fill:#c3373f;stroke:#000000;stroke-width:0.1pt;text-anchor:middle;font-style:Normal;font-size:6pt;font-family:Acme;" >
< !ENTITY classLigne2H "fill:#4b37c3;stroke:#000000;stroke-width:0.1pt;text-anchor:middle;font-style:Normal;font-size:6pt;font-family:Acme;" >
< !ENTITY classLigne3H "fill:#4b37c3;stroke:#000000;stroke-width:0.1pt;text-anchor:middle;font-style:Normal;font-size:6pt;font-family:Acme;" >
< !ENTITY classLigne4H "fill:#c3378d;stroke:#000000;stroke-width:0.1pt;text-anchor:middle;font-style:Normal;font-size:6pt;font-family:Acme;" >
< !ENTITY classLigne5H "fill:#37c339;stroke:#000000;stroke-width:0.1pt;text-anchor:middle;font-style:Normal;font-size:6pt;font-family:Acme;" >
< !ENTITY classLigne6H "fill:#4b37c3;stroke:#000000;stroke-width:0.1pt;text-anchor:middle;font-style:Normal;font-size:6pt;font-family:Acme;" >
< !ENTITY classLigne7H "fill:#4b37c3;stroke:#000000;stroke-width:0.1pt;text-anchor:middle;font-style:Normal;font-size:6pt;font-family:Acme;" >
]>
<svg version="1.1"
id="Calque_1" xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0pt" y="0pt" width="297mm"
height="210mm" viewBox="0 0 841.89 595.276" style="enable-background:new 0 0 841.89 595.276;" xml:space="preserve">
<g id="montexte">
<text id="Sosa1" x="0" y="538.583" width="225.354" height="56.6929" transform="translate(307.922,-43.2756)">
<tspan x="0.0000" y="548" width="225.354" height="56.6929" data-ligne="nom_5LI" data-type="simple" data-libelle="nom" style="&classLigne1H;">Nom Sosa1</tspan>
<tspan x="0.0000" y="558" width="225.354" height="56.6929" data-ligne="prenom_5LI" data-type="simple" data-libelle="prenom" style="&classLigne2H;">prenom Sosa1</tspan>
<tspan x="0.0000" y="568" width="225.354" height="56.6929" data-ligne="metier_5LI" data-type="simple" data-libelle="metier" style="&classLigne3H;">metier Sosa1</tspan>
<tspan x="53.1833" y="578" width="225.354" height="56.6929" data-ligne="date_n_5LI" data-type="triple_n" style="text-anchor: start;"><tspan data-libelle="intitule_n" style="&classLigne4H;">° </tspan><tspan data-libelle="date_n" style="&classLigne4H;">date_n Sosa1</tspan><tspan data-libelle="lieu_n" style="&classLigne5H;">lieu_n Sosa1</tspan><tspan data-libelle="finx"></tspan></tspan>
<tspan x="-49.4167" y="588" width="225.354" height="56.6929" data-ligne="date_d_5LI" data-type="triple_d" style="text-anchor: start;"><tspan data-libelle="intitule_d" style="&classLigne6H;">+ </tspan><tspan data-libelle="date_d" style="&classLigne6H;">date_d Sosa1</tspan><tspan data-libelle="lieu_d" style="&classLigne7H;">lieu_d Sosa1</tspan><tspan data-libelle="finx"></tspan></tspan>
</text>
</g>
</svg>
With Jquery, I tried to get the exact width of the group of nested tspans to force their absolute positioning in the text block (the tspan data-libelle="finx" is just there to get the left of its offset).
// the var 'name' is obtained by another function each (I don't put all the code here)
$('tspan[data-ligne=' + nom + ']', '#montexte').each(function (index) {
var type = $(this).data('type');
var bloctxt = $(this).parent().attr('id'); // bloc text Sosa
var x = $(this).parent().attr('x'); // bloc text
var width = $(this).parent().attr('width'); // bloc text
var anchor = $('#centrageTexte option:selected').val();
var convert = 0.75; // 1pt = 0.75px
// part of the switch case
switch (type) {
case 'triple_n':// 3 tspan (intitulé + date + lieu)
var offset = $(this).parent().position(); //left du bloc text
var left = parseFloat((offset.left) * convert); // left du bloc text
var offset0 = $('tspan[data-libelle="intitule_n"]', this).position();
var left0 = parseFloat((offset0.left) * convert); // left du premier tspan
var x0 = parseFloat($(this).attr('x')); // x du tspan conteneur
var offsetx = $('tspan[data-libelle="finx"]', this).position(); // pos du dernier tspan (vide)
var leftx = parseFloat((offsetx.left) * convert); // x du dernier tspan (vide)
var marge = parseFloat(left0 - left); // largeur du tspan conteneur
var larg = parseFloat(left0 - leftx); // largeur du tspan conteneur
if (anchor == 'middle') x0 = parseFloat((x0 - (width / 2)) + (marge));
if (anchor == 'end') x0 = parseFloat(x0 - larg);
var xnew = parseFloat(x0).toFixed(4);
$('tspan[data-ligne=' + nom + ']', '#clonetexte').attr('x', xnew);
break;
default:
break;
}
});
I force the display to 100% on the screen before calculations and printing, but the results are always uneven and hazardous. Is another solution on SVG code possible (since CSS property inline-block doesn't work in SVG)? Should we go directly to modify the startSVGElementHandler() function in the tcpdf.php file of TCPDF (line 24333 case 'text': case 'tspan') or getHTMLUnitToUnits()? And if yes, how ? Thanks in advance, hoping to have been sufficiently clear in the description of the problem.