Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xetex rounds all image sizes to integer pt values #597

Closed
1 task done
ivankokan opened this issue Aug 8, 2020 · 22 comments
Closed
1 task done

xetex rounds all image sizes to integer pt values #597

ivankokan opened this issue Aug 8, 2020 · 22 comments
Assignees
Labels
Milestone

Comments

@ivankokan
Copy link
Contributor

ivankokan commented Aug 8, 2020

Hi, for the following MWE I cannot get the same PDF output using pdflatex and xelatex - the graphics are slightly displaced (both horizontally and vertically) in the version produced by xelatex. Interestingly, without specifying the 12pt the horizontal difference is lost but vertical is still present. (My MiKTeX is updated.)

\documentclass[12pt]{article}%
\usepackage{graphicx}%
\begin{document}%
\includegraphics{test_0}%
\end{document}%

all_files_and_logs.zip

Comparisons:

  1. pdflatex_with_12pt.pdf vs xelatex_with_12pt.pdf: both horizontal and vertical displacement
  2. pdflatex_without_12pt.pdf vs xelatex_without_12pt.pdf: only vertical displacement

There are no such issues in the latest TeX Live, though - pdflatex and xelatex produce (respectively) the same PDF output as MiKTeX's pdflatex.

I am not sure if there are some issues in the binaries, the class definitions (the impact of 12pt), or even in the graphicx bundle. Maybe MiKTeX is not synced with CTAN, I really cannot tell anything else - but something is fishy.

There is a long story in the background of this issue, given in the following links:

ReportDate: 2020-08-08 16:48:39
CurrentVersion: 20.7
SetupDate: 2019-02-19 14:12:00
SetupVersion: 2.9
Configuration: Regular
GitInfo: d26133b / 2020-07-31 18:20:50
OS: Windows 10 Enterprise, 64-bit, build 17763
SharedSetup: no
LinkTargetDirectory: C:\Users\ekokiva\AppData\Local\Programs\MiKTeX 2.9\miktex\bin\x64
PathOkay: yes
LastUpdateCheck: 2020-08-08 16:44:49
LastUpdate: 2020-08-03 02:25:42
LastUpdateDb: 2020-08-08 16:44:48
SystemAdmin: no
RootPrivileges: no
AdminMode: no
Root0: C:\Users\ekokiva\AppData\Roaming\MiKTeX\2.9
Root1: C:\Users\ekokiva\AppData\Local\MiKTeX\2.9
Root2: C:\Users\ekokiva\AppData\Local\Programs\MiKTeX 2.9
Root3: C:\ProgramData\MiKTeX\2.9
Root4: C:\Program Files\MiKTeX 2.9
UserInstall: C:\Users\ekokiva\AppData\Local\Programs\MiKTeX 2.9
UserConfig: C:\Users\ekokiva\AppData\Roaming\MiKTeX\2.9
UserData: C:\Users\ekokiva\AppData\Local\MiKTeX\2.9
CommonInstall: C:\Program Files\MiKTeX 2.9
CommonConfig: C:\ProgramData\MiKTeX\2.9
CommonData: C:\ProgramData\MiKTeX\2.9

Regards, Ivan

@u-fischer
Copy link

miktex seems to round with xetex all image sizes to full pt values:

\documentclass{article}

\setbox0=\hbox{\XeTeXpdffile example-image-a.pdf\relax}
\showthe\wd0
\showthe\ht0


\setbox0=\hbox{\XeTeXpicfile example-image-a.jpg\relax}
\showthe\wd0
\showthe\ht0

\begin{document}
blub
\end{document}

gives with miktex:

> 321.0pt.
l.18 \showthe\wd0
                 
? 
> 240.0pt.
l.19 \showthe\ht0
                 
? 
> 401.0pt.
l.23 \showthe\wd0
                 
? 
> 301.0pt.
l.24 \showthe\ht0

and with texlive

> 321.20001pt.
l.18 \showthe\wd0
                 
? 
> 240.9pt.
l.19 \showthe\ht0
                 
? 
> 401.5pt.
l.23 \showthe\wd0
                 
? 
> 301.125pt.
l.24 \showthe\ht0

@ivankokan
Copy link
Contributor Author

Thanks @u-fischer! I have tried to trace this one and eventually got here:

extern int pdf_get_rect(char* filename, int page_num, int pdf_box, realrect* box);

typedef struct {
float x;
float y;
float wd;
float ht;
} realrect;

