/**
  * Attempts to return a conrete PDF instance.
  *
  * It allows to set up the page format, the orientation and the units of
  * measurement used in all the methods (except for the font sizes).
  *
  * Example:
  * <code>
  * $pdf = File_PDF::factory(array('orientation' => 'P',
  *                                'unit' => 'mm',
  *                                'format' => 'A4'));
  * </code>
  *
  * @param array $params  A hash with parameters for the created PDF object.
  *                       Possible parameters are:
  *                       - orientation - Default page orientation. Possible
  *                         values are (case insensitive):
  *                         - P or Portrait (default)
  *                         - L or Landscape
  *                       - unit - User measure units. Possible values
  *                         values are:
  *                         - pt: point
  *                         - mm: millimeter (default)
  *                         - cm: centimeter
  *                         - in: inch
  *                         A point equals 1/72 of inch, that is to say
  *                         about 0.35 mm (an inch being 2.54 cm). This is a
  *                         very common unit in typography; font sizes are
  *                         expressed in that unit.
  *                       - format - The format used for pages. It can be
  *                         either one of the following values (case
  *                         insensitive):
  *                         - A3
  *                         - A4 (default)
  *                         - A5
  *                         - Letter
  *                         - Legal
  *                         or a custom format in the form of a two-element
  *                         array containing the width and the height
  *                         (expressed in the unit given by the unit
  *                         parameter).
  * @param string $class  The concrete class name to return an instance of.
  *                       Defaults to File_PDF.
  */
 function &factory($params = array(), $class = 'File_PDF')
 {
     /* Default parameters. */
     $defaults = array('orientation' => 'P', 'unit' => 'mm', 'format' => 'A4');
     /* Backward compatibility with old method signature. */
     /* Should be removed a few versions later. */
     if (!is_array($params)) {
         $class = 'File_PDF';
         $params = $defaults;
         $names = array_keys($defaults);
         for ($i = 0; $i < func_num_args(); $i++) {
             $params[$names[$i]] = func_get_arg($i);
         }
     } else {
         $params = array_merge($defaults, $params);
     }
     /* Create the PDF object. */
     $pdf = new $class($params);
     /* Scale factor. */
     if ($params['unit'] == 'pt') {
         $pdf->_scale = 1;
     } elseif ($params['unit'] == 'mm') {
         $pdf->_scale = 72 / 25.4;
     } elseif ($params['unit'] == 'cm') {
         $pdf->_scale = 72 / 2.54;
     } elseif ($params['unit'] == 'in') {
         $pdf->_scale = 72;
     } else {
         $error = File_PDF::raiseError(sprintf('Incorrect units: %s', $params['unit']));
         return $error;
     }
     /* Page format. */
     if (is_string($params['format'])) {
         $params['format'] = strtolower($params['format']);
         if ($params['format'] == 'a3') {
             $params['format'] = array(841.89, 1190.55);
         } elseif ($params['format'] == 'a4') {
             $params['format'] = array(595.28, 841.89);
         } elseif ($params['format'] == 'a5') {
             $params['format'] = array(420.94, 595.28);
         } elseif ($params['format'] == 'letter') {
             $params['format'] = array(612, 792);
         } elseif ($params['format'] == 'legal') {
             $params['format'] = array(612, 1008);
         } else {
             $error = File_PDF::raiseError(sprintf('Unknown page format: %s', $params['format']));
             return $error;
         }
         $pdf->fwPt = $params['format'][0];
         $pdf->fhPt = $params['format'][1];
     } else {
         $pdf->fwPt = $params['format'][0] * $pdf->_scale;
         $pdf->fhPt = $params['format'][1] * $pdf->_scale;
     }
     $pdf->fw = $pdf->fwPt / $pdf->_scale;
     $pdf->fh = $pdf->fhPt / $pdf->_scale;
     /* Page orientation. */
     $params['orientation'] = strtolower($params['orientation']);
     if ($params['orientation'] == 'p' || $params['orientation'] == 'portrait') {
         $pdf->_default_orientation = 'P';
         $pdf->wPt = $pdf->fwPt;
         $pdf->hPt = $pdf->fhPt;
     } elseif ($params['orientation'] == 'l' || $params['orientation'] == 'landscape') {
         $pdf->_default_orientation = 'L';
         $pdf->wPt = $pdf->fhPt;
         $pdf->hPt = $pdf->fwPt;
     } else {
         $error = File_PDF::raiseError(sprintf('Incorrect orientation: %s', $params['orientation']));
         return $error;
     }
     $pdf->_current_orientation = $pdf->_default_orientation;
     $pdf->w = $pdf->wPt / $pdf->_scale;
     $pdf->h = $pdf->hPt / $pdf->_scale;
     /* Page margins (1 cm) */
     $margin = 28.35 / $pdf->_scale;
     $pdf->setMargins($margin, $margin);
     /* Interior cell margin (1 mm) */
     $pdf->_cell_margin = $margin / 10;
     /* Line width (0.2 mm) */
     $pdf->_line_width = 0.5669999999999999 / $pdf->_scale;
     /* Automatic page break */
     $pdf->setAutoPageBreak(true, 2 * $margin);
     /* Full width display mode */
     $pdf->setDisplayMode('fullwidth');
     /* Compression */
     $pdf->setCompression(true);
     return $pdf;
 }