���Root Mod By V1rus_Alfa
User / IP
:
216.73.217.78
Host / Server
:
195.214.235.115 / npln.ir
System
:
Linux damavand.pws-dns.net 5.14.0-503.35.1.el9_5.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Apr 4 05:23:43 EDT 2025 x86_64
Command
|
Upload
|
Mass Deface
|
Create
:
/
home2
/
cutunixc
/
repositories
/
npln
/
vendor
/
mpdf
/
mpdf
/
src
/
Css
/
Viewing: NormalizeProperties.php
<?php namespace Mpdf\Css; use Mpdf\Color\ColorConverter; use Mpdf\Mpdf; use Mpdf\PageFormat; use Mpdf\SizeConverter; use Mpdf\Utils\Arrays; use Mpdf\Utils\UtfString; class NormalizeProperties { /** * @var Mpdf */ private $mpdf; /** * @var SizeConverter */ private $sizeConverter; /** * @var ColorConverter */ private $colorConverter; /** * @var array */ private $properties = []; public function __construct(Mpdf $mpdf, SizeConverter $sizeConverter, ColorConverter $colorConverter) { $this->mpdf = $mpdf; $this->sizeConverter = $sizeConverter; $this->colorConverter = $colorConverter; } /** * Process and expand CSS shorthand properties. * * Takes an array of CSS properties and expands shorthand properties * into their individual components (e.g., margin -> margin-top, margin-right, * margin-bottom, margin-left). Handles font, background, border, padding, * margin, and other composite properties. * * @param array $prop CSS properties array * @return array Expanded CSS properties array */ public function normalize($prop) { if (!is_array($prop) || count($prop) === 0) { return []; } $this->properties = []; foreach ($prop as $k => $v) { if ($k !== 'BACKGROUND-IMAGE' && $k !== 'BACKGROUND' && $k !== 'ODD-HEADER-NAME' && $k !== 'EVEN-HEADER-NAME' && $k !== 'ODD-FOOTER-NAME' && $k !== 'EVEN-FOOTER-NAME' && $k !== 'HEADER' && $k !== 'FOOTER') { $v = strtolower($v); } if ($k === 'FONT') { $this->processFontProperty($v); } elseif ($k === 'FONT-FAMILY') { $this->processFontFamilyProperty($k, $v); } elseif ($k === 'FONT-VARIANT') { $this->processFontVariantProperty($v); } elseif ($k === 'MARGIN') { $tmp = $this->expandShorthandProperty($v); $this->properties['MARGIN-TOP'] = $tmp['T']; $this->properties['MARGIN-RIGHT'] = $tmp['R']; $this->properties['MARGIN-BOTTOM'] = $tmp['B']; $this->properties['MARGIN-LEFT'] = $tmp['L']; } elseif ($k === 'BORDER-RADIUS' || $k === 'BORDER-TOP-LEFT-RADIUS' || $k === 'BORDER-TOP-RIGHT-RADIUS' || $k === 'BORDER-BOTTOM-LEFT-RADIUS' || $k === 'BORDER-BOTTOM-RIGHT-RADIUS') { $this->processBorderRadiusProperty($k, $v); } elseif ($k === 'PADDING') { $tmp = $this->expandShorthandProperty($v); $this->properties['PADDING-TOP'] = $tmp['T']; $this->properties['PADDING-RIGHT'] = $tmp['R']; $this->properties['PADDING-BOTTOM'] = $tmp['B']; $this->properties['PADDING-LEFT'] = $tmp['L']; } elseif (in_array($k, ['BORDER', 'BORDER-TOP', 'BORDER-RIGHT', 'BORDER-BOTTOM', 'BORDER-LEFT'], true)) { $this->processBorderProperty($k, $v); } elseif (in_array($k, ['BORDER-STYLE', 'BORDER-WIDTH', 'BORDER-COLOR', 'BORDER-SPACING'], true)) { $this->processBorderShorthandProperty($k, $v); } elseif ($k === 'TEXT-OUTLINE') { $this->processTextOutlineProperty($v); } elseif ($k === 'SIZE' || $k === 'SHEET-SIZE') { $this->processPageSizeProperty($k, $v); } elseif (in_array($k, ['BACKGROUND', 'BACKGROUND-IMAGE', 'BACKGROUND-REPEAT', 'BACKGROUND-POSITION'], true)) { $this->processBackgroundProperty($k, $v); } elseif ($k === 'IMAGE-ORIENTATION') { $this->processImageOrientationProperty($v); } elseif ($k === 'TEXT-ALIGN') { $this->processTextAlignProperty($k, $v); } elseif ($k === 'LIST-STYLE') { $this->processListStyleProperty($v); if (preg_match('/(inside|outside)/i', $v, $m)) { $this->properties['LIST-STYLE-POSITION'] = strtolower(trim($m[1])); } } else { $this->properties[$k] = $v; } } return $this->properties; } /** * Process FONT shorthand property. * * Expands the CSS font shorthand into individual components: * font-family, font-size, line-height, font-style, font-weight, text-transform. * * @param string $value Font property value * @return void */ protected function processFontProperty($value) { $value = $this->simplifyFontNames(trim($value)); $value = preg_replace('/\s*,\s*/', ',', $value); $bits = preg_split('/\s+/', $value); $numOfBits = count($bits); if ($numOfBits < 2) { return; } // Last item is font-family $this->properties['FONT-FAMILY'] = $bits[($numOfBits - 1)]; // Second to last is font-size (possibly with /line-height) $fs = $bits[($numOfBits - 2)]; if (preg_match('/(.*?)\/(.*)/', $fs, $fsp)) { $this->properties['FONT-SIZE'] = $fsp[1]; $this->properties['LINE-HEIGHT'] = $fsp[2]; } else { $this->properties['FONT-SIZE'] = $fs; } // Check for font-style if (preg_match('/(italic|oblique)/i', $value)) { $this->properties['FONT-STYLE'] = 'italic'; } else { $this->properties['FONT-STYLE'] = 'normal'; } // Check for font-weight if (stripos($value, 'bold') !== false) { $this->properties['FONT-WEIGHT'] = 'bold'; } else { $this->properties['FONT-WEIGHT'] = 'normal'; } // Check for small-caps if (stripos($value, 'small-caps') !== false) { $this->properties['TEXT-TRANSFORM'] = 'uppercase'; } } /** * Simplify font names by removing quotes. * * Helper method for processFontProperty to remove quotes from font names * to simplify subsequent parsing. * * @param string $value Font property value * @return string Simplified font property value */ protected function simplifyFontNames($value) { // Remove quoted font names and simplify preg_match_all('/"(.*?)"/', $value, $ff); foreach ($ff[1] as $ffp) { $w = preg_split('/\s+/', $ffp); $value = preg_replace('/"' . $ffp . '"/', $w[0], $value); } preg_match_all("/'(.*?)'/", $value, $ff); foreach ($ff[1] as $ffp) { $w = preg_split('/\s+/', $ffp); $value = preg_replace("/'" . $ffp . "'/", $w[0], $value); } return $value; } /** * Process FONT-VARIANT property. * * @param string $value Property value * @return void */ protected function processFontVariantProperty($value) { if (preg_match('/(normal|none)/', $value, $m)) { $this->properties['FONT-VARIANT-LIGATURES'] = $m[1]; $this->properties['FONT-VARIANT-CAPS'] = $m[1]; $this->properties['FONT-VARIANT-NUMERIC'] = $m[1]; $this->properties['FONT-VARIANT-ALTERNATES'] = $m[1]; return; } if (preg_match_all('/(no-common-ligatures|\bcommon-ligatures|no-discretionary-ligatures|\bdiscretionary-ligatures|no-historical-ligatures|\bhistorical-ligatures|no-contextual|\bcontextual)/i', $value, $m)) { $this->properties['FONT-VARIANT-LIGATURES'] = implode(' ', $m[1]); } if (preg_match('/(all-small-caps|\bsmall-caps|all-petite-caps|\bpetite-caps|unicase|titling-caps)/i', $value, $m)) { $this->properties['FONT-VARIANT-CAPS'] = $m[1]; } if (preg_match_all('/(lining-nums|oldstyle-nums|proportional-nums|tabular-nums|diagonal-fractions|stacked-fractions)/i', $value, $m)) { $this->properties['FONT-VARIANT-NUMERIC'] = implode(' ', $m[1]); } if (preg_match('/(historical-forms)/i', $value, $m)) { $this->properties['FONT-VARIANT-ALTERNATES'] = $m[1]; } } /** * Process FONT-FAMILY property. * * @param string $propertyKey Property key * @param string $value Font family value * @return void */ protected function processFontFamilyProperty($propertyKey, $value) { /* Normalize the font list */ $fontList = array_map( function ($fontName) { return trim($fontName, " \t\n\r\0\x0B\"'"); }, explode(',', $value) ); foreach ($fontList as $fontName) { $fontName = str_replace(' ', '', strtolower($fontName)); if (in_array($fontName, $this->mpdf->fontdata, true) || in_array($fontName, $this->mpdf->available_unifonts, true) || in_array($fontName, $this->mpdf->sans_fonts, true) || in_array($fontName, $this->mpdf->serif_fonts, true) || in_array($fontName, $this->mpdf->mono_fonts, true) || ($this->mpdf->onlyCoreFonts && in_array($fontName, ['courier', 'times', 'helvetica', 'arial'], true)) || in_array($fontName, ['sjis', 'uhc', 'big5', 'gb'], true) ) { $this->properties[$propertyKey] = $fontName; return; } } $this->properties[$propertyKey] = $fontList[0]; } /** * Process BORDER shorthand and individual border properties. * * Handles BORDER, BORDER-TOP, BORDER-RIGHT, BORDER-BOTTOM, BORDER-LEFT properties * by normalizing them to consistent "width style color" format. * * @param string $propertyKey Property key (BORDER, BORDER-TOP, etc.) * @param string $value Property value * @return void */ protected function processBorderProperty($propertyKey, $value) { switch ($propertyKey) { case 'BORDER': $value = $value !== '1' ? $this->normalizeBorderString($value) : '1px solid #000000'; $this->properties['BORDER-TOP'] = $value; $this->properties['BORDER-RIGHT'] = $value; $this->properties['BORDER-BOTTOM'] = $value; $this->properties['BORDER-LEFT'] = $value; break; case 'BORDER-TOP': $this->properties['BORDER-TOP'] = $this->normalizeBorderString($value); break; case 'BORDER-RIGHT': $this->properties['BORDER-RIGHT'] = $this->normalizeBorderString($value); break; case 'BORDER-BOTTOM': $this->properties['BORDER-BOTTOM'] = $this->normalizeBorderString($value); break; case 'BORDER-LEFT': $this->properties['BORDER-LEFT'] = $this->normalizeBorderString($value); break; } } /** * Process border shorthand properties (style, width, color). * * Handles BORDER-STYLE, BORDER-WIDTH, BORDER-COLOR, BORDER-SPACING. * * @param string $key Property key * @param string $value Property value * @return void */ protected function processBorderShorthandProperty($key, $value) { if ($key === 'BORDER-STYLE') { $e = $this->expandShorthandProperty($value); if (empty($e)) { return; } $this->properties['BORDER-TOP-STYLE'] = $e['T']; $this->properties['BORDER-RIGHT-STYLE'] = $e['R']; $this->properties['BORDER-BOTTOM-STYLE'] = $e['B']; $this->properties['BORDER-LEFT-STYLE'] = $e['L']; } elseif ($key === 'BORDER-WIDTH') { $e = $this->expandShorthandProperty($value); if (empty($e)) { return; } $this->properties['BORDER-TOP-WIDTH'] = $e['T']; $this->properties['BORDER-RIGHT-WIDTH'] = $e['R']; $this->properties['BORDER-BOTTOM-WIDTH'] = $e['B']; $this->properties['BORDER-LEFT-WIDTH'] = $e['L']; } elseif ($key === 'BORDER-COLOR') { $e = $this->expandShorthandProperty($value); if (empty($e)) { return; } $this->properties['BORDER-TOP-COLOR'] = $e['T']; $this->properties['BORDER-RIGHT-COLOR'] = $e['R']; $this->properties['BORDER-BOTTOM-COLOR'] = $e['B']; $this->properties['BORDER-LEFT-COLOR'] = $e['L']; } elseif ($key === 'BORDER-SPACING') { $prop = preg_split('/\s+/', trim($value)); if (count($prop) === 1) { $this->properties['BORDER-SPACING-H'] = $prop[0]; $this->properties['BORDER-SPACING-V'] = $prop[0]; } elseif (count($prop) === 2) { $this->properties['BORDER-SPACING-H'] = $prop[0]; $this->properties['BORDER-SPACING-V'] = $prop[1]; } } } /** * Parse CSS background shorthand property. * * Extracts background color, image, repeat, and position from the * background shorthand property. Supports gradients and url() images. * * @param string $s Background property value * @return array Array with keys 'c' (color), 'i' (image), 'r' (repeat), 'p' (position) */ protected function parseCssBackground($s) { $background = [ 'c' => false, // color 'i' => false, // image 'r' => false, // repeat 'p' => false, // position ]; if (preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient\(.*\)/i', $s, $m)) { $background['i'] = $m[0]; return $background; } if (preg_match('/url\(/i', $s)) { // If color, set and strip it off if (preg_match('/^\s*(#[0-9a-fA-F]{3,6}|(rgba|rgb|device-cmyka|cmyka|device-cmyk|cmyk|hsla|hsl|spot)\(.*?\)|[a-zA-Z]{3,})\s+(url\(.*)/i', $s, $m)) { $background['c'] = strtolower($m[1]); $s = $m[3]; } if (preg_match('/url\([\'\"]{0,1}(.*?)[\'\"]{0,1}\)\s*(.*)/i', $s, $m)) { $background['i'] = $m[1]; $s = strtolower($m[2]); if (preg_match('/(repeat-x|repeat-y|no-repeat|repeat)/', $s, $m)) { $background['r'] = $m[1]; } // Remove repeat, attachment (discarded) and also any inherit $s = preg_replace('/(repeat-x|repeat-y|no-repeat|repeat|scroll|fixed|inherit)/', '', $s); $bits = preg_split('/\s+/', trim($s)); $normalizedPosition = $this->normalizeBackgroundPosition($bits); if ($normalizedPosition !== false) { $background['p'] = $normalizedPosition; } } return $background; } if (preg_match('/^\s*(#[0-9a-fA-F]{3,6}|(rgba|rgb|device-cmyka|cmyka|device-cmyk|cmyk|hsla|hsl|spot)\(.*?\)|[a-zA-Z]{3,})/i', $s, $m)) { $background['c'] = strtolower($m[1]); } return $background; } /** * Expand 1-4 value CSS property into top/right/bottom/left components. * * Handles CSS properties that can be specified with 1-4 values following * the standard CSS clockwise pattern (top, right, bottom, left). * Used for margin, padding, border-width, border-style, and border-color. * * @param string $value Property value(s) separated by spaces * @return array Associative array with keys 'T', 'R', 'B', 'L' */ protected function expandShorthandProperty($value) { $property = preg_split('/\s+/', trim($value)); switch (count($property)) { case 0: return []; case 1: return [ 'T' => $property[0], 'R' => $property[0], 'B' => $property[0], 'L' => $property[0] ]; case 2: return [ 'T' => $property[0], 'R' => $property[1], 'B' => $property[0], 'L' => $property[1] ]; case 3: return [ 'T' => $property[0], 'R' => $property[1], 'B' => $property[2], 'L' => $property[1] ]; default: // Ignore rule parts after first 4 values (most likely !important) return [ 'T' => $property[0], 'R' => $property[1], 'B' => $property[2], 'L' => $property[3] ]; } } /** * Expand border-radius properties. * * Processes border-radius CSS properties and expands them into horizontal * and vertical components for each corner (TL, TR, BL, BR). * * @param string $val Border radius value(s) * @param string $k Property name (BORDER-RADIUS or specific corner) * @return array Array with keys like 'TL-H', 'TL-V', etc. */ protected function expandBorderRadius($val, $k) { if ($k === 'BORDER-RADIUS') { return $this->parseBorderRadiusShorthand($val); } return $this->parseBorderRadiusCorner($val, $k); } /** * Parse individual border-radius corner values. * * Helper method for expandBorderRadius to parse values for a specific corner. * * @param string $val Border radius value(s) * @param string $k Property name (specific corner) * @return array Array with keys like 'TL-H', 'TL-V', etc. */ protected function parseBorderRadiusCorner($val, $k) { $b = []; $prop = preg_split('/\s+/', trim($val)); if (count($prop) === 1) { $h = $v = $val; } else { $h = $prop[0]; $v = $prop[1]; } if ($h === 0 || $v === 0) { $h = $v = 0; } if ($k === 'BORDER-TOP-LEFT-RADIUS') { $b['TL-H'] = $h; $b['TL-V'] = $v; } elseif ($k === 'BORDER-TOP-RIGHT-RADIUS') { $b['TR-H'] = $h; $b['TR-V'] = $v; } elseif ($k === 'BORDER-BOTTOM-LEFT-RADIUS') { $b['BL-H'] = $h; $b['BL-V'] = $v; } elseif ($k === 'BORDER-BOTTOM-RIGHT-RADIUS') { $b['BR-H'] = $h; $b['BR-V'] = $v; } return $b; } /** * Parse border-radius shorthand values. * * Parses the slash syntax (horizontal/vertical) and expands 1-4 values * into individual corner components. * * @param string $val Border radius value(s) * @return array Array with keys 'TL-H', 'TR-H', 'BR-H', 'BL-H', 'TL-V', 'TR-V', 'BR-V', 'BL-V' */ protected function parseBorderRadiusShorthand($val) { $border = []; $radius = explode('/', trim($val)); $properties = preg_split('/\s+/', trim($radius[0])); // single radius if (count($properties) === 1) { $border['TL-H'] = $border['TR-H'] = $border['BR-H'] = $border['BL-H'] = $properties[0]; } elseif (count($properties) === 2) { $border['TL-H'] = $border['BR-H'] = $properties[0]; $border['TR-H'] = $border['BL-H'] = $properties[1]; } elseif (count($properties) === 3) { $border['TL-H'] = $properties[0]; $border['TR-H'] = $border['BL-H'] = $properties[1]; $border['BR-H'] = $properties[2]; } elseif (count($properties) === 4) { $border['TL-H'] = $properties[0]; $border['TR-H'] = $properties[1]; $border['BR-H'] = $properties[2]; $border['BL-H'] = $properties[3]; } // Check for two radius e.g. 10px / 20px if (count($radius) === 2) { $properties = preg_split('/\s+/', trim($radius[1])); if (count($properties) === 1) { $border['TL-V'] = $border['TR-V'] = $border['BR-V'] = $border['BL-V'] = $properties[0]; } elseif (count($properties) === 2) { $border['TL-V'] = $border['BR-V'] = $properties[0]; $border['TR-V'] = $border['BL-V'] = $properties[1]; } elseif (count($properties) === 3) { $border['TL-V'] = $properties[0]; $border['TR-V'] = $border['BL-V'] = $properties[1]; $border['BR-V'] = $properties[2]; } elseif (count($properties) === 4) { $border['TL-V'] = $properties[0]; $border['TR-V'] = $properties[1]; $border['BR-V'] = $properties[2]; $border['BL-V'] = $properties[3]; } return $border; } $border['TL-V'] = Arrays::get($border, 'TL-H', 0); $border['TR-V'] = Arrays::get($border, 'TR-H', 0); $border['BL-V'] = Arrays::get($border, 'BL-H', 0); $border['BR-V'] = Arrays::get($border, 'BR-H', 0); return $border; } /** * Normalize background position values. * * Converts background position keywords (top, bottom, left, right, center) * to percentage values and validates the format. * * @param array $bits Position components (1 or 2 values) * @return string|false Normalized position string or false if invalid */ protected function normalizeBackgroundPosition($bits) { $position = ''; $numOfBits = count($bits); if ($numOfBits === 1) { if (false !== strpos($bits[0], 'bottom')) { $position = '50% 100%'; } elseif (false !== strpos($bits[0], 'top')) { $position = '50% 0%'; } else { $position = $bits[0] . ' 50%'; } } elseif ($numOfBits === 2) { // Can be either right center or center right if (preg_match('/(top|bottom)/', $bits[0]) || preg_match('/(left|right)/', $bits[1])) { $position = $bits[1] . ' ' . $bits[0]; } else { $position = $bits[0] . ' ' . $bits[1]; } } if (empty($position)) { return false; } $position = preg_replace('/(left|top)/', '0%', $position); $position = preg_replace('/(right|bottom)/', '100%', $position); $position = preg_replace('/(center)/', '50%', $position); if (!preg_match('/[\-]{0,1}\d+(in|cm|mm|pt|pc|em|ex|px|%)* [\-]{0,1}\d+(in|cm|mm|pt|pc|em|ex|px|%)*/', $position)) { return false; } return $position; } /** * Parse and normalize border shorthand property. * * Converts border shorthand syntax into standardized "width style color" format. * Handles various input formats and orders. * * @param string $bd Border property value * @return string Normalized border string in format "width style color" */ protected function normalizeBorderString($bd) { preg_match_all("/\((.*?)\)/", $bd, $m); foreach ($m[1] as $i => $value) { $sub = str_replace(' ', '', $m[1][$i]); $bd = str_replace($m[1][$i], $sub, $bd); } $prop = preg_split('/\s+/', trim($bd)); if (count($prop) > 3) { return ''; } $parts = $this->parseBorderParts($prop); $w = $parts['w']; $s = $parts['s']; $c = $parts['c']; $s = strtolower($s); return $w . ' ' . $s . ' ' . $c; } /** * Parse border property parts (width, style, color). * * Helper method for normalizeBorderString to determine width, style, and color * from split border property string. * * @param array $prop Split border property string * @return array Array containing 'w' (width), 's' (style), 'c' (color) */ protected function parseBorderParts($prop) { $width = 'medium'; $color = '#000000'; $style = 'none'; switch (count($prop)) { case 1: if (in_array($prop[0], $this->mpdf->borderstyles, true) || $prop[0] === 'none' || $prop[0] === 'hidden') { $style = $prop[0]; } elseif (is_array($this->colorConverter->convert($prop[0], $this->mpdf->PDFAXwarnings))) { $color = $prop[0]; } else { $width = $prop[0]; } break; case 2: if (in_array($prop[1], $this->mpdf->borderstyles, true) || $prop[1] === 'none' || $prop[1] === 'hidden') { $width = $prop[0]; $style = $prop[1]; } elseif (in_array($prop[0], $this->mpdf->borderstyles, true) || $prop[0] === 'none' || $prop[0] === 'hidden') { $style = $prop[0]; $color = $prop[1]; } else { $width = $prop[0]; $color = $prop[1]; } break; case 3: if (0 === strpos($prop[0], '#')) { $color = $prop[0]; $width = $prop[1]; $style = $prop[2]; } elseif (substr($prop[0], 1, 1) === '#') { $style = $prop[0]; $color = $prop[1]; $width = $prop[2]; } elseif (in_array($prop[0], $this->mpdf->borderstyles) || $prop[0] === 'none' || $prop[0] === 'hidden') { $style = $prop[0]; $width = $prop[1]; $color = $prop[2]; } else { $width = $prop[0]; $style = $prop[1]; $color = $prop[2]; } break; } return ['w' => $width, 's' => $style, 'c' => $color]; } /** * Process background related CSS properties. * * Handles BACKGROUND, BACKGROUND-IMAGE, BACKGROUND-REPEAT, and BACKGROUND-POSITION. * * @param string $property Property name * @param string $value Property value * @return void */ protected function processBackgroundProperty($property, $value) { switch ($property) { case 'BACKGROUND': $bg = $this->parseCssBackground($value); if ($bg['c']) { $this->properties['BACKGROUND-COLOR'] = $bg['c']; } else { $this->properties['BACKGROUND-COLOR'] = 'transparent'; } if ($bg['i']) { $this->properties['BACKGROUND-IMAGE'] = $bg['i']; if ($bg['r']) { $this->properties['BACKGROUND-REPEAT'] = $bg['r']; } if ($bg['p']) { $this->properties['BACKGROUND-POSITION'] = $bg['p']; } } else { $this->properties['BACKGROUND-IMAGE'] = ''; } break; case 'BACKGROUND-IMAGE': if (preg_match('/(-moz-)*(repeating-)*(linear|radial)-gradient\(.*\)/i', $value, $m)) { $this->properties['BACKGROUND-IMAGE'] = $m[0]; return; } if (preg_match('/url\([\'\"]{0,1}(.*?)[\'\"]{0,1}\)/i', $value, $m)) { $this->properties['BACKGROUND-IMAGE'] = $m[1]; } elseif (strtolower($value) === 'none') { $this->properties['BACKGROUND-IMAGE'] = ''; } break; case 'BACKGROUND-REPEAT': if (preg_match('/(repeat-x|repeat-y|no-repeat|repeat)/i', $value, $m)) { $this->properties['BACKGROUND-REPEAT'] = strtolower($m[1]); } break; case 'BACKGROUND-POSITION': $bits = preg_split('/\s+/', trim($value)); $normalizedPosition = $this->normalizeBackgroundPosition($bits); if ($normalizedPosition !== false) { $this->properties['BACKGROUND-POSITION'] = $normalizedPosition; } break; } } /** * Process border radius property. * * @param string $property Property name * @param string $value Property value * @return void */ protected function processBorderRadiusProperty($property, $value) { $borderRadius = $this->expandBorderRadius($value, $property); if (isset($borderRadius['TL-H'])) { $this->properties['BORDER-TOP-LEFT-RADIUS-H'] = $borderRadius['TL-H']; } if (isset($borderRadius['TL-V'])) { $this->properties['BORDER-TOP-LEFT-RADIUS-V'] = $borderRadius['TL-V']; } if (isset($borderRadius['TR-H'])) { $this->properties['BORDER-TOP-RIGHT-RADIUS-H'] = $borderRadius['TR-H']; } if (isset($borderRadius['TR-V'])) { $this->properties['BORDER-TOP-RIGHT-RADIUS-V'] = $borderRadius['TR-V']; } if (isset($borderRadius['BL-H'])) { $this->properties['BORDER-BOTTOM-LEFT-RADIUS-H'] = $borderRadius['BL-H']; } if (isset($borderRadius['BL-V'])) { $this->properties['BORDER-BOTTOM-LEFT-RADIUS-V'] = $borderRadius['BL-V']; } if (isset($borderRadius['BR-H'])) { $this->properties['BORDER-BOTTOM-RIGHT-RADIUS-H'] = $borderRadius['BR-H']; } if (isset($borderRadius['BR-V'])) { $this->properties['BORDER-BOTTOM-RIGHT-RADIUS-V'] = $borderRadius['BR-V']; } } /** * Process text outline CSS properties. * * Handles TEXT-OUTLINE shorthand. * * @param string $v Property value * @return void */ protected function processTextOutlineProperty($v) { $prop = preg_split('/\s+/', trim($v)); if (strtolower(trim($v)) === 'none') { $this->properties['TEXT-OUTLINE'] = 'none'; } elseif (count($prop) === 2) { $this->properties['TEXT-OUTLINE-WIDTH'] = $prop[0]; $this->properties['TEXT-OUTLINE-COLOR'] = $prop[1]; } elseif (count($prop) === 3) { $this->properties['TEXT-OUTLINE-WIDTH'] = $prop[0]; $this->properties['TEXT-OUTLINE-COLOR'] = $prop[2]; } } /** * Process page size CSS properties. * * Handles SIZE and SHEET-SIZE properties. * * @param string $property Property name * @param string $value Property value * @return void */ protected function processPageSizeProperty($property, $value) { $value = preg_split('/\s+/', trim($value)); switch ($property) { case 'SIZE': if (preg_match('/(auto|portrait|landscape)/', $value[0])) { $this->properties['SIZE'] = strtoupper($value[0]); } elseif (count($value) === 1) { $this->properties['SIZE']['W'] = $this->sizeConverter->convert($value[0]); $this->properties['SIZE']['H'] = $this->sizeConverter->convert($value[0]); } elseif (count($value) === 2) { $this->properties['SIZE']['W'] = $this->sizeConverter->convert($value[0]); $this->properties['SIZE']['H'] = $this->sizeConverter->convert($value[1]); } break; case 'SHEET-SIZE': if (count($value) === 2) { $this->properties['SHEET-SIZE'] = [ $this->sizeConverter->convert($value[0]), $this->sizeConverter->convert($value[1]) ]; } else { if (preg_match('/([0-9a-zA-Z]*)-L/i', $value[0], $m)) { // e.g. A4-L = A$ landscape $ft = PageFormat::getSizeFromName($m[1]); $format = [$ft[1], $ft[0]]; } else { $format = PageFormat::getSizeFromName($value[0]); } if ($format) { $this->properties['SHEET-SIZE'] = [$format[0] / Mpdf::SCALE, $format[1] / Mpdf::SCALE]; } } break; } } /** * Process image orientation CSS properties. * * Handles IMAGE-ORIENTATION property. * * @param string $v Property value * @return void */ protected function processImageOrientationProperty($v) { if (!preg_match('/([\-]*[0-9.]+)(deg|grad|rad)/i', $v, $m)) { return; } $angle = (float) $m[1]; if (strtolower($m[2]) === 'grad') { $angle *= (360 / 400); } elseif (strtolower($m[2]) === 'rad') { $angle = rad2deg($angle); } while ($angle < 0) { $angle += 360; } $angle %= 360; $angle /= 90; $angle = round($angle) * 90; $this->properties['IMAGE-ORIENTATION'] = $angle; } /** * Process text align CSS properties. * * Handles TEXT-ALIGN property including decimal alignment. * * @param string $k Property name * @param string $v Property value * @return void */ protected function processTextAlignProperty($k, $v) { if (preg_match('/["\'](.){1}["\']/i', $v, $m)) { $d = array_search($m[1], $this->mpdf->decimal_align); if ($d !== false) { $this->properties['TEXT-ALIGN'] = $d; } if (preg_match('/(center|left|right)/i', $v, $m)) { $this->properties['TEXT-ALIGN'] .= strtoupper(substr($m[1], 0, 1)); } else { $this->properties['TEXT-ALIGN'] .= 'R'; } // default = R } elseif (preg_match('/["\'](\\\\[a-fA-F0-9]{1,6})["\']/i', $v, $m)) { $utf8 = UtfString::codeHex2utf(substr($m[1], 1, 6)); $d = array_search($utf8, $this->mpdf->decimal_align); if ($d !== false) { $this->properties['TEXT-ALIGN'] = $d; } if (preg_match('/(center|left|right)/i', $v, $m)) { $this->properties['TEXT-ALIGN'] .= strtoupper(substr($m[1], 0, 1)); } else { $this->properties['TEXT-ALIGN'] .= 'R'; } // default = R } else { $this->properties[$k] = $v; } } /** * Process list style CSS properties. * * Handles LIST-STYLE property. * * @param string $v Property value * @return void */ protected function processListStyleProperty($v) { if (preg_match('/none/i', $v, $m)) { $this->properties['LIST-STYLE-TYPE'] = 'none'; $this->properties['LIST-STYLE-IMAGE'] = 'none'; } if (preg_match('/(lower-roman|upper-roman|lower-latin|lower-alpha|upper-latin|upper-alpha|decimal|disc|circle|square|arabic-indic|bengali|devanagari|gujarati|gurmukhi|kannada|malayalam|oriya|persian|tamil|telugu|thai|urdu|cambodian|khmer|lao|cjk-decimal|hebrew)/i', $v, $m)) { $this->properties['LIST-STYLE-TYPE'] = strtolower(trim($m[1])); } elseif (preg_match('/U\+([a-fA-F0-9]+)/i', $v, $m)) { $this->properties['LIST-STYLE-TYPE'] = strtolower(trim($m[1])); } if (preg_match('/url\([\'\"]{0,1}(.*?)[\'\"]{0,1}\)/i', $v, $m)) { $this->properties['LIST-STYLE-IMAGE'] = strtolower(trim($m[1])); } } }
Coded With 💗 by
0x6ick Mod By V1rus_Alfa