1# -- 2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/ 3# -- 4# This software comes with ABSOLUTELY NO WARRANTY. For details, see 5# the enclosed file COPYING for license information (GPL). If you 6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt. 7# -- 8 9package Kernel::System::PDF; 10 11use strict; 12use warnings; 13 14use PDF::API2; 15 16our @ObjectDependencies = ( 17 'Kernel::Config', 18 'Kernel::System::Cache', 19 'Kernel::System::DateTime', 20 'Kernel::System::Log', 21 'Kernel::System::Main', 22); 23 24=head1 NAME 25 26Kernel::System::PDF - pdf lib 27 28=head1 DESCRIPTION 29 30Functions for generating PDF files. 31 32=head1 PUBLIC INTERFACE 33 34=head2 new() 35 36Don't use the constructor directly, use the ObjectManager instead: 37 38 my $PDFObject = $Kernel::OM->Get('Kernel::System::PDF'); 39 40Please note that currently you should only create one PDF object per instance of 41this class. 42 43=cut 44 45sub new { 46 my ( $Type, %Param ) = @_; 47 48 # allocate new hash for object 49 my $Self = {}; 50 bless( $Self, $Type ); 51 52 # read string width cache 53 $Self->{CacheStringWidth} = $Kernel::OM->Get('Kernel::System::Cache')->Get( 54 Type => 'PDF', 55 Key => 'CacheStringWidth', 56 ) || {}; 57 58 return $Self; 59} 60 61=head2 DocumentNew() 62 63Create a new PDF Document 64 65These font aliases are available in all methods: 66 Proportional 67 ProportionalBold 68 ProportionalItalic 69 ProportionalBoldItalic 70 Monospaced 71 MonospacedBold 72 MonospacedItalic 73 MonospacedBoldItalic 74 75 $True = $PDFObject->DocumentNew( 76 Title => 'The Document Title', # Title of PDF Document 77 Encode => 'utf-8', # Charset of Document 78 Testfonts => 1, # (optional) default 0 79 ); 80 81=cut 82 83sub DocumentNew { 84 my ( $Self, %Param ) = @_; 85 86 # check pdf object 87 if ( $Self->{PDF} ) { 88 $Kernel::OM->Get('Kernel::System::Log')->Log( 89 Priority => 'error', 90 Message => 'Can not create new Document!', 91 ); 92 return; 93 } 94 95 # get config object 96 my $ConfigObject = $Kernel::OM->Get('Kernel::Config'); 97 98 # get Product and Version 99 my $PDFCreator = ''; # set to empty value if Secure::DisableBanner is active 100 if ( !$Kernel::OM->Get('Kernel::Config')->Get('Secure::DisableBanner') ) { 101 $PDFCreator = $ConfigObject->Get('Product') . ' ' . $ConfigObject->Get('Version'); 102 } 103 104 # set document title 105 $Self->{Document}->{Title} = $Param{Title} || $PDFCreator; 106 107 # set document encode 108 $Self->{Document}->{Encode} = $Param{Encode} || 'utf-8'; 109 110 # set logo file 111 $Self->{Document}->{LogoFile} = $ConfigObject->Get('PDF::LogoFile'); 112 113 # create a new document 114 $Self->{PDF} = PDF::API2->new(); 115 116 # check pdf object 117 if ( !$Self->{PDF} ) { 118 $Kernel::OM->Get('Kernel::System::Log')->Log( 119 Priority => 'error', 120 Message => 'Can not create new Document: $!', 121 ); 122 return; 123 } 124 125 # get time object 126 my $DateTimeObject = $Kernel::OM->Create('Kernel::System::DateTime'); 127 128 # set document infos 129 $Self->{PDF}->info( 130 'Author' => $PDFCreator, 131 'CreationDate' => "D:" 132 . $DateTimeObject->Format( Format => '%Y%m%d%H:%M:%S' ) 133 . "+01'00'", 134 'Creator' => $PDFCreator, 135 'Producer' => $PDFCreator, 136 'Title' => $Self->{Document}->{Title}, 137 'Subject' => $Self->{Document}->{Title}, 138 ); 139 140 # add font directory 141 my $FontDir = $ConfigObject->Get('Home') . '/var/fonts'; 142 $Self->{PDF}->addFontDirs($FontDir); 143 144 if ( !$Param{Testfonts} ) { 145 146 # get font config 147 my %FontFiles = %{ $ConfigObject->Get('PDF::TTFontFile') }; 148 149 # set fonts 150 for my $FontType ( sort keys %FontFiles ) { 151 $Self->{Font}->{$FontType} = $Self->{PDF}->ttfont( 152 $FontFiles{$FontType}, 153 -encode => $Self->{Document}->{Encode}, 154 -unicodemap => 1, 155 ); 156 } 157 } 158 else { 159 160 # set testfont (only used in unitests) 161 $Self->{Font}->{Testfont1} = $Self->{PDF}->corefont( 162 'Helvetica', 163 -encode => $Self->{Document}->{Encode}, 164 -unicodemap => 1, 165 ); 166 $Self->{Font}->{Testfont2} = $Self->{PDF}->ttfont( 167 'DejaVuSans.ttf', 168 -encode => $Self->{Document}->{Encode}, 169 -unicodemap => 1, 170 ); 171 172 # get font config 173 my %FontFiles = %{ $ConfigObject->Get('PDF::TTFontFile') }; 174 175 # set fonts 176 for my $FontType ( sort keys %FontFiles ) { 177 $Self->{Font}->{$FontType} = $Self->{Font}->{Testfont1}; 178 } 179 } 180 181 return 1; 182} 183 184=head2 PageBlankNew() 185 186Create a new, blank Page 187 188 $True = $PDFObject->PageBlankNew( 189 Width => 200, # (optional) default 595 (Din A4) - _ both or nothing 190 Height => 300, # (optional) default 842 (Din A4) - 191 PageOrientation => 'landscape', # (optional) default normal (normal|landscape) 192 MarginTop => 40, # (optional) default 0 - 193 MarginRight => 40, # (optional) default 0 |_ all or nothing 194 MarginBottom => 40, # (optional) default 0 | 195 MarginLeft => 40, # (optional) default 0 - 196 ShowPageNumber => 0, # (optional) default 1 197 ); 198 199=cut 200 201sub PageBlankNew { 202 my ( $Self, %Param ) = @_; 203 204 if ( !$Self->{PDF} ) { 205 $Kernel::OM->Get('Kernel::System::Log')->Log( 206 Priority => 'error', 207 Message => "Need a PDF Object!" 208 ); 209 return; 210 } 211 212 # set PageOrientation 213 if ( !defined( $Param{PageOrientation} ) ) { 214 $Param{PageOrientation} = 'normal'; 215 } 216 217 # set margins 218 $Param{MarginTop} = $Param{MarginTop} || 0; 219 $Param{MarginRight} = $Param{MarginRight} || 0; 220 $Param{MarginBottom} = $Param{MarginBottom} || 0; 221 $Param{MarginLeft} = $Param{MarginLeft} || 0; 222 223 # create a new page 224 $Self->{Page} = $Self->{PDF}->page(); 225 226 # if page was created 227 if ( $Self->{Page} ) { 228 229 # set new page width and height 230 $Self->_CurPageDimSet( %Param, ); 231 232 # get current page dimension an set mediabox 233 my %Page = $Self->_CurPageDimGet(); 234 $Self->{Page}->mediabox( $Page{Width}, $Page{Height}, ); 235 236 # set default value of ShowPageNumber, if no value given 237 my $ShowPageNumber = 1; 238 if ( defined( $Param{ShowPageNumber} ) && $Param{ShowPageNumber} eq 0 ) { 239 $ShowPageNumber = 0; 240 } 241 242 # set the page numbers 243 $Self->_CurPageNumberSet( 244 ShowPageNumber => $ShowPageNumber, 245 ); 246 247 # set printable dimension 248 $Self->_CurPrintableDimSet( 249 Top => $Param{MarginTop}, 250 Right => $Param{MarginRight}, 251 Bottom => $Param{MarginBottom}, 252 Left => $Param{MarginLeft}, 253 ); 254 255 # set activ dimension 256 $Self->DimSet( 257 Dim => 'content', 258 ); 259 260 return 1; 261 } 262 263 $Kernel::OM->Get('Kernel::System::Log')->Log( 264 Priority => 'error', 265 Message => "Can not create new blank Page!" 266 ); 267 268 return; 269} 270 271=head2 PageNew() 272 273Create a new Page 274 275 $PDFObject->PageNew( 276 Width => 200, # (optional) default 595 (Din A4) 277 Height => 300, # (optional) default 842 (Din A4) 278 PageOrientation => 'landscape', # (optional) default normal (normal|landscape) 279 MarginTop => 40, # (optional) default 0 280 MarginRight => 40, # (optional) default 0 281 MarginBottom => 40, # (optional) default 0 282 MarginLeft => 40, # (optional) default 0 283 ShowPageNumber => 0, # (optional) default 1 284 LogoFile => '/path/to/file.jpg', # (optional) you can use jpg, gif and png-Images 285 HeaderRight => 'Header Right Text', # (optional) 286 HeadlineLeft => 'Headline Text', # (optional) 287 HeadlineRight => 'Headline Text', # (optional) 288 FooterLeft => 'Footer Left Text', # (optional) 289 FooterRight => 'Footer Right Text', # (optional) 290 ); 291 292=cut 293 294sub PageNew { 295 my ( $Self, %Param ) = @_; 296 297 if ( !$Self->{PDF} ) { 298 $Kernel::OM->Get('Kernel::System::Log')->Log( 299 Priority => 'error', 300 Message => "Need a PDF Object!" 301 ); 302 return; 303 } 304 305 my %Data = (); 306 307 # set new page width and height, if values are given 308 if ( $Param{Width} && $Param{Height} ) { 309 $Data{Width} = $Param{Width}; 310 $Data{Height} = $Param{Height}; 311 } 312 313 # set new margin, if values are given 314 if ( $Param{MarginTop} && $Param{MarginRight} && $Param{MarginBottom} && $Param{MarginLeft} ) { 315 $Data{MarginTop} = $Param{MarginTop}; 316 $Data{MarginRight} = $Param{MarginRight}; 317 $Data{MarginBottom} = $Param{MarginBottom}; 318 $Data{MarginLeft} = $Param{MarginLeft}; 319 } 320 if ( $Param{ShowPageNumber} ) { 321 $Data{ShowPageNumber} = $Param{ShowPageNumber}; 322 } 323 if ( $Param{PageOrientation} ) { 324 $Data{PageOrientation} = $Param{PageOrientation}; 325 } 326 327 # create a blank page 328 $Self->PageBlankNew(%Data); 329 if ( !$Self->{PDF} ) { 330 $Kernel::OM->Get('Kernel::System::Log')->Log( 331 Priority => 'error', 332 Message => "Need a Page Object!" 333 ); 334 return; 335 } 336 337 # set activ dimension 338 $Self->DimSet( 339 Dim => 'printable', 340 ); 341 342 # get current printable dimension 343 my %Printable = $Self->_CurPrintableDimGet(); 344 345 # get logofile 346 my $LogoFile = $Self->{Document}->{LogoFile} 347 || $Kernel::OM->Get('Kernel::Config')->Get('Home') . '/var/logo-otrs.png'; 348 349 if ( 350 defined( $Param{LogoFile} ) 351 && -e $Param{LogoFile} 352 && ( 353 $Param{LogoFile} =~ /^.*\.gif$/i 354 || $Param{LogoFile} =~ /^.*\.jpg$/i 355 || $Param{LogoFile} =~ /^.*\.png$/i 356 ) 357 ) 358 { 359 $LogoFile = $Param{LogoFile}; 360 } 361 362 # output the logo image at header left 363 $Self->Image( 364 File => $LogoFile, 365 Width => 700, 366 Height => 100, 367 ); 368 369 if ( $Param{HeaderRight} ) { 370 371 # set new position 372 $Self->PositionSet( 373 Move => 'relativ', 374 X => 168, 375 Y => 15, 376 ); 377 378 # output page header right 379 $Self->Text( 380 Text => $Param{HeaderRight}, 381 Type => 'Cut', 382 Color => '#404040', 383 FontSize => 12, 384 Height => 12, 385 Align => 'right', 386 ); 387 } 388 389 # set new position 390 $Self->PositionSet( 391 X => 'left', 392 Y => 'top', 393 ); 394 395 # set new position 396 $Self->PositionSet( 397 Move => 'relativ', 398 Y => -29, 399 ); 400 401 # output the lines in top of the page 402 $Self->HLine( 403 Color => '#505050', 404 LineWidth => 0.5, 405 ); 406 407 if ( $Param{FooterLeft} ) { 408 409 # set new position 410 $Self->PositionSet( 411 X => 'left', 412 Y => 'bottom', 413 ); 414 415 # set new position 416 $Self->PositionSet( 417 Move => 'relativ', 418 Y => 8, 419 ); 420 421 # output page footer left 422 $Self->Text( 423 Text => $Param{FooterLeft}, 424 Width => ( $Printable{Width} / 4 * 3 ), 425 Type => 'Cut', 426 Color => '#404040', 427 FontSize => 8, 428 Height => 8, 429 Align => 'left', 430 ); 431 } 432 433 if ( $Param{FooterRight} ) { 434 435 # set new position 436 $Self->PositionSet( 437 X => 'left', 438 Y => 'bottom', 439 ); 440 441 # set new position 442 $Self->PositionSet( 443 Move => 'relativ', 444 X => ( $Printable{Width} / 4 * 3 ), 445 Y => 8, 446 ); 447 448 # output page footer right 449 $Self->Text( 450 Text => $Param{FooterRight}, 451 Type => 'Cut', 452 Color => '#404040', 453 FontSize => 8, 454 Height => 8, 455 Align => 'right', 456 ); 457 } 458 459 # set new position 460 $Self->PositionSet( 461 X => 'left', 462 Y => 'bottom', 463 ); 464 465 # set new position 466 $Self->PositionSet( 467 Move => 'relativ', 468 Y => 11, 469 ); 470 471 # output the lines in bottom of the page 472 $Self->HLine( 473 Color => '#505050', 474 LineWidth => 0.5, 475 ); 476 477 if ( $Param{HeadlineLeft} && $Param{HeadlineRight} ) { 478 479 # set new position 480 $Self->PositionSet( 481 X => 'left', 482 Y => 'top', 483 ); 484 485 # set new position 486 $Self->PositionSet( 487 Move => 'relativ', 488 Y => -44, 489 ); 490 $Self->Text( 491 Text => $Param{HeadlineLeft}, 492 Width => ( $Printable{Width} / 2 ), 493 Height => 12, 494 Type => 'Cut', 495 Font => 'ProportionalBold', 496 FontSize => 12, 497 ); 498 $Self->PositionSet( 499 X => 'left', 500 Y => 'top', 501 ); 502 $Self->PositionSet( 503 Move => 'relativ', 504 X => ( $Printable{Width} / 2 ), 505 Y => -48, 506 ); 507 $Self->Text( 508 Text => $Param{HeadlineRight}, 509 Height => 8, 510 Type => 'Cut', 511 Font => 'Proportional', 512 FontSize => 8, 513 Color => '#404040', 514 Align => 'right', 515 ); 516 517 # set new content dimension 518 $Self->_CurContentDimSet( 519 Top => $Printable{Top} + 64, 520 Right => $Printable{Right}, 521 Bottom => $Printable{Bottom} + 16, 522 Left => $Printable{Left}, 523 ); 524 } 525 else { 526 527 # set new content dimension 528 $Self->_CurContentDimSet( 529 Top => $Printable{Top} + 34, 530 Right => $Printable{Right}, 531 Bottom => $Printable{Bottom} + 16, 532 Left => $Printable{Left}, 533 ); 534 } 535 536 # set activ dimension 537 $Self->DimSet( 538 Dim => 'content', 539 ); 540 541 return 1; 542} 543 544=head2 DocumentOutput() 545 546Return the PDF as string 547 548 $DocumentString = $PDFObject->DocumentOutput(); 549 550=cut 551 552sub DocumentOutput { 553 my ( $Self, %Param ) = @_; 554 555 if ( !$Self->{PDF} ) { 556 $Kernel::OM->Get('Kernel::System::Log')->Log( 557 Priority => 'error', 558 Message => "Need a PDF Object!" 559 ); 560 return; 561 } 562 if ( !$Self->{Page} ) { 563 $Kernel::OM->Get('Kernel::System::Log')->Log( 564 Priority => 'error', 565 Message => "Need a Page!" 566 ); 567 return; 568 } 569 570 # return the document as string 571 my $DocumentString = $Self->{PDF}->stringify(); 572 $Self->{PDF}->end(); 573 574 return $DocumentString; 575} 576 577=head2 Table() 578 579Add a table. 580 581In case of missing or misused parameters, C<undef> is returned in scalar context 582and an empty list is returned in list context. 583 584 Return 585 $Return{State} 586 $Return{RequiredWidth} 587 $Return{RequiredHeight} 588 $Return{CellData} # (reference) complete calculated 589 $Return{ColumnData} # (reference) complete calculated 590 591 %Return = $PDFObject->Table( 592 CellData => $CellData, # 2D arrayref (see example) 593 ColumnData => $ColumnData, # arrayref (see example) 594 RowData => $RowData, # arrayref (see example) 595 Type => 'Cut', # (optional) default ReturnLeftOver (ReturnLeftOver|ReturnLeftOverHard|Cut) 596 Width => 300, # (optional) default maximal width 597 Height => 400, # (optional) default minimal height 598 Font => 'Monospaced', # (optional) default Proportional (see DocumentNew()) 599 FontSize => 9, # (optional) default 11 600 FontColor => 'red', # (optional) default black 601 FontColorEven => 'blue', # (optional) cell font color for even rows 602 FontColorOdd => 'green', # (optional) cell font color for odd rows 603 Align => 'right', # (optional) default left (left|center|right) 604 Lead => 3, # (optional) default 1 605 Padding => 18, # (optional) default 3 606 PaddingTop => 10, # (optional) top cell padding, overides Padding 607 PaddingRight => 30, # (optional) right cell padding, overides Padding 608 PaddingBottom => 30, # (optional) bottom cell padding, overides Padding 609 PaddingLeft => 10, # (optional) left cell padding, overides Padding 610 BackgroundColor => '#101010', # (optional) default white 611 BackgroundColorEven => '#F0F0F0', # (optional) cell background color for even rows 612 BackgroundColorOdd => '#A0A0A0', # (optional) cell background color for odd rows 613 Border => 1, # (optional) default 1 (values between 0 and 20) 614 BorderColor => '#FF0000', # (optional) default black 615 ); 616 617 $CellData = [ 618 [ 619 { 620 Content => "Cell 1 (Row 1, Column 1)", # (optional) 621 Font => 'Monospaced', # (optional) (see DocumentNew()) 622 FontSize => 13, # (optional) 623 FontColor => '#00FF00', # (optional) 624 Align => 'center', # (optional) 625 Lead => 7, # (optional) 626 BackgroundColor => '#101010', # (optional) 627 }, 628 { 629 Content => "Cell 2 (Row 1, Column 2)", 630 }, 631 ], 632 [ 633 { 634 Content => "Cell 3 (Row 2, Column 1)", 635 }, 636 { 637 Content => "Cell 4 (Row 2, Column 2)", 638 }, 639 ], 640 ]; 641 642 $ColumData = [ # this array was automaticly generated, if not given 643 { 644 Width => 11, # (optional) 645 }, 646 { 647 Width => 44, 648 }, 649 ]; 650 651 $RowData = [ # this array was automaticly generated, if not given 652 { 653 Height => 11, # (optional) 654 }, 655 { 656 Height => 44, 657 }, 658 ]; 659 660=cut 661 662sub Table { 663 my ( $Self, %Param ) = @_; 664 665 # check needed stuff 666 for (qw(CellData)) { 667 if ( !defined( $Param{$_} ) ) { 668 $Kernel::OM->Get('Kernel::System::Log')->Log( 669 Priority => 'error', 670 Message => "Need $_!" 671 ); 672 $Param{State} = 1; 673 return; 674 } 675 } 676 if ( !$Self->{PDF} ) { 677 $Kernel::OM->Get('Kernel::System::Log')->Log( 678 Priority => 'error', 679 Message => "Need a PDF Document!" 680 ); 681 $Param{State} = 1; 682 return; 683 } 684 if ( !$Self->{Page} ) { 685 $Kernel::OM->Get('Kernel::System::Log')->Log( 686 Priority => 'error', 687 Message => "Need a Page!" 688 ); 689 $Param{State} = 1; 690 return; 691 } 692 693 my %Dim; 694 695 # get dimension (printable or content) 696 if ( $Self->DimGet() eq 'printable' ) { 697 %Dim = $Self->_CurPrintableDimGet(); 698 } 699 else { 700 %Dim = $Self->_CurContentDimGet(); 701 } 702 703 # get current position 704 my %Position = $Self->_CurPositionGet(); 705 706 # set default values 707 $Param{ColumnData} ||= []; 708 $Param{RowData} ||= []; 709 710 if ( 711 ref( $Param{CellData} ) eq 'ARRAY' 712 && ref( $Param{ColumnData} ) eq 'ARRAY' 713 && ref( $Param{RowData} ) eq 'ARRAY' 714 ) 715 { 716 if ( !defined( $Param{OutputCount} ) ) { 717 718 # set default values 719 $Param{Type} ||= 'ReturnLeftOver'; 720 $Param{Font} ||= 'Proportional'; 721 if ( !defined( $Param{FontSize} ) || $Param{FontSize} <= 0 ) { 722 $Param{FontSize} = 10; 723 } 724 if ( !defined( $Param{Lead} ) || $Param{Lead} < -( $Param{FontSize} ) ) { 725 $Param{Lead} = int( $Param{FontSize} / 4 ); 726 if ( $Param{Lead} < 1 ) { 727 $Param{Lead} = 1; 728 } 729 } 730 $Param{FontColor} ||= 'black'; 731 $Param{FontColorOdd} ||= $Param{FontColor}; 732 $Param{FontColorEven} ||= $Param{FontColor}; 733 734 $Param{BackgroundColor} ||= 'NULL'; 735 $Param{BackgroundColorOdd} ||= $Param{BackgroundColor}; 736 $Param{BackgroundColorEven} ||= $Param{BackgroundColor}; 737 738 $Param{Align} = $Param{Align} || 'left'; 739 740 if ( !defined( $Param{Border} ) || $Param{Border} < 0 ) { 741 $Param{Border} = 1; 742 } 743 $Param{BorderColor} ||= 'black'; 744 $Param{PaddingTop} ||= $Param{Padding} || 3; 745 $Param{PaddingRight} ||= $Param{Padding} || 3; 746 $Param{PaddingBottom} ||= $Param{Padding} || 3; 747 $Param{PaddingLeft} ||= $Param{Padding} || 3; 748 749 # check given Width 750 my $DefaultWidth = $Dim{Left} + $Dim{Width} - $Position{X}; 751 if ( 752 !defined( $Param{Width} ) 753 || ( 754 $Param{Width} 755 - $Param{PaddingLeft} 756 - $Param{PaddingRight} 757 - ( 2 * $Param{Border} ) 758 ) 759 < 0 760 || $Param{Width} > $DefaultWidth 761 ) 762 { 763 $Param{Width} = $DefaultWidth; 764 } 765 766 # set output count 767 $Param{OutputCount} = 0; 768 769 # set state 770 $Param{State} = 0; 771 772 # calculate required table attributes 773 $Self->_TableCalculate( %Param, ); 774 } 775 776 # check given Height 777 my $DefaultHeight = $Position{Y} - $Dim{Bottom}; 778 if ( 779 !defined( $Param{Height} ) 780 || ( 781 $Param{Height} 782 - $Param{PaddingTop} 783 - $Param{PaddingBottom} 784 - ( 2 * $Param{Border} ) 785 ) 786 < 0 787 || $Param{Height} > $DefaultHeight 788 ) 789 { 790 $Param{Height} = $DefaultHeight; 791 } 792 793 # get maximum number of pages 794 my $MaxPages = $Kernel::OM->Get('Kernel::Config')->Get('PDF::MaxPages'); 795 796 if ( !$MaxPages || $MaxPages < 1 || $MaxPages > 1000 ) { 797 $MaxPages = 100; 798 } 799 800 # infinite loop protection 801 if ( $Param{OutputCount} < $MaxPages ) { 802 my %Block = $Self->_TableBlockNextCalculate( 803 CellData => $Param{CellData}, 804 ColumnData => $Param{ColumnData}, 805 ); 806 807 # if active cells found 808 if ( $Block{State} ) { 809 810 # start row output 811 my $Row = $Block{ReturnRowStart}; 812 my $RowCounter = 0; 813 my $RowLoop = 1; 814 my $LastBlock = $Param{ColumnData}->[ $#{ $Param{ColumnData} } ]->{Block}; 815 my $LastRow = $#{ $Param{RowData} }; 816 817 while ($RowLoop) { 818 819 # stop loop, if last row 820 if ( $Row <= $LastRow ) { 821 822 # calculate row height, if block is 0 823 if ( !$Block{ReturnBlock} ) { 824 $Self->_TableRowCalculate( 825 Row => $Row, 826 %Param, 827 ); 828 } 829 830 # save old position 831 my %PositionOld = %Position; 832 if ( 833 $Param{RowData}->[$Row]->{OutputHeight} 834 && $Param{RowData}->[$Row]->{OutputHeight} <= $Position{Y} - $Dim{Bottom} 835 ) 836 { 837 for ( $Block{ReturnColumnStart} .. $Block{ReturnColumnStop} ) { 838 my $Column = $_; 839 $Self->_TableCellOutput( 840 Text => $Param{CellData}->[$Row]->[$Column]->{Content}, 841 Type => $Param{CellData}->[$Row]->[$Column]->{Type}, 842 Width => $Param{ColumnData}->[$Column]->{OutputWidth}, 843 Height => $Param{RowData}->[$Row]->{OutputHeight}, 844 Font => $Param{CellData}->[$Row]->[$Column]->{Font}, 845 FontSize => $Param{CellData}->[$Row]->[$Column]->{FontSize}, 846 FontColor => $Param{CellData}->[$Row]->[$Column]->{FontColor}, 847 Align => $Param{CellData}->[$Row]->[$Column]->{Align}, 848 Lead => $Param{CellData}->[$Row]->[$Column]->{Lead}, 849 PaddingTop => $Param{PaddingTop}, 850 PaddingRight => $Param{PaddingRight}, 851 PaddingBottom => $Param{PaddingBottom}, 852 PaddingLeft => $Param{PaddingLeft}, 853 BackgroundColor => 854 $Param{CellData}->[$Row]->[$Column]->{BackgroundColor}, 855 Border => $Param{Border}, 856 BorderColor => $Param{BorderColor}, 857 ); 858 859 # deactivate cell and delete content 860 $Param{CellData}->[$Row]->[$Column]->{Off} = 1; 861 $Param{CellData}->[$Row]->[$Column]->{Content} = ' '; 862 863 # set new position 864 $Self->_CurPositionSet( 865 X => $Position{X} 866 + $Param{ColumnData}->[$Column]->{OutputWidth} 867 - $Param{Border}, 868 Y => $Position{Y}, 869 ); 870 871 # get current position 872 %Position = $Self->_CurPositionGet(); 873 } 874 875 # set new position 876 $Self->_CurPositionSet( 877 X => $PositionOld{X}, 878 Y => $PositionOld{Y} 879 - $Param{RowData}->[$Row]->{OutputHeight} 880 + $Param{Border}, 881 ); 882 883 # get current position 884 %Position = $Self->_CurPositionGet(); 885 } 886 else { 887 my $NewOutputHeight = $Position{Y} - $Dim{Bottom}; 888 my $NewTextHeight = $NewOutputHeight 889 - $Param{PaddingTop} 890 - $Param{PaddingBottom} 891 - ( 2 * $Param{Border} ); 892 893 if ( $NewTextHeight > $Param{RowData}->[$Row]->{MinFontSize} ) { 894 for ( $Block{ReturnColumnStart} .. $Block{ReturnColumnStop} ) { 895 my $Column = $_; 896 my $Type = 'ReturnLeftOver'; 897 if ( 898 $Param{CellData}->[$Row]->[$Column]->{Type} eq 899 'ReturnLeftOverHard' 900 ) 901 { 902 $Type = 'ReturnLeftOverHard'; 903 } 904 my %Return = $Self->_TableCellOutput( 905 Text => $Param{CellData}->[$Row]->[$Column]->{Content}, 906 Type => $Type, 907 Width => $Param{ColumnData}->[$Column]->{OutputWidth}, 908 Height => $NewOutputHeight, 909 Font => $Param{CellData}->[$Row]->[$Column]->{Font}, 910 FontSize => $Param{CellData}->[$Row]->[$Column]->{FontSize}, 911 FontColor => 912 $Param{CellData}->[$Row]->[$Column]->{FontColor}, 913 Align => $Param{CellData}->[$Row]->[$Column]->{Align}, 914 Lead => $Param{CellData}->[$Row]->[$Column]->{Lead}, 915 PaddingTop => $Param{PaddingTop}, 916 PaddingRight => $Param{PaddingRight}, 917 PaddingBottom => $Param{PaddingBottom}, 918 PaddingLeft => $Param{PaddingLeft}, 919 BackgroundColor => 920 $Param{CellData}->[$Row]->[$Column]->{BackgroundColor}, 921 Border => $Param{Border}, 922 BorderColor => $Param{BorderColor}, 923 ); 924 925 # set new content 926 if ( !$Return{State} ) { 927 $Param{CellData}->[$Row]->[$Column]->{Content} = $Return{LeftOver}; 928 } 929 else { 930 $Param{CellData}->[$Row]->[$Column]->{Content} = ' '; 931 } 932 933 # correcting content 934 if ( $Param{CellData}->[$Row]->[$Column]->{Content} eq '' ) { 935 $Param{CellData}->[$Row]->[$Column]->{Content} = ' '; 936 } 937 $Param{CellData}->[$Row]->[$Column]->{TmpOff} = 1; 938 939 # recalculate height 940 if ( 941 $Block{ReturnBlock} eq $LastBlock 942 && $Column eq $Block{ReturnColumnStop} 943 ) 944 { 945 946 # if Height was given 947 if ( $Param{RowData}->[$Row]->{Height} > 0 ) { 948 $Param{RowData}->[$Row]->{Height} -= $NewTextHeight; 949 950 # if rest too small, deactivate all cells of this row 951 if ( 952 $Param{RowData}->[$Row]->{Height} 953 < $Param{RowData}->[$Row]->{MinFontSize} 954 ) 955 { 956 for my $CellOff ( @{ $Param{CellData}->[$Row] } ) { 957 $CellOff->{Content} = ' '; 958 $CellOff->{Off} = 1; 959 $CellOff->{Tmp} = 0; 960 } 961 } 962 } 963 $Self->_TableRowCalculate( 964 Row => $Row, 965 %Param, 966 ); 967 } 968 969 # set new position 970 $Self->_CurPositionSet( 971 X => $Position{X} 972 + $Param{ColumnData}->[$Column]->{OutputWidth} 973 - $Param{Border}, 974 Y => $Position{Y}, 975 ); 976 977 # get current position 978 %Position = $Self->_CurPositionGet(); 979 } 980 } 981 $RowLoop = 0; 982 } 983 } 984 else { 985 $RowLoop = 0; 986 } 987 988 if ( $RowCounter > 100 ) { 989 $Kernel::OM->Get('Kernel::System::Log')->Log( 990 Priority => 'error', 991 Message => 992 "Too much row loops on page! Infinite Loop protection. Table Output aborted." 993 ); 994 $RowLoop = 0; 995 } 996 997 # increment Row and RowCounter 998 $Row++; 999 $RowCounter++; 1000 } 1001 } 1002 else { 1003 $Kernel::OM->Get('Kernel::System::Log')->Log( 1004 Priority => 'error', 1005 Message => "No active cells! Table Output aborted." 1006 ); 1007 $Param{State} = 1; 1008 } 1009 } 1010 else { 1011 $Kernel::OM->Get('Kernel::System::Log')->Log( 1012 Priority => 'error', 1013 Message => "Too much loops! Infinite Loop protection. Table Output aborted." 1014 ); 1015 $Param{State} = 1; 1016 } 1017 } 1018 else { 1019 $Kernel::OM->Get('Kernel::System::Log')->Log( 1020 Priority => 'error', 1021 Message => 1022 "Need array references of CellData, ColumnData and RowData! Table Output aborted." 1023 ); 1024 $Param{State} = 1; 1025 } 1026 1027 # count remaining cells 1028 my $RemainingCells = $Self->_TableCellOnCount( 1029 CellData => $Param{CellData}, 1030 ); 1031 1032 # set state 1033 if ( !$RemainingCells ) { 1034 $Param{State} = 1; 1035 } 1036 1037 $Param{OutputCount}++; 1038 1039 return %Param; 1040} 1041 1042=head2 Text() 1043 1044Output a text line 1045 1046 Return 1047 $Return{State} 1048 $Return{RequiredWidth} 1049 $Return{RequiredHeight} 1050 $Return{LeftOver} 1051 1052 %Return = $PDFObject->Text( 1053 Text => 'Text', # Text 1054 Width => 300, # (optional) available width of textblock 1055 Height => 200, # (optional) available height of textblock 1056 Type => 'Cut', # (optional) default ReturnLeftOver (ReturnLeftOver|ReturnLeftOverHard|Cut) 1057 Font => 'ProportionalBold', # (optional) default Proportional (see DocumentNew()) 1058 FontSize => 15, # (optional) default 10 1059 Color => '#FF0000', # (optional) default #000000 1060 Align => 'center', # (optional) default left (left|center|right) 1061 Lead => 20, # (optional) default 1 distance between lines 1062 ); 1063 1064=cut 1065 1066sub Text { 1067 my ( $Self, %Param ) = @_; 1068 1069 # check needed stuff 1070 for (qw(Text)) { 1071 if ( !defined( $Param{$_} ) ) { 1072 $Kernel::OM->Get('Kernel::System::Log')->Log( 1073 Priority => 'error', 1074 Message => "Need $_!" 1075 ); 1076 return; 1077 } 1078 } 1079 if ( !$Self->{PDF} ) { 1080 $Kernel::OM->Get('Kernel::System::Log')->Log( 1081 Priority => 'error', 1082 Message => "Need a PDF Document!" 1083 ); 1084 return; 1085 } 1086 if ( !$Self->{Page} ) { 1087 $Kernel::OM->Get('Kernel::System::Log')->Log( 1088 Priority => 'error', 1089 Message => "Need a Page!" 1090 ); 1091 return; 1092 } 1093 1094 my %Dim; 1095 1096 # get dimension (printable or content) 1097 if ( $Self->DimGet() eq 'printable' ) { 1098 %Dim = $Self->_CurPrintableDimGet(); 1099 } 1100 else { 1101 %Dim = $Self->_CurContentDimGet(); 1102 } 1103 1104 # get current position 1105 my %Position = $Self->_CurPositionGet(); 1106 1107 $Param{Type} = $Param{Type} || 'ReturnLeftOver'; 1108 $Param{Color} = $Param{Color} || 'black'; 1109 $Param{Font} = $Param{Font} || 'Proportional'; 1110 $Param{Align} = $Param{Align} || 'left'; 1111 1112 if ( !defined( $Param{FontSize} ) || $Param{FontSize} <= 0 ) { 1113 $Param{FontSize} = 10; 1114 } 1115 if ( !defined( $Param{Lead} ) || $Param{Lead} < -( $Param{FontSize} ) ) { 1116 $Param{Lead} = int( $Param{FontSize} / 4 ); 1117 if ( $Param{Lead} < 1 ) { 1118 $Param{Lead} = 1; 1119 } 1120 } 1121 1122 # check Width 1123 if ( 1124 !defined( $Param{Width} ) 1125 || $Param{Width} < 0 1126 || ( $Position{X} + $Param{Width} ) >= ( $Dim{Left} + $Dim{Width} ) 1127 ) 1128 { 1129 $Param{Width} = $Dim{Left} + $Dim{Width} - $Position{X}; 1130 } 1131 1132 # check Height 1133 if ( 1134 !defined( $Param{Height} ) 1135 || $Param{Height} < 0 1136 || ( $Position{Y} - $Param{Height} ) < $Dim{Bottom} 1137 ) 1138 { 1139 $Param{Height} = $Position{Y} - $Dim{Bottom}; 1140 } 1141 1142 # calculate the given text 1143 my %Return = $Self->_TextCalculate( 1144 Text => $Param{Text}, 1145 Type => $Param{Type}, 1146 Width => $Param{Width}, 1147 Height => $Param{Height}, 1148 Font => $Param{Font}, 1149 FontSize => $Param{FontSize}, 1150 Lead => $Param{Lead}, 1151 ); 1152 1153 if ( $Return{LeftOver} ne $Param{Text} ) { 1154 1155 # create a text object 1156 my $Text = $Self->{Page}->text(); 1157 1158 # set font and fontsize 1159 $Text->font( $Self->{Font}->{ $Param{Font} }, $Param{FontSize} ); 1160 1161 # set fontcolor 1162 $Text->fillcolor( $Param{Color} ); 1163 1164 # save original X position 1165 my $PositionX = $Position{X}; 1166 1167 my $Counter1 = 0; 1168 for my $Row ( @{ $Return{PossibleRows} } ) { 1169 1170 # calculate width of row 1171 my $RowWidth = $Self->_StringWidth( 1172 Text => $Row, 1173 Font => $Param{Font}, 1174 FontSize => $Param{FontSize}, 1175 ); 1176 1177 if ( $Param{Align} eq 'right' ) { 1178 1179 # set new position 1180 $Self->_CurPositionSet( 1181 X => $PositionX + $Param{Width} - $RowWidth, 1182 ); 1183 } 1184 elsif ( $Param{Align} eq 'center' ) { 1185 1186 # set new position 1187 $Self->_CurPositionSet( 1188 X => $PositionX + ( ( $Param{Width} - $RowWidth ) / 2 ), 1189 ); 1190 } 1191 1192 # set new position 1193 if ( $Counter1 > 0 ) { 1194 $Self->_CurPositionSet( 1195 Y => $Position{Y} - $Param{FontSize} - $Param{Lead}, 1196 ); 1197 } 1198 else { 1199 $Self->_CurPositionSet( 1200 Y => $Position{Y} - $Param{FontSize}, 1201 ); 1202 } 1203 1204 # get current position 1205 %Position = $Self->_CurPositionGet(); 1206 1207 # get to position 1208 $Text->translate( $Position{X}, $Position{Y} ); 1209 1210 # output text 1211 $Text->text($Row); 1212 1213 $Counter1++; 1214 } 1215 1216 # set new position 1217 $Self->_CurPositionSet( 1218 X => $PositionX, 1219 ); 1220 } 1221 1222 return %Return; 1223} 1224 1225=head2 Image() 1226 1227Output a image 1228 1229 $True = $PDFObject->Image( 1230 File => '/path/image.gif', # (gif|jpg|png) 1231 Type => 'ReturnFalse' # (optional) default Reduce (ReturnFalse|Reduce) 1232 Width => 300, # width of image 1233 Height => 150, # height of image 1234 ); 1235 1236=cut 1237 1238sub Image { 1239 my ( $Self, %Param ) = @_; 1240 1241 # check needed stuff 1242 for (qw(File Width Height)) { 1243 if ( !defined( $Param{$_} ) ) { 1244 $Kernel::OM->Get('Kernel::System::Log')->Log( 1245 Priority => 'error', 1246 Message => "Need $_!" 1247 ); 1248 return; 1249 } 1250 } 1251 if ( !$Self->{PDF} ) { 1252 $Kernel::OM->Get('Kernel::System::Log')->Log( 1253 Priority => 'error', 1254 Message => "Need a PDF Document!" 1255 ); 1256 return; 1257 } 1258 if ( !$Self->{Page} ) { 1259 $Kernel::OM->Get('Kernel::System::Log')->Log( 1260 Priority => 'error', 1261 Message => "Need a Page!" 1262 ); 1263 return; 1264 } 1265 if ( !-e $Param{File} ) { 1266 $Kernel::OM->Get('Kernel::System::Log')->Log( 1267 Priority => 'error', 1268 Message => "File $Param{File} not found!" 1269 ); 1270 return; 1271 } 1272 1273 my %Dim; 1274 1275 # get dimension (printable or content) 1276 if ( $Self->DimGet() eq 'printable' ) { 1277 %Dim = $Self->_CurPrintableDimGet(); 1278 } 1279 else { 1280 %Dim = $Self->_CurContentDimGet(); 1281 } 1282 1283 $Param{Width} = $Param{Width} / ( 300 / 72 ); 1284 $Param{Height} = $Param{Height} / ( 300 / 72 ); 1285 1286 my $Image = $Self->{Page}->gfx(); 1287 my $ImageFile; 1288 1289 # if image already used, use the existing image object 1290 if ( defined( $Self->{CacheImageObject}->{ $Param{File} } ) ) { 1291 $ImageFile = $Self->{CacheImageObject}->{ $Param{File} }; 1292 } 1293 else { 1294 if ( $Param{File} =~ /^.*\.gif$/i ) { 1295 $ImageFile = $Self->{PDF}->image_gif( $Param{File} ); 1296 } 1297 elsif ( $Param{File} =~ /^.*\.jpg$/i ) { 1298 $ImageFile = $Self->{PDF}->image_jpeg( $Param{File} ); 1299 } 1300 elsif ( $Param{File} =~ /^.*\.png$/i ) { 1301 $ImageFile = $Self->{PDF}->image_png( $Param{File} ); 1302 } 1303 else { 1304 $Kernel::OM->Get('Kernel::System::Log')->Log( 1305 Priority => 'error', 1306 Message => "Imagetype of File $Param{File} not supported", 1307 ); 1308 return; 1309 } 1310 1311 # cache image object 1312 $Self->{CacheImageObject}->{ $Param{File} } = $ImageFile; 1313 } 1314 1315 # get current position 1316 my %Position = $Self->_CurPositionGet(); 1317 1318 my $Reduce = 0; 1319 1320 # check values 1321 if ( ( $Position{X} + $Param{Width} ) >= ( $Dim{Left} + $Dim{Width} ) ) { 1322 $Param{Width} = $Dim{Left} + $Dim{Width} - $Position{X}; 1323 $Reduce = 1; 1324 } 1325 if ( $Param{Width} < 1 ) { 1326 $Param{Width} = 1; 1327 } 1328 1329 if ( ( $Position{Y} - $Param{Height} ) <= $Dim{Bottom} ) { 1330 $Param{Height} = $Position{Y} - $Dim{Bottom}; 1331 $Reduce = 1; 1332 } 1333 if ( $Param{Height} < 1 ) { 1334 $Param{Height} = 1; 1335 } 1336 1337 my $Return = 1; 1338 1339 if ( defined( $Param{Type} ) && $Param{Type} eq 'ReturnFalse' && $Reduce ) { 1340 $Return = 0; 1341 } 1342 else { 1343 1344 # output the image 1345 $Image->image( 1346 $ImageFile, $Position{X}, $Position{Y} - $Param{Height}, 1347 $Param{Width}, $Param{Height}, 1348 ); 1349 1350 # set new position 1351 $Self->_CurPositionSet( 1352 Y => $Position{Y} - $Param{Height}, 1353 ); 1354 } 1355 1356 return $Return; 1357} 1358 1359=head2 HLine() 1360 1361Output a horizontal line 1362 1363 $True = $PDFObject->HLine( 1364 Width => 300, # (optional) default 'end of printable dimension' 1365 Type => 'ReturnFalse' # (optional) default Cut (ReturnFalse|Cut) 1366 Color => '#101010', # (optional) default black 1367 LineWidth => 1, # (optional) default 1 1368 ); 1369 1370=cut 1371 1372sub HLine { 1373 my ( $Self, %Param ) = @_; 1374 1375 if ( !$Self->{PDF} ) { 1376 $Kernel::OM->Get('Kernel::System::Log')->Log( 1377 Priority => 'error', 1378 Message => "Need a PDF Document!", 1379 ); 1380 return; 1381 } 1382 if ( !$Self->{Page} ) { 1383 $Kernel::OM->Get('Kernel::System::Log')->Log( 1384 Priority => 'error', 1385 Message => "Need a Page!", 1386 ); 1387 return; 1388 } 1389 1390 my %Dim; 1391 1392 # get current position 1393 my %Position = $Self->_CurPositionGet(); 1394 1395 # get dimension (printable or content) 1396 if ( $Self->DimGet() eq 'printable' ) { 1397 %Dim = $Self->_CurPrintableDimGet(); 1398 } 1399 else { 1400 %Dim = $Self->_CurContentDimGet(); 1401 } 1402 1403 # set default color 1404 $Param{Color} = $Param{Color} || 'black'; 1405 1406 # check LineWidth 1407 if ( !defined( $Param{LineWidth} ) || $Param{LineWidth} <= 0 || $Param{LineWidth} > 100 ) { 1408 $Param{LineWidth} = 1; 1409 } 1410 1411 my $Cut = 0; 1412 1413 if ( $Position{Y} - $Param{LineWidth} < $Dim{Bottom} ) { 1414 $Param{LineWidth} = $Position{Y} - $Dim{Bottom}; 1415 if ( $Param{LineWidth} < 1 ) { 1416 $Param{LineWidth} = 1; 1417 } 1418 $Cut = 1; 1419 } 1420 $Param{LineWidth} = 0 - $Param{LineWidth}; 1421 1422 # check Width 1423 if ( defined( $Param{Width} ) && $Param{Width} >= 1 ) { 1424 if ( $Position{X} + $Param{Width} > $Dim{Left} + $Dim{Width} ) { 1425 $Param{Width} = $Dim{Left} + $Dim{Width} - $Position{X}; 1426 $Cut = 1; 1427 } 1428 } 1429 else { 1430 $Param{Width} = $Param{Width} = $Dim{Left} + $Dim{Width} - $Position{X}; 1431 } 1432 1433 # output the lines in top and bottom of the page 1434 my $Line = $Self->{Page}->gfx(); 1435 $Line->fillcolor( $Param{Color} ); 1436 1437 # check values 1438 my $Output = 0; 1439 if ( 1440 $Self->DimGet() eq 'printable' 1441 && $Self->_CurPrintableDimCheck( 1442 X => $Position{X}, 1443 Y => $Position{Y} 1444 ) 1445 && $Self->_CurPrintableDimCheck( 1446 X => $Position{X} + $Param{Width}, 1447 Y => $Position{Y} - $Param{LineWidth} 1448 ) 1449 ) 1450 { 1451 $Output = 1; 1452 } 1453 elsif ( 1454 $Self->_CurContentDimCheck( 1455 X => $Position{X}, 1456 Y => $Position{Y} 1457 ) 1458 && $Self->_CurContentDimCheck( 1459 X => $Position{X} + $Param{Width}, 1460 Y => $Position{Y} - $Param{LineWidth} 1461 ) 1462 ) 1463 { 1464 $Output = 1; 1465 } 1466 1467 if ( defined( $Param{Type} ) && $Param{Type} eq 'ReturnFalse' && $Cut ) { 1468 $Output = 1; 1469 } 1470 1471 if ($Output) { 1472 1473 # output line 1474 $Line->rect( $Position{X}, $Position{Y}, $Param{Width}, $Param{LineWidth} ); 1475 $Line->fill(); 1476 1477 # set new position 1478 $Self->_CurPositionSet( 1479 Y => $Position{Y} - $Param{LineWidth}, 1480 ); 1481 } 1482 1483 return $Output; 1484} 1485 1486=head2 PositionSet() 1487 1488Set new position on current page 1489 1490 $True = $PDFObject->PositionSet( 1491 Move => 'absolut', # (optional) default absolut (absolut|relativ) 1492 X => 10, # (optional) (<integer>|left|center|right) 1493 Y => 20, # (optional) (<integer>|top|middle|bottom) 1494 ); 1495 1496=cut 1497 1498sub PositionSet { 1499 my ( $Self, %Param ) = @_; 1500 1501 if ( !$Self->{PDF} ) { 1502 $Kernel::OM->Get('Kernel::System::Log')->Log( 1503 Priority => 'error', 1504 Message => "Need a PDF Document!", 1505 ); 1506 return; 1507 } 1508 if ( !$Self->{Page} ) { 1509 $Kernel::OM->Get('Kernel::System::Log')->Log( 1510 Priority => 'error', 1511 Message => "Need a Page!", 1512 ); 1513 return; 1514 } 1515 1516 my %Data; 1517 my %Dim; 1518 my %Position = $Self->_CurPositionGet(); 1519 1520 # get dimension (printable or content) 1521 if ( $Self->DimGet() eq 'printable' ) { 1522 $Data{Dim} = 'printable'; 1523 %Dim = $Self->_CurPrintableDimGet(); 1524 } 1525 else { 1526 $Data{Dim} = 'content'; 1527 %Dim = $Self->_CurContentDimGet(); 1528 } 1529 1530 if ( defined( $Param{X} ) ) { 1531 if ( $Param{X} eq 'left' ) { 1532 $Data{X} = $Dim{Left}; 1533 } 1534 elsif ( $Param{X} eq 'center' ) { 1535 $Data{X} = ( $Dim{Width} / 2 ) + $Dim{Left}; 1536 } 1537 elsif ( $Param{X} eq 'right' ) { 1538 $Data{X} = $Dim{Left} + $Dim{Width}; 1539 } 1540 else { 1541 if ( defined( $Param{Move} ) && $Param{Move} eq 'relativ' ) { 1542 if ( 1543 ( $Position{X} + $Param{X} ) 1544 >= $Dim{Left} 1545 && ( $Position{X} + $Param{X} ) < ( $Dim{Left} + $Dim{Width} ) 1546 ) 1547 { 1548 $Data{X} = $Position{X} + $Param{X}; 1549 } 1550 elsif ( ( $Position{X} + $Param{X} ) >= ( $Dim{Left} + $Dim{Width} ) ) { 1551 $Data{X} = $Dim{Left} + $Dim{Width}; 1552 } 1553 else { 1554 $Data{X} = $Dim{Left}; 1555 } 1556 } 1557 else { 1558 if ( $Param{X} >= $Dim{Left} && $Param{X} < ( $Dim{Left} + $Dim{Width} ) ) { 1559 $Data{X} = $Param{X}; 1560 } 1561 elsif ( $Param{X} >= ( $Dim{Left} + $Dim{Width} ) ) { 1562 $Data{X} = $Dim{Left} + $Dim{Width}; 1563 } 1564 else { 1565 $Data{X} = $Dim{Left}; 1566 } 1567 } 1568 } 1569 } 1570 1571 if ( defined( $Param{Y} ) ) { 1572 if ( $Param{Y} eq 'top' ) { 1573 $Data{Y} = $Dim{Bottom} + $Dim{Height}; 1574 } 1575 elsif ( $Param{Y} eq 'middle' ) { 1576 $Data{Y} = ( $Dim{Height} / 2 ) + $Dim{Bottom}; 1577 } 1578 elsif ( $Param{Y} eq 'bottom' ) { 1579 $Data{Y} = $Dim{Bottom}; 1580 } 1581 else { 1582 if ( defined( $Param{Move} ) && $Param{Move} eq 'relativ' ) { 1583 if ( 1584 ( $Position{Y} + $Param{Y} ) 1585 <= ( $Dim{Bottom} + $Dim{Height} ) 1586 && ( $Position{Y} + $Param{Y} ) > $Dim{Bottom} 1587 ) 1588 { 1589 $Data{Y} = $Position{Y} + $Param{Y}; 1590 } 1591 elsif ( ( $Position{Y} + $Param{Y} ) <= $Dim{Bottom} ) { 1592 $Data{Y} = $Dim{Bottom}; 1593 } 1594 else { 1595 $Data{Y} = $Dim{Bottom} + $Dim{Height}; 1596 } 1597 } 1598 else { 1599 if ( $Param{Y} > $Dim{Bottom} && $Param{Y} <= ( $Dim{Bottom} + $Dim{Height} ) ) { 1600 $Data{Y} = $Param{Y}; 1601 } 1602 elsif ( $Param{Y} <= $Dim{Bottom} ) { 1603 $Data{Y} = $Dim{Bottom}; 1604 } 1605 else { 1606 $Data{Y} = $Dim{Bottom} + $Dim{Height}; 1607 } 1608 } 1609 } 1610 } 1611 1612 $Self->_CurPositionSet( %Data, ); 1613 1614 return 1; 1615} 1616 1617=head2 PositionGet() 1618 1619Get position on current page 1620 1621 Return 1622 $Position{X} 1623 $Position{Y} 1624 1625 %Position = $PDFObject->PositionGet(); 1626 1627=cut 1628 1629sub PositionGet { 1630 my ( $Self, %Param ) = @_; 1631 1632 if ( !$Self->{PDF} ) { 1633 $Kernel::OM->Get('Kernel::System::Log')->Log( 1634 Priority => 'error', 1635 Message => "Need a PDF Document!", 1636 ); 1637 return; 1638 } 1639 if ( !$Self->{Page} ) { 1640 $Kernel::OM->Get('Kernel::System::Log')->Log( 1641 Priority => 'error', 1642 Message => "Need a Page!", 1643 ); 1644 return; 1645 } 1646 1647 my %Position = $Self->_CurPositionGet(); 1648 1649 return %Position; 1650} 1651 1652=head2 DimSet() 1653 1654Set active dimension 1655 1656 $Dim = $PDFObject->DimSet( 1657 Dim => 'printable', # (optional) default content (content|printable) 1658 ); 1659 1660=cut 1661 1662sub DimSet { 1663 my ( $Self, %Param ) = @_; 1664 1665 if ( !$Self->{PDF} ) { 1666 $Kernel::OM->Get('Kernel::System::Log')->Log( 1667 Priority => 'error', 1668 Message => "Need a PDF Document!", 1669 ); 1670 return; 1671 } 1672 if ( !$Self->{Page} ) { 1673 $Kernel::OM->Get('Kernel::System::Log')->Log( 1674 Priority => 'error', 1675 Message => "Need a Page!", 1676 ); 1677 return; 1678 } 1679 1680 if ( defined( $Param{Dim} ) && $Param{Dim} eq 'printable' ) { 1681 $Self->{Current}->{Dim} = 'printable'; 1682 } 1683 else { 1684 $Self->{Current}->{Dim} = 'content'; 1685 } 1686 1687 return $Self->{Current}->{Dim}; 1688} 1689 1690=head2 DimGet() 1691 1692Get active dimension (printable or content) 1693 1694 $Dim = $PDFObject->DimGet(); 1695 1696=cut 1697 1698sub DimGet { 1699 my ( $Self, %Param ) = @_; 1700 1701 if ( !$Self->{PDF} ) { 1702 $Kernel::OM->Get('Kernel::System::Log')->Log( 1703 Priority => 'error', 1704 Message => "Need a PDF Document!" 1705 ); 1706 return; 1707 } 1708 if ( !$Self->{Page} ) { 1709 $Kernel::OM->Get('Kernel::System::Log')->Log( 1710 Priority => 'error', 1711 Message => "Need a Page!" 1712 ); 1713 return; 1714 } 1715 1716 if ( $Self->{Current}->{Dim} eq 'printable' || $Self->{Current}->{Dim} eq 'content' ) { 1717 $Self->{Current}->{Dim} = 'content'; 1718 } 1719 1720 return $Self->{Current}->{Dim}; 1721} 1722 1723=begin Internal: 1724 1725=head2 _TableCalculate() 1726 1727calculate params of table. 1728 1729 Return # normally no return required, only references 1730 %Param 1731 1732The returned hash is usually not needed, as the passed in references are 1733modified in place. 1734In case of missing or misused parameters, C<undef> is returned in scalar context 1735and an empty list is returned in list context. 1736 1737 %Return = $PDFObject->_TableCalculate( 1738 CellData => $CellData, # 2D arrayref (see example) 1739 ColumnData => $ColumnData, # arrayref (see example) 1740 RowData => $RowData, # arrayref (see example) 1741 Width => 300, # (optional) default default maximal width 1742 Height => 400, # (optional) default minimal height 1743 Font => 'Monospaced', # (optional) default Proportional (see DocumentNew()) 1744 FontSize => 9, # (optional) default 11 1745 FontColor => 'red', # (optional) default black 1746 FontColorEven => 'blue', # (optional) cell font color for even rows 1747 FontColorOdd => 'green', # (optional) cell font color for odd rows 1748 Align => 'right', # (optional) default left (left|center|right) 1749 Lead => 3, # (optional) default 1 1750 PaddingTop => 10, # (optional) top cell padding, overides Padding 1751 PaddingRight => 30, # (optional) right cell padding, overides Padding 1752 PaddingBottom => 30, # (optional) bottom cell padding, overides Padding 1753 PaddingLeft => 10, # (optional) left cell padding, overides Padding 1754 BackgroundColor => '#101010', # (optional) default white 1755 BackgroundColorEven => '#F0F0F0', # (optional) cell background color for even rows 1756 BackgroundColorOdd => '#A0A0A0', # (optional) cell background color for odd rows 1757 Border => 1, # (optional) default 1 (values between 0 and 20) 1758 BorderColor => '#FF0000', # (optional) default black 1759 ); 1760 1761 $CellData = [ 1762 [ 1763 { 1764 Content => "Cell 1 (Row 1, Column 1)", # (optional) 1765 Font => 'Monospaced', # (optional) 1766 FontSize => 13, # (optional) 1767 FontColor => '#00FF00', # (optional) 1768 Align => 'center', # (optional) 1769 Lead => 7, # (optional) 1770 BackgroundColor => '#101010', # (optional) 1771 }, 1772 { 1773 Content => "Cell 2 (Row 1, Column 2)", 1774 }, 1775 ], 1776 [ 1777 { 1778 Content => "Cell 3 (Row 2, Column 1)", 1779 }, 1780 { 1781 Content => "Cell 4 (Row 2, Column 2)", 1782 }, 1783 ], 1784 ]; 1785 1786 $ColumData = [ # this array was automaticly generated, if not given 1787 { 1788 Width => 11, # (optional) 1789 }, 1790 { 1791 Width => 44, 1792 }, 1793 ]; 1794 1795 $RowData = [ # this array was automaticly generated, if not given 1796 { 1797 Height => 11, # (optional) 1798 }, 1799 { 1800 Height => 44, 1801 }, 1802 ]; 1803 1804=cut 1805 1806sub _TableCalculate { 1807 my ( $Self, %Param ) = @_; 1808 1809 # check needed stuff 1810 for ( 1811 qw( 1812 CellData ColumnData RowData 1813 Type Font FontSize Lead FontColor Align BackgroundColor Width Border BorderColor 1814 PaddingTop PaddingRight PaddingBottom PaddingLeft 1815 ) 1816 ) 1817 { 1818 if ( !defined( $Param{$_} ) ) { 1819 $Kernel::OM->Get('Kernel::System::Log')->Log( 1820 Priority => 'error', 1821 Message => "Need $_!" 1822 ); 1823 return; 1824 } 1825 } 1826 if ( 1827 ref( $Param{CellData} ) ne 'ARRAY' 1828 || ref( $Param{ColumnData} ) ne 'ARRAY' 1829 || ref( $Param{RowData} ) ne 'ARRAY' 1830 ) 1831 { 1832 $Kernel::OM->Get('Kernel::System::Log')->Log( 1833 Priority => 'error', 1834 Message => "Need array references of CellData, ColumnData and RowData!" 1835 ); 1836 return; 1837 } 1838 if ( !$Self->{PDF} ) { 1839 $Kernel::OM->Get('Kernel::System::Log')->Log( 1840 Priority => 'error', 1841 Message => "Need a PDF Document!" 1842 ); 1843 return; 1844 } 1845 if ( !$Self->{Page} ) { 1846 $Kernel::OM->Get('Kernel::System::Log')->Log( 1847 Priority => 'error', 1848 Message => "Need a Page!" 1849 ); 1850 return; 1851 } 1852 1853 # analyse, if table is corrupt 1854 my $ColumnMax = 0; 1855 my $RowMax = 0; 1856 for my $Row ( @{ $Param{CellData} } ) { 1857 if ( scalar(@$Row) > $ColumnMax ) { 1858 $ColumnMax = scalar(@$Row); 1859 } 1860 $RowMax++; 1861 } 1862 1863 # repair, if table is corrupt 1864 if ( $RowMax eq 0 ) { 1865 ${ $Param{CellData} }[0] = []; 1866 $RowMax = 1; 1867 } 1868 if ( $ColumnMax eq 0 ) { 1869 $ColumnMax = 1; 1870 } 1871 1872 # cut ColumnData, if to much values 1873 if ( defined( ${ $Param{ColumnData} }[$ColumnMax] ) ) { 1874 splice( @{ $Param{ColumnData} }, $ColumnMax ); 1875 } 1876 1877 # cut RowData, if to much values 1878 if ( defined( ${ $Param{RowData} }[$RowMax] ) ) { 1879 splice( @{ $Param{RowData} }, $RowMax ); 1880 } 1881 1882 my $RowCounter = 0; 1883 for my $Row ( @{ $Param{CellData} } ) { 1884 my $MinFontSize = 999; 1885 for ( my $ColumnCounter = 0; $ColumnCounter < $ColumnMax; $ColumnCounter++ ) { 1886 1887 # repair, if row is corrupt 1888 if ( !defined( $Row->[$ColumnCounter] ) ) { 1889 $Row->[$ColumnCounter] = {}; 1890 } 1891 1892 # reference of current cell 1893 my $Cell = $Row->[$ColumnCounter]; 1894 1895 # if row is odd 1896 if ( $RowCounter & 1 ) { 1897 1898 # set FontColor, if row is odd 1899 if ( 1900 !defined( $Cell->{FontColor} ) 1901 && defined( $Param{FontColorOdd} ) 1902 ) 1903 { 1904 $Cell->{FontColor} = $Param{FontColorOdd}; 1905 } 1906 1907 # set BackgroundColor, if row is odd 1908 if ( 1909 !defined( $Cell->{BackgroundColor} ) 1910 && defined( $Param{BackgroundColorOdd} ) 1911 ) 1912 { 1913 $Cell->{BackgroundColor} = $Param{BackgroundColorOdd}; 1914 } 1915 } 1916 1917 # if row is even 1918 else { 1919 1920 # set FontColor, if row is even 1921 if ( 1922 !defined( $Cell->{FontColor} ) 1923 && defined( $Param{FontColorEven} ) 1924 ) 1925 { 1926 $Cell->{FontColor} = $Param{FontColorEven}; 1927 } 1928 1929 # set BackgroundColor, if row is even 1930 if ( 1931 !defined( $Cell->{BackgroundColor} ) 1932 && defined( $Param{BackgroundColorEven} ) 1933 ) 1934 { 1935 $Cell->{BackgroundColor} = $Param{BackgroundColorEven}; 1936 } 1937 } 1938 1939 # set cell state 1940 if ( !defined( $Cell->{Off} ) ) { 1941 $Cell->{Off} = 0; 1942 } 1943 1944 # set temp cell state 1945 if ( !defined( $Cell->{TmpOff} ) ) { 1946 $Cell->{TmpOff} = 0; 1947 } 1948 1949 # prepare text 1950 if ( defined( $Cell->{Content} ) ) { 1951 $Cell->{Content} = $Self->_PrepareText( 1952 Text => $Cell->{Content}, 1953 ); 1954 } 1955 1956 # set content blank, if not defined 1957 if ( 1958 !defined( $Cell->{Content} ) 1959 || $Cell->{Content} eq '' 1960 ) 1961 { 1962 $Cell->{Content} = ' '; 1963 } 1964 1965 # set default values 1966 for (qw(Type Font FontSize FontColor Align Lead BackgroundColor)) { 1967 if ( !defined( $Cell->{$_} ) ) { 1968 $Cell->{$_} = $Param{$_}; 1969 } 1970 } 1971 1972 # calculate width of complete column content 1973 if ( !defined( $Param{ColumnData}->[$ColumnCounter]->{MaxColWidth} ) ) { 1974 $Param{ColumnData}->[$ColumnCounter]->{MaxColWidth} = 0; 1975 } 1976 my $CompleteContentWidth = $Self->_StringWidth( 1977 Text => $Cell->{Content}, 1978 Font => $Cell->{Font}, 1979 FontSize => $Cell->{FontSize}, 1980 ); 1981 if ( $CompleteContentWidth > $Param{ColumnData}->[$ColumnCounter]->{MaxColWidth} ) { 1982 $Param{ColumnData}->[$ColumnCounter]->{MaxColWidth} = $CompleteContentWidth; 1983 } 1984 1985 # calculate with of the greaterst word 1986 if ( !defined( $Param{ColumnData}->[$ColumnCounter]->{MinColWidth} ) ) { 1987 $Param{ColumnData}->[$ColumnCounter]->{MinColWidth} = 0; 1988 } 1989 my @Words = split( /\s+/, $Cell->{Content} ); 1990 my $WordMaxLength = 0; 1991 for (@Words) { 1992 my $WordLength = length($_); 1993 if ( $WordMaxLength <= $WordLength + 2 ) { 1994 $WordMaxLength = $WordLength; 1995 1996 # calculate width of word 1997 my $WordWidth = $Self->_StringWidth( 1998 Text => $_, 1999 Font => $Cell->{Font}, 2000 FontSize => $Cell->{FontSize}, 2001 ); 2002 if ( $WordWidth > $Param{ColumnData}->[$ColumnCounter]->{MinColWidth} ) { 2003 $Param{ColumnData}->[$ColumnCounter]->{MinColWidth} = $WordWidth; 2004 } 2005 } 2006 } 2007 2008 # find the smallerst fontsize 2009 if ( $Cell->{FontSize} < $MinFontSize ) { 2010 $MinFontSize = $Cell->{FontSize}; 2011 } 2012 } 2013 2014 # set MinFontSize 2015 $Param{RowData}->[$RowCounter]->{MinFontSize} = $MinFontSize; 2016 $RowCounter++; 2017 } 2018 2019 # estimate width of columns (without padding and border) 2020 for my $Column ( @{ $Param{ColumnData} } ) { 2021 if ( !defined( $Column->{Width} ) ) { 2022 $Column->{Width} = 0; 2023 } 2024 if ( $Column->{Width} > 0 ) { 2025 $Column->{EstimateWidth} = $Column->{Width}; 2026 } 2027 else { 2028 2029 # estimate width of column 2030 $Column->{EstimateWidth} = ( $Column->{MaxColWidth} + $Column->{MinColWidth} ) / 2; 2031 } 2032 2033 # reduce calculated width and width, if calculated width is greater than table width 2034 my $MaxWidth = $Param{Width} - $Param{PaddingLeft} - $Param{PaddingRight} - ( 2 * $Param{Border} ); 2035 if ( $Column->{EstimateWidth} > $MaxWidth ) { 2036 $Column->{EstimateWidth} = $MaxWidth; 2037 if ( $Column->{Width} > 0 ) { 2038 $Column->{Width} = $MaxWidth; 2039 } 2040 } 2041 2042 # set width to 1, if width is too small 2043 if ( $Column->{EstimateWidth} < 1 ) { 2044 $Column->{EstimateWidth} = 1; 2045 } 2046 } 2047 2048 # calculate exactly width of columns 2049 my $ColumnBlocks = []; 2050 $ColumnBlocks->[0]->{Width} = 0; 2051 $ColumnBlocks->[0]->{ColumnStart} = 0; 2052 $ColumnBlocks->[0]->{ColumnStop} = 0; 2053 $ColumnBlocks->[0]->{ColumnFix} = 0; 2054 $ColumnBlocks->[0]->{ColumnDyn} = 0; 2055 2056 my $Block = 0; 2057 my $Counter = 0; 2058 for my $Column ( @{ $Param{ColumnData} } ) { 2059 my $ColumnWidth = $Column->{EstimateWidth} 2060 + $Param{PaddingLeft} 2061 + $Param{PaddingRight} 2062 + ( 2 * $Param{Border} ); 2063 2064 if ( !$ColumnBlocks->[$Block]->{Width} ) { 2065 $ColumnBlocks->[$Block]->{Width} = $ColumnWidth; 2066 } 2067 else { 2068 if ( 2069 ( $ColumnBlocks->[$Block]->{Width} + $ColumnWidth - $Param{Border} ) 2070 > $Param{Width} 2071 ) 2072 { 2073 $ColumnBlocks->[$Block]->{ColumnStop} = $Counter - 1; 2074 $Block++; 2075 $ColumnBlocks->[$Block]->{Width} = $ColumnWidth; 2076 $ColumnBlocks->[$Block]->{ColumnStart} = $Counter; 2077 $ColumnBlocks->[$Block]->{ColumnFix} = 0; 2078 $ColumnBlocks->[$Block]->{ColumnDyn} = 0; 2079 } 2080 else { 2081 $ColumnBlocks->[$Block]->{Width} += $ColumnWidth - $Param{Border}; 2082 } 2083 $ColumnBlocks->[$Block]->{ColumnStop} = $Counter; 2084 } 2085 2086 if ( $Column->{Width} > 0 ) { 2087 $ColumnBlocks->[$Block]->{ColumnFix}++; 2088 } 2089 else { 2090 $ColumnBlocks->[$Block]->{ColumnDyn}++; 2091 } 2092 2093 $Counter++; 2094 } 2095 my $LastBlock = $#{$ColumnBlocks}; 2096 my $Counter2 = 0; 2097 for my $CurBlock ( @{$ColumnBlocks} ) { 2098 my $ExtraSpaceComplete; 2099 2100 # no extra space for laast block 2101 if ( $Counter2 && $Counter2 eq $LastBlock ) { 2102 $ExtraSpaceComplete = 0; 2103 } 2104 else { 2105 $ExtraSpaceComplete = $Param{Width} - $CurBlock->{Width}; 2106 } 2107 2108 my $ExtraSpaceDyn = 0; 2109 my $ExtraSpaceFix = 0; 2110 2111 if ( $CurBlock->{ColumnDyn} > 0 ) { 2112 $ExtraSpaceDyn = $ExtraSpaceComplete / $CurBlock->{ColumnDyn}; 2113 } 2114 else { 2115 $ExtraSpaceFix = $ExtraSpaceComplete / $CurBlock->{ColumnFix}; 2116 } 2117 2118 for ( $CurBlock->{ColumnStart} .. $CurBlock->{ColumnStop} ) { 2119 my $Column = $Param{ColumnData}->[$_]; 2120 my $ExtraSpace = 0; 2121 if ( $Column->{Width} > 0 ) { 2122 $ExtraSpace = $ExtraSpaceFix; 2123 } 2124 else { 2125 $ExtraSpace = $ExtraSpaceDyn; 2126 } 2127 2128 $Column->{OutputWidth} = $Column->{EstimateWidth} 2129 + $ExtraSpace 2130 + $Param{PaddingLeft} 2131 + $Param{PaddingRight} 2132 + ( 2 * $Param{Border} ); 2133 $Column->{TextWidth} = $Column->{EstimateWidth} + $ExtraSpace; 2134 2135 if ( $Column->{OutputWidth} < 1 ) { 2136 $Column->{OutputWidth} = 1; 2137 } 2138 if ( $Column->{TextWidth} < 1 ) { 2139 $Column->{TextWidth} = 1; 2140 } 2141 $Column->{Block} = $Counter2; 2142 } 2143 $Counter2++; 2144 } 2145 2146 return %Param; 2147} 2148 2149=head2 _TableBlockNextCalculate() 2150 2151calculate what block can output next 2152 2153 Return 2154 $Return{State} 2155 $Return{ReturnBlock} 2156 $Return{ReturnRowStart} 2157 $Return{ReturnColumnStart} 2158 $Return{ReturnColumnStop} 2159 2160 %Return = $PDFObject->_TableBlockNextCalculate( 2161 CellData => $CellData, # 2D arrayref 2162 ColumnData => $ColumnData, # arrayref 2163 ); 2164 2165=cut 2166 2167sub _TableBlockNextCalculate { 2168 my ( $Self, %Param ) = @_; 2169 2170 my %Return = ( 2171 State => 0, 2172 ReturnBlock => 0, 2173 ReturnRowStart => 0, 2174 ReturnColumnStart => 0, 2175 ReturnColumnStop => 0, 2176 ); 2177 2178 # check needed stuff 2179 for (qw(CellData ColumnData)) { 2180 if ( !defined $Param{$_} ) { 2181 $Kernel::OM->Get('Kernel::System::Log')->Log( 2182 Priority => 'error', 2183 Message => "Need $_!" 2184 ); 2185 return; 2186 } 2187 } 2188 if ( ref $Param{CellData} ne 'ARRAY' || ref $Param{ColumnData} ne 'ARRAY' ) { 2189 $Kernel::OM->Get('Kernel::System::Log')->Log( 2190 Priority => 'error', 2191 Message => "Need array references of CellData and ColumnData!" 2192 ); 2193 return; 2194 } 2195 if ( !$Self->{PDF} ) { 2196 $Kernel::OM->Get('Kernel::System::Log')->Log( 2197 Priority => 'error', 2198 Message => "Need a PDF Document!" 2199 ); 2200 return; 2201 } 2202 if ( !$Self->{Page} ) { 2203 $Kernel::OM->Get('Kernel::System::Log')->Log( 2204 Priority => 'error', 2205 Message => "Need a Page!" 2206 ); 2207 return; 2208 } 2209 2210 my $RowStart = 'NULL'; 2211 my $ColumnStart = 'NULL'; 2212 my $ColumnStop = 0; 2213 2214 # calculate, what cells can output (what cells are active) 2215 my $RowCounter = 0; 2216 for my $Row ( @{ $Param{CellData} } ) { 2217 2218 # if last block was temporary off, reactivate the row 2219 if ( $Param{CellData}->[$RowCounter]->[ $#{ $Param{CellData}->[$RowCounter] } ]->{TmpOff} ) 2220 { 2221 for ( my $ColumnCounter = 0; $ColumnCounter < scalar(@$Row); $ColumnCounter++ ) { 2222 $Row->[$ColumnCounter]->{TmpOff} = 0; 2223 } 2224 } 2225 2226 # now calculate, what cells can output (what cells are active) 2227 COLUMN_COUNTER: 2228 for ( my $ColumnCounter = 0; $ColumnCounter < scalar @$Row; $ColumnCounter++ ) { 2229 2230 # calculate RowStart and ColumnStart 2231 if ( 2232 $Row->[$ColumnCounter]->{Off} ne 1 2233 && $Row->[$ColumnCounter]->{TmpOff} ne 1 2234 && $RowStart eq 'NULL' 2235 && $ColumnStart eq 'NULL' 2236 ) 2237 { 2238 $RowStart = $RowCounter; 2239 $ColumnStart = $ColumnCounter; 2240 $ColumnStop = $ColumnStart; 2241 last COLUMN_COUNTER; 2242 } 2243 } 2244 $RowCounter++; 2245 } 2246 2247 if ( $RowStart ne 'NULL' && $ColumnStart ne 'NULL' ) { 2248 2249 # find last column of block 2250 my $Block = $Param{ColumnData}->[$ColumnStart]->{Block}; 2251 my $ColumnCounter = 0; 2252 for my $Column ( @{ $Param{ColumnData} } ) { 2253 if ( 2254 $ColumnCounter > $ColumnStop 2255 && $Column->{Block} eq $Block 2256 ) 2257 { 2258 $ColumnStop = $ColumnCounter; 2259 } 2260 $ColumnCounter++; 2261 } 2262 2263 $Return{State} = 1; 2264 $Return{ReturnBlock} = $Block; 2265 $Return{ReturnRowStart} = $RowStart; 2266 $Return{ReturnColumnStart} = $ColumnStart; 2267 $Return{ReturnColumnStop} = $ColumnStop; 2268 } 2269 2270 return %Return; 2271} 2272 2273=head2 _TableRowCalculate() 2274 2275calculate row of table 2276 2277 Return # normally no return required, only references 2278 %Param 2279 2280 %Return = $PDFObject->_TableRowCalculate( 2281 CellData => $CellData, # 2D arrayref 2282 RowData => $RowData, # arrayref 2283 ColumnData => $ColumnData, # arrayref 2284 Row => 3, # current row 2285 ); 2286 2287=cut 2288 2289sub _TableRowCalculate { 2290 my ( $Self, %Param ) = @_; 2291 2292 # check needed stuff 2293 for (qw(CellData RowData ColumnData Row)) { 2294 if ( !defined( $Param{$_} ) ) { 2295 $Kernel::OM->Get('Kernel::System::Log')->Log( 2296 Priority => 'error', 2297 Message => "Need $_!" 2298 ); 2299 return; 2300 } 2301 } 2302 if ( 2303 ref( $Param{CellData} ) ne 'ARRAY' 2304 || ref( $Param{ColumnData} ) ne 'ARRAY' 2305 || ref( $Param{RowData} ) ne 'ARRAY' 2306 ) 2307 { 2308 $Kernel::OM->Get('Kernel::System::Log')->Log( 2309 Priority => 'error', 2310 Message => "Need array references of CellData, ColumnData and RowData!" 2311 ); 2312 return; 2313 } 2314 if ( !$Self->{PDF} ) { 2315 $Kernel::OM->Get('Kernel::System::Log')->Log( 2316 Priority => 'error', 2317 Message => "Need a PDF Document!" 2318 ); 2319 return; 2320 } 2321 if ( !$Self->{Page} ) { 2322 $Kernel::OM->Get('Kernel::System::Log')->Log( 2323 Priority => 'error', 2324 Message => "Need a Page!" 2325 ); 2326 return; 2327 } 2328 2329 if ( $Param{RowData}->[ $Param{Row} ]->{Height} ) { 2330 $Param{RowData}->[ $Param{Row} ]->{TextHeight} = $Param{RowData}->[ $Param{Row} ]->{Height}; 2331 } 2332 else { 2333 2334 # calculate height of row 2335 $Param{RowData}->[ $Param{Row} ]->{Height} = 0; 2336 $Param{RowData}->[ $Param{Row} ]->{TextHeight} = 0; 2337 my $BiggerstFontSize = 0; 2338 my $ColumnCounter = 0; 2339 for my $Column ( @{ $Param{ColumnData} } ) { 2340 my $Cell = $Param{CellData}->[ $Param{Row} ]->[$ColumnCounter]; 2341 my %Calculate = $Self->_TextCalculate( 2342 Text => $Cell->{Content}, 2343 Type => 'ReturnLeftOver', 2344 Width => $Column->{TextWidth}, 2345 Height => 1000000, 2346 Font => $Cell->{Font}, 2347 FontSize => $Cell->{FontSize}, 2348 Lead => $Cell->{Lead}, 2349 ); 2350 if ( $Calculate{RequiredHeight} > $Param{RowData}->[ $Param{Row} ]->{TextHeight} ) { 2351 $Param{RowData}->[ $Param{Row} ]->{TextHeight} = $Calculate{RequiredHeight}; 2352 } 2353 if ( $Cell->{FontSize} > $BiggerstFontSize ) { 2354 $BiggerstFontSize = $Cell->{FontSize}; 2355 } 2356 $ColumnCounter++; 2357 } 2358 if ( !$Param{RowData}->[ $Param{Row} ]->{TextHeight} ) { 2359 $Param{RowData}->[ $Param{Row} ]->{TextHeight} = $BiggerstFontSize; 2360 } 2361 } 2362 $Param{RowData}->[ $Param{Row} ]->{OutputHeight} = $Param{RowData}->[ $Param{Row} ]->{TextHeight} 2363 + $Param{PaddingTop} 2364 + $Param{PaddingBottom} 2365 + ( 2 * $Param{Border} ); 2366 2367 return %Param; 2368} 2369 2370=head2 _TableCellOutput() 2371 2372output a cell of a table 2373 2374 Return 2375 $Return{State} 2376 $Return{RequiredWidth} 2377 $Return{RequiredHeight} 2378 $Return{LeftOver} 2379 2380 %Return = $PDFObject->_TableCellOutput( 2381 Width => 70, 2382 Height => 40, 2383 Text => 'Text', 2384 Type => 'Cut', 2385 Font => 'ProportionalBold', 2386 FontSize => 15, 2387 FontColor => '#FF0000', 2388 Align => 'center', 2389 Lead => 20, 2390 PaddingTop => 10, 2391 PaddingRight => 30, 2392 PaddingBottom => 30, 2393 PaddingLeft => 10, 2394 BackgroundColor => '#101010', 2395 Border => 1, 2396 BorderColor => '#FF0000', 2397 ); 2398 2399=cut 2400 2401sub _TableCellOutput { 2402 my ( $Self, %Param ) = @_; 2403 2404 my %Return = ( 2405 State => 0, 2406 RequiredWidth => 0, 2407 RequiredHeight => 0, 2408 LeftOver => '', 2409 ); 2410 2411 # check needed stuff 2412 for ( 2413 qw(Width Height Text Type Font FontSize FontColor Align Lead 2414 PaddingTop PaddingRight PaddingBottom PaddingLeft BackgroundColor Border BorderColor) 2415 ) 2416 { 2417 if ( !defined( $Param{$_} ) ) { 2418 $Kernel::OM->Get('Kernel::System::Log')->Log( 2419 Priority => 'error', 2420 Message => "Need $_!" 2421 ); 2422 return; 2423 } 2424 } 2425 if ( !$Self->{PDF} ) { 2426 $Kernel::OM->Get('Kernel::System::Log')->Log( 2427 Priority => 'error', 2428 Message => "Need a PDF Document!" 2429 ); 2430 return; 2431 } 2432 if ( !$Self->{Page} ) { 2433 $Kernel::OM->Get('Kernel::System::Log')->Log( 2434 Priority => 'error', 2435 Message => "Need a Page!" 2436 ); 2437 return; 2438 } 2439 my %Dim; 2440 2441 # get dimension (printable or content) 2442 if ( $Self->DimGet() eq 'printable' ) { 2443 %Dim = $Self->_CurPrintableDimGet(); 2444 } 2445 else { 2446 %Dim = $Self->_CurContentDimGet(); 2447 } 2448 2449 # get current position 2450 my %Position = $Self->_CurPositionGet(); 2451 2452 # output background 2453 if ( $Param{BackgroundColor} ne 'NULL' ) { 2454 my $Background = $Self->{Page}->gfx(); 2455 $Background->fillcolor( $Param{BackgroundColor} ); 2456 $Background->rect( $Position{X}, $Position{Y}, $Param{Width}, -( $Param{Height} ) ); 2457 $Background->fill(); 2458 } 2459 2460 # output top border 2461 if ( $Param{Border} > 0 ) { 2462 my $BorderTop = $Self->{Page}->gfx(); 2463 $BorderTop->fillcolor( $Param{BorderColor} ); 2464 $BorderTop->rect( $Position{X}, $Position{Y}, $Param{Width}, -( $Param{Border} ) ); 2465 $BorderTop->fill(); 2466 } 2467 2468 # output right border 2469 if ( $Param{Border} > 0 ) { 2470 my $BorderRight = $Self->{Page}->gfx(); 2471 $BorderRight->fillcolor( $Param{BorderColor} ); 2472 $BorderRight->rect( 2473 ( $Position{X} + $Param{Width} - $Param{Border} ), 2474 $Position{Y}, $Param{Border}, -( $Param{Height} ) 2475 ); 2476 $BorderRight->fill(); 2477 } 2478 2479 # output bottom border 2480 if ( $Param{Border} > 0 ) { 2481 my $BorderBottom = $Self->{Page}->gfx(); 2482 $BorderBottom->fillcolor( $Param{BorderColor} ); 2483 $BorderBottom->rect( 2484 $Position{X}, ( $Position{Y} - $Param{Height} + $Param{Border} ), 2485 $Param{Width}, -( $Param{Border} ) 2486 ); 2487 $BorderBottom->fill(); 2488 } 2489 2490 # output left border 2491 if ( $Param{Border} > 0 ) { 2492 my $BorderLeft = $Self->{Page}->gfx(); 2493 $BorderLeft->fillcolor( $Param{BorderColor} ); 2494 $BorderLeft->rect( $Position{X}, $Position{Y}, $Param{Border}, -( $Param{Height} ) ); 2495 $BorderLeft->fill(); 2496 } 2497 2498 # calculate text start position 2499 my $TextX = $Position{X} + $Param{Border} + $Param{PaddingLeft}; 2500 my $TextY = $Position{Y} - $Param{Border} - $Param{PaddingTop} + 1; 2501 2502 # calculate width and height of text 2503 my $TextWidth = $Param{Width} - $Param{PaddingLeft} - $Param{PaddingRight} - ( 2 * $Param{Border} ); 2504 my $TextHeight = $Param{Height} - $Param{PaddingTop} - $Param{PaddingBottom} - ( 2 * $Param{Border} ); 2505 2506 # set new position 2507 $Self->PositionSet( 2508 X => $TextX, 2509 Y => $TextY, 2510 ); 2511 2512 %Return = $Self->Text( 2513 Text => $Param{Text}, 2514 Type => $Param{Type}, 2515 Width => $TextWidth, 2516 Height => $TextHeight, 2517 Font => $Param{Font}, 2518 FontSize => $Param{FontSize}, 2519 Color => $Param{FontColor}, 2520 Align => $Param{Align}, 2521 Lead => $Param{Lead}, 2522 ); 2523 2524 return %Return; 2525} 2526 2527=head2 _TableCellOnCount() 2528 2529count all active cells 2530 2531 Return 2532 $CellCount 2533 2534 $Count = $PDFObject->_TableCellOnCount( 2535 CellData => $CellData, # 2D arrayref 2536 ); 2537 2538=cut 2539 2540sub _TableCellOnCount { 2541 my ( $Self, %Param ) = @_; 2542 2543 my $Return = 0; 2544 2545 # check needed stuff 2546 for (qw(CellData)) { 2547 if ( !defined( $Param{$_} ) ) { 2548 $Kernel::OM->Get('Kernel::System::Log')->Log( 2549 Priority => 'error', 2550 Message => "Need $_!" 2551 ); 2552 return; 2553 } 2554 } 2555 if ( ref( $Param{CellData} ) ne 'ARRAY' ) { 2556 $Kernel::OM->Get('Kernel::System::Log')->Log( 2557 Priority => 'error', 2558 Message => "Need array references of CellData!" 2559 ); 2560 return; 2561 } 2562 if ( !$Self->{PDF} ) { 2563 $Kernel::OM->Get('Kernel::System::Log')->Log( 2564 Priority => 'error', 2565 Message => "Need a PDF Document!" 2566 ); 2567 return; 2568 } 2569 if ( !$Self->{Page} ) { 2570 $Kernel::OM->Get('Kernel::System::Log')->Log( 2571 Priority => 'error', 2572 Message => "Need a Page!" 2573 ); 2574 return; 2575 } 2576 for my $Row ( @{ $Param{CellData} } ) { 2577 for ( my $ColumnCounter = 0; $ColumnCounter < scalar(@$Row); $ColumnCounter++ ) { 2578 if ( $Row->[$ColumnCounter]->{Off} ne 1 ) { 2579 $Return++; 2580 } 2581 } 2582 } 2583 2584 return $Return; 2585} 2586 2587=head2 _TextCalculate() 2588 2589calculate required values of given text 2590 2591 Return 2592 $Return{State} 2593 $Return{RequiredWidth} 2594 $Return{RequiredHeight} 2595 $Return{LeftOver} 2596 $Return{PossibleRows} # (Array Ref) 2597 2598 %Return = $PDFObject->_TextCalculate( 2599 Text => $Text, # text 2600 Type => 'Cut', # (ReturnLeftOver|ReturnLeftOverHard|Cut) 2601 Width => 300, # available width 2602 Height => 200, # available height 2603 Font => 'ProportionalBold', # font of text 2604 FontSize => 6, # fontsize of text 2605 Lead => 20, # lead 2606 ); 2607 2608=cut 2609 2610sub _TextCalculate { 2611 my ( $Self, %Param ) = @_; 2612 2613 my %Return = ( 2614 State => 0, 2615 RequiredWidth => 0, 2616 RequiredHeight => 0, 2617 LeftOver => '', 2618 ); 2619 my @PossibleRows; 2620 2621 # check needed stuff 2622 for (qw(Text Type Width Height Font FontSize Lead)) { 2623 if ( !defined( $Param{$_} ) ) { 2624 $Kernel::OM->Get('Kernel::System::Log')->Log( 2625 Priority => 'error', 2626 Message => "Need $_!" 2627 ); 2628 return; 2629 } 2630 } 2631 if ( !$Self->{PDF} ) { 2632 $Kernel::OM->Get('Kernel::System::Log')->Log( 2633 Priority => 'error', 2634 Message => "Need a PDF Document!" 2635 ); 2636 return; 2637 } 2638 if ( !$Self->{Page} ) { 2639 $Kernel::OM->Get('Kernel::System::Log')->Log( 2640 Priority => 'error', 2641 Message => "Need a Page!" 2642 ); 2643 return; 2644 } 2645 my $TextLength = 0; 2646 2647 if ( $Param{Width} <= 0 || $Param{Height} <= 0 ) { 2648 $Return{LeftOver} = $Param{Text}; 2649 $Param{Text} = undef; 2650 } 2651 else { 2652 $Param{Text} = $Self->_PrepareText( 2653 Text => $Param{Text}, 2654 ); 2655 $TextLength = length( $Param{Text} ); 2656 } 2657 my $Counter1 = 0; 2658 while ( defined( $Param{Text} ) ) { 2659 my $Row; 2660 my $DelPreSpace = 0; 2661 2662 # get next row of given text 2663 if ( $Param{Text} =~ s/^(.*?)\n(.*)/$2/s ) { 2664 $Row = $1; 2665 } 2666 else { 2667 $Row = $Param{Text}; 2668 $Param{Text} = undef; 2669 } 2670 2671 # delete one space at begin of row, if exists 2672 $Row =~ s/^\s//; 2673 2674 # calculate width of the row 2675 my $RowWidth = $Self->_StringWidth( 2676 Text => $Row, 2677 Font => $Param{Font}, 2678 FontSize => $Param{FontSize}, 2679 ); 2680 2681 # calculate height of the row 2682 my $RowHeight = $Param{FontSize}; 2683 if ( $Counter1 > 0 ) { 2684 $RowHeight += $Param{Lead}; 2685 } 2686 2687 if ( $Return{RequiredHeight} + $RowHeight <= $Param{Height} ) { 2688 2689 # if row is greater then $Param{Width} 2690 if ( $RowWidth > $Param{Width} ) { 2691 2692 # estimate point of cut 2693 my $Factor = $RowWidth / $Param{Width}; 2694 my $Cut = int( length($Row) / $Factor ); 2695 2696 # cut the row 2697 my $RowFore = substr( $Row, 0, $Cut ); 2698 my $RowRear = substr( $Row, $Cut ); 2699 2700 # calculate width of fore row 2701 my $RowForeWidth = $Self->_StringWidth( 2702 Text => $RowFore, 2703 Font => $Param{Font}, 2704 FontSize => $Param{FontSize}, 2705 ); 2706 2707 # caculate exactly point of cut 2708 while ( $RowForeWidth < $Param{Width} ) { 2709 $RowFore .= substr( $RowRear, 0, 1 ); 2710 $RowRear = substr( $RowRear, 1 ); 2711 $RowForeWidth = $Self->_StringWidth( 2712 Text => $RowFore, 2713 Font => $Param{Font}, 2714 FontSize => $Param{FontSize}, 2715 ); 2716 } 2717 while ( $RowForeWidth > $Param{Width} ) { 2718 $RowRear = chop($RowFore) . $RowRear; 2719 $RowForeWidth = $Self->_StringWidth( 2720 Text => $RowFore, 2721 Font => $Param{Font}, 2722 FontSize => $Param{FontSize}, 2723 ); 2724 } 2725 2726 if ( $Param{Type} eq 'ReturnLeftOver' || $Param{Type} eq 'Cut' ) { 2727 if ( $RowFore =~ /[^\s]$/ && $RowRear =~ /^[^\s]/ ) { 2728 $RowFore =~ s/^(.*)(\s+.+?)$/$1/; 2729 if ($2) { 2730 $RowRear = $2 . $RowRear; 2731 } 2732 } 2733 } 2734 2735 $Row = $RowFore; 2736 if ( $Param{Text} ) { 2737 $Param{Text} = $RowRear . "\n" . $Param{Text}; 2738 } 2739 else { 2740 $Param{Text} = $RowRear; 2741 } 2742 } 2743 2744 # delete spaces at end of row, if spaces exists 2745 $Row =~ s/^(.*)\s$/$1/; 2746 2747 # add Row to PossibleRows array 2748 push( @PossibleRows, $Row ); 2749 $Return{RequiredHeight} += $RowHeight; 2750 2751 # check, if min one character can count (protection of infinite loop) 2752 if ( defined( $Param{Text} ) ) { 2753 if ( length( $Param{Text} ) >= $TextLength ) { 2754 $Return{RequiredWidth} = 0; 2755 $Return{RequiredHeight} = 0; 2756 $Return{LeftOver} = $Param{Text}; 2757 $Param{Text} = undef; 2758 @PossibleRows = (); 2759 } 2760 else { 2761 $TextLength = length( $Param{Text} ); 2762 } 2763 } 2764 } 2765 else { 2766 $Return{LeftOver} = $Row; 2767 if ( $Param{Text} ) { 2768 $Return{LeftOver} .= "\n" . $Param{Text}; 2769 $Param{Text} = undef; 2770 } 2771 } 2772 $Counter1++; 2773 } 2774 2775 # cut text if type is Cut 2776 if ( $Param{Type} eq 'Cut' && $Return{LeftOver} ) { 2777 my $LastRow = $PossibleRows[-1]; 2778 if ($LastRow) { 2779 2780 # calculate width [..] 2781 my $PPWidth = $Self->_StringWidth( 2782 Text => '[..]', 2783 Font => $Param{Font}, 2784 FontSize => $Param{FontSize}, 2785 ); 2786 if ( $PPWidth <= $Param{Width} ) { 2787 2788 # calculate width of LastRow and [..] 2789 my $TextCutWidth = $Self->_StringWidth( 2790 Text => $LastRow, 2791 Font => $Param{Font}, 2792 FontSize => $Param{FontSize}, 2793 ); 2794 2795 # calculate last line 2796 while ( $TextCutWidth + $PPWidth > $Param{Width} ) { 2797 chop($LastRow); 2798 2799 # calculate width of shorted LastRow and [..] 2800 $TextCutWidth = $Self->_StringWidth( 2801 Text => $LastRow, 2802 Font => $Param{Font}, 2803 FontSize => $Param{FontSize}, 2804 ); 2805 } 2806 $PossibleRows[-1] = $LastRow . '[..]'; 2807 2808 } 2809 $Return{LeftOver} = ''; 2810 } 2811 } 2812 2813 # calculate RequiredWidth 2814 my $Counter2 = 0; 2815 for (@PossibleRows) { 2816 my $RowWidth = $Self->_StringWidth( 2817 Text => $_, 2818 Font => $Param{Font}, 2819 FontSize => $Param{FontSize}, 2820 ); 2821 2822 # set new RequiredWidth 2823 if ( $RowWidth > $Return{RequiredWidth} ) { 2824 $Return{RequiredWidth} = $RowWidth; 2825 } 2826 2827 $Counter2++; 2828 } 2829 2830 # correct RequiredHeight 2831 if ( $Return{RequiredWidth} eq 0 ) { 2832 $Return{RequiredHeight} = 0; 2833 } 2834 2835 # set state 2836 if ( !$Return{LeftOver} ) { 2837 $Return{State} = 1; 2838 } 2839 2840 $Return{PossibleRows} = \@PossibleRows; 2841 2842 return %Return; 2843} 2844 2845=head2 _StringWidth() 2846 2847calculate width of given text 2848 2849 $Width = $PDFObject->_StringWidth( 2850 Text => 'Text', # text 2851 Font => 'ProportionalBold', # font of text 2852 FontSize => 6, # fontsize of text 2853 ); 2854 2855=cut 2856 2857sub _StringWidth { 2858 my ( $Self, %Param ) = @_; 2859 2860 # check needed stuff 2861 for (qw(Text Font FontSize)) { 2862 if ( !defined $Param{$_} ) { 2863 $Kernel::OM->Get('Kernel::System::Log')->Log( 2864 Priority => 'error', 2865 Message => "Need $_!" 2866 ); 2867 return; 2868 } 2869 } 2870 2871 # check document 2872 if ( !$Self->{PDF} ) { 2873 $Kernel::OM->Get('Kernel::System::Log')->Log( 2874 Priority => 'error', 2875 Message => "Need a PDF Document!" 2876 ); 2877 return; 2878 } 2879 2880 # check page 2881 if ( !$Self->{Page} ) { 2882 $Kernel::OM->Get('Kernel::System::Log')->Log( 2883 Priority => 'error', 2884 Message => "Need a Page!" 2885 ); 2886 return; 2887 } 2888 2889 return $Self->{CacheStringWidth}->{ $Param{Font} }->{ $Param{FontSize} }->{ $Param{Text} } 2890 if $Self->{CacheStringWidth}->{ $Param{Font} }->{ $Param{FontSize} }->{ $Param{Text} }; 2891 2892 # create a text object 2893 $Self->{TextWidthObject} ||= $Self->{Page}->text(); 2894 2895 # set font and fontsize 2896 $Self->{TextWidthObject}->font( $Self->{Font}->{ $Param{Font} }, $Param{FontSize} ); 2897 2898 # calculate width of given text 2899 my $StringWidth = $Self->{TextWidthObject}->advancewidth( $Param{Text} ); 2900 2901 return $StringWidth if length $Param{Text} > 20; 2902 2903 # write width cache if length is not more than 20 chars 2904 $Self->{CacheStringWidth}->{ $Param{Font} }->{ $Param{FontSize} }->{ $Param{Text} } = $StringWidth; 2905 2906 return $StringWidth; 2907} 2908 2909=head2 _PrepareText() 2910 2911prepare given text for output 2912 2913 $Width = $PDFObject->_PrepareText( 2914 Text => 'Text', # text 2915 ); 2916 2917=cut 2918 2919sub _PrepareText { 2920 my ( $Self, %Param ) = @_; 2921 2922 # check needed stuff 2923 for (qw(Text)) { 2924 if ( !defined( $Param{$_} ) ) { 2925 $Kernel::OM->Get('Kernel::System::Log')->Log( 2926 Priority => 'error', 2927 Message => "Need $_!" 2928 ); 2929 return; 2930 } 2931 } 2932 if ( !$Self->{PDF} ) { 2933 $Kernel::OM->Get('Kernel::System::Log')->Log( 2934 Priority => 'error', 2935 Message => "Need a PDF Document!" 2936 ); 2937 return; 2938 } 2939 if ( !$Self->{Page} ) { 2940 $Kernel::OM->Get('Kernel::System::Log')->Log( 2941 Priority => 'error', 2942 Message => "Need a Page!" 2943 ); 2944 return; 2945 } 2946 2947 # prepare new line 2948 $Param{Text} =~ s/(\n\r|\r\r\n|\r\n)/\n/g; 2949 $Param{Text} =~ s/\r/\n/g; 2950 2951 # convert page brake to new lines 2952 $Param{Text} =~ s/\f/\n\n/g; 2953 2954 # convert tabs to spaces 2955 $Param{Text} =~ s/\t/ /g; 2956 2957 return $Param{Text}; 2958} 2959 2960=head2 _CurPageNumberSet() 2961 2962set number of current page 2963 2964 $PDFObject->_CurPageNumberSet( 2965 ShowPageNumber => 0, # (optional) default 1 2966 ); 2967 2968=cut 2969 2970sub _CurPageNumberSet { 2971 my ( $Self, %Param ) = @_; 2972 2973 if ( !$Self->{PDF} ) { 2974 $Kernel::OM->Get('Kernel::System::Log')->Log( 2975 Priority => 'error', 2976 Message => "Need a PDF Document!" 2977 ); 2978 return; 2979 } 2980 if ( !$Self->{Page} ) { 2981 $Kernel::OM->Get('Kernel::System::Log')->Log( 2982 Priority => 'error', 2983 Message => "Need a Page!" 2984 ); 2985 return; 2986 } 2987 2988 # set number of all over pages to 0, if first page 2989 if ( !defined( $Self->{Current}->{Page} ) ) { 2990 $Self->{Current}->{Page} = 0; 2991 } 2992 2993 # set number of displayed pages to 0, if first page 2994 if ( !defined( $Self->{Current}->{PageNumber} ) ) { 2995 $Self->{Current}->{PageNumber} = 0; 2996 } 2997 2998 # increment all over pages 2999 $Self->{Current}->{Page}++; 3000 3001 # set page number of current page 3002 if ( $Param{ShowPageNumber} eq 0 ) { 3003 $Self->{PageData}->{ $Self->{Current}->{Page} }->{PageNumber} = ''; 3004 } 3005 else { 3006 $Self->{Current}->{PageNumber}++; 3007 $Self->{PageData}->{ $Self->{Current}->{Page} }->{PageNumber} = $Self->{Current}->{PageNumber}; 3008 } 3009 3010 return 1; 3011} 3012 3013=head2 _CurPageDimSet() 3014 3015Set current Page Dimension 3016 3017 $PDFObject->_CurPageDimSet( 3018 Width => 123, # (optional) default 595 (Din A4) 3019 Height => 321, # (optional) default 842 (Din A4) 3020 PageOrientation => 'landscape', # (optional) (normal|landscape) 3021 ); 3022 3023=cut 3024 3025sub _CurPageDimSet { 3026 my ( $Self, %Param ) = @_; 3027 3028 if ( !$Self->{PDF} ) { 3029 $Kernel::OM->Get('Kernel::System::Log')->Log( 3030 Priority => 'error', 3031 Message => "Need a PDF Document!" 3032 ); 3033 return; 3034 } 3035 if ( !$Self->{Page} ) { 3036 $Kernel::OM->Get('Kernel::System::Log')->Log( 3037 Priority => 'error', 3038 Message => "Need a Page!" 3039 ); 3040 return; 3041 } 3042 3043 my $NewValue; 3044 3045 # set CurPageWidth 3046 if ( defined( $Param{Width} ) && $Param{Width} >= 100 && $Param{Width} <= 10000 ) { 3047 $Self->{Current}->{PageWidth} = int( $Param{Width} ); 3048 $NewValue = 1; 3049 } 3050 3051 # set CurPageHeight 3052 if ( defined( $Param{Height} ) && $Param{Height} >= 100 && $Param{Height} <= 10000 ) { 3053 $Self->{Current}->{PageHeight} = int( $Param{Height} ); 3054 $NewValue = 1; 3055 } 3056 3057 # get default pagesize 3058 my $DefaultWidth = 595; # DIN A4 3059 my $DefaultHeight = 842; # DIN A4 3060 if ( $Kernel::OM->Get('Kernel::Config')->Get('PDF::PageSize') eq 'letter' ) { 3061 $DefaultWidth = 612; 3062 $DefaultHeight = 792; 3063 } 3064 3065 # set page orientation 3066 if ( defined( $Param{PageOrientation} ) && $Param{PageOrientation} eq 'landscape' ) { 3067 my $TmpWidth = $DefaultWidth; 3068 $DefaultWidth = $DefaultHeight; 3069 $DefaultHeight = $TmpWidth; 3070 } 3071 3072 # set default values 3073 if ( !defined( $Self->{Current}->{PageWidth} ) ) { 3074 $Self->{Current}->{PageWidth} = $DefaultWidth; 3075 $NewValue = 1; 3076 } 3077 if ( !defined( $Self->{Current}->{PageHeight} ) ) { 3078 $Self->{Current}->{PageHeight} = $DefaultHeight; 3079 $NewValue = 1; 3080 } 3081 3082 if ($NewValue) { 3083 3084 # set new printable dimension 3085 $Self->{Current}->{PrintableTop} = 0; 3086 $Self->{Current}->{PrintableRight} = 0; 3087 $Self->{Current}->{PrintableBottom} = 0; 3088 $Self->{Current}->{PrintableLeft} = 0; 3089 $Self->{Current}->{PrintableWidth} = $Self->{Current}->{PageWidth}; 3090 $Self->{Current}->{PrintableHeight} = $Self->{Current}->{PageHeight}; 3091 3092 # set new content dimension 3093 $Self->{Current}->{ContentTop} = $Self->{Current}->{PrintableTop}; 3094 $Self->{Current}->{ContentRight} = $Self->{Current}->{PrintableRight}; 3095 $Self->{Current}->{ContentBottom} = $Self->{Current}->{PrintableBottom}; 3096 $Self->{Current}->{ContentLeft} = $Self->{Current}->{PrintableLeft}; 3097 $Self->{Current}->{ContentWidth} = $Self->{Current}->{PrintableWidth}; 3098 $Self->{Current}->{ContentHeight} = $Self->{Current}->{PrintableHeight}; 3099 3100 # set new current position 3101 $Self->{Current}->{PositionX} = $Self->{Current}->{ContentLeft}; 3102 $Self->{Current}->{PositionY} = $Self->{Current}->{PageHeight} - $Self->{Current}->{ContentTop}; 3103 } 3104 3105 return 1; 3106} 3107 3108=head2 _CurPageDimGet() 3109 3110Get current Page Dimension (Width, Height) 3111 3112 Return 3113 $CurPageDim{Width} 3114 $CurPageDim{Height} 3115 3116 %CurPageDim = $PDFObject->_CurPageDimGet(); 3117 3118=cut 3119 3120sub _CurPageDimGet { 3121 my ( $Self, %Param ) = @_; 3122 3123 if ( !$Self->{PDF} ) { 3124 $Kernel::OM->Get('Kernel::System::Log')->Log( 3125 Priority => 'error', 3126 Message => "Need a PDF Document!" 3127 ); 3128 return; 3129 } 3130 if ( !$Self->{Page} ) { 3131 $Kernel::OM->Get('Kernel::System::Log')->Log( 3132 Priority => 'error', 3133 Message => "Need a Page!" 3134 ); 3135 return; 3136 } 3137 3138 if ( !$Self->{Current}->{PageWidth} || !$Self->{Current}->{PageHeight} ) { 3139 $Self->_CurPageDimSet(); 3140 } 3141 3142 my %Data; 3143 if ( $Self->{Current}->{PageWidth} && $Self->{Current}->{PageHeight} ) { 3144 $Data{Width} = $Self->{Current}->{PageWidth}; 3145 $Data{Height} = $Self->{Current}->{PageHeight}; 3146 } 3147 3148 return %Data; 3149} 3150 3151=head2 _CurPageDimCheck() 3152 3153Check given X an/or Y if inside the page dimension 3154 3155 $True = $PDFObject->_CurPageDimCheck( 3156 X => 200, # (optional) 3157 Y => 100, # (optional) 3158 ); 3159 3160=cut 3161 3162sub _CurPageDimCheck { 3163 my ( $Self, %Param ) = @_; 3164 3165 if ( !$Self->{PDF} ) { 3166 $Kernel::OM->Get('Kernel::System::Log')->Log( 3167 Priority => 'error', 3168 Message => "Need a PDF Document!" 3169 ); 3170 return; 3171 } 3172 if ( !$Self->{Page} ) { 3173 $Kernel::OM->Get('Kernel::System::Log')->Log( 3174 Priority => 'error', 3175 Message => "Need a Page!" 3176 ); 3177 return; 3178 } 3179 3180 my $Return = 0; 3181 my %Page = $Self->_CurPageDimGet(); 3182 3183 if ( defined( $Param{X} ) ) { 3184 if ( $Param{X} >= 0 && $Param{X} <= $Page{Width} ) { 3185 $Return = 1; 3186 } 3187 } 3188 3189 if ( defined( $Param{Y} ) ) { 3190 if ( $Param{Y} >= 0 && $Param{Y} <= $Page{Height} ) { 3191 $Return = 1; 3192 } 3193 } 3194 3195 return $Return; 3196} 3197 3198=head2 _CurPrintableDimSet() 3199 3200Set current Printable Dimension 3201 3202 $True = $PDFObject->_CurPrintableDimSet( 3203 Top => 20, # (optional) 3204 Right => 20, # (optional) 3205 Bottom => 20, # (optional) 3206 Left => 20, # (optional) 3207 ); 3208 3209=cut 3210 3211sub _CurPrintableDimSet { 3212 my ( $Self, %Param ) = @_; 3213 3214 if ( !$Self->{PDF} ) { 3215 $Kernel::OM->Get('Kernel::System::Log')->Log( 3216 Priority => 'error', 3217 Message => "Need a PDF Document!" 3218 ); 3219 return; 3220 } 3221 if ( !$Self->{Page} ) { 3222 $Kernel::OM->Get('Kernel::System::Log')->Log( 3223 Priority => 'error', 3224 Message => "Need a Page!" 3225 ); 3226 return; 3227 } 3228 3229 if ( $Self->{Current}->{PageWidth} && $Self->{Current}->{PageHeight} ) { 3230 my $NewValue; 3231 3232 # set CurPrintableTop 3233 if ( 3234 defined( $Param{Top} ) 3235 && $Param{Top} > 0 3236 && $Param{Top} < $Self->{Current}->{PageHeight} / 2 3237 ) 3238 { 3239 $Self->{Current}->{PrintableTop} = $Param{Top}; 3240 $NewValue = 1; 3241 } 3242 3243 # set CurPrintableRight 3244 if ( 3245 defined( $Param{Right} ) 3246 && $Param{Right} > 0 3247 && $Param{Right} < $Self->{Current}->{PageWidth} / 2 3248 ) 3249 { 3250 $Self->{Current}->{PrintableRight} = $Param{Right}; 3251 $NewValue = 1; 3252 } 3253 3254 # set CurPrintableBottom 3255 if ( 3256 defined( $Param{Bottom} ) 3257 && $Param{Bottom} > 0 3258 && $Param{Bottom} < $Self->{Current}->{PageHeight} / 2 3259 ) 3260 { 3261 $Self->{Current}->{PrintableBottom} = $Param{Bottom}; 3262 $NewValue = 1; 3263 } 3264 3265 # set CurPrintableLeft 3266 if ( 3267 defined( $Param{Left} ) 3268 && $Param{Left} > 0 3269 && $Param{Left} < $Self->{Current}->{PageWidth} / 2 3270 ) 3271 { 3272 $Self->{Current}->{PrintableLeft} = $Param{Left}; 3273 $NewValue = 1; 3274 } 3275 3276 if ($NewValue) { 3277 3278 # calculate new printable width and height 3279 $Self->{Current}->{PrintableWidth} = $Self->{Current}->{PageWidth} 3280 - $Self->{Current}->{PrintableLeft} 3281 - $Self->{Current}->{PrintableRight}; 3282 $Self->{Current}->{PrintableHeight} = $Self->{Current}->{PageHeight} 3283 - $Self->{Current}->{PrintableTop} 3284 - $Self->{Current}->{PrintableBottom}; 3285 3286 # set new content dimension 3287 $Self->{Current}->{ContentTop} = $Self->{Current}->{PrintableTop}; 3288 $Self->{Current}->{ContentRight} = $Self->{Current}->{PrintableRight}; 3289 $Self->{Current}->{ContentBottom} = $Self->{Current}->{PrintableBottom}; 3290 $Self->{Current}->{ContentLeft} = $Self->{Current}->{PrintableLeft}; 3291 $Self->{Current}->{ContentWidth} = $Self->{Current}->{PrintableWidth}; 3292 $Self->{Current}->{ContentHeight} = $Self->{Current}->{PrintableHeight}; 3293 3294 # set new current position 3295 $Self->{Current}->{PositionX} = $Self->{Current}->{ContentLeft}; 3296 $Self->{Current}->{PositionY} = $Self->{Current}->{PageHeight} - $Self->{Current}->{ContentTop}; 3297 } 3298 } 3299 3300 return 1; 3301} 3302 3303=head2 _CurPrintableDimGet() 3304 3305Get current Printable Dimension 3306 3307 Return 3308 $CurPrintableDim{Top} 3309 $CurPrintableDim{Right} 3310 $CurPrintableDim{Bottom} 3311 $CurPrintableDim{Left} 3312 $CurPrintableDim{Width} 3313 $CurPrintableDim{Height} 3314 3315 %CurPrintableDim = $PDFObject->_CurPrintableDimGet(); 3316 3317=cut 3318 3319sub _CurPrintableDimGet { 3320 my ( $Self, %Param ) = @_; 3321 3322 if ( !$Self->{PDF} ) { 3323 $Kernel::OM->Get('Kernel::System::Log')->Log( 3324 Priority => 'error', 3325 Message => "Need a PDF Document!" 3326 ); 3327 return; 3328 } 3329 if ( !$Self->{Page} ) { 3330 $Kernel::OM->Get('Kernel::System::Log')->Log( 3331 Priority => 'error', 3332 Message => "Need a Page!" 3333 ); 3334 return; 3335 } 3336 3337 my %Data; 3338 if ( $Self->{Current}->{PageWidth} && $Self->{Current}->{PageHeight} ) { 3339 $Data{Top} = $Self->{Current}->{PrintableTop}; 3340 $Data{Right} = $Self->{Current}->{PrintableRight}; 3341 $Data{Bottom} = $Self->{Current}->{PrintableBottom}; 3342 $Data{Left} = $Self->{Current}->{PrintableLeft}; 3343 $Data{Width} = $Self->{Current}->{PrintableWidth}; 3344 $Data{Height} = $Self->{Current}->{PrintableHeight}; 3345 } 3346 3347 return %Data; 3348} 3349 3350=head2 _CurPrintableDimCheck() 3351 3352Check given X an/or Y if inside the printable dimension 3353 3354 $True = $PDFObject->_CurPrintableDimCheck( 3355 X => 200, # (optional) 3356 Y => 100, # (optional) 3357 ); 3358 3359=cut 3360 3361sub _CurPrintableDimCheck { 3362 my ( $Self, %Param ) = @_; 3363 3364 if ( !$Self->{PDF} ) { 3365 $Kernel::OM->Get('Kernel::System::Log')->Log( 3366 Priority => 'error', 3367 Message => "Need a PDF Document!" 3368 ); 3369 return; 3370 } 3371 if ( !$Self->{Page} ) { 3372 $Kernel::OM->Get('Kernel::System::Log')->Log( 3373 Priority => 'error', 3374 Message => "Need a Page!" 3375 ); 3376 return; 3377 } 3378 3379 my $Return = 0; 3380 my %Printable = $Self->_CurPrintableDimGet(); 3381 3382 if ( defined( $Param{X} ) ) { 3383 if ( 3384 $Param{X} >= $Printable{Left} 3385 && $Param{X} <= ( $Printable{Left} + $Printable{Width} ) 3386 ) 3387 { 3388 $Return = 1; 3389 } 3390 } 3391 3392 if ( defined( $Param{Y} ) ) { 3393 if ( 3394 $Param{Y} >= $Printable{Bottom} 3395 && $Param{Y} <= ( $Printable{Bottom} + $Printable{Height} ) 3396 ) 3397 { 3398 $Return = 1; 3399 } 3400 } 3401 3402 return $Return; 3403} 3404 3405=head2 _CurContentDimSet() 3406 3407Set current Content Dimension 3408 3409 $True = $PDFObject->_CurContentDimSet( 3410 Top => 20, # (optional) 3411 Right => 20, # (optional) 3412 Bottom => 20, # (optional) 3413 Left => 20, # (optional) 3414 ); 3415 3416=cut 3417 3418sub _CurContentDimSet { 3419 my ( $Self, %Param ) = @_; 3420 3421 if ( !$Self->{PDF} ) { 3422 $Kernel::OM->Get('Kernel::System::Log')->Log( 3423 Priority => 'error', 3424 Message => "Need a PDF Document!" 3425 ); 3426 return; 3427 } 3428 if ( !$Self->{Page} ) { 3429 $Kernel::OM->Get('Kernel::System::Log')->Log( 3430 Priority => 'error', 3431 Message => "Need a Page!" 3432 ); 3433 return; 3434 } 3435 3436 if ( $Self->{Current}->{PageWidth} && $Self->{Current}->{PageHeight} ) { 3437 my $NewValue; 3438 3439 # set CurContentTop 3440 if ( 3441 defined( $Param{Top} ) 3442 && $Param{Top} >= $Self->{Current}->{PrintableTop} 3443 && $Param{Top} < $Self->{Current}->{PageHeight} / 2 3444 ) 3445 { 3446 $Self->{Current}->{ContentTop} = $Param{Top}; 3447 $NewValue = 1; 3448 } 3449 3450 # set CurContentRight 3451 if ( 3452 defined( $Param{Right} ) 3453 && $Param{Right} >= $Self->{Current}->{PrintableRight} 3454 && $Param{Right} < $Self->{Current}->{PageWidth} / 2 3455 ) 3456 { 3457 $Self->{Current}->{ContentRight} = $Param{Right}; 3458 $NewValue = 1; 3459 } 3460 3461 # set CurContentBottom 3462 if ( 3463 defined( $Param{Bottom} ) 3464 && $Param{Bottom} >= $Self->{Current}->{PrintableBottom} 3465 && $Param{Bottom} < $Self->{Current}->{PageHeight} / 2 3466 ) 3467 { 3468 $Self->{Current}->{ContentBottom} = $Param{Bottom}; 3469 $NewValue = 1; 3470 } 3471 3472 # set CurContentLeft 3473 if ( 3474 defined( $Param{Left} ) 3475 && $Param{Left} >= $Self->{Current}->{PrintableLeft} 3476 && $Param{Left} < $Self->{Current}->{PageWidth} / 2 3477 ) 3478 { 3479 $Self->{Current}->{ContentLeft} = $Param{Left}; 3480 $NewValue = 1; 3481 } 3482 3483 if ($NewValue) { 3484 3485 # calculate new content width and height 3486 $Self->{Current}->{ContentWidth} = $Self->{Current}->{PageWidth} 3487 - $Self->{Current}->{ContentLeft} 3488 - $Self->{Current}->{ContentRight}; 3489 $Self->{Current}->{ContentHeight} = $Self->{Current}->{PageHeight} 3490 - $Self->{Current}->{ContentTop} 3491 - $Self->{Current}->{ContentBottom}; 3492 3493 # set new current position 3494 $Self->{Current}->{PositionX} = $Self->{Current}->{ContentLeft}; 3495 $Self->{Current}->{PositionY} = $Self->{Current}->{PageHeight} - $Self->{Current}->{ContentTop}; 3496 } 3497 } 3498 3499 return 1; 3500} 3501 3502=head2 _CurContentDimGet() 3503 3504Get current Content Dimension 3505 3506 Return 3507 $CurContentDim{Top} 3508 $CurContentDim{Right} 3509 $CurContentDim{Bottom} 3510 $CurContentDim{Left} 3511 $CurContentDim{Width} 3512 $CurContentDim{Height} 3513 3514 %CurContentDim = $PDFObject->_CurContentDimGet(); 3515 3516=cut 3517 3518sub _CurContentDimGet { 3519 my ( $Self, %Param ) = @_; 3520 3521 if ( !$Self->{PDF} ) { 3522 $Kernel::OM->Get('Kernel::System::Log')->Log( 3523 Priority => 'error', 3524 Message => "Need a PDF Document!" 3525 ); 3526 return; 3527 } 3528 if ( !$Self->{Page} ) { 3529 $Kernel::OM->Get('Kernel::System::Log')->Log( 3530 Priority => 'error', 3531 Message => "Need a Page!" 3532 ); 3533 return; 3534 } 3535 3536 my %Data; 3537 if ( $Self->{Current}->{PageWidth} && $Self->{Current}->{PageHeight} ) { 3538 $Data{Top} = $Self->{Current}->{ContentTop}; 3539 $Data{Right} = $Self->{Current}->{ContentRight}; 3540 $Data{Bottom} = $Self->{Current}->{ContentBottom}; 3541 $Data{Left} = $Self->{Current}->{ContentLeft}; 3542 $Data{Width} = $Self->{Current}->{ContentWidth}; 3543 $Data{Height} = $Self->{Current}->{ContentHeight}; 3544 } 3545 3546 return %Data; 3547} 3548 3549=head2 _CurContentDimCheck() 3550 3551Check given X an/or Y if inside the content dimension 3552 3553 $True = $PDFObject->_CurContentDimCheck( 3554 X => 200, # (optional) 3555 Y => 100, # (optional) 3556 ); 3557 3558=cut 3559 3560sub _CurContentDimCheck { 3561 my ( $Self, %Param ) = @_; 3562 3563 if ( !$Self->{PDF} ) { 3564 $Kernel::OM->Get('Kernel::System::Log')->Log( 3565 Priority => 'error', 3566 Message => "Need a PDF Document!" 3567 ); 3568 return; 3569 } 3570 if ( !$Self->{Page} ) { 3571 $Kernel::OM->Get('Kernel::System::Log')->Log( 3572 Priority => 'error', 3573 Message => "Need a Page!" 3574 ); 3575 return; 3576 } 3577 3578 my $Return = 0; 3579 my %Content = $Self->_CurContentDimGet(); 3580 3581 if ( defined( $Param{X} ) ) { 3582 if ( $Param{X} >= $Content{Left} && $Param{X} <= ( $Content{Left} + $Content{Width} ) ) { 3583 $Return = 1; 3584 } 3585 } 3586 3587 if ( defined( $Param{Y} ) ) { 3588 if ( $Param{Y} >= $Content{Bottom} && $Param{Y} <= ( $Content{Bottom} + $Content{Height} ) ) 3589 { 3590 $Return = 1; 3591 } 3592 } 3593 3594 return $Return; 3595} 3596 3597=head2 _CurPositionSet() 3598 3599Set current Position 3600 3601 $True = $PDFObject->_CurPositionSet( 3602 X => 20, # (optional) 3603 Y => 20, # (optional) 3604 ); 3605 3606=cut 3607 3608sub _CurPositionSet { 3609 my ( $Self, %Param ) = @_; 3610 3611 if ( !$Self->{PDF} ) { 3612 $Kernel::OM->Get('Kernel::System::Log')->Log( 3613 Priority => 'error', 3614 Message => "Need a PDF Document!" 3615 ); 3616 return; 3617 } 3618 if ( !$Self->{Page} ) { 3619 $Kernel::OM->Get('Kernel::System::Log')->Log( 3620 Priority => 'error', 3621 Message => "Need a Page!" 3622 ); 3623 return; 3624 } 3625 3626 if ( $Self->{Current}->{PageWidth} && $Self->{Current}->{PageHeight} ) { 3627 if ( $Self->DimGet() eq 'printable' ) { 3628 if ( 3629 defined( $Param{X} ) 3630 && $Param{X} >= $Self->{Current}->{PrintableLeft} 3631 && $Param{X} <= $Self->{Current}->{PageWidth} - $Self->{Current}->{PrintableRight} 3632 ) 3633 { 3634 $Self->{Current}->{PositionX} = $Param{X}; 3635 } 3636 if ( 3637 defined( $Param{Y} ) 3638 && $Param{Y} <= $Self->{Current}->{PageHeight} - $Self->{Current}->{PrintableTop} 3639 && $Param{Y} >= $Self->{Current}->{PrintableBottom} 3640 ) 3641 { 3642 $Self->{Current}->{PositionY} = $Param{Y}; 3643 } 3644 } 3645 else { 3646 if ( 3647 defined( $Param{X} ) 3648 && $Param{X} >= $Self->{Current}->{ContentLeft} 3649 && $Param{X} <= $Self->{Current}->{PageWidth} - $Self->{Current}->{ContentRight} 3650 ) 3651 { 3652 $Self->{Current}->{PositionX} = $Param{X}; 3653 } 3654 if ( 3655 defined( $Param{Y} ) 3656 && $Param{Y} <= $Self->{Current}->{PageHeight} - $Self->{Current}->{ContentTop} 3657 && $Param{Y} >= $Self->{Current}->{ContentBottom} 3658 ) 3659 { 3660 $Self->{Current}->{PositionY} = $Param{Y}; 3661 } 3662 } 3663 } 3664 3665 return 1; 3666} 3667 3668=head2 _CurPositionGet() 3669 3670Get current Position 3671 3672 Return 3673 $CurPosition{X} 3674 $CurPosition{Y} 3675 3676 %CurPosition = $PDFObject->_CurPositionGet(); 3677 3678=cut 3679 3680sub _CurPositionGet { 3681 my ( $Self, %Param ) = @_; 3682 3683 if ( !$Self->{PDF} ) { 3684 $Kernel::OM->Get('Kernel::System::Log')->Log( 3685 Priority => 'error', 3686 Message => "Need a PDF Document!" 3687 ); 3688 return; 3689 } 3690 if ( !$Self->{Page} ) { 3691 $Kernel::OM->Get('Kernel::System::Log')->Log( 3692 Priority => 'error', 3693 Message => "Need a Page!" 3694 ); 3695 return; 3696 } 3697 3698 my %Data; 3699 if ( $Self->{Current}->{PageWidth} && $Self->{Current}->{PageHeight} ) { 3700 $Data{X} = $Self->{Current}->{PositionX}; 3701 $Data{Y} = $Self->{Current}->{PositionY}; 3702 } 3703 3704 return %Data; 3705} 3706 3707sub DESTROY { 3708 my ( $Self, %Param ) = @_; 3709 3710 # set cache 3711 $Kernel::OM->Get('Kernel::System::Cache')->Set( 3712 Type => 'PDF', 3713 TTL => 60 * 60 * 24 * 20, 3714 Key => 'CacheStringWidth', 3715 Value => $Self->{CacheStringWidth}, 3716 ); 3717 3718 return 1; 3719} 3720 37211; 3722 3723=end Internal: 3724 3725=head1 TERMS AND CONDITIONS 3726 3727This software is part of the OTRS project (L<https://otrs.org/>). 3728 3729This software comes with ABSOLUTELY NO WARRANTY. For details, see 3730the enclosed file COPYING for license information (GPL). If you 3731did not receive this file, see L<https://www.gnu.org/licenses/gpl-3.0.txt>. 3732 3733=cut 3734