int
find_pic_file(char** path, realrect* bounds, int pdfBoxType, int page)
{
int err = -1;
FILE* fp = NULL;
char* pic_path = kpse_find_file((char*)nameoffile + 1, kpse_pict_format, 1);
*path = NULL;
bounds->x = bounds->y = bounds->wd = bounds->ht = 0.0;
if (pic_path == NULL)
goto done;
/* if cmd was \XeTeXpdffile, use xpdflib to read it */
if (pdfBoxType != 0) {
err = pdf_get_rect(pic_path, page, pdfBoxType, bounds);
goto done;
}
/* otherwise try graphics formats that we know */
fp = fopen(pic_path, FOPEN_RBIN_MODE);
if (fp == NULL)
goto done;
if (check_for_jpeg(fp)) {
struct JPEG_info info;
err = JPEG_scan_file(&info, fp);
if (err == 0) {
bounds->wd = (info.width * 72.27) / info.xdpi;
bounds->ht = (info.height * 72.27) / info.ydpi;
}
goto done;
}
if (check_for_bmp(fp)) {
struct bmp_info info;
err = bmp_scan_file(&info, fp);
if (err == 0) {
bounds->wd = (info.width * 72.27) / info.xdpi;
bounds->ht = (info.height * 72.27) / info.ydpi;
}
goto done;
}
if (check_for_png(fp)) {
#if defined(MIKTEX)
struct xetex_png_info info;
#else
struct png_info info;
#endif
err = png_scan_file(&info, fp);
if (err == 0) {
bounds->wd = (info.width * 72.27) / info.xdpi;
bounds->ht = (info.height * 72.27) / info.ydpi;
}
goto done;
}
/* could support other file types here (TIFF, WMF, etc?) */
done:
if (fp != NULL)
fclose(fp);
if (err == 0)
*path = pic_path;
else {
if (pic_path != NULL)
free(pic_path);
}
return err;
}

int
pdf_get_rect(char* filename, int page_num, int pdf_box, realrect* box)
/* return the box converted to TeX points */
{
GooString* name = new GooString(filename);
PDFDoc* doc = new PDFDoc(name);
if (!doc) {
delete name;
return -1;
}
/* if the doc got created, it now owns name, so we mustn't delete it! */
if (!doc->isOk()) {
delete doc;
return -1;
}
int pages = doc->getNumPages();
if (page_num > pages)
page_num = pages;
if (page_num < 0)
page_num = pages + 1 + page_num;
if (page_num < 1)
page_num = 1;
Page* page = doc->getCatalog()->getPage(page_num);
const PDFRectangle* r;
switch (pdf_box) {
default:
case pdfbox_crop:
r = page->getCropBox();
break;
case pdfbox_media:
r = page->getMediaBox();
break;
case pdfbox_bleed:
r = page->getBleedBox();
break;
case pdfbox_trim:
r = page->getTrimBox();
break;
case pdfbox_art:
r = page->getArtBox();
break;
}
int RotAngle = 0;
RotAngle = (int)page->getRotate() % 360;
if (RotAngle < 0)
RotAngle += 360;
if (RotAngle == 90 || RotAngle == 270) {
box->wd = 72.27 / 72 * fabs(r->y2 - r->y1);
box->ht = 72.27 / 72 * fabs(r->x2 - r->x1);
} else {
box->wd = 72.27 / 72 * fabs(r->x2 - r->x1);
box->ht = 72.27 / 72 * fabs(r->y2 - r->y1);
}
box->x = 72.27 / 72 * my_fmin(r->x1, r->x2);
box->y = 72.27 / 72 * my_fmin(r->y1, r->y2);
delete doc;
return 0;
}

As far as I can tell, all the dimension conversions seem to be correct (floats are used all the way).

@u-fischer
Copy link

Sorry I have neither the will nor the time to skim through miktex sources. But as it works in texlive (both in new and older versions) I have some doubts that the source of the problem is directly in the xetex sources.

@ivankokan
Copy link
Contributor Author

... I have some doubts that the source of the problem is directly in the xetex sources.

I agree on that.

@edocevoli
Copy link
Member

Thank you both for your efforts. Please keep in mind that XeTeX uses a bunch of 3rd party libraries (see xetex --version) and it is quite likely that MiKTeX and TeX Live differ with respect to the library versions.

@ivankokan
Copy link
Contributor Author

MiKTeX

