[3019] | 1 | <?php
|
---|
| 2 | /**
|
---|
| 3 | * DOMPDF - PHP5 HTML to PDF renderer
|
---|
| 4 | *
|
---|
| 5 | * File: $RCSfile: style.cls.php,v $
|
---|
| 6 | * Created on: 2004-06-01
|
---|
| 7 | *
|
---|
| 8 | * Copyright (c) 2004 - Benj Carson <benjcarson@digitaljunkies.ca>
|
---|
| 9 | *
|
---|
| 10 | * This library is free software; you can redistribute it and/or
|
---|
| 11 | * modify it under the terms of the GNU Lesser General Public
|
---|
| 12 | * License as published by the Free Software Foundation; either
|
---|
| 13 | * version 2.1 of the License, or (at your option) any later version.
|
---|
| 14 | *
|
---|
| 15 | * This library is distributed in the hope that it will be useful,
|
---|
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 18 | * Lesser General Public License for more details.
|
---|
| 19 | *
|
---|
| 20 | * You should have received a copy of the GNU Lesser General Public License
|
---|
| 21 | * along with this library in the file LICENSE.LGPL; if not, write to the
|
---|
| 22 | * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
---|
| 23 | * 02111-1307 USA
|
---|
| 24 | *
|
---|
| 25 | * Alternatively, you may distribute this software under the terms of the
|
---|
| 26 | * PHP License, version 3.0 or later. A copy of this license should have
|
---|
| 27 | * been distributed with this file in the file LICENSE.PHP . If this is not
|
---|
| 28 | * the case, you can obtain a copy at http://www.php.net/license/3_0.txt.
|
---|
| 29 | *
|
---|
| 30 | * The latest version of DOMPDF might be available at:
|
---|
| 31 | * http://www.digitaljunkies.ca/dompdf
|
---|
| 32 | *
|
---|
| 33 | * @link http://www.digitaljunkies.ca/dompdf
|
---|
| 34 | * @copyright 2004 Benj Carson
|
---|
| 35 | * @author Benj Carson <benjcarson@digitaljunkies.ca>
|
---|
| 36 | * @contributor Helmut Tischer <htischer@weihenstephan.org>
|
---|
| 37 | * @package dompdf
|
---|
| 38 | * @version 0.5.1
|
---|
| 39 | *
|
---|
| 40 | * Changes
|
---|
| 41 | * @contributor Helmut Tischer <htischer@weihenstephan.org>
|
---|
| 42 | * @version 0.5.1.htischer.20090507
|
---|
| 43 | * - Fix px to pt conversion according to DOMPDF_DPI
|
---|
| 44 | * - Recognize css styles with !important attribute, and store !important attribute within style
|
---|
| 45 | * - Propagate !important by inherit and sequences of styles with merge.
|
---|
| 46 | * - Add missing style property cache flushes for consistent rendering, e.g. on explicte assignments
|
---|
| 47 | * - Add important set/get for access from outside of class
|
---|
| 48 | * - Fix font_family search path with multiple fonts list in css attribute:
|
---|
| 49 | * On missing font, do not immediately fall back to default font,
|
---|
| 50 | * but try subsequent fonts in search chain. Only when none found, explicitely
|
---|
| 51 | * refer to default font.
|
---|
| 52 | * - Allow read of background individual properties
|
---|
| 53 | * - Add support for individual styles background-position, background-attachment, background-repeat
|
---|
| 54 | * - Complete style components of list-style
|
---|
| 55 | * - Add support for combined styles in addition to individual styles
|
---|
| 56 | * like {border: red 1px solid;}, { border-width: 1px;}, { border-right-color: red; } ...
|
---|
| 57 | * for font, background
|
---|
| 58 | * - Propagate attributes including !important from combined style to individual component
|
---|
| 59 | * for border, background, padding, margin, font, list_style
|
---|
| 60 | * - Refactor common code of border, background, padding, margin, font, list_style
|
---|
| 61 | * - Refactor common code of list-style-image and background-image
|
---|
| 62 | * - special treatment of css images "none" instead of url(...), otherwise would prepend string "none" with path name
|
---|
| 63 | * - Added comments
|
---|
| 64 | * - Added debug output
|
---|
| 65 | * @contributor Helmut Tischer <htischer@weihenstephan.org>
|
---|
| 66 | * @version dompdf_trunk_with_helmut_mods.20090524
|
---|
| 67 | * - Allow superflous white space and string delimiter in font search path.
|
---|
| 68 | * - Restore lost change of default font of above
|
---|
| 69 | * @version 20090610
|
---|
| 70 | * - Allow absolute path from web server root as html image reference
|
---|
| 71 | * - More accurate handling of css property cache consistency
|
---|
| 72 | */
|
---|
| 73 |
|
---|
| 74 | /* $Id: style.cls.php 186 2009-10-19 22:42:06Z eclecticgeek@gmail.com $ */
|
---|
| 75 |
|
---|
| 76 | /**
|
---|
| 77 | * Represents CSS properties.
|
---|
| 78 | *
|
---|
| 79 | * The Style class is responsible for handling and storing CSS properties.
|
---|
| 80 | * It includes methods to resolve colours and lengths, as well as getters &
|
---|
| 81 | * setters for many CSS properites.
|
---|
| 82 | *
|
---|
| 83 | * Actual CSS parsing is performed in the {@link Stylesheet} class.
|
---|
| 84 | *
|
---|
| 85 | * @package dompdf
|
---|
| 86 | */
|
---|
| 87 | class Style {
|
---|
| 88 |
|
---|
| 89 | /**
|
---|
| 90 | * Default font size, in points.
|
---|
| 91 | *
|
---|
| 92 | * @var float
|
---|
| 93 | */
|
---|
| 94 | static $default_font_size = 12;
|
---|
| 95 |
|
---|
| 96 | /**
|
---|
| 97 | * Default line height, as a fraction of the font size.
|
---|
| 98 | *
|
---|
| 99 | * @var float
|
---|
| 100 | */
|
---|
| 101 | static $default_line_height = 1.2;
|
---|
| 102 |
|
---|
| 103 | /**
|
---|
| 104 | * List of all inline types. Should really be a constant.
|
---|
| 105 | *
|
---|
| 106 | * @var array
|
---|
| 107 | */
|
---|
| 108 | static $INLINE_TYPES = array("inline");
|
---|
| 109 |
|
---|
| 110 | /**
|
---|
| 111 | * List of all block types. Should really be a constant.
|
---|
| 112 | *
|
---|
| 113 | * @var array
|
---|
| 114 | */
|
---|
| 115 | static $BLOCK_TYPES = array("block","inline-block", "table-cell", "list-item");
|
---|
| 116 |
|
---|
| 117 | /**
|
---|
| 118 | * List of all table types. Should really be a constant.
|
---|
| 119 | *
|
---|
| 120 | * @var array;
|
---|
| 121 | */
|
---|
| 122 | static $TABLE_TYPES = array("table", "inline-table");
|
---|
| 123 |
|
---|
| 124 | /**
|
---|
| 125 | * List of valid border styles. Should also really be a constant.
|
---|
| 126 | *
|
---|
| 127 | * @var array
|
---|
| 128 | */
|
---|
| 129 | static $BORDER_STYLES = array("none", "hidden", "dotted", "dashed", "solid",
|
---|
| 130 | "double", "groove", "ridge", "inset", "outset");
|
---|
| 131 |
|
---|
| 132 | /**
|
---|
| 133 | * Default style values.
|
---|
| 134 | *
|
---|
| 135 | * @link http://www.w3.org/TR/CSS21/propidx.html
|
---|
| 136 | *
|
---|
| 137 | * @var array
|
---|
| 138 | */
|
---|
| 139 | static protected $_defaults = null;
|
---|
| 140 |
|
---|
| 141 | /**
|
---|
| 142 | * List of inherited properties
|
---|
| 143 | *
|
---|
| 144 | * @link http://www.w3.org/TR/CSS21/propidx.html
|
---|
| 145 | *
|
---|
| 146 | * @var array
|
---|
| 147 | */
|
---|
| 148 | static protected $_inherited = null;
|
---|
| 149 |
|
---|
| 150 | /**
|
---|
| 151 | * The stylesheet this style belongs to
|
---|
| 152 | *
|
---|
| 153 | * @see Stylesheet
|
---|
| 154 | * @var Stylesheet
|
---|
| 155 | */
|
---|
| 156 | protected $_stylesheet; // stylesheet this style is attached to
|
---|
| 157 |
|
---|
| 158 | /**
|
---|
| 159 | * Main array of all CSS properties & values
|
---|
| 160 | *
|
---|
| 161 | * @var array
|
---|
| 162 | */
|
---|
| 163 | protected $_props;
|
---|
| 164 |
|
---|
| 165 | /* var instead of protected would allow access outside of class */
|
---|
| 166 | protected $_important_props;
|
---|
| 167 |
|
---|
| 168 | /**
|
---|
| 169 | * Cached property values
|
---|
| 170 | *
|
---|
| 171 | * @var array
|
---|
| 172 | */
|
---|
| 173 | protected $_prop_cache;
|
---|
| 174 |
|
---|
| 175 | /**
|
---|
| 176 | * Font size of parent element in document tree. Used for relative font
|
---|
| 177 | * size resolution.
|
---|
| 178 | *
|
---|
| 179 | * @var float
|
---|
| 180 | */
|
---|
| 181 | protected $_parent_font_size; // Font size of parent element
|
---|
| 182 |
|
---|
| 183 | // private members
|
---|
| 184 | /**
|
---|
| 185 | * True once the font size is resolved absolutely
|
---|
| 186 | *
|
---|
| 187 | * @var bool
|
---|
| 188 | */
|
---|
| 189 | private $__font_size_calculated; // Cache flag
|
---|
| 190 |
|
---|
| 191 | /**
|
---|
| 192 | * Class constructor
|
---|
| 193 | *
|
---|
| 194 | * @param Stylesheet $stylesheet the stylesheet this Style is associated with.
|
---|
| 195 | */
|
---|
| 196 | function __construct(Stylesheet $stylesheet) {
|
---|
| 197 | $this->_props = array();
|
---|
| 198 | $this->_important_props = array();
|
---|
| 199 | $this->_stylesheet = $stylesheet;
|
---|
| 200 | $this->_parent_font_size = null;
|
---|
| 201 | $this->__font_size_calculated = false;
|
---|
| 202 |
|
---|
| 203 | if ( !isset(self::$_defaults) ) {
|
---|
| 204 |
|
---|
| 205 | // Shorthand
|
---|
| 206 | $d =& self::$_defaults;
|
---|
| 207 |
|
---|
| 208 | // All CSS 2.1 properties, and their default values
|
---|
| 209 | $d["azimuth"] = "center";
|
---|
| 210 | $d["background_attachment"] = "scroll";
|
---|
| 211 | $d["background_color"] = "transparent";
|
---|
| 212 | $d["background_image"] = "none";
|
---|
| 213 | $d["background_position"] = "0% 0%";
|
---|
| 214 | $d["background_repeat"] = "repeat";
|
---|
| 215 | $d["background"] = "";
|
---|
| 216 | $d["border_collapse"] = "separate";
|
---|
| 217 | $d["border_color"] = "";
|
---|
| 218 | $d["border_spacing"] = "0";
|
---|
| 219 | $d["border_style"] = "";
|
---|
| 220 | $d["border_top"] = "";
|
---|
| 221 | $d["border_right"] = "";
|
---|
| 222 | $d["border_bottom"] = "";
|
---|
| 223 | $d["border_left"] = "";
|
---|
| 224 | $d["border_top_color"] = "";
|
---|
| 225 | $d["border_right_color"] = "";
|
---|
| 226 | $d["border_bottom_color"] = "";
|
---|
| 227 | $d["border_left_color"] = "";
|
---|
| 228 | $d["border_top_style"] = "none";
|
---|
| 229 | $d["border_right_style"] = "none";
|
---|
| 230 | $d["border_bottom_style"] = "none";
|
---|
| 231 | $d["border_left_style"] = "none";
|
---|
| 232 | $d["border_top_width"] = "medium";
|
---|
| 233 | $d["border_right_width"] = "medium";
|
---|
| 234 | $d["border_bottom_width"] = "medium";
|
---|
| 235 | $d["border_left_width"] = "medium";
|
---|
| 236 | $d["border_width"] = "medium";
|
---|
| 237 | $d["border"] = "";
|
---|
| 238 | $d["bottom"] = "auto";
|
---|
| 239 | $d["caption_side"] = "top";
|
---|
| 240 | $d["clear"] = "none";
|
---|
| 241 | $d["clip"] = "auto";
|
---|
| 242 | $d["color"] = "#000000";
|
---|
| 243 | $d["content"] = "normal";
|
---|
| 244 | $d["counter_increment"] = "none";
|
---|
| 245 | $d["counter_reset"] = "none";
|
---|
| 246 | $d["cue_after"] = "none";
|
---|
| 247 | $d["cue_before"] = "none";
|
---|
| 248 | $d["cue"] = "";
|
---|
| 249 | $d["cursor"] = "auto";
|
---|
| 250 | $d["direction"] = "ltr";
|
---|
| 251 | $d["display"] = "inline";
|
---|
| 252 | $d["elevation"] = "level";
|
---|
| 253 | $d["empty_cells"] = "show";
|
---|
| 254 | $d["float"] = "none";
|
---|
| 255 | $d["font_family"] = "serif";
|
---|
| 256 | $d["font_size"] = "medium";
|
---|
| 257 | $d["font_style"] = "normal";
|
---|
| 258 | $d["font_variant"] = "normal";
|
---|
| 259 | $d["font_weight"] = "normal";
|
---|
| 260 | $d["font"] = "";
|
---|
| 261 | $d["height"] = "auto";
|
---|
| 262 | $d["left"] = "auto";
|
---|
| 263 | $d["letter_spacing"] = "normal";
|
---|
| 264 | $d["line_height"] = "normal";
|
---|
| 265 | $d["list_style_image"] = "none";
|
---|
| 266 | $d["list_style_position"] = "outside";
|
---|
| 267 | $d["list_style_type"] = "disc";
|
---|
| 268 | $d["list_style"] = "";
|
---|
| 269 | $d["margin_right"] = "0";
|
---|
| 270 | $d["margin_left"] = "0";
|
---|
| 271 | $d["margin_top"] = "0";
|
---|
| 272 | $d["margin_bottom"] = "0";
|
---|
| 273 | $d["margin"] = "";
|
---|
| 274 | $d["max_height"] = "none";
|
---|
| 275 | $d["max_width"] = "none";
|
---|
| 276 | $d["min_height"] = "0";
|
---|
| 277 | $d["min_width"] = "0";
|
---|
| 278 | $d["orphans"] = "2";
|
---|
| 279 | $d["outline_color"] = "invert";
|
---|
| 280 | $d["outline_style"] = "none";
|
---|
| 281 | $d["outline_width"] = "medium";
|
---|
| 282 | $d["outline"] = "";
|
---|
| 283 | $d["overflow"] = "visible";
|
---|
| 284 | $d["padding_top"] = "0";
|
---|
| 285 | $d["padding_right"] = "0";
|
---|
| 286 | $d["padding_bottom"] = "0";
|
---|
| 287 | $d["padding_left"] = "0";
|
---|
| 288 | $d["padding"] = "";
|
---|
| 289 | $d["page_break_after"] = "auto";
|
---|
| 290 | $d["page_break_before"] = "auto";
|
---|
| 291 | $d["page_break_inside"] = "auto";
|
---|
| 292 | $d["pause_after"] = "0";
|
---|
| 293 | $d["pause_before"] = "0";
|
---|
| 294 | $d["pause"] = "";
|
---|
| 295 | $d["pitch_range"] = "50";
|
---|
| 296 | $d["pitch"] = "medium";
|
---|
| 297 | $d["play_during"] = "auto";
|
---|
| 298 | $d["position"] = "static";
|
---|
| 299 | $d["quotes"] = "";
|
---|
| 300 | $d["richness"] = "50";
|
---|
| 301 | $d["right"] = "auto";
|
---|
| 302 | $d["speak_header"] = "once";
|
---|
| 303 | $d["speak_numeral"] = "continuous";
|
---|
| 304 | $d["speak_punctuation"] = "none";
|
---|
| 305 | $d["speak"] = "normal";
|
---|
| 306 | $d["speech_rate"] = "medium";
|
---|
| 307 | $d["stress"] = "50";
|
---|
| 308 | $d["table_layout"] = "auto";
|
---|
| 309 | $d["text_align"] = "left";
|
---|
| 310 | $d["text_decoration"] = "none";
|
---|
| 311 | $d["text_indent"] = "0";
|
---|
| 312 | $d["text_transform"] = "none";
|
---|
| 313 | $d["top"] = "auto";
|
---|
| 314 | $d["unicode_bidi"] = "normal";
|
---|
| 315 | $d["vertical_align"] = "baseline";
|
---|
| 316 | $d["visibility"] = "visible";
|
---|
| 317 | $d["voice_family"] = "";
|
---|
| 318 | $d["volume"] = "medium";
|
---|
| 319 | $d["white_space"] = "normal";
|
---|
| 320 | $d["widows"] = "2";
|
---|
| 321 | $d["width"] = "auto";
|
---|
| 322 | $d["word_spacing"] = "normal";
|
---|
| 323 | $d["z_index"] = "auto";
|
---|
| 324 |
|
---|
| 325 | // Properties that inherit by default
|
---|
| 326 | self::$_inherited = array("azimuth",
|
---|
| 327 | "border_collapse",
|
---|
| 328 | "border_spacing",
|
---|
| 329 | "caption_side",
|
---|
| 330 | "color",
|
---|
| 331 | "cursor",
|
---|
| 332 | "direction",
|
---|
| 333 | "elevation",
|
---|
| 334 | "empty_cells",
|
---|
| 335 | "font_family",
|
---|
| 336 | "font_size",
|
---|
| 337 | "font_style",
|
---|
| 338 | "font_variant",
|
---|
| 339 | "font_weight",
|
---|
| 340 | "font",
|
---|
| 341 | "letter_spacing",
|
---|
| 342 | "line_height",
|
---|
| 343 | "list_style_image",
|
---|
| 344 | "list_style_position",
|
---|
| 345 | "list_style_type",
|
---|
| 346 | "list_style",
|
---|
| 347 | "orphans",
|
---|
| 348 | "page_break_inside",
|
---|
| 349 | "pitch_range",
|
---|
| 350 | "pitch",
|
---|
| 351 | "quotes",
|
---|
| 352 | "richness",
|
---|
| 353 | "speak_header",
|
---|
| 354 | "speak_numeral",
|
---|
| 355 | "speak_punctuation",
|
---|
| 356 | "speak",
|
---|
| 357 | "speech_rate",
|
---|
| 358 | "stress",
|
---|
| 359 | "text_align",
|
---|
| 360 | "text_indent",
|
---|
| 361 | "text_transform",
|
---|
| 362 | "visibility",
|
---|
| 363 | "voice_family",
|
---|
| 364 | "volume",
|
---|
| 365 | "white_space",
|
---|
| 366 | "widows",
|
---|
| 367 | "word_spacing");
|
---|
| 368 | }
|
---|
| 369 |
|
---|
| 370 | }
|
---|
| 371 |
|
---|
| 372 | /**
|
---|
| 373 | * "Destructor": forcibly free all references held by this object
|
---|
| 374 | */
|
---|
| 375 | function dispose() {
|
---|
| 376 | unset($this->_stylesheet);
|
---|
| 377 | }
|
---|
| 378 |
|
---|
| 379 | /**
|
---|
| 380 | * returns the {@link Stylesheet} this Style is associated with.
|
---|
| 381 | *
|
---|
| 382 | * @return Stylesheet
|
---|
| 383 | */
|
---|
| 384 | function get_stylesheet() { return $this->_stylesheet; }
|
---|
| 385 |
|
---|
| 386 | /**
|
---|
| 387 | * Converts any CSS length value into an absolute length in points.
|
---|
| 388 | *
|
---|
| 389 | * length_in_pt() takes a single length (e.g. '1em') or an array of
|
---|
| 390 | * lengths and returns an absolute length. If an array is passed, then
|
---|
| 391 | * the return value is the sum of all elements.
|
---|
| 392 | *
|
---|
| 393 | * If a reference size is not provided, the default font size is used
|
---|
| 394 | * ({@link Style::$default_font_size}).
|
---|
| 395 | *
|
---|
| 396 | * @param float|array $length the length or array of lengths to resolve
|
---|
| 397 | * @param float $ref_size an absolute reference size to resolve percentage lengths
|
---|
| 398 | * @return float
|
---|
| 399 | */
|
---|
| 400 | function length_in_pt($length, $ref_size = null) {
|
---|
| 401 |
|
---|
| 402 | if ( !is_array($length) )
|
---|
| 403 | $length = array($length);
|
---|
| 404 |
|
---|
| 405 | if ( !isset($ref_size) )
|
---|
| 406 | $ref_size = self::$default_font_size;
|
---|
| 407 |
|
---|
| 408 | $ret = 0;
|
---|
| 409 | foreach ($length as $l) {
|
---|
| 410 |
|
---|
| 411 | if ( $l === "auto" )
|
---|
| 412 | return "auto";
|
---|
| 413 |
|
---|
| 414 | if ( $l === "none" )
|
---|
| 415 | return "none";
|
---|
| 416 |
|
---|
| 417 | // Assume numeric values are already in points
|
---|
| 418 | if ( is_numeric($l) ) {
|
---|
| 419 | $ret += $l;
|
---|
| 420 | continue;
|
---|
| 421 | }
|
---|
| 422 |
|
---|
| 423 | if ( $l === "normal" ) {
|
---|
| 424 | $ret += $ref_size;
|
---|
| 425 | continue;
|
---|
| 426 | }
|
---|
| 427 |
|
---|
| 428 | // Border lengths
|
---|
| 429 | if ( $l === "thin" ) {
|
---|
| 430 | $ret += 0.5;
|
---|
| 431 | continue;
|
---|
| 432 | }
|
---|
| 433 |
|
---|
| 434 | if ( $l === "medium" ) {
|
---|
| 435 | $ret += 1.5;
|
---|
| 436 | continue;
|
---|
| 437 | }
|
---|
| 438 |
|
---|
| 439 | if ( $l === "thick" ) {
|
---|
| 440 | $ret += 2.5;
|
---|
| 441 | continue;
|
---|
| 442 | }
|
---|
| 443 |
|
---|
| 444 | if ( ($i = mb_strpos($l, "pt")) !== false ) {
|
---|
| 445 | $ret += mb_substr($l, 0, $i);
|
---|
| 446 | continue;
|
---|
| 447 | }
|
---|
| 448 |
|
---|
| 449 | if ( ($i = mb_strpos($l, "px")) !== false ) {
|
---|
| 450 | $ret += ( mb_substr($l, 0, $i) * 72 ) / DOMPDF_DPI;
|
---|
| 451 | continue;
|
---|
| 452 | }
|
---|
| 453 |
|
---|
| 454 | if ( ($i = mb_strpos($l, "em")) !== false ) {
|
---|
| 455 | $ret += mb_substr($l, 0, $i) * $this->__get("font_size");
|
---|
| 456 | continue;
|
---|
| 457 | }
|
---|
| 458 |
|
---|
| 459 | // FIXME: em:ex ratio?
|
---|
| 460 | if ( ($i = mb_strpos($l, "ex")) !== false ) {
|
---|
| 461 | $ret += mb_substr($l, 0, $i) * $this->__get("font_size");
|
---|
| 462 | continue;
|
---|
| 463 | }
|
---|
| 464 |
|
---|
| 465 | if ( ($i = mb_strpos($l, "%")) !== false ) {
|
---|
| 466 | $ret += mb_substr($l, 0, $i)/100 * $ref_size;
|
---|
| 467 | continue;
|
---|
| 468 | }
|
---|
| 469 |
|
---|
| 470 | if ( ($i = mb_strpos($l, "in")) !== false ) {
|
---|
| 471 | $ret += mb_substr($l, 0, $i) * 72;
|
---|
| 472 | continue;
|
---|
| 473 | }
|
---|
| 474 |
|
---|
| 475 | if ( ($i = mb_strpos($l, "cm")) !== false ) {
|
---|
| 476 | $ret += mb_substr($l, 0, $i) * 72 / 2.54;
|
---|
| 477 | continue;
|
---|
| 478 | }
|
---|
| 479 |
|
---|
| 480 | if ( ($i = mb_strpos($l, "mm")) !== false ) {
|
---|
| 481 | $ret += mb_substr($l, 0, $i) * 72 / 25.4;
|
---|
| 482 | continue;
|
---|
| 483 | }
|
---|
| 484 |
|
---|
| 485 | if ( ($i = mb_strpos($l, "pc")) !== false ) {
|
---|
| 486 | $ret += mb_substr($l, 0, $i) / 12;
|
---|
| 487 | continue;
|
---|
| 488 | }
|
---|
| 489 |
|
---|
| 490 | // Bogus value
|
---|
| 491 | $ret += $ref_size;
|
---|
| 492 | }
|
---|
| 493 |
|
---|
| 494 | return $ret;
|
---|
| 495 | }
|
---|
| 496 |
|
---|
| 497 |
|
---|
| 498 | /**
|
---|
| 499 | * Set inherited properties in this style using values in $parent
|
---|
| 500 | *
|
---|
| 501 | * @param Style $parent
|
---|
| 502 | */
|
---|
| 503 | function inherit(Style $parent) {
|
---|
| 504 |
|
---|
| 505 | // Set parent font size
|
---|
| 506 | $this->_parent_font_size = $parent->get_font_size();
|
---|
| 507 |
|
---|
| 508 | foreach (self::$_inherited as $prop) {
|
---|
| 509 | //inherit the !important property also.
|
---|
| 510 | //if local property is also !important, don't inherit.
|
---|
| 511 | if ( isset($parent->_props[$prop]) &&
|
---|
| 512 | ( !isset($this->_props[$prop]) ||
|
---|
| 513 | ( isset($parent->_important_props[$prop]) && !isset($this->_important_props[$prop]) )
|
---|
| 514 | )
|
---|
| 515 | ) {
|
---|
| 516 | if ( isset($parent->_important_props[$prop]) ) {
|
---|
| 517 | $this->_important_props[$prop] = true;
|
---|
| 518 | }
|
---|
| 519 | //see __set and __get, on all assignments clear cache!
|
---|
| 520 | $this->_prop_cache[$prop] = null;
|
---|
| 521 | $this->_props[$prop] = $parent->_props[$prop];
|
---|
| 522 | }
|
---|
| 523 | }
|
---|
| 524 |
|
---|
| 525 | foreach (array_keys($this->_props) as $prop) {
|
---|
| 526 | if ( $this->_props[$prop] == "inherit" ) {
|
---|
| 527 | if ( isset($parent->_important_props[$prop]) ) {
|
---|
| 528 | $this->_important_props[$prop] = true;
|
---|
| 529 | }
|
---|
| 530 | //do not assign direct, but
|
---|
| 531 | //implicite assignment through __set, redirect to specialized, get value with __get
|
---|
| 532 | //This is for computing defaults if the parent setting is also missing.
|
---|
| 533 | //Therefore do not directly assign the value without __set
|
---|
| 534 | //set _important_props before that to be able to propagate.
|
---|
| 535 | //see __set and __get, on all assignments clear cache!
|
---|
| 536 | //$this->_prop_cache[$prop] = null;
|
---|
| 537 | //$this->_props[$prop] = $parent->_props[$prop];
|
---|
| 538 | //props_set for more obvious explicite assignment not implemented, because
|
---|
| 539 | //too many implicite uses.
|
---|
| 540 | // $this->props_set($prop, $parent->$prop);
|
---|
| 541 | $this->$prop = $parent->$prop;
|
---|
| 542 | }
|
---|
| 543 | }
|
---|
| 544 |
|
---|
| 545 | return $this;
|
---|
| 546 | }
|
---|
| 547 |
|
---|
| 548 |
|
---|
| 549 | /**
|
---|
| 550 | * Override properties in this style with those in $style
|
---|
| 551 | *
|
---|
| 552 | * @param Style $style
|
---|
| 553 | */
|
---|
| 554 | function merge(Style $style) {
|
---|
| 555 | //treat the !important attribute
|
---|
| 556 | //if old rule has !important attribute, override with new rule only if
|
---|
| 557 | //the new rule is also !important
|
---|
| 558 | foreach($style->_props as $prop => $val ) {
|
---|
| 559 | if (isset($style->_important_props[$prop])) {
|
---|
| 560 | $this->_important_props[$prop] = true;
|
---|
| 561 | //see __set and __get, on all assignments clear cache!
|
---|
| 562 | $this->_prop_cache[$prop] = null;
|
---|
| 563 | $this->_props[$prop] = $val;
|
---|
| 564 | } else if ( !isset($this->_important_props[$prop]) ) {
|
---|
| 565 | //see __set and __get, on all assignments clear cache!
|
---|
| 566 | $this->_prop_cache[$prop] = null;
|
---|
| 567 | $this->_props[$prop] = $val;
|
---|
| 568 | }
|
---|
| 569 | }
|
---|
| 570 |
|
---|
| 571 | if ( isset($style->_props["font_size"]) )
|
---|
| 572 | $this->__font_size_calculated = false;
|
---|
| 573 | }
|
---|
| 574 |
|
---|
| 575 |
|
---|
| 576 | /**
|
---|
| 577 | * Returns an array(r, g, b, "r"=> r, "g"=>g, "b"=>b, "hex"=>"#rrggbb")
|
---|
| 578 | * based on the provided CSS colour value.
|
---|
| 579 | *
|
---|
| 580 | * @param string $colour
|
---|
| 581 | * @return array
|
---|
| 582 | */
|
---|
| 583 | function munge_colour($colour) {
|
---|
| 584 | if ( is_array($colour) )
|
---|
| 585 | // Assume the array has the right format...
|
---|
| 586 | // FIXME: should/could verify this.
|
---|
| 587 | return $colour;
|
---|
| 588 |
|
---|
| 589 | $r = 0;
|
---|
| 590 | $g = 0;
|
---|
| 591 | $b = 0;
|
---|
| 592 |
|
---|
| 593 | // Handle colour names
|
---|
| 594 | switch ($colour) {
|
---|
| 595 |
|
---|
| 596 | case "maroon":
|
---|
| 597 | $r = 0x80;
|
---|
| 598 | break;
|
---|
| 599 |
|
---|
| 600 | case "red":
|
---|
| 601 | $r = 0xff;
|
---|
| 602 | break;
|
---|
| 603 |
|
---|
| 604 | case "orange":
|
---|
| 605 | $r = 0xff;
|
---|
| 606 | $g = 0xa5;
|
---|
| 607 | break;
|
---|
| 608 |
|
---|
| 609 | case "yellow":
|
---|
| 610 | $r = 0xff;
|
---|
| 611 | $g = 0xff;
|
---|
| 612 | break;
|
---|
| 613 |
|
---|
| 614 | case "olive":
|
---|
| 615 | $r = 0x80;
|
---|
| 616 | $g = 0x80;
|
---|
| 617 | break;
|
---|
| 618 |
|
---|
| 619 | case "purple":
|
---|
| 620 | $r = 0x80;
|
---|
| 621 | $b = 0x80;
|
---|
| 622 | break;
|
---|
| 623 |
|
---|
| 624 | case "fuchsia":
|
---|
| 625 | $r = 0xff;
|
---|
| 626 | $b = 0xff;
|
---|
| 627 | break;
|
---|
| 628 |
|
---|
| 629 | case "white":
|
---|
| 630 | $r = $g = $b = 0xff;
|
---|
| 631 | break;
|
---|
| 632 |
|
---|
| 633 | case "lime":
|
---|
| 634 | $g = 0xff;
|
---|
| 635 | break;
|
---|
| 636 |
|
---|
| 637 | case "green":
|
---|
| 638 | $g = 0x80;
|
---|
| 639 | break;
|
---|
| 640 |
|
---|
| 641 | case "navy":
|
---|
| 642 | $b = 0x80;
|
---|
| 643 | break;
|
---|
| 644 |
|
---|
| 645 | case "blue":
|
---|
| 646 | $b = 0xff;
|
---|
| 647 | break;
|
---|
| 648 |
|
---|
| 649 | case "aqua":
|
---|
| 650 | $g = 0xff;
|
---|
| 651 | $b = 0xff;
|
---|
| 652 | break;
|
---|
| 653 |
|
---|
| 654 | case "teal":
|
---|
| 655 | $g = 0x80;
|
---|
| 656 | $b = 0x80;
|
---|
| 657 | break;
|
---|
| 658 |
|
---|
| 659 | case "black":
|
---|
| 660 | break;
|
---|
| 661 |
|
---|
| 662 | case "sliver":
|
---|
| 663 | $r = $g = $b = 0xc0;
|
---|
| 664 | break;
|
---|
| 665 |
|
---|
| 666 | case "gray":
|
---|
| 667 | case "grey":
|
---|
| 668 | $r = $g = $b = 0x80;
|
---|
| 669 | break;
|
---|
| 670 |
|
---|
| 671 | case "transparent":
|
---|
| 672 | return "transparent";
|
---|
| 673 |
|
---|
| 674 | default:
|
---|
| 675 | if ( mb_strlen($colour) == 4 && $colour{0} == "#" ) {
|
---|
| 676 | // #rgb format
|
---|
| 677 | $r = hexdec($colour{1} . $colour{1});
|
---|
| 678 | $g = hexdec($colour{2} . $colour{2});
|
---|
| 679 | $b = hexdec($colour{3} . $colour{3});
|
---|
| 680 |
|
---|
| 681 | } else if ( mb_strlen($colour) == 7 && $colour{0} == "#" ) {
|
---|
| 682 | // #rrggbb format
|
---|
| 683 | $r = hexdec(mb_substr($colour, 1, 2));
|
---|
| 684 | $g = hexdec(mb_substr($colour, 3, 2));
|
---|
| 685 | $b = hexdec(mb_substr($colour, 5, 2));
|
---|
| 686 |
|
---|
| 687 | } else if ( mb_strpos($colour, "rgb") !== false ) {
|
---|
| 688 | // rgb( r,g,b ) format
|
---|
| 689 | $i = mb_strpos($colour, "(");
|
---|
| 690 | $j = mb_strpos($colour, ")");
|
---|
| 691 |
|
---|
| 692 | // Bad colour value
|
---|
| 693 | if ($i === false || $j === false)
|
---|
| 694 | return null;
|
---|
| 695 |
|
---|
| 696 | $triplet = explode(",", mb_substr($colour, $i+1, $j-$i-1));
|
---|
| 697 |
|
---|
| 698 | if (count($triplet) != 3)
|
---|
| 699 | return null;
|
---|
| 700 |
|
---|
| 701 | foreach (array_keys($triplet) as $c) {
|
---|
| 702 | $triplet[$c] = trim($triplet[$c]);
|
---|
| 703 |
|
---|
| 704 | if ( $triplet[$c]{mb_strlen($triplet[$c]) - 1} == "%" )
|
---|
| 705 | $triplet[$c] = round($triplet[$c] * 0.255);
|
---|
| 706 | }
|
---|
| 707 |
|
---|
| 708 | list($r, $g, $b) = $triplet;
|
---|
| 709 |
|
---|
| 710 | } else {
|
---|
| 711 | // Who knows?
|
---|
| 712 | return null;
|
---|
| 713 | }
|
---|
| 714 |
|
---|
| 715 | // Clip to 0 - 1
|
---|
| 716 | $r = $r < 0 ? 0 : ($r > 255 ? 255 : $r);
|
---|
| 717 | $g = $g < 0 ? 0 : ($g > 255 ? 255 : $g);
|
---|
| 718 | $b = $b < 0 ? 0 : ($b > 255 ? 255 : $b);
|
---|
| 719 | break;
|
---|
| 720 |
|
---|
| 721 | }
|
---|
| 722 |
|
---|
| 723 | // Form array
|
---|
| 724 | $arr = array(0 => $r / 0xff, 1 => $g / 0xff, 2 => $b / 0xff,
|
---|
| 725 | "r"=>$r / 0xff, "g"=>$g / 0xff, "b"=>$b / 0xff,
|
---|
| 726 | "hex" => sprintf("#%02X%02X%02X", $r, $g, $b));
|
---|
| 727 | return $arr;
|
---|
| 728 |
|
---|
| 729 | }
|
---|
| 730 |
|
---|
| 731 |
|
---|
| 732 | /**
|
---|
| 733 | * Alias for {@link Style::munge_colour()}
|
---|
| 734 | *
|
---|
| 735 | * @param string $color
|
---|
| 736 | * @return array
|
---|
| 737 | */
|
---|
| 738 | function munge_color($color) { return $this->munge_colour($color); }
|
---|
| 739 |
|
---|
| 740 | /* direct access to _important_props array from outside would work only when declared as
|
---|
| 741 | * 'var $_important_props;' instead of 'protected $_important_props;'
|
---|
| 742 | * Don't call _set/__get on missing attribute. Therefore need a special access.
|
---|
| 743 | * Assume that __set will be also called when this is called, so do not check validity again.
|
---|
| 744 | * Only created, if !important exists -> always set true.
|
---|
| 745 | */
|
---|
| 746 | function important_set($prop) {
|
---|
| 747 | $prop = str_replace("-", "_", $prop);
|
---|
| 748 | $this->_important_props[$prop] = true;
|
---|
| 749 | }
|
---|
| 750 |
|
---|
| 751 | function important_get($prop) {
|
---|
| 752 | isset($this->_important_props[$prop]);
|
---|
| 753 | }
|
---|
| 754 |
|
---|
| 755 | /**
|
---|
| 756 | * PHP5 overloaded setter
|
---|
| 757 | *
|
---|
| 758 | * This function along with {@link Style::__get()} permit a user of the
|
---|
| 759 | * Style class to access any (CSS) property using the following syntax:
|
---|
| 760 | * <code>
|
---|
| 761 | * Style->margin_top = "1em";
|
---|
| 762 | * echo (Style->margin_top);
|
---|
| 763 | * </code>
|
---|
| 764 | *
|
---|
| 765 | * __set() automatically calls the provided set function, if one exists,
|
---|
| 766 | * otherwise it sets the property directly. Typically, __set() is not
|
---|
| 767 | * called directly from outside of this class.
|
---|
| 768 | *
|
---|
| 769 | * On each modification clear cache to return accurate setting.
|
---|
| 770 | * Also affects direct settings not using __set
|
---|
| 771 | * For easier finding all assignments, attempted to allowing only explicite assignment:
|
---|
| 772 | * Very many uses, e.g. frame_reflower.cls.php -> for now leave as it is
|
---|
| 773 | * function __set($prop, $val) {
|
---|
| 774 | * throw new DOMPDF_Exception("Implicite replacement of assignment by __set. Not good.");
|
---|
| 775 | * }
|
---|
| 776 | * function props_set($prop, $val) { ... }
|
---|
| 777 | *
|
---|
| 778 | * @param string $prop the property to set
|
---|
| 779 | * @param mixed $val the value of the property
|
---|
| 780 | *
|
---|
| 781 | */
|
---|
| 782 | function __set($prop, $val) {
|
---|
| 783 | global $_dompdf_warnings;
|
---|
| 784 |
|
---|
| 785 | $prop = str_replace("-", "_", $prop);
|
---|
| 786 | $this->_prop_cache[$prop] = null;
|
---|
| 787 |
|
---|
| 788 | if ( !isset(self::$_defaults[$prop]) ) {
|
---|
| 789 | $_dompdf_warnings[] = "'$prop' is not a valid CSS2 property.";
|
---|
| 790 | return;
|
---|
| 791 | }
|
---|
| 792 |
|
---|
| 793 | if ( $prop !== "content" && is_string($val) && mb_strpos($val, "url") === false ) {
|
---|
| 794 | $val = mb_strtolower(trim(str_replace(array("\n", "\t"), array(" "), $val)));
|
---|
| 795 | $val = preg_replace("/([0-9]+) (pt|px|pc|em|ex|in|cm|mm|%)/S", "\\1\\2", $val);
|
---|
| 796 | }
|
---|
| 797 |
|
---|
| 798 | $method = "set_$prop";
|
---|
| 799 |
|
---|
| 800 | if ( method_exists($this, $method) )
|
---|
| 801 | $this->$method($val);
|
---|
| 802 | else
|
---|
| 803 | $this->_props[$prop] = $val;
|
---|
| 804 |
|
---|
| 805 | }
|
---|
| 806 |
|
---|
| 807 | /**
|
---|
| 808 | * PHP5 overloaded getter
|
---|
| 809 | *
|
---|
| 810 | * Along with {@link Style::__set()} __get() provides access to all CSS
|
---|
| 811 | * properties directly. Typically __get() is not called directly outside
|
---|
| 812 | * of this class.
|
---|
| 813 | *
|
---|
| 814 | * On each modification clear cache to return accurate setting.
|
---|
| 815 | * Also affects direct settings not using __set
|
---|
| 816 | *
|
---|
| 817 | * @param string $prop
|
---|
| 818 | * @return mixed
|
---|
| 819 | */
|
---|
| 820 | function __get($prop) {
|
---|
| 821 |
|
---|
| 822 | if ( !isset(self::$_defaults[$prop]) )
|
---|
| 823 | throw new DOMPDF_Exception("'$prop' is not a valid CSS2 property.");
|
---|
| 824 |
|
---|
| 825 | if ( isset($this->_prop_cache[$prop]) && $this->_prop_cache[$prop] != null)
|
---|
| 826 | return $this->_prop_cache[$prop];
|
---|
| 827 |
|
---|
| 828 | $method = "get_$prop";
|
---|
| 829 |
|
---|
| 830 | // Fall back on defaults if property is not set
|
---|
| 831 | if ( !isset($this->_props[$prop]) )
|
---|
| 832 | $this->_props[$prop] = self::$_defaults[$prop];
|
---|
| 833 |
|
---|
| 834 | if ( method_exists($this, $method) )
|
---|
| 835 | return $this->_prop_cache[$prop] = $this->$method();
|
---|
| 836 |
|
---|
| 837 |
|
---|
| 838 | return $this->_prop_cache[$prop] = $this->_props[$prop];
|
---|
| 839 | }
|
---|
| 840 |
|
---|
| 841 |
|
---|
| 842 | /**
|
---|
| 843 | * Getter for the 'font-family' CSS property.
|
---|
| 844 | *
|
---|
| 845 | * Uses the {@link Font_Metrics} class to resolve the font family into an
|
---|
| 846 | * actual font file.
|
---|
| 847 | *
|
---|
| 848 | * @link http://www.w3.org/TR/CSS21/fonts.html#propdef-font-family
|
---|
| 849 | * @return string
|
---|
| 850 | */
|
---|
| 851 | function get_font_family() {
|
---|
| 852 |
|
---|
| 853 | $DEBUGCSS=DEBUGCSS; //=DEBUGCSS; Allow override of global setting for ad hoc debug
|
---|
| 854 |
|
---|
| 855 | // Select the appropriate font. First determine the subtype, then check
|
---|
| 856 | // the specified font-families for a candidate.
|
---|
| 857 |
|
---|
| 858 | // Resolve font-weight
|
---|
| 859 | $weight = $this->__get("font_weight");
|
---|
| 860 |
|
---|
| 861 | if ( is_numeric($weight) ) {
|
---|
| 862 |
|
---|
| 863 | if ( $weight < 600 )
|
---|
| 864 | $weight = "normal";
|
---|
| 865 | else
|
---|
| 866 | $weight = "bold";
|
---|
| 867 |
|
---|
| 868 | } else if ( $weight == "bold" || $weight == "bolder" ) {
|
---|
| 869 | $weight = "bold";
|
---|
| 870 |
|
---|
| 871 | } else {
|
---|
| 872 | $weight = "normal";
|
---|
| 873 |
|
---|
| 874 | }
|
---|
| 875 |
|
---|
| 876 | // Resolve font-style
|
---|
| 877 | $font_style = $this->__get("font_style");
|
---|
| 878 |
|
---|
| 879 | if ( $weight == "bold" && ($font_style == "italic" || $font_style == "oblique") )
|
---|
| 880 | $subtype = "bold_italic";
|
---|
| 881 | else if ( $weight == "bold" && $font_style != "italic" && $font_style != "oblique" )
|
---|
| 882 | $subtype = "bold";
|
---|
| 883 | else if ( $weight != "bold" && ($font_style == "italic" || $font_style == "oblique") )
|
---|
| 884 | $subtype = "italic";
|
---|
| 885 | else
|
---|
| 886 | $subtype = "normal";
|
---|
| 887 |
|
---|
| 888 | // Resolve the font family
|
---|
| 889 | if ($DEBUGCSS) {
|
---|
| 890 | print "<pre>[get_font_family:";
|
---|
| 891 | print '('.$this->_props["font_family"].'.'.$font_style.'.'.$this->__get("font_weight").'.'.$weight.'.'.$subtype.')';
|
---|
| 892 | }
|
---|
| 893 | $families = explode(",", $this->_props["font_family"]);
|
---|
| 894 | $families = array_map('trim',$families);
|
---|
| 895 | reset($families);
|
---|
| 896 |
|
---|
| 897 | $font = null;
|
---|
| 898 | while ( current($families) ) {
|
---|
| 899 | list(,$family) = each($families);
|
---|
| 900 | //remove leading and trailing string delimiters, e.g. on font names with spaces;
|
---|
| 901 | //remove leading and trailing whitespace
|
---|
| 902 | $family=trim($family," \t\n\r\x0B\"'");
|
---|
| 903 | if ($DEBUGCSS) print '('.$family.')';
|
---|
| 904 | $font = Font_Metrics::get_font($family, $subtype);
|
---|
| 905 |
|
---|
| 906 | if ( $font ) {
|
---|
| 907 | if ($DEBUGCSS) print '('.$font.")get_font_family]\n</pre>";
|
---|
| 908 | return $font;
|
---|
| 909 | }
|
---|
| 910 | }
|
---|
| 911 |
|
---|
| 912 | $family = null;
|
---|
| 913 | if ($DEBUGCSS) print '(default)';
|
---|
| 914 | $font = Font_Metrics::get_font($family, $subtype);
|
---|
| 915 |
|
---|
| 916 | if ( $font ) {
|
---|
| 917 | if ($DEBUGCSS) print '('.$font.")get_font_family]\n</pre>";
|
---|
| 918 | return $font;
|
---|
| 919 | }
|
---|
| 920 | throw new DOMPDF_Exception("Unable to find a suitable font replacement for: '" . $this->_props["font_family"] ."'");
|
---|
| 921 |
|
---|
| 922 | }
|
---|
| 923 |
|
---|
| 924 | /**
|
---|
| 925 | * Returns the resolved font size, in points
|
---|
| 926 | *
|
---|
| 927 | * @link http://www.w3.org/TR/CSS21/fonts.html#propdef-font-size
|
---|
| 928 | * @return float
|
---|
| 929 | */
|
---|
| 930 | function get_font_size() {
|
---|
| 931 |
|
---|
| 932 | if ( $this->__font_size_calculated )
|
---|
| 933 | return $this->_props["font_size"];
|
---|
| 934 |
|
---|
| 935 | if ( !isset($this->_props["font_size"]) )
|
---|
| 936 | $fs = self::$_defaults["font_size"];
|
---|
| 937 | else
|
---|
| 938 | $fs = $this->_props["font_size"];
|
---|
| 939 |
|
---|
| 940 | if ( !isset($this->_parent_font_size) )
|
---|
| 941 | $this->_parent_font_size = self::$default_font_size;
|
---|
| 942 |
|
---|
| 943 | switch ($fs) {
|
---|
| 944 |
|
---|
| 945 | case "xx-small":
|
---|
| 946 | $fs = 3/5 * $this->_parent_font_size;
|
---|
| 947 | break;
|
---|
| 948 |
|
---|
| 949 | case "x-small":
|
---|
| 950 | $fs = 3/4 * $this->_parent_font_size;
|
---|
| 951 | break;
|
---|
| 952 |
|
---|
| 953 | case "smaller":
|
---|
| 954 | case "small":
|
---|
| 955 | $fs = 8/9 * $this->_parent_font_size;
|
---|
| 956 | break;
|
---|
| 957 |
|
---|
| 958 | case "medium":
|
---|
| 959 | $fs = $this->_parent_font_size;
|
---|
| 960 | break;
|
---|
| 961 |
|
---|
| 962 | case "larger":
|
---|
| 963 | case "large":
|
---|
| 964 | $fs = 6/5 * $this->_parent_font_size;
|
---|
| 965 | break;
|
---|
| 966 |
|
---|
| 967 | case "x-large":
|
---|
| 968 | $fs = 3/2 * $this->_parent_font_size;
|
---|
| 969 | break;
|
---|
| 970 |
|
---|
| 971 | case "xx-large":
|
---|
| 972 | $fs = 2/1 * $this->_parent_font_size;
|
---|
| 973 | break;
|
---|
| 974 |
|
---|
| 975 | default:
|
---|
| 976 | break;
|
---|
| 977 | }
|
---|
| 978 |
|
---|
| 979 | // Ensure relative sizes resolve to something
|
---|
| 980 | if ( ($i = mb_strpos($fs, "em")) !== false )
|
---|
| 981 | $fs = mb_substr($fs, 0, $i) * $this->_parent_font_size;
|
---|
| 982 |
|
---|
| 983 | else if ( ($i = mb_strpos($fs, "ex")) !== false )
|
---|
| 984 | $fs = mb_substr($fs, 0, $i) * $this->_parent_font_size;
|
---|
| 985 |
|
---|
| 986 | else
|
---|
| 987 | $fs = $this->length_in_pt($fs);
|
---|
| 988 |
|
---|
| 989 | //see __set and __get, on all assignments clear cache!
|
---|
| 990 | $this->_prop_cache["font_size"] = null;
|
---|
| 991 | $this->_props["font_size"] = $fs;
|
---|
| 992 | $this->__font_size_calculated = true;
|
---|
| 993 | return $this->_props["font_size"];
|
---|
| 994 |
|
---|
| 995 | }
|
---|
| 996 |
|
---|
| 997 | /**
|
---|
| 998 | * @link http://www.w3.org/TR/CSS21/text.html#propdef-word-spacing
|
---|
| 999 | * @return float
|
---|
| 1000 | */
|
---|
| 1001 | function get_word_spacing() {
|
---|
| 1002 | if ( $this->_props["word_spacing"] === "normal" )
|
---|
| 1003 | return 0;
|
---|
| 1004 |
|
---|
| 1005 | return $this->_props["word_spacing"];
|
---|
| 1006 | }
|
---|
| 1007 |
|
---|
| 1008 | /**
|
---|
| 1009 | * @link http://www.w3.org/TR/CSS21/visudet.html#propdef-line-height
|
---|
| 1010 | * @return float
|
---|
| 1011 | */
|
---|
| 1012 | function get_line_height() {
|
---|
| 1013 | if ( $this->_props["line_height"] === "normal" )
|
---|
| 1014 | return self::$default_line_height * $this->get_font_size();
|
---|
| 1015 |
|
---|
| 1016 | if ( is_numeric($this->_props["line_height"]) )
|
---|
| 1017 | return $this->length_in_pt( $this->_props["line_height"] . "%", $this->get_font_size());
|
---|
| 1018 |
|
---|
| 1019 | return $this->length_in_pt( $this->_props["line_height"], $this->get_font_size() );
|
---|
| 1020 | }
|
---|
| 1021 |
|
---|
| 1022 | /**
|
---|
| 1023 | * Returns the colour as an array
|
---|
| 1024 | *
|
---|
| 1025 | * The array has the following format:
|
---|
| 1026 | * <code>array(r,g,b, "r" => r, "g" => g, "b" => b, "hex" => "#rrggbb")</code>
|
---|
| 1027 | *
|
---|
| 1028 | * @link http://www.w3.org/TR/CSS21/colors.html#propdef-color
|
---|
| 1029 | * @return array
|
---|
| 1030 | */
|
---|
| 1031 | function get_color() {
|
---|
| 1032 | return $this->munge_color( $this->_props["color"] );
|
---|
| 1033 | }
|
---|
| 1034 |
|
---|
| 1035 | /**
|
---|
| 1036 | * Returns the background colour as an array
|
---|
| 1037 | *
|
---|
| 1038 | * The returned array has the same format as {@link Style::get_color()}
|
---|
| 1039 | *
|
---|
| 1040 | * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-color
|
---|
| 1041 | * @return array
|
---|
| 1042 | */
|
---|
| 1043 | function get_background_color() {
|
---|
| 1044 | return $this->munge_color( $this->_props["background_color"] );
|
---|
| 1045 | }
|
---|
| 1046 |
|
---|
| 1047 | /**
|
---|
| 1048 | * Returns the background position as an array
|
---|
| 1049 | *
|
---|
| 1050 | * The returned array has the following format:
|
---|
| 1051 | * <code>array(x,y, "x" => x, "y" => y)</code>
|
---|
| 1052 | *
|
---|
| 1053 | * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-position
|
---|
| 1054 | * @return array
|
---|
| 1055 | */
|
---|
| 1056 | function get_background_position() {
|
---|
| 1057 |
|
---|
| 1058 | $tmp = explode(" ", $this->_props["background_position"]);
|
---|
| 1059 |
|
---|
| 1060 | switch ($tmp[0]) {
|
---|
| 1061 |
|
---|
| 1062 | case "left":
|
---|
| 1063 | $x = "0%";
|
---|
| 1064 | break;
|
---|
| 1065 |
|
---|
| 1066 | case "right":
|
---|
| 1067 | $x = "100%";
|
---|
| 1068 | break;
|
---|
| 1069 |
|
---|
| 1070 | case "top":
|
---|
| 1071 | $y = "0%";
|
---|
| 1072 | break;
|
---|
| 1073 |
|
---|
| 1074 | case "bottom":
|
---|
| 1075 | $y = "100%";
|
---|
| 1076 | break;
|
---|
| 1077 |
|
---|
| 1078 | case "center":
|
---|
| 1079 | $x = "50%";
|
---|
| 1080 | $y = "50%";
|
---|
| 1081 | break;
|
---|
| 1082 |
|
---|
| 1083 | default:
|
---|
| 1084 | $x = $tmp[0];
|
---|
| 1085 | break;
|
---|
| 1086 | }
|
---|
| 1087 |
|
---|
| 1088 | if ( isset($tmp[1]) ) {
|
---|
| 1089 |
|
---|
| 1090 | switch ($tmp[1]) {
|
---|
| 1091 | case "left":
|
---|
| 1092 | $x = "0%";
|
---|
| 1093 | break;
|
---|
| 1094 |
|
---|
| 1095 | case "right":
|
---|
| 1096 | $x = "100%";
|
---|
| 1097 | break;
|
---|
| 1098 |
|
---|
| 1099 | case "top":
|
---|
| 1100 | $y = "0%";
|
---|
| 1101 | break;
|
---|
| 1102 |
|
---|
| 1103 | case "bottom":
|
---|
| 1104 | $y = "100%";
|
---|
| 1105 | break;
|
---|
| 1106 |
|
---|
| 1107 | case "center":
|
---|
| 1108 | if ( $tmp[0] == "left" || $tmp[0] == "right" || $tmp[0] == "center" )
|
---|
| 1109 | $y = "50%";
|
---|
| 1110 | else
|
---|
| 1111 | $x = "50%";
|
---|
| 1112 | break;
|
---|
| 1113 |
|
---|
| 1114 | default:
|
---|
| 1115 | $y = $tmp[1];
|
---|
| 1116 | break;
|
---|
| 1117 | }
|
---|
| 1118 |
|
---|
| 1119 | } else {
|
---|
| 1120 | $y = "50%";
|
---|
| 1121 | }
|
---|
| 1122 |
|
---|
| 1123 | if ( !isset($x) )
|
---|
| 1124 | $x = "0%";
|
---|
| 1125 |
|
---|
| 1126 | if ( !isset($y) )
|
---|
| 1127 | $y = "0%";
|
---|
| 1128 |
|
---|
| 1129 | return array( 0 => $x, "x" => $x,
|
---|
| 1130 | 1 => $y, "y" => $y );
|
---|
| 1131 | }
|
---|
| 1132 |
|
---|
| 1133 |
|
---|
| 1134 | /**
|
---|
| 1135 | * Returns the background as it is currently stored
|
---|
| 1136 | *
|
---|
| 1137 | * (currently anyway only for completeness.
|
---|
| 1138 | * not used for further processing)
|
---|
| 1139 | *
|
---|
| 1140 | * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-attachment
|
---|
| 1141 | * @return string
|
---|
| 1142 | */
|
---|
| 1143 | function get_background_attachment() {
|
---|
| 1144 | return $this->_props["background_attachment"];
|
---|
| 1145 | }
|
---|
| 1146 |
|
---|
| 1147 |
|
---|
| 1148 | /**
|
---|
| 1149 | * Returns the background_repeat as it is currently stored
|
---|
| 1150 | *
|
---|
| 1151 | * (currently anyway only for completeness.
|
---|
| 1152 | * not used for further processing)
|
---|
| 1153 | *
|
---|
| 1154 | * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-repeat
|
---|
| 1155 | * @return string
|
---|
| 1156 | */
|
---|
| 1157 | function get_background_repeat() {
|
---|
| 1158 | return $this->_props["background_repeat"];
|
---|
| 1159 | }
|
---|
| 1160 |
|
---|
| 1161 |
|
---|
| 1162 | /**
|
---|
| 1163 | * Returns the background as it is currently stored
|
---|
| 1164 | *
|
---|
| 1165 | * (currently anyway only for completeness.
|
---|
| 1166 | * not used for further processing, but the individual get_background_xxx)
|
---|
| 1167 | *
|
---|
| 1168 | * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background
|
---|
| 1169 | * @return string
|
---|
| 1170 | */
|
---|
| 1171 | function get_background() {
|
---|
| 1172 | return $this->_props["background"];
|
---|
| 1173 | }
|
---|
| 1174 |
|
---|
| 1175 |
|
---|
| 1176 | /**#@+
|
---|
| 1177 | * Returns the border colour as an array
|
---|
| 1178 | *
|
---|
| 1179 | * See {@link Style::get_color()}
|
---|
| 1180 | *
|
---|
| 1181 | * @link http://www.w3.org/TR/CSS21/box.html#border-color-properties
|
---|
| 1182 | * @return array
|
---|
| 1183 | */
|
---|
| 1184 | function get_border_top_color() {
|
---|
| 1185 | if ( $this->_props["border_top_color"] === "" ) {
|
---|
| 1186 | //see __set and __get, on all assignments clear cache!
|
---|
| 1187 | $this->_prop_cache["border_top_color"] = null;
|
---|
| 1188 | $this->_props["border_top_color"] = $this->__get("color");
|
---|
| 1189 | }
|
---|
| 1190 | return $this->munge_color($this->_props["border_top_color"]);
|
---|
| 1191 | }
|
---|
| 1192 |
|
---|
| 1193 | function get_border_right_color() {
|
---|
| 1194 | if ( $this->_props["border_right_color"] === "" ) {
|
---|
| 1195 | //see __set and __get, on all assignments clear cache!
|
---|
| 1196 | $this->_prop_cache["border_right_color"] = null;
|
---|
| 1197 | $this->_props["border_right_color"] = $this->__get("color");
|
---|
| 1198 | }
|
---|
| 1199 | return $this->munge_color($this->_props["border_right_color"]);
|
---|
| 1200 | }
|
---|
| 1201 |
|
---|
| 1202 | function get_border_bottom_color() {
|
---|
| 1203 | if ( $this->_props["border_bottom_color"] === "" ) {
|
---|
| 1204 | //see __set and __get, on all assignments clear cache!
|
---|
| 1205 | $this->_prop_cache["border_bottom_color"] = null;
|
---|
| 1206 | $this->_props["border_bottom_color"] = $this->__get("color");
|
---|
| 1207 | }
|
---|
| 1208 | return $this->munge_color($this->_props["border_bottom_color"]);;
|
---|
| 1209 | }
|
---|
| 1210 |
|
---|
| 1211 | function get_border_left_color() {
|
---|
| 1212 | if ( $this->_props["border_left_color"] === "" ) {
|
---|
| 1213 | //see __set and __get, on all assignments clear cache!
|
---|
| 1214 | $this->_prop_cache["border_left_color"] = null;
|
---|
| 1215 | $this->_props["border_left_color"] = $this->__get("color");
|
---|
| 1216 | }
|
---|
| 1217 | return $this->munge_color($this->_props["border_left_color"]);
|
---|
| 1218 | }
|
---|
| 1219 |
|
---|
| 1220 | /**#@-*/
|
---|
| 1221 |
|
---|
| 1222 | /**#@+
|
---|
| 1223 | * Returns the border width, as it is currently stored
|
---|
| 1224 | *
|
---|
| 1225 | * @link http://www.w3.org/TR/CSS21/box.html#border-width-properties
|
---|
| 1226 | * @return float|string
|
---|
| 1227 | */
|
---|
| 1228 | function get_border_top_width() {
|
---|
| 1229 | $style = $this->__get("border_top_style");
|
---|
| 1230 | return $style !== "none" && $style !== "hidden" ? $this->length_in_pt($this->_props["border_top_width"]) : 0;
|
---|
| 1231 | }
|
---|
| 1232 |
|
---|
| 1233 | function get_border_right_width() {
|
---|
| 1234 | $style = $this->__get("border_right_style");
|
---|
| 1235 | return $style !== "none" && $style !== "hidden" ? $this->length_in_pt($this->_props["border_right_width"]) : 0;
|
---|
| 1236 | }
|
---|
| 1237 |
|
---|
| 1238 | function get_border_bottom_width() {
|
---|
| 1239 | $style = $this->__get("border_bottom_style");
|
---|
| 1240 | return $style !== "none" && $style !== "hidden" ? $this->length_in_pt($this->_props["border_bottom_width"]) : 0;
|
---|
| 1241 | }
|
---|
| 1242 |
|
---|
| 1243 | function get_border_left_width() {
|
---|
| 1244 | $style = $this->__get("border_left_style");
|
---|
| 1245 | return $style !== "none" && $style !== "hidden" ? $this->length_in_pt($this->_props["border_left_width"]) : 0;
|
---|
| 1246 | }
|
---|
| 1247 | /**#@-*/
|
---|
| 1248 |
|
---|
| 1249 | /**
|
---|
| 1250 | * Return an array of all border properties.
|
---|
| 1251 | *
|
---|
| 1252 | * The returned array has the following structure:
|
---|
| 1253 | * <code>
|
---|
| 1254 | * array("top" => array("width" => [border-width],
|
---|
| 1255 | * "style" => [border-style],
|
---|
| 1256 | * "color" => [border-color (array)]),
|
---|
| 1257 | * "bottom" ... )
|
---|
| 1258 | * </code>
|
---|
| 1259 | *
|
---|
| 1260 | * @return array
|
---|
| 1261 | */
|
---|
| 1262 | function get_border_properties() {
|
---|
| 1263 | return array("top" => array("width" => $this->__get("border_top_width"),
|
---|
| 1264 | "style" => $this->__get("border_top_style"),
|
---|
| 1265 | "color" => $this->__get("border_top_color")),
|
---|
| 1266 | "bottom" => array("width" => $this->__get("border_bottom_width"),
|
---|
| 1267 | "style" => $this->__get("border_bottom_style"),
|
---|
| 1268 | "color" => $this->__get("border_bottom_color")),
|
---|
| 1269 | "right" => array("width" => $this->__get("border_right_width"),
|
---|
| 1270 | "style" => $this->__get("border_right_style"),
|
---|
| 1271 | "color" => $this->__get("border_right_color")),
|
---|
| 1272 | "left" => array("width" => $this->__get("border_left_width"),
|
---|
| 1273 | "style" => $this->__get("border_left_style"),
|
---|
| 1274 | "color" => $this->__get("border_left_color")));
|
---|
| 1275 | }
|
---|
| 1276 |
|
---|
| 1277 | /**
|
---|
| 1278 | * Return a single border property
|
---|
| 1279 | *
|
---|
| 1280 | * @return mixed
|
---|
| 1281 | */
|
---|
| 1282 | protected function _get_border($side) {
|
---|
| 1283 | $color = $this->__get("border_" . $side . "_color");
|
---|
| 1284 |
|
---|
| 1285 | return $this->__get("border_" . $side . "_width") . " " .
|
---|
| 1286 | $this->__get("border_" . $side . "_style") . " " . $color["hex"];
|
---|
| 1287 | }
|
---|
| 1288 |
|
---|
| 1289 | /**#@+
|
---|
| 1290 | * Return full border properties as a string
|
---|
| 1291 | *
|
---|
| 1292 | * Border properties are returned just as specified in CSS:
|
---|
| 1293 | * <pre>[width] [style] [color]</pre>
|
---|
| 1294 | * e.g. "1px solid blue"
|
---|
| 1295 | *
|
---|
| 1296 | * @link http://www.w3.org/TR/CSS21/box.html#border-shorthand-properties
|
---|
| 1297 | * @return string
|
---|
| 1298 | */
|
---|
| 1299 | function get_border_top() { return $this->_get_border("top"); }
|
---|
| 1300 | function get_border_right() { return $this->_get_border("right"); }
|
---|
| 1301 | function get_border_bottom() { return $this->_get_border("bottom"); }
|
---|
| 1302 | function get_border_left() { return $this->_get_border("left"); }
|
---|
| 1303 | /**#@-*/
|
---|
| 1304 |
|
---|
| 1305 |
|
---|
| 1306 | /**
|
---|
| 1307 | * Returns border spacing as an array
|
---|
| 1308 | *
|
---|
| 1309 | * The array has the format (h_space,v_space)
|
---|
| 1310 | *
|
---|
| 1311 | * @link http://www.w3.org/TR/CSS21/tables.html#propdef-border-spacing
|
---|
| 1312 | * @return array
|
---|
| 1313 | */
|
---|
| 1314 | function get_border_spacing() {
|
---|
| 1315 | return explode(" ", $this->_props["border_spacing"]);
|
---|
| 1316 | }
|
---|
| 1317 |
|
---|
| 1318 | /*==============================*/
|
---|
| 1319 |
|
---|
| 1320 | /*
|
---|
| 1321 | !important attribute
|
---|
| 1322 | For basic functionality of the !important attribute with overloading
|
---|
| 1323 | of several styles of an element, changes in inherit(), merge() and _parse_properties()
|
---|
| 1324 | are sufficient [helpers var $_important_props, __construct(), important_set(), important_get()]
|
---|
| 1325 |
|
---|
| 1326 | Only for combined attributes extra treatment needed. See below.
|
---|
| 1327 |
|
---|
| 1328 | div { border: 1px red; }
|
---|
| 1329 | div { border: solid; } // Not combined! Only one occurence of same style per context
|
---|
| 1330 | //
|
---|
| 1331 | div { border: 1px red; }
|
---|
| 1332 | div a { border: solid; } // Adding to border style ok by inheritance
|
---|
| 1333 | //
|
---|
| 1334 | div { border-style: solid; } // Adding to border style ok because of different styles
|
---|
| 1335 | div { border: 1px red; }
|
---|
| 1336 | //
|
---|
| 1337 | div { border-style: solid; !important} // border: overrides, even though not !important
|
---|
| 1338 | div { border: 1px dashed red; }
|
---|
| 1339 | //
|
---|
| 1340 | div { border: 1px red; !important }
|
---|
| 1341 | div a { border-style: solid; } // Need to override because not set
|
---|
| 1342 |
|
---|
| 1343 | Special treatment:
|
---|
| 1344 | At individual property like border-top-width need to check whether overriding value is also !important.
|
---|
| 1345 | Also store the !important condition for later overrides.
|
---|
| 1346 | Since not known who is initiating the override, need to get passed !importan as parameter.
|
---|
| 1347 | !important Paramter taken as in the original style in the css file.
|
---|
| 1348 | When poperty border !important given, do not mark subsets like border_style as important. Only
|
---|
| 1349 | individual properties.
|
---|
| 1350 |
|
---|
| 1351 | Note:
|
---|
| 1352 | Setting individual property directly from css with e.g. set_border_top_style() is not needed, because
|
---|
| 1353 | missing set funcions handled by a generic handler __set(), including the !important.
|
---|
| 1354 | Setting individual property of as sub-property is handled below.
|
---|
| 1355 |
|
---|
| 1356 | Implementation see at _set_style_side_type()
|
---|
| 1357 | Callers _set_style_sides_type(), _set_style_type, _set_style_type_important()
|
---|
| 1358 |
|
---|
| 1359 | Related functionality for background, padding, margin, font, list_style
|
---|
| 1360 | */
|
---|
| 1361 |
|
---|
| 1362 | /* Generalized set function for individual attribute of combined style.
|
---|
| 1363 | * With check for !important
|
---|
| 1364 | * Applicable for background, border, padding, margin, font, list_style
|
---|
| 1365 | * Note: $type has a leading underscore (or is empty), the others not.
|
---|
| 1366 | */
|
---|
| 1367 | protected function _set_style_side_type($style,$side,$type,$val,$important) {
|
---|
| 1368 | if ( !isset($this->_important_props[$style.'_'.$side.$type]) || $important) {
|
---|
| 1369 | //see __set and __get, on all assignments clear cache!
|
---|
| 1370 | $this->_prop_cache[$style.'_'.$side.$type] = null;
|
---|
| 1371 | if ($important) {
|
---|
| 1372 | $this->_important_props[$style.'_'.$side.$type] = true;
|
---|
| 1373 | }
|
---|
| 1374 | $this->_props[$style.'_'.$side.$type] = $val;
|
---|
| 1375 | }
|
---|
| 1376 | }
|
---|
| 1377 |
|
---|
| 1378 | protected function _set_style_sides_type($style,$top,$right,$bottom,$left,$type,$important) {
|
---|
| 1379 | $this->_set_style_side_type($style,'top',$type,$top,$important);
|
---|
| 1380 | $this->_set_style_side_type($style,'right',$type,$right,$important);
|
---|
| 1381 | $this->_set_style_side_type($style,'bottom',$type,$bottom,$important);
|
---|
| 1382 | $this->_set_style_side_type($style,'left',$type,$left,$important);
|
---|
| 1383 | }
|
---|
| 1384 |
|
---|
| 1385 | protected function _set_style_type($style,$type,$val,$important) {
|
---|
| 1386 | $arr = explode(" ", $val);
|
---|
| 1387 | switch (count($arr)) {
|
---|
| 1388 | case 1:
|
---|
| 1389 | $this->_set_style_sides_type($style,$arr[0],$arr[0],$arr[0],$arr[0],$type,$important);
|
---|
| 1390 | break;
|
---|
| 1391 | case 2:
|
---|
| 1392 | $this->_set_style_sides_type($style,$arr[0],$arr[1],$arr[0],$arr[1],$type,$important);
|
---|
| 1393 | break;
|
---|
| 1394 | case 3:
|
---|
| 1395 | $this->_set_style_sides_type($style,$arr[0],$arr[1],$arr[1],$arr[2],$type,$important);
|
---|
| 1396 | break;
|
---|
| 1397 | case 4:
|
---|
| 1398 | $this->_set_style_sides_type($style,$arr[0],$arr[1],$arr[2],$arr[3],$type,$important);
|
---|
| 1399 | break;
|
---|
| 1400 | default:
|
---|
| 1401 | break;
|
---|
| 1402 | }
|
---|
| 1403 | //see __set and __get, on all assignments clear cache!
|
---|
| 1404 | $this->_prop_cache[$style.$type] = null;
|
---|
| 1405 | $this->_props[$style.$type] = $val;
|
---|
| 1406 | }
|
---|
| 1407 |
|
---|
| 1408 | protected function _set_style_type_important($style,$type,$val) {
|
---|
| 1409 | $this->_set_style_type($style,$type,$val,isset($this->_important_props[$style.$type]));
|
---|
| 1410 | }
|
---|
| 1411 |
|
---|
| 1412 | /* Anyway only called if _important matches and is assigned
|
---|
| 1413 | * E.g. _set_style_side_type($style,$side,'',str_replace("none", "0px", $val),isset($this->_important_props[$style.'_'.$side]));
|
---|
| 1414 | */
|
---|
| 1415 | protected function _set_style_side_width_important($style,$side,$val) {
|
---|
| 1416 | //see __set and __get, on all assignments clear cache!
|
---|
| 1417 | $this->_prop_cache[$style.'_'.$side] = null;
|
---|
| 1418 | $this->_props[$style.'_'.$side] = str_replace("none", "0px", $val);
|
---|
| 1419 | }
|
---|
| 1420 |
|
---|
| 1421 | protected function _set_style($style,$val,$important) {
|
---|
| 1422 | if ( !isset($this->_important_props[$style]) || $important) {
|
---|
| 1423 | if ($important) {
|
---|
| 1424 | $this->_important_props[$style] = true;
|
---|
| 1425 | }
|
---|
| 1426 | //see __set and __get, on all assignments clear cache!
|
---|
| 1427 | $this->_prop_cache[$style] = null;
|
---|
| 1428 | $this->_props[$style] = $val;
|
---|
| 1429 | }
|
---|
| 1430 | }
|
---|
| 1431 |
|
---|
| 1432 | protected function _image($val) {
|
---|
| 1433 | $DEBUGCSS=DEBUGCSS;
|
---|
| 1434 |
|
---|
| 1435 | if ( mb_strpos($val, "url") === false ) {
|
---|
| 1436 | $path = "none"; //Don't resolve no image -> otherwise would prefix path and no longer recognize as none
|
---|
| 1437 | }
|
---|
| 1438 | else {
|
---|
| 1439 | $val = preg_replace("/url\(['\"]?([^'\")]+)['\"]?\)/","\\1", trim($val));
|
---|
| 1440 |
|
---|
| 1441 | // Resolve the url now in the context of the current stylesheet
|
---|
| 1442 | $parsed_url = explode_url($val);
|
---|
| 1443 | if ( $parsed_url["protocol"] == "" && $this->_stylesheet->get_protocol() == "" ) {
|
---|
| 1444 | if ($parsed_url["path"]{0} == '/' || $parsed_url["path"]{0} == '\\' ) {
|
---|
| 1445 | $path = $_SERVER["DOCUMENT_ROOT"].'/';
|
---|
| 1446 | } else {
|
---|
| 1447 | $path = $this->_stylesheet->get_base_path();
|
---|
| 1448 | }
|
---|
| 1449 | $path .= $parsed_url["path"] . $parsed_url["file"];
|
---|
| 1450 | $path = dompdf_realpath($path);
|
---|
| 1451 | } else {
|
---|
| 1452 | $path = build_url($this->_stylesheet->get_protocol(),
|
---|
| 1453 | $this->_stylesheet->get_host(),
|
---|
| 1454 | $this->_stylesheet->get_base_path(),
|
---|
| 1455 | $val);
|
---|
| 1456 | }
|
---|
| 1457 | }
|
---|
| 1458 | if ($DEBUGCSS) {
|
---|
| 1459 | print "<pre>[_image\n";
|
---|
| 1460 | print_r($parsed_url);
|
---|
| 1461 | print $this->_stylesheet->get_protocol()."\n".$this->_stylesheet->get_base_path()."\n".$path."\n";
|
---|
| 1462 | print "_image]</pre>";;
|
---|
| 1463 | }
|
---|
| 1464 | return $path;
|
---|
| 1465 | }
|
---|
| 1466 |
|
---|
| 1467 | /*======================*/
|
---|
| 1468 |
|
---|
| 1469 | /**
|
---|
| 1470 | * Sets colour
|
---|
| 1471 | *
|
---|
| 1472 | * The colour parameter can be any valid CSS colour value
|
---|
| 1473 | *
|
---|
| 1474 | * @link http://www.w3.org/TR/CSS21/colors.html#propdef-color
|
---|
| 1475 | * @param string $colour
|
---|
| 1476 | */
|
---|
| 1477 | function set_color($colour) {
|
---|
| 1478 | $col = $this->munge_colour($colour);
|
---|
| 1479 |
|
---|
| 1480 | if ( is_null($col) )
|
---|
| 1481 | $col = self::$_defaults["color"];
|
---|
| 1482 |
|
---|
| 1483 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1484 | $this->_prop_cache["color"] = null;
|
---|
| 1485 | $this->_props["color"] = $col["hex"];
|
---|
| 1486 | }
|
---|
| 1487 |
|
---|
| 1488 | /**
|
---|
| 1489 | * Sets the background colour
|
---|
| 1490 | *
|
---|
| 1491 | * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-color
|
---|
| 1492 | * @param string $colour
|
---|
| 1493 | */
|
---|
| 1494 | function set_background_color($colour) {
|
---|
| 1495 | $col = $this->munge_colour($colour);
|
---|
| 1496 | if ( is_null($col) )
|
---|
| 1497 | $col = self::$_defaults["background_color"];
|
---|
| 1498 |
|
---|
| 1499 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1500 | $this->_prop_cache["background_color"] = null;
|
---|
| 1501 | $this->_props["background_color"] = is_array($col) ? $col["hex"] : $col;
|
---|
| 1502 | }
|
---|
| 1503 |
|
---|
| 1504 | /**
|
---|
| 1505 | * Set the background image url
|
---|
| 1506 | *
|
---|
| 1507 | * @link http://www.w3.org/TR/CSS21/colors.html#background-properties
|
---|
| 1508 | * @param string $url
|
---|
| 1509 | */
|
---|
| 1510 | function set_background_image($val) {
|
---|
| 1511 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1512 | $this->_prop_cache["background_image"] = null;
|
---|
| 1513 | $this->_props["background_image"] = $this->_image($val);
|
---|
| 1514 | }
|
---|
| 1515 |
|
---|
| 1516 | /**
|
---|
| 1517 | * Sets the background repeat
|
---|
| 1518 | *
|
---|
| 1519 | * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-repeat
|
---|
| 1520 | * @param string $val
|
---|
| 1521 | */
|
---|
| 1522 | function set_background_repeat($val) {
|
---|
| 1523 | if ( is_null($val) )
|
---|
| 1524 | $val = self::$_defaults["background_repeat"];
|
---|
| 1525 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1526 | $this->_prop_cache["background_repeat"] = null;
|
---|
| 1527 | $this->_props["background_repeat"] = $val;
|
---|
| 1528 | }
|
---|
| 1529 |
|
---|
| 1530 | /**
|
---|
| 1531 | * Sets the background attachment
|
---|
| 1532 | *
|
---|
| 1533 | * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-attachment
|
---|
| 1534 | * @param string $val
|
---|
| 1535 | */
|
---|
| 1536 | function set_background_attachment($val) {
|
---|
| 1537 | if ( is_null($val) )
|
---|
| 1538 | $val = self::$_defaults["background_attachment"];
|
---|
| 1539 |
|
---|
| 1540 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1541 | $this->_prop_cache["background_attachment"] = null;
|
---|
| 1542 | $this->_props["background_attachment"] = $val;
|
---|
| 1543 | }
|
---|
| 1544 |
|
---|
| 1545 | /**
|
---|
| 1546 | * Sets the background position
|
---|
| 1547 | *
|
---|
| 1548 | * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-position
|
---|
| 1549 | * @param string $val
|
---|
| 1550 | */
|
---|
| 1551 | function set_background_position($val) {
|
---|
| 1552 | if ( is_null($val) )
|
---|
| 1553 | $val = self::$_defaults["background_position"];
|
---|
| 1554 |
|
---|
| 1555 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1556 | $this->_prop_cache["background_position"] = null;
|
---|
| 1557 | $this->_props["background_position"] = $val;
|
---|
| 1558 | }
|
---|
| 1559 |
|
---|
| 1560 | /**
|
---|
| 1561 | * Sets the background - combined options
|
---|
| 1562 | *
|
---|
| 1563 | * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background
|
---|
| 1564 | * @param string $val
|
---|
| 1565 | */
|
---|
| 1566 | function set_background($val) {
|
---|
| 1567 | $col = null;
|
---|
| 1568 | $pos = array();
|
---|
| 1569 | $tmp = explode(" ", $val);
|
---|
| 1570 | $important = isset($this->_important_props["background"]);
|
---|
| 1571 | foreach($tmp as $attr) {
|
---|
| 1572 | if (mb_substr($attr, 0, 3) == "url" || $attr == "none") {
|
---|
| 1573 | $this->_set_style("background_image", $this->_image($attr), $important);
|
---|
| 1574 | } else if ($attr == "fixed" || $attr == "scroll") {
|
---|
| 1575 | $this->_set_style("background_attachment", $attr, $important);
|
---|
| 1576 | } else if ($attr == "repeat" || $attr == "repeat-x" || $attr == "repeat-y" || $attr == "no-repeat") {
|
---|
| 1577 | $this->_set_style("background_repeat", $attr, $important);
|
---|
| 1578 | } else if (($col = $this->munge_color($attr)) != null ) {
|
---|
| 1579 | $this->_set_style("background_color", is_array($col) ? $col["hex"] : $col, $important);
|
---|
| 1580 | } else {
|
---|
| 1581 | $pos[] = $attr;
|
---|
| 1582 | }
|
---|
| 1583 | }
|
---|
| 1584 | if (count($pos)) {
|
---|
| 1585 | $this->_set_style("background_position",implode(' ',$pos), $important);
|
---|
| 1586 | }
|
---|
| 1587 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1588 | $this->_prop_cache["background"] = null;
|
---|
| 1589 | $this->_props["background"] = $val;
|
---|
| 1590 | }
|
---|
| 1591 |
|
---|
| 1592 | /**
|
---|
| 1593 | * Sets the font size
|
---|
| 1594 | *
|
---|
| 1595 | * $size can be any acceptable CSS size
|
---|
| 1596 | *
|
---|
| 1597 | * @link http://www.w3.org/TR/CSS21/fonts.html#propdef-font-size
|
---|
| 1598 | * @param string|float $size
|
---|
| 1599 | */
|
---|
| 1600 | function set_font_size($size) {
|
---|
| 1601 | $this->__font_size_calculated = false;
|
---|
| 1602 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1603 | $this->_prop_cache["font_size"] = null;
|
---|
| 1604 | $this->_props["font_size"] = $size;
|
---|
| 1605 | }
|
---|
| 1606 |
|
---|
| 1607 | /**
|
---|
| 1608 | * Sets the font style
|
---|
| 1609 | *
|
---|
| 1610 | * combined attributes
|
---|
| 1611 | * set individual attributes also, respecting !important mark
|
---|
| 1612 | * exactly this order, separate by space. Multiple fonts separated by comma:
|
---|
| 1613 | * font-style, font-variant, font-weight, font-size, line-height, font-family
|
---|
| 1614 | *
|
---|
| 1615 | * Other than with border and list, existing partial attributes should
|
---|
| 1616 | * reset when starting here, even when not mentioned.
|
---|
| 1617 | * If individual attribute is !important and explicite or implicite replacement is not,
|
---|
| 1618 | * keep individual attribute
|
---|
| 1619 | *
|
---|
| 1620 | * require whitespace as delimiters for single value attributes
|
---|
| 1621 | * On delimiter "/" treat first as font height, second as line height
|
---|
| 1622 | * treat all remaining at the end of line as font
|
---|
| 1623 | * font-style, font-variant, font-weight, font-size, line-height, font-family
|
---|
| 1624 | *
|
---|
| 1625 | * missing font-size and font-family might be not allowed, but accept it here and
|
---|
| 1626 | * use default (medium size, enpty font name)
|
---|
| 1627 | *
|
---|
| 1628 | * @link http://www.w3.org/TR/CSS21/generate.html#propdef-list-style
|
---|
| 1629 | * @param $val
|
---|
| 1630 | */
|
---|
| 1631 | function set_font($val) {
|
---|
| 1632 | $this->__font_size_calculated = false;
|
---|
| 1633 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1634 | $this->_prop_cache["font"] = null;
|
---|
| 1635 | $this->_props["font"] = $val;
|
---|
| 1636 |
|
---|
| 1637 | $important = isset($this->_important_props["font"]);
|
---|
| 1638 |
|
---|
| 1639 | if ( preg_match("/^(italic|oblique|normal)\s*(.*)$/i",$val,$match) ) {
|
---|
| 1640 | $this->_set_style("font_style", $match[1], $important);
|
---|
| 1641 | $val = $match[2];
|
---|
| 1642 | } else {
|
---|
| 1643 | $this->_set_style("font_style", self::$_defaults["font_style"], $important);
|
---|
| 1644 | }
|
---|
| 1645 |
|
---|
| 1646 | if ( preg_match("/^(small-caps|normal)\s*(.*)$/i",$val,$match) ) {
|
---|
| 1647 | $this->_set_style("font_variant", $match[1], $important);
|
---|
| 1648 | $val = $match[2];
|
---|
| 1649 | } else {
|
---|
| 1650 | $this->_set_style("font_variant", self::$_defaults["font_variant"], $important);
|
---|
| 1651 | }
|
---|
| 1652 |
|
---|
| 1653 | //matching numeric value followed by unit -> this is indeed a subsequent font size. Skip!
|
---|
| 1654 | if ( preg_match("/^(bold|bolder|lighter|100|200|300|400|500|600|700|800|900|normal)\s*(.*)$/i",$val,$match) &&
|
---|
| 1655 | !preg_match("/^(?:pt|px|pc|em|ex|in|cm|mm|%)/",$match[2])
|
---|
| 1656 | ) {
|
---|
| 1657 | $this->_set_style("font_weight", $match[1], $important);
|
---|
| 1658 | $val = $match[2];
|
---|
| 1659 | } else {
|
---|
| 1660 | $this->_set_style("font_weight", self::$_defaults["font_weight"], $important);
|
---|
| 1661 | }
|
---|
| 1662 |
|
---|
| 1663 | if ( preg_match("/^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger|\d+\s*(?:pt|px|pc|em|ex|in|cm|mm|%))\s*(.*)$/i",$val,$match) ) {
|
---|
| 1664 | $this->_set_style("font_size", $match[1], $important);
|
---|
| 1665 | $val = $match[2];
|
---|
| 1666 | if (preg_match("/^\/\s*(\d+\s*(?:pt|px|pc|em|ex|in|cm|mm|%))\s*(.*)$/i",$val,$match) ) {
|
---|
| 1667 | $this->_set_style("line_height", $match[1], $important);
|
---|
| 1668 | $val = $match[2];
|
---|
| 1669 | } else {
|
---|
| 1670 | $this->_set_style("line_height", self::$_defaults["line_height"], $important);
|
---|
| 1671 | }
|
---|
| 1672 | } else {
|
---|
| 1673 | $this->_set_style("font_size", self::$_defaults["font_size"], $important);
|
---|
| 1674 | $this->_set_style("line_height", self::$_defaults["line_height"], $important);
|
---|
| 1675 | }
|
---|
| 1676 |
|
---|
| 1677 | if(strlen($val) != 0) {
|
---|
| 1678 | $this->_set_style("font_family", $val, $important);
|
---|
| 1679 | } else {
|
---|
| 1680 | $this->_set_style("font_family", self::$_defaults["font_family"], $important);
|
---|
| 1681 | }
|
---|
| 1682 | }
|
---|
| 1683 |
|
---|
| 1684 | /**#@+
|
---|
| 1685 | * Sets page break properties
|
---|
| 1686 | *
|
---|
| 1687 | * @link http://www.w3.org/TR/CSS21/page.html#page-breaks
|
---|
| 1688 | * @param string $break
|
---|
| 1689 | */
|
---|
| 1690 | function set_page_break_before($break) {
|
---|
| 1691 | if ($break === "left" || $break === "right")
|
---|
| 1692 | $break = "always";
|
---|
| 1693 |
|
---|
| 1694 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1695 | $this->_prop_cache["page_break_before"] = null;
|
---|
| 1696 | $this->_props["page_break_before"] = $break;
|
---|
| 1697 | }
|
---|
| 1698 |
|
---|
| 1699 | function set_page_break_after($break) {
|
---|
| 1700 | if ($break === "left" || $break === "right")
|
---|
| 1701 | $break = "always";
|
---|
| 1702 |
|
---|
| 1703 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1704 | $this->_prop_cache["page_break_after"] = null;
|
---|
| 1705 | $this->_props["page_break_after"] = $break;
|
---|
| 1706 | }
|
---|
| 1707 | /**#@-*/
|
---|
| 1708 |
|
---|
| 1709 | //........................................................................
|
---|
| 1710 |
|
---|
| 1711 | /**#@+
|
---|
| 1712 | * Sets the margin size
|
---|
| 1713 | *
|
---|
| 1714 | * @link http://www.w3.org/TR/CSS21/box.html#margin-properties
|
---|
| 1715 | * @param $val
|
---|
| 1716 | */
|
---|
| 1717 | function set_margin_top($val) {
|
---|
| 1718 | $this->_set_style_side_width_important('margin','top',$val);
|
---|
| 1719 | }
|
---|
| 1720 |
|
---|
| 1721 | function set_margin_right($val) {
|
---|
| 1722 | $this->_set_style_side_width_important('margin','right',$val);
|
---|
| 1723 | }
|
---|
| 1724 |
|
---|
| 1725 | function set_margin_bottom($val) {
|
---|
| 1726 | $this->_set_style_side_width_important('margin','bottom',$val);
|
---|
| 1727 | }
|
---|
| 1728 |
|
---|
| 1729 | function set_margin_left($val) {
|
---|
| 1730 | $this->_set_style_side_width_important('margin','left',$val);
|
---|
| 1731 | }
|
---|
| 1732 |
|
---|
| 1733 | function set_margin($val) {
|
---|
| 1734 | $val = str_replace("none", "0px", $val);
|
---|
| 1735 | $this->_set_style_type_important('margin','',$val);
|
---|
| 1736 | }
|
---|
| 1737 | /**#@-*/
|
---|
| 1738 |
|
---|
| 1739 | /**#@+
|
---|
| 1740 | * Sets the padding size
|
---|
| 1741 | *
|
---|
| 1742 | * @link http://www.w3.org/TR/CSS21/box.html#padding-properties
|
---|
| 1743 | * @param $val
|
---|
| 1744 | */
|
---|
| 1745 | function set_padding_top($val) {
|
---|
| 1746 | $this->_set_style_side_width_important('padding','top',$val);
|
---|
| 1747 | }
|
---|
| 1748 |
|
---|
| 1749 | function set_padding_right($val) {
|
---|
| 1750 | $this->_set_style_side_width_important('padding','right',$val);
|
---|
| 1751 | }
|
---|
| 1752 |
|
---|
| 1753 | function set_padding_bottom($val) {
|
---|
| 1754 | $this->_set_style_side_width_important('padding','bottom',$val);
|
---|
| 1755 | }
|
---|
| 1756 |
|
---|
| 1757 | function set_padding_left($val) {
|
---|
| 1758 | $this->_set_style_side_width_important('padding','left',$val);
|
---|
| 1759 | }
|
---|
| 1760 |
|
---|
| 1761 | function set_padding($val) {
|
---|
| 1762 | $val = str_replace("none", "0px", $val);
|
---|
| 1763 | $this->_set_style_type_important('padding','',$val);
|
---|
| 1764 | }
|
---|
| 1765 | /**#@-*/
|
---|
| 1766 |
|
---|
| 1767 | /**
|
---|
| 1768 | * Sets a single border
|
---|
| 1769 | *
|
---|
| 1770 | * @param string $side
|
---|
| 1771 | * @param string $border_spec ([width] [style] [color])
|
---|
| 1772 | */
|
---|
| 1773 | protected function _set_border($side, $border_spec, $important) {
|
---|
| 1774 | $border_spec = str_replace(",", " ", $border_spec);
|
---|
| 1775 | $arr = explode(" ", $border_spec);
|
---|
| 1776 |
|
---|
| 1777 | // FIXME: handle partial values
|
---|
| 1778 |
|
---|
| 1779 | //For consistency of individal and combined properties, and with ie8 and firefox3
|
---|
| 1780 | //reset all attributes, even if only partially given
|
---|
| 1781 | $this->_set_style_side_type('border',$side,'_style',self::$_defaults['border_'.$side.'_style'],$important);
|
---|
| 1782 | $this->_set_style_side_type('border',$side,'_width',self::$_defaults['border_'.$side.'_width'],$important);
|
---|
| 1783 | $this->_set_style_side_type('border',$side,'_color',self::$_defaults['border_'.$side.'_color'],$important);
|
---|
| 1784 |
|
---|
| 1785 | foreach ($arr as $value) {
|
---|
| 1786 | $value = trim($value);
|
---|
| 1787 | if ( in_array($value, self::$BORDER_STYLES) ) {
|
---|
| 1788 | $this->_set_style_side_type('border',$side,'_style',$value,$important);
|
---|
| 1789 |
|
---|
| 1790 | } else if ( preg_match("/[.0-9]+(?:px|pt|pc|em|ex|%|in|mm|cm)|(?:thin|medium|thick)/", $value ) ) {
|
---|
| 1791 | $this->_set_style_side_type('border',$side,'_width',$value,$important);
|
---|
| 1792 |
|
---|
| 1793 | } else {
|
---|
| 1794 | // must be colour
|
---|
| 1795 | $this->_set_style_side_type('border',$side,'_color',$value,$important);
|
---|
| 1796 | }
|
---|
| 1797 | }
|
---|
| 1798 |
|
---|
| 1799 | //see __set and __get, on all assignments clear cache!
|
---|
| 1800 | $this->_prop_cache['border_'.$side] = null;
|
---|
| 1801 | $this->_props['border_'.$side] = $border_spec;
|
---|
| 1802 | }
|
---|
| 1803 |
|
---|
| 1804 | /**#@+
|
---|
| 1805 | * Sets the border styles
|
---|
| 1806 | *
|
---|
| 1807 | * @link http://www.w3.org/TR/CSS21/box.html#border-properties
|
---|
| 1808 | * @param string $val
|
---|
| 1809 | */
|
---|
| 1810 | function set_border_top($val) { $this->_set_border("top", $val, isset($this->_important_props['border_top'])); }
|
---|
| 1811 | function set_border_right($val) { $this->_set_border("right", $val, isset($this->_important_props['border_right'])); }
|
---|
| 1812 | function set_border_bottom($val) { $this->_set_border("bottom", $val, isset($this->_important_props['border_bottom'])); }
|
---|
| 1813 | function set_border_left($val) { $this->_set_border("left", $val, isset($this->_important_props['border_left'])); }
|
---|
| 1814 |
|
---|
| 1815 | function set_border($val) {
|
---|
| 1816 | $important = isset($this->_important_props["border"]);
|
---|
| 1817 | $this->_set_border("top", $val, $important);
|
---|
| 1818 | $this->_set_border("right", $val, $important);
|
---|
| 1819 | $this->_set_border("bottom", $val, $important);
|
---|
| 1820 | $this->_set_border("left", $val, $important);
|
---|
| 1821 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1822 | $this->_prop_cache["border"] = null;
|
---|
| 1823 | $this->_props["border"] = $val;
|
---|
| 1824 | }
|
---|
| 1825 |
|
---|
| 1826 | function set_border_width($val) {
|
---|
| 1827 | $this->_set_style_type_important('border','_width',$val);
|
---|
| 1828 | }
|
---|
| 1829 |
|
---|
| 1830 | function set_border_color($val) {
|
---|
| 1831 | $this->_set_style_type_important('border','_color',$val);
|
---|
| 1832 | }
|
---|
| 1833 |
|
---|
| 1834 | function set_border_style($val) {
|
---|
| 1835 | $this->_set_style_type_important('border','_style',$val);
|
---|
| 1836 | }
|
---|
| 1837 | /**#@-*/
|
---|
| 1838 |
|
---|
| 1839 |
|
---|
| 1840 | /**
|
---|
| 1841 | * Sets the border spacing
|
---|
| 1842 | *
|
---|
| 1843 | * @link http://www.w3.org/TR/CSS21/box.html#border-properties
|
---|
| 1844 | * @param float $val
|
---|
| 1845 | */
|
---|
| 1846 | function set_border_spacing($val) {
|
---|
| 1847 |
|
---|
| 1848 | $arr = explode(" ", $val);
|
---|
| 1849 |
|
---|
| 1850 | if ( count($arr) == 1 )
|
---|
| 1851 | $arr[1] = $arr[0];
|
---|
| 1852 |
|
---|
| 1853 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1854 | $this->_prop_cache["border_spacing"] = null;
|
---|
| 1855 | $this->_props["border_spacing"] = $arr[0] . " " . $arr[1];
|
---|
| 1856 | }
|
---|
| 1857 |
|
---|
| 1858 | /**
|
---|
| 1859 | * Sets the list style image
|
---|
| 1860 | *
|
---|
| 1861 | * @link http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image
|
---|
| 1862 | * @param $val
|
---|
| 1863 | */
|
---|
| 1864 | function set_list_style_image($val) {
|
---|
| 1865 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1866 | $this->_prop_cache["list_style_image"] = null;
|
---|
| 1867 | $this->_props["list_style_image"] = $this->_image($val);
|
---|
| 1868 | }
|
---|
| 1869 |
|
---|
| 1870 | /**
|
---|
| 1871 | * Sets the list style
|
---|
| 1872 | *
|
---|
| 1873 | * @link http://www.w3.org/TR/CSS21/generate.html#propdef-list-style
|
---|
| 1874 | * @param $val
|
---|
| 1875 | */
|
---|
| 1876 | function set_list_style($val) {
|
---|
| 1877 | $important = isset($this->_important_props["list_style"]);
|
---|
| 1878 | $arr = explode(" ", str_replace(",", " ", $val));
|
---|
| 1879 |
|
---|
| 1880 | static $types = array("disc", "circle", "square", "decimal",
|
---|
| 1881 | "decimal-leading-zero", "lower-roman",
|
---|
| 1882 | "upper-roman", "lower-greek", "lower-latin",
|
---|
| 1883 | "upper-latin", "armenian", "georgian",
|
---|
| 1884 | "lower-alpha", "upper-alpha", "hebrew",
|
---|
| 1885 | "cjk-ideographic", "hiragana", "katakana",
|
---|
| 1886 | "hiragana-iroha", "katakana-iroha", "none");
|
---|
| 1887 |
|
---|
| 1888 | static $positions = array("inside", "outside");
|
---|
| 1889 |
|
---|
| 1890 | foreach ($arr as $value) {
|
---|
| 1891 | /* http://www.w3.org/TR/CSS21/generate.html#list-style
|
---|
| 1892 | * A value of 'none' for the 'list-style' property sets both 'list-style-type' and 'list-style-image' to 'none'
|
---|
| 1893 | */
|
---|
| 1894 | if ($value == "none") {
|
---|
| 1895 | $this->_set_style("list_style_type", $value, $important);
|
---|
| 1896 | $this->_set_style("list_style_image", $value, $important);
|
---|
| 1897 | continue;
|
---|
| 1898 | }
|
---|
| 1899 |
|
---|
| 1900 | //On setting or merging or inheriting list_style_image as well as list_style_type,
|
---|
| 1901 | //and url exists, then url has precedence, otherwise fall back to list_style_type
|
---|
| 1902 | //Firefox is wrong here (list_style_image gets overwritten on explicite list_style_type)
|
---|
| 1903 | //Internet Explorer 7/8 and dompdf is right.
|
---|
| 1904 |
|
---|
| 1905 | if (mb_substr($value, 0, 3) == "url") {
|
---|
| 1906 | $this->_set_style("list_style_image", $this->_image($value), $important);
|
---|
| 1907 | continue;
|
---|
| 1908 | }
|
---|
| 1909 |
|
---|
| 1910 | if ( in_array($value, $types) ) {
|
---|
| 1911 | $this->_set_style("list_style_type", $value, $important);
|
---|
| 1912 | } else if ( in_array($value, $positions) ) {
|
---|
| 1913 | $this->_set_style("list_style_position", $value, $important);
|
---|
| 1914 | }
|
---|
| 1915 | }
|
---|
| 1916 |
|
---|
| 1917 | //see __set and __get, on all assignments clear cache, not needed on direct set through __set
|
---|
| 1918 | $this->_prop_cache["list_style"] = null;
|
---|
| 1919 | $this->_props["list_style"] = $val;
|
---|
| 1920 | }
|
---|
| 1921 |
|
---|
| 1922 | /**
|
---|
| 1923 | * Generate a string representation of the Style
|
---|
| 1924 | *
|
---|
| 1925 | * This dumps the entire property array into a string via print_r. Useful
|
---|
| 1926 | * for debugging.
|
---|
| 1927 | *
|
---|
| 1928 | * @return string
|
---|
| 1929 | */
|
---|
| 1930 | /*DEBUGCSS print: see below additional debugging util*/
|
---|
| 1931 | function __toString() {
|
---|
| 1932 | return print_r(array_merge(array("parent_font_size" => $this->_parent_font_size),
|
---|
| 1933 | $this->_props), true);
|
---|
| 1934 | }
|
---|
| 1935 |
|
---|
| 1936 | /*DEBUGCSS*/ function debug_print()
|
---|
| 1937 | /*DEBUGCSS*/ {
|
---|
| 1938 | /*DEBUGCSS*/ print "parent_font_size:".$this->_parent_font_size . ";\n";
|
---|
| 1939 | /*DEBUGCSS*/ foreach($this->_props as $prop => $val ) {
|
---|
| 1940 | /*DEBUGCSS*/ print $prop.':'.$val;
|
---|
| 1941 | /*DEBUGCSS*/ if (isset($this->_important_props[$prop])) {
|
---|
| 1942 | /*DEBUGCSS*/ print '!important';
|
---|
| 1943 | /*DEBUGCSS*/ }
|
---|
| 1944 | /*DEBUGCSS*/ print ";\n";
|
---|
| 1945 | /*DEBUGCSS*/ }
|
---|
| 1946 | /*DEBUGCSS*/ }
|
---|
| 1947 | }
|
---|
| 1948 | ?> |
---|