HPDF units for text width and height - pdf-generation

Maybe it's just my head spinning, but there seems to be no documentation on the units of measure for HPDF's HPDF_Font_TextWidth() function, nor can I figure it out.
The number I get for a particular text of 7 characters is around 3000. The rendered text seems to be around 80 pixels, which is also returned from HPDF_Page_TextWidth().
HPDF_Font_TextWidth() does not know the font size so it must use some other unit. What is it?
And is that the same unit that HPDF_Font_GetBBox() returns?
I'm actually trying to put text in the center of a rectangle, and need the width and height of the text in the units of the rectangle.

This is an old post but I just stumbled upon it because I had the same issue. As far as I know, looking into the source of HPDF_Font_GetUnicodeWidth(), the units that it returns needs to be multiplied by the font size, then divided by 1000 to get the width in points, which is what the rest of the PDF coordinate system uses.
width = (HPDF_Font_TextWidth() * font_size) / 1000.0;

All the following return EM units, which must be divided by 1000 and multiplied by the point size to get points, as stated above:
The units are relative to the baseline. Descender, BBox left & bottom are negative. The zone between caps Height and ascender is for diacritics.
To calculate the height of a slug of text, compute caps height less descender, or ascender less descender if your text has upper-case diacritics.
Keyword: Haru PDF

Related

Read the width and length of the pixel in .dcm format with dicominfo

I have pictures in .dcm format.
I'm looking for the width and length of the pixel.
As far as I know that Dicominfo gives the information of the picture.
Do you know what parameters are used to obtain the width and length of the pixel in the Dicominfo?
I had an idea that I first need the FOVx "Field Of View" and then I can divide by the number of pixels. This is how I get the width and length of the pixel.
I am very grateful for every answer.
Not sure what you exactly mean by "length". Furthermore, geometrical information (pixel size in mm) may vary regarding the tag numbers, depending on the type of object. The attribute tags I am providing here should work for the majority of DICOM images that have geometrical information at all.
image size in pixels (x,y) -> Columns (0028,0011), Rows (0028,0010)
size of the pixels (y,x) -> Pixel Spacing (0028,0030)
Pixel Spacing is a multi-valued attribute from which you can obtain two values which are separated by a Backslash "\". Not sure how the API of DicomInfo allows access to multiple values in the same attribute.
Note the difference "(y,x)" in Pixel Spacing. This is very unintuitive, but it is like it is.

Specifying a pitch for SetDIBitsToDevice