MiKTeX-pdfTeX 4.0.1 (MiKTeX 20.7)
© 1982 D. E. Knuth, © 1996-2020 Hàn Thế Thành
TeX is a trademark of the American Mathematical Society.
using bzip2 version 1.0.6, 6-Sept-2010
compiled with curl version 7.61.1; using libcurl/7.61.1 WinSSL
compiled with expat version 2.2.6; using expat_2.2.6
compiled with jpeg version 9.3
compiled with liblzma version 50020042; using 50020042
compiled with libpng version 1.6.37; using 1.6.37
compiled with libressl version LibreSSL 2.8.2; using LibreSSL 2.8.2
compiled with MiKTeX Application Framework version 4.0; using 4.0
compiled with MiKTeX Core version 4.0; using 4.0
compiled with MiKTeX Archive Extractor version 4.0; using 4.0
compiled with MiKTeX Package Manager version 4.0; using 4.0
compiled with poppler version 0.60.1
compiled with uriparser version 0.9.2
compiled with zlib version 1.2.11; using 1.2.11
MiKTeX-XeTeX 4.0 (MiKTeX 20.7)
© 1994-2008 SIL International, © 2009-2012 Jonathan Kew, © 2010-2012 Hàn Thế Thành, © 2012-2013 Khaled Hosny
TeX is a trademark of the American Mathematical Society
using bzip2 version 1.0.6, 6-Sept-2010
compiled with curl version 7.61.1; using libcurl/7.61.1 WinSSL
compiled with expat version 2.2.6; using expat_2.2.6
compiled with fontconfig version 2.13.1; using 2.13.1
compiled with freetype2 version 2.9.1; using 2.9.1
compiled with graphite2 version 1.3.12; using 1.3.12
compiled with harfbuzz version 2.5.3; using 2.5.3
compiled with icu version 60.1; using 60.1
compiled with jpeg version 9.3
compiled with liblzma version 50020042; using 50020042
compiled with libpng version 1.6.37; using 1.6.37
compiled with libressl version LibreSSL 2.8.2; using LibreSSL 2.8.2
compiled with MiKTeX Application Framework version 4.0; using 4.0
compiled with MiKTeX Core version 4.0; using 4.0
compiled with MiKTeX Archive Extractor version 4.0; using 4.0
compiled with MiKTeX Package Manager version 4.0; using 4.0
compiled with poppler version 0.60.1
using teckit version 2.4
compiled with uriparser version 0.9.2
compiled with zlib version 1.2.11; using 1.2.11

@ivankokan
Copy link
Contributor Author

Compiling the "with 12pt" version with \tracingall gives me:

pdflatex

Completed box being shipped out [1]
\vbox(632.5+0.0)x429.0
.\glue 17.0
.\vbox(615.5+0.0)x390.0, shifted 39.0
..\vbox(12.0+0.0)x390.0, glue set 12.0fil
...\glue 0.0 plus 1.0fil
...\hbox(0.0+0.0)x390.0
..\glue 25.0
..\glue(\lineskip) 0.0
..\vbox(548.5+0.0)x390.0, glue set 434.63864fil
...\write-{}
...\glue(\topskip) 0.0
...\hbox(113.81493+0.0)x390.0, glue set 258.56024fil
....\hbox(0.0+0.0)x17.62482
....\hbox(113.81493+0.0)x113.81493
.....\hbox(113.81522+0.0)x113.81522
......\hbox(113.81522+0.0)x113.81522
.......\hbox(113.81522+0.0)x0.0
........\hbox(113.81522+0.0)x0.0, glue set - 113.81522fil
.........\hbox(113.81522+0.0)x113.81522
..........\pdfrefximage(113.81522+0.0)x113.81522
.........\glue 0.0 plus 1.0fil minus 1.0fil
.......\kern 113.81522
.......\glue 0.0 plus 1.0fil minus 1.0fil
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
...\glue 0.0 plus 1.0fil
...\glue 0.0
...\glue 0.0 plus 0.0001fil
..\glue(\baselineskip) 22.26668
..\hbox(7.73332+0.0)x390.0, glue set 192.06253fil
...\glue 0.0 plus 1.0fil
...\OT1/cmr/m/n/12 1
...\glue 0.0 plus 1.0fil

xelatex

Completed box being shipped out [1]
\vbox(632.5+0.0)x429.0
.\glue 17.0
.\vbox(615.5+0.0)x390.0, shifted 39.0
..\vbox(12.0+0.0)x390.0, glue set 12.0fil
...\glue 0.0 plus 1.0fil
...\hbox(0.0+0.0)x390.0
..\glue 25.0
..\glue(\lineskip) 0.0
..\vbox(548.5+0.0)x390.0, glue set 435.45377fil
...\write-{}
...\glue(\topskip) 0.0
...\hbox(112.99973+0.0)x390.0, glue set 259.00027fil
....\hbox(0.0+0.0)x18.0
....\hbox(112.99973+0.0)x112.99973
.....\hbox(113.0+0.0)x113.0
......\hbox(113.0+0.0)x113.0
.......\hbox(113.0+0.0)x0.0
........\special{pdf:btrans}
........\special{x:scale 1 1}
........\hbox(113.0+0.0)x0.0, glue set - 113.0fil
.........\hbox(113.0+0.0)x113.0
..........\XeTeXpdffile "./test_0.pdf"
.........\glue 0.0 plus 1.0fil minus 1.0fil
........\special{pdf:etrans}
.......\kern 113.0
.......\glue 0.0 plus 1.0fil minus 1.0fil
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
...\glue 0.0 plus 1.0fil
...\glue 0.0
...\glue 0.0 plus 0.0001fil
..\glue(\baselineskip) 22.02
..\hbox(7.98+0.0)x390.0, glue set 192.06fil
...\glue 0.0 plus 1.0fil
...\TU/lmr/m/n/12 1
...\glue 0.0 plus 1.0fil

@ivankokan
Copy link
Contributor Author

