Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]

   1  <?php
   2  
   3  namespace PhpOffice\PhpSpreadsheet\Shared;
   4  
   5  use GdImage;
   6  
   7  class Drawing
   8  {
   9      /**
  10       * Convert pixels to EMU.
  11       *
  12       * @param int $pValue Value in pixels
  13       *
  14       * @return int Value in EMU
  15       */
  16      public static function pixelsToEMU($pValue)
  17      {
  18          return round($pValue * 9525);
  19      }
  20  
  21      /**
  22       * Convert EMU to pixels.
  23       *
  24       * @param int $pValue Value in EMU
  25       *
  26       * @return int Value in pixels
  27       */
  28      public static function EMUToPixels($pValue)
  29      {
  30          if ($pValue != 0) {
  31              return round($pValue / 9525);
  32          }
  33  
  34          return 0;
  35      }
  36  
  37      /**
  38       * Convert pixels to column width. Exact algorithm not known.
  39       * By inspection of a real Excel file using Calibri 11, one finds 1000px ~ 142.85546875
  40       * This gives a conversion factor of 7. Also, we assume that pixels and font size are proportional.
  41       *
  42       * @param int $pValue Value in pixels
  43       * @param \PhpOffice\PhpSpreadsheet\Style\Font $pDefaultFont Default font of the workbook
  44       *
  45       * @return int Value in cell dimension
  46       */
  47      public static function pixelsToCellDimension($pValue, \PhpOffice\PhpSpreadsheet\Style\Font $pDefaultFont)
  48      {
  49          // Font name and size
  50          $name = $pDefaultFont->getName();
  51          $size = $pDefaultFont->getSize();
  52  
  53          if (isset(Font::$defaultColumnWidths[$name][$size])) {
  54              // Exact width can be determined
  55              $colWidth = $pValue * Font::$defaultColumnWidths[$name][$size]['width'] / Font::$defaultColumnWidths[$name][$size]['px'];
  56          } else {
  57              // We don't have data for this particular font and size, use approximation by
  58              // extrapolating from Calibri 11
  59              $colWidth = $pValue * 11 * Font::$defaultColumnWidths['Calibri'][11]['width'] / Font::$defaultColumnWidths['Calibri'][11]['px'] / $size;
  60          }
  61  
  62          return $colWidth;
  63      }
  64  
  65      /**
  66       * Convert column width from (intrinsic) Excel units to pixels.
  67       *
  68       * @param float $pValue Value in cell dimension
  69       * @param \PhpOffice\PhpSpreadsheet\Style\Font $pDefaultFont Default font of the workbook
  70       *
  71       * @return int Value in pixels
  72       */
  73      public static function cellDimensionToPixels($pValue, \PhpOffice\PhpSpreadsheet\Style\Font $pDefaultFont)
  74      {
  75          // Font name and size
  76          $name = $pDefaultFont->getName();
  77          $size = $pDefaultFont->getSize();
  78  
  79          if (isset(Font::$defaultColumnWidths[$name][$size])) {
  80              // Exact width can be determined
  81              $colWidth = $pValue * Font::$defaultColumnWidths[$name][$size]['px'] / Font::$defaultColumnWidths[$name][$size]['width'];
  82          } else {
  83              // We don't have data for this particular font and size, use approximation by
  84              // extrapolating from Calibri 11
  85              $colWidth = $pValue * $size * Font::$defaultColumnWidths['Calibri'][11]['px'] / Font::$defaultColumnWidths['Calibri'][11]['width'] / 11;
  86          }
  87  
  88          // Round pixels to closest integer
  89          $colWidth = (int) round($colWidth);
  90  
  91          return $colWidth;
  92      }
  93  
  94      /**
  95       * Convert pixels to points.
  96       *
  97       * @param int $pValue Value in pixels
  98       *
  99       * @return float Value in points
 100       */
 101      public static function pixelsToPoints($pValue)
 102      {
 103          return $pValue * 0.75;
 104      }
 105  
 106      /**
 107       * Convert points to pixels.
 108       *
 109       * @param int $pValue Value in points
 110       *
 111       * @return int Value in pixels
 112       */
 113      public static function pointsToPixels($pValue)
 114      {
 115          if ($pValue != 0) {
 116              return (int) ceil($pValue / 0.75);
 117          }
 118  
 119          return 0;
 120      }
 121  
 122      /**
 123       * Convert degrees to angle.
 124       *
 125       * @param int $pValue Degrees
 126       *
 127       * @return int Angle
 128       */
 129      public static function degreesToAngle($pValue)
 130      {
 131          return (int) round($pValue * 60000);
 132      }
 133  
 134      /**
 135       * Convert angle to degrees.
 136       *
 137       * @param int $pValue Angle
 138       *
 139       * @return int Degrees
 140       */
 141      public static function angleToDegrees($pValue)
 142      {
 143          if ($pValue != 0) {
 144              return round($pValue / 60000);
 145          }
 146  
 147          return 0;
 148      }
 149  
 150      /**
 151       * Create a new image from file. By alexander at alexauto dot nl.
 152       *
 153       * @see http://www.php.net/manual/en/function.imagecreatefromwbmp.php#86214
 154       *
 155       * @param string $p_sFile Path to Windows DIB (BMP) image
 156       *
 157       * @return GdImage|resource
 158       */
 159      public static function imagecreatefrombmp($p_sFile)
 160      {
 161          //    Load the image into a string
 162          $file = fopen($p_sFile, 'rb');
 163          $read = fread($file, 10);
 164          while (!feof($file) && ($read != '')) {
 165              $read .= fread($file, 1024);
 166          }
 167  
 168          $temp = unpack('H*', $read);
 169          $hex = $temp[1];
 170          $header = substr($hex, 0, 108);
 171  
 172          //    Process the header
 173          //    Structure: http://www.fastgraph.com/help/bmp_header_format.html
 174          if (substr($header, 0, 4) == '424d') {
 175              //    Cut it in parts of 2 bytes
 176              $header_parts = str_split($header, 2);
 177  
 178              //    Get the width        4 bytes
 179              $width = hexdec($header_parts[19] . $header_parts[18]);
 180  
 181              //    Get the height        4 bytes
 182              $height = hexdec($header_parts[23] . $header_parts[22]);
 183  
 184              //    Unset the header params
 185              unset($header_parts);
 186          }
 187  
 188          //    Define starting X and Y
 189          $x = 0;
 190          $y = 1;
 191  
 192          //    Create newimage
 193          $image = imagecreatetruecolor($width, $height);
 194  
 195          //    Grab the body from the image
 196          $body = substr($hex, 108);
 197  
 198          //    Calculate if padding at the end-line is needed
 199          //    Divided by two to keep overview.
 200          //    1 byte = 2 HEX-chars
 201          $body_size = (strlen($body) / 2);
 202          $header_size = ($width * $height);
 203  
 204          //    Use end-line padding? Only when needed
 205          $usePadding = ($body_size > ($header_size * 3) + 4);
 206  
 207          //    Using a for-loop with index-calculation instaid of str_split to avoid large memory consumption
 208          //    Calculate the next DWORD-position in the body
 209          for ($i = 0; $i < $body_size; $i += 3) {
 210              //    Calculate line-ending and padding
 211              if ($x >= $width) {
 212                  // If padding needed, ignore image-padding
 213                  // Shift i to the ending of the current 32-bit-block
 214                  if ($usePadding) {
 215                      $i += $width % 4;
 216                  }
 217  
 218                  //    Reset horizontal position
 219                  $x = 0;
 220  
 221                  //    Raise the height-position (bottom-up)
 222                  ++$y;
 223  
 224                  //    Reached the image-height? Break the for-loop
 225                  if ($y > $height) {
 226                      break;
 227                  }
 228              }
 229  
 230              // Calculation of the RGB-pixel (defined as BGR in image-data)
 231              // Define $i_pos as absolute position in the body
 232              $i_pos = $i * 2;
 233              $r = hexdec($body[$i_pos + 4] . $body[$i_pos + 5]);
 234              $g = hexdec($body[$i_pos + 2] . $body[$i_pos + 3]);
 235              $b = hexdec($body[$i_pos] . $body[$i_pos + 1]);
 236  
 237              // Calculate and draw the pixel
 238              $color = imagecolorallocate($image, $r, $g, $b);
 239              imagesetpixel($image, $x, $height - $y, $color);
 240  
 241              // Raise the horizontal position
 242              ++$x;
 243          }
 244  
 245          // Unset the body / free the memory
 246          unset($body);
 247  
 248          //    Return image-object
 249          return $image;
 250      }
 251  }