Skip to main content
Participating Frequently
February 15, 2022
Question

Recalculate line width with CTM

  • February 15, 2022
  • 1 reply
  • 2709 views

Good day,

 

Context: I am rewriting content acquiring mechanism in Adobe Acrobat Core API.

I am having trouble recalculating line width with CTM. How it should be done?

In PDF Refernce:

The effect produced in device space depends on the current transformation matrix (CTM) in effect at the time the path is stroked. If the CTM specifies scaling by different factors in the horizontal and vertical dimensions, the thickness of stroked lines in device space shall vary according to their orientation.

As I understand, when I encounter w operator, I should only set operands fixed value to graphic state attribute line width and just before setting current path's graphic state (PDEElementSetGState) I should recalculate line width?
I tried this approach first:

 

		ASFixedRect r;
		r.bottom = fixedZero;
		r.left = fixedZero;
		r.right = graphic_state.lineWidth;	
		r.top = graphic_state.lineWidth;		
		ASFixedMatrixTransformRect(&r, &CTM, &r);
		double x1 = ASFixedToFloat(r.right - r.left);
		double y1 = ASFixedToFloat(r.top - r.bottom);
		double width = sqrt((x1 * x1 + y1 * y1) / 2);
		graphic_state.lineWidth = ASFloatToFixed(width);

 

However, I am not getting the correct  (but pretty close) results when using this approach. Maybe anyone has any idea how can i approach this?
Thank you in advance,

Cheers

This topic has been closed for replies.

1 reply

Legend
February 15, 2022

In general there is no line width in device space. There is only a line width in  the (common and normal) case where the CTM has equal X and Y scaling. In general a line width is used as follows:

- a stroked line is contructed in user space, of the required width

- the shape of the line is transformed to device space

- adjustments are made for subjective improvement (undocumented and outside the scope of the standard); this may include pixel snapping, thin line removal or widening, antialiasing and other effects

- the transformed shape is rendered to the device

MikelKlink
Participating Frequently
February 15, 2022

To illustrate what it means that there is no line width in device space as @Test Screen Name said - this is a curve (well, a pair of curves) drawn without changing the width, merely distorted by transformation:

 

The content stream:

5 0 0 1 25 25 cm
50 25 m
50 38.81 38.81 50 25 50 c
11.19 50 0 38.81 0 25 c
S

 

LMax99Author
Participating Frequently
February 17, 2022

Do not recalculate coordinates, widths etc. This is wrong - though it will work most of the time, it will fail for line widths and some other things, for the reason already given.

 

Since I now see you are not rendering, but trying to convert a page stream to PDFEdit calls -- Do NOT apply the CTM to any coordinates or numbers in the parsed stream. Instead, set the CTM with PDEElementSetMatrix. You must still calculate the effective CTM by concatenating matrix, and honouring Q/q.  I am not sure why you would convert a page stream to PDFEdit calls - there are already good APIs to do that.


You should check out Xpdf source code in order to get a better idea of what I am constructing.