SetData($data, 0); } function SetData($data) { $this->Data = $data; } function Init() { parent::Init(); $this->SetCSSProperty('display', 'inline'); } function ComputeCSSProperties() { parent::ComputeCSSProperties(); // http://manual.prod.intechnic.lv/css21/text.html#q8 $whitespace = str_replace('-', '', $this->GetCSSProperty('white-space')); // remove "-" to avoid confusion if ($whitespace == 'normal' || $whitespace == 'nowrap' || $whitespace == 'preline') { $this->Data = preg_replace('/[\n]{1}[\t\\r ]{1}|[\t\\r ]{1}[\n]{1}/', "\n", $this->Data); } if ($whitespace == 'pre' || $whitespace == 'prewrap') { $this->Data = preg_replace('/ /', ' ', $this->Data); } if ($whitespace == 'normal' || $whitespace == 'nowrap') { $this->Data = preg_replace('/[\r\n]/', ' ', $this->Data); } if ($whitespace == 'normal' || $whitespace == 'nowrap' || $whitespace == 'preline') { $this->Data = preg_replace('/\t/', ' ', $this->Data); $this->Data = preg_replace('/ [ ]+/', ' ', $this->Data); } $transform = $this->GetCSSProperty('text-transform'); if ($transform == 'uppercase') { $this->Data = strtoupper($this->Data); } if ($transform == 'lowercase') { $this->Data = strtolower($this->Data); } if ($transform == 'capitalize') { $this->Data = ucwords($this->Data); } } function CheckDimensions() { $font_size = $this->GetCSSProperty('font-size'); $this->Helper->PDF->SetFont( $this->GetCSSProperty('font-family'), $font_size, $this->GetCSSProperty('font-weight'), $this->GetCSSProperty('font-style'), $this->GetCSSProperty('font-variant')); $this->Ascent = $this->Helper->PDF->GetAscent(); $this->Descent = -$this->Helper->PDF->GetDescent(); // ((-$font->getDescent() / $units) * $size); $this->Gap = $this->Helper->PDF->GetLineGap(); // (($font->getLineGap() / $units) * $size); // proportionally fit ascent & descent into font-size. Wiered why they are greater... if ($this->Ascent + $this->Descent > $font_size) { $this->Ascent = $this->Ascent/($this->Ascent+$this->Descent)*$font_size; $this->Descent = $this->Descent/($this->Ascent+$this->Descent)*$font_size; } if ($this->Helper->DimensionsMode == kPDFHelper::DM_SKIP) { return ; } if ($this->Node->Name == 'BR') { $this->ContentHeight = $this->Ascent + $this->Descent + $this->Gap; $this->SetCSSProperty('height', $this->ContentHeight); $this->NextLine(''); $this->GetLineBox()->Closed(); return ; } $whitespace = str_replace('-', '', $this->GetCSSProperty('white-space')); // remove "-" to avoid confusion if (!$this->Data) { parent::CheckDimensions(); return; } $this->Wrap2($whitespace); $this->GetLineBox()->Closed(); parent::CheckDimensions(); } function CalcMinMaxContentWidth() { $font_size = $this->GetCSSProperty('font-size'); $this->Helper->PDF->SetFont( $this->GetCSSProperty('font-family'), $font_size, $this->GetCSSProperty('font-weight'), $this->GetCSSProperty('font-style'), $this->GetCSSProperty('font-variant')); $data = $this->Data; $this->MaxContentWidth = ceil($this->Helper->PDF->GetStringWidth($data)); $words = preg_split('/([ \[\]\+\(\)]{1})/u', $data, null, PREG_SPLIT_NO_EMPTY); $min_w = $this->MaxContentWidth; foreach ($words as $word) { $word_w = ceil($this->Helper->PDF->GetStringWidth($word)); if ($word_w < $min_w) { $min_w = $word_w; } } $this->MinContentWidth = $min_w; parent::CalcMinMaxContentWidth(); } function Wrap2($whitespace) { $start = $this->GetLineBox()->CurX; $data = $this->Data; if ($this->Parent->FirstChild === $this && ($whitespace == 'normal' || $whitespace == 'nowrap' || $whitespace == 'preline')) { $data = ltrim($data); } $words = preg_split('/([ \[\]\+\(\)]{1})/u', $data, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); $words_count = count($words); $i = 0; $elem_w = 0; $max_width = $this->GetLineBox()->GetCSSProperty('width'); $line_break = false; while ($i < $words_count) { $word_w = $this->Helper->PDF->GetStringWidth($words[$i]); if ( (floor($max_width - $start - $elem_w - $word_w) < 0) && ($i > 0 || $start > 0) ) { $line_break = true; break; } $elem_w += $word_w; $i++; } // remove space at the end of line // @todo Find a way to detect a space at the end of last line, which is NOT wrapped // otherwise right-aligned blocks will have a space at the end of last line if ( ($i > 0 && $words[$i-1]) == ' ' && $line_break && ($whitespace == 'normal' || $whitespace == 'nowrap' || $whitespace == 'preline') ) { $i--; $elem_w -= $this->Helper->PDF->GetStringWidth($words[$i]); array_splice($words, $i, 1); } $this->Data = join( array_splice($words, 0, $i) ); //$i here is the number of last word (starting with 0) + 1, so it's fine for splice if (!$this->Data) { // nothing fitted on current line $this->Ascent = 0; $this->Descent = 0; $this->Gap = 0; $this->NextLine(join( $words )); } else { $h = $this->Ascent + $this->Descent + $this->Gap; $elem = $this; if (preg_match_all('/( )/', $this->Data, $regs, PREG_PATTERN_ORDER)) { $spacers = count($regs[1]); } else { $spacers = 0; } do { $elem->SetCSSProperty('width', $elem->GetCSSProperty('width') + $elem_w); $elem->Spacers = $elem->Spacers + $spacers; $elem->ContentHeight = $h; $elem->SetCSSProperty('height', $h); $elem = $elem->Parent; } while ($elem && $elem->GetDisplayLevel() == 'inline'); $elem->Spacers += $spacers; $this->GetLineBox()->CurX = $start + $elem_w; if ($i < $words_count) { $this->NextLine(join( $words )); } } } function GetFollowingSiblings() { $cur_line = $this->GetLineBox(); $elem = $this; $cur_pos = 0; do { $cur_pos = $elem->Position; $elem = $elem->Parent; } while ( $elem && !($elem instanceof kPDFLine) ); return $cur_line->RemoveChildren($cur_pos+1); } function CreateNextLine() { $cur_line = $this->GetLineBox(); $cur_line->Closed(); if ($this->Node->Name != 'BR') $cur_line->LastLine = false; return $cur_line->Parent->AddChild( new kPDFLine($cur_line->Parent->Node, $this->Helper), true, $cur_line); } function NextLine($words) { $removed = $this->GetFollowingSiblings(); $next_line = $this->CreateNextLine(); if ($words) { $new_elem = $next_line->AddChild( new kPDFTextElement( $words, $this->Node, $this->Helper )); $new_elem->Closed(); } foreach ($removed as $elem) { $next_line->AddChild( $elem, false ); //don't init } } function DrawAt($page, $x=0, $y=0, $spacer_w=0) { $page->SetLineWidth(0.1); $y += $this->Ascent; //finding baseline $this->Helper->PDF->SetFont( $this->GetCSSProperty('font-family'), $this->GetCSSProperty('font-size'), $this->GetCSSProperty('font-weight'), $this->GetCSSProperty('font-style'), $this->GetCSSProperty('font-variant')); if ($color = $this->GetCSSProperty('color')) { $page->SetFillColor($color); } if (defined('PDF_DEBUG_NO_TEXT')) return ; if ($spacer_w == 0) { $data = preg_replace('/\xA0/u', ' ', $this->Data); $page->drawText($data, $x, $y); } else { $spacer_w += $page->GetStringWidth(' '); $words = explode(' ', $this->Data); foreach ($words as $word) { $word = preg_replace('/\xA0/u', ' ', $word); $page->drawText($word, $x, $y); $x += $page->GetStringWidth($word); $x += $spacer_w; } } $this->CurX = $x; } }