line height variances between HTML in browser and PDF output

2,695 views
Skip to first unread message

Dan Steeby

unread,
Nov 23, 2015, 5:48:51 PM11/23/15
to dompdf
We are trying to develop a publishing tool where users use an HTML editor to create content and then output that content as a PDF using DOMPDF.  We are making use of a lot of fonts and have found that there is a variance between them all between what is viewed in the browser and what is output in the PDF file regarding the line height.  I have found and tried adjusting the DOMPDF_FONT_HEIGHT_RATIO setting in the DOMPDF config file, but this seems to only be a solution for using a single font, as what works for one font does not seem to work well for others.  To address this, our best solution currently is to write custom style rules for the PDF output that is not rendered in the HTML preview, and then manually set these styles for each instance that the font size or font famlily changes to preserve the height of a line to a near-pixel-perfect solution.  Here is an example of what we are having to do:

.front-cover {
font-family: ptsans;
font-size: 12pt;
line-height: 12pt;
}
body.pdf .front-cover { line-height: 10.5pt }

In short, the html preview does not have a 'pdf' class attached to its body, so the second style rule is not applied in the browser, but when the html is passed to DOMPDF to be rendered, the 'pdf' class is attached to the body, so all those special rules kick in.  For this particular font, we have to adjust the line height from 12pt down to 10.5pt to get the same line height as the HTML preview, but this ratio is different for each font that we test with, so we have to write rules for each font we want to work with.  Also, the scale does not seem consistent, in that if we set the percentage to 87.5% (which is 10.5/12 or the same ratio set up above with fixed numbers), the line heights look consistent for fonts at 12pt, but if we change the font size, the line height gets off again in spite of using a percentage to calculate the line height based on the font size.  So, using percentages to illustrate, an accurate comparison of the ptsans font works with line height of 87.5% when its font size is 12 pt, but a different percentage is needed for a different font size to remain accurate to the HTML view.  If this is the case, we can't easily get consistent line heights and I think a lot of extra CSS would have to be written to handle this.

Is there any trick that I have overlooked that may help with this issue, or is there anything that others are doing to handle or compensate for this?  We are hoping to introduce a solution that includes a lot of fonts, and this issue may be a major hurdle in our project if we want to keep the PDF output looking consistently like our HTML content that we are feeding it. Any thoughts are appreciated.

BrianS

unread,
Dec 8, 2015, 12:38:58 PM12/8/15
to dompdf
Which version of dompdf are you using? The line height is determined based on the font metrics generated by php-font-lib. If you're not already you might try out the 0.7.0 beta to see if the updated version of php-font-lib used with that release produces better metrics.

If that doesn't work you might try tweaking the font metrics. Line height is based on the font height and is determined (in CPDF) by the ascender/descender metrics. If those aren't present the upper and lower bounds of the bounding box is used. I wouldn't modify those values, however. You can supply a FontHeightOffset value in the metrics to tweak the height of the font.

The down side is that you'll still need to tweak each font individually.

HTH
-b

Dan Steeby

unread,
Dec 14, 2015, 2:46:53 PM12/14/15
to dompdf
Hi Brian,

I have upgraded to 0.7.0 beta 2, but my current codebase is not playing well with it.  I have previously instantiated DOMPDF with:

require_once( '/path/to/dompdf/dompdf_config.inc.php' ); # LOAD DOMPDF

I see that config files have been eliminated, but don't see clear instructions on what exactly to do in their stead.  I have tried requiring the autoload.inc.php file that is in the root of the 0.7.0 files, but am getting the following errors:

$dompdf = new Dompdf();

Fatal error: Class 'Dompdf' not found in /home/rpgbardc/public_html/alpha/wp-content/plugins/rpgbard/rpgbard.php on line 709

It looks like the autoload.inc.php file in turn loads the other autoloaders I would think to load up. A quick search through the project files does not clearly show me where the Dompdf.php file that contains the Dompdf class gets loaded, and my guess is that I'm not properly autoloading the new version or am otherwise missing some requires or something.
Are there any notes on upgrading other than the migration instructions in the README that I can reference to troubleshoot this?  Or any other insights on how to get this new version working with my install?

