diff --git a/pdf/contentstream/draw/shapes.go b/pdf/contentstream/draw/shapes.go index 889c88d5..749b62f4 100644 --- a/pdf/contentstream/draw/shapes.go +++ b/pdf/contentstream/draw/shapes.go @@ -386,7 +386,7 @@ func (line BasicLine) Draw(gsName string) ([]byte, *pdf.PdfRectangle, error) { dx := x2 - x1 theta := math.Atan2(dy, dx) - L := math.Sqrt(math.Pow(dx, 2.0) + math.Pow(dy, 2.0)) + //L := math.Sqrt(math.Pow(dx, 2.0) + math.Pow(dy, 2.0)) w := line.LineWidth pi := math.Pi @@ -408,12 +408,12 @@ func (line BasicLine) Draw(gsName string) ([]byte, *pdf.PdfRectangle, error) { V1Y := VsY + w/2*math.Sin(theta+pi/2) // //// P2. - V2X := VsX + w/2*math.Cos(theta+pi/2) + L*math.Cos(theta) - V2Y := VsY + w/2*math.Sin(theta+pi/2) + L*math.Sin(theta) + //V2X := VsX + w/2*math.Cos(theta+pi/2) + L*math.Cos(theta) + //V2Y := VsY + w/2*math.Sin(theta+pi/2) + L*math.Sin(theta) // //// P3. - V3X := VsX + w/2*math.Cos(theta+pi/2) + L*math.Cos(theta) + w*math.Cos(theta-pi/2) - V3Y := VsY + w/2*math.Sin(theta+pi/2) + L*math.Sin(theta) + w*math.Sin(theta-pi/2) + //V3X := VsX + w/2*math.Cos(theta+pi/2) + L*math.Cos(theta) + w*math.Cos(theta-pi/2) + //V3Y := VsY + w/2*math.Sin(theta+pi/2) + L*math.Sin(theta) + w*math.Sin(theta-pi/2) // P4. V4X := VsX + w/2*math.Cos(theta-pi/2) @@ -421,20 +421,19 @@ func (line BasicLine) Draw(gsName string) ([]byte, *pdf.PdfRectangle, error) { path := NewPath() path = path.AppendPoint(NewPoint(V1X, V1Y)) - path = path.AppendPoint(NewPoint(V2X, V2Y)) - path = path.AppendPoint(NewPoint(V3X, V3Y)) + //path = path.AppendPoint(NewPoint(V2X, V2Y)) + //path = path.AppendPoint(NewPoint(V3X, V3Y)) path = path.AppendPoint(NewPoint(V4X, V4Y)) creator := pdfcontent.NewContentCreator() - - // Draw line with arrow - creator. - Add_q(). - Add_rg(line.LineColor.R(), line.LineColor.G(), line.LineColor.B()) - if len(gsName) > 1 { - // If a graphics state is provided, use it. (Used for transparency settings here). - creator.Add_gs(pdfcore.PdfObjectName(gsName)) - } + //// Draw line with arrow + //creator. + // Add_q(). + // Add_rg(line.LineColor.R(), line.LineColor.G(), line.LineColor.B()) + //if len(gsName) > 1 { + // // If a graphics state is provided, use it. (Used for transparency settings here). + // creator.Add_gs(pdfcore.PdfObjectName(gsName)) + //} path = path.Offset(line.X1, line.Y1) @@ -445,12 +444,13 @@ func (line BasicLine) Draw(gsName string) ([]byte, *pdf.PdfRectangle, error) { if line.LineStyle == LineStyleDashed { creator. Add_d([]int64{1, 1}, 0). + Add_w(w). Add_S(). - Add_f(). Add_Q() } else { creator. - Add_f(). + Add_w(w). + Add_S(). Add_Q() } diff --git a/pdf/creator/basic_line.go b/pdf/creator/basic_line.go new file mode 100644 index 00000000..f6537172 --- /dev/null +++ b/pdf/creator/basic_line.go @@ -0,0 +1,83 @@ +package creator + +import ( + "math" + + "github.com/unidoc/unidoc/pdf/contentstream/draw" + "github.com/unidoc/unidoc/pdf/model" +) + +// BasicLine defines a line between point 1 (X1,Y1) and point 2 (X2,Y2). The line ending styles can be none (regular line), +// or arrows at either end. The line also has a specified width, color and opacity. +// Implements the Drawable interface and can be drawn on PDF using the Creator. +type BasicLine struct { + x1 float64 + y1 float64 + x2 float64 + y2 float64 + lineColor *model.PdfColorDeviceRGB + lineWidth float64 +} + +// NewBasicLine creates a new Line with default parameters between (x1,y1) to (x2,y2). +func NewBasicLine(x1, y1, x2, y2 float64) *Line { + l := &Line{} + + l.x1 = x1 + l.y1 = y1 + l.x2 = x2 + l.y2 = y2 + + l.lineColor = model.NewPdfColorDeviceRGB(0, 0, 0) + l.lineWidth = 1.0 + + return l +} + +// GetCoords returns the (x1, y1), (x2, y2) points defining the Line. +func (l *BasicLine) GetCoords() (float64, float64, float64, float64) { + return l.x1, l.y1, l.x2, l.y2 +} + +// SetLineWidth sets the line width. +func (l *BasicLine) SetLineWidth(lw float64) { + l.lineWidth = lw +} + +// SetColor sets the line color. +// Use ColorRGBFromHex, ColorRGBFrom8bit or ColorRGBFromArithmetic to make the color object. +func (l *BasicLine) SetColor(col Color) { + l.lineColor = model.NewPdfColorDeviceRGB(col.ToRGB()) +} + +// Length calculates and returns the line length. +func (l *BasicLine) Length() float64 { + return math.Sqrt(math.Pow(l.x2-l.x1, 2.0) + math.Pow(l.y2-l.y1, 2.0)) +} + +// GeneratePageBlocks draws the line on a new block representing the page. Implements the Drawable interface. +func (l *BasicLine) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) { + block := NewBlock(ctx.PageWidth, ctx.PageHeight) + + drawline := draw.BasicLine{ + LineWidth: l.lineWidth, + Opacity: 1.0, + LineColor: l.lineColor, + X1: l.x1, + Y1: ctx.PageHeight - l.y1, + X2: l.x2, + Y2: ctx.PageHeight - l.y2, + } + + contents, _, err := drawline.Draw("") + if err != nil { + return nil, ctx, err + } + + err = block.addContentsByString(string(contents)) + if err != nil { + return nil, ctx, err + } + + return []*Block{block}, ctx, nil +} diff --git a/pdf/creator/creator_test.go b/pdf/creator/creator_test.go index 9b271a41..a34ea0a8 100644 --- a/pdf/creator/creator_test.go +++ b/pdf/creator/creator_test.go @@ -1635,6 +1635,22 @@ func TestCreatorTableBorderReq1(t *testing.T) { } } +func TestBasicLine(t *testing.T) { + line := NewBasicLine(100, 100, 200, 100) + line.SetLineWidth(2) + line.SetColor(ColorRed) + + c := New() + c.Draw(line) + + //err := c.WriteToFile("/tmp/table_border_req1_test.pdf") + err := c.WriteToFile("../../testfiles/table.pdf") + if err != nil { + t.Errorf("Fail: %v\n", err) + return + } +} + func TestTableInSubchapter(t *testing.T) { c := New()