Dixi quod…
>Dmitry Shachnev dixit:
>>Now that you dug so deeply, maybe you can try to replace qRound in those
>>three lines that you mentioned with TO_TTF, and check if it fixes the bug
>
>That *and* figure out somehow how to fix the PDF /FontBBox, at
>least… (though I binary-patched the hhea ascender in the PDF and
>it made Atril happy, so it “should”, despite the still-wrong OS/2
>table values some of which are notably used in clipping by some
>softwares…)

Yes, that worked. I’m attaching the final patch in entirety again
for your convenience.

>I’m trying this (attached). That does both (by letting toTruetype()
>adjust the already-existing scaling factor in the caller) and
>applies suitable rounding (normal for normal values, away from zero
>for the bounding box so it’s guaranteed to encompass all possible
>values). I’ll build it now so I don’t know if it even compiles yet…

It still does not address the OS/2 table, but it does manage to
fix both the PDF-side and font-side hhea table metrics, which is
enough for Atril at least. (Not sure whether it’s enough for my
gf’s printer, I’ll have to test. Or extend the patch to fix the
OS/2 table as well, which I probably should anyway; I have to find
the time for that sometime within the next few days.)

bye,
//mirabilos
-- 
> Hi, does anyone sell openbsd stickers by themselves and not packaged
> with other products?
No, the only way I've seen them sold is for $40 with a free OpenBSD CD.
        -- Haroon Khalid and Steve Shockley in gmane.os.openbsd.misc
Description: scale /FontBBox and hhea table when scaling fonts
 for embedding (the OS/2 table needs handling XXX TODO)
Author: mirabilos <t...@debian.org>
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1070406

--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1870,11 +1870,20 @@ void QPdfEnginePrivate::writeAttachmentR
             "endobj\n");
 }
 
+static inline int roundForBbox(qreal v)
+{
+    return (v < 0) ? floor(v) : ceil(v);
+}
+
 void QPdfEnginePrivate::embedFont(QFontSubset *font)
 {
+    QFontEngine::Properties properties = font->fontEngine->properties();
+    QByteArray postscriptName = properties.postscriptName.replace(' ', '_');
+    qreal scale = 1000/properties.emSquare.toReal();
+
     //qDebug() << "embedFont" << font->object_id;
     int fontObject = font->object_id;
-    QByteArray fontData = font->toTruetype();
+    QByteArray fontData = font->toTruetype(&scale);
 #ifdef FONT_DUMP
     static int i = 0;
     QString fileName("font%1.ttf");
@@ -1891,11 +1900,7 @@ void QPdfEnginePrivate::embedFont(QFontS
     int toUnicode = requestObject();
     int cidset = requestObject();
 
-    QFontEngine::Properties properties = font->fontEngine->properties();
-    QByteArray postscriptName = properties.postscriptName.replace(' ', '_');
-
     {
-        qreal scale = 1000/properties.emSquare.toReal();
         addXrefEntry(fontDescriptor);
         QByteArray descriptor;
         QPdf::ByteStream s(&descriptor);
@@ -1909,15 +1914,15 @@ void QPdfEnginePrivate::embedFont(QFontS
         s <<  '+' << postscriptName << "\n"
             "/Flags " << 4 << "\n"
             "/FontBBox ["
-          << properties.boundingBox.x()*scale
-          << -(properties.boundingBox.y() + 
properties.boundingBox.height())*scale
-          << (properties.boundingBox.x() + 
properties.boundingBox.width())*scale
-          << -properties.boundingBox.y()*scale  << "]\n"
+          << roundForBbox(properties.boundingBox.x()*scale)
+          << roundForBbox(-(properties.boundingBox.y() + 
properties.boundingBox.height())*scale)
+          << roundForBbox((properties.boundingBox.x() + 
properties.boundingBox.width())*scale)
+          << roundForBbox(-properties.boundingBox.y()*scale)  << "]\n"
             "/ItalicAngle " << properties.italicAngle.toReal() << "\n"
-            "/Ascent " << properties.ascent.toReal()*scale << "\n"
-            "/Descent " << -properties.descent.toReal()*scale << "\n"
-            "/CapHeight " << properties.capHeight.toReal()*scale << "\n"
-            "/StemV " << properties.lineWidth.toReal()*scale << "\n"
+            "/Ascent " << qRound(properties.ascent.toReal()*scale) << "\n"
+            "/Descent " << qRound(-properties.descent.toReal()*scale) << "\n"
+            "/CapHeight " << qRound(properties.capHeight.toReal()*scale) << 
"\n"
+            "/StemV " << qRound(properties.lineWidth.toReal()*scale) << "\n"
             "/FontFile2 " << fontstream << "0 R\n"
             "/CIDSet " << cidset << "0 R\n"
             ">>\nendobj\n";
--- a/src/gui/text/qfontsubset.cpp
+++ b/src/gui/text/qfontsubset.cpp
@@ -1162,13 +1162,14 @@ static QByteArray bindFont(const QVector
   if really required.
 */
 
-QByteArray QFontSubset::toTruetype() const
+QByteArray QFontSubset::toTruetype(qreal *scalep) const
 {
     qttf_font_tables font;
     memset(&font, 0, sizeof(qttf_font_tables));
 
     qreal ppem = fontEngine->fontDef.pixelSize;
 #define TO_TTF(x) qRound(x * 2048. / ppem)
+    *scalep *= 2048. / ppem;
 
     QFontEngine::Properties properties = fontEngine->properties();
     // initialize some stuff needed in createWidthArray
@@ -1188,9 +1189,9 @@ QByteArray QFontSubset::toTruetype() con
     font.head.macStyle |= (fontEngine->fontDef.styleHint != 
QFont::StyleNormal) ? 1 : 0;
 
     // hhea table
-    font.hhea.ascender = qRound(properties.ascent);
-    font.hhea.descender = -qRound(properties.descent);
-    font.hhea.lineGap = qRound(properties.leading);
+    font.hhea.ascender = TO_TTF(properties.ascent.toReal());
+    font.hhea.descender = TO_TTF(-properties.descent.toReal());
+    font.hhea.lineGap = TO_TTF(properties.leading.toReal());
     font.hhea.maxAdvanceWidth = TO_TTF(fontEngine->maxCharWidth());
     font.hhea.minLeftSideBearing = TO_TTF(fontEngine->minLeftBearing());
     font.hhea.minRightSideBearing = TO_TTF(fontEngine->minRightBearing());
--- a/src/gui/text/qfontsubset_p.h
+++ b/src/gui/text/qfontsubset_p.h
@@ -72,7 +72,7 @@ public:
             delete fontEngine;
     }
 
-    QByteArray toTruetype() const;
+    QByteArray toTruetype(qreal *scalep) const;
 #ifndef QT_NO_PDF
     QByteArray widthArray() const;
     QByteArray createToUnicodeMap() const;

Reply via email to