thanks again,

Dan Steeby

BrianS

unread,
Dec 14, 2015, 4:15:32 PM12/14/15
to dompdf
How did you install the 0.7.0 beta?

If you downloaded the packages release make sure you grab the right file. The source code download is auto-generated by github and doesn't include the external libraries. The correct link should be labeled dompdf_0-7-0_beta2.zip. When using the packaged release the autoload.inc.php should load the external libraries.

If you're using composer you should use its autoloader.

If you're cloning the repo you'll have to manually grab the external libraries.

FYI, once you get 0.7.0 running you'll want to remove any existing fonts and re-install them manually or use the @font-face directive. Otherwise the old font metrics will still be in use.

Dan Steeby

unread,
Dec 14, 2015, 5:54:38 PM12/14/15
to dom...@googlegroups.com
Hi Brian, I downloaded the dompdf_0-7-0_beta2.zip file, and it appears
that the require_once calls in autoload.inc.php are executing without
problems. My best guess is that the requires in the autoloader are
working but these are not bringing in the class definition for the
Dompdf class. I have looked around at other group posts to see if I can
glean any examples from other discussions, but the closest I have found
is this thread:

https://groups.google.com/forum/#!topic/dompdf/cE-551JlK-w

In which you discuss creating an Options class instance and passing that
to the Dompdf::setOptions method. You don't show how the $dompdf
variable was instantiated in the code in that example, but I assume a
'$dompdf = new Dompdf()' would do the trick, but a call to 'new Dompdf'
results in the 'class not found' message I originally reported. I have
tried creating an Options instance as well, as shown in the other post,
and that class is also not available.

I've taken a look at the /src/Autoloader.php file, and it looks like in
the autoload method is a line:

$file = str_replace('\\', DIRECTORY_SEPARATOR, substr($class,
$prefixLength));

In looking into this, it appears that in my environment $class is
'Dompdf', $prefixLength is 6, and DIRECTORY_SEPARATOR is '/'. the
substr() call returns an empty string, as it is getting a subset of the
string 'Dompdf', starting at the 6th character, which is the end of the
string. This sets $file to an empty string, which in turn does not
successfully get the file.

I have replaced the "$file = str_replace( '\\', DIRECTORY_SEPARATOR,
substr( $class, $prefixLength));" line with a simple "$file = $class;"
line to force the loading of the Dompdf.php file, which contains the
Dompdf class definitition, but even with this in place, I am getting a
'Class Dompdf not found' error when trying to instantiate using new
Dompdf(), which surprises me.

Any thoughts or ideas on how to move this forward?

thanks again,

Dan Steeby

BrianS

unread,
Dec 15, 2015, 2:34:47 PM12/15/15
to dompdf
Are you using the Dompdf namespace? That could be the problem. Since Dompdf now uses namespaces you either have to provide the full namespace path for the class or add a use statement. I'd go ahead and add a use statement, it'll make the transition a bit easier. From the README.md:

// reference the Dompdf namespace
use Dompdf\Dompdf;

// instantiate and use the dompdf class
$dompdf
= new Dompdf();

Dan Steeby

unread,
Dec 15, 2015, 5:51:52 PM12/15/15
to dompdf
Hi Brian, you are right, I was missing the namespace stuff. Thanks!

I am now able to export a PDF (yay) and am looking to move forward with installing some custom fonts.  I see in your migration notes that your handy web UI is not in place for this beta, so am wondering if there is an example code on how to install a font using the beta?

I had written a font installer for 0.6.2, and have tried updating it to work with 0.7.0. using your migration notes regarding Font Metrics now being instantiated rather than static.  In my code, it does not appear that the $fontMetrics variable is set as indicated in your note.  here is a snippet of code, with the first (commented out) line being the original approach I took to initialize the Font Metrics class and install fonts:

