gnuplot pdfcairo matches latex font size - latex

I plot a pdf figure using gnuplot 5.0 with pdfcairo terminal, and then insert this figure into a pdf file using latex. However, I found the font size in gunplot is different with the font size in latex, although I set them to be the same.
To make the font size consistent in gnuplot and latex, I have to set the fontscale in gnuplot as 0.75, as shown in the following codes.
gnuplot codes: plot an 'A' in blue (Helvetica, size 12, fontscale 0.75).
set terminal pdfcairo font 'Helvetica,12' size 1cm,1cm fontscale 0.75
set output 'test0.pdf'
set xrange [-1:1]
set yrange [-1:1]
unset xtics
unset ytics
unset border
set label 'A' at 0,0 textcolor 'blue'
p 1/0 notitle
Latex codes: insert the previous figure in original size, and write a black 'A' (Helvetica, size 12) next to the previous 'A'.
\documentclass[12pt]{standalone}
\usepackage{tikz}
\usepackage{helvet}
\usepackage{graphicx}
\begin{document}
\begin{tikzpicture}
\node at (0,0) {\includegraphics{test0.pdf}};
\node at (0.3, -0.025) {\textsf{A}};
\end{tikzpicture}
\end{document}
You can see the final pdf file here. Now we can see these two 'A' are exactly the same size under the gnuplot setting 'fontscale 0.75'. I don't understand why 'fontscale 0.75' should be used in gnuplot, not 'fontscale 1'?
Is this a problem of cairo? And is there any elegant way to deal with this font size issue?
Short answer: gnuplot uses 72dpi, while cairo uses 96dpi. (96/72=4/3)
Note: For the same reason, if using pngcairo, 'fontscale 0.75' should also be used to get the right font size.
Alternative solution: cairolatex. #user8153