ivankokan commented Aug 29, 2020

I have managed to find the root cause of the horizontal differences.

After noticing the following difference between pdflatex and xelatex \tracingall logs:
{restoring \parindent=17.62482pt} vs {restoring \parindent=18.0pt}, here is what I got

pdflatex 17.62482pt
xelatex 18.0pt

for the following MWE:

\documentclass[12pt]{article}
\begin{document}
\the\parindent
\end{document}

Root cause is the length of \parindent within size12.clo. The size of 1em really depends on the used font (type): roughly the width of an 'M' (uppercase) in the current font, depends on the font used.

\if@twocolumn
  \setlength\parindent{1em}
\else
  \setlength\parindent{1.5em}
\fi

On the other hand, here is what we have within size10.clo and size11.clo:

\if@twocolumn
  \setlength\parindent{1em}
\else
  \setlength\parindent{15\p@}
\fi
\if@twocolumn
  \setlength\parindent{1em}
\else
  \setlength\parindent{17\p@}
\fi
  1. It is clear that \parindents are inconsistently defined for different options. It would be better to have size given in \p@s within size12.clo as well, e.g. 18\p@. And this would suppress the difference between the pdflatex and xelatex output.
  2. A similar proposal would be to use 10\p@, 11\p@ and 12\p@ respectively for two-column mode.

I guess my findings are not MiKTeX-specific, and I would like to submit my proposal at the appropriate address.
@u-fischer @edocevoli Can you please advise me on how to do it?

(Horizontal differences in my original MWE can be suppressed explicitly setting \parindent to some non-em size.)

@u-fischer
Copy link

Sorry I hadn't realized that you were still fighting also with the horizontal displacement, or I have told you that it is the \parindent. But this is not a miktex specific problem and should not be discussed here, the right place to suggest changes to the standard classes is the latex2e github. But your chances that \parindent is changed are slim - it would affect to many existing documents, a feature request would be closed. If you want a fix parindent size, set it in your document.

@ivankokan
Copy link
Contributor Author

ivankokan commented Aug 29, 2020

But your chances that \parindent is changed are slim - it would affect to many existing documents, a feature request would be closed.

I understand the impact. On the other hand, if there are no issues for 10pt and 11pt cases, but there is for 12pt due to inconsistent definition in the code base, it should be (at least) reported and properly discussed.

@ivankokan
Copy link
Contributor Author

ivankokan commented Aug 29, 2020

Horizontal differences

They are not MiKTeX-specific. The root cause is explained here: latex3/latex2e#381. Explicitly setting \parindent to some non-em size can help to avoid the issue.

Vertical differences

To be continued...

@ivankokan
Copy link
Contributor Author

ivankokan commented Aug 30, 2020

MiKTeX-XeTeX 4.0 (MiKTeX 20.7)
© 1994-2008 SIL International, © 2009-2012 Jonathan Kew, © 2010-2012 Hàn Thế Thành, © 2012-2013 Khaled Hosny
TeX is a trademark of the American Mathematical Society
using bzip2 version 1.0.6, 6-Sept-2010
compiled with curl version 7.61.1; using libcurl/7.61.1 WinSSL
compiled with expat version 2.2.6; using expat_2.2.6
compiled with fontconfig version 2.13.1; using 2.13.1
compiled with freetype2 version 2.9.1; using 2.9.1
compiled with graphite2 version 1.3.12; using 1.3.12
compiled with harfbuzz version 2.5.3; using 2.5.3
compiled with icu version 60.1; using 60.1
compiled with jpeg version 9.3
compiled with liblzma version 50020042; using 50020042
compiled with libpng version 1.6.37; using 1.6.37
compiled with libressl version LibreSSL 2.8.2; using LibreSSL 2.8.2
compiled with MiKTeX Application Framework version 4.0; using 4.0
compiled with MiKTeX Core version 4.0; using 4.0
compiled with MiKTeX Archive Extractor version 4.0; using 4.0
compiled with MiKTeX Package Manager version 4.0; using 4.0
compiled with poppler version 0.60.1
using teckit version 2.4
compiled with uriparser version 0.9.2
compiled with zlib version 1.2.11; using 1.2.11

/* if cmd was \XeTeXpdffile, use xpdflib to read it */
if (pdfBoxType != 0) {
err = pdf_get_rect(pic_path, page, pdfBoxType, bounds);
goto done;
}

Where does xpdflib belong to? poppler?

pdfinfo -box test_0.pdf:

Creator:        Asymptote 2.67git2.67-7
Producer:       GPL Ghostscript 9.52
CreationDate:   Sat Jul 11 10:34:01 2020 Central European Daylight Time
ModDate:        Sat Jul 11 10:34:01 2020 Central European Daylight Time
Tagged:         no
UserProperties: no
Suspects:       no
Form:           none
JavaScript:     no
Pages:          1
Encrypted:      no
Page size:      113.39 x 113.39 pts
Page rot:       0
MediaBox:           0.00     0.00   113.39   113.39
CropBox:            0.00     0.00   113.39   113.39
BleedBox:           0.00     0.00   113.39   113.39
TrimBox:            0.00     0.00   113.39   113.39
ArtBox:             0.00     0.00   113.39   113.39
File size:      2470 bytes
Optimized:      no
PDF version:    1.4