# Font_Metrics::init(); # 0.6.2 INITIALIZE DOMPDF FONT_METRICS CLASS
$fontMetrics->init(); # 0.7.0 INITIALIZE DOMPDF FONT_METRICS CLASS
foreach( $data as $font_data ){ # LOOP THRU FONTS ...
  # IF FONT REGISTERS, PUT CONFIRMATION MESSAGE
if( $fontMetrics->register_font( $font_data[ 'font' ], $font_data[ 'path' ] ) )
echo sprintf( "font family '%s' successfully installed into dompdf.<br>", $font_data[ 'font' ][ 'family' ] );
  else # ELSE REPORT THAT THERE WAS A PROBLEM
  echo sprintf( "font family '%s' did not properly install!<br>font URL: %s<br>", $font_data[ 'font' ][ 'family' ], $font_data[ 'path' ] );
 } echo 'import complete!<br>';

This code currently errors out at "Undefined variable: fontMetrics".  Is there an example of this working somewhere or can you otherwise point out what I'm missing?  Thanks again for any help.

Dan Steeby

BrianS

unread,
Dec 17, 2015, 12:57:40 PM12/17/15
to dompdf
The easiest way to install a font would be to use @font-face in your CSS. You could set up a page for font installation. Just fill it up with @font-face declarations. Then in each of your documents use the same @font-face declaration to instantiate the font. Fonts loaded this way don't have to be re-processed on subsequent use, so it shouldn't affect performance.

I've been working on an updated version of of the load_font.php script. I'm hoping to start a tools project with things like this, just not sure when I'll have it all done. When I have a moment I'll see where I am with that and post it if things look to be reasonably functional.

BrianS

unread,
Dec 23, 2015, 6:57:27 PM12/23/15
to dompdf
The load_font.php file still needs a bit of work, but I'll see if I can get it functional relatively soon.

Dan Steeby

unread,
Dec 30, 2015, 1:15:01 PM12/30/15
to dompdf
Hi Brian,

Hope you are having a good end-of-year!  It sounds like as long as we include a @font-face style rule in the HTML content we are passing to dompdf, the font will automagically get installed?  If so, I am not experiencing this currently and am trying to piece together why ... We are using @font-face declarations with style tags in the content passed to dompdf, and I believe the paths to the font files should be good as well.  Here is a condensed example of what we are passing to dompdf:

<!DOCTYPE html>
<html>
 
<head>
 
<style>
 
@font-face { font-family: 'metamorphous'; font-weight: normal; font-style: normal;
 
/* N */ src: url( '/libraries/fonts/google/Metamorphous-Regular.ttf' ) format( 'truetype' ); }
 
@font-face { font-family: 'metamorphous'; font-weight: bold; font-style: normal;
 
/* B */ src: url( '/libraries/fonts/google/Metamorphous-Regular.ttf' ) format( 'truetype' ); }
 
@font-face { font-family: 'metamorphous'; font-weight: bold; font-style: italic;
 
/* BI */ src: url( '/libraries/fonts/google/Metamorphous-Regular.ttf' ) format( 'truetype' ); }
 
@font-face { font-family: 'metamorphous'; font-weight: normal; font-style: italic;
 
/* I */ src: url( '/libraries/fonts/google/Metamorphous-Regular.ttf' ) format( 'truetype' ); }
 
.front-cover { font-family: metamorphous; }
 
</style>
 
</head>
 
<body>
 
<div class="front-cover">A  3.5/OGL/PF Adventure for Level 4</div>
 
</body>
</html>

Here is the PHP code that I am using (lifted from another post in this group) currently: 

require_once( '/home/rpgbardc/public_html/dompdf_070/autoload.inc.php' ); # LOAD DOMPDF
$dompdf = new Dompdf\Dompdf();
$options = new Dompdf\Options();
$dompdf->set_option( "defaultFont", "rothenburgdecorative" );
$options->set( 'isRemoteEnabled', true );
$dompdf->setOptions( $options );
$dompdf->load_html( $html ); # LOAD OUR HTML INTO DOMPDF
$dompdf->render(); # RENDER
$dompdf->stream( $book->post_title ); # DUMP PDF FILE TO USER

