function &create(&$root, &$pipeline) { // Create contents of this inline box if ($root->node_type() == XML_TEXT_NODE) { $handler = get_css_handler('white-space'); return InlineBox::create_from_text($root->content, $handler->get()); } else { $box =& new InlineBox(); // Initialize content $child = $root->first_child(); while ($child) { $child_box =& create_pdf_box($child, $pipeline); $box->add_child($child_box); $child = $child->next_sibling(); } // Add fake whitespace box with zero size for the anchor spans // We need this, as "reflow" functions will automatically remove empty inline boxes from the // document tree // if ($box->is_null()) { push_css_defaults(); pop_font_size(); push_font_size('0.01pt'); $whitespace = new WhitespaceBox(); $box->add_child($whitespace); pop_css_defaults(); } } return $box; }
function apply(&$root, &$pipeline) { $local_css = array(); if (isset($this->tag_filtered[strtolower($root->tagname())])) { $local_css = $this->tag_filtered[strtolower($root->tagname())]; } if (isset($this->tag_filtered["*"])) { $local_css = array_merge($local_css, $this->tag_filtered["*"]); } $applicable = array(); foreach ($local_css as $rule) { if ($rule->match($root)) { $applicable[] = $rule; } } usort($applicable, "cmp_rule_objs"); foreach ($applicable as $rule) { switch ($rule->get_pseudoelement()) { case SELECTOR_PSEUDOELEMENT_BEFORE: case SELECTOR_PSEUDOELEMENT_AFTER: // Just store something in the 'content' property to indicate that current // element have pseudoelements // $handler =& get_css_handler('content'); $handler->css("+", $pipeline); break; default: $rule->apply($root, $pipeline); break; } } }
function ButtonImageBox($img, $field, $value) { $this->ImgBox($img); global $g_css_handlers; $handler =& get_css_handler('-html2ps-form-action'); $this->_action_url = $handler->get(); $this->_field_name = $field; $this->_field_value = $value; }
function inherit() { // Determine parent 'display' value $handler =& get_css_handler('display'); // note that as css handlers are evaluated in alphabetic order, parent display value still will be on the top of the stack $parent_display = $handler->get(); // If parent is a table row, inherit the background settings $this->push($parent_display == 'table-row' ? $this->get() : $this->default_value()); }
/** * Constructs new (possibly interactive) button box * * @param String $text text to display * @param String $field field name (interactive forms) * @param String $value field value (interactive forms) */ function ButtonSubmitBox($text, $field, $value) { $this->ButtonBox($text); /** * Save current form action reference for interactive form generation */ $handler =& get_css_handler('-html2ps-form-action'); $this->_action_url = $handler->get(); $this->_field_name = $field; $this->_value = $value; }
function inherit() { // Determine parent 'display' value $handler =& get_css_handler('display'); $parent_display = $handler->get_parent(); // Inherit vertical-align from table-rows if ($parent_display === "table-row") { $this->push($this->get()); return; } $this->push(is_inline_element($parent_display) ? $this->get() : $this->default_value()); }
function inherit() { // This pseudo-property is not inherited by tables // As current box display value may not be know at the moment of inheriting, // we'll use parent display value, stopping inheritance on the table-row/table-group level // Determine parent 'display' value $handler =& get_css_handler('display'); $parent_display = $handler->get_parent(); if ($parent_display === "table") { $this->push($this->default_value()); return; } $this->push($this->get()); }
function inherit() { // Determine parent 'display' value $handler =& get_css_handler('display'); // 'display' CSS property processed AFTER this; so parent display value will be // on the top of the stack // $parent_display = $handler->get(); // Inherit vertical-align from table-rows if ($parent_display === "table-row" || $parent_display === "table") { $this->push($this->get()); return; } $this->push(is_inline_element($parent_display) ? $this->get() : $this->default_value()); }
function RadioBox($checked, $value) { // Call parent constructor $this->GenericFormattedBox(); // Check the box state $this->_checked = $checked; /** * Store the form value for this radio button */ $this->_value = trim($value); $handler =& get_css_handler('-html2ps-form-radiogroup'); $this->_group_name = $handler->get(); // Setup box size: $this->default_baseline = units2pt(CHECKBOX_SIZE); $this->height = units2pt(CHECKBOX_SIZE); $this->width = units2pt(CHECKBOX_SIZE); }
function CSSRule($rule, &$pipeline) { $this->selector = $rule[0]; $this->body = $rule[1]; $this->baseurl = $rule[2]; $this->order = $rule[3]; // Pre-parse property values foreach (array_keys($this->body) as $key) { $handler =& get_css_handler($key); if ($handler) { $value = $this->parse_important($key, $this->body[$key]); $pipeline->push_base_url($this->baseurl); $this->body[$key] = $handler->parse($value, $pipeline); $pipeline->pop_base_url(); } } $this->specificity = css_selector_specificity($this->selector); $this->pseudoelement = css_find_pseudoelement($this->selector); }
/** * Create new BR element */ function BRBox() { /** * We're trying to avoid inheriting any of current CSS properties; * push_css_defaults will prevent any unneeded CSS properties like margins and padding to be inherited; * on the other size, it will keep the 'font-size' property we need to calculate the line height */ push_css_defaults(); $this->GenericFormattedBox(); pop_css_defaults(); /** * We treat BR as a block box; as default value of 'display' property is not 'block', we should * set it up manually. */ $this->display = 'block'; /** * In addition to 'display', we should inherit the 'clear' CSS property, as the * <BR style="clear: both;"> construct is often used all over the Net. */ $handler =& get_css_handler('clear'); $this->clear = $handler->get(); }
function GenericBox() { $this->_left = 0; $this->_top = 0; $this->baseline = 0; $this->default_baseline = 0; // Generic CSS properties // Save CSS property values $base_font_size = get_base_font_size(); // 'color' $handler = get_css_handler('color'); $this->color = $handler->get(); // 'font-size' $this->font_size = units2pt(get_font_size(), $base_font_size); // 'font-family' $this->family = get_font_family(); // 'font-weight' $this->weight = get_font_weight(); // 'font-style' $this->style = get_font_style(); // 'text-decoration' $handler = get_css_handler('text-decoration'); $this->decoration = $handler->get(); }
function _fix_tag_display($default_display, &$pipeline) { // In some cases 'display' CSS property should be ignored for element-generated boxes // Here we will use the $default_display stored above // Note that "display: none" should _never_ be changed // $handler =& get_css_handler('display'); if ($handler->get() === "none") { return; } switch ($default_display) { case 'table-cell': // TD will always have 'display: table-cell' $handler->css('table-cell', $pipeline); break; case '-button': // INPUT buttons will always have 'display: -button' (in latter case if display = 'block', we'll use a wrapper box) if ($handler->get() === 'block') { $need_block_wrapper = true; } $handler->css('-button', $pipeline); break; } }
function ListItemBox(&$root, &$pipeline) { // Call parent constructor $this->BlockBox($root); // Pseudo-CSS properties // '-list-counter' $counter =& get_css_handler('-list-counter'); $background_color =& get_css_handler('background-color'); $background_color->push_css('transparent', $pipeline); $this->str_number_box = TextBox::create(CSSListStyleType::format_number($this->list_style->type, $counter->get()), 'iso-8859-1'); $this->str_number_box->baseline = $this->str_number_box->default_baseline; $background_color->pop(); // increase counter value $counter->pop(); // remove inherited value $counter->replace($counter->get() + 1); $counter->push($counter->get()); // open the marker image if specified if (!$this->list_style->image->is_default()) { $this->marker_image = $this->list_style->image->_image; } else { $this->marker_image = null; } }
function TableBox(&$root, &$pipeline) { // Call parent constructor $this->GenericContainerBox(); // Initialize line box // $this->_current_x = 0; // $this->_current_y = 0; // List of column width constraints $this->cwc = array(); // Initialize content // $this->content = array(); // Automatically create at least one table row // if (count($this->content) == 0) { // This row should not inherit any table specific properties! // 'overflow' for example // push_css_defaults(); $this->content[] =& new TableRowBox($root); pop_css_defaults(); // } // Setup cellspacing / cellpadding values $handler =& get_css_handler('border-collapse'); if ($handler->get() == BORDER_COLLAPSE) { $handler =& get_css_handler('padding'); $handler->css("0", $pipeline); } // Set text-align to 'left'; all browsers I've ever seen prevent inheriting of // 'text-align' property by the tables. // Say, in the following example the text inside the table cell will be aligned left, // instead of inheriting 'center' value. // // <div style="text-align: center; background-color: green;"> // <table width="100" bgcolor="red"> // <tr><td>TEST // </table> // </div> $handler =& get_css_handler('text-align'); $handler->css('left', $pipeline); // Parse table contents $child = $root->first_child(); $col_index = 0; while ($child) { if ($child->node_type() === XML_ELEMENT_NODE) { if ($child->tagname() === 'colgroup') { // COLGROUP tags do not generate boxes; they contain information on the columns // $col_index = $this->parse_colgroup_tag($child, $col_index); } else { $child_box =& create_pdf_box($child, $pipeline); $this->add_child($child_box); } } $child = $child->next_sibling(); } $this->normalize(); $this->normalize_cwc(); $this->normalize_rhc(); $this->normalize_parent(); }
function &create_pdf_pseudoelement($root, $pe_type, &$pipeline) { // Store initial values to CSS stack // push_css_defaults(); // Apply default stylesheet rules (using base element) global $g_css_defaults_obj; $g_css_defaults_obj->apply($root, $pipeline); // Initially generated boxes do not require block wrappers // Block wrappers are required in following cases: // - float property is specified for non-block box which cannot be directly converted to block box // (a button, for example) // - display set to block for such box $need_block_wrapper = false; // Order is important. Items with most priority should be applied last // Tag attributes execute_attrs_before($root, $pipeline); // CSS stylesheet global $g_css_obj; $g_css_obj->apply($root, $pipeline); // values from 'style' attribute if ($root->has_attribute("style")) { parse_style_attr(null, $root, $pipeline); } // Pseudoelement-specific rules; be default, it should flow inline // $handler =& get_css_handler('display'); $handler->css('inline', $pipeline); $handler =& get_css_handler('content'); $handler->css("", $pipeline); $handler =& get_css_handler('float'); $handler->css("none", $pipeline); $handler =& get_css_handler('position'); $handler->css("static", $pipeline); $handler =& get_css_handler('margin'); $handler->css("0", $pipeline); $handler =& get_css_handler('width'); $handler->css("auto", $pipeline); $handler =& get_css_handler('height'); $handler->css("auto", $pipeline); $g_css_obj->apply_pseudoelement($pe_type, $root, $pipeline); // Now, if no content found, just return // $handler =& get_css_handler('content'); $content = $handler->get(); if ($content === "") { pop_css_defaults(); $dummy = null; return $dummy; } // CSS 2.1: // 9.7 Relationships between 'display', 'position', and 'float' // The three properties that affect box generation and layout — // 'display', 'position', and 'float' — interact as follows: // 1. If 'display' has the value 'none', then 'position' and 'float' do not apply. // In this case, the element generates no box. $position_handler =& get_css_handler('position'); $float_handler =& get_css_handler('float'); // 2. Otherwise, if 'position' has the value 'absolute' or 'fixed', the box is absolutely positioned, // the computed value of 'float' is 'none', and display is set according to the table below. // The position of the box will be determined by the 'top', 'right', 'bottom' and 'left' properties and // the box's containing block. $position = $position_handler->get(); if ($position === POSITION_ABSOLUTE || $position === POSITION_FIXED) { $float_handler->replace(FLOAT_NONE); $need_block_wrapper |= _fix_display_position_float(); } // 3. Otherwise, if 'float' has a value other than 'none', the box is floated and 'display' is set // according to the table below. $float = $float_handler->get(); if ($float != FLOAT_NONE) { $need_block_wrapper |= _fix_display_position_float(); } // 4. Otherwise, if the element is the root element, 'display' is set according to the table below. // 5. Otherwise, the remaining 'display' property values apply as specified. (see _fix_display_position_float) // Note that pseudoelements may get only standard display values $display_handler =& get_css_handler('display'); switch (trim($display_handler->get())) { case "block": $box =& BlockBox::create_from_text($content); break; case "inline": $ws_handler =& get_css_handler('white-space'); $box =& InlineBox::create_from_text($content, $ws_handler->get()); break; default: die("Unsupported 'display' value: " . $display_handler->get()); } // Check if this box needs a block wrapper (for example, floating button) // Note that to keep float/position information, we clear the CSS stack only // AFTER the wrapper box have been created; BUT we should clear the following CSS properties // to avoid the fake wrapper box actually affect the layout: // - margin // - border // - padding // - background // if ($need_block_wrapper) { $handler =& get_css_handler('margin'); $handler->css("0", $pipeline); pop_border(); push_border(default_border()); pop_padding(); push_padding(default_padding()); $handler =& get_css_handler('background'); $handler->css('transparent', $pipeline); // Create "clean" block box $wrapper =& new BlockBox(); $wrapper->add_child($box); // Remove CSS propery values from stack execute_attrs_after($root, $pipeline); pop_css_defaults(); return $wrapper; } else { // Remove CSS propery values from stack execute_attrs_after($root, $pipeline); pop_css_defaults(); return $box; } }
function ButtonResetBox($text) { $this->ButtonBox($text); $handler =& get_css_handler('-html2ps-form-action'); $this->_action_url = $handler->get(); }
function GenericFormattedBox() { $this->GenericBox(); $base_font_size = get_base_font_size(); // 'background' $handler = get_css_handler('background'); $this->background = $handler->get(); $this->background = $this->background->copy(); $this->background->units2pt($base_font_size); // 'border' $this->border = new BorderPDF(get_border()); // '-cellpadding' $handler = get_css_handler('-cellpadding'); $this->cellpadding = units2pt($handler->get(), $base_font_size); // '-cellspacing' $handler = get_css_handler('-cellspacing'); $this->cellspacing = units2pt($handler->get(), $base_font_size); // 'clear' $handler = get_css_handler('clear'); $this->clear = $handler->get(); // 'content' $handler = get_css_handler('content'); $this->content_pseudoelement = $handler->get(); // 'display' $handler = get_css_handler('display'); $this->display = $handler->get(); // 'float' $handler = get_css_handler('float'); $this->float = $handler->get(); // 'height' $this->_height_constraint = HCConstraint::create($this); $this->_height_constraint->units2pt($base_font_size); // $this->height = $this->_height_constraint->apply(0, $this); $this->height = 0; // 'line-height' $this->line_height = get_line_height(); $this->line_height = $this->line_height->copy(); $this->line_height->units2pt($base_font_size); // 'list-style' $handler = get_css_handler('list-style'); $this->list_style = $handler->get(); $this->list_style = $this->list_style->copy(); // 'margin' $handler = get_css_handler('margin'); $this->margin = $handler->get(); $this->margin = $this->margin->copy(); $this->margin->units2pt($base_font_size); // 'overflow' $handler = get_css_handler('overflow'); $this->overflow = $handler->get(); // 'padding' $handler = get_css_handler('padding'); $this->padding = $handler->get(); $this->padding = $this->padding->copy(); $this->padding->units2pt($base_font_size); // 'page-break-after' $handler = get_css_handler('page-break-after'); $this->page_break_after = $handler->get(); // 'position' $handler = get_css_handler('position'); $this->position = $handler->get(); // 'text-align' $handler = get_css_handler('text-align'); $this->text_align = $handler->get(); // 'text-indent' $handler = get_css_handler('text-indent'); $this->text_indent = $handler->get(); $this->text_indent = $this->text_indent->copy(); $this->text_indent->units2pt($base_font_size); // 'vertical-align' $handler = get_css_handler('vertical-align'); $this->vertical_align = $handler->get(); // 'visibility' $handler = get_css_handler('visibility'); $this->visibility = $handler->get(); // 'width' $handler = get_css_handler('width'); $this->_width_constraint = $handler->get(); $this->_width_constraint = $this->_width_constraint->copy(); $this->_width_constraint->units2pt($base_font_size); $this->width = $this->_width_constraint->apply(0, 0); // 'white-space' $handler = get_css_handler('white-space'); $this->white_space = $handler->get(); // CSS positioning properties // 'left' $handler = get_css_handler('left'); $value = $handler->get(); $this->left = $value; // 'top' $handler = get_css_handler('top'); $this->top = $handler->get(); // 'bottom' // TODO: automatic height calculation $handler = get_css_handler('bottom'); $this->bottom = $handler->get(); if (!is_null($this->bottom)) { $this->bottom = units2pt($this->bottom, $base_font_size); } // 'right' // TODO: automatic width calculation $handler = get_css_handler('right'); $this->right = $handler->get(); $handler = get_css_handler('z-index'); $this->z_index = $handler->get(); // 'PSEUDO-CSS' properties // '-align' $handler = get_css_handler('-align'); $this->pseudo_align = $handler->get(); // '-html2ps-link-destination' global $g_config; if ($g_config["renderlinks"]) { $handler = get_css_handler('-html2ps-link-destination'); $this->pseudo_link_destination = $handler->get(); } else { $this->pseudo_link_destination = ""; } // '-html2ps-link-target' global $g_config; if ($g_config["renderlinks"]) { $handler = get_css_handler('-html2ps-link-target'); $this->pseudo_link_target = $handler->get(); } else { $this->pseudo_link_target = ""; } // '-localalign' $handler = get_css_handler('-localalign'); switch ($handler->get()) { case LA_LEFT: break; case LA_RIGHT: $this->margin->left->auto = true; break; case LA_CENTER: $this->margin->left->auto = true; $this->margin->right->auto = true; break; } // '-nowrap' $handler = get_css_handler('-nowrap'); $this->pseudo_nowrap = $handler->get(); // Layout data $this->baseline = 0; $this->parent = null; // Unique box identifier global $g_box_uid; $g_box_uid++; $this->uid = $g_box_uid; // As PHP in most cases passes a copy of an object instead // of reference and it is pretty hard to track (especially between different versions // of PHP), we'll keep references to all boxes in the global array // global $g_boxes; // $g_boxes[$this->uid] =& $this; }
function inherit() { $handler =& get_css_handler('display'); $parent_display = $handler->get_parent(); $this->push(is_inline_element($parent_display) ? $this->get() : $this->default_value()); }
function applicable() { $handler =& get_css_handler('display'); $display = $handler->get(); return $display === 'table-cell' || $display === 'table-row' || is_inline_element($display); }
function TableCellBox(&$root, $pipeline) { $this->_suppress_first = false; $this->_suppress_last = false; $this->colspan = 1; $this->rowspan = 1; // This value will be overwritten in table 'normalize_parent' method // $this->column = 0; $this->row = 0; if ($root->tagname() === 'td' || $root->tagname() === 'th') { // Use cellspacing / cellpadding values from the containing table $handler =& get_css_handler('-cellspacing'); $cellspacing = $handler->get(); $cp_handler =& get_css_handler('-cellpadding'); $cellpadding = $cp_handler->get(); // FIXME: I'll need to resolve that issue with COLLAPSING border model. Now borders // are rendered separated // if not border set explicitly, inherit value set via border attribute of TABLE tag if (is_default_border(get_border())) { $border = get_table_border(); pop_border(); push_border($border); } $margin =& get_css_handler('margin'); $margin->replace($margin->default_value()); $handler =& get_css_handler('border-collapse'); if ($handler->get() == BORDER_COLLAPSE) { $h_padding =& get_css_handler('padding'); if ($h_padding->is_default($h_padding->get())) { $h_padding->css($cellpadding, $pipeline); } } else { $h_padding =& get_css_handler('padding'); if ($h_padding->is_default($h_padding->get())) { $h_padding->css($cellpadding, $pipeline); } if ($margin->is_default($margin->get())) { $margin->css(units_mul($cellspacing, 0.5), $pipeline); } } // Save colspan and rowspan information $this->colspan = max(1, (int) $root->get_attribute('colspan')); $this->rowspan = max(1, (int) $root->get_attribute('rowspan')); } // $root->tagname() == 'td' // Call parent constructor $this->GenericContainerBox(); // 'vertical-align' CSS value is not inherited from the table cells $handler =& get_css_handler('vertical-align'); $handler->push_default(); $this->create_content($root, $pipeline); global $g_config; if ($g_config['mode'] == "quirks") { // QUIRKS MODE: // H1-H6 and P elements should have their top/bottom margin suppressed if they occur as the first/last table cell child // correspondingly; note that we cannot do it usung CSS rules, as there's no selectors for the last child. // $child = $root->first_child(); if ($child) { while ($child && $child->node_type() != XML_ELEMENT_NODE) { $child = $child->next_sibling(); } if ($child) { if (array_search(strtolower($child->tagname()), array("h1", "h2", "h3", "h4", "h5", "h6", "p"))) { $this->_suppress_first = true; } } } $child = $root->last_child(); if ($child) { while ($child && $child->node_type() != XML_ELEMENT_NODE) { $child = $child->previous_sibling(); } if ($child) { if (array_search(strtolower($child->tagname()), array("h1", "h2", "h3", "h4", "h5", "h6", "p"))) { $this->_suppress_last = true; } } } } // pop the default vertical-align value $handler->pop(); }
function alpha($psdata, $src_img, &$size_x, &$size_y, &$image, &$mask) { $id = $this->generate_id(); $size_x = imagesx($src_img); $size_y = imagesy($src_img); $ps_image_data = ""; $ps_mask_data = 0xff; $ctr = 1; $row = 1; for ($y = 0; $y < $size_y; $y++) { for ($x = 0; $x < $size_x; $x++) { // Mask pixel $colors = imagecolorsforindex($src_img, imagecolorat($src_img, $x, $y)); $a = $colors['alpha']; $r = $colors['red']; $g = $colors['green']; $b = $colors['blue']; $handler =& get_css_handler('background-color'); $bg = $handler->get_visible_background_color(); $r = (int) ($r + ($bg[0] - $r) * $a / 127); $g = (int) ($g + ($bg[1] - $g) * $a / 127); $b = (int) ($b + ($bg[2] - $b) * $a / 127); $ps_image_data .= sprintf("\\%03o\\%03o\\%03o", $r, $g, $b); // Write mask and image rows $ctr++; if ($ctr > MAX_IMAGE_ROW_LEN || $x + 1 == $size_x) { $row_next = $size_x - $x - 1 + $size_x * ($size_y - $y - 1) == 0 ? 1 : $row + 1; $psdata->write("/row-{$id}-{$row} { /image-{$id}-data { row-{$id}-{$row_next} } def ({$ps_image_data}) } def\n"); $ps_image_data = ""; $ctr = 1; $row += 1; } } } if ($ps_image_data) { $psdata->write("/row-{$id}-{$row} { /image-{$id}-data { row-{$id}-{$row_next} } def ({$ps_image_data}) } def\n"); } $psdata->write("/image-{$id}-data { row-{$id}-1 } def\n"); $psdata->write("/image-{$id}-init { } def\n"); // return image and mask data references $image = "{image-{$id}-data}"; $mask = ""; return $id; }
function apply_css_rule_obj($properties, $baseurl, $root, &$pipeline) { $pipeline->push_base_url($baseurl); foreach ($properties as $key => $value) { switch ($key) { case 'border': css_border($value, $root); break; case 'border-color': css_border_color($value, $root); break; case 'border-top': css_border_top($value, $root); break; case 'border-right': css_border_right($value, $root); break; case 'border-bottom': css_border_bottom($value, $root); break; case 'border-left': css_border_left($value, $root); break; case 'border-style': css_border_style($value, $root); break; case 'border-top-style': css_border_top_style($value, $root); break; case 'border-right-style': css_border_right_style($value, $root); break; case 'border-bottom-style': css_border_bottom_style($value, $root); break; case 'border-left-style': css_border_left_style($value, $root); break; case 'border-top-color': css_border_top_color($value, $root); break; case 'border-right-color': css_border_right_color($value, $root); break; case 'border-bottom-color': css_border_bottom_color($value, $root); break; case 'border-left-color': css_border_left_color($value, $root); break; case 'border-width': css_border_width($value, $root); break; case 'border-top-width': css_border_top_width($value, $root); break; case 'border-right-width': css_border_right_width($value, $root); break; case 'border-bottom-width': css_border_bottom_width($value, $root); break; case 'border-left-width': css_border_left_width($value, $root); break; case 'font': css_font($value, $root); break; case 'font-family': css_font_family($value, $root); break; case 'font-size': css_font_size($value, $root); break; case 'font-style': css_font_style($value, $root); break; case 'font-weight': css_font_weight($value, $root); break; case 'line-height': css_line_height($value, $root); break; default: $handler =& get_css_handler($key); if ($handler) { $handler->replace($value, $pipeline); } break; } } $pipeline->pop_base_url(); }
function alpha(&$psdata, $src_img, &$size_x, &$size_y, &$image, &$mask) { // Generate an unique image id $id = $this->generate_id(); // Determine image size $size_x = imagesx($src_img); $size_y = imagesy($src_img); // write stread header to the postscript file $psdata->write("/image-{$id}-init { image-{$id}-data 0 setfileposition } def\n"); $psdata->write("/image-{$id}-data currentfile << /Filter /ASCIIHexDecode >> /ReusableStreamDecode filter\n"); // initialize line length counter $ctr = 0; // Save visible background color $handler =& get_css_handler('background-color'); $bg = $handler->get_visible_background_color(); for ($y = 0; $y < $size_y; $y++) { for ($x = 0; $x < $size_x; $x++) { // Check color/alpha of current pixels $colors = imagecolorsforindex($src_img, imagecolorat($src_img, $x, $y)); $a = $colors['alpha']; $r = $colors['red']; $g = $colors['green']; $b = $colors['blue']; // Calculate approximate color $r = (int) ($r + ($bg[0] - $r) * $a / 127); $g = (int) ($g + ($bg[1] - $g) * $a / 127); $b = (int) ($b + ($bg[2] - $b) * $a / 127); // Save image pixel to the stream data $psdata->write(sprintf("%02X%02X%02X", $r, $g, $b)); // Increate the line length counter; check if stream line needs to be terminated $ctr += 6; if ($ctr > MAX_LINE_LENGTH) { $psdata->write("\n"); $ctr = 0; } } } // terminate the stream data $psdata->write(">\ndef\n"); // return image and mask data references $image = "image-{$id}-data"; $mask = ""; return $id; }
function create($box) { // Determine if there's constant restriction $handler =& get_css_handler('height'); if (!$handler->is_default($handler->get())) { $constant = $handler->get(); } else { $constant = null; } // Determine if there's min restriction $handler =& get_css_handler('min-height'); if (!$handler->is_default($handler->get())) { $min = $handler->get(); } else { $min = null; } // Determine if there's max restriction $handler =& get_css_handler('max-height'); if (!$handler->is_default($handler->get())) { $max = $handler->get(); } else { $max = null; } $constraint = new HCConstraint($constant, $min, $max); return $constraint; }