Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
3320a9c19d
|
|||
8dcd8a270a
|
|||
03a9b276d8
|
|||
9c8cde384f
|
|||
99b000ecf4
|
|||
a173e30090
|
|||
a3481a7d2d
|
|||
a8e6f98a89
|
|||
ab805403b9
|
|||
1e98d351ce
|
|||
c40bdc8e9e
|
|||
7204562879
|
|||
741611a2e1
|
|||
133aeb8374
|
@@ -46,7 +46,7 @@ var rexEnumPackage = rext.W(regexp.MustCompile(`^package\s+(?P<name>[A-Za-z0-9_]
|
||||
|
||||
var rexEnumDef = rext.W(regexp.MustCompile(`^\s*type\s+(?P<name>[A-Za-z0-9_]+)\s+(?P<type>[A-Za-z0-9_]+)\s*//\s*(@enum:type).*$`))
|
||||
|
||||
var rexEnumValueDef = rext.W(regexp.MustCompile(`^\s*(?P<name>[A-Za-z0-9_]+)\s+(?P<type>[A-Za-z0-9_]+)\s*=\s*(?P<value>("[A-Za-z0-9_:\s\-.]+"|[0-9]+))\s*(//(?P<comm>.*))?.*$`))
|
||||
var rexEnumValueDef = rext.W(regexp.MustCompile(`^\s*(?P<name>[A-Za-z0-9_]+)\s+(?P<type>[A-Za-z0-9_]+)\s*=\s*(?P<value>("[A-Za-z0-9_:\s\-.]*"|[0-9]+))\s*(//(?P<comm>.*))?.*$`))
|
||||
|
||||
var rexEnumChecksumConst = rext.W(regexp.MustCompile(`const ChecksumEnumGenerator = "(?P<cs>[A-Za-z0-9_]*)"`))
|
||||
|
||||
|
8
go.mod
8
go.mod
@@ -6,11 +6,11 @@ require (
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/glebarez/go-sqlite v1.22.0 // only needed for tests -.-
|
||||
github.com/jmoiron/sqlx v1.4.0
|
||||
github.com/rs/xid v1.5.0
|
||||
github.com/rs/xid v1.6.0
|
||||
github.com/rs/zerolog v1.33.0
|
||||
go.mongodb.org/mongo-driver v1.16.0
|
||||
go.mongodb.org/mongo-driver v1.16.1
|
||||
golang.org/x/crypto v0.26.0
|
||||
golang.org/x/sys v0.23.0
|
||||
golang.org/x/sys v0.24.0
|
||||
golang.org/x/term v0.23.0
|
||||
)
|
||||
|
||||
@@ -45,7 +45,7 @@ require (
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/montanaflynn/stats v0.7.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
|
8
go.sum
8
go.sum
@@ -175,6 +175,8 @@ github.com/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtos
|
||||
github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/phpdave11/gofpdi v1.0.7/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -184,6 +186,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
|
||||
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
|
||||
@@ -234,6 +238,8 @@ go.mongodb.org/mongo-driver v1.15.1 h1:l+RvoUOoMXFmADTLfYDm7On9dRm7p4T80/lEQM+r7
|
||||
go.mongodb.org/mongo-driver v1.15.1/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
||||
go.mongodb.org/mongo-driver v1.16.0 h1:tpRsfBJMROVHKpdGyc1BBEzzjDUWjItxbVSZ8Ls4BQ4=
|
||||
go.mongodb.org/mongo-driver v1.16.0/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw=
|
||||
go.mongodb.org/mongo-driver v1.16.1 h1:rIVLL3q0IHM39dvE+z2ulZLp9ENZKThVfuvN/IiN4l8=
|
||||
go.mongodb.org/mongo-driver v1.16.1/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
|
||||
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
@@ -335,6 +341,8 @@ golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
|
||||
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
|
||||
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
|
||||
|
@@ -1,5 +1,5 @@
|
||||
package goext
|
||||
|
||||
const GoextVersion = "0.0.494"
|
||||
const GoextVersion = "0.0.508"
|
||||
|
||||
const GoextVersionTimestamp = "2024-08-07T13:57:29+0200"
|
||||
const GoextVersionTimestamp = "2024-08-25T17:36:20+0200"
|
||||
|
@@ -1353,7 +1353,7 @@ func typeFields(t reflect.Type, tagkey string) structFields {
|
||||
|
||||
var jsonfilter []string
|
||||
jsonfilterTag := sf.Tag.Get("jsonfilter")
|
||||
if jsonfilterTag != "" && jsonfilterTag != "-" {
|
||||
if jsonfilterTag != "" {
|
||||
jsonfilter = strings.Split(jsonfilterTag, ",")
|
||||
}
|
||||
|
||||
|
@@ -214,7 +214,7 @@ func ObjectFitImage(img image.Image, bbw float64, bbh float64, fit ImageFit, fil
|
||||
draw.Draw(newImg, newImg.Bounds(), &image.Uniform{C: fillColor}, image.Pt(0, 0), draw.Src)
|
||||
draw.Draw(newImg, newImg.Bounds(), img, image.Pt(0, 0), draw.Over)
|
||||
|
||||
return newImg, newImg.Bounds(), nil
|
||||
return newImg, PercentageRectangle{0, 0, 1, 1}, nil
|
||||
}
|
||||
|
||||
if fit == ImageFitContainCenter || fit == ImageFitContainTopLeft || fit == ImageFitContainTopRight || fit == ImageFitContainBottomLeft || fit == ImageFitContainBottomRight {
|
||||
@@ -266,7 +266,7 @@ func ObjectFitImage(img image.Image, bbw float64, bbh float64, fit ImageFit, fil
|
||||
draw.Draw(newImg, newImg.Bounds(), &image.Uniform{C: fillColor}, image.Pt(0, 0), draw.Src)
|
||||
draw.Draw(newImg, destBounds, img, image.Pt(0, 0), draw.Over)
|
||||
|
||||
return newImg, destBounds, nil
|
||||
return newImg, calcRelativeRect(destBounds, newImg.Bounds()), nil
|
||||
}
|
||||
|
||||
if fit == ImageFitStretch {
|
||||
@@ -293,10 +293,10 @@ func ObjectFitImage(img image.Image, bbw float64, bbh float64, fit ImageFit, fil
|
||||
draw.Draw(newImg, newImg.Bounds(), &image.Uniform{C: fillColor}, image.Pt(0, 0), draw.Src)
|
||||
draw.Draw(newImg, newImg.Bounds(), img, image.Pt(0, 0), draw.Over)
|
||||
|
||||
return newImg, newImg.Bounds(), nil
|
||||
return newImg, PercentageRectangle{0, 0, 1, 1}, nil
|
||||
}
|
||||
|
||||
return nil, image.Rectangle{}, exerr.New(exerr.TypeInternal, fmt.Sprintf("unknown image-fit: '%s'", fit)).Build()
|
||||
return nil, PercentageRectangle{}, exerr.New(exerr.TypeInternal, fmt.Sprintf("unknown image-fit: '%s'", fit)).Build()
|
||||
}
|
||||
|
||||
func VerifyAndDecodeImage(data io.Reader, mime string) (image.Image, error) {
|
||||
|
@@ -1,5 +1,7 @@
|
||||
package imageext
|
||||
|
||||
import "image"
|
||||
|
||||
type Rectangle struct {
|
||||
X float64
|
||||
Y float64
|
||||
@@ -22,3 +24,12 @@ func (r PercentageRectangle) Of(ref Rectangle) Rectangle {
|
||||
H: r.H * ref.H,
|
||||
}
|
||||
}
|
||||
|
||||
func calcRelativeRect(inner image.Rectangle, outer image.Rectangle) PercentageRectangle {
|
||||
return PercentageRectangle{
|
||||
X: float64(inner.Min.X-outer.Min.X) / float64(outer.Dx()),
|
||||
Y: float64(inner.Min.Y-outer.Min.Y) / float64(outer.Dy()),
|
||||
W: float64(inner.Dx()) / float64(outer.Dx()),
|
||||
H: float64(inner.Dy()) / float64(outer.Dy()),
|
||||
}
|
||||
}
|
||||
|
@@ -323,6 +323,16 @@ func ArrMap[T1 any, T2 any](arr []T1, conv func(v T1) T2) []T2 {
|
||||
return r
|
||||
}
|
||||
|
||||
func ArrDeRef[T1 any](arr []*T1) []T1 {
|
||||
r := make([]T1, 0, len(arr))
|
||||
for _, v := range arr {
|
||||
if v != nil {
|
||||
r = append(r, *v)
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func MapMap[TK comparable, TV any, TR any](inmap map[TK]TV, conv func(k TK, v TV) TR) []TR {
|
||||
r := make([]TR, 0, len(inmap))
|
||||
for k, v := range inmap {
|
||||
|
15
langext/io.go
Normal file
15
langext/io.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package langext
|
||||
|
||||
import "io"
|
||||
|
||||
type nopCloser struct {
|
||||
io.Writer
|
||||
}
|
||||
|
||||
func (n nopCloser) Close() error {
|
||||
return nil // no op
|
||||
}
|
||||
|
||||
func WriteNopCloser(w io.Writer) io.WriteCloser {
|
||||
return nopCloser{w}
|
||||
}
|
@@ -12,7 +12,11 @@ import (
|
||||
func (c *Coll[TData]) FindOne(ctx context.Context, filter bson.M) (TData, error) {
|
||||
r, err := c.findOneInternal(ctx, filter, false)
|
||||
if err != nil {
|
||||
return *new(TData), exerr.Wrap(err, "mongo-query[find-one] failed").Str("collection", c.Name()).Build()
|
||||
if filterId, ok := filter["_id"]; ok {
|
||||
return *new(TData), exerr.Wrap(err, "mongo-query[find-one] failed").Str("collection", c.Name()).Any("filter", filter).Any("filter_id", filterId).Build()
|
||||
} else {
|
||||
return *new(TData), exerr.Wrap(err, "mongo-query[find-one] failed").Str("collection", c.Name()).Any("filter", filter).Build()
|
||||
}
|
||||
}
|
||||
|
||||
return *r, nil
|
||||
@@ -21,7 +25,7 @@ func (c *Coll[TData]) FindOne(ctx context.Context, filter bson.M) (TData, error)
|
||||
func (c *Coll[TData]) FindOneOpt(ctx context.Context, filter bson.M) (*TData, error) {
|
||||
r, err := c.findOneInternal(ctx, filter, true)
|
||||
if err != nil {
|
||||
return nil, exerr.Wrap(err, "mongo-query[find-one-opt] failed").Str("collection", c.Name()).Build()
|
||||
return nil, exerr.Wrap(err, "mongo-query[find-one-opt] failed").Str("collection", c.Name()).Any("filter", filter).Build()
|
||||
}
|
||||
|
||||
return r, nil
|
||||
@@ -58,7 +62,11 @@ func (c *Coll[TData]) findOneInternal(ctx context.Context, filter bson.M, allowN
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, exerr.Wrap(err, "mongo-query[find-one] failed").Any("filter", filter).Str("collection", c.Name()).NoLog().Build()
|
||||
if filterId, ok := filter["_id"]; ok {
|
||||
return nil, exerr.Wrap(err, "mongo-query[find-one|internal] failed").Str("collection", c.Name()).Any("filter", filter).Any("filter_id", filterId).NoLog().Build()
|
||||
} else {
|
||||
return nil, exerr.Wrap(err, "mongo-query[find-one|internal] failed").Str("collection", c.Name()).Any("filter", filter).NoLog().Build()
|
||||
}
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
|
1
wpdf/.gitignore
vendored
Normal file
1
wpdf/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
wpdf_test.pdf
|
BIN
wpdf/logo.png
Normal file
BIN
wpdf/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
36
wpdf/wpdf.go
36
wpdf/wpdf.go
@@ -14,6 +14,7 @@ type WPDFBuilder struct {
|
||||
fontName PDFFontFamily
|
||||
fontStyle PDFFontStyle
|
||||
fontSize float64
|
||||
debug bool
|
||||
}
|
||||
|
||||
type PDFMargins struct {
|
||||
@@ -62,6 +63,19 @@ func (b *WPDFBuilder) SetMargins(v PDFMargins) {
|
||||
|
||||
func (b *WPDFBuilder) AddPage() {
|
||||
b.b.AddPage()
|
||||
|
||||
if b.debug {
|
||||
|
||||
ml, mt, mr, mb := b.GetMargins()
|
||||
pw, ph := b.GetPageSize()
|
||||
|
||||
b.Rect(pw-ml-mr, ph-mt-mb, RectOutline, NewPDFRectOpt().X(ml).Y(mt).LineWidth(0.25).DrawColor(0, 0, 128))
|
||||
|
||||
b.Rect(pw, mt, RectFill, NewPDFRectOpt().X(0).Y(0).FillColor(0, 0, 255).Alpha(0.2, BlendNormal))
|
||||
b.Rect(ml, ph-mt-mb, RectFill, NewPDFRectOpt().X(0).Y(mt).FillColor(0, 0, 255).Alpha(0.2, BlendNormal))
|
||||
b.Rect(mr, ph-mt-mb, RectFill, NewPDFRectOpt().X(pw-mr).Y(mt).FillColor(0, 0, 255).Alpha(0.2, BlendNormal))
|
||||
b.Rect(pw, mb, RectFill, NewPDFRectOpt().X(0).Y(ph-mb).FillColor(0, 0, 255).Alpha(0.2, BlendNormal))
|
||||
}
|
||||
}
|
||||
|
||||
func (b *WPDFBuilder) SetTextColor(cr, cg, cb int) {
|
||||
@@ -123,7 +137,21 @@ func (b *WPDFBuilder) SetCellSpacing(h float64) {
|
||||
}
|
||||
|
||||
func (b *WPDFBuilder) Ln(h float64) {
|
||||
xBefore, yBefore := b.GetXY()
|
||||
|
||||
b.b.Ln(h)
|
||||
|
||||
yAfter := b.GetY()
|
||||
|
||||
if b.debug {
|
||||
|
||||
_, _, mr, _ := b.GetMargins()
|
||||
pw, _ := b.GetPageSize()
|
||||
|
||||
b.Rect(pw-mr-xBefore, yAfter-yBefore, RectOutline, NewPDFRectOpt().X(xBefore).Y(yBefore).LineWidth(0.25).DrawColor(128, 128, 0).Alpha(0.5, BlendNormal))
|
||||
b.Rect(pw-mr-xBefore, yAfter-yBefore, RectFill, NewPDFRectOpt().X(xBefore).Y(yBefore).LineWidth(0.25).FillColor(128, 128, 0).Alpha(0.1, BlendNormal))
|
||||
b.Line(xBefore, yBefore, pw-mr, yAfter, NewPDFLineOpt().LineWidth(0.25).DrawColor(128, 128, 0))
|
||||
}
|
||||
}
|
||||
|
||||
func (b *WPDFBuilder) Build() ([]byte, error) {
|
||||
@@ -217,6 +245,10 @@ func (b *WPDFBuilder) PageNo() int {
|
||||
return b.b.PageNo()
|
||||
}
|
||||
|
||||
func (b *WPDFBuilder) Bookmark(txtStr string, level int, y float64) {
|
||||
b.b.Bookmark(b.tr(txtStr), level, y)
|
||||
}
|
||||
|
||||
func (b *WPDFBuilder) GetStringWidth(str string, opts ...PDFCellOpt) float64 {
|
||||
|
||||
var fontNameOverride *PDFFontFamily
|
||||
@@ -242,3 +274,7 @@ func (b *WPDFBuilder) GetStringWidth(str string, opts ...PDFCellOpt) float64 {
|
||||
|
||||
return b.b.GetStringWidth(str)
|
||||
}
|
||||
|
||||
func (b *WPDFBuilder) Debug(v bool) {
|
||||
b.debug = v
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ type PDFCellOpt struct {
|
||||
borderColor *PDFColor
|
||||
fillColor *PDFColor
|
||||
autoWidthPaddingX *float64
|
||||
debug *bool
|
||||
}
|
||||
|
||||
func NewPDFCellOpt() *PDFCellOpt {
|
||||
@@ -158,6 +159,11 @@ func (opt *PDFCellOpt) Alpha(alpha float64, blendMode PDFBlendMode) *PDFCellOpt
|
||||
return opt
|
||||
}
|
||||
|
||||
func (opt *PDFCellOpt) Debug(v bool) *PDFCellOpt {
|
||||
opt.debug = &v
|
||||
return opt
|
||||
}
|
||||
|
||||
func (opt *PDFCellOpt) Copy() *PDFCellOpt {
|
||||
c := *opt
|
||||
return &c
|
||||
@@ -186,7 +192,7 @@ func (b *WPDFBuilder) Cell(txt string, opts ...*PDFCellOpt) {
|
||||
txtTR := b.tr(txt)
|
||||
|
||||
width := float64(0)
|
||||
height := b.cellHeight + b.cellSpacing
|
||||
var height *float64 = nil
|
||||
border := BorderNone
|
||||
ln := BreakToNextLine
|
||||
align := AlignLeft
|
||||
@@ -204,10 +210,11 @@ func (b *WPDFBuilder) Cell(txt string, opts ...*PDFCellOpt) {
|
||||
var borderColor *PDFColor
|
||||
var fillColor *PDFColor
|
||||
autoWidthPaddingX := float64(0)
|
||||
debug := b.debug
|
||||
|
||||
for _, opt := range opts {
|
||||
width = langext.Coalesce(opt.width, width)
|
||||
height = langext.Coalesce(opt.height, height)
|
||||
height = langext.CoalesceOpt(opt.height, height)
|
||||
border = langext.Coalesce(opt.border, border)
|
||||
ln = langext.Coalesce(opt.ln, ln)
|
||||
align = langext.Coalesce(opt.align, align)
|
||||
@@ -225,6 +232,7 @@ func (b *WPDFBuilder) Cell(txt string, opts ...*PDFCellOpt) {
|
||||
borderColor = langext.CoalesceOpt(opt.borderColor, borderColor)
|
||||
fillColor = langext.CoalesceOpt(opt.fillColor, fillColor)
|
||||
autoWidthPaddingX = langext.Coalesce(opt.autoWidthPaddingX, autoWidthPaddingX)
|
||||
debug = langext.Coalesce(opt.debug, debug)
|
||||
}
|
||||
|
||||
if fontNameOverride != nil || fontStyleOverride != nil || fontSizeOverride != nil {
|
||||
@@ -238,6 +246,11 @@ func (b *WPDFBuilder) Cell(txt string, opts ...*PDFCellOpt) {
|
||||
defer func() { b.SetFont(oldFontName, oldFontStyle, oldFontSize) }()
|
||||
}
|
||||
|
||||
if height == nil {
|
||||
// (do after SetFont, so that b.cellHeight is correctly set to fontOverride)
|
||||
height = langext.Ptr(b.cellHeight + b.cellSpacing)
|
||||
}
|
||||
|
||||
if textColor != nil {
|
||||
oldColorR, oldColorG, oldColorB := b.b.GetTextColor()
|
||||
b.SetTextColor(textColor.R, textColor.G, textColor.B)
|
||||
@@ -267,10 +280,22 @@ func (b *WPDFBuilder) Cell(txt string, opts ...*PDFCellOpt) {
|
||||
}
|
||||
|
||||
if autoWidth {
|
||||
width = b.b.GetStringWidth(txtTR) + autoWidthPaddingX
|
||||
width = b.GetStringWidth(txtTR, langext.ArrDeRef(opts)...) + autoWidthPaddingX
|
||||
}
|
||||
|
||||
b.b.CellFormat(width, height, txtTR, string(border), int(ln), string(align), fill, link, linkStr)
|
||||
xBefore, yBefore := b.b.GetXY()
|
||||
|
||||
b.b.CellFormat(width, *height, txtTR, string(border), int(ln), string(align), fill, link, linkStr)
|
||||
|
||||
if debug {
|
||||
if ln == BreakToNextLine {
|
||||
b.Rect(b.GetPageWidth()-xBefore-b.GetMarginRight(), *height, RectOutline, NewPDFRectOpt().X(xBefore).Y(yBefore).LineWidth(0.25).DrawColor(0, 128, 0))
|
||||
} else if ln == BreakToRight {
|
||||
b.Rect(b.GetX()-xBefore, *height, RectOutline, NewPDFRectOpt().X(xBefore).Y(yBefore).LineWidth(0.25).DrawColor(0, 128, 0))
|
||||
} else if ln == BreakToBelow {
|
||||
b.Rect(b.GetPageWidth()-xBefore-b.GetMarginRight(), *height, RectOutline, NewPDFRectOpt().X(xBefore).Y(yBefore).LineWidth(0.25).DrawColor(0, 128, 0))
|
||||
}
|
||||
}
|
||||
|
||||
if extraLn != 0 {
|
||||
b.b.Ln(extraLn)
|
||||
|
@@ -247,7 +247,7 @@ func (b *WPDFBuilder) Image(img *PDFImageRef, opts ...*PDFImageOpt) {
|
||||
var imageFit *imageext.ImageFit = nil
|
||||
var fillColor color.Color = color.Transparent
|
||||
compression := imageext.CompressionPNGSpeed
|
||||
debug := false
|
||||
debug := b.debug
|
||||
var crop *imageext.ImageCrop = nil
|
||||
var alphaOverride *dataext.Tuple[float64, PDFBlendMode]
|
||||
|
||||
@@ -271,6 +271,10 @@ func (b *WPDFBuilder) Image(img *PDFImageRef, opts ...*PDFImageOpt) {
|
||||
alphaOverride = langext.CoalesceOpt(opt.alphaOverride, alphaOverride)
|
||||
}
|
||||
|
||||
if flow {
|
||||
y = b.GetY()
|
||||
}
|
||||
|
||||
regName := img.Name
|
||||
|
||||
var subImageBounds *imageext.PercentageRectangle = nil
|
||||
@@ -355,13 +359,14 @@ func (b *WPDFBuilder) Image(img *PDFImageRef, opts ...*PDFImageOpt) {
|
||||
b.b.ImageOptions(regName, x, y, w, h, flow, fpdfOpt, link, linkStr)
|
||||
|
||||
if debug {
|
||||
b.Rect(w, h, RectOutline, NewPDFRectOpt().X(x).Y(y).LineWidth(2).DrawColor(255, 0, 0))
|
||||
b.Rect(w, h, RectOutline, NewPDFRectOpt().X(x).Y(y).LineWidth(0.25).DrawColor(255, 0, 0))
|
||||
|
||||
if subImageBounds != nil {
|
||||
r := subImageBounds.Of(imageext.Rectangle{X: x, Y: y, W: w, H: h})
|
||||
b.Rect(r.W, r.H, RectOutline, NewPDFRectOpt().X(r.X).Y(r.Y).LineWidth(0.25).DrawColor(255, 0, 0))
|
||||
b.Rect(r.W, r.H, RectFill, NewPDFRectOpt().X(r.X).Y(r.Y).FillColor(255, 0, 0).Alpha(0.2, BlendNormal))
|
||||
b.Line(r.X, r.Y, r.X+r.W, r.Y+r.H, NewPDFLineOpt().LineWidth(2).DrawColor(255, 0, 0))
|
||||
b.Line(r.X+r.W, r.Y, r.X, r.Y+r.H, NewPDFLineOpt().LineWidth(2).DrawColor(255, 0, 0))
|
||||
b.Line(r.X, r.Y, r.X+r.W, r.Y+r.H, NewPDFLineOpt().LineWidth(0.25).DrawColor(255, 0, 0))
|
||||
b.Line(r.X+r.W, r.Y, r.X, r.Y+r.H, NewPDFLineOpt().LineWidth(0.25).DrawColor(255, 0, 0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ type PDFLineOpt struct {
|
||||
drawColor *PDFColor
|
||||
alpha *dataext.Tuple[float64, PDFBlendMode]
|
||||
capStyle *PDFLineCapStyle
|
||||
debug *bool
|
||||
}
|
||||
|
||||
func NewPDFLineOpt() *PDFLineOpt {
|
||||
@@ -51,17 +52,24 @@ func (opt *PDFLineOpt) CapRound() *PDFLineOpt {
|
||||
return opt
|
||||
}
|
||||
|
||||
func (opt *PDFLineOpt) Debug(v bool) *PDFLineOpt {
|
||||
opt.debug = &v
|
||||
return opt
|
||||
}
|
||||
|
||||
func (b *WPDFBuilder) Line(x1 float64, y1 float64, x2 float64, y2 float64, opts ...*PDFLineOpt) {
|
||||
var lineWidth *float64
|
||||
var drawColor *PDFColor
|
||||
var alphaOverride *dataext.Tuple[float64, PDFBlendMode]
|
||||
capStyle := CapButt
|
||||
debug := b.debug
|
||||
|
||||
for _, opt := range opts {
|
||||
lineWidth = langext.CoalesceOpt(opt.lineWidth, lineWidth)
|
||||
drawColor = langext.CoalesceOpt(opt.drawColor, drawColor)
|
||||
alphaOverride = langext.CoalesceOpt(opt.alpha, alphaOverride)
|
||||
capStyle = langext.Coalesce(opt.capStyle, capStyle)
|
||||
debug = langext.Coalesce(opt.debug, debug)
|
||||
}
|
||||
|
||||
if lineWidth != nil {
|
||||
|
@@ -20,6 +20,7 @@ type PDFMultiCellOpt struct {
|
||||
textColor *PDFColor
|
||||
borderColor *PDFColor
|
||||
fillColor *PDFColor
|
||||
debug *bool
|
||||
}
|
||||
|
||||
func NewPDFMultiCellOpt() *PDFMultiCellOpt {
|
||||
@@ -128,6 +129,16 @@ func (opt *PDFMultiCellOpt) Alpha(alpha float64, blendMode PDFBlendMode) *PDFMul
|
||||
return opt
|
||||
}
|
||||
|
||||
func (opt *PDFMultiCellOpt) Debug(v bool) *PDFMultiCellOpt {
|
||||
opt.debug = &v
|
||||
return opt
|
||||
}
|
||||
|
||||
func (opt *PDFMultiCellOpt) Copy() *PDFMultiCellOpt {
|
||||
c := *opt
|
||||
return &c
|
||||
}
|
||||
|
||||
func (b *WPDFBuilder) MultiCell(txt string, opts ...*PDFMultiCellOpt) {
|
||||
|
||||
txtTR := b.tr(txt)
|
||||
@@ -146,6 +157,7 @@ func (b *WPDFBuilder) MultiCell(txt string, opts ...*PDFMultiCellOpt) {
|
||||
var textColor *PDFColor
|
||||
var borderColor *PDFColor
|
||||
var fillColor *PDFColor
|
||||
debug := b.debug
|
||||
|
||||
for _, opt := range opts {
|
||||
width = langext.Coalesce(opt.width, width)
|
||||
@@ -162,6 +174,7 @@ func (b *WPDFBuilder) MultiCell(txt string, opts ...*PDFMultiCellOpt) {
|
||||
textColor = langext.CoalesceOpt(opt.textColor, textColor)
|
||||
borderColor = langext.CoalesceOpt(opt.borderColor, borderColor)
|
||||
fillColor = langext.CoalesceOpt(opt.fillColor, fillColor)
|
||||
debug = langext.Coalesce(opt.debug, debug)
|
||||
}
|
||||
|
||||
if fontNameOverride != nil || fontStyleOverride != nil || fontSizeOverride != nil {
|
||||
@@ -203,8 +216,14 @@ func (b *WPDFBuilder) MultiCell(txt string, opts ...*PDFMultiCellOpt) {
|
||||
b.b.SetX(*x)
|
||||
}
|
||||
|
||||
xBefore, yBefore := b.b.GetXY()
|
||||
|
||||
b.b.MultiCell(width, height, txtTR, string(border), string(align), fill)
|
||||
|
||||
if debug {
|
||||
b.Rect(b.GetPageWidth()-xBefore-b.GetMarginRight(), b.GetY()-yBefore, RectOutline, NewPDFRectOpt().X(xBefore).Y(yBefore).LineWidth(0.25).DrawColor(0, 128, 0))
|
||||
}
|
||||
|
||||
if extraLn != 0 {
|
||||
b.b.Ln(extraLn)
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@ type PDFRectOpt struct {
|
||||
radiusTR *float64
|
||||
radiusBR *float64
|
||||
radiusBL *float64
|
||||
debug *bool
|
||||
}
|
||||
|
||||
func NewPDFRectOpt() *PDFRectOpt {
|
||||
@@ -90,6 +91,11 @@ func (opt *PDFRectOpt) Alpha(alpha float64, blendMode PDFBlendMode) *PDFRectOpt
|
||||
return opt
|
||||
}
|
||||
|
||||
func (opt *PDFRectOpt) Debug(v bool) *PDFRectOpt {
|
||||
opt.debug = &v
|
||||
return opt
|
||||
}
|
||||
|
||||
func (b *WPDFBuilder) Rect(w float64, h float64, styleStr PDFRectStyle, opts ...*PDFRectOpt) {
|
||||
x := b.GetX()
|
||||
y := b.GetY()
|
||||
@@ -101,6 +107,7 @@ func (b *WPDFBuilder) Rect(w float64, h float64, styleStr PDFRectStyle, opts ...
|
||||
radiusTR := float64(0)
|
||||
radiusBR := float64(0)
|
||||
radiusBL := float64(0)
|
||||
debug := b.debug
|
||||
|
||||
for _, opt := range opts {
|
||||
x = langext.Coalesce(opt.x, x)
|
||||
@@ -113,6 +120,7 @@ func (b *WPDFBuilder) Rect(w float64, h float64, styleStr PDFRectStyle, opts ...
|
||||
radiusTR = langext.Coalesce(opt.radiusTR, radiusTR)
|
||||
radiusBR = langext.Coalesce(opt.radiusBR, radiusBR)
|
||||
radiusBL = langext.Coalesce(opt.radiusBL, radiusBL)
|
||||
debug = langext.Coalesce(opt.debug, debug)
|
||||
}
|
||||
|
||||
if lineWidth != nil {
|
||||
|
@@ -35,24 +35,7 @@ type TableBuilder struct {
|
||||
rows []tableRow
|
||||
defaultCellStyle *TableCellStyleOpt
|
||||
columnWidths *[]string
|
||||
}
|
||||
|
||||
type TableCell struct {
|
||||
Content string
|
||||
Style TableCellStyleOpt
|
||||
}
|
||||
|
||||
type TableCellStyleOpt struct {
|
||||
MultiCell *bool
|
||||
Ellipsize *bool
|
||||
PaddingHorz *float64
|
||||
MinWidth *float64
|
||||
|
||||
PDFCellOpt
|
||||
}
|
||||
|
||||
type tableRow struct {
|
||||
cells []TableCell
|
||||
debug *bool
|
||||
}
|
||||
|
||||
func (r tableRow) maxFontSize(defaultFontSize float64) float64 {
|
||||
@@ -70,8 +53,8 @@ func (b *TableBuilder) Widths(v ...string) *TableBuilder {
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *TableBuilder) DefaultStyle(s TableCellStyleOpt) *TableBuilder {
|
||||
b.defaultCellStyle = &s
|
||||
func (b *TableBuilder) DefaultStyle(s *TableCellStyleOpt) *TableBuilder {
|
||||
b.defaultCellStyle = s
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -85,31 +68,42 @@ func (b *TableBuilder) PadY(v float64) *TableBuilder {
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *TableBuilder) AddRow(cells ...TableCell) {
|
||||
func (b *TableBuilder) AddRow(cells ...TableCell) *TableBuilder {
|
||||
b.rows = append(b.rows, tableRow{cells: cells})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *TableBuilder) AddRowWithStyle(style TableCellStyleOpt, cells ...string) {
|
||||
func (b *TableBuilder) AddRowWithStyle(style *TableCellStyleOpt, cells ...string) *TableBuilder {
|
||||
tcels := make([]TableCell, 0, len(cells))
|
||||
for _, cell := range cells {
|
||||
tcels = append(tcels, TableCell{Content: cell, Style: style})
|
||||
tcels = append(tcels, TableCell{Content: cell, Style: *style})
|
||||
}
|
||||
|
||||
b.rows = append(b.rows, tableRow{cells: tcels})
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *TableBuilder) AddRowDefaultStyle(cells ...string) {
|
||||
func (b *TableBuilder) AddRowDefaultStyle(cells ...string) *TableBuilder {
|
||||
tcels := make([]TableCell, 0, len(cells))
|
||||
for _, cell := range cells {
|
||||
tcels = append(tcels, TableCell{Content: cell, Style: langext.Coalesce(b.defaultCellStyle, TableCellStyleOpt{})})
|
||||
}
|
||||
|
||||
b.rows = append(b.rows, tableRow{cells: tcels})
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *TableBuilder) BuildRow() *TableRowBuilder {
|
||||
return &TableRowBuilder{tabbuilder: b, cells: make([]TableCell, 0)}
|
||||
}
|
||||
|
||||
func (b *TableBuilder) Build() {
|
||||
builder := b.builder
|
||||
|
||||
debug := langext.Coalesce(b.debug, b.builder.debug)
|
||||
|
||||
if len(b.rows) == 0 {
|
||||
return // nothing to do
|
||||
}
|
||||
@@ -140,17 +134,21 @@ func (b *TableBuilder) Build() {
|
||||
str := cell.Content
|
||||
style := cell.Style
|
||||
|
||||
ellipsize := langext.Coalesce(style.Ellipsize, true)
|
||||
cellPaddingHorz := langext.Coalesce(style.PaddingHorz, 2)
|
||||
ellipsize := langext.Coalesce(style.ellipsize, true)
|
||||
cellPaddingHorz := langext.Coalesce(style.paddingHorz, 2)
|
||||
|
||||
fillHeight := langext.Coalesce(style.fillHeight, false)
|
||||
|
||||
bx := builder.GetX()
|
||||
by := builder.GetY()
|
||||
|
||||
cellWidth := columnWidths[cellIdx]
|
||||
|
||||
if langext.Coalesce(style.MultiCell, true) {
|
||||
_ = fillHeight // TODO implement, but how?? ( cells with fillHeight=true should have a border of the full column height, even if another column is growing it, but we do not know teh height beforehand ... )
|
||||
|
||||
builder.MultiCell(str, style.PDFCellOpt.Copy().ToMulti().Width(cellWidth))
|
||||
if langext.Coalesce(style.multiCell, true) {
|
||||
|
||||
builder.MultiCell(str, style.PDFCellOpt.Copy().ToMulti().Width(cellWidth).Debug(debug))
|
||||
|
||||
} else {
|
||||
|
||||
@@ -163,7 +161,7 @@ func (b *TableBuilder) Build() {
|
||||
}
|
||||
}
|
||||
|
||||
builder.Cell(str, style.PDFCellOpt.Copy().Width(cellWidth))
|
||||
builder.Cell(str, style.PDFCellOpt.Copy().Width(cellWidth).Debug(debug))
|
||||
|
||||
}
|
||||
|
||||
@@ -222,8 +220,8 @@ func (b *TableBuilder) calculateColumns() []float64 {
|
||||
for _, row := range b.rows {
|
||||
if len(row.cells) > colIdx {
|
||||
|
||||
ph := langext.Coalesce(row.cells[colIdx].Style.PaddingHorz, 2)
|
||||
mw := langext.Coalesce(row.cells[colIdx].Style.MinWidth, 0)
|
||||
ph := langext.Coalesce(row.cells[colIdx].Style.paddingHorz, 2)
|
||||
mw := langext.Coalesce(row.cells[colIdx].Style.minWidth, 0)
|
||||
|
||||
minWidth = max(minWidth, ph+mw)
|
||||
|
||||
@@ -281,23 +279,28 @@ func (b *TableBuilder) calculateColumns() []float64 {
|
||||
return columnWidths
|
||||
}
|
||||
|
||||
for i, _ := range columnDef {
|
||||
if frColumnWeights[i] != 0 {
|
||||
w := min(autoWidths[i], (remainingWidth/float64(frColumnWidthCount))*frColumnWeights[i])
|
||||
remainingWidth += columnWidths[i]
|
||||
columnWidths[i] = w
|
||||
remainingWidth -= w
|
||||
{
|
||||
rmSub := 0.0
|
||||
for i := range columnDef {
|
||||
if frColumnWeights[i] != 0 {
|
||||
w := min(autoWidths[i], (remainingWidth/float64(frColumnWidthCount))*frColumnWeights[i])
|
||||
rmSub += w - columnWidths[i]
|
||||
columnWidths[i] = w
|
||||
}
|
||||
}
|
||||
remainingWidth -= rmSub
|
||||
}
|
||||
|
||||
if remainingWidth > 0 {
|
||||
if remainingWidth > 0.01 {
|
||||
rmSub := 0.0
|
||||
for i, _ := range columnDef {
|
||||
if frColumnWeights[i] != 0 {
|
||||
addW := (remainingWidth / float64(frColumnWidthCount)) * frColumnWeights[i]
|
||||
rmSub += addW
|
||||
columnWidths[i] += addW
|
||||
remainingWidth -= addW
|
||||
}
|
||||
}
|
||||
remainingWidth -= rmSub
|
||||
}
|
||||
|
||||
return columnWidths
|
||||
@@ -307,6 +310,11 @@ func (b *TableBuilder) RowCount() int {
|
||||
return len(b.rows)
|
||||
}
|
||||
|
||||
func (b *TableBuilder) Debug(v bool) *TableBuilder {
|
||||
b.debug = &v
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *WPDFBuilder) Table() *TableBuilder {
|
||||
return &TableBuilder{
|
||||
builder: b,
|
||||
@@ -321,12 +329,13 @@ func defaultTableStyle() *TableCellStyleOpt {
|
||||
return &TableCellStyleOpt{
|
||||
PDFCellOpt: *NewPDFCellOpt().
|
||||
FontSize(float64(8)).
|
||||
BorderColorHex(uint32(0x888888)).
|
||||
FillColorHex(uint32(0xFFFFFF)).
|
||||
Border(BorderFull).
|
||||
BorderColorHex(uint32(0x666666)).
|
||||
FillColorHex(uint32(0xF0F0F0)).
|
||||
TextColorHex(uint32(0x000000)).
|
||||
FillBackground(false),
|
||||
MinWidth: langext.Ptr(float64(5)),
|
||||
Ellipsize: langext.PTrue,
|
||||
MultiCell: langext.PFalse,
|
||||
FillBackground(true),
|
||||
minWidth: langext.Ptr(float64(5)),
|
||||
ellipsize: langext.PTrue,
|
||||
multiCell: langext.PFalse,
|
||||
}
|
||||
}
|
||||
|
187
wpdf/wpdfTableCell.go
Normal file
187
wpdf/wpdfTableCell.go
Normal file
@@ -0,0 +1,187 @@
|
||||
package wpdf
|
||||
|
||||
import (
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/dataext"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
)
|
||||
|
||||
type TableCell struct {
|
||||
Content string
|
||||
Style TableCellStyleOpt
|
||||
}
|
||||
|
||||
type TableCellStyleOpt struct {
|
||||
multiCell *bool
|
||||
ellipsize *bool
|
||||
paddingHorz *float64
|
||||
minWidth *float64
|
||||
fillHeight *bool
|
||||
|
||||
PDFCellOpt
|
||||
}
|
||||
|
||||
func NewTableCellStyleOpt() *TableCellStyleOpt {
|
||||
return &TableCellStyleOpt{}
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) FillHeight(b bool) *TableCellStyleOpt {
|
||||
o.fillHeight = &b
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) MultiCell(v bool) *TableCellStyleOpt {
|
||||
o.multiCell = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) Ellipsize(v bool) *TableCellStyleOpt {
|
||||
o.ellipsize = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) PaddingHorz(v float64) *TableCellStyleOpt {
|
||||
o.paddingHorz = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) MinWidth(v float64) *TableCellStyleOpt {
|
||||
o.minWidth = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) CellStyle(v PDFCellOpt) *TableCellStyleOpt {
|
||||
o.PDFCellOpt = v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) Width(v float64) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.width = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) Height(v float64) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.height = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) Border(v PDFBorder) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.border = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) LnPos(v PDFTextBreak) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.ln = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) Align(v PDFTextAlign) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.align = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) FillBackground(v bool) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.fill = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) Link(v int) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.link = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) LinkStr(v string) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.linkStr = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) Font(fontName PDFFontFamily, fontStyle PDFFontStyle, fontSize float64) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.fontNameOverride = &fontName
|
||||
o.PDFCellOpt.fontStyleOverride = &fontStyle
|
||||
o.PDFCellOpt.fontSizeOverride = &fontSize
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) FontName(v PDFFontFamily) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.fontNameOverride = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) FontStyle(v PDFFontStyle) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.fontStyleOverride = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) FontSize(v float64) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.fontSizeOverride = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) Bold() *TableCellStyleOpt {
|
||||
o.PDFCellOpt.fontStyleOverride = langext.Ptr(Bold)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) Italic() *TableCellStyleOpt {
|
||||
o.PDFCellOpt.fontStyleOverride = langext.Ptr(Italic)
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) LnAfter(v float64) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.extraLn = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) X(v float64) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.x = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) AutoWidth() *TableCellStyleOpt {
|
||||
o.PDFCellOpt.autoWidth = langext.PTrue
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) AutoWidthPaddingX(v float64) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.autoWidthPaddingX = &v
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) TextColor(cr, cg, cb int) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.textColor = langext.Ptr(rgbToColor(cr, cg, cb))
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) TextColorHex(c uint32) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.textColor = langext.Ptr(hexToColor(c))
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) BorderColor(cr, cg, cb int) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.borderColor = langext.Ptr(rgbToColor(cr, cg, cb))
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) BorderColorHex(c uint32) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.borderColor = langext.Ptr(hexToColor(c))
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) FillColor(cr, cg, cb int) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.fillColor = langext.Ptr(rgbToColor(cr, cg, cb))
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) FillColorHex(c uint32) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.fillColor = langext.Ptr(hexToColor(c))
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) Alpha(alpha float64, blendMode PDFBlendMode) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.alphaOverride = &dataext.Tuple[float64, PDFBlendMode]{V1: alpha, V2: blendMode}
|
||||
return o
|
||||
}
|
||||
|
||||
func (o *TableCellStyleOpt) Debug(v bool) *TableCellStyleOpt {
|
||||
o.PDFCellOpt.debug = &v
|
||||
return o
|
||||
}
|
52
wpdf/wpdfTableRow.go
Normal file
52
wpdf/wpdfTableRow.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package wpdf
|
||||
|
||||
import "gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
|
||||
type tableRow struct {
|
||||
cells []TableCell
|
||||
}
|
||||
|
||||
type TableRowBuilder struct {
|
||||
tabbuilder *TableBuilder
|
||||
defaultStyle *TableCellStyleOpt
|
||||
cells []TableCell
|
||||
}
|
||||
|
||||
func (r *TableRowBuilder) RowStyle(style *TableCellStyleOpt) *TableRowBuilder {
|
||||
r.defaultStyle = style
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *TableRowBuilder) Cell(cell string) *TableRowBuilder {
|
||||
r.cells = append(r.cells, TableCell{Content: cell, Style: langext.Coalesce3(r.defaultStyle, r.tabbuilder.defaultCellStyle, TableCellStyleOpt{})})
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *TableRowBuilder) Cells(cells ...string) *TableRowBuilder {
|
||||
for _, cell := range cells {
|
||||
r.cells = append(r.cells, TableCell{Content: cell, Style: langext.Coalesce3(r.defaultStyle, r.tabbuilder.defaultCellStyle, TableCellStyleOpt{})})
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *TableRowBuilder) CellObject(cell TableCell) *TableRowBuilder {
|
||||
r.cells = append(r.cells, cell)
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *TableRowBuilder) CellObjects(cells ...TableCell) *TableRowBuilder {
|
||||
for _, cell := range cells {
|
||||
r.cells = append(r.cells, cell)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *TableRowBuilder) CellWithStyle(cell string, style *TableCellStyleOpt) *TableRowBuilder {
|
||||
r.cells = append(r.cells, TableCell{Content: cell, Style: *style})
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *TableRowBuilder) BuildRow() *TableBuilder {
|
||||
r.tabbuilder.AddRow(r.cells...)
|
||||
return r.tabbuilder
|
||||
}
|
105
wpdf/wpdf_test.go
Normal file
105
wpdf/wpdf_test.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package wpdf
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/imageext"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
)
|
||||
|
||||
//go:embed logo.png
|
||||
var logoData []byte
|
||||
|
||||
func TestPDFBuilder(t *testing.T) {
|
||||
builder := NewPDFBuilder(Portrait, SizeA4, true)
|
||||
|
||||
builder.Debug(true)
|
||||
|
||||
logoRef := builder.RegisterImage(logoData)
|
||||
|
||||
builder.SetMargins(PDFMargins{Left: 15, Top: 40, Right: 10})
|
||||
builder.AddPage()
|
||||
|
||||
builder.SetFont(FontHelvetica, Normal, 10)
|
||||
builder.Cell("Neueinrichtung deiner Entgeltumwandlung", NewPDFCellOpt().Bold().FontSize(20))
|
||||
builder.Ln(10)
|
||||
|
||||
builder.SetFont(FontHelvetica, Normal, 10)
|
||||
builder.Cell("Hello World", NewPDFCellOpt().Width(50).Align(AlignHorzCenter).LnPos(BreakToRight))
|
||||
builder.IncX(10)
|
||||
builder.Cell("Second Text", NewPDFCellOpt().AutoWidth().AutoWidthPaddingX(2).LnPos(BreakToRight))
|
||||
builder.Ln(10)
|
||||
|
||||
builder.MultiCell("Im Fall einer individuellen Entgeltumwandlung ist die Zuschussverpflichtung auf der Grundlage des Betriebsrentenstärkungsgesetzes in der gesetzlich vorgeschriebenen Höhe (§ 1a Abs. 1a BetrAVG), über den arbeitgeberfinanzierten Zuschuss erfüllt.")
|
||||
builder.Ln(4)
|
||||
|
||||
builder.Image(logoRef, NewPDFImageOpt().X(90).Y(160).Width(70).Height(30).ImageFit(imageext.ImageFitContainCenter))
|
||||
|
||||
builder.Ln(4)
|
||||
|
||||
cellStyleHeader := &TableCellStyleOpt{
|
||||
PDFCellOpt: *NewPDFCellOpt().
|
||||
FontSize(float64(8)).
|
||||
BorderColorHex(uint32(0x666666)).
|
||||
Border(BorderFull).
|
||||
FillColorHex(uint32(0xC0C0C0)).
|
||||
FillBackground(true).
|
||||
TextColorHex(uint32(0x000000)).
|
||||
Align(AlignHorzCenter).
|
||||
Bold(),
|
||||
minWidth: langext.Ptr(float64(5)),
|
||||
ellipsize: langext.PTrue,
|
||||
multiCell: langext.PFalse,
|
||||
}
|
||||
|
||||
cellStyleMulti := &TableCellStyleOpt{
|
||||
PDFCellOpt: *NewPDFCellOpt().
|
||||
FontSize(float64(8)).
|
||||
BorderColorHex(uint32(0x666666)).
|
||||
Border(BorderFull).
|
||||
FillColorHex(uint32(0xC060C0)).
|
||||
FillBackground(true).
|
||||
TextColorHex(uint32(0x000000)),
|
||||
minWidth: langext.Ptr(float64(5)),
|
||||
ellipsize: langext.PFalse,
|
||||
multiCell: langext.PTrue,
|
||||
}
|
||||
|
||||
builder.Table().
|
||||
Widths("auto", "20", "1fr", "20").
|
||||
PadX(2).
|
||||
PadY(2).
|
||||
AddRowWithStyle(cellStyleHeader, "test", "hello", "123", "end").
|
||||
AddRowDefaultStyle("test", "hello", "123", "end").
|
||||
AddRowDefaultStyle("123", "helasdsalo", "a", "enwqad").
|
||||
AddRowDefaultStyle("123asd", "TrimMeTrimMeTrimMeTrimMe", "a", "enwqad").
|
||||
AddRowWithStyle(cellStyleMulti, "123", "helasdsalo", "a", "MultiCell: enwqad enw\nqad enwqad enwqad enwqad enwqad").
|
||||
AddRowDefaultStyle("123", "helasdsalo", "a", "enwqad").
|
||||
Debug(false).
|
||||
Build()
|
||||
|
||||
builder.Ln(8)
|
||||
|
||||
builder.Table().
|
||||
Widths("auto", "20", "1fr", "20").
|
||||
PadX(2).
|
||||
PadY(2).
|
||||
BuildRow().RowStyle(cellStyleHeader).Cells("test", "hello", "123", "end").BuildRow().
|
||||
BuildRow().Cells("test", "hello", "123", "end").BuildRow().
|
||||
BuildRow().RowStyle(cellStyleMulti.FillHeight(true)).Cell("123").Cell("helasdsalo").Cell("a").Cell("MultiCell: enwqad enw\nqad enwqad enwqad enwqad enwqad").BuildRow().
|
||||
AddRowDefaultStyle("123", "helasdsalo", "a", "enwqad").
|
||||
Debug(false).
|
||||
Build()
|
||||
|
||||
bin, err := builder.Build()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fn := "wpdf_test.pdf"
|
||||
_ = os.WriteFile(fn, bin, 0644)
|
||||
fmt.Println("file://" + path.Join(langext.Must(os.Getwd()), fn))
|
||||
}
|
Reference in New Issue
Block a user