This renders a fine looking PDF file, but no fancy Metamorphus font.

Does this look like it should work to you?  We have a preview feature that does display the fonts in a browser, using the same HTML content that is passed to dompdf to render, and fonts are working well there.  I have attached the entire HTML file that is passed to dompdf if you care to look-- there are a LOT of @font-face declarations in the file, most of which are not used in the document, in the actual file, and the body element gets a 'pdf' class added to it for rendering in dompdf.  For what it's worth, we have a 0.6.2 install which is working fine when passed this content, but of course has all the fonts installed 'the old fashioned way'.

Thanks for any additional input!


book_cover-a-test_.html

BrianS

unread,
Jan 1, 2016, 10:52:52 AM1/1/16
to dompdf
Is that font path relative to your website root or filesystem root? Since you're using load_html dompdf will assume all paths that don't include a protocol & host to be relative to the filesystem.

Dan Steeby

unread,
Jan 6, 2016, 7:04:10 PM1/6/16
to dompdf


Hi Brian,  you are correct that the file paths in the CSS file were relative to the web root rather than the filesystem root.  I have updated the stylesheet so that all font-face rules use a path that includes the http protocol and host, and confirmed that the referenced font files are available by this path.  My previous example above has been updated to: 


<!DOCTYPE html>
<html>
 
<head>
 
<style>
 
@font-face { font-family: 'metamorphous'; font-weight: normal; font-style: normal;

  
/* N */ src: url( 'http://my-site.com/libraries/fonts/google/Metamorphous-Regular.ttf' ) format( 'truetype' ); }

 
@font-face { font-family: 'metamorphous'; font-weight: bold; font-style: normal;

  
/* B */ src: url( 'http://my-site.com/libraries/fonts/google/Metamorphous-Regular.ttf' ) format( 'truetype' ); }

 
@font-face { font-family: 'metamorphous'; font-weight: bold; font-style: italic;

  
/* BI */ src: url( 'http://my-site.com/libraries/fonts/google/Metamorphous-Regular.ttf' ) format( 'truetype' ); }

 
@font-face { font-family: 'metamorphous'; font-weight: normal; font-style: italic;

  
/* I */ src: url( 'http://my-site.com/libraries/fonts/google/Metamorphous-Regular.ttf' ) format( 'truetype' ); }
 .front-cover { font-family: metamorphous; }
 
</style>
 
</head>
 
<body>
 
<div class="front-cover">A  3.5/OGL/PF Adventure for Level 4</div>
 
</body>
</html>

In testing this, I am still not seeing the Metamorphus font in the PDF output.  Please let  me know if I am still missing something in my material, or if you have anything else you'd like me to try to get some fonts installed my beta installation of dompdf?

thanks again!

Dan Steeby

BrianS

unread,
Jan 6, 2016, 10:53:02 PM1/6/16
to dompdf
Looks like there might be a minor issue parsing the CSS. Try taking out the extra space around the font src attribute, e.g.


@font-face { font-family: 'metamorphous'; font-weight: normal; font-style: normal;

 
/* N */ src: url('http://my-site.com/libraries/fonts/google/Metamorphous-Regular.ttf') format( 'truetype' ); }



Sometimes some minor formatting issues can cause problems for parsing the CSS. We should probably address this one.

Coincidentally I had a chance to finish hacking together a usable load_font.php script. If you're interested in trying that route see the attached file.
load_font.php

Dan Steeby

unread,
Jan 8, 2016, 12:22:54 PM1/8/16
to dompdf
Hi Brian, I was able to use your load_font.php file with an existing script, great to see some of our fonts working in the new version!  We are having some issues with certain fonts, but overall the importer is working for us-- thanks!

Dan Steeby

BrianS

unread,
Jan 8, 2016, 1:46:53 PM1/8/16
to dompdf
Glad to hear it! Feel free to post info related to problems with a font, or open an issue on the project site.
Reply all
Reply to author
Forward
0 new messages