I think this might be due to cairo rendering. In order to set the font size, Gnuplot calls function pango_font_description_set_size with the supplied size, i.e., 12 in your case. However, this is then translated into the cairo units:
the size of the font in points, scaled by PANGO_SCALE. (That is, a
size value of 10 * PANGO_SCALE is a 10 point font. The conversion
factor between points and device units depends on system configuration
and the output device. For screen display, a logical DPI of 96 is
common, in which case a 10 point font corresponds to a 10 * (96 / 72)
= 13.3 pixel font.
Moreveor, from the documentation of the function pango_cairo_font_map_set_resolution:
/**
* pango_cairo_font_map_set_resolution:
* #fontmap: a #PangoCairoFontMap
* #dpi: the resolution in "dots per inch". (Physical inches aren't actually
* involved; the terminology is conventional.)
*
* Sets the resolution for the fontmap. This is a scale factor between
* points specified in a #PangoFontDescription and Cairo units. The
* default value is 96, meaning that a 10 point font will be 13
* units high. (10 * 96. / 72. = 13.3).
*
* Since: 1.10
**/
So in summary, it seems that the supplied size is then for the purposes of the rendering multiplied by 96/72 = 4/3 which effectively yields a font of size 16 instead of 12. The scaling factor of 0.75 which you applied would then revert this.

Related

Remove unnecessary margin in epslatex/gnuplot

I would like to remove unnecessary margins (gray part in the figure below) in a PDF figure generated by epslatex (gnuplot).
Following are scripts and commands to create the figure.
set term epslatex standalone
set output "figure.tex"
set xlabel "\\LARGE $x$"
set ylabel "\\LARGE $y$"
set format x "\\Large{%.1f}"
set format y "\\Large{%.1f}"
set key left top Left
set size square
set xrange [0.0:1.0]
set yrange [0.0:1.0]
plot x with lines dt 1 lw 5.0 lc rgb "red" title "\\Large $y = x$",\
x*x with lines dt 2 lw 5.0 lc rgb "green" title "\\Large $y = x^2$",\
x*x*x with lines dt 3 lw 5.0 lc rgb "blue" title "\\Large $y = x^3$"
and commands
$ gnuplot sample.gp
$ pdflatex figure.tex
Instead of pdflatex, xelatex would also work. I would like to directly convert to PDF file.
It will be super good if we can remove these margins without too much effort (such as removing the margin manually one-by-one).
Thanks!
If you check help latex, it will tell you that default size is 5 x 3 inches.
Since you set size square, there will be for sure an "unwanted" left and right margin.
What you can do to at least minimize the margins is to set the terminal size to square size as well, e.g. to 3 x 3 inches.
However, keep in mind the graph size is square but x and y axes have tics and labels which require space depending on numbers and labels which might be different for x and y.
set term epslatex standalone size 3 in, 3 in
From help latex:
Syntax:
set terminal {latex | emtex} {default | {courier|roman} {<fontsize>}}
{size <XX>{unit}, <YY>{unit}} {rotate | norotate}
By default the plot will inherit font settings from the embedding
document. You have the option of forcing either Courier (cmtt) or
Roman (cmr) fonts instead. In this case you may also specify a
fontsize. Unless your driver is capable of building fonts at any size
(e.g. dvips), stick to the standard 10, 11 and 12 point sizes.
...
Maybe, there are LaTeX commands to crop the graph to its bounding box.
Thanks to #AlainMarigot help, I change the system to Lua tikz with the option tightboundingbox.
Looks good, but not exactly same as epslatex.

Calculate logical pixels from millimeters

I have a design with widths, heights, paddings... in millimeters. I'm now trying to figure out how to convert those numbers to the logical pixel system Flutter uses.
I found the docs for the device pixel ratio but I'm not sure how to interpret that number and I quote:
The Flutter framework operates in logical pixels, so it is rarely necessary to directly deal with this property.
So I am not sure if this is the way to go.
My question comes down to this: Is there an easy way to calculate from millimeter to logical pixels that works for both Android and iOS?
Flutter's unit is DP or dip (aka density independent pixels).
Like it's name is implying, it's independent from the screen pixel ratio.
What's the difference with millimeters ? None really important.
Converting mm>dp or dp>mm is similar to mm>inch/inch>mm.
The relationship between them is fairly simple :
1 inch = 25.4 mm = 160.0 DP
Which means 1 mm = 6.299 DP
I would say the current accepted answer is not really accurate.
You can print the number of logical pixels for real phones, like this:
maxWidth = MediaQuery.of(context).size.width;
maxHeight = MediaQuery.of(context).size.height;
print("maxWidth = $maxWidth / maxHeight = $maxHeight");
I would appreciate if someone with real iPhones and iPads could run this code and tell me the resulting maxWidth and maxHeights. So far, with Android phones, I've compiled the results comparing with the real phone sizes. What I got is this:
Galaxy S6 ➜ 5.668537826 dp/mm for height, and 5.668537826 dp/mm for width.
Galaxy S7 ➜ 5.668537826 dp/mm for height, and 5.668537826 dp/mm for width.
Galaxy S9 ➜ 5.223614747 dp/mm for height, and 5.585946405 dp/mm for width.
Pixel XL ➜ 5.612956709 dp/mm for height, and 6.007177748 dp/mm for width.
See my spreadsheet here: https://docs.google.com/spreadsheets/d/1zmGyeKSf4w4B-bX4HSY4oSuh9RkIIkFwYSd3P9C7eX8/edit?usp=sharing
Update:
Android docs (https://developer.android.com/training/multiscreen/screendensities#TaskUseDP) say "One dp is a virtual pixel unit that's roughly equal to one pixel on a medium-density screen (160dpi; the "baseline" density)". That's obviously not true in practice for Samsung and Google phones. Or it is, if you pay attention to the word "roughly".
Flutter docs (https://api.flutter.dev/flutter/dart-ui/FlutterView/devicePixelRatio.html) say it's 3.8 logical pixels per mm, which is obviously very false.
Logical pixel is the ratio of dots per unit distance(mm), so you have to change your question to How many dots per mm represents 1 logical pixel?
As it is mentioned here
Flutter follows a simple density-based format like iOS. Assets might
be 1.0x, 2.0x, 3.0x, or any other multiplier. Flutter doesn’t have dps
but there are logical pixels, which are basically the same as
device-independent pixels. The so-called devicePixelRatio expresses
the ratio of physical pixels in a single logical pixel.
And as mentioned 1.0x logical pixel ratio represents mdpi in Android density qualifiers. And according to this, mdpi ≃ 160DPI and as dpi represents the number of individual dots that can be placed in a line within the span of 1 inch (2.54 cm) so:
160dpi = 160 dots per inch = 6.299 dots per mm
And as mdpi ≃ 160DPI and 1 logical pixel represents mdpi so:
1.0x logical pixel ratio ≃ 6.299 dots per mm
To display a widget at a real size.
double millimeterToSize(double millimeter) => millimeter * 160 * 0.03937;

How can I get a the default width of a specified font in Delphi?

I'm writing a DXF exporter/importer. The DXF MTEXT entity format supports width factor for a text block (how times it is wider than the default font width). The Windows LogFont record contains the lfWidth field (how many pixel will be the average font width if you select the logfont to create a hFont). How can I get the default width of the used font to calculate the scaling factor back and forth? Is there any WinAPI call?
OK. I have found It. The getTextMetrics fills up a TEXTMETRIC record. It has a tmAveCharWidth. The searched value.

SpriteKit SKLabelNode font size to pixels

What's a clean way to use SKLabelNode's fontSize to map to pixels? I'm trying to place text inside a box that fits in a fixed box proportionately.
According to apple's documentation, 1 font point is equal to 2 pixels.
For example, a 90 pixel font is equal to mytext.fontSize = 90 / 2

How to get font size in delphi

I am looking for a function which should take parameters as Font name, sample character, width, height of the sample character and should return Font Size.
It must look like this:
GetFontSize(<Font Name>, <Sample Character>, <Sample Character Width>,
<Sample Character Height>)
which must return the font size,
Is this possible in delphi?
You may want to take a look at this page that discusses font size and points.
It uses the following to convert between the points and pixel size:
Arial 12pt at 96 dpi:
font size in points 12
font size in pixels = ------------------- × 96 dpi = ---- × 96 = 16 pixels
72 points per inch 72
You could use that for your conversion. You just need to be aware of possible differences in your screen dpi as Blorgbeard stated. Points are usually used to describe the size on paper. You need to decide how you want to map that to the screen. For example many programs will allow you to set a zoom level. That does not change the printed size on paper but does affect the pixel height on the screen.
Depending on what you are trying to accomplish you may need to get the actual sizes of the font. If you are trying to find out exactly how the font is put together take a look at Obtaining Font Metrics The code on that page uses the .Net libraries but it has a good explanation. If you want to get the Text Metrics in Delphi you would use the GetTextMetrics function.
As Rob stated in his comment you can draw text at a specific height by setting the Font.Size property to the negative height in pixels. Windows will then draw the text out at that height. In that case you don't need a specific letter or the width as you have in your prototype function. For a given font size each letter will have a different height and width. I.E. capital letters will be taller than lower case letters and letters like "W" will be wider than letters like "i".
I'm only aware of methods to do the opposite - that is, to get pixel sizes from point sizes.
The only way I can think of is to set up a TCanvas, and repeatedly call GetTextExtent on it, changing the font size each time, until you get a size that's acceptably close to what you want.
Depending on how accurate you need this, you could just convert your desired height in pixels to points - a point is 1/72 of an inch, and your screen is probably 96 pixels per inch (but check GetDeviceCaps to get the real figure). See this question.
That would get you a font size pretty close to the pixel size you want.

Resources