I am using fpdf to generate a report but one of the field I need to be multicell as the contents can be few lines long. Below is the codes what happens now is that the multicell will be few lines long but the rest of it will be only one standard size and the content after multicell will be on the next line. So how to overcome all this problem
$row_height = 5; // set the default
$column_width = 15;
$number_of_lines = ceil( $pdf->GetStringWidth($eventMessage) / ($column_width - 1) );
$cell_height = 5;
$height_of_cell = ceil( $number_of_lines * $cell_height );
if ( $cell_height > $row_height ) {
$row_height = $cell_height;
}
$pdf->Cell( 10, $row_height,$count, 1, 0, 'L', true );
$pdf->Cell( 15, $row_height,$row['latitude'], 1, 0, 'L', true );
$pdf->Cell( 16, $row_height,$row['longitude'], 1, 0, 'L', true );
$pdf->Cell( 25, $row_height,$row['dateTimer'], 1, 0, 'L', true );
$pdf->Cell( 25, $row_height,$row['insertDateTime'], 1, 0, 'L', true );
$pdf->MultiCell( 15, $row_height,$eventMessage, 1, 'J',true);
$pdf->Cell( 15, $row_height,$eventSource, 1, 0, 'L', true );
$pdf->Cell( 15, $row_height,$eventLocation, 1, 0, 'L', true );
$pdf->Cell( 18, $row_height,$row['stat'], 1, 0, 'L', true );
class pdf extends FPDF {
function GetMultiCellHeight($w, $h, $txt, $border=null, $align='J') {
// Calculate MultiCell with automatic or explicit line breaks height
// $border is un-used, but I kept it in the parameters to keep the call
// to this function consistent with MultiCell()
$cw = &$this->CurrentFont['cw'];
if($w==0)
$w = $this->w-$this->rMargin-$this->x;
$wmax = ($w-2*$this->cMargin)*1000/$this->FontSize;
$s = str_replace("\r",'',$txt);
$nb = strlen($s);
if($nb>0 && $s[$nb-1]=="\n")
$nb--;
$sep = -1;
$i = 0;
$j = 0;
$l = 0;
$ns = 0;
$height = 0;
while($i<$nb)
{
// Get next character
$c = $s[$i];
if($c=="\n")
{
// Explicit line break
if($this->ws>0)
{
$this->ws = 0;
$this->_out('0 Tw');
}
//Increase Height
$height += $h;
$i++;
$sep = -1;
$j = $i;
$l = 0;
$ns = 0;
continue;
}
if($c==' ')
{
$sep = $i;
$ls = $l;
$ns++;
}
$l += $cw[$c];
if($l>$wmax)
{
// Automatic line break
if($sep==-1)
{
if($i==$j)
$i++;
if($this->ws>0)
{
$this->ws = 0;
$this->_out('0 Tw');
}
//Increase Height
$height += $h;
}
else
{
if($align=='J')
{
$this->ws = ($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0;
$this->_out(sprintf('%.3F Tw',$this->ws*$this->k));
}
//Increase Height
$height += $h;
$i = $sep+1;
}
$sep = -1;
$j = $i;
$l = 0;
$ns = 0;
}
else
$i++;
}
// Last chunk
if($this->ws>0)
{
$this->ws = 0;
$this->_out('0 Tw');
}
//Increase Height
$height += $h;
return $height;
}
}
So
$pdf = new pdf();
$pdf->addPage();
$pdf->MultiCell(50, 4, 'Bla bla bla');
$pdf->ln(GetMultiCellHeight(50, 4, 'Bla bla bla'));
$pdf->Output();
Related
Answer "the script used too much memory".
I start a few start to read text file line by line, and convert the text to blob, then send it to socket:
use experimental :pack;
sub heart-msg(Str $msg, Str $device-id --> Blob) {
my $heart-msg = $msg.substr(0, $msg.chars - 8);
my $header-buf = pack("H*", $heart-msg);
my $device-id-buf = pack("L*", $device-id);
$header-buf ~ $device-id-buf
}
sub deal-message(Str $msg, Str $device-id --> Blob) {
my $now = DateTime.now();
my $year = $now.year;
my $month = $now.month;
my $day = $now.day;
my $hour = $now.hour;
my $minute = $now.minute;
my $second = $now.second.Int;
my $check-number = 0;
my $head-msg = $msg.substr(0,4);
my $device-id-length = $msg.substr(4,2);
my $pf-code = $msg.substr(14, 2);
my $msg-length = $msg.substr(16, 4);
my $rel-time = $msg.substr(20, 4);
my $end-msg = $msg.substr(38, $msg.chars - 38 - 2);
my $head-msg-buf = pack("H*", $head-msg);
my $device-id-len-buf = pack("H*", $device-id-length);
my $device-id-buf = pack("L*", $device-id);
my $pf-code-buf = pack("H*", $pf-code);
my $msg-length-buf = pack("H*", $msg-length);
my $rel-time-buf = pack("H*", $rel-time);
my $year-buf = pack("S*", $year);
my $month-buf = pack("C*", $month);
my $day-buf = pack("C*", $day);
my $hour-buf = pack("C*", $hour);
my $minute-buf = pack("C*", $minute);
my $second-buf = pack("C*", $second);
my $end-msg-buf = pack("H*", $end-msg);
my #bufs = [$device-id-len-buf, $device-id-buf, $pf-code-buf, $msg-length-buf,
$rel-time-buf, $year-buf, $month-buf, $day-buf, $hour-buf, $minute-buf, $second-buf,
$end-msg-buf];
for #bufs -> $byte {
my $byte_sum = [+] $byte.contents;
$check-number += $byte_sum;
}
$check-number = $check-number % 256;
my $checked-msg-buf = pack("C*", $check-number);
[~] $head-msg-buf, |#bufs, $checked-msg-buf
}
sub deal-data(Str $msg, Str $device-id --> Blob) {
my $header = $msg.substr(0, 4);
given $header {
when '6868' {
return deal-message($msg, $device-id);
}
when '7468' {
return heart-msg($msg, $device-id);
}
default { return Buf.new }
}
}
sub MAIN(
:$host = '10.0.0.77',
Int() :$port = 4444,
Rat() :$interval = 0.001,
:$file = 'data.txt',
Int() :$device-num = 169) {
my $conn = IO::Socket::INET.new(:$host, :$port);
my #devices = "modelId.txt".IO.lines;
my #promises = gather for #devices[159..$device-num] -> $device-id {
take start {
my $f = lazy $file.IO.lines;
my $iterator = $f.iterator;
react {
whenever Supply.interval($interval) {
try {
my $line := $iterator.pull-one;
if $line =:= IterationEnd {
done;
} else {
my $blob = deal-data($line.chomp.split(/\s+/).tail, $device-id.Str);
#say $blob;
$conn.write($blob);
}
}
QUIT {
$conn.close;
say 'connecting closed';
default {
say .^name, '→ ', .Str;
say "handled in line $?LINE";
}
}
LAST {
say "Connection closed";
done;
}
}
}
}
}
await #promises;
}
When running on CentOS 7.4(12 core, 32G RAM), after a few seconds, my script was killed by system. When running on Win11(12 core, 16G RAM), it's OK.
So how to debug this script?
I have a Perl script that compares two sets of data loaded into two arrays, and I'm trying to make the comparison more efficient. Currently the code is as follows:
foreach(#{FILE_DATA}) {
if((++$file_current_linenum % 200) == 0) {
$progress = int($file_current_linenum / $file_total_lines * 10000) / 100;
logg("Processed $file_current_linenum file rows, $progress%, $mismatches mismatches.");
}
$file_current_line = $_;
$match_found = 0;
foreach(#{DB_DATA}) {
$db_current_line = $_;
if($file_current_line->{"channel"} == $db_current_line->{"channel"} ) {
if ($file_current_line->{"checksum"} == $db_current_line->{"checksum"} &&
$file_current_line->{"time"} > ($db_current_line->{"date_part"} - $TIME_MATCH_TOLERANCE) &&
$file_current_line->{"time"} < ($db_current_line->{"date_part"} + $TIME_MATCH_TOLERANCE) ){
$match_found = 1;
last; # break;
}
}
}
if($match_found != 1) {
push(#results, $file_current_line);
$mismatches++;
}
}
My first thought would be to remove matches from both arrays to reduce the pool size, would that affect the iterators position?
Both sets of data can have up to a couple of million elements and the comparison can take a few hours to complete.
Your solution is O(DB * FILE).
The following is O(DB + FILE) if and only if there never more than a few lines with the same channel and checksum:
my %DB_DATA;
for my $db_line (#DB_DATA) {
push #{ $DB_DATA{ $db_line->{channel} }{ $db_line->{checksum} } }, $db_line;
}
for my $file_line_idx (0..$#FILE_DATA) {
my $file_line = $FILE_DATA[$file_line_idx];
my $found = 0;
if (my $r1 = $DB_DATA{ $file_line->{channel} } ) {
if (my $r2 = $r1->{ $file_line->{checksum} } ) {
my $file_time = $file_line->{time};
for my $db_line (#$r2) {
my $db_time = $db_line->{date_part};
if (abs($file_time - $db_time) < $TIME_MATCH_TOLERANCE) {
$found = 1;
last;
}
}
}
}
push #mismatches, $file_line if !$found;
if ((($file_line_idx+1) % 200) == 0) {
logg(sprintf("Processed %d file rows, %d%, %d mismatches.",
$file_line_idx+1,
int(($file_line_idx+1)/#FILE_DATA) * 100,
0+#mismatches,
));
}
}
The following is O(DB + FILE) even if there are many lines with the same channel and checksum, but uses a lot of memory if $TIME_MATCH_TOLERANCE is big:
my %DB_DATA;
for my $db_line (#DB_DATA) {
for my $db_time (
$db_line->{date_part} - $TIME_MATCH_TOLERANCE + 1
..
$db_line->{date_part} + $TIME_MATCH_TOLERANCE - 1
) {
++$DB_DATA{ $db_line->{channel} }{ $db_line->{checksum} }{$db_time};
}
}
for my $file_line_idx (0..$#FILE_DATA) {
my $file_line = $FILE_DATA[$file_line_idx];
my $found = 0;
if (my $r1 = $DB_DATA{ $file_line->{channel} } ) {
if (my $r2 = $r1->{ $file_line->{checksum} } ) {
if ($r2->{ $file_line->{time} } {
$found = 1;
last;
}
}
}
push #mismatches, $file_line if !$found;
if ((($file_line_idx+1) % 200) == 0) {
logg(sprintf("Processed %d file rows, %d%, %d mismatches.",
$file_line_idx+1,
int(($file_line_idx+1)/#FILE_DATA) * 100,
0+#mismatches,
));
}
}
Note: Assumes the timestamps are integers. If they're not, convert them to integers before using them as keys.
The following is O((DB + FILE) log DB) [ which is very close to O(DB + FILE) ] even if there are many lines with the same channel and checksum, and uses minimal memory:
sub binsearch(&\#) {
my ($compare, $array) = #_;
my $i = 0;
my $j = $#$array;
return 0 if $j == -1;
while (1) {
my $k = int(($i+$j)/2);
for ($array->[$k]) {
my $cmp = $compare->()
or return 1;
if ($cmp < 0) {
$j = $k-1;
return 0 if $i > $j;
} else {
$i = $k+1;
return 0 if $i > $j;
}
}
}
}
my %DB_DATA;
for my $db_line (#DB_DATA) {
push #{ $DB_DATA{ $db_line->{channel} }{ $db_line->{checksum} } }, $db_line;
}
for my $r1 (values(%DB_DATA)) {
for my $r2 (values(%$r1)) {
#$r2 = sort { $a->{date_part} <=> $b->{date_part} } #$r2;
}
}
for my $file_line_idx (0..$#FILE_DATA) {
my $file_line = $FILE_DATA[$file_line_idx];
my $found = 0;
if (my $r1 = $DB_DATA{ $file_line->{channel} } ) {
if (my $r2 = $r1->{ $file_line->{checksum} } ) {
my $file_time = $file_line->{time};
my $min_db_time = $file_time - $TIME_MATCH_TOLERANCE;
my $max_db_time = $file_time + $TIME_MATCH_TOLERANCE;
if ( binsearch {
$_->{date_part} >= $max_db_time ? -1
: $_->{date_part} <= $min_db_time ? +1
: 0
} #$r2 ) {
$found = 1;
last;
}
}
}
push #mismatches, $file_line if !$found;
if ((($file_line_idx+1) % 200) == 0) {
logg(sprintf("Processed %d file rows, %d%, %d mismatches.",
$file_line_idx+1,
int(($file_line_idx+1)/#FILE_DATA) * 100,
0+#mismatches,
));
}
}
You could probably reduce the time significantly by pre-building a hash from DB_DATA, using the concatenation of the "channel" and "checksum" values as the key, and each value being a list of all of the DB_DATA entries with that channel and checksum. That way, for each FILE_DATA entry, you only need to check that list.
If there are a lot of entries with a given channel and checksum, you try to improve even more by sorting them by date_part, and then trying to binary search to find a valid entry.
If there are very few entries with a given channel and checksum, this should reduce your run time by a factor of a million or so, since it reduces the run time from O($#FILE_DATA * $#DB_DATA) to O($#FILE_DATA + $#DB_DATA).
I am trying to make this calendar start on Sunday instead of Monday. I've looked through all the help files I can Google on this topic & cannot find any that have any lines of code that I can reference. Am I missing some? Or can some one point me to the point I need to change in order to make it start on Sunday instead of Monday?
<?php
/**
* Copyright (C) 2006-2014 Center Stage Software
* 1191 Luxton Street, Seaside, California 93955
* All Rights Reserved
*/
// ensure that this file is called up by another file
defined('_VALID_ACCESS') or die('Direct access of this file is prohibited.');
/**
* renderEventCalendar - Creates a calendar display of events for one month.
*
* #global (Array) $cstage
*/
function renderEventCalendar() {
global $cstage, $path;
// Result variable.
$calendar = '';
// Calculate first and last day of the month.
$firstDayTimestamp = strtotime($_SESSION[SYS_USER]['search']['Month'].'-01 07:00:00');
list($year,$month) = explode("-",$_SESSION[SYS_USER]['search']['Month']);
if( $month == 12 ) {
$month = 00;
$year += 1;
}
$lastDayTimestamp = strtotime("$year-".($month+1).'-01 08:00:00') - 86400; // minus 24 hours and add 1-day-light-savings-hour
// TODO: Remove the following calendar debugging code.
// print "<h1>first=$firstDayTimestamp; last=$lastDayTimestamp</h1>";
// Build query to retrieve entries for that month.
$aryEvents = array();
$extraSqlFields = '';
$extraSqlJoins = '';
$extraSqlConditions = '';
if( !empty($_SESSION[SYS_USER]['domain']) ) {
$extraSqlJoins .= 'LEFT JOIN "domainlist" AS "domain2" ON "domain2"."master_id" = "master"."master_id" ';
$extraSqlConditions .= sprintf('AND "domain2"."domain"=\'%s\' '
,$_SESSION[SYS_USER]['domain']
);
}
if( !empty($_SESSION[SYS_USER]['search']['Theatre']) ) {
$extraSqlConditions .= sprintf('AND "master"."theatre"=\'%s\' '
,$_SESSION[SYS_USER]['search']['Theatre']
);
}
if( !empty($_SESSION[SYS_USER]['search']['Location']) ) {
$extraSqlConditions .= sprintf('AND "master"."location"=\'%s\' '
,$_SESSION[SYS_USER]['search']['Location']
);
}
if( !empty($_SESSION[SYS_USER]['search']['EventType']) ) {
$extraSqlConditions .= sprintf('AND "master"."event_types_id"=\'%s\' '
,$_SESSION[SYS_USER]['search']['EventType']
);
}
if( !empty($_SESSION[SYS_USER]['search']['Month']) ) {
$extraSqlConditions .= sprintf('AND "shows"."show_date" >= \'%s\' AND "shows"."show_date" <= \'%s\' '
,date('Y-m-d',$firstDayTimestamp)
,date('Y-m-d',$lastDayTimestamp)
);
}
if( $cstage['rttEnable'] ) {
$extraSqlFields .= ', "rtt"."label" AS "rtt_label"';
$extraSqlJoins .= 'LEFT JOIN "rtt" ON "master"."rtt_id" = "rtt"."rtt_id" ';
} else {
$extraSqlConditions .= 'AND "master"."rtt_id"=0 ';
}
if( $cstage['enableEventPriceListTest'] ) {
$aryGroups = array($cstage['tixDomain']);
if( !empty($_SESSION[SYS_USER]['info']) && count($_SESSION[SYS_USER]['info']['groupDomains']) > 0 ) {
$aryGroups = array_merge($aryGroups, $_SESSION[SYS_USER]['info']['groupDomains']);
}
$extraSqlFields .= ', GROUP_CONCAT(DISTINCT "prices"."prices_id" SEPARATOR \';\') AS "priceidlist"';
$extraSqlFields .= ', GROUP_CONCAT(DISTINCT CONCAT("price_category"."label",\' \', "prices"."printed_as") SEPARATOR \', \') AS "pricelist"';
$extraSqlJoins .= ' INNER JOIN "price_category" ON "price_category"."master_id" = "master"."master_id" OR "price_category"."master_id"=0 INNER JOIN "prices" ON "price_category"."price_category_id" = "prices"."price_category_id" INNER JOIN "price_category_domain" ON "price_category_domain"."price_category_id" = "price_category"."price_category_id"';
$extraSqlConditions .= sprintf('AND ("price_category"."master_id"="shows"."master_id" OR "price_category"."master_id"=0) AND ("prices"."shows_id"="shows"."shows_id" OR "prices"."shows_id"=0) AND "prices"."onsale"<=CONCAT("shows"."show_date", \' 00:00:00\') AND ("prices"."offsale">=CONCAT("shows"."show_date", \' 23:59:59\') OR "prices"."offsale" IS NULL) AND "price_category_domain"."domain" IN (\'%s\') '
,implode('\',\'', $aryGroups)
);
}
$now = date('Y-m-d H:i:s');
$query = sprintf('SELECT "master".*, "shows"."show_date", "shows"."show_time", "shows"."onsale" AS "min_onsale"%s FROM "shows" INNER JOIN "master" ON "master"."master_id" = "shows"."master_id" INNER JOIN "domainlist" ON "domainlist"."master_id" = "master"."master_id" %s WHERE "shows"."offsale" >= \'%s\' AND ("shows"."wt_offsale"=\'\' OR "shows"."wt_offsale"=0) AND "domainlist"."domain"=\'%s\' %s GROUP BY "shows"."shows_id"'
,$extraSqlFields
,$extraSqlJoins
,$now
,$cstage['tixDomain']
,$extraSqlConditions
);
$keyEventCalendar = 'eventCalendar_'.$cstage['dbDatabase'].sha1($query);
if( !empty($cstage['cache']) ) {
// Is the record cached to save on slow database connections?
$calendar = $cstage['cache']->load($keyEventCalendar);
}
if( !$calendar ) {
$result = $cstage['pdo']->query( $query );
while( $show = $result->fetch( PDO::FETCH_ASSOC ) ) {
$show['domainlist'] = $cstage['tixDomain'].';'.$_SESSION[SYS_USER]['domain'];
$show['comingSoon'] = false;
if( $now < $show['min_onsale'] ) {
$show['comingSoon'] = true;
}
if( $show['rtt_id'] > 0 ) {
$show['master_id'] = trim($show['rtt_label']).trim($show[]);
if( !$cstage['rttEnable'] ) {
$show = array();
}
}
$path->inc_once('_includes/libf_okEvent.php');
if( okEvent($show) ) {
// Save data into array for usage later
$extraSort = $cstage['useEventSortOrder'] === true ? sprintf('%05d',$show['sortorder']) : '';
$aryEvents[$show['show_date']][date('H:i',strtotime($show['show_time'])).$extraSort.$show['showname'].$show['master_id']] = $show;
}
}
// Start rendering calendar.
$calendar = "\r\n".'<table class="EventCalendar ui-widget-content ui-corner-all"><thead '._HEAD.'><tr><th colspan="7">'.lang('Calendar of events for').' '.date('Y F',strtotime($_SESSION[SYS_USER]['search']['Month'].'-02')).'</th></tr>'
. "\r\n".'<tr><th>'.lang('Sunday').'</th><th>'.lang('Monday').'</th><th>'.lang('Tuesday').'</th><th>'.lang('Wednesday').'</th><th>'.lang('Thursday').'</th><th>'.lang('Friday').'</th><th>'.lang('Saturday').'</th></tr></thead>'
. '<tbody>';
$dayOfWeekPadding = date('w',$firstDayTimestamp);
if( $dayOfWeekPadding == 0 ) {
$dayOfWeekPadding = 6;
} else {
$dayOfWeekPadding -= 0;
}
if( $dayOfWeekPadding > 0 ) {
$calendar .= "\r\n<tr>";
}
for($day=7; $day < $dayOfWeekPadding; $day++) {
$calendar .= "\r\n<td class='EventCalendar_EmptyDate'> </td>";
}
$timeStamp = $firstDayTimestamp;
while( $timeStamp <= $lastDayTimestamp ) {
if( date('w',$timeStamp) == 0 ) {
$calendar .= "\r\n<tr>";
}
$dateKey = date('Y-m-d',$timeStamp);
$calendar .= "\r\n".'<td class="EventCalendar_Date" id="date'.$dateKey.'" onmouseover="tbl_colorchange(\'date'.$dateKey.'\', \'highlight\');" onmouseout="tbl_colorchange(\'date'.$dateKey.'\', \'normal\');"><span>'.date('d',$timeStamp).'</span>';
if( !empty($aryEvents[$dateKey]) ) {
ksort($aryEvents[$dateKey]);
$count = 0;
foreach( $aryEvents[$dateKey] as $key=>$show ) {
$cssClass = $count++ % 2 ? _ODD : _EVEN;
$rttUrl = ( $show['rtt_id'] > 0 ) ? '&rtt='.$show['rtt_id'] : '';
$strPriceList = (empty($show['pricelist']) ? '' : ' title="'.lang('Prices available').': '.$show['pricelist'].'"');
$calendar .= "\r\n<div {$cssClass}{$strPriceList}><a href='event-details.php?e={$show['master_id']}&date={$dateKey}{$rttUrl}'>{$show['']} # {$show['show_time']}</a></div>";
}
}
$calendar .= '</td>';
if( date('w',$timeStamp) == 0 ) {
$calendar .= "\r\n</tr>";
}
$timeStamp += 86400; // Get the next day (in seconds).
}
$dayOfWeekPadding = date('w',$timeStamp);
if( $dayOfWeekPadding == 0 ) {
$dayOfWeekPadding = 6;
} else if( $dayOfWeekPadding == 0 ) {
$dayOfWeekPadding = 0; // do not have an empty week of padding
} else {
$dayOfWeekPadding = 6 - $dayOfWeekPadding;
}
for($day=0; $day < $dayOfWeekPadding; $day++) {
$calendar .= "\r\n<td class='EventCalendar_EmptyDate'> </td>";
}
if( $dayOfWeekPadding > 0 ) {
$calendar .= "\r\n</tr>";
}
$calendar .= "\r\n</tbody></table>";
if( !empty($cstage['cache']) ) {
$cstage['cache']->save($calendar, $keyEventCalendar);
}
}
return $calendar;
}
I want to add a custom text around a barcode inside a PDF-document using Zend_Pdf and Zend_Barcode. Right now it is only showing the barcode but I want to add my custom text too above it.
So now I am getting this:
but I want this:
Here is my code:
$pdf = new Zend_Pdf();
$hidden =$_POST['hidden'];
$quantityfrom =$_POST['quantity_from'];
$quantityto =$_POST['quantity_to'];
//Here is code for update the Quantity
$product_id = $_POST['product_id'];
$table = new Account_Model_DbTable_Products();
$query = $table->updateQuantity($product_id,$quantityto);
Zend_Barcode::setBarcodeFont(dirname(ROOT_PATH) . '/inventory/library/Zend/Barcode/Object/fonts/open-sans/OpenSans-Semibold.ttf');
$numberOfPages = ceil(($quantityto-$quantityfrom)/15);
$equipmentCount = $quantityto-$quantityfrom+1;
for($i = 1; $i <= $numberOfPages; $i++)
{
$page = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4);
$width = $page->getWidth(); // A4 : 595
$height = $page->getHeight(); // A4 : 842
$page->setFont(Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA), 20);
$pdf->pages[] = $page;
}
$index = 0;
for($j=1 ; $j<=$numberOfPages;$j++){
if($equipmentCount > 10)
{
$barcodesOnThisPage = 10;
$equipmentCount = $equipmentCount - 10;
}
else
{
$barcodesOnThisPage = $equipmentCount;
}
echo $barcodesOnThisPage."</br>";
$k = 1;
for($i=1;$i<=$barcodesOnThisPage;$i++){
$num_padded = sprintf("%04d", $quantityfrom);
$barcodeOptions = array(
'text' => $hidden.$num_padded,
'barHeight' =>100,
);
$rendererOptions = array(
'topOffset' => 80*$k,
'horizontalPosition' =>'left'
);
$pdfWithBarcode = Zend_Barcode::factory('code39', 'pdf',
$barcodeOptions, $rendererOptions)->setResource($pdf,$index)->draw();
$pdfWithBarcode->save('testBarcode.pdf');
$k++;
$quantityfrom++;
}
$index++;
}
$this->_redirect('/testBarcode.pdf');
}
I wrote this code using C++ example from net to rotate my set of points in 3D.
##matrix is points and their 3D coordinates.
#rotated_matrix = rotate_l(\#matrix, 0);
sub rotate_l {
my $ref = $_[0];
my $x = 0;
my $step = 1;
#if rotx
if ($_[1] == 0) {
while ($$ref[$x][0]) {
$$ref[$x][1] += ($$ref[$x][1]*cos($step) - $$ref[$x][2]*sin($step));
$$ref[$x][2] += ($$ref[$x][1]*sin($step) + $$ref[$x][2]*cos($step));
$x++;
}
}
#if roty
if ($_[1] == 1) {
while ($$ref[$x][0]) {
$$ref[$x][0] += ( $$ref[$x][0]*cos($step) + $$ref[$x][2]*sin($step));
$$ref[$x][2] += (-$$ref[$x][0]*sin($step) + $$ref[$x][2]*cos($step));
$x++;
}
}
#if rotz
if ($_[1] == 2) {
while ($$ref[$x][0]) {
$$ref[$x][0] += ($$ref[$x][0]*cos($step) - $$ref[$x][1]*sin($step));
$$ref[$x][1] += ($$ref[$x][0]*sin($step) + $$ref[$x][1]*cos($step));
$x++;
}
}
return #$ref;
}
But something is wrong. Object size/form fails to stay same. And my math is not that good to realize why. I even not sure I need += or =?
Thx amon. As suggested this works:
##matrix is points and their 3D coordinates.
#rotated_matrix = rotate_l(\#matrix, 0);
sub rotate_l {
my $ref = $_[0];
my $x = 0;
my $step = pi;
#if rotx
if ($_[1] == 0) {
while ($$ref[$x][0]) {
$$ref[$x][1] = ($$ref[$x][1]*cos($step) - $$ref[$x][2]*sin($step));
$$ref[$x][2] = ($$ref[$x][1]*sin($step) + $$ref[$x][2]*cos($step));
$x++;
}
}
#if roty
if ($_[1] == 1) {
while ($$ref[$x][0]) {
$$ref[$x][0] = ( $$ref[$x][0]*cos($step) + $$ref[$x][2]*sin($step));
$$ref[$x][2] = (-$$ref[$x][0]*sin($step) + $$ref[$x][2]*cos($step));
$x++;
}
}
#if rotz
if ($_[1] == 2) {
while ($$ref[$x][0]) {
$$ref[$x][0] = ($$ref[$x][0]*cos($step) - $$ref[$x][1]*sin($step));
$$ref[$x][1] = ($$ref[$x][0]*sin($step) + $$ref[$x][1]*cos($step));
$x++;
}
}
return #$ref;
}
If I need to rotate not around (0,0,0), but against other point the best way is to translate to 0 point rotate and then translate back?
Just as an example of what I meant by what I recommend you do:
#! /usr/bin/env perl
use common::sense;
use YAML 'Dump';
sub translate {
my ($deltaX, $deltaY) = #{pop()}; # <-- don't mind this.
for (#_) { # <--- this is the important part
$_->[0] += $deltaX;
$_->[1] += $deltaY;
}
#_
}
my #points = ([0, 1], [0, -1], [-1, 0], [1, 0]);
print Dump([translate #points, [2, 2]]);
my $box = \#points;
print Dump([translate #$box, [5, 0]]);