473,594 Members | 2,757 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

width of a charactor

In php, is there a way obtain the width of a charactor of a certain font?

Alex

--
=============== =============== =============== =====
Cell Phone Batteries at 30-50%+ off retail prices!
http://www.pocellular.com
=============== =============== =============== =====
Jul 17 '05 #1
2 3168
"Alex Shi" <ch****@stonix. com> wrote in message
news:F8******** **********@nntp-post.primus.ca. ..
In php, is there a way obtain the width of a charactor of a certain font?

Alex

--
=============== =============== =============== =====
Cell Phone Batteries at 30-50%+ off retail prices!
http://www.pocellular.com
=============== =============== =============== =====


yes/no

Depends on where this chr is destined, if you are working with images, yes,
if you are working with web pages no. But if you need to set chr width, do
it in CSS.

--
Mike Bradley
http://www.gzentools.com -- free online php tools
Jul 17 '05 #2
Uzytkownik "Alex Shi" <ch****@stonix. com> napisal w wiadomosci
news:F8******** **********@nntp-post.primus.ca. ..
In php, is there a way obtain the width of a charactor of a certain font?

Alex

--
=============== =============== =============== =====
Cell Phone Batteries at 30-50%+ off retail prices!
http://www.pocellular.com
=============== =============== =============== =====


Yes, but it's rather painful. With Type 1 fonts it's easier, as the width
info is stored in a plain text file. With TrueType fonts it's quite hard.

Look at the PDF functions and see if there's a function that yields the
width of a string. Some time ago I've written a PDF layout engine in PHP.
Exactly how it works I can't remember. There's a PDFTrueTypeFont class in
there. The GetTextWidth method should give you the width of a text string,
while GetCharWidth method--the width of a char.

[begin code flood]

<?php

$TTFDirectory = false;
$Type1Directory = false;
$imageDirectory = false;
$charMapDirecto ry = false;

class PDFObj {
var $id;
var $offset;

function SetId($id) {
$this->id = $id;
}

function SetOffset($pos) {
$this->offset = $pos;
}

function Registered() {
return $this->id ? True : False;
}

function Reference() {
return "$this->id 0 R";
}

function Written() {
return $this->offset ? True : False;
}

function Output(&$pdf_fi le) {
$pdf_file->Write("$this->id 0 obj\n");
$pdf_file->Write($this->ToString());
$pdf_file->Write("\nendob j\n");
}
}

class PDFBoolean extends PDFObj {
var $value;

function PDFBoolean($val ue) {
$this->value = $value;
}

function ToString() {
return ($this->value) ? 'true' : 'false';
}
}

class PDFInteger extends PDFObj {
var $value;

function PDFInteger($val ue) {
$this->value = $value;
}

function Add($value) {
$this->value += $value;
}

function ToString() {
return (string) $this->value;
}
}

class PDFHex extends PDFInteger {

function PDFHex($value) {
$this->PDFInteger($va lue);
}

function ToString() {
if($this->value < 256) $format = '<%02x>';
else if($this->value < 65536) $format = '<%04x>';
else $format = '<%08x>';
return sprintf($format , $this->value);
}
}

$string_escape_ table = array('(' => '\\(', ')' => '\\)', '\\' => '\\\\',
"\n" => '\n', "\r" => '\r', "\t" => '\t');

class PDFString extends PDFObj {
var $value;

function PDFString($valu e) {
$this->value = $value;
}

function Prepend($obj) {
$this->value = ((get_class($ob j) == 'pdfstring') ? $obj->value : $obj) .
$this->value;
}

function Append($obj) {
$this->value .= ((get_class($ob j) == 'pdfstring') ? $obj->value : $obj);
}

function IsEmpty() {
return (strlen($this->value) == 0);
}

function ToString() {
global $string_escape_ table;
return '(' . strtr($this->value, $string_escape_ table) . ')';
}
}

class PDFName extends PDFObj {
var $value;

function PDFName($value) {
$this->value = $value;
}

function ToString() {
return "/$this->value";
}
}

function Name($name) {
return new PDFName($name);
}

class PDFCollection extends PDFObj {

function NewObj($value) {
if(is_numeric($ value))
{
return new PDFInteger($val ue);
}
else if(is_string($v alue))
{
return new PDFString($valu e);
}
else if(is_array($va lue))
{
if(sizeof($valu e) > 0 && !isset($value[0])) // is associative array
{
$new_array = new PDFDictionary() ;
foreach($value as $akey => $avalue)
{
if(is_object($a value))
{
$new_array->AssignObj($ake y, $value[$akey]);
}
else
{
$new_array->Assign($akey , $avalue);
}
}
}
else
{
$new_array = new PDFArray();
foreach($value as $akey => $avalue)
{
if(is_object($a value))
{
$new_array->AddObj($valu e[$akey]);
}
else
{
$new_array->Add($avalue) ;
}
}
}
return $new_array;
}
else
{
return new PDFBoolean($val ue);
}
}
}

class PDFDictionary extends PDFCollection {
var $values;

function PDFDictionary($ type = false) {
$this->values = array();
if($type)
{
$this->values['Type'] = new PDFName($type);
}
}

function Assign($key, $value) {
if($value !== False)
{
if(is_object($v alue))
{
$this->values[$key] = $value;
}
else
{
$this->values[$key] = PDFCollection:: NewObj($value);
}
}
}

function AssignObj($key, &$obj) {
if(!is_object($ obj))
{
die("$key not an object!");
}
$this->values[$key] = &$obj;
}

function IsAssigned($key ) {
return isset($this->values[$key]);
}

function Unassign($key) {
unset($this->values[$key]);
}

function &Object($key ) {
return $this->values[$key];
}

function ToString() {
$s = '<<';
foreach($this->values as $key => $obj)
{
$s .= " /$key ";
if($obj->Registered() )
{
$s .= $obj->Reference();
}
else
{
$s .= $obj->ToString($valu e);
}
}
$s .= ' >>';
return $s;
}
}

class PDFArray extends PDFCollection {
var $values;

function PDFArray() {
$this->values = array();
}

function Count() {
return sizeof($this->values);
}

function Add($value) {
if($value !== False)
{
$index = count($this->values);
$this->values[] = PDFCollection:: NewObj($value);
return $index;
}
}

function AddObj(&$obj) {
$index = count($this->values);
$this->values[] = &$obj;
return $index;
}

function InsertObj(&$obj , $index) {
array_splice($t his->values, $index, 0, array(0));
$this->values[$index] = &$obj;
return $index;
}

function IsEmpty() {
return (sizeof($this->values) == 0);
}

function ToString() {
$s = '[';
foreach($this->values as $obj)
{
$s .= ' ';
if($obj->Registered() )
{
$s .= $obj->Reference();
}
else
{
$s .= $obj->ToString();
}
}
$s .= ' ]';
return $s;
}
}

class PDFStream extends PDFDictionary {
var $data;

function PDFStream($type = false) {
$this->PDFDictionary( $type);
}

function Write($s) {
$this->data .= $s;
}

function Output(&$pdf_fi le) {
$this->Assign('Length ', strlen($this->data));
$pdf_file->Write("$this->id 0 obj\n");
$pdf_file->Write($this->ToString());
$pdf_file->Write("\nstrea m\n");
$pdf_file->Write($this->data);
$pdf_file->Write("endstre am");
$pdf_file->Write("\nendob j\n");
}
}

class PDFFileStream extends PDFStream {

function PDFFileStream($ filePath) {
$this->PDFStream();
$filesize = filesize($fileP ath);
$file = fopen($filePath , "rb");
$this->data = fread($file, $filesize);
fclose($file);
}
}

if(function_exi sts('gzdeflate' ))
{

class PDFFlateStream extends PDFStream {
var $data;

function PDFFlateStream( ) {
$this->PDFStream();
$this->Assign('Filter ', Name('FlateDeco de'));
}

function Output(&$pdf_fi le) {
$deflated_data = gzdeflate($this->data);
$length = strlen($deflate d_data) + 2;
$this->Assign('Length ', $length);
$pdf_file->Write("$this->id 0 obj\n");
$pdf_file->Write($this->ToString());
$pdf_file->Write("\nstrea m\n");
$pdf_file->Write("H‰");
$pdf_file->Write($deflate d_data);
$pdf_file->Write("endstre am");
$pdf_file->Write("\nendob j\n");
}
}

class PDFFlateFileStr eam extends PDFFlateStream {

function PDFFlateFileStr eam($filePath) {
$this->PDFFlateStream ();
$filesize = filesize($fileP ath);
$file = fopen($filePath , "rb");
$this->data = fread($file, $filesize);
fclose($file);
}
}

}
else
{

class PDFFlateStream extends PDFStream {
var $data;
var $temp_file;
var $temp_filename;

function PDFFlateStream( ) {
$this->PDFStream();
$this->Assign('Filter ', Name('FlateDeco de'));
$this->temp_filenam e = tempnam('', 'strm');
$this->temp_file = fopen($this->temp_filenam e, "wb");
}

function Write($s) {
fwrite($this->temp_file, $s);
}

function Output(&$pdf_fi le) {
fclose($this->temp_file);
`gzip -9nf $this->temp_filename` ;
$this->temp_filenam e .= '.gz';
$filesize = filesize($this->temp_filename) ;
$gz = fopen($this->temp_filenam e, 'rb');
fseek($gz, 10);
$deflated_data = fread($gz, $filesize - 14);
fclose($gz);
unlink($this->temp_filename) ;
$length = $filesize - 14 + 2;
$this->Assign('Length ', $length);
$pdf_file->Write("$this->id 0 obj\n");
$pdf_file->Write($this->ToString());
$pdf_file->Write("\nstrea m\n");
$pdf_file->Write("H‰");
$pdf_file->Write($deflate d_data);
$pdf_file->Write("endstre am");
$pdf_file->Write("\nendob j\n");
}
}

class PDFFlateFileStr eam extends PDFStream {
var $filePath;

function PDFFlateFileStr eam($filePath) {
$this->PDFStream();
$this->filePath = $filePath;
}

function Output(&$pdf_fi le) {
$gzip_data = `gzip -9cnf $this->filePath`;
$deflated_data = substr($gzip_da ta, 10, -4);
$length = strlen($deflate d_data) + 2;
$this->Assign('Length ', $length);
$pdf_file->Write("$this->id 0 obj\n");
$pdf_file->Write($this->ToString());
$pdf_file->Write("\nstrea m\n");
$pdf_file->Write("H‰");
$pdf_file->Write($deflate d_data);
$pdf_file->Write("endstre am");
$pdf_file->Write("\nendob j\n");
}
}

}

class PDFTrueTypeFile Stream extends PDFFlateFileStr eam {

function PDFTrueTypeFile Stream($filePat h) {
$this->PDFFlateFileSt ream($filePath) ;
$this->Assign('Length 1', strlen($this->data));
}
}

class PDFType1FileStr eam extends PDFFileStream {

function PDFType1FileStr eam($filePath) {
$this->PDFFileStream( $filePath);
$encrypted_star t_index = strpos($this->data, "currentfil e eexec\r") + 18;
$encrypted_end_ index = strpos($this->data,
"00000000000000 000000000000000 000000000000000 000000000000000 00000");
$this->Assign('Length 1', $encrypted_star t_index);
$this->Assign('Length 2', $encrypted_end_ index - $encrypted_star t_index);
$this->Assign('Length 3', strlen($this->data) - $encrypted_end_ index);
}
}

class PDFRect extends PDFObj {
var $left;
var $top;
var $right;
var $bottom;
var $width;
var $height;

function PDFRect($left, $top, $right, $bottom) {
$this->left = (int) $left;
$this->top = (int) $top;
$this->right = (int) $right;
$this->bottom = (int) $bottom;
$this->width = $right - $left;
$this->height = $top - $bottom;
}

function ToString() {
return "[$this->left $this->top $this->right $this->bottom]";
}
}

class PDFDate extends PDFString {

function PDFDate($value = False) {
if(!$value) $value = time();
$this->PDFString('D :' . gmdate('YmdHis' ) . 'Z');
}
}

define('BLACK', 0);
define('WHITE', 1);
define('LIGHTGR AY', 0.9);
define('DARKGRA Y', 0.4);

class PDFGray extends PDFObj {
var $level;

function PDFGray($level) {
$this->level = $level;
}

function ToStringStrokin g() {
return "$this->level G\n";
}

function ToStringNonStro king() {
return "$this->level g\n";
}
}