pdfinfo:

pdfinfo version 0.60.1
Copyright 2005-2017 The Poppler Developers - http://poppler.freedesktop.org
Copyright 1996-2011 Glyph & Cog, LLC
Usage: pdfinfo [options] <PDF-file>
  -f <int>             : first page to convert
  -l <int>             : last page to convert
  -box                 : print the page bounding boxes
  -meta                : print the document metadata (XML)
  -js                  : print all JavaScript in the PDF
  -struct              : print the logical document structure (for tagged files)
  -struct-text         : print text contents along with document structure (for tagged files)
  -isodates            : print the dates in ISO-8601 format
  -rawdates            : print the undecoded date strings directly from the PDF file
  -dests               : print all named destinations in the PDF
  -enc <string>        : output text encoding name
  -listenc             : list available encodings
  -opw <string>        : owner password (for encrypted files)
  -upw <string>        : user password (for encrypted files)
  -v                   : print copyright and version info
  -h                   : print usage information
  -help                : print usage information
  --help               : print usage information
  -?                   : print usage information

test_0.pdf is 40 mm x 40 mm, i.e. 113.385826772 bp x 113.385826772 bp, and that matches the pdfinfo output.
Also, poppler 0.60.1 seems to be used in both pdfinfo and xelatex.

@ivankokan
Copy link
Contributor Author

ivankokan commented Aug 30, 2020

miktex seems to round with xetex all image sizes to full pt values:

\documentclass{article}

\setbox0=\hbox{\XeTeXpdffile example-image-a.pdf\relax}
\showthe\wd0
\showthe\ht0


\setbox0=\hbox{\XeTeXpicfile example-image-a.jpg\relax}
\showthe\wd0
\showthe\ht0

\begin{document}
blub
\end{document}

gives with miktex:

> 321.0pt.
l.18 \showthe\wd0
                 
? 
> 240.0pt.
l.19 \showthe\ht0
                 
? 
> 401.0pt.
l.23 \showthe\wd0
                 
? 
> 301.0pt.
l.24 \showthe\ht0

and with texlive

> 321.20001pt.
l.18 \showthe\wd0
                 
? 
> 240.9pt.
l.19 \showthe\ht0
                 
? 
> 401.5pt.
l.23 \showthe\wd0
                 
? 
> 301.125pt.
l.24 \showthe\ht0

Essentially, it is what @u-fischer found out: the width, height and depth of \hbox{\includegraphics{test_0}} are:

  • 113.81493pt, 113.81493pt, 0.0pt with pdflatex 👍
  • but 112.99973pt, 112.99973pt, 0.0pt with xelatex 👎.

@ivankokan
Copy link
Contributor Author

miktex seems to round with xetex all image sizes to full pt values:

\documentclass{article}

\setbox0=\hbox{\XeTeXpdffile example-image-a.pdf\relax}
\showthe\wd0
\showthe\ht0


\setbox0=\hbox{\XeTeXpicfile example-image-a.jpg\relax}
\showthe\wd0
\showthe\ht0

\begin{document}
blub
\end{document}

gives with miktex:

> 321.0pt.
l.18 \showthe\wd0
                 
? 
> 240.0pt.
l.19 \showthe\ht0
                 
? 
> 401.0pt.
l.23 \showthe\wd0
                 
? 
> 301.0pt.
l.24 \showthe\ht0

and with texlive

> 321.20001pt.
l.18 \showthe\wd0
                 
? 
> 240.9pt.
l.19 \showthe\ht0
                 
? 
> 401.5pt.
l.23 \showthe\wd0
                 
? 
> 301.125pt.
l.24 \showthe\ht0

Interestingly, (what @u-fischer found out) it seems that the wrong dimensions are present even for JPEG (probably for other non-PDF formats as well).

I see that different code (libs) are being used, meaning that the issue is present not only in one place? Or maybe there is an unique issue in postprocessing (of both)?

PDF:

/* if cmd was \XeTeXpdffile, use xpdflib to read it */
if (pdfBoxType != 0) {
err = pdf_get_rect(pic_path, page, pdfBoxType, bounds);
goto done;
}

JPEG:

if (check_for_jpeg(fp)) {
struct JPEG_info info;
err = JPEG_scan_file(&info, fp);
if (err == 0) {
bounds->wd = (info.width * 72.27) / info.xdpi;
bounds->ht = (info.height * 72.27) / info.ydpi;
}
goto done;
}

@ivankokan
Copy link
Contributor Author

ivankokan commented Oct 25, 2020

