# How to get clean, pixel perfect strokes in tables

I'm conscious that this may be unanswerable because of limitation in LaTeX itself, but I'll expose my problem anyway.

## Introduction

I'm having a table that renders perfectly in every viewer I tested when it is constructed in Microsoft Word, then exported to PDF from Word.

I'm trying to reproduce this table as much as possible in LaTeX and I'm unable to have the same results on the borders.

A comparison is shown below, note that even if the LaTex screenshot showcases the Calibri font, it's still LaTeX behind the wheel (please click images to display them at 100%):

As you can see, the second table does not display nearly as good as the first table.

## Comparisons

I did some experiments with different zoom levels (100, 150, and 160%) in Google Chrome's viewer (which I believe will be the main viewer of the target document) of tables rendered by Word, LaTex and LibreOffice (which apparently has the same problem):

(Don't forget to open the images at 100% size to have a real representation of my problem)

As you can see here, in the first two zoom levels, the lines are rendered as perfect 1px lines, and there is a threshold at which it switches to 2px lines (visible in the last zoom level).

Here the lines are antialiased (badly), some lines are 1px wide, some are 1.5, etc.

I opened both PDF in Master PDF Editor (a good tool) to inspect the generated lines:

LaTeX's (and LibreOffice's) lines are converted to native Strokes whereas Office renders line as fixed width filled rectangles, which apparently PDF viewer render better.

I know ultimately it is probably a problem with the viewer (in this case Chrome, it happens also in Slack, Evince, probably others, I didn't see any that didn't have the problem), and the real question here is can I do something to mitigate the problem?

## MWE

MWE to get a PDF that renders poorly in Chrome / Evince (at low zoom levels):

\documentclass[11pt, a4paper]{article}

\usepackage{colortbl}
\usepackage{tabularx}

\begin{document}

\noindent
\begin{tabularx}{\textwidth}{|>{\columncolor[gray]{0.95}}l|X|}
\hline
Titre                & Some text here                    \\\hline
Date de modification & \today                            \\\hline
Responsable          & Some name                         \\\hline
E-mail               & Sorry for the french              \\\hline
Sujet                & Lorem Ipsum                       \\\hline
Version du document  & 2.0                               \\\hline
\end{tabularx}

\end{document}


Again, this is what it looks like in Chrome, at 100% zoom, quite unprofessional if you want my opinion:

• You can presumably turn anti-aliasing off or toggle thin-line enhancement or whatever your viewer provides. These are recognitions of the problem, since there isn't much even the viewer can do. It is really a result of pixel displays, I guess. With a sufficiently high resolution display, the problem would become invisible.
– cfr
Mar 3, 2017 at 3:55
• I meant that Word's tables do not look professional quality, regardless of the lines looking perfect. They don't look like the high quality tables you see in publications, for example. Of course, maybe Word can create such tables. I wouldn't know. But there is a definite look to the ones people do create with it.
– cfr
Mar 3, 2017 at 4:00
• @jon I don't see that. Sure, it is a viewer problem. But, can LaTeX implement this particular workaround seems a perfectly on-topic question to me. We can agree that the PDF LaTeX produces is semantically superior to Word's, but it may still be practically inferior in this respect for certain purposes (e.g. electronic-only distribution). Whether LaTeX can produce PDF that does X rather than Y is on-topic. Whether X or Y is better is, obviously, off-topic. But that's not the question. The case for Y is just to motivate the technical question.
– cfr
Mar 3, 2017 at 5:02
• @jon booktabs rules do not look correct in my viewer. It is not just viewer-dependent. It is screen-resolution dependent and probably more-dependent. Boxes which look more like rules than rules are not an unattractive suggestion. Whether it could be done is another matter. But it is an interesting question, in my view.
– cfr
Mar 3, 2017 at 5:04
• Are you talking about 'strokes' and 'fill'? If so, some pointers as to what those things are would be useful. If they are features of the PDF specification, then, sure, I'd say it's on-topic; if they are PDF reader features, I'm not as convinced. But as I implied (and would have said if not for the character count), I don't know what 'fill' and 'stroke' are in this context.
– jon
Mar 3, 2017 at 5:06

There are several issues at play here. All of them sort of fixable from within TeX, but none that I know of actually fixed "out of the box"

1. Strokes verses filled rectangles.

TeX doesn't mandate anything here. LaTeX uses the TeX primitive \hrule and \vrule but TeX doesn't mandate how they are translated to PDF (or anything else). It would not be possible to address this within the TeX macros of LaTeX but the pdf generation code of pdftex or luatex or of dvi to xxx translators such as dvips or dvipdfm(x) could be altered to use filled rectangles rather than rules. (I seem to recall dvips sources having some comments about related issues here.)

So, without changing tex-the-program or the dvi driver, you would have to the macros to use \pdfliteral or equivalent to make the \hline from a filled rectangle. That is not exactly trivial as the primitive TeX \hline automatically expands to the width of the surrounding box, which is not so easily done with an explicit PDF drawn rule, especially in tables, where by default the macro layer doesn't know the width of each cell.

