Is it possible to determine the (pixel-)width of text-strings bevore SVGs are created with scripts - perl

I am about the create a bunch of SVG graphics with (probabably) a perl script. These SVG graphics will contain text blocks. Since I want to "connect" such text blocks (of varying widths) with lines I'd like to know what width a text will be so that I can draw the connecting lines' length accordingly.
I have seen in SVG get text element width that it could be possible with java script. But that's probably not what I am after since I don't intend to host the SVG in a browser.
So, I thought that maybe there's a way to find out the desired width at the script's runtime. If someone can point me to a solution (also outside the realm of perl but on windows), I'd be very gratefu.

I did that exactly that about a year ago using PDF::API2 and advancewidth function: https://metacpan.org/module/PDF::API2::Content#width-txt-advancewidth-string-text_state-
Note that you need to correlate DPI of PDF and SVG: they may be different (I actually did that just dividing values by 1.25, you can be better).
PDF::API2 gives you very accurate values that works for Inkscape (in my case) well.

Related

Export to vector graphics fails with large number of data-points

I want to export some MATLAB-plots as vector-graphics for presentations. In the most cases, using print-command, for example:
set(0,'defaultAxesTickLabelInterpreter','Latex')
set(0,'defaultTextInterpreter','Latex')
t=linspace(0,6,6000);
s=sin(t);
figure
for spl=1:16
subplot(4,4,spl);
plot(t,s,'k')
end
print('Sinetest','-dpdf');
but as soon as the number of data-points (or the expected file size) turns too big, for example use t=linspace(0,6,7000); the method fails: instead of a scalable vector graphic, an ugly pixel-monster is saved in the .pdf-file. I've tried to use other file-formats, for exampl .emf, .eps, .svg (svg is what I need actually) instead of .pdf, but it's always the same problem. Reducing the number of data points works in this example, but not in general for me.
Is there any option or work around?
The solution is to specify that the painter renderer should be used:
print('Sinetest','-dpdf', '-painters');
If you save to a vector graphics file and if the figure RendererMode
property is set to 'auto', then print automatically attempts to use
the Painters renderer. If you want to ensure that your output format
is a true vector graphics file, then specify the Painters renderer.
Note that this may result in long rendering times as mentioned in the docs:
Sometimes, saving a file with the '-painters' option can cause longer
rendering times [...]

Libreoffice Draw Export Resolution makes no sense

I am attempting to make a very simple label using Libreoffice Draw v 4.0.2.2. The label has not much more to it than regularly spaced lines of centered text
This image will be printed, and I have a fixed size/ppi requirement to ensure appropriate print quality.
I set the page size to my specs, and layout the text as I desire. The print shop takes several image formats including .tiff and .png. When I export the image, a dialog pops up that asks for the image size/ resolution. The given ppi is very low (~40) and I require a minimum of 180ppi. When I enter this, the image size adjusts itself and results in an image that is far too small.
The only solution that appears to be viable is to explode the page size and the drawing text size so it gets shrunk upon export. This is a very imprecise and illogical feature (bug?) of the program that I really wish is a result of my ignorance.
I found a thread in the mailing list which describes this issue exactly. The only answer that is given is essentially "yes, this is ridiculous and doesn't help anybody".
Can anyone give some advice to this? Or at least shed some light on who might need this "feature"?
There is something off about the Export tool of LibreOffice in general. It has been years since it is broken. Taking a screenshot is an alternative, but obviously you cannot control the resolution.
So, a better work around is exporting to SVG, and then convert the SVG to PNG with Inkscape. Once downloaded, convert the file with the following command:
inkscape -z -e out.png -w 1024 in.svg
If you are in Windows (x64), you will need to indicate the full path:
"C:/Program Files/Inkscape/inkscape.exe" -z -e out.png -w 1024 in.svg
If you install the 32 bit version, this should work:
"C:\Program Files (x86)/Inkscape/inkscape.exe" -z -e out.png -w 1024 in.svg
This can be done from inside Libre Office, there is no need to use any external tool. The Export dialog is very confusing, yes; you have to realize that both size and resolution can be set independently.
Select File -> Export -> choose the desired format. The export dialog should appear.
TAKE NOTE of Width and Height. Set the desired resolution; notice how Width and Height change (?). Don't worry, restore Width and Height to your saved values. And that's it. You get a high resolution image with the desired size and DPI.
Libre Draw (the one I'm using anyway) is a vector drawing app - have you asked the print shop if they can use vector formats like eps, pdf? Most should be able to in my experience. Then resolution becomes irrelevant.
-Terry

Is it possible to get around MATLAB's limitation on font embedding in vector format files?

According to the MATLAB manual, when you save a figure using print or by choosing file|save, if you choose the painters renderer and save to PDF or EPS vector formats, all fonts get substituted. Is there a way to get around this limitation?
Whenever I output a figure, whether I use print or export_fig, the fonts get substituted, and so they no longer match the fonts in the document that I plan on putting the figure into. I would prefer to keep them in a vector format, because I use LaTeX and so I want to be able to use the same figures in my documents as in my beamer presentations and have them scale nicely without bloating the file size.
If I'm reading that link correctly, not all fonts get substituted. From 'Choosing a Printer Driver':
The table below lists the fonts supported by the MATLAB PostScript and Ghostscript drivers when generated with the Painters renderer (fully vectorized output). This same set of fonts is supported on both Windows and UNIX:
AvantGarde
Helvetica-Narrow
Times-Roman
Bookman
NewCenturySchlbk
ZapfChancery
Courier
Palatino
ZapfDingbats
Helvetica
Symbol
So, if you use one of the above fonts, the output vector-format figure should maintain the correct font. See for example:
list_fonts = listfonts
figure('renderer','painters'),
plot(peaks),
xlabel('this font is Helvetica','fontname','Helvetica','fontsize',24)
set(gcf,'paperpositionmode','auto')
print(gcf,'-depsc2','test1.eps')
Which produces:
So, choose one of the fonts from the list above, and the font will be output correctly. Otherwise, change the font in your presentation to match one of the above fonts.
I also encountered this problem for many times, and I have an simple but effective way that never fails me (on Windows, need GSview).
1) save fig as PDF
2) save PDF as ps
3) open ps with GSview, then click "File->PS to EPS", specify a file name and done.
Hope this helps.

