Transformations

Add-On Transformations

Informations

Authors:Moritz Wagner&Andreas Würmser
License: 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();
?>
View the result here.

Download

ZIP | TGZ
Es ist ein Fehler aufgetreten

Es ist ein Fehler aufgetreten

Was ist das Problem?

Bei der Ausführung des Skriptes ist ein Fehler aufgetreten. Irgendetwas funktioniert nicht richtig.

Wie kann ich das Problem lösen?

Öffnen Sie die aktuelle Log-Datei im Ordner var/logs bzw. app/logs und suchen Sie die zugehörige Fehlermeldung (normalerweise die letzte).

Weitere Informationen

Die Skriptausführung wurde gestoppt, weil irgendetwas nicht korrekt funktioniert. Die eigentliche Fehlermeldung wird aus Sicherheitsgründen hinter dieser Meldung verborgen und findet sich in der aktuellen Log-Datei (siehe oben). Wenn Sie die Fehlermeldung nicht verstehen oder nicht wissen, wie das Problem zu beheben ist, durchsuchen Sie die Contao-FAQs oder besuchen Sie die Contao-Supportseite.