Skip to content

Commit

Permalink
Conversion of arbitrary absolute CSS units
Browse files Browse the repository at this point in the history
- utility functions to parse lengths given in absolute CSS units (in. px,
mm, cm, pc)
  • Loading branch information
ejn committed Jun 27, 2017
1 parent 4decaff commit 02508f2
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 0 deletions.
117 changes: 117 additions & 0 deletions src/PhpWord/Shared/Converter.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

namespace PhpOffice\PhpWord\Shared;

use PhpOffice\PhpWord\Exception\InvalidStyleException;

/**
* Common converter functions
*/
Expand Down Expand Up @@ -227,6 +229,121 @@ public static function emuToPixel($emu = 1)
return round($emu / self::PIXEL_TO_EMU);
}

/**
* Convert an absolute CSS measurement to pixels
*
* Units for absolute CSS measurements are cm, mm, in, px, pt and pc
*
* Note that the result will be rounded to the nearest pixel
*
* @param string $cssMeasurement If no measurement unit is included then cm
* is assumed
*
* @throws \PHPOffice\PhpWord\Exception\InvalidStyleException
*
* @return float
*/
public static function cssToPixel($cssMeasurement = '1cm')
{
$units = trim(preg_replace('/^-?(?:\\d+\\.\\d+|\\.?\\d+)/', '', trim($cssMeasurement)));
$value = preg_replace('/\\D+$/', '', trim($cssMeasurement));
if ((strlen($value) > 0) && ($value[0] == '.')) {
$value = '0' . $value;
}
switch (strtolower($units)) {
case 'in':
$pixel = $value * static::INCH_TO_PIXEL;
break;
case 'cm':
case '':
$pixel = ($value / static::INCH_TO_CM) * static::INCH_TO_PIXEL;
break;
case 'mm':
$pixel = ($value / (10 * static::INCH_TO_CM)) * static::INCH_TO_PIXEL;
break;
case 'pt':
$pixel = ($value / static::INCH_TO_POINT) * static::INCH_TO_PIXEL;
break;
case 'pc':
$pixel = ($value / (12 * static::INCH_TO_POINT)) * static::INCH_TO_PIXEL;
break;
case 'px':
$pixel = floatval($value);
break;
default:
throw new InvalidStyleException($cssMeasurement . ' is an unsupported CSS measurement');
}
return $pixel;
}

/**
* Convert an absolute CSS measurement to EMU
*
* Units for absolute CSS measurements are cm, mm, in, px, pt and pc
*
* @param string $cssMeasurement If no measurement unit is included then cm
* is assumed
*
* @throws \PHPOffice\PhpWord\Exception\InvalidStyleException
*
* @return float
*/
public static function cssToEmu($cssMeasurement = '1cm')
{
return static::cssToPixel($cssMeasurement) * static::PIXEL_TO_EMU;
}

/**
* Convert an absolute CSS measurement to point
*
* Units for absolute CSS measurements are cm, mm, in, px, pt and pc
*
* @param string $cssMeasurement If no measurement unit is included then cm
* is assumed
*
* @throws \PHPOffice\PhpWord\Exception\InvalidStyleException
*
* @return float
*/
public static function cssToPoint($cssMeasurement = '1cm')
{
return static::cssToPixel($cssMeasurement) * static::INCH_TO_POINT / static::INCH_TO_PIXEL;
}

/**
* Convert an absolute CSS measurement to twip
*
* Units for absolute CSS measurements are cm, mm, in, px, pt and pc
*
* @param string $cssMeasurement If no measurement unit is included then cm
* is assumed
*
* @throws \PHPOffice\PhpWord\Exception\InvalidStyleException
*
* @return float
*/
public static function cssToTwip($cssMeasurement = '1cm')
{
return static::cssToPixel($cssMeasurement) * static::INCH_TO_TWIP / static::INCH_TO_PIXEL;
}

/**
* Convert an absolute CSS measurement to centimeter
*
* Units for absolute CSS measurements are cm, mm, in, px, pt and pc
*
* @param string $cssMeasurement If no measurement unit is included then cm
* is assumed
*
* @throws \PHPOffice\PhpWord\Exception\InvalidStyleException
*
* @return float
*/
public static function cssToCm($cssMeasurement = '1cm')
{
return static::cssToPixel($cssMeasurement) * static::INCH_TO_CM / static::INCH_TO_PIXEL;
}

/**
* Convert degree to angle
*
Expand Down
80 changes: 80 additions & 0 deletions tests/PhpWord/Shared/ConverterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,84 @@ public function testHtmlToRGB()
$this->assertEquals($value[1], $result);
}
}

/**
* @covers ::cssToPixel
* @test
*/
public function testCssToPixel()
{
// Prepare test values [ original, expected ]
$values[] = array('1pt', (1 / 72) * 96);
$values[] = array('10.5pc', (10.5 / (72 * 12)) * 96);
$values[] = array('4cm', (4 / 2.54) * 96);
$values[] = array('1', (1 / 2.54) * 96);
$values[] = array('2mm', (0.2 / 2.54) * 96);
$values[] = array('.1', (0.1 / 2.54) * 96);
$values[] = array('2in', 2 * 96);
foreach ($values as $value) {
$result = Converter::cssToPixel($value[0]);
$this->assertEquals($value[1], $result);
}
}

/**
* @covers ::cssToEmu
* @test
*/
public function testCssToEmu()
{
// Prepare test values [ original, expected ]
$values[] = array('1pt', (1 / 72) * 96 * 9525);
$values[] = array('10.5pc', (10.5 / (72 * 12)) * 96 * 9525);
$values[] = array('4cm', (4 / 2.54) * 96 * 9525);
$values[] = array('1', (1 / 2.54) * 96 * 9525);
$values[] = array('2mm', (0.2 / 2.54) * 96 * 9525);
$values[] = array('.1', (0.1 / 2.54) * 96 * 9525);
$values[] = array('2in', 2 * 96 * 9525);
foreach ($values as $value) {
$result = Converter::cssToEmu($value[0]);
$this->assertEquals($value[1], $result);
}
}

/**
* @covers ::cssToCm
* @test
*/
public function testCssToCm()
{
// Prepare test values [ original, expected ]
$values[] = array('1pt', (1 / 72) * 2.54);
$values[] = array('10.5pc', (10.5 / (72 * 12)) * 2.54);
$values[] = array('4cm', 4);
$values[] = array('1', 1);
$values[] = array('2mm', 2 / 10);
$values[] = array('.1', 1 / 10);
$values[] = array('2in', 2 * 2.54);
foreach ($values as $value) {
$result = Converter::cssToCm($value[0]);
$this->assertEquals($value[1], $result);
}
}

/**
* @covers ::cssToTwip
* @test
*/
public function testCssToTwip()
{
// Prepare test values [ original, expected ]
$values[] = array('1pt', (1 / 72) * 1440);
$values[] = array('10.5pc', (10.5 / (72 * 12)) * 1440);
$values[] = array('4cm', (4 / 2.54) * 1440);
$values[] = array('1', (1 / 2.54) * 1440);
$values[] = array('2mm', (0.2 / 2.54) * 1440);
$values[] = array('.1', (0.1 / 2.54) * 1440);
$values[] = array('2in', 2 * 1440);
foreach ($values as $value) {
$result = Converter::cssToTwip($value[0]);
$this->assertEquals($value[1], $result);
}
}
}

0 comments on commit 02508f2

Please sign in to comment.