However even in classic TeX packages like longtable show that to an extent it is possible to discover the extent of table cells, and using features of TeX extensions or dvi drivers, tikzmark or pstricks node etc show that in fact it is possible to mark the final coordinates of any node, and then use the back end drawing language to draw lines (or filled rectangles) at those coordinates.

So if you arranged a table macro so that tikz knew where all the cells were you could use those locations to overlay lines using \pdfliteral so using any PDF construct desired. It might be easier to start with the existing tikz matrix library rather than traditional LaTeX table markup.

2. Rules adjacent to coloured panels.

Most other systems, if rendering a table cell coloured background and a border, render the background first and then render the text and the border over the background, that more or less ensures that small pixel variations in the coloured panels or rules do not obscure the border.

Most latex coloured tables use colortbl which doesn't do that, because it is designed to work with the standard latex table markup, and only use the basic colour specials and not an extended coordinate tracking back end, produces the rules in the order they are encountered, so a cell with four borders and a background colour is rendered in the order top, left, background, text, right, bottom. The border rules do not overlay the background colour panel, they are adjacent to it. Within the TeX dimensions the positioning is exact, but it does mean that when rendered to a device any pixel adjustment of either the edge of the colour panel or the rule is likely to have a visible effect and possibly make the rule invisible, especially at the top or left of the cell where the rule is drawn before the coloured panel.

So...

If I wanted to do this I would probably approach it by first typesetting the table without rules or coloured backgrounds but using tikz or primitive box measuring or \pdfsavepos extensions, to record the dimensions of every cell.

Then work out where the coloured panels need to be based on the saved coordinates. (For example in a "zebra striped" table, you could colour each row as a single coloured panel rather than add a background for each cell separately. Typeset these panels, then output the saved box with the table cells, then re-use the previously saved coordinates to overlay vertical and horizontal rules (perhaps implemented as filled rectangles) using tikz or more primitive drawing commands.

• Thank you for your kind answer. It mostly confirms what I imagine I needed to do in order to fix/reduce my problem, but it really adds many details and vocabulary I didn't have earlier. It is true that there are two issues at hand here and maybe I should've split my question. Mar 3, 2017 at 17:03
• @AntoineBolvy That's why I suggested taking the colour out: that issue is already the subject of many questions and a known issue. There are already workarounds for that - you just need to use them. The distinct question here concerns the boxes vs. rules.
– cfr
Mar 3, 2017 at 21:58

With ConTeXt MKIV and Natural Tables you can easily colour rows or columns selectively.

\starttext

\startsetups table:pixelperfect
\setupTABLE[column][first][background=color,backgroundcolor=gray]
\stopsetups
\startTABLE[setups={table:pixelperfect}]
\NC Titre                \NC Some text here       \NC\NR
\NC Date de modification \NC \currentdate         \NC\NR
\NC Responsable          \NC Some name            \NC\NR
\NC E-mail               \NC Sorry for the french \NC\NR
\NC Sujet                \NC Lorem Ipsum          \NC\NR
\NC Version du document  \NC 2.0                  \NC\NR
\stopTABLE

\stoptext


You could also use xtables which render much faster but are extremely verbose. However, the syntax if very nice for automated generation.

\starttext

\startxtable
\startxrow
\startxcell[background=color,backgroundcolor=gray]
Titre
\stopxcell
\startxcell
Some text here
\stopxcell
\stopxrow
\startxrow
\startxcell[background=color,backgroundcolor=gray]
Date de modification
\stopxcell
\startxcell
\currentdate
\stopxcell
\stopxrow
\startxrow
\startxcell[background=color,backgroundcolor=gray]
Responsable
\stopxcell
\startxcell
Some name
\stopxcell
\stopxrow
\startxrow
\startxcell[background=color,backgroundcolor=gray]
E-mail
\stopxcell
\startxcell
Sorry for the french
\stopxcell
\stopxrow
\startxrow
\startxcell[background=color,backgroundcolor=gray]
Sujet
\stopxcell
\startxcell
Lorem Ipsum
\stopxcell
\stopxrow
\startxrow
\startxcell[background=color,backgroundcolor=gray]
Version du document
\stopxcell
\startxcell
2.0
\stopxcell
\stopxrow
\stopxtable

\stoptext


• can't believe no one gave you a vote in 4 hours:-) Mar 3, 2017 at 15:54
• I tested it and it indeed fixes most of the problem (i.e. the gray background is "really" in the background, behind the rules, so the aliasing problem is reduced). However, I'm not sure I'm ready to change to ConTeXt just for this problem. Still an interesting and correct answer nonetheless ;) Mar 3, 2017 at 17:00

With {NiceTabular} of nicematrix, the rules are drawn by Tikz after the construction of the array (however, this requires several compilations).

The rules won't seem to disappear, even when they are near a colored panel.

\documentclass{article}
\usepackage{nicematrix}
\begin{document}

\begin{center}
\begin{NiceTabularX}{\textwidth}{>{\columncolor[gray]{0.95}}lX}[hvlines,colortbl-like]
Titre                & Some text here         \\
Date de modification & \today                 \\
Responsable          & Some name              \\
E-mail               & Sorry for the french   \\
Sujet                & Lorem Ipsum            \\
Version du document  & 2.0                    \\
\end{NiceTabularX}
\end{center}

\end{document}