Add-On Transformations
Informations
Authors:Moritz Wagner&Andreas WürmserLicense: FPDF
Description
Performs the following 2D transformations: scaling, mirroring, translation, rotation and skewing.Use StartTransform() before, and StopTransform() after the transformations to restore the normal behavior.
StartTransform()
Use this before calling any tranformation.
ScaleX(float s_x [, float x [, float y]])
ScaleY(float s_y [, float x [, float y]])
ScaleXY(float s [, float x [, float y]])
Scale(float s_x, float s_y [, float x [, float y]])
s_x: scaling factor for width as percent. 0 is not allowed.
s_y: scaling factor for height as percent. 0 is not allowed.
s: scaling factor for width and height as percent. 0 is not allowed.
x: abscissa of the scaling center. Default is current x position
y: ordinate of the scaling center. Default is current y position
MirrorH([float x])
Alias for scaling -100% in x-direction
x: abscissa of the axis of reflection
MirrorV([float y])
Alias for scaling -100% in y-direction
y: ordinate of the axis of reflection
MirrorP([float x, [float y]])
Point reflection on point (x, y). (alias for scaling -100 in x- and y-direction)
x: abscissa of the point. Default is current x position
y: ordinate of the point. Default is current y position
MirrorL([float angle [, float x [, float y]]])
Reflection against a straight line through point (x, y) with the gradient angle (angle).
angle: gradient angle of the straight line. Default is 0 (horizontal line).
x: abscissa of the point. Default is current x position
y: ordinate of the point. Default is current y position
TranslateX(float t_x)
TranslateY(float t_y)
Translate(float t_x, float t_y)
t_x: movement to the right
t_y: movement to the bottom
Rotate(float angle [, float x [, float y]])
angle: angle in degrees for counter-clockwise rotation
x: abscissa of the rotation center. Default is current x position
y: ordinate of the rotation center. Default is current y position
SkewX(float angle_x [, float x [, float y]])
SkewY(float angle_y [, float x [, float y]])
Skew(float angle_x, float angle_y [, float x [, float y]])
angle_x: angle in degrees between -90 (skew to the left) and 90 (skew to the right)
angle_y: angle in degrees between -90 (skew to the bottom) and 90 (skew to the top)
x: abscissa of the skewing center. default is current x position
y: ordinate of the skewing center. default is current y position
StopTransform()
Restores the normal painting and placing behavior as it was before calling StartTransform().
Source
<?php
/*
Version 2
Changes since version 1:
- added function MirrorP()
- added function MirrorL()
- fixed bug in Translate(): the movement is now performed in user units instead of pts
*/
require('fpdf.php');
class PDF_Transform extends FPDF{
function StartTransform(){
//save the current graphic state
$this->_out('q');
}
function ScaleX($s_x, $x='', $y=''){
$this->Scale($s_x, 100, $x, $y);
}
function ScaleY($s_y, $x='', $y=''){
$this->Scale(100, $s_y, $x, $y);
}
function ScaleXY($s, $x='', $y=''){
$this->Scale($s, $s, $x, $y);
}
function Scale($s_x, $s_y, $x='', $y=''){
if($x === '')
$x=$this->x;
if($y === '')
$y=$this->y;
if($s_x == 0 || $s_y == 0)
$this->Error('Please use values unequal to zero for Scaling');
$y=($this->h-$y)*$this->k;
$x*=$this->k;
//calculate elements of transformation matrix
$s_x/=100;
$s_y/=100;
$tm[0]=$s_x;
$tm[1]=0;
$tm[2]=0;
$tm[3]=$s_y;
$tm[4]=$x*(1-$s_x);
$tm[5]=$y*(1-$s_y);
//scale the coordinate system
$this->Transform($tm);
}
function MirrorH($x=''){
$this->Scale(-100, 100, $x);
}
function MirrorV($y=''){
$this->Scale(100, -100, '', $y);
}
function MirrorP($x='', $y=''){
$this->Scale(-100, -100, $x, $y);
}
function MirrorL($angle=0, $x='', $y=''){
$this->Scale(-100, 100, $x, $y);
$this->Rotate(-2*($angle-90), $x, $y);
}
function TranslateX($t_x){
$this->Translate($t_x, 0, $x, $y);
}
function TranslateY($t_y){
$this->Translate(0, $t_y, $x, $y);
}
function Translate($t_x, $t_y){
//calculate elements of transformation matrix
$tm[0]=1;
$tm[1]=0;
$tm[2]=0;
$tm[3]=1;
$tm[4]=$t_x*$this->k;
$tm[5]=-$t_y*$this->k;
//translate the coordinate system
$this->Transform($tm);
}
function Rotate($angle, $x='', $y=''){
if($x === '')
$x=$this->x;
if($y === '')
$y=$this->y;
$y=($this->h-$y)*$this->k;
$x*=$this->k;
//calculate elements of transformation matrix
$tm[0]=cos(deg2rad($angle));
$tm[1]=sin(deg2rad($angle));
$tm[2]=-$tm[1];
$tm[3]=$tm[0];
$tm[4]=$x+$tm[1]*$y-$tm[0]*$x;
$tm[5]=$y-$tm[0]*$y-$tm[1]*$x;
//rotate the coordinate system around ($x, $y)
$this->Transform($tm);
}
function SkewX($angle_x, $x='', $y=''){
$this->Skew($angle_x, 0, $x, $y);
}
function SkewY($angle_y, $x='', $y=''){
$this->Skew(0, $angle_y, $x, $y);
}
function Skew($angle_x, $angle_y, $x='', $y=''){
if($x === '')
$x=$this->x;
if($y === '')
$y=$this->y;
if($angle_x <= -90 || $angle_x >= 90 || $angle_y <= -90 || $angle_y >= 90)
$this->Error('Please use values between -90° and 90° for skewing');
$x*=$this->k;
$y=($this->h-$y)*$this->k;
//calculate elements of transformation matrix
$tm[0]=1;
$tm[1]=tan(deg2rad($angle_y));
$tm[2]=tan(deg2rad($angle_x));
$tm[3]=1;
$tm[4]=-$tm[2]*$y;
$tm[5]=-$tm[1]*$x;
//skew the coordinate system
$this->Transform($tm);
}
function Transform($tm){
$this->_out(sprintf('%.3F %.3F %.3F %.3F %.3F %.3F cm', $tm[0], $tm[1], $tm[2], $tm[3], $tm[4], $tm[5]));
}
function StopTransform(){
//restore previous graphic state
$this->_out('Q');
}
}
?>
Example
<?php
require('transform.php');
$pdf = new PDF_Transform();
$pdf->AddPage();
$pdf->SetFont('Arial', '', 12);
//Scaling
$pdf->SetDrawColor(200);
$pdf->SetTextColor(200);
$pdf->Rect(50, 20, 40, 10, 'D');
$pdf->Text(50, 19, 'Scale');
$pdf->SetDrawColor(0);
$pdf->SetTextColor(0);
//Start Transformation
$pdf->StartTransform();
//Scale by 150% centered by (50, 30) which is the lower left corner of the rectangle
$pdf->ScaleXY(150, 50, 30);
$pdf->Rect(50, 20, 40, 10, 'D');
$pdf->Text(50, 19, 'Scale');
//Stop Transformation
$pdf->StopTransform();
//Translation
$pdf->SetDrawColor(200);
$pdf->SetTextColor(200);
$pdf->Rect(125, 20, 40, 10, 'D');
$pdf->Text(125, 19, 'Translate');
$pdf->SetDrawColor(0);
$pdf->SetTextColor(0);
//Start Transformation
$pdf->StartTransform();
//Translate 7 to the right, 5 to the bottom
$pdf->Translate(7, 5);
$pdf->Rect(125, 20, 40, 10, 'D');
$pdf->Text(125, 19, 'Translate');
//Stop Transformation
$pdf->StopTransform();
//Rotation
$pdf->SetDrawColor(200);
$pdf->SetTextColor(200);
$pdf->Rect(50, 50, 40, 10, 'D');
$pdf->Text(50, 49, 'Rotate');
$pdf->SetDrawColor(0);
$pdf->SetTextColor(0);
//Start Transformation
$pdf->StartTransform();
//Rotate 20 degrees counter-clockwise centered by (50, 60) which is the lower left corner of the rectangle
$pdf->Rotate(20, 50, 60);
$pdf->Rect(50, 50, 40, 10, 'D');
$pdf->Text(50, 49, 'Rotate');
//Stop Transformation
$pdf->StopTransform();
//Skewing
$pdf->SetDrawColor(200);
$pdf->SetTextColor(200);
$pdf->Rect(125, 50, 40, 10, 'D');
$pdf->Text(125, 49, 'Skew');
$pdf->SetDrawColor(0);
$pdf->SetTextColor(0);
//Start Transformation
$pdf->StartTransform();
//skew 30 degrees along the x-axis centered by (125, 60) which is the lower left corner of the rectangle
$pdf->SkewX(30, 125, 60);
$pdf->Rect(125, 50, 40, 10, 'D');
$pdf->Text(125, 49, 'Skew');
//Stop Transformation
$pdf->StopTransform();
//Mirroring horizontally
$pdf->SetDrawColor(200);
$pdf->SetTextColor(200);
$pdf->Rect(50, 80, 40, 10, 'D');
$pdf->Text(50, 79, 'MirrorH');
$pdf->SetDrawColor(0);
$pdf->SetTextColor(0);
//Start Transformation
$pdf->StartTransform();
//mirror horizontally with axis of reflection at x-position 50 (left side of the rectangle)
$pdf->MirrorH(50);
$pdf->Rect(50, 80, 40, 10, 'D');
$pdf->Text(50, 79, 'MirrorH');
//Stop Transformation
$pdf->StopTransform();
//Mirroring vertically
$pdf->SetDrawColor(200);
$pdf->SetTextColor(200);
$pdf->Rect(125, 80, 40, 10, 'D');
$pdf->Text(125, 79, 'MirrorV');
$pdf->SetDrawColor(0);
$pdf->SetTextColor(0);
//Start Transformation
$pdf->StartTransform();
//mirror vertically with axis of reflection at y-position 90 (bottom side of the rectangle)
$pdf->MirrorV(90);
$pdf->Rect(125, 80, 40, 10, 'D');
$pdf->Text(125, 79, 'MirrorV');
//Stop Transformation
$pdf->StopTransform();
//Point reflection
$pdf->SetDrawColor(200);
$pdf->SetTextColor(200);
$pdf->Rect(50, 110, 40, 10, 'D');
$pdf->Text(50, 109, 'MirrorP');
$pdf->SetDrawColor(0);
$pdf->SetTextColor(0);
//Start Transformation
$pdf->StartTransform();
//point reflection at the lower left point of rectangle
$pdf->MirrorP(50, 120);
$pdf->Rect(50, 110, 40, 10, 'D');
$pdf->Text(50, 109, 'MirrorP');
//Stop Transformation
$pdf->StopTransform();
//Mirroring against a straigth line described by a point (120, 120) and an angle -20°
$angle=-20;
$px=120;
$py=120;
/* */ //just vor visualisation: the straight line to mirror against
/* */ $pdf->SetDrawColor(200);
/* */ $pdf->Line($px-1, $py-1, $px+1, $py+1);
/* */ $pdf->Line($px-1, $py+1, $px+1, $py-1);
/* */ $pdf->StartTransform();
/* */ $pdf->Rotate($angle, $px, $py);
/* */ $pdf->Line($px-5, $py, $px+60, $py);
/* */ $pdf->StopTransform();
$pdf->SetDrawColor(200);
$pdf->SetTextColor(200);
$pdf->Rect(125, 110, 40, 10, 'D');
$pdf->Text(125, 109, 'MirrorL');
$pdf->SetDrawColor(0);
$pdf->SetTextColor(0);
//Start Transformation
$pdf->StartTransform();
//mirror against the straight line
$pdf->MirrorL($angle, $px, $py);
$pdf->Rect(125, 110, 40, 10, 'D');
$pdf->Text(125, 109, 'MirrorL');
//Stop Transformation
$pdf->StopTransform();
$pdf->Output();
?>