Blame | Letzte Änderung | Log anzeigen | RSS feed
<?phprequire_once(HTML2PS_DIR.'utils_array.php');require_once(HTML2PS_DIR.'utils_graphic.php');require_once(HTML2PS_DIR.'utils_url.php');require_once(HTML2PS_DIR.'utils_text.php');require_once(HTML2PS_DIR.'utils_units.php');require_once(HTML2PS_DIR.'utils_number.php');require_once(HTML2PS_DIR.'value.color.php');require_once(HTML2PS_DIR.'config.parse.php');require_once(HTML2PS_DIR.'flow_context.class.inc.php');require_once(HTML2PS_DIR.'flow_viewport.class.inc.php');require_once(HTML2PS_DIR.'output._interface.class.php');require_once(HTML2PS_DIR.'output._generic.class.php');require_once(HTML2PS_DIR.'output._generic.pdf.class.php');require_once(HTML2PS_DIR.'output._generic.ps.class.php');require_once(HTML2PS_DIR.'output.pdflib.old.class.php');require_once(HTML2PS_DIR.'output.pdflib.1.6.class.php');require_once(HTML2PS_DIR.'output.fpdf.class.php');require_once(HTML2PS_DIR.'output.fastps.class.php');require_once(HTML2PS_DIR.'output.fastps.l2.class.php');require_once(HTML2PS_DIR.'output.png.class.php');// require_once(HTML2PS_DIR.'output.pcl.class.php');require_once(HTML2PS_DIR.'stubs.common.inc.php');require_once(HTML2PS_DIR.'media.layout.inc.php');require_once(HTML2PS_DIR.'box.php');require_once(HTML2PS_DIR.'box.generic.php');require_once(HTML2PS_DIR.'box.generic.formatted.php');require_once(HTML2PS_DIR.'box.container.php');require_once(HTML2PS_DIR.'box.generic.inline.php');require_once(HTML2PS_DIR.'box.inline.php');require_once(HTML2PS_DIR.'box.inline.control.php');require_once(HTML2PS_DIR.'font.class.php');require_once(HTML2PS_DIR.'font_factory.class.php');require_once(HTML2PS_DIR.'box.br.php');require_once(HTML2PS_DIR.'box.block.php');require_once(HTML2PS_DIR.'box.page.php');require_once(HTML2PS_DIR.'box.page.margin.class.php');require_once(HTML2PS_DIR.'box.body.php');require_once(HTML2PS_DIR.'box.block.inline.php');require_once(HTML2PS_DIR.'box.button.php');require_once(HTML2PS_DIR.'box.button.submit.php');require_once(HTML2PS_DIR.'box.button.reset.php');require_once(HTML2PS_DIR.'box.checkbutton.php');require_once(HTML2PS_DIR.'box.form.php');require_once(HTML2PS_DIR.'box.frame.php');require_once(HTML2PS_DIR.'box.iframe.php');require_once(HTML2PS_DIR.'box.input.text.php');require_once(HTML2PS_DIR.'box.input.textarea.php');require_once(HTML2PS_DIR.'box.input.password.php');require_once(HTML2PS_DIR.'box.legend.php');require_once(HTML2PS_DIR.'box.list-item.php');require_once(HTML2PS_DIR.'box.null.php');require_once(HTML2PS_DIR.'box.radiobutton.php');require_once(HTML2PS_DIR.'box.select.php');require_once(HTML2PS_DIR.'box.table.php');require_once(HTML2PS_DIR.'box.table.cell.php');require_once(HTML2PS_DIR.'box.table.cell.fake.php');require_once(HTML2PS_DIR.'box.table.row.php');require_once(HTML2PS_DIR.'box.table.section.php');require_once(HTML2PS_DIR.'box.text.php');require_once(HTML2PS_DIR.'box.text.string.php');require_once(HTML2PS_DIR.'box.field.pageno.php');require_once(HTML2PS_DIR.'box.field.pages.php');require_once(HTML2PS_DIR.'box.whitespace.php');require_once(HTML2PS_DIR.'box.img.php'); // Inherited from the text box!require_once(HTML2PS_DIR.'box.input.img.php');require_once(HTML2PS_DIR.'box.utils.text-align.inc.php');require_once(HTML2PS_DIR.'manager.encoding.php');require_once(HTML2PS_DIR.'ps.unicode.inc.php');require_once(HTML2PS_DIR.'ps.utils.inc.php');require_once(HTML2PS_DIR.'ps.whitespace.inc.php');require_once(HTML2PS_DIR.'ps.image.encoder.inc.php');require_once(HTML2PS_DIR.'ps.image.encoder.simple.inc.php');require_once(HTML2PS_DIR.'ps.l2.image.encoder.stream.inc.php');require_once(HTML2PS_DIR.'ps.l3.image.encoder.stream.inc.php');require_once(HTML2PS_DIR.'tag.body.inc.php');require_once(HTML2PS_DIR.'tag.font.inc.php');require_once(HTML2PS_DIR.'tag.frame.inc.php');require_once(HTML2PS_DIR.'tag.input.inc.php');require_once(HTML2PS_DIR.'tag.img.inc.php');require_once(HTML2PS_DIR.'tag.select.inc.php');require_once(HTML2PS_DIR.'tag.span.inc.php');require_once(HTML2PS_DIR.'tag.table.inc.php');require_once(HTML2PS_DIR.'tag.td.inc.php');require_once(HTML2PS_DIR.'tag.utils.inc.php');require_once(HTML2PS_DIR.'tree.navigation.inc.php');require_once(HTML2PS_DIR.'html.attrs.inc.php');require_once(HTML2PS_DIR.'xhtml.autoclose.inc.php');require_once(HTML2PS_DIR.'xhtml.utils.inc.php');require_once(HTML2PS_DIR.'xhtml.tables.inc.php');require_once(HTML2PS_DIR.'xhtml.p.inc.php');require_once(HTML2PS_DIR.'xhtml.lists.inc.php');require_once(HTML2PS_DIR.'xhtml.deflist.inc.php');require_once(HTML2PS_DIR.'xhtml.script.inc.php');require_once(HTML2PS_DIR.'xhtml.entities.inc.php');require_once(HTML2PS_DIR.'xhtml.comments.inc.php');require_once(HTML2PS_DIR.'xhtml.style.inc.php');require_once(HTML2PS_DIR.'xhtml.selects.inc.php');require_once(HTML2PS_DIR.'background.image.php');require_once(HTML2PS_DIR.'background.position.php');require_once(HTML2PS_DIR.'list-style.image.php');require_once(HTML2PS_DIR.'height.php');require_once(HTML2PS_DIR.'width.php');require_once(HTML2PS_DIR.'css.counter.php');require_once(HTML2PS_DIR.'css.counter.collection.php');require_once(HTML2PS_DIR.'css.colors.inc.php');require_once(HTML2PS_DIR.'css.constants.inc.php');require_once(HTML2PS_DIR.'css.inc.php');require_once(HTML2PS_DIR.'css.state.class.php');require_once(HTML2PS_DIR.'css.cache.class.php');require_once(HTML2PS_DIR.'css.property.handler.class.php');require_once(HTML2PS_DIR.'css.property.stringset.class.php');require_once(HTML2PS_DIR.'css.property.sub.class.php');require_once(HTML2PS_DIR.'css.property.sub.field.class.php');require_once(HTML2PS_DIR.'css.utils.inc.php');require_once(HTML2PS_DIR.'css.parse.inc.php');require_once(HTML2PS_DIR.'css.parse.media.inc.php');require_once(HTML2PS_DIR.'css.background.attachment.inc.php');require_once(HTML2PS_DIR.'css.background.color.inc.php');require_once(HTML2PS_DIR.'css.background.image.inc.php');require_once(HTML2PS_DIR.'css.background.repeat.inc.php');require_once(HTML2PS_DIR.'css.background.position.inc.php');require_once(HTML2PS_DIR.'css.background.inc.php');require_once(HTML2PS_DIR.'css.border.inc.php');require_once(HTML2PS_DIR.'css.border.style.inc.php');require_once(HTML2PS_DIR.'css.border.collapse.inc.php');require_once(HTML2PS_DIR.'css.bottom.inc.php');require_once(HTML2PS_DIR.'css.clear.inc.php');require_once(HTML2PS_DIR.'css.color.inc.php');require_once(HTML2PS_DIR.'css.direction.inc.php');require_once(HTML2PS_DIR.'css.html2ps.html.content.inc.php');require_once(HTML2PS_DIR.'css.html2ps.pseudoelements.inc.php');require_once(HTML2PS_DIR.'css.html2ps.pixels.php');require_once(HTML2PS_DIR.'css.content.inc.php');require_once(HTML2PS_DIR.'css.display.inc.php');require_once(HTML2PS_DIR.'css.float.inc.php');require_once(HTML2PS_DIR.'css.font.inc.php');require_once(HTML2PS_DIR.'css.height.inc.php');require_once(HTML2PS_DIR.'css.min-height.inc.php');require_once(HTML2PS_DIR.'css.max-height.inc.php');require_once(HTML2PS_DIR.'css.left.inc.php');require_once(HTML2PS_DIR.'css.letter-spacing.inc.php');require_once(HTML2PS_DIR.'css.list-style-image.inc.php');require_once(HTML2PS_DIR.'css.list-style-position.inc.php');require_once(HTML2PS_DIR.'css.list-style-type.inc.php');require_once(HTML2PS_DIR.'css.list-style.inc.php');require_once(HTML2PS_DIR.'css.margin.inc.php');require_once(HTML2PS_DIR.'css.overflow.inc.php');require_once(HTML2PS_DIR.'css.padding.inc.php');require_once(HTML2PS_DIR.'css.page.inc.php');require_once(HTML2PS_DIR.'css.page-break.inc.php');require_once(HTML2PS_DIR.'css.page-break-after.inc.php');require_once(HTML2PS_DIR.'css.page-break-before.inc.php');require_once(HTML2PS_DIR.'css.page-break-inside.inc.php');require_once(HTML2PS_DIR.'css.orphans.inc.php');require_once(HTML2PS_DIR.'css.size.inc.php');require_once(HTML2PS_DIR.'css.widows.inc.php');require_once(HTML2PS_DIR.'css.position.inc.php');require_once(HTML2PS_DIR.'css.right.inc.php');require_once(HTML2PS_DIR.'css.property.declaration.php');require_once(HTML2PS_DIR.'css.rules.inc.php');require_once(HTML2PS_DIR.'css.ruleset.class.php');require_once(HTML2PS_DIR.'css.selectors.inc.php');require_once(HTML2PS_DIR.'css.table-layout.inc.php');require_once(HTML2PS_DIR.'css.text-align.inc.php');require_once(HTML2PS_DIR.'css.text-decoration.inc.php');require_once(HTML2PS_DIR.'css.text-transform.inc.php');require_once(HTML2PS_DIR.'css.text-indent.inc.php');require_once(HTML2PS_DIR.'css.top.inc.php');require_once(HTML2PS_DIR.'css.vertical-align.inc.php');require_once(HTML2PS_DIR.'css.visibility.inc.php');require_once(HTML2PS_DIR.'css.white-space.inc.php');require_once(HTML2PS_DIR.'css.width.inc.php');require_once(HTML2PS_DIR.'css.word-spacing.inc.php');require_once(HTML2PS_DIR.'css.z-index.inc.php');require_once(HTML2PS_DIR.'css.pseudo.add.margin.inc.php');require_once(HTML2PS_DIR.'css.pseudo.align.inc.php');require_once(HTML2PS_DIR.'css.pseudo.cellspacing.inc.php');require_once(HTML2PS_DIR.'css.pseudo.cellpadding.inc.php');require_once(HTML2PS_DIR.'css.pseudo.form.action.inc.php');require_once(HTML2PS_DIR.'css.pseudo.form.radiogroup.inc.php');require_once(HTML2PS_DIR.'css.pseudo.link.destination.inc.php');require_once(HTML2PS_DIR.'css.pseudo.link.target.inc.php');require_once(HTML2PS_DIR.'css.pseudo.listcounter.inc.php');require_once(HTML2PS_DIR.'css.pseudo.localalign.inc.php');require_once(HTML2PS_DIR.'css.pseudo.nowrap.inc.php');require_once(HTML2PS_DIR.'css.pseudo.table.border.inc.php');// After all CSS utilities and constants have been initialized, load the default (precomiled) CSS stylesheetrequire_once(HTML2PS_DIR.'converter.class.php');require_once(HTML2PS_DIR.'treebuilder.class.php');require_once(HTML2PS_DIR.'image.class.php');require_once(HTML2PS_DIR.'fetched_data._interface.class.php');require_once(HTML2PS_DIR.'fetched_data._html.class.php');require_once(HTML2PS_DIR.'fetched_data.url.class.php');require_once(HTML2PS_DIR.'fetched_data.file.class.php');require_once(HTML2PS_DIR.'filter.data._interface.class.php');require_once(HTML2PS_DIR.'filter.data.doctype.class.php');require_once(HTML2PS_DIR.'filter.data.utf8.class.php');require_once(HTML2PS_DIR.'filter.data.ucs2.class.php');require_once(HTML2PS_DIR.'filter.data.html2xhtml.class.php');require_once(HTML2PS_DIR.'filter.data.xhtml2xhtml.class.php');require_once(HTML2PS_DIR.'parser._interface.class.php');require_once(HTML2PS_DIR.'parser.xhtml.class.php');require_once(HTML2PS_DIR.'filter.pre._interface.class.php');require_once(HTML2PS_DIR.'filter.pre.fields.class.php');require_once(HTML2PS_DIR.'filter.pre.headfoot.class.php');require_once(HTML2PS_DIR.'filter.pre.footnotes.class.php');require_once(HTML2PS_DIR.'filter.pre.height-constraint.class.php');require_once(HTML2PS_DIR.'layout._interface.class.php');require_once(HTML2PS_DIR.'layout.default.class.php');require_once(HTML2PS_DIR.'layout.page.breaks.php');require_once(HTML2PS_DIR.'filter.post._interface.class.php');require_once(HTML2PS_DIR.'filter.post.positioned.class.php');require_once(HTML2PS_DIR.'filter.post.postponed.class.php');require_once(HTML2PS_DIR.'filter.output._interface.class.php');require_once(HTML2PS_DIR.'filter.output.ps2pdf.class.php');require_once(HTML2PS_DIR.'filter.output.gzip.class.php');require_once(HTML2PS_DIR.'destination._interface.class.php');require_once(HTML2PS_DIR.'destination._http.class.php');require_once(HTML2PS_DIR.'destination.browser.class.php');require_once(HTML2PS_DIR.'destination.download.class.php');require_once(HTML2PS_DIR.'destination.file.class.php');require_once(HTML2PS_DIR.'xml.validation.inc.php');require_once(HTML2PS_DIR.'content_type.class.php');require_once(HTML2PS_DIR.'dispatcher.class.php');require_once(HTML2PS_DIR.'observer.class.php');require_once(HTML2PS_DIR.'strategy.page.break.simple.php');require_once(HTML2PS_DIR.'strategy.page.break.smart.php');require_once(HTML2PS_DIR.'strategy.link.rendering.normal.php');require_once(HTML2PS_DIR.'strategy.position.absolute.php');require_once(HTML2PS_DIR.'strategy.width.absolute.positioned.php');require_once(HTML2PS_DIR.'autofix.url.php');require_once(HTML2PS_DIR.'fetcher._interface.class.php');require_once(HTML2PS_DIR.'features/_factory.php');class Pipeline {var $fetchers;var $data_filters;var $error_message;var $parser;var $pre_tree_filters;var $layout_engine;var $post_tree_filters;var $output_driver;var $output_filters;var $destination;var $_base_url;var $_page_at_rules;var $_counters;var $_footnotes;var $_cssState;var $_css;var $_defaultCSS;var $_dispatcher;var $_current_page_name;var $_page_break_strategy;function Pipeline() {$this->_css = array();$this->_counters = array();$this->_footnotes = array();$this->_base_url = array('');$this->_reset_page_at_rules();$this->pre_tree_filters = array();$this->_dispatcher =& new Dispatcher();$this->_dispatcher->add_event('before-page-heights');$this->_dispatcher->add_event('before-page');$this->_dispatcher->add_event('after-page');$this->_dispatcher->add_event('before-batch-item');$this->_dispatcher->add_event('after-batch-item');$this->_dispatcher->add_event('after-parse');$this->_dispatcher->add_event('before-document');$this->_dispatcher->add_event('after-document');$this->_dispatcher->add_event('before-batch');$this->_dispatcher->add_event('after-batch');$this->_page_break_strategy = new StrategyPageBreakSimple();}function add_feature($feature_name, $params = array()) {$feature_object =& FeatureFactory::get($feature_name);if (is_null($feature_object)) {die(sprintf('No feature "%s" found', $feature_name));};$feature_object->install($this, $params);}function add_fetcher(&$fetcher) {array_unshift($this->fetchers, $fetcher);}function calculate_page_heights(&$media, &$box) {return $this->_page_break_strategy->run($this, $media, $box);}function clear_box_id_map() {$GLOBALS['__html_box_id_map'] = array();}function close() {$this->_dispatcher->fire('after-batch', array('pipeline' => &$this));$this->output_driver->close();$this->_output();$this->output_driver->release();// Non HTML-specific cleanup//ImageFactory::clear_cache();}function configure($options) {$defaults = array('compress' => false,'cssmedia' => 'screen','debugbox' => false,'debugnoclip' => false,'draw_page_border' => false,'encoding' => '','html2xhtml' => true,'imagequality_workaround' => false,'landscape' => false,'margins' => array('left' => 30,'right' => 15,'top' => 15,'bottom' => 15),'media' => 'A4','method' => 'fpdf','mode' => 'html','output' => 0,'pagewidth' => 800,'pdfversion' => "1.2",'ps2pdf' => false,'pslevel' => 3,'renderfields' => false,'renderforms' => false,'renderimages' => true,'renderlinks' => false,'scalepoints' => true,'smartpagebreak' => true,'transparency_workaround' => false);// As a reminder: If the input arrays have the same string keys, then the later value for that key will overwrite the previous one.$GLOBALS['g_config'] = array_merge($defaults, $options);// Note that CSS media names should be case-insensitive$GLOBALS['g_config']['cssmedia'] = strtolower($GLOBALS['g_config']['cssmedia']);if ($GLOBALS['g_config']['smartpagebreak']) {$this->_page_break_strategy = new StrategyPageBreakSmart();} else {$this->_page_break_strategy = new StrategyPageBreakSimple();};}function _addFootnote(&$note_call) {$this->_footnotes[] =& $note_call;}// function _fillContent($content) {// $filled = "";// while (preg_match("/^.*?('.*?'|\".*?\"|counter\(.*?\))(.*)$/", $content, $matches)) {// $data = $matches[1];// $content = $matches[2];// if ($data{0} != '\'' && $data{0} != '"') {// $filled .= $this->_fillContentCounter($data);// } else {// $filled .= $this->_fillContentString($data);// };// };// return $filled;// }// function _fillContentString($content) {// $unescaped_content = css_process_escapes($content);// $unquoted_content = css_remove_value_quotes($unescaped_content);// return $unquoted_content;// }// function _fillContentCounter($content) {// preg_match("/counter\((.*?)\)/", $content, $matches);// return $this->_getCounter($matches[1]);// }function &get_counters() {$counter_collection =& new CSSCounterCollection();foreach ($this->_counters as $counter_name => $counter_value) {$counter =& new CSSCounter($counter_name);$counter->set($counter_value);$counter_collection->add($counter);};return $counter_collection;}function &get_dispatcher() {return $this->_dispatcher;}function get_counter($counter) {if (isset($this->_counters[$counter])) {return $this->_counters[$counter];};/*** CSS 2.1: Counters that are not in the scope of any* 'counter-reset', are assumed to have been reset to 0 by a* 'counter-reset' on the root element.*/return 0;}function reset_counter($counter, $value) {$this->_counters[$counter] = $value;}function increment_counter($counter, $value) {$this->_counters[$counter] += $value;}function add_at_rule_page($at_rule) {$selector =& $at_rule->getSelector();$type = $selector->get_type();$this->_page_at_rules[$type][] = $at_rule;}function _reset_page_at_rules() {$this->_page_at_rules = array(CSS_PAGE_SELECTOR_ALL => array(),CSS_PAGE_SELECTOR_FIRST => array(),CSS_PAGE_SELECTOR_LEFT => array(),CSS_PAGE_SELECTOR_RIGHT => array(),CSS_PAGE_SELECTOR_NAMED => array());}function &get_default_css() {return $this->_defaultCSS;}function &get_current_css() {return $this->_css[0];}function &get_current_css_state() {return $this->_cssState[0];}function push_css() {array_unshift($this->_css, new CSSRuleset());}function pop_css() {array_shift($this->_css);}/*** Note that different pages may define different margin boxes (for* example, left and right pages may have different headers). In* this case, we should process @page rules in order of their* specificity (no selector < :left / :right < :first) and extract* margin boxes to be drawn** @param $page_no Integer current page index (1-based)* @param $media*/function render_margin_boxes($page_no, &$media) {$boxes =& $this->reflow_margin_boxes($page_no, $media);foreach ($boxes as $selector => $box) {$boxes[$selector]->show($this->output_driver);};// Memleak fixfor ($i=0, $size = count($boxes); $i < $size; $i++) {$boxes[$i]->destroy();};unset($boxes);}function get_page_media($page_no, &$media) {$page_rules =& $this->get_page_rules($page_no);$size_landscape = $page_rules->get_property_value(CSS_SIZE);if (!is_null($size_landscape)) {$media->set_width($size_landscape['size']['width']);$media->set_height($size_landscape['size']['height']);$media->set_landscape($size_landscape['landscape']);};$margins = $page_rules->get_property_value(CSS_MARGIN);if (!is_null($margins)) {$media->margins['left'] = $margins->left->calc(mm2pt($media->get_width())) / mm2pt(1) / pt2pt(1);$media->margins['right'] = $margins->right->calc(mm2pt($media->get_width())) / mm2pt(1) / pt2pt(1);$media->margins['top'] = $margins->top->calc(mm2pt($media->get_height())) / mm2pt(1) / pt2pt(1);$media->margins['bottom'] = $margins->bottom->calc(mm2pt($media->get_height())) / mm2pt(1) / pt2pt(1);};$left_margin = $page_rules->get_property_value(CSS_MARGIN_LEFT);if (!is_null($left_margin)) {$media->margins['left'] = $left_margin->calc(mm2pt($media->get_width())) / mm2pt(1) / pt2pt(1);};$right_margin = $page_rules->get_property_value(CSS_MARGIN_RIGHT);if (!is_null($right_margin)) {$media->margins['right'] = $right_margin->calc(mm2pt($media->get_width())) / mm2pt(1) / pt2pt(1);};$top_margin = $page_rules->get_property_value(CSS_MARGIN_TOP);if (!is_null($top_margin)) {$media->margins['top'] = $top_margin->calc(mm2pt($media->get_height())) / mm2pt(1) / pt2pt(1);};$bottom_margin = $page_rules->get_property_value(CSS_MARGIN_BOTTOM);if (!is_null($bottom_margin)) {$media->margins['bottom'] = $bottom_margin->calc(mm2pt($media->get_height())) / mm2pt(1) / pt2pt(1);};$pixels = $page_rules->get_property_value(CSS_HTML2PS_PIXELS);if (!is_null($pixels)) {$media->set_pixels($pixels);};}function &get_page_rules($page_no) {$collection =& new CSSPropertyCollection();foreach ($this->_page_at_rules[CSS_PAGE_SELECTOR_ALL] as $rule) {$collection->merge($rule->css);};/*** Check which one of :right/:left selector is applicable (assuming that first page matches :right)*/if ($page_no % 2 == 0) {foreach ($this->_page_at_rules[CSS_PAGE_SELECTOR_LEFT] as $rule) {$collection->merge($rule->css);};} else {foreach ($this->_page_at_rules[CSS_PAGE_SELECTOR_RIGHT] as $rule) {$collection->merge($rule->css);};};if ($page_no == 1) {foreach ($this->_page_at_rules[CSS_PAGE_SELECTOR_FIRST] as $rule) {$collection->merge($rule->css);};};return $collection;}function &reflow_page_box($page_no, &$media) {$rules =& $this->get_page_rules($page_no);$box =& BoxPage::create($this, $rules);$box->reflow($media);return $box;}function render_page_box($page_no, &$media) {$box =& $this->reflow_page_box($page_no, $media);$box->show($this->output_driver);$box->destroy();unset($box);}function &reflow_margin_boxes($page_no, &$media) {$at_rules = $this->_getMarginBoxes($page_no, $media);$boxes = array();foreach ($at_rules as $at_rule) {$selector = $at_rule->getSelector();$boxes[$selector] =& BoxPageMargin::create($this, $at_rule);};foreach ($boxes as $selector => $box) {$linebox_started = false;$previous_whitespace = false;$boxes[$selector]->reflow_whitespace($linebox_started, $previous_whitespace);$boxes[$selector]->reflow_text($this->output_driver);};foreach ($boxes as $selector => $box) {$boxes[$selector]->reflow($this->output_driver,$media,$boxes);};return $boxes;}/*** Note that "+" operation on arrays will preserve existing elements; thus* we need to process @page rules in order of decreasing specificity**/function _getMarginBoxes($page_no, $media) {$applicable_margin_boxes = array();/*** Check if :first selector is applicable*/if ($page_no == 1) {foreach ($this->_page_at_rules[CSS_PAGE_SELECTOR_FIRST] as $rule) {$applicable_margin_boxes = $applicable_margin_boxes + $rule->getAtRuleMarginBoxes();};};/*** Check which one of :right/:left selector is applicable (assuming that first page matches :right)*/if ($page_no % 2 == 0) {foreach ($this->_page_at_rules[CSS_PAGE_SELECTOR_LEFT] as $rule) {$applicable_margin_boxes = $applicable_margin_boxes + $rule->getAtRuleMarginBoxes();};} else {foreach ($this->_page_at_rules[CSS_PAGE_SELECTOR_RIGHT] as $rule) {$applicable_margin_boxes = $applicable_margin_boxes + $rule->getAtRuleMarginBoxes();};};/*** Extract margin boxes from plain @page rules*/foreach ($this->_page_at_rules[CSS_PAGE_SELECTOR_ALL] as $rule) {$applicable_margin_boxes = $applicable_margin_boxes + $rule->getAtRuleMarginBoxes();};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_TOP])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_TOP] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_TOP,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_TOP_LEFT_CORNER])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_TOP_LEFT_CORNER] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_TOP_LEFT_CORNER,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_TOP_LEFT])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_TOP_LEFT] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_TOP_LEFT,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_TOP_CENTER])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_TOP_CENTER] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_TOP_CENTER,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_TOP_RIGHT])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_TOP_RIGHT] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_TOP_RIGHT,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_TOP_RIGHT_CORNER])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_TOP_RIGHT_CORNER] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_TOP_RIGHT_CORNER,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_BOTTOM])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_BOTTOM] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_BOTTOM,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_BOTTOM_LEFT_CORNER])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_BOTTOM_LEFT_CORNER] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_BOTTOM_LEFT_CORNER,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_BOTTOM_LEFT])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_BOTTOM_LEFT] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_BOTTOM_LEFT,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_BOTTOM_CENTER])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_BOTTOM_CENTER] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_BOTTOM_CENTER,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_BOTTOM_RIGHT])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_BOTTOM_RIGHT] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_BOTTOM_RIGHT,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_BOTTOM_RIGHT_CORNER])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_BOTTOM_RIGHT_CORNER] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_BOTTOM_RIGHT_CORNER,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_LEFT_TOP])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_LEFT_TOP] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_LEFT_TOP,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_LEFT_MIDDLE])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_LEFT_MIDDLE] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_LEFT_MIDDLE,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_LEFT_BOTTOM])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_LEFT_BOTTOM] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_LEFT_BOTTOM,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_RIGHT_TOP])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_RIGHT_TOP] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_RIGHT_TOP,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_RIGHT_MIDDLE])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_RIGHT_MIDDLE] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_RIGHT_MIDDLE,$this);};if (!isset($applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_RIGHT_BOTTOM])) {$applicable_margin_boxes[CSS_MARGIN_BOX_SELECTOR_RIGHT_BOTTOM] =&new CSSAtRuleMarginBox(CSS_MARGIN_BOX_SELECTOR_RIGHT_BOTTOM,$this);};return $applicable_margin_boxes;}function _process_item($data_id, &$media, $offset=0) {$this->_dispatcher->fire('before-batch-item', array('pipeline' => &$this));$box =& $this->_layout_item($data_id, $media, $offset, $context, $postponed_filter);if (is_null($box)) {error_log(sprintf(_('Could not fetch: %s'), (string)$data_id));return true;};$this->_show_item($box, $offset, $context, $media, $postponed_filter);// Clear CSS for this item$this->pop_css();$this->_defaultCSS = null;// Memory leak fix: caused by circular references?$box->destroy();$this->_dispatcher->fire('after-batch-item', array('pipeline' => &$this));return true;}function _show_item(&$box, $offset, &$context, &$media, &$postponed_filter) {$context->sort_absolute_positioned_by_z_index();$this->_dispatcher->fire('before-page-heights', array('pipeline' => &$this,'document' => &$box,'media' => &$media));// Make batch-processing offset$page_heights = $this->calculate_page_heights($media, $box);$box->offset(0, $offset);$box->reflow_anchors($this->output_driver, $this->output_driver->anchors, $page_heights);$this->_dispatcher->fire('before-document', array('pipeline' => &$this,'document' => &$box,'page-heights' => &$page_heights,'media' => &$media));$expected_pages = count($page_heights);$this->output_driver->set_expected_pages($expected_pages);$this->reset_counter('pages', $expected_pages);$this->reset_counter('page', 0);// Output PDF pages using chosen PDF driverfor ($i = 0; $i < $expected_pages; $i++) {$this->get_page_media(1, $media);$this->output_driver->update_media($media);$this->_setupScales($media);$current_page_offset = $i == 0 ? 0 : $page_heights[$i-1];$current_page_height = $page_heights[$i];$this->output_driver->next_page($current_page_offset);// Preparen list of postponed (floating and relative-positioned) boxes for the current page$postponed_filter->process($box, null, $this);$this->reset_counter('footnote', 0);$this->increment_counter('page', 1);$this->output_driver->save();/*** Note that margin boxes should be rendered before 'setup_clip', as it will trim all* content rendered outside the 'main' page area*/$this->render_margin_boxes($i+1, $media);$this->render_page_box($i+1, $media);$this->output_driver->setPageHeight($current_page_height);$this->output_driver->setup_clip();$this->_dispatcher->fire('before-page', array('pipeline' => &$this,'document' => &$box,'pageno' => $i));if (is_null($box->show($this->output_driver))) {error_log('Pipeline::_process_item: output routine failed');return null;};/*** Show postponed boxes - relative and floating boxes, as they should be* shown over boxes on the same layer*/$this->output_driver->show_postponed();$this->renderAbsolutePositioned($context);$this->output_driver->restore();$this->renderFixedPositioned($context);$this->renderFootnotes();global $g_config;if ($g_config['draw_page_border']) {$this->output_driver->draw_page_border();};$this->_dispatcher->fire('after-page', array('pipeline' => &$this,'document' => &$box,'pageno' => $i));};$this->_dispatcher->fire('after-document', array('pipeline' => &$this,'document' => &$box));}function _output() {$temporary_output_filename = $this->output_driver->get_filename();for ($i=0; $i<count($this->output_filters); $i++) {$temporary_output_filename = $this->output_filters[$i]->process($temporary_output_filename);};// Determine the content type of the result$content_type = null;$i = count($this->output_filters)-1;while (($i >= 0) && (is_null($content_type))) {$content_type = $this->output_filters[$i]->content_type();$i--;};if (is_null($content_type)) {$content_type = $this->output_driver->content_type();};$this->destination->process($temporary_output_filename, $content_type);unlink($temporary_output_filename);}function set_destination(&$destination) {$this->destination =& $destination;}function set_output_driver(&$output_driver) {$this->output_driver =& $output_driver;}function &fetch($data_id) {if (count($this->fetchers) == 0) {ob_start();include(HTML2PS_DIR.'templates/error._no_fetchers.tpl');$this->error_message = ob_get_contents();ob_end_clean();$null = null;return $null;};// Fetch datafor ($i=0; $i<count($this->fetchers); $i++) {$data = $this->fetchers[$i]->get_data($data_id);if ($data != null) {$this->push_base_url($this->fetchers[$i]->get_base_url());return $data;};};if (defined('DEBUG_MODE')) {error_log(sprintf('Could not fetch %s', $data_id));};$null = null;return $null;}function process($data_id, &$media) {return $this->process_batch(array($data_id), $media);}function _setupScales(&$media) {global $g_config;global $g_px_scale;global $g_pt_scale;$g_px_scale = floor(mm2pt($media->width() - $media->margins['left'] - $media->margins['right'])) / $media->pixels;if ($g_config['scalepoints']) {$g_pt_scale = $g_px_scale * 1.33; // This is a magic number, just don't touch it, or everything will explode!} else {$g_pt_scale = 1.0;};}/*** Processes an set of URLs ot once; every URL is rendered on the separate page and* merged to one PDF file.** Note: to reduce peak memory requirement, URLs are processed one-after-one.** @param Array $data_id_array Array of page identifiers to be processed (usually URLs or files paths)* @param Media $media Object describing the media to render for (size, margins, orientaiton & resolution)*/function process_batch($data_id_array, &$media) {$this->clear_box_id_map();// Save and disable magic_quotes_runtime$mq_runtime = get_magic_quotes_runtime();set_magic_quotes_runtime(0);$this->_prepare($media);$this->_dispatcher->fire('before-batch', array('pipeline' => &$this));$i = 0;$offset = 0;foreach ($data_id_array as $data_id) {$this->_process_item($data_id, $media, $offset);$i++;$offset = $this->output_driver->offset;};$this->close();// Restore magic_quotes_runtime settingset_magic_quotes_runtime($mq_runtime);return true;}function error_message() {$message = file_get_contents(HTML2PS_DIR.'templates/error._header.tpl');$message .= $this->error_message;for ($i=0; $i<count($this->fetchers); $i++) {$message .= $this->fetchers[$i]->error_message();};$message .= $this->output_driver->error_message();$message .= file_get_contents(HTML2PS_DIR.'templates/error._footer.tpl');return $message;}function push_base_url($url) {array_unshift($this->_base_url, $url);}function pop_base_url() {array_shift($this->_base_url);}function get_base_url() {return $this->_base_url[0];}function &get_output_driver() {return $this->output_driver;}function guess_url($src) {return guess_url($src, $this->get_base_url());}function renderFootnotes() {/*** Render every footnote defined (note-call element is visible) on a current page*/$footnote_y = $this->output_driver->getFootnoteTop() - FOOTNOTE_LINE_TOP_GAP - FOOTNOTE_LINE_BOTTOM_GAP;$footnote_x = $this->output_driver->getPageLeft();$footnotes_found = false;foreach ($this->_footnotes as $footnote) {// Note that footnote area for current page have been already defined,// as show_foonote is called after note-call boxes were placed.if ($this->output_driver->contains($footnote->_note_call_box)) {$footnotes_found = true;$footnote_y = $footnote->show_footnote($this->output_driver,$footnote_x,$footnote_y);$footnote_y -= FOOTNOTE_GAP;};};/*** Draw thin line separating footnotes from page content*/if ($footnotes_found) {$this->output_driver->setrgbcolor(0,0,0);$this->output_driver->moveto($this->output_driver->getPageLeft(),$this->output_driver->getFootnoteTop() - FOOTNOTE_LINE_TOP_GAP);$this->output_driver->lineto($this->output_driver->getPageLeft() + $this->output_driver->getPageWidth()*FOOTNOTE_LINE_PERCENT/100,$this->output_driver->getFootnoteTop() - FOOTNOTE_LINE_TOP_GAP);$this->output_driver->stroke();};}function renderAbsolutePositioned(&$context) {for ($j=0, $size = count($context->absolute_positioned); $j<$size; $j++) {$current_box =& $context->absolute_positioned[$j];if ($current_box->get_css_property(CSS_VISIBILITY) === VISIBILITY_VISIBLE) {$this->output_driver->save();$current_box->_setupClip($this->output_driver);if (is_null($current_box->show($this->output_driver))) {return null;};$this->output_driver->restore();};};$this->output_driver->show_postponed_in_absolute();}function renderFixedPositioned(&$context) {for ($j=0, $size = count($context->fixed_positioned); $j<$size; $j++) {$current_box =& $context->fixed_positioned[$j];if ($current_box->get_css_property(CSS_VISIBILITY) === VISIBILITY_VISIBLE) {$this->output_driver->save();$current_box->_setupClip($this->output_driver);if (is_null($current_box->show_fixed($this->output_driver))) {return null;};$this->output_driver->restore();};};$this->output_driver->show_postponed_in_fixed();}function _prepare(&$media) {$this->_setupScales($media);$GLOBALS['g_media'] =& $media;$this->output_driver->reset($media);}function reset_css() {$css_cache = CSSCache::get();$this->_defaultCSS = $css_cache->compile('resource://default.css',file_get_contents(HTML2PS_DIR.'default.css'),$this);$this->_css = array();$this->push_css();$this->_cssState = array(new CSSState(CSS::get()));}function &_layout_item($data_id, &$media, $offset, &$context, &$postponed_filter) {$this->_reset_page_at_rules();$this->reset_css();$font = $this->_cssState[0]->get_property(CSS_FONT);$font->units2pt(0);$this->_cssState[0]->set_property(CSS_FONT, $font);$data = $this->fetch($data_id);if (is_null($data)) {$dummy = null;return $dummy;};// Run raw data filtersfor ($i = 0; $i < count($this->data_filters); $i++) {$data = $this->data_filters[$i]->process($data);};// Parse the raw data$box =& $this->parser->process($data->get_content(), $this, $media);$this->_dispatcher->fire('after-parse', array('pipeline' => &$this,'document' => &$box,'media' => $media));/*** Run obligatory tree filters*//*** height-constraint processing filter;*/$filter = new PreTreeFilterHeightConstraint();$filter->process($box, $data, $this);/*** Footnote support filter*/$filter = new PreTreeFilterFootnotes();$filter->process($box, $data, $this);// Run pre-layout tree filtersfor ($i=0, $size = count($this->pre_tree_filters); $i < $size; $i++) {$this->pre_tree_filters[$i]->process($box, $data, $this);};$context = new FlowContext;/*** Extract absolute/fixed positioned boxes*/$positioned_filter = new PostTreeFilterPositioned($context);$positioned_filter->process($box, null, $this);$postponed_filter = new PostTreeFilterPostponed($this->output_driver);$postponed_filter->process($box, null, $this);$this->output_driver->prepare();// Force generation of custom characters for margin boxesfor ($i = 0; $i <= 1; $i++) {$this->get_page_media(1, $media);$at_rules = $this->_getMarginBoxes($i, $media);$boxes = array();foreach ($at_rules as $at_rule) {$selector = $at_rule->getSelector();$boxes[$selector] =& BoxPageMargin::create($this, $at_rule);};};$status = $this->layout_engine->process($box, $media, $this->output_driver, $context);if (is_null($status)) {error_log('Pipeline::_process_item: layout routine failed');$dummy = null;return $dummy;};// Run post-layout tree filtersfor ($i=0; $i<count($this->post_tree_filters); $i++) {$this->post_tree_filters[$i]->process($box);};return $box;}function &getDispatcher() {return $this->_dispatcher;}function get_current_page_name() {return $this->_current_page_name;}function set_current_page_name($name) {$this->_current_page_name = $name;}}?>