tpf80
13th January 2009, 14:55
I have a Qt 4.4.3 app that uses QPainter to draw to a PDF QPrinter. It works perfectly in linux, and in windows, however the font sizes are enlarged when the code runs on the windows version. How can I get the Windows and Linux PDF's to render fonts exactly the same size?
Heres the code that I used to create the PDF:
void PdfGenerate::generatePdf() {
QString stufftowritetopdf;
QPrinter printer; //create a printer
setupLetterPoints(printer, "filename.pdf"); //set up reference points for our coordinate system
QPainter painter(&printer); //make a painter, which uses this printer,
///////////////////////////////////////////
/// in here draw some text
/////////////////////////////////////////////
stufftowritetopdf = "here we put a lot of text so that its long enough
to force a word wrap. When this text is rendered in linux and windows,
the resulting PDFs will have a different visable font size, even though the
code and text is the same. If You put enough text here to fill up a page
when compiled in linux, it will run off the bottom of the page in the windows
compiled version due to the windows version using a larger font size.";
totaldepth = totaldepth + drawrichtextinrect(&painter, leftmargin, totaldepth, horizmarginwidth, 0, stufftowritetopdf, normalsize);
///////////////////////////////////////////
/// done drawing text
/////////////////////////////////////////////
printlastpage(painter); //end the final page:
}
//set up the point coordinates for a letter sheet of paper:
void PdfGenerate::setupLetterPoints(QPrinter& printer, QString filename) {
printer.setOrientation(QPrinter::Portrait); //set theorientation of the paper
printer.setOutputFormat(QPrinter::PdfFormat); //make that printer as a PDF
printer.setOutputFileName(filename); //set the PDF file name
printer.setPaperSize(QPrinter::Letter); //set paper size
printer.setFullPage(false); //coordinates based on printable area
printer.setPageMargins( 0.5, 0.5, 0.5, 0.5, QPrinter::Inch);
printer.setResolution(72); //72 is standard
//(72 points / inch)
pagewidth = 540; //8.5 inch
pageheight = 720; //11 inch
margin = 0; // 0.5 inch margin
topmargin = margin;
bottommargin = pageheight - margin;
leftmargin = margin;
rightmargin = pagewidth - margin;
vertmarginwidth = pageheight - (margin * 2);
horizmarginwidth = pagewidth - (margin * 2);
noindent = 0;
indent1 = noindent + 15;
indent2 = indent1 + 15;
//font sizes:
fontFamily = "Times New Roman";
headersize = 15;
titlesize = 12;
stitlesize = 10;
normalsize = 8;
contractsize = 6;
pagenumsize = 8;
totaldepth = topmargin;
pagenum = 1;
totalpages = 5;
}
//draw rich text in a rect:
qreal PdfGenerate::drawrichtextinrect(QPainter *painter, qreal ulx, qreal uly, qreal rwidth, int flags, QString &text, int fontsize) {
QRectF rect(ulx, uly - 2, rwidth, 0);
qreal txtHeight = rect.height();
QTextDocument textdocument;
textdocument.setHtml(text);
textdocument.setDefaultFont(QFont(fontFamily, fontsize));
textdocument.setPageSize(QSize(rect.width(), QWIDGETSIZE_MAX));
QAbstractTextDocumentLayout* layout = textdocument.documentLayout();
//if our text takes up more than the rectangle height, then return the actual space taken up:
if (layout->documentSize().height() > txtHeight) {
txtHeight = layout->documentSize().height() - 4;
}
const int height = qRound(layout->documentSize().height());
int y = rect.y();
if (flags & Qt::AlignBottom)
y += (rect.height() - height);
else if (flags & Qt::AlignVCenter)
y += (rect.height() - height)/2;
QAbstractTextDocumentLayout::PaintContext context;
context.palette.setColor(QPalette::Text, painter->pen().color());
painter->save();
painter->translate(rect.x(), rect.y());
layout->draw(painter, context);
painter->restore();
return txtHeight;
}
void PdfGenerate::printlastpage(QPainter& painter) {
painter.end(); //done drawing, so save the PDF
}
Also, the PDF that is generated on the linux machine looks the same on the windows machine as it does on the linux machine. Conversely the PDF generated on the windows machine will have larger fonts when viewed on the linux machine. This leads me to believe the problem lies either in my code, the font, or a difference in the PDF QPrinter from windows to linux.
Heres the code that I used to create the PDF:
void PdfGenerate::generatePdf() {
QString stufftowritetopdf;
QPrinter printer; //create a printer
setupLetterPoints(printer, "filename.pdf"); //set up reference points for our coordinate system
QPainter painter(&printer); //make a painter, which uses this printer,
///////////////////////////////////////////
/// in here draw some text
/////////////////////////////////////////////
stufftowritetopdf = "here we put a lot of text so that its long enough
to force a word wrap. When this text is rendered in linux and windows,
the resulting PDFs will have a different visable font size, even though the
code and text is the same. If You put enough text here to fill up a page
when compiled in linux, it will run off the bottom of the page in the windows
compiled version due to the windows version using a larger font size.";
totaldepth = totaldepth + drawrichtextinrect(&painter, leftmargin, totaldepth, horizmarginwidth, 0, stufftowritetopdf, normalsize);
///////////////////////////////////////////
/// done drawing text
/////////////////////////////////////////////
printlastpage(painter); //end the final page:
}
//set up the point coordinates for a letter sheet of paper:
void PdfGenerate::setupLetterPoints(QPrinter& printer, QString filename) {
printer.setOrientation(QPrinter::Portrait); //set theorientation of the paper
printer.setOutputFormat(QPrinter::PdfFormat); //make that printer as a PDF
printer.setOutputFileName(filename); //set the PDF file name
printer.setPaperSize(QPrinter::Letter); //set paper size
printer.setFullPage(false); //coordinates based on printable area
printer.setPageMargins( 0.5, 0.5, 0.5, 0.5, QPrinter::Inch);
printer.setResolution(72); //72 is standard
//(72 points / inch)
pagewidth = 540; //8.5 inch
pageheight = 720; //11 inch
margin = 0; // 0.5 inch margin
topmargin = margin;
bottommargin = pageheight - margin;
leftmargin = margin;
rightmargin = pagewidth - margin;
vertmarginwidth = pageheight - (margin * 2);
horizmarginwidth = pagewidth - (margin * 2);
noindent = 0;
indent1 = noindent + 15;
indent2 = indent1 + 15;
//font sizes:
fontFamily = "Times New Roman";
headersize = 15;
titlesize = 12;
stitlesize = 10;
normalsize = 8;
contractsize = 6;
pagenumsize = 8;
totaldepth = topmargin;
pagenum = 1;
totalpages = 5;
}
//draw rich text in a rect:
qreal PdfGenerate::drawrichtextinrect(QPainter *painter, qreal ulx, qreal uly, qreal rwidth, int flags, QString &text, int fontsize) {
QRectF rect(ulx, uly - 2, rwidth, 0);
qreal txtHeight = rect.height();
QTextDocument textdocument;
textdocument.setHtml(text);
textdocument.setDefaultFont(QFont(fontFamily, fontsize));
textdocument.setPageSize(QSize(rect.width(), QWIDGETSIZE_MAX));
QAbstractTextDocumentLayout* layout = textdocument.documentLayout();
//if our text takes up more than the rectangle height, then return the actual space taken up:
if (layout->documentSize().height() > txtHeight) {
txtHeight = layout->documentSize().height() - 4;
}
const int height = qRound(layout->documentSize().height());
int y = rect.y();
if (flags & Qt::AlignBottom)
y += (rect.height() - height);
else if (flags & Qt::AlignVCenter)
y += (rect.height() - height)/2;
QAbstractTextDocumentLayout::PaintContext context;
context.palette.setColor(QPalette::Text, painter->pen().color());
painter->save();
painter->translate(rect.x(), rect.y());
layout->draw(painter, context);
painter->restore();
return txtHeight;
}
void PdfGenerate::printlastpage(QPainter& painter) {
painter.end(); //done drawing, so save the PDF
}
Also, the PDF that is generated on the linux machine looks the same on the windows machine as it does on the linux machine. Conversely the PDF generated on the windows machine will have larger fonts when viewed on the linux machine. This leads me to believe the problem lies either in my code, the font, or a difference in the PDF QPrinter from windows to linux.