1<?php 2// $Header: /cvsroot/html2ps/html.attrs.inc.php,v 1.63 2007/03/15 18:37:32 Konstantin Exp $ 3 4global $g_tag_attrs; 5$g_tag_attrs = array( 6 /** 7 * Attribute handlers applicable to all tags 8 */ 9 '*' => array( 10 'id' => 'attr_id', 11 ), 12 13 /** 14 * Tag-specific attribute handlers 15 */ 16 'a' => array( 17 'href' => 'attr_href', 18 'name' => 'attr_name' 19 ), 20 'body' => array( 21 'background' => 'attr_background', 22 'bgcolor' => 'attr_bgcolor', 23 'dir' => 'attr_dir', 24 'text' => 'attr_body_text', 25 'link' => 'attr_body_link', 26 'topmargin' => 'attr_body_topmargin', 27 'leftmargin' => 'attr_body_leftmargin', 28 'marginheight' => 'attr_body_marginheight', 29 'marginwidth' => 'attr_body_marginwidth' 30 ), 31 'div' => array( 32 'align' => 'attr_align' 33 ), 34 'font' => array( 35 'size' => 'attr_font_size', 36 'color' => 'attr_font_color', 37 'face' => 'attr_font_face' 38 ), 39 'form' => array( 40 'action' => 'attr_form_action' 41 ), 42 'frame' => array( 43 'frameborder' => 'attr_frameborder', 44 'marginwidth' => 'attr_iframe_marginwidth', 45 'marginheight' => 'attr_iframe_marginheight' 46 ), 47 'frameset'=> array( 48 'frameborder' => 'attr_frameborder' 49 ), 50 'h1' => array( 51 'align' => 'attr_align' 52 ), 53 'h2' => array( 54 'align' => 'attr_align' 55 ), 56 'h3' => array( 57 'align' => 'attr_align' 58 ), 59 'h4' => array( 60 'align' => 'attr_align' 61 ), 62 'h5' => array( 63 'align' => 'attr_align' 64 ), 65 'h6' => array( 66 'align' => 'attr_align' 67 ), 68 'hr' => array( 69 'align' => 'attr_self_align', 70 'width' => 'attr_width', 71 'color' => 'attr_hr_color' 72 ), 73 'input' => array( 74 'name' => 'attr_input_name', 75 'size' => 'attr_input_size' 76 ), 77 'iframe' => array( 78 'frameborder' => 'attr_frameborder', 79 'marginwidth' => 'attr_iframe_marginwidth', 80 'marginheight' => 'attr_iframe_marginheight', 81 'height' => 'attr_height_required', 82 'width' => 'attr_width' 83 ), 84 'img' => array( 85 'width' => 'attr_width', 86 'height' => 'attr_height_required', 87 'border' => 'attr_border', 88 'hspace' => 'attr_hspace', 89 'vspace' => 'attr_vspace', 90 'align' => 'attr_img_align' 91 ), 92 'marquee' => array( 93 'width' => 'attr_width', 94 'height' => 'attr_height_required' 95 ), 96 'object' => array( 97 'width' => 'attr_width', 98 'height' => 'attr_height' 99 ), 100 'ol' => array( 101 'start' => 'attr_start', 102 'type' => 'attr_ol_type' 103 ), 104 'p' => array( 105 'align' => 'attr_align' 106 ), 107 'table' => array( 108 'border' => 'attr_table_border', 109 'bordercolor' => 'attr_table_bordercolor', 110 'align' => 'attr_table_float_align', 111 'bgcolor' => 'attr_bgcolor', 112 'width' => 'attr_width', 113 'background' => 'attr_background', 114 'height' => 'attr_height', 115 'cellspacing' => 'attr_cellspacing', 116 'cellpadding' => 'attr_cellpadding', 117 'rules' => 'attr_table_rules' // NOTE that 'rules' should appear _after_ 'border' handler! 118 ), 119 'td' => array( 120 'align' => 'attr_align', 121 'valign' => 'attr_valign', 122 'height' => 'attr_height', 123 'background' => 'attr_background', 124 'bgcolor' => 'attr_bgcolor', 125 'nowrap' => 'attr_nowrap', 126 'width' => 'attr_width' 127 ), 128 'textarea'=> array( 129 'rows' => 'attr_textarea_rows', 130 'cols' => 'attr_textarea_cols' 131 ), 132 'th' => array( 133 'align' => 'attr_align', 134 'valign' => 'attr_valign', 135 'height' => 'attr_height', 136 'background' => 'attr_background', 137 'bgcolor' => 'attr_bgcolor', 138 'nowrap' => 'attr_nowrap', 139 'width' => 'attr_width' 140 ), 141 'tr' => array( 142 'align' => 'attr_align', 143 'bgcolor' => 'attr_bgcolor', 144 'valign' => 'attr_row_valign', 145 'height' => 'attr_height' 146 ), 147 'ul' => array( 148 'start' => 'attr_start', 149 'type' => 'attr_ul_type' 150 ) 151); 152 153 154function execute_attrs_before($root, &$pipeline) { execute_attrs($root, '_before', $pipeline); } 155function execute_attrs_after($root, &$pipeline) { execute_attrs($root, '_after', $pipeline); } 156function execute_attrs_after_styles($root, &$pipeline) { execute_attrs($root, '_after_styles', $pipeline); } 157 158function execute_attrs(&$root, $suffix, &$pipeline) { 159 global $g_tag_attrs; 160 161 foreach ($g_tag_attrs['*'] as $attr => $fun) { 162 if ($root->has_attribute($attr)) { 163 $fun = $fun.$suffix; 164 $fun($root, $pipeline); 165 }; 166 }; 167 168 if (array_key_exists($root->tagname(), $g_tag_attrs)) { 169 foreach ($g_tag_attrs[$root->tagname()] as $attr => $fun) { 170 if ($root->has_attribute($attr)) { 171 $fun = $fun.$suffix; 172 $fun($root, $pipeline); 173 }; 174 }; 175 }; 176}; 177 178// ========= Handlers 179 180// A NAME 181function attr_name_before(&$root, &$pipeline) { 182 $handler =& CSS::get_handler(CSS_HTML2PS_LINK_DESTINATION); 183 $handler->css($root->get_attribute('name'), $pipeline); 184} 185function attr_name_after_styles(&$root, &$pipeline) {}; 186function attr_name_after(&$root, &$pipeline) {}; 187 188// A ID 189function attr_id_before(&$root, &$pipeline) { 190 $handler =& CSS::get_handler(CSS_HTML2PS_LINK_DESTINATION); 191 $handler->css($root->get_attribute('id'), $pipeline); 192} 193function attr_id_after_styles(&$root, &$pipeline) {}; 194function attr_id_after(&$root, &$pipeline) {}; 195 196 197// A HREF 198function attr_href_before(&$root, &$pipeline) { 199 $handler =& CSS::get_handler(CSS_HTML2PS_LINK_TARGET); 200 $handler->css($root->get_attribute('href'), $pipeline); 201} 202function attr_href_after_styles(&$root, &$pipeline) {}; 203function attr_href_after(&$root, &$pipeline) {}; 204 205// IFRAME 206function attr_frameborder_before(&$root, &$pipeline) { 207 $css_state =& $pipeline->get_current_css_state(); 208 $handler =& CSS::get_handler(CSS_BORDER); 209 210 switch ($root->get_attribute('frameborder')) { 211 case '1': 212 $handler->css('inset black 1px', $pipeline); 213 break; 214 case '0': 215 $handler->css('none', $pipeline); 216 break; 217 }; 218} 219function attr_frameborder_after_styles(&$root, &$pipeline) {}; 220function attr_frameborder_after(&$root, &$pipeline) {}; 221 222function attr_iframe_marginheight_before(&$root, &$pipeline) { 223 $handler =& CSS::get_handler(CSS_PADDING_TOP); 224 $handler->css((int)$root->get_attribute('marginheight').'px',$pipeline); 225 $handler =& CSS::get_handler(CSS_PADDING_BOTTOM); 226 $handler->css((int)$root->get_attribute('marginheight').'px',$pipeline); 227} 228function attr_iframe_marginheight_after_styles(&$root, &$pipeline) {}; 229function attr_iframe_marginheight_after(&$root, &$pipeline) {}; 230 231function attr_iframe_marginwidth_before(&$root, &$pipeline) { 232 $handler =& CSS::get_handler(CSS_PADDING_RIGHT); 233 $handler->css((int)$root->get_attribute('marginwidth').'px',$pipeline); 234 $handler =& CSS::get_handler(CSS_PADDING_LEFT); 235 $handler->css((int)$root->get_attribute('marginwidth').'px',$pipeline); 236} 237function attr_iframe_marginwidth_after_styles(&$root, &$pipeline) {}; 238function attr_iframe_marginwidth_after(&$root, &$pipeline) {}; 239 240 241// BODY-specific 242function attr_body_text_before(&$root, &$pipeline) { 243 $handler =& CSS::get_handler(CSS_COLOR); 244 $handler->css($root->get_attribute('text'),$pipeline); 245} 246function attr_body_text_after_styles(&$root, &$pipeline) {}; 247function attr_body_text_after(&$root, &$pipeline) {}; 248 249function attr_body_link_before(&$root, &$pipeline) { 250 $color = $root->get_attribute('link'); 251 252 // -1000 means priority modifier; so, any real CSS rule will have more priority than 253 // this fake rule 254 255 $collection = new CSSPropertyCollection(); 256 $collection->add_property(CSSPropertyDeclaration::create(CSS_COLOR, $color, $pipeline)); 257 $rule = array(array(SELECTOR_SEQUENCE, array(array(SELECTOR_TAG, 'a'), 258 array(SELECTOR_PSEUDOCLASS_LINK_LOW_PRIORITY))), 259 $collection, 260 '', 261 -1000); 262 263 $css =& $pipeline->get_current_css(); 264 $css->add_rule($rule, $pipeline); 265} 266function attr_body_link_after_styles(&$root, &$pipeline) {}; 267function attr_body_link_after(&$root, &$pipeline) {}; 268 269function attr_body_topmargin_before(&$root, &$pipeline) { 270 $handler =& CSS::get_handler(CSS_MARGIN_TOP); 271 $handler->css((int)$root->get_attribute('topmargin').'px',$pipeline); 272} 273function attr_body_topmargin_after_styles(&$root, &$pipeline) {}; 274function attr_body_topmargin_after(&$root, &$pipeline) {}; 275 276function attr_body_leftmargin_before(&$root, &$pipeline) { 277 $handler =& CSS::get_handler(CSS_MARGIN_LEFT); 278 $handler->css((int)$root->get_attribute('leftmargin').'px',$pipeline); 279} 280function attr_body_leftmargin_after_styles(&$root, &$pipeline) {}; 281function attr_body_leftmargin_after(&$root, &$pipeline) {}; 282 283function attr_body_marginheight_before(&$root, &$pipeline) { 284 $css_state =& $pipeline->get_current_css_state(); 285 286 $h_top =& CSS::get_handler(CSS_MARGIN_TOP); 287 $h_bottom =& CSS::get_handler(CSS_MARGIN_BOTTOM); 288 289 $top = $h_top->get($css_state->getState()); 290 291 $h_bottom->css(((int)$root->get_attribute('marginheight') - $top->value).'px',$pipeline); 292} 293function attr_body_marginheight_after_styles(&$root, &$pipeline) {}; 294function attr_body_marginheight_after(&$root, &$pipeline) {}; 295 296function attr_body_marginwidth_before(&$root, &$pipeline) { 297 $css_state =& $pipeline->get_current_css_state(); 298 299 $h_left =& CSS::get_handler(CSS_MARGIN_LEFT); 300 $h_right =& CSS::get_handler(CSS_MARGIN_RIGHT); 301 302 $left = $h_left->get($css_state->getState()); 303 304 $h_right->css(((int)$root->get_attribute('marginwidth') - $left->value).'px',$pipeline); 305} 306function attr_body_marginwidth_after_styles(&$root, &$pipeline) {}; 307function attr_body_marginwidth_after(&$root, &$pipeline) {}; 308 309// === nowrap 310function attr_nowrap_before(&$root, &$pipeline) { 311 $css_state =& $pipeline->get_current_css_state(); 312 $css_state->set_property(CSS_HTML2PS_NOWRAP, NOWRAP_NOWRAP); 313} 314 315function attr_nowrap_after_styles(&$root, &$pipeline) {} 316function attr_nowrap_after(&$root, &$pipeline) {} 317 318// === hspace 319 320function attr_hspace_before(&$root, &$pipeline) { 321 $handler =& CSS::get_handler(CSS_PADDING_LEFT); 322 $handler->css((int)$root->get_attribute('hspace').'px',$pipeline); 323 $handler =& CSS::get_handler(CSS_PADDING_RIGHT); 324 $handler->css((int)$root->get_attribute('hspace').'px',$pipeline); 325} 326 327function attr_hspace_after_styles(&$root, &$pipeline) {} 328 329function attr_hspace_after(&$root, &$pipeline) {} 330 331// === vspace 332 333function attr_vspace_before(&$root, &$pipeline) { 334 $handler =& CSS::get_handler(CSS_PADDING_TOP); 335 $handler->css((int)$root->get_attribute('vspace').'px',$pipeline); 336 $handler =& CSS::get_handler(CSS_PADDING_BOTTOM); 337 $handler->css((int)$root->get_attribute('vspace').'px',$pipeline); 338} 339 340function attr_vspace_after_styles(&$root, &$pipeline) {} 341function attr_vspace_after(&$root, &$pipeline) {} 342 343// === background 344 345function attr_background_before(&$root, &$pipeline) { 346 $handler =& CSS::get_handler(CSS_BACKGROUND_IMAGE); 347 $handler->css('url('.$root->get_attribute('background').')',$pipeline); 348} 349function attr_background_after_styles(&$root, &$pipeline) {} 350function attr_background_after(&$root, &$pipeline) {} 351 352// === align 353 354function attr_table_float_align_before(&$root, &$pipeline) {} 355function attr_table_float_align_after_styles(&$root, &$pipeline) { 356 if ($root->get_attribute('align') === 'center') { 357 $margin_left =& CSS::get_handler(CSS_MARGIN_LEFT); 358 $margin_left->css('auto',$pipeline); 359 360 $margin_right =& CSS::get_handler(CSS_MARGIN_RIGHT); 361 $margin_right->css('auto',$pipeline); 362 } else { 363 $float =& CSS::get_handler(CSS_FLOAT); 364 $css_state =& $pipeline->get_current_css_state(); 365 $float->replace($float->parse($root->get_attribute('align')), 366 $css_state); 367 }; 368} 369function attr_table_float_align_after(&$root, &$pipeline) {} 370 371function attr_img_align_before(&$root, &$pipeline) { 372 if (preg_match('/left|right/', $root->get_attribute('align'))) { 373 $float =& CSS::get_handler(CSS_FLOAT); 374 $css_state =& $pipeline->get_current_css_state(); 375 $float->replace($float->parse($root->get_attribute('align')), 376 $css_state); 377 } else { 378 $handler =& CSS::get_handler(CSS_VERTICAL_ALIGN); 379 $css_state =& $pipeline->get_current_css_state(); 380 $handler->replace($handler->parse($root->get_attribute('align')), 381 $css_state); 382 }; 383} 384function attr_img_align_after_styles(&$root, &$pipeline) {} 385function attr_img_align_after(&$root, &$pipeline) {} 386 387function attr_self_align_before(&$root, &$pipeline) { 388 $handler =& CSS::get_handler(CSS_HTML2PS_LOCALALIGN); 389 $css_state =& $pipeline->get_current_css_state(); 390 391 switch ($root->get_attribute('align')) { 392 case 'left': 393 $handler->replace(LA_LEFT, 394 $css_state); 395 break; 396 case 'center': 397 $handler->replace(LA_CENTER, 398 $css_state); 399 break; 400 case 'right': 401 $handler->replace(LA_RIGHT, 402 $css_state); 403 break; 404 default: 405 $handler->replace(LA_LEFT, 406 $css_state); 407 break; 408 }; 409} 410 411function attr_self_align_after_styles(&$root, &$pipeline) {} 412function attr_self_align_after(&$root, &$pipeline) {} 413 414// === bordercolor 415 416function attr_table_bordercolor_before(&$root, &$pipeline) { 417 $color = parse_color_declaration($root->get_attribute('bordercolor')); 418 419 $css_state =& $pipeline->get_current_css_state(); 420 $border =& $css_state->get_property(CSS_HTML2PS_TABLE_BORDER); 421 $border =& $border->copy(); 422 423 $border->left->color = $color; 424 $border->right->color = $color; 425 $border->top->color = $color; 426 $border->bottom->color = $color; 427 428// $css_state->pushState(); 429// $css_state->set_property(CSS_HTML2PS_TABLE_BORDER, $border); 430 431// $css_state->pushState(); 432// $css_state->set_property(CSS_BORDER, $border); 433} 434 435function attr_table_bordercolor_after_styles(&$root, &$pipeline) { 436// $css_state =& $pipeline->get_current_css_state(); 437// $css_state->popState(); 438} 439 440function attr_table_bordercolor_after(&$root, &$pipeline) { 441// $css_state =& $pipeline->get_current_css_state(); 442// $css_state->popState(); 443} 444 445// === border 446 447function attr_border_before(&$root, &$pipeline) { 448 $width = (int)$root->get_attribute('border'); 449 450 $css_state =& $pipeline->get_current_css_state(); 451 $border =& $css_state->get_property(CSS_BORDER); 452 $border =& $border->copy(); 453 454 $border->left->width = Value::fromData($width, UNIT_PX); 455 $border->right->width = Value::fromData($width, 'px'); 456 $border->top->width = Value::fromData($width, 'px'); 457 $border->bottom->width = Value::fromData($width, 'px'); 458 459 $border->left->style = BS_SOLID; 460 $border->right->style = BS_SOLID; 461 $border->top->style = BS_SOLID; 462 $border->bottom->style = BS_SOLID; 463 464 $css_state->set_property(CSS_BORDER, $border); 465} 466 467function attr_border_after_styles(&$root, &$pipeline) {} 468function attr_border_after(&$root, &$pipeline) {} 469 470// === rules (table) 471 472function attr_table_rules_before(&$root, &$pipeline) { 473 /** 474 * Handle 'rules' attribute 475 */ 476 $rules = $root->get_attribute('rules'); 477 478 $css_state =& $pipeline->get_current_css_state(); 479 $border = $css_state->get_property(CSS_HTML2PS_TABLE_BORDER); 480 481 switch ($rules) { 482 case 'none': 483 $border->left->style = BS_NONE; 484 $border->right->style = BS_NONE; 485 $border->top->style = BS_NONE; 486 $border->bottom->style = BS_NONE; 487 break; 488 case 'groups': 489 // Not supported 490 break; 491 case 'rows': 492 $border->left->style = BS_NONE; 493 $border->right->style = BS_NONE; 494 break; 495 case 'cols': 496 $border->top->style = BS_NONE; 497 $border->bottom->style = BS_NONE; 498 break; 499 case 'all': 500 break; 501 }; 502 503 $css_state->set_property(CSS_HTML2PS_TABLE_BORDER, $border); 504} 505 506function attr_table_rules_after_styles(&$root, &$pipeline) {} 507function attr_table_rules_after(&$root, &$pipeline) {} 508 509// === border (table) 510 511function attr_table_border_before(&$root, &$pipeline) { 512 $width = (int)$root->get_attribute('border'); 513 514 $css_state =& $pipeline->get_current_css_state(); 515 $border =& $css_state->get_property(CSS_HTML2PS_TABLE_BORDER); 516 $border =& $border->copy(); 517 518 $border->left->width = Value::fromData($width, UNIT_PX); 519 $border->right->width = Value::fromData($width, UNIT_PX); 520 $border->top->width = Value::fromData($width, UNIT_PX); 521 $border->bottom->width = Value::fromData($width, UNIT_PX); 522 523 $border->left->style = BS_SOLID; 524 $border->right->style = BS_SOLID; 525 $border->top->style = BS_SOLID; 526 $border->bottom->style = BS_SOLID; 527 528 $css_state->set_property(CSS_BORDER, $border); 529 530 $css_state->pushState(); 531 $border =& $border->copy(); 532 $css_state->set_property(CSS_HTML2PS_TABLE_BORDER, $border); 533} 534 535function attr_table_border_after_styles(&$root, &$pipeline) {} 536 537function attr_table_border_after(&$root, &$pipeline) { 538 $css_state =& $pipeline->get_current_css_state(); 539 $css_state->popState(); 540} 541 542// === dir 543function attr_dir_before(&$root, &$pipeline) { 544 $handler =& CSS::get_handler(CSS_TEXT_ALIGN); 545 switch (strtolower($root->get_attribute('dir'))) { 546 case 'ltr': 547 $handler->css('left',$pipeline); 548 return; 549 case 'rtl': 550 $handler->css('right',$pipeline); 551 return; 552 }; 553} 554 555function attr_dir_after_styles(&$root, &$pipeline) {} 556function attr_dir_after(&$root, &$pipeline) {} 557 558// === align 559function attr_align_before(&$root, &$pipeline) { 560 $handler =& CSS::get_handler(CSS_TEXT_ALIGN); 561 $handler->css($root->get_attribute('align'),$pipeline); 562 563 $handler =& CSS::get_handler(CSS_HTML2PS_ALIGN); 564 $handler->css($root->get_attribute('align'),$pipeline); 565} 566 567function attr_align_after_styles(&$root, &$pipeline) {} 568 569function attr_align_after(&$root, &$pipeline) {} 570 571// valign 572// 'valign' attribute value for table rows is inherited 573function attr_row_valign_before(&$root, &$pipeline) { 574 $handler =& CSS::get_handler(CSS_VERTICAL_ALIGN); 575 $handler->css($root->get_attribute('valign'),$pipeline); 576} 577function attr_row_valign_after_styles(&$root, &$pipeline) {} 578function attr_row_valign_after(&$root, &$pipeline) {} 579 580// 'valign' attribute value for boxes other than table rows is not inherited 581function attr_valign_before(&$root, &$pipeline) { 582 $handler =& CSS::get_handler(CSS_VERTICAL_ALIGN); 583 $handler->css($root->get_attribute('valign'), 584 $pipeline); 585} 586 587function attr_valign_after_styles(&$root, &$pipeline) {} 588function attr_valign_after(&$root, &$pipeline) {} 589 590// bgcolor 591 592function attr_bgcolor_before(&$root, &$pipeline) { 593 $handler =& CSS::get_handler(CSS_BACKGROUND_COLOR); 594 $handler->css($root->get_attribute('bgcolor'), $pipeline); 595} 596function attr_bgcolor_after_styles(&$root, &$pipeline) {} 597function attr_bgcolor_after(&$root, &$pipeline) {} 598 599// width 600 601function attr_width_before(&$root, &$pipeline) { 602 $width =& CSS::get_handler(CSS_WIDTH); 603 604 $value = $root->get_attribute('width'); 605 if (preg_match('/^\d+$/', $value)) { $value .= 'px'; }; 606 607 $width->css($value,$pipeline); 608} 609 610function attr_width_after_styles(&$root, &$pipeline) {} 611function attr_width_after(&$root, &$pipeline) {} 612 613// height 614 615// Difference between 'attr_height' and 'attr_height_required': 616// attr_height sets the minimal box height so that is cal be expanded by it content; 617// a good example is table rows and cells; on the other side, attr_height_required 618// sets the fixed box height - it is useful for boxes which content height can be greater 619// that box height - marquee or iframe, for example 620 621function attr_height_required_before(&$root, &$pipeline) { 622 $handler =& CSS::get_handler(CSS_HEIGHT); 623 624 $value = $root->get_attribute('height'); 625 if (preg_match('/^\d+$/', $value)) { $value .= 'px'; }; 626 $handler->css($value,$pipeline); 627} 628 629function attr_height_required_after_styles(&$root, &$pipeline) {} 630 631function attr_height_required_after(&$root, &$pipeline) {} 632 633function attr_height_before(&$root, &$pipeline) { 634 $handler =& CSS::get_handler(CSS_MIN_HEIGHT); 635 636 $value = $root->get_attribute('height'); 637 if (preg_match('/^\d+$/', $value)) { $value .= 'px'; }; 638 $handler->css($value,$pipeline); 639} 640 641function attr_height_after_styles(&$root, &$pipeline) {} 642function attr_height_after(&$root, &$pipeline) {} 643 644// FONT attributes 645function attr_font_size_before(&$root, &$pipeline) { 646 $size = $root->get_attribute('size'); 647 648 /** 649 * Check if attribute value is empty; no actions will be taken in this case 650 */ 651 if ($size == '') { return; }; 652 653 if ($size{0} == '-') { 654 $koeff = 1; 655 $repeats = (int)substr($size,1); 656 for ($i=0; $i<$repeats; $i++) { 657 $koeff *= 1/1.2; 658 }; 659 $newsize = sprintf('%.2fem', round($koeff, 2)); 660 } else if ($size{0} == '+') { 661 $koeff = 1; 662 $repeats = (int)substr($size,1); 663 for ($i=0; $i<$repeats; $i++) { 664 $koeff *= 1.2; 665 }; 666 $newsize = sprintf('%.2fem', round($koeff, 2)); 667 } else { 668 switch ((int)$size) { 669 case 1: 670 $newsize = BASE_FONT_SIZE_PT/1.2/1.2; 671 break; 672 case 2: 673 $newsize = BASE_FONT_SIZE_PT/1.2; 674 break; 675 case 3: 676 $newsize = BASE_FONT_SIZE_PT; 677 break; 678 case 4: 679 $newsize = BASE_FONT_SIZE_PT*1.2; 680 break; 681 case 5: 682 $newsize = BASE_FONT_SIZE_PT*1.2*1.2; 683 break; 684 case 6: 685 $newsize = BASE_FONT_SIZE_PT*1.2*1.2*1.2; 686 break; 687 case 7: 688 $newsize = BASE_FONT_SIZE_PT*1.2*1.2*1.2*1.2; 689 break; 690 default: 691 $newsize = BASE_FONT_SIZE_PT; 692 break; 693 }; 694 $newsize = $newsize . 'pt'; 695 }; 696 697 $handler =& CSS::get_handler(CSS_FONT_SIZE); 698 $handler->css($newsize, $pipeline); 699} 700function attr_font_size_after_styles(&$root, &$pipeline) {} 701function attr_font_size_after(&$root, &$pipeline) {} 702 703function attr_font_color_before(&$root, &$pipeline) { 704 $handler =& CSS::get_handler(CSS_COLOR); 705 $handler->css($root->get_attribute('color'),$pipeline); 706} 707function attr_font_color_after_styles(&$root, &$pipeline) {} 708function attr_font_color_after(&$root, &$pipeline) {} 709 710function attr_font_face_before(&$root, &$pipeline) { 711 $handler =& CSS::get_handler(CSS_FONT_FAMILY); 712 $handler->css($root->get_attribute('face'), $pipeline); 713} 714function attr_font_face_after_styles(&$root, &$pipeline) {} 715function attr_font_face_after(&$root, &$pipeline) {} 716 717function attr_form_action_before(&$root, &$pipeline) { 718 $handler =& CSS::get_handler(CSS_HTML2PS_FORM_ACTION); 719 if ($root->has_attribute('action')) { 720 $handler->css($pipeline->guess_url($root->get_attribute('action')),$pipeline); 721 } else { 722 $handler->css(null,$pipeline); 723 }; 724} 725function attr_form_action_after_styles(&$root, &$pipeline) {} 726function attr_form_action_after(&$root, &$pipeline) {} 727 728function attr_input_name_before(&$root, &$pipeline) { 729 $handler =& CSS::get_handler(CSS_HTML2PS_FORM_RADIOGROUP); 730 if ($root->has_attribute('name')) { 731 $handler->css($root->get_attribute('name'),$pipeline); 732 }; 733} 734function attr_input_name_after_styles(&$root, &$pipeline) {} 735function attr_input_name_after(&$root, &$pipeline) {} 736 737function attr_input_size_before(&$root, &$pipeline) { 738 // Check if current node has 'size' attribute 739 if (!$root->has_attribute('size')) { 740 return; 741 }; 742 $size = $root->get_attribute('size'); 743 744 // Get the exact type of the input node, as 'size' has 745 // different meanings for different input types 746 $type = 'text'; 747 if ($root->has_attribute('type')) { 748 $type = strtolower($root->get_attribute('type')); 749 }; 750 751 switch ($type) { 752 case 'text': 753 case 'password': 754 $handler =& CSS::get_handler(CSS_WIDTH); 755 $width = sprintf('%.2fem', INPUT_SIZE_BASE_EM + $size*INPUT_SIZE_EM_KOEFF); 756 $handler->css($width, $pipeline); 757 break; 758 }; 759}; 760 761function attr_input_size_after_styles(&$root, &$pipeline) {} 762function attr_input_size_after(&$root, &$pipeline) {} 763 764// TABLE 765 766function attr_cellspacing_before(&$root, &$pipeline) { 767 $css_state =& $pipeline->get_current_css_state(); 768 $handler =& CSS::get_handler(CSS_HTML2PS_CELLSPACING); 769 $handler->replace(Value::fromData((int)$root->get_attribute('cellspacing'), UNIT_PX), 770 $css_state); 771} 772function attr_cellspacing_after_styles(&$root, &$pipeline) {} 773function attr_cellspacing_after(&$root, &$pipeline) {} 774 775function attr_cellpadding_before(&$root, &$pipeline) { 776 $css_state =& $pipeline->get_current_css_state(); 777 $handler =& CSS::get_handler(CSS_HTML2PS_CELLPADDING); 778 $handler->replace(Value::fromData((int)$root->get_attribute('cellpadding'), UNIT_PX), 779 $css_state); 780} 781function attr_cellpadding_after_styles(&$root, &$pipeline) {} 782function attr_cellpadding_after(&$root, &$pipeline) {} 783 784// UL/OL 'start' attribute 785function attr_start_before(&$root, &$pipeline) { 786 $handler =& CSS::get_handler(CSS_HTML2PS_LIST_COUNTER); 787 $css_state =& $pipeline->get_current_css_state(); 788 $handler->replace((int)$root->get_attribute('start'), 789 $css_state); 790} 791function attr_start_after_styles(&$root, &$pipeline) {} 792function attr_start_after(&$root, &$pipeline) {} 793 794// UL 'type' attribute 795// 796// For the UL element, possible values for the type attribute are 797// disc, square, and circle. The default value depends on the level of 798// nesting of the current list. These values are case-insensitive. 799// 800// How each value is presented depends on the user agent. User agents 801// should attempt to present a "disc" as a small filled-in circle, a 802// "circle" as a small circle outline, and a "square" as a small 803// square outline. 804// 805function attr_ul_type_before(&$root, &$pipeline) { 806 $type = (string)$root->get_attribute('type'); 807 $handler =& CSS::get_handler(CSS_LIST_STYLE_TYPE); 808 $css_state =& $pipeline->get_current_css_state(); 809 810 switch (strtolower($type)) { 811 case 'disc': 812 $handler->replace(LST_DISC, $css_state); 813 break; 814 case 'circle': 815 $handler->replace(LST_CIRCLE, $css_state); 816 break; 817 case 'square': 818 $handler->replace(LST_SQUARE, $css_state); 819 break; 820 }; 821} 822function attr_ul_type_after_styles(&$root, &$pipeline) {} 823function attr_ul_type_after(&$root, &$pipeline) {} 824 825// OL 'type' attribute 826// 827// For the OL element, possible values for the type attribute are summarized in the table below (they are case-sensitive): 828// Type Numbering style 829// 1 arabic numbers 1, 2, 3, ... 830// a lower alpha a, b, c, ... 831// A upper alpha A, B, C, ... 832// i lower roman i, ii, iii, ... 833// I upper roman I, II, III, ... 834// 835function attr_ol_type_before(&$root, &$pipeline) { 836 $type = (string)$root->get_attribute('type'); 837 $handler =& CSS::get_handler(CSS_LIST_STYLE_TYPE); 838 $css_state =& $pipeline->get_current_css_state(); 839 840 switch ($type) { 841 case '1': 842 $handler->replace(LST_DECIMAL, $css_state); 843 break; 844 case 'a': 845 $handler->replace(LST_LOWER_LATIN, $css_state); 846 break; 847 case 'A': 848 $handler->replace(LST_UPPER_LATIN, $css_state); 849 break; 850 case 'i': 851 $handler->replace(LST_LOWER_ROMAN, $css_state); 852 break; 853 case 'I': 854 $handler->replace(LST_UPPER_ROMAN, $css_state); 855 break; 856 }; 857} 858function attr_ol_type_after_styles(&$root, &$pipeline) {} 859function attr_ol_type_after(&$root, &$pipeline) {} 860 861// Textarea 862 863function attr_textarea_rows_before(&$root, &$pipeline) { 864 $handler =& CSS::get_handler(CSS_HEIGHT); 865 $handler->css(sprintf('%dem', (int)$root->get_attribute('rows')*1.40),$pipeline); 866} 867function attr_textarea_rows_after_styles(&$root, &$pipeline) {} 868function attr_textarea_rows_after(&$root, &$pipeline) {} 869 870function attr_textarea_cols_before(&$root, &$pipeline) { 871 $handler =& CSS::get_handler(CSS_WIDTH); 872 $handler->css(sprintf('%dem', (int)$root->get_attribute('cols')*0.675),$pipeline); 873} 874function attr_textarea_cols_after_styles(&$root, &$pipeline) {} 875function attr_textarea_cols_after(&$root, &$pipeline) {} 876 877/** 878 * HR-specific attributes 879 */ 880function attr_hr_color_before(&$root, &$pipeline) { 881 $handler =& CSS::get_handler(CSS_BORDER_COLOR); 882 $handler->css($root->get_attribute('color'), $pipeline); 883} 884function attr_hr_color_after_styles(&$root, &$pipeline) {} 885function attr_hr_color_after(&$root, &$pipeline) {} 886 887 888?>