Skip to content

Commit

Permalink
Utility methods for unit conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolaasuni committed Oct 4, 2023
1 parent f687e34 commit 0a614c3
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 49 deletions.
2 changes: 1 addition & 1 deletion examples/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -926,7 +926,7 @@
$txt = $pdf->getTextLine(
'Test PDF text with justification (stretching).',
0,
$pdf->pointsToUserUnit($bfont2['ascent']),
$pdf->toUnit($bfont2['ascent']),
$page11['width']
);

Expand Down
32 changes: 16 additions & 16 deletions src/Output.php
Original file line number Diff line number Diff line change
Expand Up @@ -588,10 +588,10 @@ protected function getOutXObjects()
}
$out .= sprintf(
' /BBox [%F %F %F %F]',
$this->userToPointsUnit($data['x']),
$this->userToPointsUnit(-$data['y']),
$this->userToPointsUnit(($data['w'] + $data['x'])),
$this->userToPointsUnit(($data['h'] - $data['y']))
$this->toPoints($data['x']),
$this->toPoints(-$data['y']),
$this->toPoints(($data['w'] + $data['x'])),
$this->toPoints(($data['h'] - $data['y']))
);
$out .= ' /Matrix [1 0 0 1 0 0]'
.' /Resources <<'
Expand Down Expand Up @@ -691,8 +691,8 @@ protected function getOutDestinations()
foreach ($this->dests as $name => $dst) {
$page = $this->page->getPage($dst['p']);
$poid = $page['n'];
$pgx = $this->userToPointsUnit($dst['x']);
$pgy = ($page['pheight'] - $this->userToPointsUnit($dst['y']));
$pgx = $this->toPoints($dst['x']);
$pgy = $this->toYPoints($dst['y'], $page['pheight']);
$out .= ' /'.$name.' '.sprintf('[%u 0 R /XYZ %F %F null]', $poid, $pgx, $pgy);
}
$out .= ' >>'."\n"
Expand Down Expand Up @@ -818,10 +818,10 @@ protected function getOutAnnotations()
$annot = $this->annotation[$oid];
$annot['opt'] = array_change_key_case($annot['opt'], CASE_LOWER);
$out .= $this->getAnnotationRadiobuttonGroups($annot);
$orx = ($annot['x'] * $this->kunit);
$ory = ($page['pheight'] - (($annot['y'] + $annot['h']) * $this->kunit));
$width = ($annot['w'] * $this->kunit);
$height = ($annot['h'] * $this->kunit);
$orx = $this->toPoints($annot['x']);
$ory = $this->toYPoints(($annot['y'] + $annot['h']), $page['pheight']);
$width = $this->toPoints($annot['w']);
$height = $this->toPoints($annot['h']);
$rect = sprintf('%F %F %F %F', $orx, $ory, $orx+$width, $ory+$height);
$out .= $oid.' 0 obj'."\n"
.'<<'
Expand Down Expand Up @@ -1329,7 +1329,7 @@ protected function getOutAnnotationOptSubtypeLink($annot, $pagenum, $oid)
// internal link ID
$l = $this->links[$annot['txt']];
$page = $this->page->getPage($l['p']);
$y = ($page['height'] - $this->userToPointsUnit($l['y']));
$y = $this->toYPoints($l['y'], $page['height']);
$out .= sprintf(' /Dest [%u 0 R /XYZ 0 %F null]', $page['n'], $y);
}
$hmodes = array('N', 'I', 'O', 'P');
Expand Down Expand Up @@ -1368,7 +1368,7 @@ protected function getOutAnnotationOptSubtypeFreetext($annot)
if (isset($annot['opt']['cl']) && is_array($annot['opt']['cl'])) {
$out .= ' /CL [';
foreach ($annot['opt']['cl'] as $cl) {
$out .= sprintf('%F ', $this->userToPointsUnit($cl));
$out .= sprintf('%F ', $this->toPoints($cl));
}
$out .= ']';
}
Expand All @@ -1377,10 +1377,10 @@ protected function getOutAnnotationOptSubtypeFreetext($annot)
$out .= ' /IT /'.$annot['opt']['it'];
}
if (isset($annot['opt']['rd']) && is_array($annot['opt']['rd'])) {
$l = $this->userToPointsUnit($annot['opt']['rd'][0]);
$r = $this->userToPointsUnit($annot['opt']['rd'][1]);
$t = $this->userToPointsUnit($annot['opt']['rd'][2]);
$b = $this->userToPointsUnit($annot['opt']['rd'][3]);
$l = $this->toPoints($annot['opt']['rd'][0]);
$r = $this->toPoints($annot['opt']['rd'][1]);
$t = $this->toPoints($annot['opt']['rd'][2]);
$b = $this->toPoints($annot['opt']['rd'][3]);
$out .= ' /RD ['.sprintf('%F %F %F %F', $l, $r, $t, $b).']';
}
$lineendings = array(
Expand Down
51 changes: 41 additions & 10 deletions src/Tcpdf.php
Original file line number Diff line number Diff line change
Expand Up @@ -364,27 +364,58 @@ public function getBarcode(
}

/**
* Convert the input points value to the user units.
* Convert user units to internal points unit.
*
* @param float $val Value in internal points unit.
* @param float $usr Value to convert.
*
* @return float Value in user units.
* @return float
*/
public function pointsToUserUnit($val)
public function toPoints($usr)
{
return ((float) $val / $this->kunit);
return ((float) $usr * $this->kunit);
}

/**
* Convert the input value in user unit to internal points.
* Convert internal points to user unit.
*
* @param float $val Value in user unit.
* @param float $pnt Value to convert in user units.
*
* @return float Value in internal points.
* @return float
*/
public function userToPointsUnit($val)
public function toUnit($pnt)
{
return ((float) $val * $this->kunit);
return ((float) $pnt / $this->kunit);
}

/**
* Convert vertical user value to internal points unit.
* Note: the internal Y points coordinate starts at the bottom left of the page.
*
* @param float $usr Value to convert.
* @param float $pageh Optional page height in internal points ($pageh:$this->page->getPage()['pheight']).
*
* @return float
*/
public function toYPoints($usr, $pageh = -1)
{
$pageh = $pageh>=0?$pageh:$this->page->getPage()['pheight'];
return ($pageh - $this->toPoints($usr));
}


/**
* Convert vertical internal points value to user unit.
* Note: the internal Y points coordinate starts at the bottom left of the page.
*
* @param float $usr Value to convert.
* @param float $pageh Optional page height in internal points ($pageh:$this->page->getPage()['pheight']).
*
* @return float
*/
public function toYUnit($pnt, $pageh = -1)
{
$pageh = $pageh>=0?$pageh:$this->page->getPage()['pheight'];
return ($pageh - $this->toUnit($pnt));
}

/**
Expand Down
44 changes: 22 additions & 22 deletions src/Text.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,20 @@ public function getTextLine(
$curfont = $this->font->getCurrentFont();
$this->lasttxtbbox = array(
'x' => $posx,
'y' => ($posy - $this->pointsToUserUnit($curfont['ascent'])),
'y' => ($posy - $this->toUnit($curfont['ascent'])),
'width' => $width,
'height' => ($this->pointsToUserUnit($curfont['ascent'] - $curfont['descent']))
'height' => $this->toUnit($curfont['ascent'] - $curfont['descent'])
);
$out = $this->getJustifiedString($txt, $width, $forcertl);
$out = $this->getOutTextPosXY($out, $posx, $posy, 'Td');
$trmode = $this->getTextRenderingMode($fill, $stroke, $clip);
$out = $this->getOutTextStateOperator($out, 'w', $this->userToPointsUnit($strokewidth));
$out = $this->getOutTextStateOperator($out, 'w', $this->toPoints($strokewidth));
$out = $this->getOutTextStateOperator($out, 'Tr', $trmode);
$out = $this->getOutTextStateOperator($out, 'Tw', $this->userToPointsUnit($wordspacing));
$out = $this->getOutTextStateOperator($out, 'Tw', $this->toPoints($wordspacing));
$out = $this->getOutTextStateOperator($out, 'Tc', $curfont['spacing']);
$out = $this->getOutTextStateOperator($out, 'Tz', $curfont['stretching']);
$out = $this->getOutTextStateOperator($out, 'TL', $this->userToPointsUnit($leading));
$out = $this->getOutTextStateOperator($out, 'Ts', $this->userToPointsUnit($rise));
$out = $this->getOutTextStateOperator($out, 'TL', $this->toPoints($leading));
$out = $this->getOutTextStateOperator($out, 'Ts', $this->toPoints($rise));
$out = $this->getOutTextObject($out);
return $out;
}
Expand Down Expand Up @@ -132,15 +132,15 @@ protected function getJustifiedString($txt, $width = 0, $forcertl = false)
// converts an UTF-8 string to an array of UTF-8 codepoints (integer values)
$ordarr = $this->uniconv->strToOrdArr($txt);
$dim = $this->font->getOrdArrDims($ordarr);
$width *= $this->kunit;
$spacewidth = (($width - $dim['totwidth'] + $dim['totspacewidth']) / ($dim['spaces']?$dim['spaces']:1));
$pwidth = $this->toPoints($width);
$spacewidth = (($pwidth - $dim['totwidth'] + $dim['totspacewidth']) / ($dim['spaces']?$dim['spaces']:1));
if (!$this->isunicode) {
$txt = $this->encrypt->escapeString($txt);
$txt = $this->getOutTextShowing($txt, 'Tj');
if ($width > 0) {
return $this->getOutTextStateOperator($txt, 'Tw', $spacewidth * $this->kunit);
if ($pwidth > 0) {
return $this->getOutTextStateOperator($txt, 'Tw', $this->toPoints($spacewidth));
}
$this->lasttxtbbox['width'] = $this->pointsToUserUnit($dim['totwidth']);
$this->lasttxtbbox['width'] = $this->toUnit($dim['totwidth']);
return $txt;
}
if ($this->font->isCurrentByteFont()) {
Expand All @@ -151,8 +151,8 @@ protected function getJustifiedString($txt, $width = 0, $forcertl = false)
$txt = $this->uniconv->toUTF16BE($unistr);
}
$txt = $this->encrypt->escapeString($txt);
if ($width <= 0) {
$this->lasttxtbbox['width'] = $this->pointsToUserUnit($dim['totwidth']);
if ($pwidth <= 0) {
$this->lasttxtbbox['width'] = $this->toUnit($dim['totwidth']);
return $this->getOutTextShowing($txt, 'Tj');
}
$fontsize = $this->font->getCurrentFont()['size']?$this->font->getCurrentFont()['size']:1;
Expand All @@ -174,13 +174,13 @@ protected function getJustifiedString($txt, $width = 0, $forcertl = false)
protected function getOutTextPosXY($raw, $posx = 0, $posy = 0, $mode = 'Td')
{

$posx *= $this->kunit;
$posy = $this->page->getPage()['pheight'] - ($posy * $this->kunit);
$pntx = $this->toPoints($posx);
$pnty = $this->toYPoints($posy);
switch ($mode) {
case 'Td': // Move to the start of the next line, offset from the start of the current line by (posx, posy).
return sprintf('%F %F Td '.$raw, $posx, $posy);
return sprintf('%F %F Td '.$raw, $pntx, $pnty);
case 'TD': // Same as: -posx TL posx posy Td
return sprintf('%F %F TD '.$raw, $posx, $posy);
return sprintf('%F %F TD '.$raw, $pntx, $pnty);
case 'T*': // Move to the start of the next line.
return sprintf('T* '.$raw);
}
Expand Down Expand Up @@ -220,7 +220,7 @@ protected function getTextRenderingMode($fill = true, $stroke = false, $clip = f
*
* @param string $raw Raw PDf data to be wrapped by this command.
* @param string $param Text state parameter to apply (one of: Tc, Tw, Tz, TL, Tf, Tr, Ts, w)
* @param int|float $value Value to apply.
* @param int|float $value Raw value to apply in internal units.
*
* @return string
*/
Expand All @@ -231,17 +231,17 @@ protected function getOutTextStateOperator($raw, $param, $value = 0)
if ($value == 0) {
break;
}
return sprintf('%F Tc '.$raw.' 0 Tc', ($value * $this->kunit));
return sprintf('%F Tc '.$raw.' 0 Tc', $value);
case 'Tw': // word spacing
if ($value == 0) {
break;
}
return sprintf('%F Tw '.$raw.' 0 Tw', ($value * $this->kunit));
return sprintf('%F Tw '.$raw.' 0 Tw', $value);
case 'Tz': // horizontal scaling
if ($value == 1) {
break;
}
return sprintf('%F Tz '.$raw.' 100 Tz', ($value * 100));
return sprintf('%F Tz '.$raw.' 100 Tz', $value);
case 'TL': // text leading
if ($value == 0) {
break;
Expand All @@ -258,7 +258,7 @@ protected function getOutTextStateOperator($raw, $param, $value = 0)
}
return sprintf('%F Ts '.$raw.' 0 Ts', $value);
case 'w': // stroke width
return sprintf('%F w '.$raw, ($value > 0 ? ($value * $this->kunit) : 0));
return sprintf('%F w '.$raw, ($value > 0 ? $value : 0));
}
return $raw;
}
Expand Down

0 comments on commit 0a614c3

Please sign in to comment.