PDF Line Patterns

Does anyone know any “gotchas” related to Pen Patterns in a PDF Document

supposedly the PDF code is [dash dot] start d
for example [2 4] 0 d

which “sometimes works” if the line is horizontal or vertical, and only 1 point wide, but if the line is diagonal (at various angles)
the line pattern changes drastically… when all the docs seem to indicate that it SHOULD remain consistent.

And if the thickness changes (increased the dot/dash number accordingly), the line remains solid
and it seems that even if the line thickness is 1, and the pattern is “reversed” (ie. [4 2]), it doesn’t work
it almost as if the 2nd number MUST exceed the first number, but again that is NOT what the documents say

Has anyone played with this?

Hi Dave.
You wont like the answer, but I use dashed lines via DynaPDF, and I don’t see similar issues.
They vary in thickness, and arent horizontal or vertical.

BUT: I do recall that when the line was thicker the ON/OFF values needed to be multiplied by the thickness
eg pattern of 3 on / 2 off needed to change to 9 on/ 6 off when the line was 3 wide.
Otherwise the ‘on’ parts ran together and the line looked solid.

Stupid idea:

use the good old way to generate a pdf (print to pdf on OS X) and print some lines, then do some reverse engineering to get the way it is done ?

Yes, stupid idea; but sometimes…

[quote=233871:@Jeff Tullin]Hi Dave.
You wont like the answer, but I use dashed lines via DynaPDF, and I don’t see similar issues.
They vary in thickness, and arent horizontal or vertical.

BUT: I do recall that when the line was thicker the ON/OFF values needed to be multiplied by the thickness
eg pattern of 3 on / 2 off needed to change to 9 on/ 6 off when the line was 3 wide.
Otherwise the ‘on’ parts ran together and the line looked solid.[/quote]

I understand that the dot/dash numbers need to be related to the line thickness, which is why I indicated that the issues I see occur even at line thickness of “1”

[quote=233887:@Emile Schwarz]Stupid idea:

use the good old way to generate a pdf (print to pdf on OS X) and print some lines, then do some reverse engineering to get the way it is done ?

Yes, stupid idea; but sometimes…[/quote]

Not a stupid idea… but one that does present a few challenges

  • must generate patterned line with something that will actually create the correct PDF code. Meaning the underlying graphic operations need to translate to the PDF version of a patterned line, and not to a boatload of short line segments
  • the resultant PDF needs to be a clear-text version, not one using ZIP to obsfucate the internals

You did indeed say that.
But humor me… instead of “4 2” just try “16 8” without changing anything.
As I say, I’ve done this sucessfully with DynaPDF not your new class/method, but I’m hopeful the underlying stuff should be the same?

I discovered the problem :slight_smile:

I was using the wrong stroke command

453 787 m 503 737 l s

the “s” needs to be “S”, a little “s” is for close/stroke for polygons etc. the capital “S” is just “stroke the path”

The interesting thing is… what you said is true about multiplying dot/dash by line width…
but for it too look nice, the MINIMUM dot dash values are 2x
so a DOTTED line is [2 2] for width 1 or 2, and then [3 3], [4 4] etc

If memory serves, when the thickness increases, the dash part occupies more space than the equivalent gap.
This seems to be because the end point of the ‘line’ is not where the pixels stop.

[-oooooooooo-]

The end point of the drawn part is where the hyphen is.
So the drawn part extends into the gap part.
2 2 will probably look a little more like 3 2 in closeup.

well this is what I came up with… and now seems to work perfectly

        Redim linePattern(-1)
        lineMult=Max(2,PenWidth)
        Select Case PenStyle
        Case DotLine
          linePattern=Array(1,1)
        Case DashLine
          linePattern=Array(2,1)
        Case DashDotLine
          linePattern=Array(2,1,1,1)
        Case DotDotLine
          linePattern=Array(1,1,2,1,1,1)
        Case Else // SolidLine
        End Select
        s="["
        If linePattern.Ubound>=0 Then 
          For i=0 To linePattern.Ubound
            s=s+Str(lineMult*linePattern(i))+" "
          Next i
        End If
        s=Trim(s)+"] 0 d"
        PDF_Stream s

and a lot would depend on the EndCap define for the line… mine are not rounded