Hi @edocevoli. I am keen to help with debugging and resolving this issue. Can you please instruct how to set up the dev environment? (In general, I cannot find such instructions.)

@ivankokan
Copy link
Contributor Author

ivankokan commented Nov 5, 2020

I finally managed to build and do some testing and logging.

Let's recall that the original graphics dimensions are 40 mm x 40 mm. Additionally, we have 40 mm = 113.385826772 pt (PostScript) = 113.811023622395 pt (TeX) (up to some numeric precision).

Compiling the "with 12pt" version with \tracingall gives me:

pdflatex

Completed box being shipped out [1]
\vbox(632.5+0.0)x429.0
.\glue 17.0
.\vbox(615.5+0.0)x390.0, shifted 39.0
..\vbox(12.0+0.0)x390.0, glue set 12.0fil
...\glue 0.0 plus 1.0fil
...\hbox(0.0+0.0)x390.0
..\glue 25.0
..\glue(\lineskip) 0.0
..\vbox(548.5+0.0)x390.0, glue set 434.63864fil
...\write-{}
...\glue(\topskip) 0.0
...\hbox(113.81493+0.0)x390.0, glue set 258.56024fil
....\hbox(0.0+0.0)x17.62482
....\hbox(113.81493+0.0)x113.81493
.....\hbox(113.81522+0.0)x113.81522
......\hbox(113.81522+0.0)x113.81522
.......\hbox(113.81522+0.0)x0.0
........\hbox(113.81522+0.0)x0.0, glue set - 113.81522fil
.........\hbox(113.81522+0.0)x113.81522
..........\pdfrefximage(113.81522+0.0)x113.81522
.........\glue 0.0 plus 1.0fil minus 1.0fil
.......\kern 113.81522
.......\glue 0.0 plus 1.0fil minus 1.0fil
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
...\glue 0.0 plus 1.0fil
...\glue 0.0
...\glue 0.0 plus 0.0001fil
..\glue(\baselineskip) 22.26668
..\hbox(7.73332+0.0)x390.0, glue set 192.06253fil
...\glue 0.0 plus 1.0fil
...\OT1/cmr/m/n/12 1
...\glue 0.0 plus 1.0fil

xelatex

Completed box being shipped out [1]
\vbox(632.5+0.0)x429.0
.\glue 17.0
.\vbox(615.5+0.0)x390.0, shifted 39.0
..\vbox(12.0+0.0)x390.0, glue set 12.0fil
...\glue 0.0 plus 1.0fil
...\hbox(0.0+0.0)x390.0
..\glue 25.0
..\glue(\lineskip) 0.0
..\vbox(548.5+0.0)x390.0, glue set 435.45377fil
...\write-{}
...\glue(\topskip) 0.0
...\hbox(112.99973+0.0)x390.0, glue set 259.00027fil
....\hbox(0.0+0.0)x18.0
....\hbox(112.99973+0.0)x112.99973
.....\hbox(113.0+0.0)x113.0
......\hbox(113.0+0.0)x113.0
.......\hbox(113.0+0.0)x0.0
........\special{pdf:btrans}
........\special{x:scale 1 1}
........\hbox(113.0+0.0)x0.0, glue set - 113.0fil
.........\hbox(113.0+0.0)x113.0
..........\XeTeXpdffile "./test_0.pdf"
.........\glue 0.0 plus 1.0fil minus 1.0fil
........\special{pdf:etrans}
.......\kern 113.0
.......\glue 0.0 plus 1.0fil minus 1.0fil
....\penalty 10000
....\glue(\parfillskip) 0.0 plus 1.0fil
....\glue(\rightskip) 0.0
...\glue 0.0 plus 1.0fil
...\glue 0.0
...\glue 0.0 plus 0.0001fil
..\glue(\baselineskip) 22.02
..\hbox(7.98+0.0)x390.0, glue set 192.06fil
...\glue 0.0 plus 1.0fil
...\TU/lmr/m/n/12 1
...\glue 0.0 plus 1.0fil

113.81522 pt are correct (pdflatex). On the other hand, 113.0 pt are not (xelatex).

Adding logs into XeTeX_pic.c and pdfimage.cpp I find that these dimensions are reported: 113.39 pt (PostScript) = 113.815 pt (TeX).

Thank you both for your efforts. Please keep in mind that XeTeX uses a bunch of 3rd party libraries (see xetex --version) and it is quite likely that MiKTeX and TeX Live differ with respect to the library versions.

It seems that 3rd party library works correctly, and that dimensions are rounded after calling find_pic_file.

@ivankokan ivankokan changed the title Slightly different positioning of graphics compiling with xelatex instead of pdflatex xetex rounds all image sizes to integer pt values Nov 5, 2020
@ivankokan
Copy link
Contributor Author

I see that different code (libs) are being used, meaning that the issue is present not only in one place? Or maybe there is an unique issue in postprocessing (of both)?

The issue definitely lies in postprocessing.

