mirror of
https://github.com/unidoc/unipdf.git
synced 2025-04-27 13:48:51 +08:00
373 lines
9.7 KiB
Go
373 lines
9.7 KiB
Go
package creator
|
|
|
|
import (
|
|
"github.com/unidoc/unipdf/v3/contentstream/draw"
|
|
"github.com/unidoc/unipdf/v3/model"
|
|
)
|
|
|
|
// border represents cell border.
|
|
type border struct {
|
|
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
|
|
LineStyle draw.LineStyle
|
|
styleLeft CellBorderStyle
|
|
styleRight CellBorderStyle
|
|
styleTop CellBorderStyle
|
|
styleBottom CellBorderStyle
|
|
}
|
|
|
|
// newBorder returns and instance of border.
|
|
func newBorder(x, y, width, height float64) *border {
|
|
border := &border{}
|
|
|
|
border.x = x
|
|
border.y = y
|
|
border.width = width
|
|
border.height = height
|
|
|
|
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)
|
|
|
|
border.borderWidthTop = 0
|
|
border.borderWidthBottom = 0
|
|
border.borderWidthLeft = 0
|
|
border.borderWidthRight = 0
|
|
|
|
border.LineStyle = draw.LineStyleSolid
|
|
return border
|
|
}
|
|
|
|
// GetCoords returns coordinates of border.
|
|
func (border *border) GetCoords() (float64, float64) {
|
|
return border.x, border.y
|
|
}
|
|
|
|
// SetWidthLeft sets border width for left.
|
|
func (border *border) SetWidthLeft(bw float64) {
|
|
border.borderWidthLeft = bw
|
|
}
|
|
|
|
// SetColorLeft sets border color for left.
|
|
func (border *border) SetColorLeft(col Color) {
|
|
border.borderColorLeft = model.NewPdfColorDeviceRGB(col.ToRGB())
|
|
}
|
|
|
|
// SetWidthBottom sets border width for bottom.
|
|
func (border *border) SetWidthBottom(bw float64) {
|
|
border.borderWidthBottom = bw
|
|
}
|
|
|
|
// SetColorBottom sets border color for bottom.
|
|
func (border *border) SetColorBottom(col Color) {
|
|
border.borderColorBottom = model.NewPdfColorDeviceRGB(col.ToRGB())
|
|
}
|
|
|
|
// SetWidthRight sets border width for right.
|
|
func (border *border) SetWidthRight(bw float64) {
|
|
border.borderWidthRight = bw
|
|
}
|
|
|
|
// SetColorRight sets border color for right.
|
|
func (border *border) SetColorRight(col Color) {
|
|
border.borderColorRight = model.NewPdfColorDeviceRGB(col.ToRGB())
|
|
}
|
|
|
|
// SetWidthTop sets border width for top.
|
|
func (border *border) SetWidthTop(bw float64) {
|
|
border.borderWidthTop = bw
|
|
}
|
|
|
|
// SetColorTop sets border color for top.
|
|
func (border *border) SetColorTop(col Color) {
|
|
border.borderColorTop = model.NewPdfColorDeviceRGB(col.ToRGB())
|
|
}
|
|
|
|
// SetFillColor sets background color for border.
|
|
func (border *border) SetFillColor(col Color) {
|
|
border.fillColor = model.NewPdfColorDeviceRGB(col.ToRGB())
|
|
}
|
|
|
|
// SetStyleLeft sets border style for left side.
|
|
func (border *border) SetStyleLeft(style CellBorderStyle) {
|
|
border.styleLeft = style
|
|
}
|
|
|
|
// SetStyleRight sets border style for right side.
|
|
func (border *border) SetStyleRight(style CellBorderStyle) {
|
|
border.styleRight = style
|
|
}
|
|
|
|
// SetStyleTop sets border style for top side.
|
|
func (border *border) SetStyleTop(style CellBorderStyle) {
|
|
border.styleTop = style
|
|
}
|
|
|
|
// SetStyleBottom sets border style for bottom side.
|
|
func (border *border) SetStyleBottom(style CellBorderStyle) {
|
|
border.styleBottom = style
|
|
}
|
|
|
|
// GeneratePageBlocks implements drawable interface.
|
|
func (border *border) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) {
|
|
block := NewBlock(ctx.PageWidth, ctx.PageHeight)
|
|
// Start points is in upper left corner.
|
|
startX := border.x
|
|
startY := ctx.PageHeight - border.y
|
|
|
|
if border.fillColor != nil {
|
|
drawrect := draw.Rectangle{
|
|
Opacity: 1.0,
|
|
X: border.x,
|
|
Y: ctx.PageHeight - border.y - border.height,
|
|
Height: border.height,
|
|
Width: border.width,
|
|
}
|
|
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
|
|
}
|
|
}
|
|
|
|
// a is the spacing between inner and outer line centers (double border only).
|
|
aTop := border.borderWidthTop
|
|
aBottom := border.borderWidthBottom
|
|
aLeft := border.borderWidthLeft
|
|
aRight := border.borderWidthRight
|
|
|
|
// wb represents the effective width of border (including gap and double lines in double border).
|
|
wbTop := border.borderWidthTop
|
|
if border.styleTop == CellBorderStyleDouble {
|
|
wbTop += 2 * aTop
|
|
}
|
|
wbBottom := border.borderWidthBottom
|
|
if border.styleBottom == CellBorderStyleDouble {
|
|
wbBottom += 2 * aBottom
|
|
}
|
|
wbLeft := border.borderWidthLeft
|
|
if border.styleLeft == CellBorderStyleDouble {
|
|
wbLeft += 2 * aLeft
|
|
}
|
|
wbRight := border.borderWidthRight
|
|
if border.styleRight == CellBorderStyleDouble {
|
|
wbRight += 2 * aRight
|
|
}
|
|
|
|
// Left border.
|
|
if border.borderWidthTop != 0 {
|
|
x := startX
|
|
y := startY
|
|
|
|
if border.styleTop == CellBorderStyleDouble {
|
|
y -= aTop
|
|
|
|
// Double - Outer line.
|
|
lineTop := draw.BasicLine{}
|
|
lineTop.X1 = x - wbTop/2
|
|
lineTop.Y1 = y + 2*aTop
|
|
lineTop.X2 = x + border.width + wbTop/2
|
|
lineTop.Y2 = y + 2*aTop
|
|
lineTop.LineColor = border.borderColorTop
|
|
lineTop.LineWidth = border.borderWidthTop
|
|
lineTop.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
|
|
}
|
|
}
|
|
|
|
lineTop := draw.BasicLine{
|
|
LineWidth: border.borderWidthTop,
|
|
Opacity: 1.0,
|
|
LineColor: border.borderColorTop,
|
|
X1: x - wbTop/2 + (wbLeft - border.borderWidthLeft),
|
|
Y1: y,
|
|
X2: x + border.width + wbTop/2 - (wbRight - border.borderWidthRight),
|
|
Y2: y,
|
|
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
|
|
}
|
|
}
|
|
|
|
// Bottom border.
|
|
if border.borderWidthBottom != 0 {
|
|
x := startX
|
|
y := startY - border.height
|
|
|
|
if border.styleBottom == CellBorderStyleDouble {
|
|
y += aBottom
|
|
// Double border - Outer line.
|
|
lineBottom := draw.BasicLine{
|
|
LineWidth: border.borderWidthBottom,
|
|
Opacity: 1.0,
|
|
LineColor: border.borderColorBottom,
|
|
X1: x - wbBottom/2,
|
|
Y1: y - 2*aBottom,
|
|
X2: x + border.width + wbBottom/2,
|
|
Y2: y - 2*aBottom,
|
|
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
|
|
}
|
|
}
|
|
|
|
lineBottom := draw.BasicLine{
|
|
LineWidth: border.borderWidthBottom,
|
|
Opacity: 1.0,
|
|
LineColor: border.borderColorBottom,
|
|
X1: x - wbBottom/2 + (wbLeft - border.borderWidthLeft),
|
|
Y1: y,
|
|
X2: x + border.width + wbBottom/2 - (wbRight - border.borderWidthRight),
|
|
Y2: y,
|
|
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
|
|
}
|
|
}
|
|
|
|
// Left border.
|
|
if border.borderWidthLeft != 0 {
|
|
x := startX
|
|
y := startY
|
|
|
|
if border.styleLeft == CellBorderStyleDouble {
|
|
x += aLeft
|
|
|
|
// Double border - outer line.
|
|
lineLeft := draw.BasicLine{
|
|
LineWidth: border.borderWidthLeft,
|
|
Opacity: 1.0,
|
|
LineColor: border.borderColorLeft,
|
|
X1: x - 2*aLeft,
|
|
Y1: y + wbLeft/2,
|
|
X2: x - 2*aLeft,
|
|
Y2: y - border.height - wbLeft/2,
|
|
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
|
|
}
|
|
}
|
|
|
|
// Line Left.
|
|
lineLeft := draw.BasicLine{
|
|
LineWidth: border.borderWidthLeft,
|
|
Opacity: 1.0,
|
|
LineColor: border.borderColorLeft,
|
|
X1: x,
|
|
Y1: y + wbLeft/2 - (wbTop - border.borderWidthTop),
|
|
X2: x,
|
|
Y2: y - border.height - wbLeft/2 + (wbBottom - border.borderWidthBottom),
|
|
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
|
|
}
|
|
}
|
|
|
|
// Right border.
|
|
if border.borderWidthRight != 0 {
|
|
x := startX + border.width
|
|
y := startY
|
|
|
|
if border.styleRight == CellBorderStyleDouble {
|
|
x -= aRight
|
|
|
|
// Double border - Outer line.
|
|
lineRight := draw.BasicLine{
|
|
LineWidth: border.borderWidthRight,
|
|
Opacity: 1.0,
|
|
LineColor: border.borderColorRight,
|
|
X1: x + 2*aRight,
|
|
Y1: y + wbRight/2,
|
|
X2: x + 2*aRight,
|
|
Y2: y - border.height - wbRight/2,
|
|
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
|
|
}
|
|
}
|
|
|
|
lineRight := draw.BasicLine{
|
|
LineWidth: border.borderWidthRight,
|
|
Opacity: 1.0,
|
|
LineColor: border.borderColorRight,
|
|
X1: x,
|
|
Y1: y + wbRight/2 - (wbTop - border.borderWidthTop),
|
|
X2: x,
|
|
Y2: y - border.height - wbRight/2 + (wbBottom - border.borderWidthBottom),
|
|
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
|
|
}
|
|
}
|
|
|
|
return []*Block{block}, ctx, nil
|
|
}
|