class PDFRGB extends PDFObj {
var $r;
var $g;
var $b;

function PDFRGB($r, $g, $b) {
$this->r = $r;
$this->g = $g;
$this->b = $b;
}

function ToStringStrokin g() {
return "$this->r $this->g $this->b RG\n";
}

function ToStringNonStro king() {
return "$this->r $this->g $this->b rg\n";
}
}

function ToUnicodeStr($s , $encoding) {
$map = GetCharSetUnico deMap($encoding );
$us = "\xfe\xff";
for($i = 0, $len = strlen($s); $i < $len; $i++)
{
$c = ord($s[$i]);
$uc = $map[$c];
$us .= chr($uc >> 8) . chr($uc & 0x00FF);
}
return $us;
}

class PDFBookmark extends PDFDictionary {

function PDFBookmark(&$p age, $title, $encoding = 'WinAnsiEncodin g', $top =
false) {
$this->PDFDictionary( );
$this->Assign('Title' , ToUnicodeStr($t itle, $encoding));
$dest = ($top) ? array(&$page, Name('FitH'), $top) : array(&$page,
Name('Fit'));
$this->Assign('Dest ', $dest);
}

function SetParent(&$par ent) {
$this->Assign('Parent ', $parent);
if(!$parent->IsAssigned('Fi rst'))
{
$parent->AssignObj('Fir st', $this);
}
if($parent->IsAssigned('La st'))
{
$last =& $parent->Object('Last') ;
$last->AssignObj('Nex t', $this);
$this->AssignObj('Pre v', $last);
}
$parent->AssignObj('Las t', $this);
}
}

class PDFWebBookmark extends PDFDictionary {

function PDFWebBookmark( $title, $url) {
$this->PDFDictionary( );
$this->Assign('Title' , $title);
$action = new PDFDictionary() ;
$action->Assign('S', Name('URI'));
$action->Assign('URI' , $url);
$this->AssignObj('A ', $action);
}

function SetParent(&$par ent) {
$this->Assign('Parent ', $parent);
if(!$parent->IsAssigned('Fi rst'))
{
$parent->AssignObj('Fir st', $this);
}
if($parent->IsAssigned('La st'))
{
$last =& $parent->Object('Last') ;
$last->AssignObj('Nex t', $this);
$this->AssignObj('Pre v', $last);
}
$parent->AssignObj('Las t', $this);
}
}

class PDFPageLabel extends PDFDictionary {

function PDFPageLabel($s tyle, $prefix = False, $encoding =
'WinAnsiEncodin g') {
if($style)
{
$this->Assign('S', Name($style));
}
if($prefix)
{
$this->Assign('P', ToUnicodeStr($p refix, $encoding));
}
}
}

class PDFKernedString extends PDFArray {

function PDFKernedString ($value = False, $offset = False) {
$this->PDFArray();
if($value)
{
$this->Add($value);
if($offset) $this->Add($offset) ;
}
}

function Prepend($obj) {
if(sizeof($this->values) > 0)
{
$this->values[0]->Prepend($obj );
}
else
{
$this->Add($obj);
}
}

function Append($obj, $offset = False) {
$last_index = sizeof($this->values) - 1;
if($last_index < 0 || get_class($this->values[$last_index]) ==
'pdfinteger')
{
$this->Add($obj);
}
else
{
if(get_class($o bj) == 'pdfkernedstrin g')
{
$this->values[$last_index]->Append($obj->values[0]);
for($i = 1; $i < sizeof($obj->values); $i++)
{
$this->AddObj($obj->values[$i]);
}
}
else
{
$this->values[$last_index]->Append($obj) ;
}
}
if($offset)
{
$this->Add(- $offset);
}
}
}

class PDFFont extends PDFDictionary {
var $ref_name;
var $widths;
var $rExtents;
var $kerning_pairs;
var $properties;

function PDFFont() {
global $font_number;
$font_number++;
$ref_name = "F$font_number" ;
$this->PDFDictionary( 'Font');
$this->Assign('Name ', Name($ref_name) );
$this->ref_name = $ref_name;
}

function Transform($text , $size) {
$len = strlen($text);
if($this->kerning_pair s)
{
for($i = 0; $i < $len; $i++)
{
$char = ord($text{$i});
$width += $this->widths[$char];
if($kerning_off sets = $this->kerning_pair s[$char])
{
$next_index = $i + 1;
$next_char = ord($text{$next _index});
if($offset = $kerning_offset s[$next_char])
{
if(!$kerned_str ing) $kerned_string = new PDFKernedString ();
$kerned_string->Append(substr( $text, $last_kerned_ch ar, $next_index -
$last_kerned_ch ar), $offset);
$last_kerned_ch ar = $next_index;
$width += $offset;
}
}
}
}
else
{
for($i = 0; $i < $len; $i++)
{
$char = ord($text{$i});
$width += $this->widths[$char];
}
}
$pt_width = $width * $size / 1000;
$r_extent = $this->rExtents[ord($text{$len - 1})] * $size / 1000;
if($kerned_stri ng)
{
$kerned_string->Append(substr( $text, $last_kerned_ch ar));
return array($kerned_s tring, $pt_width, $r_extent);
}
else
{
return array(new PDFString($text ), $pt_width, $r_extent);
}
}

function GetCharWidth($c har, $size) {
return $this->widths[ord($char)] * $size / 1000;
}

function GetTextWidth($t ext, $size) {
$len = strlen($text);
if($this->kerning_pair s)
{
for($i = 0; $i < $len; $i++)
{
$char = ord($text{$i});
$width += $this->widths[$char];
if($kerning_off sets = $this->kerning_pair s[$char])
{
$next_index = $i + 1;
$next_char = ord($text{$next _index});
if($offset = $kerning_offset s[$next_char])
{
$width += $offset;
}
}
}
}
else
{
for($i = 0; $i < $len; $i++)
{
$char = ord($text{$i});
$width += $this->widths[$char];
}
}
$pt_width = $width * $size / 1000;
return $pt_width;
}
}

function ParseCPGFile($f ilePath) {
$char_to_unicod e_map = array();
$lines = file($filePath) ;
foreach($lines as $line)
{
if(list($unicod eHex, $charCodeHex) = explode("\t", $line))
{
if(!strncmp($un icodeHex, '0x', 2) && !strncmp($charC odeHex, '0x', 2))
{
$unicode = hexdec(substr($ unicodeHex, 2));
$charCode = hexdec(substr($ charCodeHex, 2));
$char_to_unicod e_map[$charCode] = $unicode;
}
}
}
return $char_to_unicod e_map;
}

function ParseENCFile($f ilePath) {
$char_to_name_m ap = array();
$lines = file($filePath) ;
foreach($lines as $line)
{
if(list($name, $charCode) = preg_split('/\\s+/', $line, -1,
PREG_SPLIT_NO_E MPTY))
{
if($name{0} != '%' && is_numeric($cha rCode))
{
$char_to_name_m ap[(int) $charCode] = $name;
}
}
}
return $char_to_name_m ap;
}

$winAnsiEncodin gNameMap = array(
32 => 'space', 33 => 'exclam', 34 => 'quotedbl', 35 => 'numbersign',
36 => 'dollar', 37 => 'percent', 38 => 'ampersand', 39 => 'quotesingle',
40 => 'parenleft', 41 => 'parenright', 42 => 'asterisk', 43 => 'plus',
44 => 'comma', 45 => 'hyphen', 46 => 'period', 47 => 'slash',
48 => 'zero', 49 => 'one', 50 => 'two', 51 => 'three',
52 => 'four', 53 => 'five', 54 => 'six', 55 => 'seven',
56 => 'eight', 57 => 'nine', 58 => 'colon', 59 => 'semicolon',
60 => 'less', 61 => 'equal', 62 => 'greater', 63 => 'question',
64 => 'at', 65 => 'A', 66 => 'B', 67 => 'C',
68 => 'D', 69 => 'E', 70 => 'F', 71 => 'G',
72 => 'H', 73 => 'I', 74 => 'J', 75 => 'K',
76 => 'L', 77 => 'M', 78 => 'N', 79 => 'O',
80 => 'P', 81 => 'Q', 82 => 'R', 83 => 'S',
84 => 'T', 85 => 'U', 86 => 'V', 87 => 'W',
88 => 'X', 89 => 'Y', 90 => 'Z', 91 => 'bracketleft',
92 => 'backslash', 93 => 'bracketright', 94 => 'asciicircum', 95 =>
'underscore',
96 => 'grave', 97 => 'a', 98 => 'b', 99 => 'c',
100 => 'd', 101 => 'e', 102 => 'f', 103 => 'g',
104 => 'h', 105 => 'i', 106 => 'j', 107 => 'k',
108 => 'l', 109 => 'm', 110 => 'n', 111 => 'o',
112 => 'p', 113 => 'q', 114 => 'r', 115 => 's', 116 => 't', 117 => 'u',
118 => 'v', 119 => 'w',
120 => 'x', 121 => 'y', 122 => 'z', 123 => 'braceleft',
124 => 'bar', 125 => 'braceright', 126 => 'asciitilde', 128 => 'Euro',
130 => 'quotesinglbase ',131 => 'florin', 132 => 'quotedblbase', 133 =>
'ellipsis',
134 => 'dagger', 135 => 'daggerdbl', 136 => 'circumflex', 137 =>
'perthousand',
138 => 'Scaron', 139 => 'guilsinglleft' , 140 => 'OE', 142 => 'Zcaron',
145 => 'quoteleft', 146 => 'quoteright', 147 => 'quotedblleft', 148 =>
'quotedblright' ,
150 => 'endash', 151 => 'emdash', 152 => 'tilde', 153 => 'trademark',
154 => 'scaron', 155 => 'guilsinglright ',156 => 'oe', 158 => 'zcaron',
159 => 'Ydieresis', 161 => 'exclamdown', 162 => 'cent', 163 => 'sterling',
164 => 'currency1', 165 => 'yen', 166 => 'brokenbar', 167 => 'section',
168 => 'dieresis', 169 => 'copyright', 170 => 'ordfeminine', 171 =>
'guillemotleft' ,
172 => 'logicalnot', 174 => 'registered', 175 => 'macron', 176 => 'degree',
177 => 'plusminus', 178 => 'twosuperior', 179 => 'threesuperior' , 180 =>
'acute',
181 => 'mu', 182 => 'paragraph', 183 => 'periodcentered ',184 => 'cedilla',
185 => 'onesuperior', 186 => 'ordmasculine', 187 => 'guillemotright ',188 =>
'onequarter',
189 => 'onehalf', 190 => 'threequarters' , 191 => 'questiondown', 192 =>
'Agrave',
193 => 'Aacute', 194 => 'Acircumflex', 195 => 'Atilde', 196 => 'Adieresis',
197 => 'Aring', 198 => 'AE', 199 => 'Ccedilla', 200 => 'Egrave',
201 => 'Eacute', 202 => 'Ecircumflex', 203 => 'Edieresis', 204 => 'Igrave',
205 => 'Iacute', 206 => 'Icircumflex', 207 => 'Idieresis', 208 => 'Eth',
209 => 'Ntilde', 210 => 'Ograve', 211 => 'Oacute', 212 => 'Ocircumflex',
213 => 'Otilde', 214 => 'Odieresis', 215 => 'multiply', 216 => 'Oslash',
217 => 'Ugrave', 218 => 'Uacute', 219 => 'Ucircumflex', 220 => 'Udieresis',
221 => 'Yacute', 222 => 'Thorn', 223 => 'germandbls', 224 => 'agrave',
225 => 'aacute', 226 => 'acircumflex', 227 => 'atilde', 228 => 'adieresis',
229 => 'aring', 230 => 'ae', 231 => 'ccedilla', 232 => 'egrave',
233 => 'eacute', 234 => 'ecircumflex', 235 => 'edieresis', 236 => 'igrave',
237 => 'iacute', 238 => 'icircumflex', 239 => 'idieresis', 240 => 'eth',
241 => 'ntilde', 242 => 'ograve', 243 => 'oacute', 244 => 'ocircumflex',
245 => 'otilde', 246 => 'odieresis', 247 => 'divide', 248 => 'oslash',
249 => 'ugrave', 250 => 'uacute', 251 => 'ucircumflex', 252 => 'udieresis',
253 => 'yacute', 254 => 'thorn', 255 => 'ydieresis');