@ivankokan
Copy link
Contributor Author

ivankokan commented Nov 6, 2020

Hi @edocevoli. Here is the root cause...

When xetex.cc is generated from xetex.web, these lines

  setPoint(corners[0], xField(bounds), yField(bounds));
  setPoint(corners[1], xField(corners[0]), yField(bounds) + htField(bounds));
  setPoint(corners[2], xField(bounds) + wdField(bounds), yField(corners[1]));
  setPoint(corners[3], xField(corners[2]), yField(corners[0]));

are translated to:

  setpoint (corners[ 0 ], xfield (bounds), yfield (bounds));
  setpoint (corners[ 1 ], xfield (corners[ 0 ]), yfield (bounds) + (C4P_integer)     htfield (bounds));
  setpoint (corners[ 2 ], xfield (bounds) + (C4P_integer)     wdfield (bounds), yfield (corners[ 1 ]));
  setpoint (corners[ 3 ], xfield (corners[ 2 ]), yfield (corners[ 0 ]));

where two (C4P_integer) casts round dimensions to integer values.

Why do they even appear here? Does the original source code somehow suggest that htField and wdField return integer values?

Eventually, there are tens of thousands (C4P_integer) casts. Hopefully, the fix will not make any harm to other parts of the code?

My guess is that C4P grammar must be updated, at least these four sections:

| expression relational_operator
{
if (relational_cast_expressions)
{
$<buf_mark>$ = cppout.get_buf_mark();
cppout.out_s("(C4P_integer) ");
}
}

| '-'
{
cppout.out_s(" - ");
if (other_cast_expressions)
{
cppout.out_s("(C4P_integer) ");
}
}

| simple_expression adding_operator
{
if (other_cast_expressions)
{
$<buf_mark>$ = cppout.get_buf_mark();
cppout.out_s("(C4P_integer) ");
}
}

| term multiplying_operator
{
if (other_cast_expressions)
{
$<buf_mark>$ = cppout.get_buf_mark();
cppout.out_s("(C4P_integer) ");
}
}

@edocevoli
Copy link
Member

Thank, the grammar should certainly reviewed. Some of the explicit C4P_integer may be unnecessary or wrong. Now that you have narrowed down the issue (thanks), it should be possible to provide a fix.

@edocevoli edocevoli self-assigned this Nov 6, 2020
@edocevoli edocevoli added this to the 20.12 milestone Nov 6, 2020
@edocevoli edocevoli added the bug label Nov 6, 2020
@ivankokan
Copy link
Contributor Author

ivankokan commented Nov 8, 2020