I am displaying bitmaps with the function SetDIBitsToDevice. This function knows about the total image size via a LPBITMAPINFO structure that has Width and Height fields. It also knows about the region of interest to be drawn via the arguments XDest, YDest, Width, Height. All these are specified in pixels.
So far so good when the image is stored as a canonical one, i.e. with a row pitch (number of bytes between a pixel and the one immediately below) that matches the image width in bytes, with padding (if necessary) to reach the next multiple of four bytes.
For technical reasons, I have images with a larger pitch (but still a multiple of four). For instance, width=1000 but pitch=1024. For a grayscale image (1 byte per pixel), I can trick the function by declaring a width of 1024 in LPBITMAPINFO and a width of 1000 when passed to SetDIBitsToDevice.
But for a 3 bytes per pixels image (RGB), I am stuck because 1024 bytes do not correspond to an integer number of pixels, and I see no way to specify that pitch.
Do you see a workaround or something I missed in the documentation ? (I don't think that the field SizeImage can be of any use.)

Element x, y, width, height translation to different dimensions

My math must be very rusty. I have to come up with an algorithm that will take a known:
x
y
width
height
of elements in a document and translate them to the same area on a different hardware device. For example, The document is being created for print (let's assume 8.5"x11" letter size) and elements inside of this document will then be transferred to a proprietary e-reader.
Also, the known facts about the e-reader, the screen is 825x1200 pixels portrait. There are 150 pixels per inch.
I am given the source elements from the printed document in points (72 Postscript points per inch).
So far I have an algorithm that get's close, but it needs to be exact, and I have a feeling I need to incorporate aspect ratio into the picture. What I am doing now is:
x (in pixels) = ( x(in points)/width(of document in points) ) * width(of ereader in pixels)
etc.
Any clues?
Thanks!
You may want to revert the order of your operations to reduce the effect of integer truncation, as follows:
x (in pixels) = x(in points) * width(of ereader in pixels) / width(of document in points)
I don't think you have an aspect ratio problem, unless you forgot to mention that your e-reader device has non-square pixels. In that case you will have a different amount of pixels per inch horizontally and vertically on the device's screen, so you will use the horizontal ppi for x and the vertical ppi for y.
assuming your coordinates are integer numbers, the formula x/width is truncating (integer division). What you need is to perform the division/multiplication in floating point numbers, then truncate. Something like
(int)(((double)x)/width1*width2)
should do the trick (using C-like conversion to double and int)

UIScrollView zoomscale inaccuracy

I am trying to fit an image into a predefined graphical representation of a frame (not a view.frame) using UIZoomView.
For adjusting the zoomscale in a way that the image fits into the desired frame width of 250, the code basically is:
float frameWidth=250;
float currentZoomScale=frameWidth/currentImage.size.width;
self.scrollView.zoomScale=currentZoomScale;
This works almost fine...almost. My problem is a slight inaccuracy depending on the image width.
For example, an image with a width of 640 will result in a zoomScale of 0.390625.
But the visible image width on the screen will be 1 pixel below 250. With other images of different sizes the algorithm works.
I suspect the reason is that the floating point nature of the division result collides with the integer nature of the actual screen pixels...I mean that the zoomscale should be something like 0.391 or similar (I tried 0.4, which is too big).
My questions:
Is the algorithm above the right way
to get what I want?
If yes, is there a way to take the inaccuracy into account, i.e. a better algorithm?
Thanks for any reply!
I suspect the division you are using is producing a decimal number and when converted to pixels the decimal number is scrapped because you can't have 0.5 of a pixel. You could automatically round up. Change you algorithm to this:
(currentImage.size.width+frameWidth-1)/currentImage.size.width
This will give you a whole number rounded up every time.

How to calculate screen resolution change

I have an application that is on a mobile device. I am moving resolutions of my app from 240W x 320L to 640W X 480L.
I have a bunch of columns that have their width in pixels (say 55 for example). I need to convert this to the new resolution.
"Easy", I thought 640/240 = 2 2/3. So I just take 55 * 2.6666667 and that is my new width.
Alas, that did not work. My columns (all together) are larger than my screen size now.
I tried 55 * 2 and that is too small. I am sure I can get there with trial an error, but I want to know an exact ratio.
So, what am I missing? how do I calculate my new column widths (other than by trial and error).
Rounding is your problem; Suppose that you have 24 columns of 10 pixels on the 240 pixel display. You calculate the new width: 10*2.667 = 27 so the total width sums to: 648 > 640. Oops...
To get this right you need to scale the absolute location of the column. That is if column number k begins on x-coordinate = X then after scaling it should begin on round(X*2.667). After this subtract rounded right side X from rounded left side X to get the width. This way you will round widths down and some up, but the total width will remain inside your limits.
The screen DPI is changing when resolution changes. So you need to take this into account.
Check this link about DPI Aware apps and search according to your platform (Native or CF)
I think your logic is good, but maybe you had rounding errors? If you want to make sure the total width is less than the screen resolution, after multiplying by the scale factor you should always round down to the nearest integer to get the width in pixels.
Also, if your columns have any padding, borders, or other space between them, you would have to take that into account as well.
If you can run on a desktop environment, I know there are "pixel ruler" sort of tools to actually measure things on the screen, you can search Google for them.

Resources