$winAnsiEncodin gUnicodeMap = array(
0x20 => 0x20, 0x21 => 0x21, 0x22 => 0x22, 0x23 => 0x23,
0x24 => 0x24, 0x25 => 0x25, 0x26 => 0x26, 0x27 => 0x27,
0x28 => 0x28, 0x29 => 0x29, 0x2a => 0x2a, 0x2b => 0x2b,
0x2c => 0x2c, 0x2d => 0x2d, 0x2e => 0x2e, 0x2f => 0x2f,
0x30 => 0x30, 0x31 => 0x31, 0x32 => 0x32, 0x33 => 0x33,
0x34 => 0x34, 0x35 => 0x35, 0x36 => 0x36, 0x37 => 0x37,
0x38 => 0x38, 0x39 => 0x39, 0x3a => 0x3a, 0x3b => 0x3b,
0x3c => 0x3c, 0x3d => 0x3d, 0x3e => 0x3e, 0x3f => 0x3f,
0x40 => 0x40, 0x41 => 0x41, 0x42 => 0x42, 0x43 => 0x43,
0x44 => 0x44, 0x45 => 0x45, 0x46 => 0x46, 0x47 => 0x47,
0x48 => 0x48, 0x49 => 0x49, 0x4a => 0x4a, 0x4b => 0x4b,
0x4c => 0x4c, 0x4d => 0x4d, 0x4e => 0x4e, 0x4f => 0x4f,
0x50 => 0x50, 0x51 => 0x51, 0x52 => 0x52, 0x53 => 0x53,
0x54 => 0x54, 0x55 => 0x55, 0x56 => 0x56, 0x57 => 0x57,
0x58 => 0x58, 0x59 => 0x59, 0x5a => 0x5a, 0x5b => 0x5b,
0x5c => 0x5c, 0x5d => 0x5d, 0x5e => 0x5e, 0x5f => 0x5f,
0x60 => 0x60, 0x61 => 0x61, 0x62 => 0x62, 0x63 => 0x63,
0x64 => 0x64, 0x65 => 0x65, 0x66 => 0x66, 0x67 => 0x67,
0x68 => 0x68, 0x69 => 0x69, 0x6a => 0x6a, 0x6b => 0x6b,
0x6c => 0x6c, 0x6d => 0x6d, 0x6e => 0x6e, 0x6f => 0x6f,
0x70 => 0x70, 0x71 => 0x71, 0x72 => 0x72, 0x73 => 0x73,
0x74 => 0x74, 0x75 => 0x75, 0x76 => 0x76, 0x77 => 0x77,
0x78 => 0x78, 0x79 => 0x79, 0x7a => 0x7a, 0x7b => 0x7b,
0x7c => 0x7c, 0x7d => 0x7d, 0x7e => 0x7e, 0x80 => 0x20ac,
0x82 => 0x201a, 0x83 => 0x192, 0x84 => 0x201e, 0x85 => 0x2026,
0x86 => 0x2020, 0x87 => 0x2021, 0x88 => 0x2c6, 0x89 => 0x2030,
0x8a => 0x160, 0x8b => 0x2039, 0x8c => 0x152, 0x8e => 0x17d,
0x91 => 0x2018, 0x92 => 0x2019, 0x93 => 0x201c, 0x94 => 0x201d,
0x96 => 0x2013, 0x97 => 0x2014, 0x98 => 0x2dc, 0x99 => 0x2122,
0x9a => 0x161, 0x9b => 0x203a, 0x9c => 0x153, 0x9e => 0x17e,
0x9f => 0x178, 0xa1 => 0xa1, 0xa2 => 0xa2, 0xa3 => 0xa3,
0xa4 => 0xa4, 0xa5 => 0xa5, 0xa6 => 0xa6, 0xa7 => 0xa7,
0xa8 => 0xa8, 0xa9 => 0xa9, 0xaa => 0xaa, 0xab => 0xab,
0xac => 0xac, 0xae => 0xae, 0xaf => 0xaf, 0xb0 => 0xb0,
0xb1 => 0xb1, 0xb2 => 0xb2, 0xb3 => 0xb3, 0xb4 => 0xb4,
0xb5 => 0xb5, 0xb6 => 0xb6, 0xb7 => 0xb7, 0xb8 => 0xb8,
0xb9 => 0xb9, 0xba => 0xba, 0xbb => 0xbb, 0xbc => 0xbc,
0xbd => 0xbd, 0xbe => 0xbe, 0xbf => 0xbf, 0xc0 => 0xc0,
0xc1 => 0xc1, 0xc2 => 0xc2, 0xc3 => 0xc3, 0xc4 => 0xc4,
0xc5 => 0xc5, 0xc6 => 0xc6, 0xc7 => 0xc7, 0xc8 => 0xc8,
0xc9 => 0xc9, 0xca => 0xca, 0xcb => 0xcb, 0xcc => 0xcc,
0xcd => 0xcd, 0xce => 0xce, 0xcf => 0xcf, 0xd0 => 0xd0,
0xd1 => 0xd1, 0xd2 => 0xd2, 0xd3 => 0xd3, 0xd4 => 0xd4,
0xd5 => 0xd5, 0xd6 => 0xd6, 0xd7 => 0xd7, 0xd8 => 0xd8,
0xd9 => 0xd9, 0xda => 0xda, 0xdb => 0xdb, 0xdc => 0xdc,
0xdd => 0xdd, 0xde => 0xde, 0xdf => 0xdf, 0xe0 => 0xe0,
0xe1 => 0xe1, 0xe2 => 0xe2, 0xe3 => 0xe3, 0xe4 => 0xe4,
0xe5 => 0xe5, 0xe6 => 0xe6, 0xe7 => 0xe7, 0xe8 => 0xe8,
0xe9 => 0xe9, 0xea => 0xea, 0xeb => 0xeb, 0xec => 0xec,
0xed => 0xed, 0xee => 0xee, 0xef => 0xef, 0xf0 => 0xf0,
0xf1 => 0xf1, 0xf2 => 0xf2, 0xf3 => 0xf3, 0xf4 => 0xf4,
0xf5 => 0xf5, 0xf6 => 0xf6, 0xf7 => 0xf7, 0xf8 => 0xf8,
0xf9 => 0xf9, 0xfa => 0xfa, 0xfb => 0xfb, 0xfc => 0xfc,
0xfd => 0xfd, 0xfe => 0xfe, 0xff => 0xff );

$charSetNameMap s = array('WinAnsiE ncoding' => $winAnsiEncodin gNameMap);
$charSetUnicode Maps = array('WinAnsiE ncoding' =>
$winAnsiEncodin gUnicodeMap);

function GetCharSetUnico deMap($charSet) {
global $charMapDirecto ry, $charSetUnicode Maps;
if(!($map = $charSetUnicode Maps[$charSet]))
{
if(!$charMapDir ectory)
{
die("GetCharSet UnicodeMap: global variable \$charMapDirect ory not set");
}
$map = ParseCPGFile("$ charMapDirector y/$charSet.cpg");
$charSetUnicode Maps[$charSet] = $map;
}
return $map;
}

function GetCharSetNameM ap($charSet) {
global $charMapDirecto ry, $charSetNameMap s;
if(!($map = $charSetNameMap s[$charSet]))
{
if(!$charMapDir ectory)
{
die("GetCharSet NameMap: global variable \$charMapDirect ory not set");
}
$map = ParseENCFile("$ charMapDirector y/$charSet.enc");
$charSetNameMap s[$charSet] = $map;
}
return $map;
}

function GetInverseMap($ map) {
$imap = array();
foreach($map as $apple => $orange)
{
if(!$imap[$orange]) !$imap[$orange] = array();
$imap[$orange][] = $apple;
}
return $imap;
}

class PDFEncodingCMap extends PDFFlateStream {
var $CIDSystemInfo;

function PDFEncodingCMap ($charSet, $char_to_glyph_ map) {
$this->PDFFlateStream ('CMap');
$this->Assign('CMapNa me', $charSet);
$this->CIDSystemInf o = new PDFDictionary() ;
$this->CIDSystemInf o->Assign('Regist ry', $charSet);
$this->CIDSystemInf o->Assign('Orderi ng', $charSet);
$this->CIDSystemInf o->Assign('Supple ment', 0);
$this->AssignObj('CID SystemInfo', $this->CIDSystemInfo) ;
$this->Write(<<<CMAP_ HEADER
/CIDInit /ProcSet findresource
begin
12 dict
begin
begincmap
/CIDSystemInfo <</Registry ($charSet) /Ordering ($charSet) /Supplement 0 >>
def
/CMapName /$charSet def 1
/CMapType 1 def
CMAP_HEADER
);
$this->Write("1 begincodespacer ange\n<00> <FF>\nendcodesp acerange\n");
$glyphRangeStar t = false;
$nextGlyphId = -1;
$nextCharCode = -1;
$cidRangeEntrie s = array();
foreach($char_t o_glyph_map as $charCode => $glyphId)
{
if($nextCharCod e == $charCode && $glyphId == $nextGlyphId)
{
$rangeEnd = $charCode;
$nextGlyphId++;
$nextCharCode++ ;
}
else
{
if($glyphRangeS tart)
{
$cidRangeEntrie s[] = sprintf('<%02x> <%02x> %d', $rangeStart, $rangeEnd,
$glyphRangeStar t);
$glyphRangeStar t = false;
$nextGlyphId = -1;
$nextCharCode = -1;
}
if($glyphId)
{
$rangeStart = $charCode;
$rangeEnd = $charCode;
$glyphRangeStar t = $glyphId;
$nextGlyphId = $glyphId + 1;
$nextCharCode = $charCode + 1;
}
}
}
if($glyphRangeS tart)
{
$cidRangeEntrie s[] = sprintf('<%02x> <%02x> %d', $rangeStart, $rangeEnd,
$glyphRangeStar t);
}
for($j = 0, $j_bound = count($cidRange Entries); $j < $j_bound; $j += 100)
{
$c = min(100, $j_bound - $j);
$this->Write("$c begincidrange\n ");
$this->Write(implode( "\n", array_slice($ci dRangeEntries, $j, $c)));
$this->Write("\nendci drange\n");
}
$this->Write(<<<CMAP_ TRAILER
endcmap
CMapName
currentdict
/CMap
defineresource
pop
end
end
CMAP_TRAILER
);
}
}

class PDFToUnicodeCMa p extends PDFFlateStream {

function PDFToUnicodeCMA P($charSet, $char_to_unicod e_map) {
$this->PDFFlateStream ();
$this->Write(<<<CMAP_ HEADER
/CIDInit /ProcSet findresource
begin
12 dict
begin
begincmap
/CIDSystemInfo <</Registry ($charSet) /Ordering ($charSet) /Supplement 0 >>
def
/CMapName /$charSet def 1
/CMapType 1 def
CMAP_HEADER
);
$this->Write("1 begincodespacer ange\n<00> <FF>\nendcodesp acerange\n");
$unicodeRangeSt art = false;
$nextUnicode = -1;
$nextCharCode = -1;
$cidRangeEntrie s = array();
foreach($char_t o_unicode_map as $charCode => $unicode)
{
if($charCode == $nextCharCode && $unicode == $nextUnicode)
{
$rangeEnd = $charCode;
$nextUnicode++;
$nextCharCode++ ;
}
else
{
if($unicodeRang eStart)
{
$cidRangeEntrie s[] = sprintf('<%02x> <%02x> <%04x>', $rangeStart,
$rangeEnd, $unicodeRangeSt art);
$unicodeRangeSt art = false;
$nextUnicode = -1;
$nextCharCode = -1;
}
if($unicode)
{
$rangeStart = $charCode;
$rangeEnd = $charCode;
$unicodeRangeSt art = $unicode;
$nextUnicode = $unicode + 1;
$nextCharCode = $charCode + 1;
}
}
}
if($unicodeRang eStart)
{
$cidRangeEntrie s[] = sprintf('<%02x> <%02x> <%04x>', $rangeStart,
$rangeEnd, $unicodeRangeSt art);
}
for($j = 0, $j_bound = count($cidRange Entries); $j < $j_bound; $j += 100)
{
$c = min(100, $j_bound - $j);
$this->Write("$c beginbfrange\n" );
$this->Write(implode( "\n", array_slice($ci dRangeEntries, $j, $c)));
$this->Write("\nendbf range\n");
}
$this->Write(<<<CMAP_ TRAILER
endcmap
CMapName
currentdict
/CMap
defineresource
pop
end
end
CMAP_TRAILER
);
}
}