For the record, there are 83 files with 31485 occurrences of (C4P_ after cmake, make and make install (grep -rn '.' -e '(C4P_' | wc -l):

./Programs/Generators/patgen/patgen.cc
./Programs/DviWare/dvicopy/dvicopy.h.intermediate
./Programs/DviWare/dvicopy/dvicopy.h
./Programs/DviWare/dvicopy/dvicopy.cc
./Programs/TeXAndFriends/xetex/CMakeLists.txt
./Programs/TeXAndFriends/xetex/xetex.cc
./Programs/TeXAndFriends/xetex/xetexd.h
./Programs/TeXAndFriends/xetex/xetexd.h.intermediate
./Programs/TeXAndFriends/pdftex/pdftexd.h.intermediate
./Programs/TeXAndFriends/pdftex/CMakeLists.txt
./Programs/TeXAndFriends/pdftex/pdftex.cc
./Programs/TeXAndFriends/pdftex/pdftexd.h
./Programs/TeXAndFriends/omega/omegaware/ofm2opl.cc
./Programs/TeXAndFriends/omega/omegaware/opl2ofm.h
./Programs/TeXAndFriends/omega/omegaware/opl2ofm.h.intermediate
./Programs/TeXAndFriends/omega/omegaware/opl2ofm.cc
./Programs/TeXAndFriends/omega/omegaware/ovp2ovf.h.intermediate
./Programs/TeXAndFriends/omega/omegaware/ovp2ovf.cc
./Programs/TeXAndFriends/omega/omegaware/ovf2ovp.h.intermediate
./Programs/TeXAndFriends/omega/omegaware/ofm2opl.h.intermediate
./Programs/TeXAndFriends/omega/omegaware/ovp2ovf.h
./Programs/TeXAndFriends/omega/omegaware/ofm2opl.h
./Programs/TeXAndFriends/omega/omegaware/odvicopy.cc
./Programs/TeXAndFriends/omega/omegaware/odvicopy.h
./Programs/TeXAndFriends/omega/omegaware/odvicopy.h.intermediate
./Programs/TeXAndFriends/omega/omegaware/ovf2ovp.cc
./Programs/TeXAndFriends/omega/omegaware/ovf2ovp.h
./Programs/TeXAndFriends/Knuth/tex/CMakeLists.txt
./Programs/TeXAndFriends/Knuth/tex/tex.h.intermediate
./Programs/TeXAndFriends/Knuth/tex/tex.cc
./Programs/TeXAndFriends/Knuth/tex/tex.h
./Programs/TeXAndFriends/Knuth/etc/vptovf.cc
./Programs/TeXAndFriends/Knuth/etc/vftovp.h.intermediate
./Programs/TeXAndFriends/Knuth/etc/vftovp.cc
./Programs/TeXAndFriends/Knuth/etc/vptovf.h
./Programs/TeXAndFriends/Knuth/etc/vftovp.h
./Programs/TeXAndFriends/Knuth/etc/vptovf.h.intermediate
./Programs/TeXAndFriends/Knuth/mf/mf.cc
./Programs/TeXAndFriends/Knuth/mf/CMakeLists.txt
./Programs/TeXAndFriends/Knuth/mf/mf.h.intermediate
./Programs/TeXAndFriends/Knuth/mf/mf.h
./Programs/TeXAndFriends/Knuth/mfware/gftopk.h.intermediate
./Programs/TeXAndFriends/Knuth/mfware/gftype.cc
./Programs/TeXAndFriends/Knuth/mfware/gftodvi.h
./Programs/TeXAndFriends/Knuth/mfware/gftype.h
./Programs/TeXAndFriends/Knuth/mfware/mft.h.intermediate
./Programs/TeXAndFriends/Knuth/mfware/gftopk.cc
./Programs/TeXAndFriends/Knuth/mfware/gftodvi.cc
./Programs/TeXAndFriends/Knuth/mfware/mft.cc
./Programs/TeXAndFriends/Knuth/mfware/gftype.h.intermediate
./Programs/TeXAndFriends/Knuth/mfware/gftopk.h
./Programs/TeXAndFriends/Knuth/mfware/mft.h
./Programs/TeXAndFriends/Knuth/mfware/gftodvi.h.intermediate
./Programs/TeXAndFriends/Knuth/web/tangle.h
./Programs/TeXAndFriends/Knuth/web/weave.h
./Programs/TeXAndFriends/Knuth/web/tangle.cc
./Programs/TeXAndFriends/Knuth/web/tangle.h.intermediate
./Programs/TeXAndFriends/Knuth/web/weave.cc
./Programs/TeXAndFriends/Knuth/web/weave.h.intermediate
./Programs/TeXAndFriends/Knuth/texware/dvitype.h.intermediate
./Programs/TeXAndFriends/Knuth/texware/tftopl.h.intermediate
./Programs/TeXAndFriends/Knuth/texware/pltotf.cc
./Programs/TeXAndFriends/Knuth/texware/dvitype.cc
./Programs/TeXAndFriends/Knuth/texware/dvitype.h
./Programs/TeXAndFriends/Knuth/texware/pltotf.h
./Programs/TeXAndFriends/Knuth/texware/tftopl.h
./Programs/TeXAndFriends/Knuth/texware/pltotf.h.intermediate
./Programs/TeXAndFriends/Knuth/texware/tftopl.cc
./Programs/TeXAndFriends/Knuth/texware/pooltype.cc
./Programs/Bibliography/bibtex/bibtex.cc
./Programs/Bibliography/bibtex/bibtex.h.intermediate
./Programs/Bibliography/bibtex/bibtex.h
./BuildUtilities/c4p/CMakeFiles/c4p.dir/gram.cpp.o
./BuildUtilities/c4p/CMakeFiles/c4p.dir/misc.cpp.o
./BuildUtilities/c4p/gram.y
./BuildUtilities/c4p/subrange.cpp
./BuildUtilities/c4p/misc.cpp
./BuildUtilities/c4p/gram.cpp
./BuildUtilities/c4p/common.h
./BuildUtilities/c4p/gram.tab.c
./Libraries/MiKTeX/TeXAndFriends/c4plib.cpp
./Libraries/MiKTeX/TeXAndFriends/include/miktex/C4P/C4P.h
./sandbox/miktex/bin/linux-x86_64/c4p

Additionally:

  • Why is Web -> Pascal -> C/C++ translation implemented, can't binaries be built from Pascal? I guess the second step is necessary because of the interoperability with other C/C++ libraries?
  • Is Web2C used at all and what is its relation with C4P? Is C4P MiKTeX-specific library?

@edocevoli
Copy link
Member

Why is Web -> Pascal -> C/C++ translation implemented, can't binaries be built from Pascal? I guess the second step is necessary because of the interoperability with other C/C++ libraries?

In the old days, C/C++ compiler did produce better (faster) code than C/C++. And nowadays, it is hard to find a working Pascal compiler.

Is Web2C used at all and what is its relation with C4P? Is C4P MiKTeX-specific library?

web2c is not used. Instead, MiKTeX uses c4p (just another Pascal-to-C converter).

edocevoli added a commit that referenced this issue Nov 9, 2020
@edocevoli
Copy link
Member

I have removed the wrong casts. This should fix the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants