From 0c17a677944c8841908c04c3bbbe84b949737ea3 Mon Sep 17 00:00:00 2001 From: celogeek <65178+celogeek@users.noreply.github.com> Date: Sun, 1 Oct 2023 17:36:33 +0200 Subject: [PATCH] update style for max compatibility --- go.mod | 10 ++-- go.sum | 47 +++------------ internal/epub/epub.go | 34 ++++------- internal/epub/image/epub_image.go | 60 +++++++++---------- internal/epub/options/epub_options.go | 4 ++ .../templates/epub_templates_style.css.tmpl | 39 ++++++++---- .../templates/epub_templates_text.xhtml.tmpl | 8 ++- 7 files changed, 90 insertions(+), 112 deletions(-) diff --git a/go.mod b/go.mod index 985741f..e7715d7 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/celogeek/go-comic-converter/v2 -go 1.20 +go 1.21 require ( github.com/beevik/etree v1.2.0 @@ -12,7 +12,7 @@ require ( github.com/raff/pdfreader v0.0.0-20220308062436-033e8ac577f0 github.com/schollz/progressbar/v3 v3.13.1 github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e - golang.org/x/image v0.12.0 + golang.org/x/image v0.13.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -24,7 +24,7 @@ require ( github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/stretchr/testify v1.8.4 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sys v0.12.0 // indirect - golang.org/x/term v0.12.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect ) diff --git a/go.sum b/go.sum index 68f1986..64904f0 100644 --- a/go.sum +++ b/go.sum @@ -43,48 +43,17 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e h1:IWllFTiDjjLIf2oeKxpIUmtiDV5sn71VgeQgg6vcE7k= github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e/go.mod h1:d7u6HkTYKSv5m6MCKkOQlHwaShTMl3HjqSGW3XtVhXM= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ= -golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg= +golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/epub/epub.go b/internal/epub/epub.go index df4da11..5a70328 100644 --- a/internal/epub/epub.go +++ b/internal/epub/epub.go @@ -75,10 +75,9 @@ func (e *ePub) writeImage(wz *epubzip.EPUBZip, img *epubimage.Image, zipImg *zip err := wz.WriteContent( img.EPUBPagePath(), []byte(e.render(epubtemplates.Text, map[string]any{ - "Title": fmt.Sprintf("Image %d Part %d", img.Id, img.Part), - "ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height), - "ImagePath": img.ImgPath(), - "ImageStyle": img.ImgStyle(e.Image.View.Width, e.Image.View.Height, ""), + "Title": fmt.Sprintf("Image %d Part %d", img.Id, img.Part), + "ViewPort": e.Image.View.Port(), + "Image": img.ImgStyle("", e.Image.View.Width, e.Image.View.Height), })), ) if err == nil { @@ -94,7 +93,7 @@ func (e *ePub) writeBlank(wz *epubzip.EPUBZip, img *epubimage.Image) error { img.EPUBSpacePath(), []byte(e.render(epubtemplates.Blank, map[string]any{ "Title": fmt.Sprintf("Blank Page %d", img.Id), - "ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height), + "ViewPort": e.Image.View.Port(), })), ) } @@ -111,10 +110,9 @@ func (e *ePub) writeCoverImage(wz *epubzip.EPUBZip, img *epubimage.Image, part, if err := wz.WriteContent( "OEBPS/Text/cover.xhtml", []byte(e.render(epubtemplates.Text, map[string]any{ - "Title": title, - "ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height), - "ImagePath": fmt.Sprintf("Images/cover.%s", e.Image.Format), - "ImageStyle": img.ImgStyle(e.Image.View.Width, e.Image.View.Height, ""), + "Title": title, + "ViewPort": e.Image.View.Port(), + "Image": img.ImgStyle("cover", e.Image.View.Width, e.Image.View.Height), })), ); err != nil { return err @@ -144,21 +142,12 @@ func (e *ePub) writeCoverImage(wz *epubzip.EPUBZip, img *epubimage.Image, part, // write title image func (e *ePub) writeTitleImage(wz *epubzip.EPUBZip, img *epubimage.Image, title string) error { - titleAlign := "" - if !e.Image.View.PortraitOnly { - if e.Image.Manga { - titleAlign = "right:0" - } else { - titleAlign = "left:0" - } - } - if !e.Image.View.PortraitOnly { if err := wz.WriteContent( "OEBPS/Text/space_title.xhtml", []byte(e.render(epubtemplates.Blank, map[string]any{ "Title": "Blank Page Title", - "ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height), + "ViewPort": e.Image.View.Port(), })), ); err != nil { return err @@ -168,10 +157,9 @@ func (e *ePub) writeTitleImage(wz *epubzip.EPUBZip, img *epubimage.Image, title if err := wz.WriteContent( "OEBPS/Text/title.xhtml", []byte(e.render(epubtemplates.Text, map[string]any{ - "Title": title, - "ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height), - "ImagePath": fmt.Sprintf("Images/title.%s", e.Image.Format), - "ImageStyle": img.ImgStyle(e.Image.View.Width, e.Image.View.Height, titleAlign), + "Title": title, + "ViewPort": e.Image.View.Port(), + "Image": img.ImgStyle("title", e.Image.View.Width, e.Image.View.Height), })), ); err != nil { return err diff --git a/internal/epub/image/epub_image.go b/internal/epub/image/epub_image.go index 4b84595..d5d7681 100644 --- a/internal/epub/image/epub_image.go +++ b/internal/epub/image/epub_image.go @@ -6,7 +6,6 @@ package epubimage import ( "fmt" "image" - "strings" ) type Image struct { @@ -66,40 +65,19 @@ func (i *Image) ImgPath() string { return fmt.Sprintf("Images/%s.%s", i.ImgKey(), i.Format) } +// special path +func (i *Image) ImgSpecialPath(kind string) string { + if kind == "" { + return i.ImgPath() + } + return fmt.Sprintf("Images/%s.%s", kind, i.Format) +} + // image path into the EPUB func (i *Image) EPUBImgPath() string { return fmt.Sprintf("OEBPS/%s", i.ImgPath()) } -// style to apply to the image. -// -// center by default. -// align to left or right if it's part of the splitted double page. -func (i *Image) ImgStyle(viewWidth, viewHeight int, align string) string { - relWidth, relHeight := i.RelSize(viewWidth, viewHeight) - marginW, marginH := float64(viewWidth-relWidth)/2, float64(viewHeight-relHeight)/2 - - style := []string{} - - style = append(style, fmt.Sprintf("width:%dpx", relWidth)) - style = append(style, fmt.Sprintf("height:%dpx", relHeight)) - style = append(style, fmt.Sprintf("top:%.2f%%", marginH*100/float64(viewHeight))) - if align == "" { - switch i.Position { - case "rendition:page-spread-left": - style = append(style, "right:0") - case "rendition:page-spread-right": - style = append(style, "left:0") - default: - style = append(style, fmt.Sprintf("left:%.2f%%", marginW*100/float64(viewWidth))) - } - } else { - style = append(style, align) - } - - return strings.Join(style, "; ") -} - func (i *Image) RelSize(viewWidth, viewHeight int) (relWidth, relHeight int) { w, h := viewWidth, viewHeight srcw, srch := i.Width, i.Height @@ -121,3 +99,25 @@ func (i *Image) RelSize(viewWidth, viewHeight int) (relWidth, relHeight int) { return } + +func (i *Image) ImgStyle(kind string, viewWidth, viewHeight int) map[string]any { + align := "" + switch i.Position { + case "rendition:page-spread-right": + align = "left:0" + case "rendition:page-spread-left": + align = "right:0" + } + + relWidth, relHeight := i.RelSize(viewWidth, viewHeight) + marginH := float64(viewHeight-relHeight) / 2 + top := fmt.Sprintf("%.2f", marginH*100/float64(viewHeight)) + + return map[string]any{ + "Path": i.ImgSpecialPath(kind), + "Width": relWidth, + "Height": relHeight, + "Top": top, + "Align": align, + } +} diff --git a/internal/epub/options/epub_options.go b/internal/epub/options/epub_options.go index 2de0277..58e87be 100644 --- a/internal/epub/options/epub_options.go +++ b/internal/epub/options/epub_options.go @@ -21,6 +21,10 @@ type View struct { Color Color } +func (v *View) Port() string { + return fmt.Sprintf("width=%d, height=%d", v.Width, v.Height) +} + type Image struct { Crop *Crop Quality int diff --git a/internal/epub/templates/epub_templates_style.css.tmpl b/internal/epub/templates/epub_templates_style.css.tmpl index cfa4f08..6dd924b 100644 --- a/internal/epub/templates/epub_templates_style.css.tmpl +++ b/internal/epub/templates/epub_templates_style.css.tmpl @@ -1,18 +1,31 @@ +@page { + margin: 0; + padding: 0; +} + body { - color: #{{ .View.Color.Foreground }}; - background: #{{ .View.Color.Background }}; - top: 0; - left: 0; - margin: 0; - padding: 0; - width: {{ .View.Width }}px; - height: {{ .View.Height }}px; - text-align: center; + color: #{{ .View.Color.Foreground }}; + background: #{{ .View.Color.Background }}; + width: {{ .View.Width }}px; + height: {{ .View.Height }}px; + margin: 0; + padding: 0; +} + +div { + margin: 0; + padding: 0; + text-align: center; + position: absolute; +} + +span { + margin: 0; + padding: 0; + text-indent: 0; } img { - position: absolute; - margin:0; - padding:0; - z-index:0; + margin: 0; + padding: 0; } \ No newline at end of file diff --git a/internal/epub/templates/epub_templates_text.xhtml.tmpl b/internal/epub/templates/epub_templates_text.xhtml.tmpl index 21cea8f..1211c4e 100644 --- a/internal/epub/templates/epub_templates_text.xhtml.tmpl +++ b/internal/epub/templates/epub_templates_text.xhtml.tmpl @@ -7,7 +7,11 @@ - - {{ .Title }} + +
+ + {{ .Title }} + +
\ No newline at end of file