Get image width and height in pixels

so i have looked at a couple other questions like this and from what i saw none of the answers seemed to answer my question. I created a program that creates ASCII art, which is basically a picture of text instead of colors. the way i have the program set up at the moment you have to manually set the Width and Height of the pixels. If the width and height of the pixels is too large it simply wont work. so basically what i want to do is have a function to automatically set the width and height to the size of the picture. http://www.mediafire.com/?3nb8jfb8bhj8d is the link to the program now. I looked into pixel grabber but the constructor methods all needed a range of pixels. I also have another folder for the classes, http://www.mediafire.com/?2u7qt21xhbwtp
on another note this program is incredibly inefficient, i know that it is inefficient in the grayscaleValue() method, but i dont know if there is any better way to do this. Any suggestions on this program would be awesome too. Thanks in advance! (this program was all done on eclipse)
After you read the image into your BufferedImage, you can call getWidth() and getHeight() on it to get this information dynamically. See the JavaDocs. Also, Use a constructor for GetPixelColor to create the BufferedImage once and for all. This will avoid reading the entire file from disk for each channel of each pixel.
For further code clean up, change series of if statements to a switch construct, or an index into an array, whichever is more natural. See this for an explanation of the switch construct.
One last comment: anything inside a class that logically represents the state of an object should be declared non static. If, say, you wanted to render two images side by side, you would need to create to instances if GetPixelColor, and each one should have its own height and width attributes. Since they're currently declared static, each instance would be sharing the same data, which is clearly not desireable behavior.

FreeType2: Get global font bounding box in pixels?

I'm using FreeType2 for font rendering, and I need to get a global bounding box for all fonts, so I can align them in a nice grid. I call FT_Set_Char_Size followed by extracting the global bounds using
int pixels_x = ::FT_MulFix((face->bbox.xMax - face->bbox.xMin), face->size->metrics.x_scale );
int pixels_y = ::FT_MulFix((face->bbox.yMax - face->bbOx.yMin), face->size->metrics.y_scale );
return Size (pixels_x / 64, pixels_y / 64);
which works, but it's quite a bit too large. I also tried to compute using doubles (as described in the FreeType2 tutorial), but the results are practically the same. Even using just face->bbox.xMax results in bounding boxes which are too wide. Am I doing the right thing, or is there simply some huge glyph in my font (Arial.ttf in this case?) Any way to check which glyph is supposedly that big?
Why not calculate the min/max from the characters that you are using in the string that you want to align? Just loop through the characters and store the maximum and minimum from the characters that you are using. You can store these values after you rendered them so you don't need to look it up every time you render the glyphs.
I have a similar problem using freetype to render a bunch of text elements that will appear in a grid. Not all of the text elements are the same size, and I need to prerender them before I know where they would be laid out. The different sizes were the biggest problem when the heights changed, such as for letters with descending portions (like "j" or "Q").
I ended up using the height that is on the face (kind of like you did with the bbox). But like you mentioned, that value was much to big. It's supposed to be the baseline to baseline distance, but it appeared to be about twice that distance. So, I took the easy way out and divided the reported height by 2 and used that as a general height value. Most likely, the height is too big because there are some characters in the font that go way high or way low.
I suppose a better way might be to loop through all the characters expected to be used, get their glyph metrics and store the largest height found. But that doesn't seem all that robust either.
Your code is right.
It's not too large.
Because there are so many special symbols that is vary large than ascii charater. . view special big symbol
it's easy to traverse all unicode charcode, to find those large symbol.
if you only need ascii, my hack method is
FT_MulFix(face_->units_per_EM, face_->size->metrics.x_scale ) >> 6
FT_MulFix(face_->units_per_EM, face_->size->metrics.y_scale ) >> 6