class PDFType1Font extends PDFFont {
var $encoding;
var $toUnicode;
var $widthArray;
var $descriptor;
var $stream;

function PDFType1Font($n ame, $charSet = 'WinAnsiEncodin g', $builtIn =
false) {
global $Type1Directory ;
if(!$Type1Direc tory)
{
die("PDFType1Fo nt: global variable \$Type1Director y not set");
}
$this->PDFFont();
if($charSet != 'WinAnsiEncodin g') $char_to_unicod e_map =
GetCharSetUnico deMap($charSet) ;
$char_to_name_m ap = GetCharSetNameM ap($charSet);
$name_to_char_m ap = GetInverseMap($ char_to_name_ma p);
$afm_file = fopen("$Type1Di rectory/$name.afm", "rt");
$properties = array();
$widths = array();
$rExtents = array();
$kerning_pairs = array();
$name_to_index_ map = array();

while($line = fgets($afm_file , 256))
{
if($in_char_met rics)
{
if(strstr($line , 'EndCharMetrics '))
{
$in_char_metric s = False;
}
else
{
$metric_items = explode(';', $line);
$char_name = substr($metric_ items[2], 3, -1);
if($char_name)
{
$bbox = explode(' ', substr($metric_ items[3], 3, -1));
$width = (int) substr($metric_ items[1], 4, -1);
$rExtent = $bbox[2] - $width;
if($a = $name_to_char_m ap[$char_name])
{
foreach($a as $charCode)
{
$widths[$charCode] = $width;
$rExtents[$charCode] = $rExtent;
$c = chr($charCode);
}
}
}
}
}
else if($in_kern_pai rs)
{
if(strstr($line , 'EndKernPairs') )
{
$in_kern_pairs = False;
}
else
{
$kern_pair_item s = explode(' ', $line);
$aLeft = $name_to_char_m ap[$kern_pair_item s[1]];
$aRight = $name_to_char_m ap[$kern_pair_item s[2]];
$offset = (int) $kern_pair_item s[3];
if($aLeft && $aRight)
{
foreach($aLeft as $charCodeLeft)
{
if(!$kerning_pa irs[$charCodeLeft]) $kerning_pairs[$charCodeLeft] =
array();
foreach($aRight as $charCodeRight)
{
$kerning_pairs[$charCodeLeft][$charCodeRight] = $offset;
}
}
}
}
}
else
{
$i = strpos($line, ' ');
$key = substr($line, 0, $i);
if($key == 'StartCharMetri cs')
{
$in_char_metric s = True;
}
else if($key == 'StartKernPairs ')
{
$in_kern_pairs = True;
}
else if($key)
{
$value = trim(substr($li ne, $i));
$properties[$key] = $value;
}
}
}
fclose($afm_fil e);
$this->Assign('Subtyp e', Name('Type1'));
if($charSet != 'WinAnsiEncodin g')
{
$this->encoding = new PDFDictionary(' Encoding');
$differences = new PDFArray();
$nextCharCode = -1;
foreach($char_t o_name_map as $charCode => $charName)
{
if($nextCharCod e != $charCode)
{
$differences->Add($charCode) ;
$nextCharCode = $charCode;
}
$differences->AddObj(Name($c harName));
$nextCharCode++ ;
}
$this->encoding->AssignObj('Dif ferences', $differences);
$this->AssignObj('Enc oding', $this->encoding);
$this->toUnicode = new PDFToUnicodeCma p($charSet, $char_to_unicod e_map);
$this->AssignObj('ToU nicode', $this->toUnicode);
}
else
{
$this->Assign('Encodi ng', Name('WinAnsiEn coding'));
}
if(!$builtIn)
{
$this->widthArray = new PDFArray();
$charCodes = array_keys($wid ths);
sort($charCodes );
$firstChar = $charCodes[0];
$lastChar = $charCodes[count($charCode s) - 1];
for($i = $firstChar; $i <= $lastChar; $i++)
{
$this->widthArray->Add((int) $widths[$i]);
}
$this->Assign('FirstC har', $firstChar);
$this->Assign('LastCh ar', $lastChar);
$this->AssignObj('Wid ths', $this->widthArray);

$this->descriptor = new PDFDictionary(' FontDescriptor' );
$this->descriptor->Assign('FontNa me', Name($propertie s['FontName']));
$bbox = explode(' ', $properties['FontBBox']);
$this->descriptor->Assign('FontBB ox', new PDFRect($bbox[0], $bbox[1],
$bbox[2], $bbox[3]));
$this->descriptor->Assign('Italic Angle', (float)
$properties['italicAngle']);
$this->descriptor->Assign('Ascent ', (int) $properties['Ascender']);
$this->descriptor->Assign('Descen t', (int) $properties['Descender']);
$this->descriptor->Assign('CapHei ght', (int) $properties['CapHeight']);
$this->descriptor->Assign('XHeigh t', (int) $properties['XHeight']);
$this->descriptor->Assign('StemH' , (int) $properties['StdHW']);
$this->descriptor->Assign('StemV' , (int) $properties['StdVW']);
$flags = (($properties['IsFixedPitch'] == 'true') ? 0x0001 : 0x0000) |
($properties['CharacterSet'] == 'Special') ? 0x0004 : 0x0020;
if($properties['italicAngle'] > 0) $flags |= 0x0040;
$this->descriptor->Assign('Flags' , $flags);
$this->stream = new PDFType1FileStr eam("$Type1Dire ctory/$name.pfb");
$this->descriptor->AssignObj('Fon tFile', $this->stream);
$this->AssignObj('Fon tDescriptor', $this->descriptor);
}
$this->Assign('BaseFo nt', Name($propertie s['FontName']));
$this->widths = $widths;
$this->rExtents = $rExtents;
$this->kerning_pair s = $kerning_pairs;
}
}

class PDFBuiltInFont extends PDFType1Font {

function PDFBuiltInFont( $name, $charSet = 'WinAnsiEncodin g') {
$this->PDFType1Font($ name, $charSet, true);
}
}

function UnpackTag($t) {
return chr($t >> 24) . chr(($t >> 16) & 0xFF) . chr(($t >> 8) & 0xFF) .
chr($t & 0xFF);
}

function CollapseUCS16St ring($s) {
$result = '';
for($i = 1, $i_bound = strlen($s); $i < $i_bound; $i += 2)
{
$result .= $s[$i];
}
return $result;
}

function FWord(&$d) {
if($d & 0x8000)
{
$d = - ($d ^ 0xFFFF);
}
}

function Fixed(&$d) {
$d = ($d / 65536);
}

define('SIZEOF_ BYTE', 1);
define('SIZEOF_ CHAR', 1);
define('SIZEOF_ USHORT', 2);
define('SIZEOF_ SHORT', 2);
define('SIZEOF_ ULONG', 4);
define('SIZEOF_ LONG', 4);
define('SIZEOF_ FIXED', 4);

