@@ -738,24 +738,72 @@ end
738738-- Draw line on current page
739739function PDFGenerator :drawLine (x1 , y1 , x2 , y2 , width , options )
740740 options = options or {}
741- options .color = options .color or " 000000"
741+ options .color = options .color or " 000000"
742+ options .style = options .style or " solid" -- "solid", "dashed", "dotted"
743+ options .cap = options .cap or " butt" -- "butt", "round", "square"
744+ options .opacity = options .opacity or 1.0 -- 0.0 to 1.0
745+
742746 width = width or 1
743747 local rgb = PDFGenerator :hexToRGB (options .color )
744748 local content = self .contents [self .current_page_obj ]
749+
750+ -- Save graphics state
751+ table.insert (content .streams , " q\n " )
752+
753+ -- Set line width and color
754+ table.insert (content .streams , string.format (" %s w\n " , numberToString (width )))
755+ table.insert (content .streams , string.format (" %s %s %s RG\n " ,
756+ numberToString (rgb [1 ]), numberToString (rgb [2 ]), numberToString (rgb [3 ])))
757+
758+ -- Set line style (dash pattern)
759+ if options .style == " dashed" then
760+ table.insert (content .streams , " [6 3] 0 d\n " )
761+ elseif options .style == " dotted" then
762+ table.insert (content .streams , string.format (" [%s %s] 0 d\n " ,
763+ numberToString (width ), numberToString (width * 2 )))
764+ else
765+ table.insert (content .streams , " [] 0 d\n " )
766+ end
767+
768+ -- Set line cap
769+ if options .cap == " round" then
770+ table.insert (content .streams , " 1 J\n " )
771+ elseif options .cap == " square" then
772+ table.insert (content .streams , " 2 J\n " )
773+ else
774+ table.insert (content .streams , " 0 J\n " )
775+ end
776+
777+ -- Set opacity (only if < 1.0)
778+ if options .opacity < 1.0 then
779+ local gsName = " GS" .. tostring (math.floor (options .opacity * 100 ))
780+ if not self .extGStates then self .extGStates = {} end
781+ if not self .extGStates [gsName ] then
782+ -- Create ExtGState object
783+ local objNum = getNewObjNum ()
784+ self .extGStates [gsName ] = objNum
785+ table.insert (self .objects , {
786+ num = objNum ,
787+ data = string.format (" << /Type /ExtGState /CA %s /ca %s >>" ,
788+ numberToString (options .opacity ),
789+ numberToString (options .opacity ))
790+ })
791+ end
792+ table.insert (content .streams , string.format (" /%s gs\n " , gsName ))
793+ end
794+
795+ -- Draw the line
745796 table.insert (content .streams , string.format (
746- " %s w\n %s %s %s RG\n %s %s m\n %s %s l\n S\n " ,
747- numberToString (width ),
748- numberToString (rgb [1 ]),
749- numberToString (rgb [2 ]),
750- numberToString (rgb [3 ]),
751- numberToString (x1 ),
752- numberToString (y1 ),
753- numberToString (x2 ),
754- numberToString (y2 )
755- ))
797+ " %s %s m\n %s %s l\n S\n " ,
798+ numberToString (x1 ), numberToString (y1 ),
799+ numberToString (x2 ), numberToString (y2 )
800+ ))
801+
802+ -- Restore graphics state
803+ table.insert (content .streams , " Q\n " )
804+
756805 return self
757806end
758-
759807-- Draw circle on current page
760808-- borderColor and fillColor should be hex color codes (e.g., "000000" for black)
761809function PDFGenerator :drawCircle (radius , borderWidth , borderStyle , borderColor , fillColor )
0 commit comments