unipdf/pdf/creator/border.go

364 lines
11 KiB
Go
Raw Normal View History

2018-06-09 06:03:40 +06:00
package creator
import (
"github.com/unidoc/unidoc/pdf/contentstream/draw"
"github.com/unidoc/unidoc/pdf/model"
)
2018-07-06 21:11:34 +06:00
const (
doubleBorderAdjustment = 1
)
// border represents cell border
type border struct {
2018-06-12 03:41:33 +06:00
x float64 // Upper left corner
y float64
width float64
height float64
fillColor *model.PdfColorDeviceRGB
borderColorLeft *model.PdfColorDeviceRGB
borderWidthLeft float64
borderColorBottom *model.PdfColorDeviceRGB
borderWidthBottom float64
borderColorRight *model.PdfColorDeviceRGB
borderWidthRight float64
borderColorTop *model.PdfColorDeviceRGB
borderWidthTop float64
2018-06-29 23:55:23 +06:00
LineStyle draw.LineStyle
2018-07-06 21:11:34 +06:00
StyleLeft CellBorderStyle
StyleRight CellBorderStyle
StyleTop CellBorderStyle
StyleBottom CellBorderStyle
2018-06-09 06:03:40 +06:00
}
2018-07-06 22:12:20 +06:00
// newBorder returns and instance of border
func newBorder(x, y, width, height float64) *border {
2018-07-06 21:11:34 +06:00
border := &border{}
2018-06-09 06:03:40 +06:00
border.x = x
border.y = y
border.width = width
border.height = height
2018-06-12 03:41:33 +06:00
border.borderColorTop = model.NewPdfColorDeviceRGB(0, 0, 0)
border.borderColorBottom = model.NewPdfColorDeviceRGB(0, 0, 0)
border.borderColorLeft = model.NewPdfColorDeviceRGB(0, 0, 0)
border.borderColorRight = model.NewPdfColorDeviceRGB(0, 0, 0)
2018-06-29 23:55:23 +06:00
border.borderWidthTop = 1
border.borderWidthBottom = 1
border.borderWidthLeft = 1
border.borderWidthRight = 1
2018-07-06 21:11:34 +06:00
border.LineStyle = draw.LineStyleSolid
2018-06-09 06:03:40 +06:00
return border
}
2018-06-29 23:55:23 +06:00
// GetCoords returns coordinates of border
2018-07-06 21:11:34 +06:00
func (border *border) GetCoords() (float64, float64) {
2018-06-09 06:03:40 +06:00
return border.x, border.y
}
2018-06-29 23:55:23 +06:00
// SetWidthLeft sets border width for left
2018-07-06 21:11:34 +06:00
func (border *border) SetWidthLeft(bw float64) {
2018-06-09 06:03:40 +06:00
border.borderWidthLeft = bw
}
2018-06-29 23:55:23 +06:00
// SetColorLeft sets border color for left
2018-07-06 21:11:34 +06:00
func (border *border) SetColorLeft(col Color) {
2018-06-09 06:03:40 +06:00
border.borderColorLeft = model.NewPdfColorDeviceRGB(col.ToRGB())
}
2018-06-29 23:55:23 +06:00
// SetWidthBottom sets border width for bottom
2018-07-06 21:11:34 +06:00
func (border *border) SetWidthBottom(bw float64) {
2018-06-09 06:03:40 +06:00
border.borderWidthBottom = bw
}
2018-06-29 23:55:23 +06:00
// SetColorBottom sets border color for bottom
2018-07-06 21:11:34 +06:00
func (border *border) SetColorBottom(col Color) {
2018-06-09 06:03:40 +06:00
border.borderColorBottom = model.NewPdfColorDeviceRGB(col.ToRGB())
}
2018-06-29 23:55:23 +06:00
// SetWidthRight sets border width for right
2018-07-06 21:11:34 +06:00
func (border *border) SetWidthRight(bw float64) {
2018-06-09 06:03:40 +06:00
border.borderWidthRight = bw
}
2018-06-29 23:55:23 +06:00
// SetColorRight sets border color for right
2018-07-06 21:11:34 +06:00
func (border *border) SetColorRight(col Color) {
2018-06-09 06:03:40 +06:00
border.borderColorRight = model.NewPdfColorDeviceRGB(col.ToRGB())
}
2018-06-29 23:55:23 +06:00
// SetWidthTop sets border width for top
2018-07-06 21:11:34 +06:00
func (border *border) SetWidthTop(bw float64) {
2018-06-09 06:03:40 +06:00
border.borderWidthTop = bw
}
2018-06-29 23:55:23 +06:00
// SetColorTop sets border color for top
2018-07-06 21:11:34 +06:00
func (border *border) SetColorTop(col Color) {
2018-06-09 06:03:40 +06:00
border.borderColorTop = model.NewPdfColorDeviceRGB(col.ToRGB())
}
2018-06-29 23:55:23 +06:00
// SetFillColor sets background color for border
2018-07-06 21:11:34 +06:00
func (border *border) SetFillColor(col Color) {
2018-06-09 06:03:40 +06:00
border.fillColor = model.NewPdfColorDeviceRGB(col.ToRGB())
}
2018-06-29 23:55:23 +06:00
// GeneratePageBlocks creates drawable
2018-07-06 21:11:34 +06:00
func (border *border) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) {
2018-06-09 06:03:40 +06:00
block := NewBlock(ctx.PageWidth, ctx.PageHeight)
startX := border.x
startY := ctx.PageHeight - border.y
2018-07-06 21:11:34 +06:00
// Width height adjustment for double border
autoTopAdjustmentOnLeft := border.borderWidthLeft * doubleBorderAdjustment
autoTopAdjustmentOnRight := border.borderWidthRight * doubleBorderAdjustment
autoRightAdjustmentOnTop := border.borderWidthTop * doubleBorderAdjustment
autoRightAdjustmentOnBottom := border.borderWidthBottom * doubleBorderAdjustment
autoLeftAdjustmentOnTop := border.borderWidthTop * doubleBorderAdjustment
autoLeftAdjustmentOnBottom := border.borderWidthBottom * doubleBorderAdjustment
autoBottomAdjustmentOnLeft := border.borderWidthLeft * doubleBorderAdjustment
autoBottomAdjustmentOnRight := border.borderWidthRight * doubleBorderAdjustment
2018-06-09 06:03:40 +06:00
if border.fillColor != nil {
drawrect := draw.Rectangle{
Opacity: 1.0,
2018-07-06 21:11:34 +06:00
X: border.x + (border.borderWidthLeft * 3) - 0.5,
Y: (ctx.PageHeight - border.y - border.height) + (border.borderWidthLeft * 2) - 0.5,
Height: border.height - (border.borderWidthBottom * 3),
Width: border.width - (border.borderWidthRight * 3),
2018-06-09 06:03:40 +06:00
}
drawrect.FillEnabled = true
drawrect.FillColor = border.fillColor
drawrect.BorderEnabled = false
contents, _, err := drawrect.Draw("")
if err != nil {
return nil, ctx, err
}
err = block.addContentsByString(string(contents))
if err != nil {
return nil, ctx, err
}
}
2018-06-30 00:06:50 +06:00
if border.borderWidthTop != 0 {
2018-07-06 21:11:34 +06:00
y1 := startY
y2 := startY
if border.StyleTop == CellBorderStyleDoubleTop {
// Line Top
lineTop := draw.Line{
LineWidth: border.borderWidthTop,
Opacity: 1.0,
LineColor: border.borderColorTop,
LineEndingStyle1: draw.LineEndingStyleNone,
LineEndingStyle2: draw.LineEndingStyleNone,
X1: startX + autoTopAdjustmentOnLeft + 1, // +1 for corner adjustment
Y1: y1 - (doubleBorderAdjustment * border.borderWidthTop),
X2: ((startX + border.width) - autoTopAdjustmentOnRight) + 0.5, // +0.5 for corner adjustment
Y2: y2 - (doubleBorderAdjustment * border.borderWidthTop),
LineStyle: border.LineStyle,
}
contentsTop, _, err := lineTop.Draw("")
if err != nil {
return nil, ctx, err
}
err = block.addContentsByString(string(contentsTop))
if err != nil {
return nil, ctx, err
}
y1 = y1 + (doubleBorderAdjustment * border.borderWidthTop)
y2 = y2 + (doubleBorderAdjustment * border.borderWidthTop)
}
2018-06-30 00:06:50 +06:00
// Line Top
lineTop := draw.Line{
LineWidth: border.borderWidthTop,
Opacity: 1.0,
LineColor: border.borderColorTop,
LineEndingStyle1: draw.LineEndingStyleNone,
LineEndingStyle2: draw.LineEndingStyleNone,
2018-07-06 21:11:34 +06:00
X1: startX + 0.5,
Y1: y1,
X2: startX + border.width + autoTopAdjustmentOnRight + 0.5,
Y2: y2,
2018-06-30 00:06:50 +06:00
LineStyle: border.LineStyle,
}
contentsTop, _, err := lineTop.Draw("")
if err != nil {
return nil, ctx, err
}
err = block.addContentsByString(string(contentsTop))
if err != nil {
return nil, ctx, err
}
2018-06-09 06:03:40 +06:00
}
2018-06-30 00:06:50 +06:00
if border.borderWidthLeft != 0 {
2018-07-06 21:11:34 +06:00
x1 := startX + 1
x2 := startX + 1
if border.StyleLeft == CellBorderStyleDoubleLeft {
// Line Left
lineLeft := draw.Line{
LineWidth: border.borderWidthLeft,
Opacity: 1.0,
LineColor: border.borderColorLeft,
LineEndingStyle1: draw.LineEndingStyleNone,
LineEndingStyle2: draw.LineEndingStyleNone,
X1: x1 - (doubleBorderAdjustment * border.borderWidthLeft),
Y1: startY + autoLeftAdjustmentOnTop,
X2: x2 - (doubleBorderAdjustment * border.borderWidthLeft),
Y2: (startY - border.height) - autoLeftAdjustmentOnBottom,
LineStyle: border.LineStyle,
}
contentsLeft, _, err := lineLeft.Draw("")
if err != nil {
return nil, ctx, err
}
err = block.addContentsByString(string(contentsLeft))
if err != nil {
return nil, ctx, err
}
x1 = x1 + (doubleBorderAdjustment * border.borderWidthLeft)
x2 = x2 + (doubleBorderAdjustment * border.borderWidthLeft)
}
2018-06-30 00:06:50 +06:00
// Line Left
lineLeft := draw.Line{
LineWidth: border.borderWidthLeft,
Opacity: 1.0,
LineColor: border.borderColorLeft,
LineEndingStyle1: draw.LineEndingStyleNone,
LineEndingStyle2: draw.LineEndingStyleNone,
2018-07-06 21:11:34 +06:00
X1: x1,
2018-06-30 00:06:50 +06:00
Y1: startY,
2018-07-06 21:11:34 +06:00
X2: x2,
Y2: (startY - border.height) + autoLeftAdjustmentOnBottom,
2018-06-30 00:06:50 +06:00
LineStyle: border.LineStyle,
}
contentsLeft, _, err := lineLeft.Draw("")
if err != nil {
return nil, ctx, err
}
err = block.addContentsByString(string(contentsLeft))
if err != nil {
return nil, ctx, err
}
2018-06-09 06:03:40 +06:00
}
2018-06-30 00:06:50 +06:00
if border.borderWidthRight != 0 {
2018-07-06 21:11:34 +06:00
x1 := startX + border.width
x2 := startX + border.width
if border.StyleRight == CellBorderStyleDoubleRight {
// Line Right
lineRight := draw.Line{
LineWidth: border.borderWidthRight,
Opacity: 1.0,
LineColor: border.borderColorRight,
LineEndingStyle1: draw.LineEndingStyleNone,
LineEndingStyle2: draw.LineEndingStyleNone,
X1: x1 - (doubleBorderAdjustment * border.borderWidthRight),
Y1: startY - autoRightAdjustmentOnTop,
X2: x2 - (doubleBorderAdjustment * border.borderWidthRight),
Y2: (startY - border.height) + autoRightAdjustmentOnBottom,
LineStyle: border.LineStyle,
}
contentsRight, _, err := lineRight.Draw("")
if err != nil {
return nil, ctx, err
}
err = block.addContentsByString(string(contentsRight))
if err != nil {
return nil, ctx, err
}
x1 = x1 + (doubleBorderAdjustment * border.borderWidthRight)
x2 = x2 + (doubleBorderAdjustment * border.borderWidthRight)
}
2018-06-30 00:06:50 +06:00
// Line Right
lineRight := draw.Line{
LineWidth: border.borderWidthRight,
Opacity: 1.0,
LineColor: border.borderColorRight,
LineEndingStyle1: draw.LineEndingStyleNone,
LineEndingStyle2: draw.LineEndingStyleNone,
2018-07-06 21:11:34 +06:00
X1: x1,
Y1: startY + autoRightAdjustmentOnTop,
X2: x2,
Y2: (startY - border.height) - autoRightAdjustmentOnBottom,
2018-06-30 00:06:50 +06:00
LineStyle: border.LineStyle,
}
contentsRight, _, err := lineRight.Draw("")
if err != nil {
return nil, ctx, err
}
err = block.addContentsByString(string(contentsRight))
if err != nil {
return nil, ctx, err
}
2018-06-09 06:03:40 +06:00
}
2018-06-30 00:06:50 +06:00
if border.borderWidthBottom != 0 {
// Line Bottom
2018-07-06 21:11:34 +06:00
y1 := startY - border.height
y2 := startY - border.height
if border.StyleBottom == CellBorderStyleDoubleBottom {
lineBottom := draw.Line{
LineWidth: border.borderWidthBottom,
Opacity: 1.0,
LineColor: border.borderColorBottom,
LineEndingStyle1: draw.LineEndingStyleNone,
LineEndingStyle2: draw.LineEndingStyleNone,
X1: (startX + border.width) - autoBottomAdjustmentOnRight,
Y1: y1 + (doubleBorderAdjustment * border.borderWidthBottom),
X2: startX + autoBottomAdjustmentOnLeft + 1, // +1 for corner adjustment
Y2: y2 + (doubleBorderAdjustment * border.borderWidthBottom),
LineStyle: border.LineStyle,
}
contentsBottom, _, err := lineBottom.Draw("")
if err != nil {
return nil, ctx, err
}
err = block.addContentsByString(string(contentsBottom))
if err != nil {
return nil, ctx, err
}
y1 = y1 - (doubleBorderAdjustment * border.borderWidthBottom)
y2 = y2 - (doubleBorderAdjustment * border.borderWidthBottom)
}
2018-06-30 00:06:50 +06:00
lineBottom := draw.Line{
LineWidth: border.borderWidthBottom,
Opacity: 1.0,
LineColor: border.borderColorBottom,
LineEndingStyle1: draw.LineEndingStyleNone,
LineEndingStyle2: draw.LineEndingStyleNone,
2018-07-06 21:11:34 +06:00
X1: startX + border.width + autoBottomAdjustmentOnRight,
Y1: y1,
X2: startX + autoBottomAdjustmentOnRight,
Y2: y2,
2018-06-30 00:06:50 +06:00
LineStyle: border.LineStyle,
}
contentsBottom, _, err := lineBottom.Draw("")
if err != nil {
return nil, ctx, err
}
err = block.addContentsByString(string(contentsBottom))
if err != nil {
return nil, ctx, err
}
2018-06-09 06:03:40 +06:00
}
2018-06-30 00:06:50 +06:00
2018-06-09 06:03:40 +06:00
return []*Block{block}, ctx, nil
}