class PDFTrueTypeFont extends PDFFont {
var $descriptor;
var $CIDFont;
var $encoding;
var $toUnicode;
var $stream;

function PDFTrueTypeFont ($filename, $charSet = 'WinAnsiEncodin g') {
global $TTFDirectory;
if(!$TTFDirecto ry)
{
die("PDFType1Fo nt: global variable \$TTFDirectory not set");
}
$this->PDFFont();
$char_to_unicod e_map = GetCharSetUnico deMap($charSet) ;
$file = fopen("$TTFDire ctory/$filename", "rb");
$offsetTableBin = fread($file, SIZEOF_FIXED + SIZEOF_USHORT * 4);
$offsetTable =
unpack("Nversio n/nnumTables/nsearchRange/nentrySelector/nrangeShift",
$offsetTableBin );
$tableDir = Array();
for($i = 0, $i_bound = $offsetTable['numTables']; $i < $i_bound; $i++)
{
$tableDirEntryB in = fread($file, SIZEOF_ULONG * 4);
$tableDirEntry = unpack("Ntag/NcheckSum/Noffset/Nlength",
$tableDirEntryB in);
$tag = UnpackTag($tabl eDirEntry['tag']);
$tableDir[$tag] = $tableDirEntry;
}
$headEntry = $tableDir['head'];
fseek($file, $headEntry['offset']);
$headBin = fread($file, $headEntry['length']);
$head =
unpack("NtableV ersion/NfontRevision/NcheckSumAdjust ment/NmagicNumber/nflags/
nunitsPerEm/a8created/a8modified/nxMin/nyMin/nxMax/nyMax/nmacStyle/nlowestRe
cPPEM/nfontDirectionH int/nindexToLocForm at/nglyphDataForma t", $headBin);
FWord($head['xMin']);
FWord($head['yMin']);
FWord($head['xMax']);
FWord($head['yMax']);
$pdf_unit_ratio = 1000 / $head['unitsPerEm'];

$postEntry = $tableDir['post'];
fseek($file, $postEntry['offset']);
$postBin = fread($file, $postEntry['length']);
$post =
unpack("Nformat Type/NitalicAngle/nunderlinePosit ion/nunderlineThick ness/NisF
ixedPitch/NminMemType42/NmaxMemType42/NminMemType1/NmaxMemType1", $postBin);
Fixed($post['formatType']);
Fixed($post['italicAngle']);
FWord($post['underlinePosit ion']);

$hheaEntry = $tableDir['hhea'];
fseek($file, $hheaEntry['offset']);
$hheaBin = fread($file, $hheaEntry['length']);
$hhea =
unpack("NtableV ersion/nascender/ndescender/nlineGap/nadvanceWidthMa x/nminLef
tSideBearing/nminRightSideBe aring/nxMaxExtent/ncaretSlopeRise/ncareSlopRun/n
5reserved/nmetricDataForm at/nnumMetrics", $hheaBin);
FWord($hhea['ascender']);
FWord($hhea['descender']);
FWord($hhea['lineGap']);
FWord($hhea['minLeftSideBea ring']);
FWord($hhea['minRightSideBe aring']);
FWord($hhea['xMaxExtent']);

$os2Entry = $tableDir['OS/2'];
fseek($file, $os2Entry['offset']);
$os2Bin = fread($file, $os2Entry['length']);
$os2 =
unpack("nversio n/navgCharWidth/nweightClass/nwidthClass/nfsType/nsubscriptXS
ize/nsubscriptYSize/nsubscriptXOffs et/nsubscriptYOffs et/nsuperscriptXSi ze/ns
uperscriptYSize/nsuperscriptXOf fset/nsuperscriptYOf fset/nstrikeoutSize/nstri
keoutPosition/nfamilyClass/a10panose/N4unicodeRange/a4vendId/nselection/nfir
stCharIndex/nlastCharIndex/ntypoAscender/ntypoDescender/ntypeLineGap/nwinAsc
ent/nwinDescent/NcodePageRange1/NcodePageRange2 ", $os2Bin);
FWord($os2['typoDescender']);

if($pcltEntry = $tableDir['PCLT'])
{
fseek($file, $pcltEntry['offset']);
$pcltBin = fread($file, $pcltEntry['length']);
$pclt =
unpack("Nversio n/NfontNumber/npitch/nxHeight/nstyle/ntypeFamily/ncapHeight/n
symbolSet/a16typeFace/a8characterComp lement/a6filename/CstrokeWeight/CwidthT
ype/CserifStyle/Creserved", $pcltBin);
}

$nameEntry = $tableDir['name'];
fseek($file, $nameEntry['offset']);
$nameBin = fread($file, $nameEntry['length']);
$name = unpack("nformat/nnumRecords/noffset", $nameBin);
$nameRecordSize = SIZEOF_USHORT * 6;
for($i = 0, $i_bound = $name['numRecords'], $offset = SIZEOF_USHORT * 3; $i
< $i_bound; $i++, $offset += $nameRecordSize )
{
$nameRecordBin = substr($nameBin , $offset, $nameRecordSize );
$nameRecord =
unpack("nplatfo rmId/nencodingId/nlangId/nnameId/nlength/noffset",
$nameRecordBin) ;
if($nameRecord['nameId'] == 6)
{
fseek($file, $nameEntry['offset'] + $name['offset'] +
$nameRecord['offset']);
$postscriptName = CollapseUCS16St ring(fread($fil e,
$nameRecord['length']));
break;
}
}

$cmapEntry = $tableDir['cmap'];
fseek($file, $cmapEntry['offset']);
$cmapBin = fread($file, $cmapEntry['length']);
$cmap = unpack("ntableV ersion/nnumEncodings", $cmapBin);
$encodingEntryS ize = (SIZEOF_USHORT * 2) + SIZEOF_ULONG;
for($i = 0, $i_bound = $cmap['numEncodings'], $offset = SIZEOF_USHORT * 2;
$i < $i_bound; $i++, $offset += $encodingEntryS ize)
{
$encodingEntryB in = substr($cmapBin , $offset, $encodingEntryS ize);
$encodingEntry = unpack("nplatfo rmId/nencodingId/Noffset",
$encodingEntryB in);
if($encodingEnt ry['platformId'] == 3 && $encodingEntry['encodingId'] == 1)
{
$unicodeMapBin = substr($cmapBin , $encodingEntry['offset'], SIZEOF_USHORT
* 7);
$unicodeMap =
unpack("nformat/nlength/nversion/nsegCountX2/nsearchRange/nentrySelector/nra
ngeShift", $unicodeMapBin) ;
$segCount = $unicodeMap['segCountX2'] / 2;
$offset = $encodingEntry['offset'] + SIZEOF_USHORT * 7;
$endCodesBin = substr($cmapBin , $offset, SIZEOF_USHORT * $segCount);
$endCodes = unpack("n$segCo unt", $endCodesBin);
$offset += SIZEOF_USHORT * $segCount + SIZEOF_USHORT;
$startCodesBin = substr($cmapBin , $offset, SIZEOF_USHORT * $segCount);
$startCodes = unpack("n$segCo unt", $startCodesBin) ;
$offset += SIZEOF_USHORT * $segCount;
$idDeltasBin = substr($cmapBin , $offset, SIZEOF_USHORT * $segCount);
$idDeltas = unpack("n$segCo unt", $idDeltasBin);
array_walk($idD eltas, 'FWord');
$offset += SIZEOF_USHORT * $segCount;
$rangeOffsetsBi n = substr($cmapBin , $offset, SIZEOF_USHORT * $segCount);
$rangeOffsets = unpack("n$segCo unt", $rangeOffsetsBi n);
$offset += SIZEOF_USHORT * $segCount;
$glyphIdCount = ($unicodeMap['length'] - SIZEOF_USHORT * (($segCount * 4
+ 8))) / SIZEOF_USHORT;
$glyphIdsBin = substr($cmapBin , $offset, SIZEOF_USHORT * $glyphIdCount);
$glyphIds = unpack("n$glyph IdCount", $glyphIdsBin);
$char_to_glyph_ map = array();
$glyph_to_char_ map = array();
$maxGlyphId = 0;
foreach($char_t o_unicode_map as $charCode => $unicode)
{
for($j = 1; $j < $segCount; $j++)
{
if($unicode <= $endCodes[$j])
{
if($unicode >= $startCodes[$j])
{
if($rangeOffset s[$j] == 0)
{
$glyphId = $unicode + $idDeltas[$j] - 1;
}
else
{
$offset = ($rangeOffsets[$j] / 2) - ($segCount - $j) + ($unicode -
$startCodes[$j]);
$glyphId = $glyphIds[$offset];
}
$char_to_glyph_ map[$charCode] = $glyphId;
// need inverse map for mapping kerning info
if(!$glyph_to_c har_map[$glyphId]) $glyph_to_char_ map[$glyphId] =
array();
$glyph_to_char_ map[$glyphId][] = $charCode;
$maxGlyphId = max($maxGlyphId , $glyphId);
}
else
{
break;
}
}
}
}
break;
}
}

$widths = array();
$gWidths = array();
$hmtxEntry = $tableDir['hmtx'];
fseek($file, $hmtxEntry['offset']);
$hmtxBin = fread($file, $hmtxEntry['length']);
foreach($char_t o_glyph_map as $charCode => $glyphId)
{
$offset = $glyphId * SIZEOF_USHORT * 2;
$metricBin = substr($hmtxBin , $offset, SIZEOF_USHORT * 2);
$metric = unpack("nadvanc eWidth/nlsb", $metricBin);
$width = round($metric['advanceWidth'] * $pdf_unit_ratio );
$widths[$charCode] = $width;
$gWidths[$glyphId] = $width;
}

if($kernEntry = $tableDir['kern'])
{
$kerning_pairs = array();
fseek($file, $kernEntry['offset']);
$kernBin = fread($file, $kernEntry['length']);
$kern = unpack("ntableV ersion/nnumSubTables", $cmapBin);
for($i = 0, $i_bound = $kern['numSubTables'], $offset = SIZEOF_USHORT * 2;
$i < $i_bound; $i++)
{
$kerningEntryBi n = substr($kernBin , $offset, SIZEOF_USHORT * 3);
$kerningEntry = unpack("nversio n/nlength/ncoverage", $kerningEntryBi n);
$format = $kerningEntry['coverage'] >> 8;
$horizontal = ($kerningEntry['coverage'] & 0x0001) ? true : false;
if($horizontal && $format == 0)
{
$kerningSubTabl eBin = substr($kernBin , $offset + SIZEOF_USHORT * 3,
SIZEOF_USHORT * 4);
$kerningSubTabl e =
unpack("nnumPai rs/nsearchRange/nentrySelector/nrangeShift",
$kerningSubTabl eBin);
$kerningPairSiz e = SIZEOF_USHORT * 3;
for($j = 0, $j_bound = $kerningSubTabl e['numPairs'], $offset = $offset +
SIZEOF_USHORT * 4; $j < $j_bound; $j++, $offset += $kerningPairSiz e)
{
$kerningPairBin = substr($kernBin , $offset, $kerningPairSiz e);
$kerningPair = unpack("nleft/nright/nvalue", $kerningPairBin );
FWord($kerningP air['value']);
$glyphIdLeft = $kerningPair['left'];
$glyphIdRight = $kerningPair['right'];
$aLeft = $glyph_to_char_ map[$glyphIdLeft];
$aRight = $glyph_to_char_ map[$glyphIdRight];
if($aLeft && $aRight)
{
$kerningOffset = $kerningPair['value'] * $pdf_unit_ratio ;
foreach($aLeft as $charCodeLeft)
{
if(!$kerning_pa irs[$charCodeLeft]) $kerning_pairs[$charCodeLeft] =
array();
foreach($aRight as $charCodeRight)
{
$kerning_pairs[$charCodeLeft][$charCodeRight] = $kerningOffset;
}
}
if($maxGlyphId < $glyphIdLeft && $maxGlyphId < $glyphIdRight) {
break; }
}
}
break;
}
$offset += $kerningEntry['length'];
}
}

$w = new PDFArray();
$rangeWidths = false;
$nextCharCode = -1;
foreach($gWidth s as $glyphId => $width)
{
if($glyphId == $nextGlyphId)
{
$rangeWidths[] = $width;
$nextGlyphId++;
}
else
{
if($rangeWidths )
{
$w->Add($rangeStar t);
$w->Add($rangeWidt hs);
}
$rangeStart = $glyphId;
$rangeWidths = array($width);
$nextGlyphId = $glyphId + 1;
}
}
$w->Add($rangeStar t);
$w->Add($rangeWidt hs);

$this->descriptor = new PDFDictionary(' FontDescriptor' );
$this->stream = new PDFTrueTypeFile Stream("$TTFDir ectory/$filename");
$this->encoding = new PDFEncodingCMap ($charSet, $char_to_glyph_ map);
$this->toUnicode = new PDFToUnicodeCMa p($charSet, $char_to_unicod e_map);
$this->Assign('Subtyp e', Name('Type0'));
$this->AssignObj('Enc oding', $this->encoding);
$this->AssignObj('ToU nicode', $this->toUnicode);
$this->CIDFont = new PDFDictionary(' Font');
$this->CIDFont->Assign('Subtyp e', Name('CIDFontTy pe2'));
$this->CIDFont->AssignObj('Fon tDescriptor', $this->descriptor);
$this->CIDFont->AssignObj('CID SystemInfo', $this->encoding->CIDSystemInfo) ;
$this->CIDFont->AssignObj('W ', $w);
$this->descriptor->AssignObj('Fon tFile2', $this->stream);
$descendantFont s = new PDFArray();
$descendantFont s->AddObj($this->CIDFont);
$this->AssignObj('Des cendantFonts', $descendantFont s);

$this->Assign('BaseFo nt', Name($postscrip tName));
$this->CIDFont->Assign('BaseFo nt', Name($postscrip tName));
$this->descriptor->Assign('FontNa me', Name($postscrip tName));
$left = round($head['xMin'] * $pdf_unit_ratio );
$bottom = round($head['yMin'] * $pdf_unit_ratio );
$right = round($head['xMax'] * $pdf_unit_ratio );
$top = round($head['yMax'] * $pdf_unit_ratio );
$this->descriptor->Assign('FontBB ox', new PDFRect($left, $bottom, $right,
$top));
$this->descriptor->Assign('Italic Angle', $post['italicAngle']);
$this->descriptor->Assign('Ascent ', round($os2['typoAscender'] *
$pdf_unit_ratio ));
$this->descriptor->Assign('Descen t', round($os2['typoDescender'] *
$pdf_unit_ratio ));
$this->descriptor->Assign('AvgWid th', round($os2['avgCharWidth'] *
$pdf_unit_ratio ));
$this->descriptor->Assign('Leadin g', round($os2['typeLineGap'] *
$pdf_unit_ratio ));
if($pclt)
{
$this->descriptor->Assign('CapHei ght', round($pclt['capHeight'] *
$pdf_unit_ratio ));
$this->descriptor->Assign('XHeigh t', round($pclt['xHeight'] *
$pdf_unit_ratio ));
}
else
{
$this->descriptor->Assign('CapHei ght', round($os2['typoAscender']*
$pdf_unit_ratio ));
}
$this->descriptor->Assign('StemV' , 45);
$flags = $post['isFixedPitch'] | ($os2['codePageRange1 '] & 0x8000000) ?
0x0004 : 0x0020;
if($os2['panose1'] == 3) $flags |= 0x0008;
if($os2['panose2'] != 11 && $os2['panose2'] != 12 && $os2['panose2'] != 13)
$flags |= 0x0002;
if($post['italicAngle']) $flags |= 0x0040;
$this->descriptor->Assign('Flags' , $flags);
$this->widths = $widths;
$this->kerning_pair s = $kerning_pairs;
}
}

class PDFPageLabels extends PDFDictionary {
var $nums;

function PDFPageLabels() {
$this->PDFDictionary( 'PageLabels');
$this->nums = new PDFArray();
$this->AssignObj('Num s', $this->nums);
}

function Add($start_inde x, &$label) {
$this->nums->Add($start_ind ex);
$this->nums->AddObj($label) ;
}
}

class PDFOutlines extends PDFDictionary {

function PDFOutlines() {
$this->PDFDictionary( 'Outlines');
$this->Assign('Count' , 0);
}

function IncrementCount( ) {
$count =& $this->Object('Count' );
$count->Add(1);
}
}

class Rect {
var $left;
var $right;
var $top;
var $bottom;
var $width;
var $height;

function Rect($left, $bottom, $right, $top) {
$this->left = $left;
$this->bottom = $bottom;
$this->right = $right;
$this->top = $top;
$this->width = $right - $left;
$this->height = $top - $bottom;
}

function Intersect($rect ) {
return (min($this->top, $rect->top) > max($this->bottom, $rect->bottom))
&& (min($this->right, $rect->right) > max($this->left, $rect->left));
}
}

class PDFSpacing {
var $left;
var $right;
var $top;
var $bottom;

function PDFSpacing($lef t, $bottom, $right, $top) {
$this->left = $left;
$this->bottom = $bottom;
$this->right = $right;
$this->top = $top;
}
}

class PDFPadding extends PDFSpacing {
function PDFPadding($lef t, $bottom, $right, $top) {
$this->PDFSpacing($le ft, $bottom, $right, $top);
}
}

class PDFBorder {
var $left;
var $right;
var $top;
var $bottom;
var $color;

function PDFBorder($left , $bottom, $right, $top, $color) {
$this->left = $left;
$this->bottom = $bottom;
$this->right = $right;
$this->top = $top;
$this->color = $color;
}

function Simple() {
return ($this->left === $this->right) && ($this->left === $this->top) &&
($this->left === $this->bottom);
}
}

class PDFRegion {
var $rects;
var $bounding_rects ;
var $padding;
var $spacing;
var $minWidth;
var $alloc_index;
var $alloc_top;
var $prev_left;
var $prev_right;

function PDFRegion($rect s, $spacing = 0, $padding = 0, $minWidth = 144) {
$this->rects = $rects;
$this->padding = is_object($padd ing) ? $padding : new PDFPadding($pad ding,
$padding, $padding, $padding);
$this->spacing = is_object($spac ing) ? $spacing : new PDFSpacing($spa cing,
$spacing, $spacing, $spacing);
$this->minWidth = $minWidth;
$this->alloc_index = 0;
$this->alloc_top = -1;
}

function AllocLineRect($ lineHeight) {
while($this->alloc_index < count($this->rects))
{
$a = $this->rects[$this->alloc_index];
$top = ($this->alloc_top != -1) ? $this->alloc_top : $a->top -
$this->padding->top;
$bottom = $top - $lineHeight;
$this->alloc_top = $bottom;
if($bottom >= $a->bottom + $this->padding->bottom)
{
if($top <= $a->top - $this->padding->top)
{
return new Rect($a->left + $this->padding->left, $bottom, $a->right -
$this->padding->right, $top);
}
else
{
return new Rect($this->prev_left + $this->padding->left, $bottom,
$this->prev_right - $this->padding->right, $top);
}
}
else
{
$b = $this->rects[$this->alloc_index + 1];
if($b->top == $a->bottom)
{
$this->alloc_index+ +;
if($bottom >= $b->bottom + $this->padding->bottom)
{
$this->prev_left = max($b->left, $a->left);
$this->prev_right = min($b->right, $a->right);
return new Rect($this->prev_left + $this->padding->left, $bottom,
$this->prev_right - $this->padding->right, $top);
}
}
else
{
// move to the next, disconnected rect
$this->alloc_index+ +;
$this->alloc_top = -1;
}
}
}
return null;
}

function RemoveRect($rec t) {
$newRects = array();
foreach($this->rects as $a)
{
if($a->Intersect($rec t))
{
$b1 = $b2 = $b3 = $b4 = false;
$top = $a->top;
$ctop = $rect->top + $this->spacing->top;
if($top > $ctop)
{
$b1 = new Rect($a->left, $ctop, $a->right, $top);
$top = $ctop;
}
$bottom = $a->bottom;
$cbottom = $rect->bottom - $this->spacing->bottom;
if($bottom < $cbottom)
{
$b4 = new Rect($a->left, $bottom, $a->right, $cbottom);
$bottom = $cbottom;
}
$left = $a->left;
$cleft = $rect->left - $this->spacing->left;
if($left < $cleft)
{
$b2 = new Rect($left, $bottom, $cleft, $top);
if($b2->width < $this->minWidth) $b2 = false;
}
$right = $a->right;
$cright = $rect->right + $this->spacing->right;
if($right > $cright)
{
$b3 = new Rect($cright, $bottom, $right, $top);
if($b3->width < $this->minWidth) $b3 = false;
}
if($b1) $newRects[] = $b1;
if($b2 || $b3)
{
if(!$b3)
{
$newRects[] = $b2;
}
else if(!$b2)
{
$newRects[] = $b3;
}
else
{
$newRects[] = ($b2->width >= $b3->width) ? $b2 : $b3;
}
}
if($b4) $newRects[] = $b4;
}
else
{
$newRects[] = $a;
}
}
$this->rects = $newRects;
}

function RemoveRects($re cts) {
foreach($rects as $rect)
{
$this->RemoveRect($re ct);
}
}

function GetTop() {
return ($this->rects) ? $this->rects[0]->top : 0;
}
}

class PDFRectangularR egion extends PDFRegion {

function PDFRectangularR egion($left, $bottom, $right, $top, $spacing = 0,
$padding = 0, $minWidth = 144) {
$this->PDFRegion(arra y(new Rect($left, $bottom, $right, $top)), $spacing,
$padding, $minWidth);
}
}

class PDFMultiColumnR egion extends PDFRegion {

function PDFMultiColumnR egion($left, $bottom, $right, $top, $col, $gutter =
18, $spacing = 0, $padding = 0, $minWidth = -1) {
if(is_scalar($p adding)) $padding = new PDFPadding($pad ding, $padding,
$padding, $padding);
$paddedWidth = $padding->left + $padding->right;
$colWidth = (int) round((($right - $left) - $paddedWidth - ($gutter *
($col - 1))) / $col);
$rects = array();
for($i = 0, $offset = 0; $i < $col; $i++)
{
$rects[] = new Rect($left + $offset, $bottom, $left + $offset + $colWidth
+ $paddedWidth, $top);
$offset += $colWidth + $gutter;
}
$this->PDFRegion($rec ts, $spacing, $padding, ($minWidth >= 0) ? $minWidth :
(int) $colWidth / 2);
}
}

function Bound($n, $min = 0, $max = 1) {
if($n > $max) return 1;
else if($n < $min) return 0;
return $n;
}

class PDFRGBChromaKey extends PDFArray {

function PDFRGBChromaKey ($r, $g, $b, $delta = 0.01) {
$this->PDFArray();
$this->Add(round(Boun d($r - $delta) * 255));
$this->Add(round(Boun d($r + $delta) * 255));
$this->Add(round(Boun d($g - $delta) * 255));
$this->Add(round(Boun d($g + $delta) * 255));
$this->Add(round(Boun d($g - $delta) * 255));
$this->Add(round(Boun d($g + $delta) * 255));
}
}

class PDFGrayChromaKe y extends PDFArray {

function PDFGrayChromaKe y($grayLevel, $delta = 0.01) {
$this->PDFArray();
$this->Add(round(Boun d($grayLevel - $delta) * 255));
$this->Add(round(Boun d($grayLevel + $delta) * 255));
}

function ToRGB() {
$this->values[2] = $this->values[0];
$this->values[3] = $this->values[1];
$this->values[4] = $this->values[0];
$this->values[5] = $this->values[1];
}
}

define('UPPER_L EFT', 0);
define('UPPER_R IGHT', 1);
define('LOWER_L EFT', 2);
define('LOWER_R IGHT', 3);
define('CENTER' , 4);
define('CENTER_ LEFT', 5);
define('CENTER_ RIGHT', 6);

$image_number = 0;

class PDFJPEGImageStr eam extends PDFFileStream {
var $ref_name;
var $width;
var $height;
var $is_color;

function PDFJPEGImageStr eam($filepath, $chromaKey = false) {
global $image_number, $imageDirectory ;
if(basename($fi lepath) == $filepath)
{
$filepath = "$imageDirector y/$filepath";
}
$this->PDFFileStream( $filepath);
$image_number++ ;
$this->ref_name = "Im$image_numbe r";
$this->PDFDictionary( 'XObject');
$this->Assign('Filter ', Name('DCTDecode '));
$this->size = filesize($filep ath);
$img_info = GetImageSize($f ilepath);
$this->width = $img_info[0];
$this->height = $img_info[1];
$this->is_color = ($img_info['channels'] == 3);
$this->Assign('Length ', $this->size);
$this->Assign('Subtyp e', Name('Image'));
$this->Assign('Width' , $this->width);
$this->Assign('Height ', $this->height);
$this->Assign('ColorS pace', Name($this->is_color ? 'DeviceRGB' :
'DeviceGray'));
$this->Assign('BitsPe rComponent', 8);
if($chromaKey)
{
// fix image/chroma-key mismatch
if($this->is_color && get_class($chro maKey) == 'pdfgraychromak ey')
{
$chromaKey->ToRGB();
}
else if(!$this->is_color && get_class($chro maKey) == 'pdfrgbchromake y')
{
// tricky situation: a color chroma-key was defined but the image turns
out to be monochromatic
// set choma-key to white, since that's the likeliest background color
$chromaKey = new PDFGrayChromaKe y(1);
}
$this->Assign('Mask ', $chromaKey);
}
}

function Width() {
return $this->width;
}

function Height() {
return $this->height;
}

function IsColor() {
return $this->is_color;
}

function GetRect($x, $y, $origin = UPPER_LEFT, $dpi = 96) {
$pt_width = round($this->width * 72 / $dpi, 4);
$pt_height = round($this->height * 72 / $dpi, 4);
switch($origin) {
case UPPER_LEFT:
return new Rect($x, $y - $pt_height, $x + $pt_width, $y);
break;
case UPPER_RIGHT:
return new Rect($x - $pt_width , $y - $pt_height, $x, $y);
break;
case LOWER_LEFT:
return new Rect($x, $y, $x + $pt_width, $y + $pt_height);
break;
case LOWER_RIGHT:
return new Rect($x - $pt_width, $y, $x, $y + $pt_height);
break;
case CENTER:
return new Rect($x - $pt_width / 2, $y - $pt_height / 2, $x + $pt_width /
2, $y + $pt_height / 2);
break;
case CENTER_LEFT:
return new Rect($x, $y - $pt_height / 2, $x + $pt_width, $y + $pt_height
/ 2);
break;
case CENTER_RIGHT:
return new Rect($x - $pt_width, $y - $pt_height / 2, $x, $y + $pt_height
/ 2);
break;
}
}
}

class TextStyle {
var $font;
var $size;
var $rise;
var $color;
}

function JoinWords(&$lin e, $obj, $addSpace) {
$last_index = sizeof($line) - 1;
if($last_index >= 0)
{
if($addSpace)
{
for($i = $last_index; $i >= 0; $i--)
{
if(get_class($l ine[$i]) != 'textstyle')
{
$obj->Prepend(' ');
break;
}
}
}
$last_obj = &$line[$last_index];
if(get_class($l ast_obj) == 'textstyle')
{
$line[] = $obj;
}
else
{
if(get_class($l ast_obj) == 'pdfstring' && get_class($obj) ==
'pdfkernedstrin g')
{
$obj->Prepend($last_ obj);
$line[$last_index] = $obj;
}
else
{
$last_obj->Append($obj) ;
}
}
}
else
{
$line[] = $obj;
}
}

define('DELIMIT ER_NOT_ADDED', 0x01);
define('WORD_NO T_ADDED', 0x02);
define('WORD_IS _TOO_LONG', 0x04);

define('JUSTIFY _LEFT', 0);
define('JUSTIFY _RIGHT', 1);
define('JUSTIFY _CENTER', 2);
define('JUSTIFY _FULL', 3);

class PDFTextArea {
var $region;
var $spacing;
var $current_justif y;
var $current_text_s tyle;
var $current_line_s pacing;
var $current_leadin g;
var $current_line;
var $current_line_w idth;
var $current_line_r ight_extent;
var $current_line_w ord_count;
var $current_line_c har_count;
var $current_line_s pace_count;
var $current_line_b ox;
var $current_font;
var $space_width;
var $last_text_styl e;
var $stream;

function PDFTextArea(&$s tream, $region) {
$this->stream = &$stream;
$this->current_line = array();
$this->current_line_w idth = 0;
$this->current_line_w ord_count = 0;
$this->current_justif y = JUSTIFY_FULL;
$this->current_text_s tyle = new TextStyle();
$this->region = $region;
}

function LineFeed() {
if($this->current_line_b ox)
{
$this->WriteCurrentLi ne(True);
unset($this->current_line_b ox);
}
else
{
$this->region->AllocLineRect( $this->current_leadin g);
}
}

function CarrierReturn() {
if($this->current_line_b ox)
{
$this->WriteCurrentLi ne(True);
}
}

function SetJustify($jus tify) {
$this->current_justif y = $justify;
}

function SetLineSpacing( $spacing) {
$this->current_line_s pacing = $spacing;
$this->SetLeading($th is->current_text_s tyle->size + $spacing);
}

function SetLeading($lea ding) {
$this->current_leadin g = $leading;
}

function SetColor($color ) {
if(is_scalar($c olor)) $color = new PDFGray($color) ;
$this->current_text_s tyle->color = $color;
$this->current_line[] = $this->current_text_s tyle;
}

function SetFont($font, $size, $text_rise = 0) {
$this->current_font = $font;
$this->current_text_s tyle->font = $font->ref_name;
$this->current_text_s tyle->size = $size;
$this->current_text_s tyle->rise = $text_rise;
$this->space_width = $font->GetCharWidth (' ', $size);
$this->current_line[] = $this->current_text_s tyle;
$this->SetLeading($si ze + $this->current_line_s pacing);
}

function Indent($width) {
$this->current_line_b ox->width -= $width;
switch($this->current_justif y)
{
case JUSTIFY_FULL:
case JUSTIFY_LEFT:
$this->current_line_b ox->left += $width;
break;
case JUSTIFY_CENTER:
$this->current_line_b ox->right -= (int) floor($width / 2);
$this->current_line_b ox->left += (int) ceil($width / 2);
case JUSTIFY_RIGHT:
$this->current_line_b ox->right -= $width;
}
}

function WriteCurrentLin e($line_break = False) {
$extra_width = $this->current_line_b ox->width - $this->current_line_w idth -
$this->current_line_r ight_extent;
$y = $this->current_line_b ox->bottom;
switch($this->current_justif y)
{
case JUSTIFY_FULL:
$x = $this->current_line_b ox->left;
if(!$line_break )
{
// fill in extra space by expanding both character spacing and word
spacing
$space_count = $this->current_line_s pace_count;
$char_gap_count = $this->current_line_c har_count - 1;
if($char_gap_co unt > 0)
{
$cs_portion = $extra_width / (($space_count * 0.25) + 1); // becomes
smaller with more words
if($space_count > 0)
{
$ws_portion = $extra_width - $cs_portion;
$this->ApplyWordSpaci ng(Round($ws_po rtion / $space_count, 4));
}
$this->ApplyCharSpaci ng(Round($cs_po rtion / $char_gap_count , 4));
}
}
else
{
$this->ApplyWordSpaci ng(0);
$this->ApplyCharSpaci ng(0);
}
break;
case JUSTIFY_LEFT:
$x = $this->current_line_b ox->left;
$this->ApplyWordSpaci ng(0);
break;
case JUSTIFY_RIGHT:
$x = $this->current_line_b ox->left + $extra_width;
$this->ApplyWordSpaci ng(0);
break;
case JUSTIFY_CENTER:
$x = $this->current_line_b ox->left + ($extra_width / 2);
$this->ApplyWordSpaci ng(0);
break;
}
$this->stream->Write("BT\n$ x $y Td\n");
foreach($this->current_line as $obj)
{
if(get_class($o bj) == 'textstyle')
{
$this->ApplyTextStyle ($obj);
}
else
{
$this->WriteText($obj );
}
}
$this->stream->Write("ET\n" );
$this->current_line = array();
$this->current_line_w idth = 0;
$this->current_line_w ord_count = 0;
$this->current_line_c har_count = 0;
$this->current_line_s pace_count = 0;
}

function WriteText($obj) {
if(!$obj->IsEmpty())
{
$this->stream->Write($obj->ToString());
$this->stream->Write(get_clas s($obj) == 'pdfkernedstrin g' ? " TJ\n" : "
Tj\n");
}
}

function ApplyTextStyle( $style) {
if($style != $this->last_text_styl e)
{
if(!$this->last_text_styl e || $this->last_text_styl e->font != $style->font
|| $this->last_text_styl e->size !=
$style->size)
{
if($style->font)
{
$this->stream->Write("/$style->font $style->size Tf\n");
}
}
if((!$this->last_text_styl e && $style->rise > 0) ||
$this->last_text_styl e->rise != $style->rise)
{
$this->stream->Write("$styl e->rise Ts\n");
}
if($style->color && (!$this->last_text_styl e ||
$this->last_text_styl e->color != $style->color))
{
$this->stream->Write($style->color->ToStringNonStr oking());
}
$this->last_text_styl e = $style;
}
}

function ApplyWordSpacin g($spacing) {
if($this->word_spacing != $spacing)
{
$this->stream->Write("$spacin g Tw\n");
$this->word_spacing = $spacing;
}
}

function ApplyCharSpacin g($spacing) {
$this->stream->Write("$spacin g Tc\n");
}

function AddWord($separa tor, $word) {
$flags = DELIMITER_NOT_A DDED | WORD_NOT_ADDED;
$char_count = strlen($word);
list($word_obj, $word_width, $right_extent) =
$this->current_font->Transform($wor d, $this->current_text_s tyle->size);
if($separator == ' ')
{
if($this->current_line_w ord_count > 0)
{
$separator_widt h = $this->space_width;
$separator_char _count = 1;
}
}
else if($separator == "\x09" && $this->current_line_w ord_count == 0)
{
if($this->current_line_b ox || $this->current_line_b ox =
$this->region->AllocLineRect( $this->current_leadin g))
{
$this->Indent($this->space_width * 4);
$flags &= ~DELIMITER_NOT_ ADDED;
}
}
else if($separator)
{
if($separator == "\x09") $separator = "\xA0\xA0\xA0\x A0"; // change tab
into 4 non-breaking spaces
list($separator _obj, $separator_widt h, $separator_righ t_extent) =
$this->current_font->Transform($sep arator, $this->current_text_s tyle->size);
$separator_char _count = strlen($separat or);
}
while($this->current_line_b ox || ($this->current_line_b ox =
$this->region->AllocLineRect( $this->current_leadin g)))
{
if($this->current_line_w idth + $separator_widt h + $word_width <=
$this->current_line_b ox->width)
{
if($separator_o bj)
{
JoinWords($this->current_line , $separator_obj, false);
JoinWords($this->current_line , $word_obj, false);
}
else
{
JoinWords($this->current_line , $word_obj, ($separator_cha r_count > 0));
}
$this->current_line_w idth += $separator_widt h + $word_width;
$this->current_line_w ord_count++;
$this->current_line_c har_count += $separator_char _count + $char_count;
$this->current_line_r ight_extent = $right_extent;
if($separator == ' ') $this->current_line_s pace_count +=
$separator_char _count;
$flags &= ~(DELIMITER_NOT _ADDED | WORD_NOT_ADDED) ;
break;
}
else if($separator_o bj && $this->current_line_w idth + $separator_widt h <=
$this->current_line_b ox->width) // add delimiter to current line if possible
{
JoinWords($this->current_line , $separator_obj, false);
$this->current_line_w idth += $separator_widt h;
$this->current_line_c har_count += $separator_char _count;
$this->current_line_r ight_extent = $separator_righ t_extent;
$this->WriteCurrentLi ne();
unset($this->current_line_b ox);
$separator_obj = null;
$separator_widt h = 0;
$separator_char _count = 0;
$flags &= ~DELIMITER_NOT_ ADDED;
}
else if($this->current_line_w idth > 0)
{
$this->WriteCurrentLi ne();
unset($this->current_line_b ox);
if($separator == ' ')
{
$separator_char _count = 0;
$separator_widt h = 0;
}
}
else
{
$flags |= WORD_IS_TOO_LON G;
break;
}
}
return $flags;
}

function AddText($text, $end_of_paragra ph = true) {
if(!$this->current_font )
{
die("Use PDFTextArea::Se tText() to set current font before adding text");
}
if(is_array($te xt))
{
foreach($text as $index => $line)
{
if($leftover = $this->AddText(chop($ line)))
{
$leftover_lines = array_slice($te xt, $index + 1);
array_unshift($ leftover_lines, $leftover);
return $leftover_lines ;
}
}
return array();
}
else
{
$written_count = 0;
$matches = array();

if(preg_match_a ll('/([\\x20\\x09\\x85 \\x97-]?)([^\\x20\\x09\\x8 5\\x97-]*)/',
$text, $matches, PREG_PATTERN_OR DER))
{
$separators = $matches[1];
$words = $matches[2];
foreach($words as $index => $word)
{
$separator = $separators[$index];
if($separator || $word)
{
$flags = $this->AddWord($separ ator, $word);
if(!($flags & DELIMITER_NOT_A DDED))
{
$written_count += strlen($separat or);
}
if(!($flags & WORD_NOT_ADDED) )
{
$written_count += strlen($word);
}
else
{
return substr($text, $written_count) ;
}
}
}
}
if($end_of_para graph)
{
$this->LineFeed();
}
return '';
}
}

function GetCurrentLineT op() {
return ($this->current_line_b ox) ? $this->current_line_b ox :
$this->region->GetTop();
}
}

define('BUTT_CA P', 0);
define('ROUND_C AP', 1);
define('PROJECT ING_SQUARE_CAP' , 2);

define('MITER_J OIN', 0);
define('ROUND_J OIN', 1);
define('BEVEL_J OIN', 2);

class PDFPage extends PDFDictionary {
var $width;
var $height;
var $stream;
var $occupied_rects ;

function PDFPage($width, $height) {
$this->PDFDictionary( 'Page');
$this->width = $width;
$this->height = $height;
$this->Assign('MediaB ox', new PDFRect(0, 0, $width, $height));
$this->stream = new PDFFlateStream( );
$this->AssignObj('Con tents', $this->stream);
$this->occupied_rec ts = array();
}
function AddOccupiedRect s($rects, $spacing) {
foreach($rects as $rect)
{
$this->occupied_rec ts[] = new Rect($rect->left - $spacing->left,
$rect->bottom - $spacing->bottom, $rect->right + $spacing->right, $rect->top
+ $spacing->top);
}
}

function MoveTo($x, $y) {
$this->stream->Write("$x $y m\n");
}

function LineTo($x, $y) {
$this->stream->Write("$x $y l\n");
}

function ClosePath() {
$this->stream->Write("h\n") ;
}

function SetLineColor($c olor) {
if(is_scalar($c olor)) $color = new PDFGray($color) ;
$this->stream->Write($color->ToStringStroki ng());
}

function SetFillColor($c olor) {
if(is_scalar($c olor)) $color = new PDFGray($color) ;
$this->stream->Write($color->ToStringNonStr oking());
}

function SetLineWidth($w idth) {
$this->stream->Write("$widt h w\n");
}

function SetLineCap($cap ) {
$this->stream->Write("$cap J\n");
}

function SetLineJoin($jo in) {
$this->stream->Write("$join j\n");
}

function DrawPath() {
$this->stream->Write("S\n") ;
}

function FillPath() {
$this->stream->Write("f\n") ;
}

function ClipPath() {
$this->stream->Write("W n\n");
}

function SaveGraphicStat e() {
$this->stream->Write("q\n") ;
}

function RestoreGraphicS tate() {
$this->stream->Write("Q\n") ;
}

function SetPath($region ) {
$moveTo = true;
$endIndex = count($region->rects) - 1;
for($i = 0; $i <= $endIndex; $i++)
{
$rect = $region->rects[$i];
$next_rect = $region->rects[$i + 1];
if($moveTo) // start at top, left corner
{
$this->MoveTo($rect->left, $rect->top);
$startIndex = $i;
$moveTo = false;
}
if($i == $endIndex || $next_rect->top != $rect->bottom)
{
$this->LineTo($rect->left, $rect->bottom);
$this->LineTo($rect->right, $rect->bottom);
for($j = $i; $j >= $startIndex; $j--)
{
$rect = $region->rects[$j];
$prev_rect = $region->rects[$j - 1];
if($j == $startIndex)
{
$this->LineTo($rect->right, $rect->top);
$this->ClosePath();
}
else if($prev_rect->right != $rect->right)
{
$this->LineTo($rect->right, $rect->top);
$this->LineTo($prev_r ect->right, $rect->top);
}
}
$moveTo = true;
}
else if($next_rect->left != $rect->left)
{
$this->LineTo($rect->left, $rect->bottom);
$this->LineTo($next_r ect->left, $rect->bottom);
}
}
}

function FillRegion($reg ion, $color) {
$this->SaveGraphicSta te();
$this->SetFillColor($ color);
$this->SetPath($regio n);
$this->FillPath();
$this->RestoreGraphic State();
}

function DrawBorder($reg ion, $border) {
if(is_scalar($b order)) $border = new PDFBorder($bord er, $border, $border,
$border, BLACK);
$this->SaveGraphicSta te();
$this->SetLineColor($ border->color);
if($border->Simple()) // if all four sides have the same border width
{
$this->SetLineWidth($ border->left);
$this->SetPath($regio n);
$this->DrawPath();
}
else
{
$endIndex = count($region->rects) - 1;
$borderWidth = false;
if($border->left !== false)
{
$borderWidth = $border->left;
$this->SetLineWidth($ borderWidth);
for($i = 0; $i <= $endIndex; $i++)
{
$rect = $region->rects[$i];
$next_rect = $region->rects[$i + 1];
if($i == 0)
{
$this->MoveTo($rect->left, $rect->top);
}
if($i == $endIndex)
{
$this->LineTo($rect->left, $rect->bottom);
}
else if($rect->bottom != $next_rect->top || $rect->left !=
$next_rect->left)
{
$this->LineTo($rect->left, $rect->bottom);
$this->MoveTo($next_r ect->left, $next_rect->top);
}
}
$this->DrawPath();
}
if($border->right !== false)
{
if($border->right !== $borderWidth)
{
$borderWidth = $border->right;
$this->SetLineWidth($ borderWidth);
}
for($i = 0; $i <= $endIndex; $i++)
{
$rect = $region->rects[$i];
$next_rect = $region->rects[$i + 1];
if($i == 0)
{
$this->MoveTo($rect->right, $rect->top);
}
if($i == $endIndex)
{
$this->LineTo($rect->right, $rect->bottom);
}
else if($rect->bottom != $next_rect->top || $rect->right !=
$next_rect->right)
{
$this->LineTo($rect->right, $rect->bottom);
$this->MoveTo($next_r ect->right, $next_rect->top);
}
}
$this->DrawPath();
}
if($border->top !== false)
{
if($border->top !== $borderWidth)
{
$borderWidth = $border->top;
$this->SetLineWidth($ borderWidth);
}
for($i = $endIndex; $i >= 0; $i--)
{
$rect = $region->rects[$i];
$prev_rect = $region->rects[$i - 1];
if($i == 0 || $rect->top != $prev_rect->bottom)
{
$this->MoveTo($rect->left, $rect->top);
$this->LineTo($rect->right, $rect->top);
}
else
{
if($rect->left < $prev_rect->left)
{
$this->MoveTo($rect->left, $rect->top);
$this->LineTo($prev_r ect->left, $rect->top);
}
if($rect->right > $prev_rect->right)
{
$this->MoveTo($rect->right, $rect->top);
$this->LineTo($prev_r ect->right, $rect->top);
}
}
}
$this->DrawPath();
}
if($border->bottom !== false)
{
if($border->bottom !== $borderWidth)
{
$borderWidth = $border->bottom;
$this->SetLineWidth($ borderWidth);
}
for($i = 0; $i <= $endIndex; $i++)
{
$rect = $region->rects[$i];
$next_rect = $region->rects[$i + 1];
if($i == $endIndex || $rect->bottom != $next_rect->top)
{
$this->MoveTo($rect->left, $rect->bottom);
$this->LineTo($rect->right, $rect->bottom);
}
else
{
if($rect->left < $next_rect->left)
{
$this->MoveTo($rect->left, $rect->bottom);
$this->LineTo($next_r ect->left, $rect->bottom);
}
if($rect->right > $next_rect->right)
{
$this->MoveTo($rect->right, $rect->bottom);
$this->LineTo($next_r ect->right, $rect->bottom);
}
}
}
$this->DrawPath();
}
}
$this->RestoreGraphic State();
}

function InsertTextArea( $region, $border = false, $backgroundColo r = false,
$overlay = false) {
if(!$overlay)
{
$region->RemoveRects($t his->occupied_rects );
$this->AddOccupiedRec ts($region->rects, $region->spacing);
}
if($backgroundC olor !== false)
{
$this->FillRegion($re gion, $backgroundColo r);
}
if($border !== false)
{
$this->DrawBorder($re gion, $border);
}
return new PDFTextArea($th is->stream, $region);
}

function InsertImage($im ageSrc, $rect, $spacing = 0, $border = false,
$overlay = false) {
if(!$imageSrc->Registered() )
{
die("Use PDF::AddImageSt ream() to add image to resource table first");
}
$region = new PDFRegion(array ($rect), $spacing, 0, 0);
if(!$overlay)
{
$region->RemoveRects($t his->occupied_rects );
$this->AddOccupiedRec ts($region->rects, $region->spacing);
}
if(is_scalar($s pacing))
{
$spacing = new PDFSpacing($spa cing, $spacing, $spacing, $spacing);
}
$this->SaveGraphicSta te();
$this->SetPath($regio n);
$this->ClipPath();
$this->stream->Write("$rect->width 0 0 $rect->height $rect->left
$rect->bottom cm\n/$imageSrc->ref_name Do\n");
$this->RestoreGraphic State();
if($border !== false)
{
$this->DrawBorder($re gion, $border);
}
}

}

class PDFPages extends PDFDictionary {
var $default_width;
var $default_height ;
var $kids;

function PDFPages() {
$this->PDFDictionary( 'Pages');
$this->kids = new PDFArray();
$this->AssignObj('Kid s', $this->kids);
}

function Add(&$page, $index) {
if($index >= 0)
{
$this->kids->InsertObj($pag e, $index);
}
else
{
$index = $this->kids->AddObj($page );
}
$page->AssignObj('Par ent', $this);
if(!$this->default_widt h || !$this->default_height )
{
$this->default_widt h = $page->width;
$this->default_heig ht = $page->height;
$this->Assign('MediaB ox', new PDFRect(0, 0, $this->default_widt h,
$this->default_height ));
$page->Unassign('Medi aBox');
}
else if($page->width == $this->default_widt h && $page->height ==
$this->default_height )
{
$page->Unassign('Medi aBox');
}
$this->Assign('Count' , $this->kids->Count());
return $index;
}
}

class PDFDocument {
var $file;
var $objects;
var $next_id;
var $current_offset ;
var $pages;
var $page_labels;
var $outlines;
var $fonts;
var $trailer;
var $info;
var $xobjects;
var $prevBookmarks;

function PDFDocument() {
$this->objects = array();
$this->next_id = 1;
$this->current_offs et = 0;
$this->fonts = new PDFDictionary() ;
$this->xobjects = new PDFDictionary() ;
$resources = new PDFDictionary() ;
$resources->Assign('ProcSe t', array(Name('PDF '), Name('Text'),
Name('ImageB')) );
$resources->AssignObj('Fon t', $this->fonts);
$resources->AssignObj('XOb ject', $this->xobjects);
$this->pages = new PDFPages();
$this->pages->AssignObj('Res ources', $resources);
$this->page_labels = new PDFPageLabels() ;
$this->outlines = new PDFOutlines();
$this->info = new PDFDictionary() ;
$this->info->Assign('Creato r', 'pdf_class.php' );
$this->info->Assign('Produc er', 'Chung Leong (ch***********@ hotmail.com)');
$this->info->Assign('Creati onDate', new PDFDate());
$catalog = new PDFDictionary(' Catalog');
$catalog->AssignObj('Pag es', $this->pages);
$catalog->AssignObj('Pag eLabels', $this->page_labels) ;
$catalog->AssignObj('Out lines', $this->outlines);
$this->trailer = new PDFDictionary() ;
$this->trailer->AssignObj('Roo t', $catalog);
$this->trailer->AssignObj('Inf o', $this->info);
$this->RegisterObject ($this->outlines);
$this->RegisterObject ($this->page_labels) ;
$this->RegisterObject ($this->pages);
$this->RegisterObject ($catalog);
$this->RegisterObject ($this->info);
$this->prevBookmark s = array();
}

function SetDocInfo($nam e, $value) {
$this->info->Assign($name , $value);
}

function RegisterObject( &$obj) {
$id = $this->next_id++;
$this->objects[] = &$obj;
$obj->SetId($id);
$child_objs = get_object_vars ($obj);
foreach($child_ objs as $child_name => $child_obj)
{
if(is_subclass_ of($child_obj, 'PDFObj') && !$child_obj->Registered() )
{
$this->RegisterObject ($obj->$child_name) ;
}
}
return $id;
}

function Write($s) {
if($this->file) fputs($this->file, $s);
else echo $s;
$this->current_offs et += strlen($s);
}

function WriteObject(&$o bj) {
if(!$obj->Registered() )
{
$this->RegisterObject ($obj);
}
$obj->SetOffset($thi s->current_offset );
$obj->Output($this );
}

function WritePage(&$pag e) {
$this->WriteObject($p age);
$this->WriteObject($p age->stream);
}

function Open($filename = false) {
if($filename)
{
$this->file = fopen($filename , "wb");
}
$this->Write("%PDF-1.3\n");
$this->Write("%üë++\n ");
}

function AddFont(&$font) {
$this->fonts->AssignObj($fon t->ref_name, $font);
$this->RegisterObject ($font);
}

function AddImageStream( &$stream) {
$this->xobjects->AssignObj($str eam->ref_name, $stream);
$this->RegisterObject ($stream);
}

function AddPage(&$page, $index = -1) {
$index = $this->pages->Add($page, $index);
$this->WritePage($pag e);
return $index;
}

function AddBookmark(&$b ookmark, $depth = 0) {
if($depth == 0)
{
$bookmark->SetParent($thi s->outlines);
}
else
{
if($parent =& $this->prevBookmark s[$depth - 1])
{
$bookmark->SetParent($par ent);
}
else
{
$pDepth = $depth - 1;
die("PDFPage::A ddBookmark: No bookmark exists at parent level
($pDepth)");
}
}
$this->prevBookmark s[$depth] =& $bookmark;
$this->outlines->IncrementCount ();
return $this->RegisterObject ($bookmark);
}

function AddPageLabels($ start_index, &$label) {
return $this->page_labels->Add($start_ind ex, $label);
}

function Close() {
$object_count = sizeof($this->objects);
for($i = 0; $i < $object_count; $i++)
{
$obj =& $this->objects[$i];
if(!$obj->Written())
{
$this->WriteObject($o bj);
}
}
$xref_count = $object_count + 1;
$xref_offset = $this->current_offset ;
$this->Write("xref\n" );
$this->Write("0 $xref_count\n") ;
$this->Write("0000000 000 65535 f\r\n");
for($i = 0; $i < $object_count; $i++)
{
$this->Write(sprintf( "%010d 00000 n\r\n", $this->objects[$i]->offset));
}
$this->Write("trailer \n");
$this->trailer->Assign('Size ', $xref_count);
$this->Write($this->trailer->ToString());
$this->Write("\nstart xref\n$xref_off set\n");
$this->Write("%%EOF\n ");
if($this->file)
{
fclose($this->file);
}
}
}

?>
Jul 17 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
12185
by: Graham J | last post by:
Apologies for the partial post that mysteriously escaped as I was composing. I shall try again. For many years I have been happily and successfully coding tables such that the WIDTH specified in a TD is the complete column width including any CELLPADDING. For example for a 400 pixel wide table with four 100 pixel wide columns and 10 pixel cellpadding... <TABLE WIDTH="400" BORDER="0" CELLSPACING="0" CELLPADDING="10">
25
13334
by: Sune A | last post by:
Hi All! I'm having problems with www.suneworld.com The thing is that I'd like to lock the width of the page, so that it won't adjust dynamically. Any CSS people out there that can help me? Kind regards, Sune Alexandersen
16
12867
by: karlman | last post by:
I am trying to create a web page that shows a calendar schedules. I am attempting to use table cells with fixed widths and different colors to display this. It seems that IE6 doesn't always correctly render the widths exactly as intended. I am using dream weaver and when I copy the HTML code into that it renders perfectly. Is there any known issues with the way IE6 renders table cells with fixed widths?
0
3063
by: javaguy | last post by:
I have a table I hide show/hide through a pair of divs. The show/hide part works fine in both Mozilla and MSIE. When switching between the hide and show versions the Mozilla browser keeps them in small width, about 740 pixels. When switching between show/hide with MSIE the "show" table wants to display about 960 pixels. If I set the outer table to ' style="table-layout: fixed;" ' then MSIE chooses to force the width to 960 pixels.
5
169722
by: Jean Pion | last post by:
Dear readers, Can anyone explain how to set column width of a table in ccs. I use the following style in an external stylesheet: table.tbl { table-layout:fixed; border-top: 5px solid #333; border-collapse: collapse; background: #fff; width: 95%} table.tbl td { border-bottom: 1px dashed #33ccff; padding: 2px 5px; text-overflow:ellipsis; overflow:hidden; white-space:nowrap; }
2
1450
by: Stewart | last post by:
Originally posted in comp.lang.javascript: Newsgroups: comp.lang.javascript From: "Stewart" Date: 23 Aug 2005 02:50:04 -0700 Local: Tues, Aug 23 2005 10:50 am Subject: FireFox, RemoveChild, AppendChild, making width grow? Hi,
7
2353
by: Yongjian | last post by:
Hello, I want to read a text file which contains French charactor, then modify some of the sentence, save it as a new text file. But I found the new text file lost all the French charactors. Anybody can help me? Thanks, Yongjian
1
1408
by: sandipvdhande | last post by:
I have problem in printinh the extended ascii charactors to file in C.Please tell me the solution for this issue .Is there any function to convert the charactor ..or is there any function to change the charactor set in C
4
9387
by: lilOlMe | last post by:
Hi there! I'm developing a "scrollable table". At first I started using CSS. It worked pretty well until I found a bug that happens when placing this table into a tabbing control... So I decided to develop 2 tables...one for the header information and one for the body. I simply placed the body into a <div> with style="overflow:auto". I've set the header table to be 100%...expecting it to span 100% of the parent. This works fine in...
0
7947
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
7880
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8255
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8374
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8010
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8242
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
5739
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
3868
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2389
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.