mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-08-30 12:12:40 +08:00
feat(印章渲染): 支持OFD格式电子印章渲染
This commit is contained in:
+73
-17
@@ -47,8 +47,25 @@ type RendererOption func(*Renderer)
|
|||||||
|
|
||||||
// RenderPage 渲染特定页面内容
|
// RenderPage 渲染特定页面内容
|
||||||
// 入参: page 页面内容
|
// 入参: page 页面内容
|
||||||
// 返回: *canvas.Canvas 画布实例, err 错误信息
|
// 返回: *canvas.Canvas 画布实例, error 错误信息
|
||||||
func (r *Renderer) RenderPage(page *PageContent) (*canvas.Canvas, error) {
|
func (r *Renderer) RenderPage(page *PageContent) (*canvas.Canvas, error) {
|
||||||
|
box, err := r.GetPageBox(page)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
width, height := box.W, box.H
|
||||||
|
c := canvas.New(width, height)
|
||||||
|
ctx := canvas.NewContext(c)
|
||||||
|
if err := r.RenderPageToContext(ctx, page); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPageBox 获取页面物理区域
|
||||||
|
// 入参: page 页面内容
|
||||||
|
// 返回: Box 区域, error 错误信息
|
||||||
|
func (r *Renderer) GetPageBox(page *PageContent) (Box, error) {
|
||||||
boxStr := page.Area.PhysicalBox
|
boxStr := page.Area.PhysicalBox
|
||||||
if boxStr == "" {
|
if boxStr == "" {
|
||||||
boxStr = page.Area.ApplicationBox
|
boxStr = page.Area.ApplicationBox
|
||||||
@@ -62,18 +79,25 @@ func (r *Renderer) RenderPage(page *PageContent) (*canvas.Canvas, error) {
|
|||||||
if boxStr == "" {
|
if boxStr == "" {
|
||||||
boxStr = "0 0 210 297"
|
boxStr = "0 0 210 297"
|
||||||
}
|
}
|
||||||
box, err := ParseBox(boxStr)
|
return ParseBox(boxStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RenderPageToContext 渲染页面到指定上下文
|
||||||
|
// 入参: ctx 画布上下文, page 页面内容
|
||||||
|
// 返回: error 错误信息
|
||||||
|
func (r *Renderer) RenderPageToContext(ctx *canvas.Context, page *PageContent) error {
|
||||||
|
box, err := r.GetPageBox(page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
c := canvas.New(box.W, box.H)
|
|
||||||
ctx := canvas.NewContext(c)
|
|
||||||
pageH := box.H
|
pageH := box.H
|
||||||
ctx.SetFillColor(canvas.White)
|
ctx.SetFillColor(canvas.White)
|
||||||
ctx.DrawPath(0, 0, canvas.Rectangle(box.W, box.H))
|
ctx.DrawPath(0, 0, canvas.Rectangle(box.W, box.H))
|
||||||
if len(page.Template) > 0 && r.Reader.doc != nil {
|
if len(page.Template) > 0 && r.Reader.doc != nil {
|
||||||
for _, tplRef := range page.Template {
|
for _, tplRef := range page.Template {
|
||||||
r.renderTemplate(ctx, tplRef.TemplateID, pageH)
|
if tplRef.ZOrder != "Foreground" {
|
||||||
|
r.renderTemplate(ctx, tplRef.TemplateID, pageH)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if page.Content.Layer != nil {
|
if page.Content.Layer != nil {
|
||||||
@@ -81,17 +105,24 @@ func (r *Renderer) RenderPage(page *PageContent) (*canvas.Canvas, error) {
|
|||||||
r.renderLayer(ctx, layer, pageH, nil, nil, 0)
|
r.renderLayer(ctx, layer, pageH, nil, nil, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if stamps, ok := r.Reader.Stamps[page.ID]; ok {
|
if len(page.Template) > 0 && r.Reader.doc != nil {
|
||||||
for _, s := range stamps {
|
for _, tplRef := range page.Template {
|
||||||
r.renderStamp(ctx, s, pageH)
|
if tplRef.ZOrder == "Foreground" {
|
||||||
|
r.renderTemplate(ctx, tplRef.TemplateID, pageH)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c, nil
|
if stamps, ok := r.Reader.Stamps[page.ID]; ok {
|
||||||
|
for _, stamp := range stamps {
|
||||||
|
r.renderStamp(ctx, stamp, pageH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenderPageByIndex 按索引渲染页面
|
// RenderPageByIndex 按索引渲染页面
|
||||||
// 入参: index 页面索引
|
// 入参: index 页面索引
|
||||||
// 返回: *canvas.Canvas 画布实例, err 错误信息
|
// 返回: *canvas.Canvas 画布实例, error 错误信息
|
||||||
func (r *Renderer) RenderPageByIndex(index int) (*canvas.Canvas, error) {
|
func (r *Renderer) RenderPageByIndex(index int) (*canvas.Canvas, error) {
|
||||||
doc, err := r.Reader.Doc()
|
doc, err := r.Reader.Doc()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -109,7 +140,7 @@ func (r *Renderer) RenderPageByIndex(index int) (*canvas.Canvas, error) {
|
|||||||
|
|
||||||
// RenderToImage 渲染为光栅图
|
// RenderToImage 渲染为光栅图
|
||||||
// 入参: page 页面内容
|
// 入参: page 页面内容
|
||||||
// 返回: image.Image 图像对象, err 错误信息
|
// 返回: image.Image 图像对象, error 错误信息
|
||||||
func (r *Renderer) RenderToImage(page *PageContent) (image.Image, error) {
|
func (r *Renderer) RenderToImage(page *PageContent) (image.Image, error) {
|
||||||
c, err := r.RenderPage(page)
|
c, err := r.RenderPage(page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -121,7 +152,7 @@ func (r *Renderer) RenderToImage(page *PageContent) (image.Image, error) {
|
|||||||
|
|
||||||
// RenderToSVG 渲染为SVG
|
// RenderToSVG 渲染为SVG
|
||||||
// 入参: page 页面内容, writer 输出流
|
// 入参: page 页面内容, writer 输出流
|
||||||
// 返回: err 错误信息
|
// 返回: error 错误信息
|
||||||
func (r *Renderer) RenderToSVG(page *PageContent, writer io.Writer) error {
|
func (r *Renderer) RenderToSVG(page *PageContent, writer io.Writer) error {
|
||||||
c, err := r.RenderPage(page)
|
c, err := r.RenderPage(page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -132,7 +163,7 @@ func (r *Renderer) RenderToSVG(page *PageContent, writer io.Writer) error {
|
|||||||
|
|
||||||
// RenderToPDF 渲染为PDF
|
// RenderToPDF 渲染为PDF
|
||||||
// 入参: page 页面内容, writer 输出流
|
// 入参: page 页面内容, writer 输出流
|
||||||
// 返回: err 错误信息
|
// 返回: error 错误信息
|
||||||
func (r *Renderer) RenderToPDF(page *PageContent, writer io.Writer) error {
|
func (r *Renderer) RenderToPDF(page *PageContent, writer io.Writer) error {
|
||||||
c, err := r.RenderPage(page)
|
c, err := r.RenderPage(page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -143,7 +174,7 @@ func (r *Renderer) RenderToPDF(page *PageContent, writer io.Writer) error {
|
|||||||
|
|
||||||
// RenderToEPS 渲染为EPS
|
// RenderToEPS 渲染为EPS
|
||||||
// 入参: page 页面内容, writer 输出流
|
// 入参: page 页面内容, writer 输出流
|
||||||
// 返回: err 错误信息
|
// 返回: error 错误信息
|
||||||
func (r *Renderer) RenderToEPS(page *PageContent, writer io.Writer) error {
|
func (r *Renderer) RenderToEPS(page *PageContent, writer io.Writer) error {
|
||||||
c, err := r.RenderPage(page)
|
c, err := r.RenderPage(page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -602,11 +633,37 @@ func (r *Renderer) loadFont(fontID string) *canvas.FontFamily {
|
|||||||
// 入参: ctx 画布上下文, s 印章对象, pageH 页面高度
|
// 入参: ctx 画布上下文, s 印章对象, pageH 页面高度
|
||||||
func (r *Renderer) renderStamp(ctx *canvas.Context, s Stamp, pageH float64) {
|
func (r *Renderer) renderStamp(ctx *canvas.Context, s Stamp, pageH float64) {
|
||||||
x, y, w, h := s.Box.X, s.Box.Y, s.Box.W, s.Box.H
|
x, y, w, h := s.Box.X, s.Box.Y, s.Box.W, s.Box.H
|
||||||
|
screenY := pageH - (y + h)
|
||||||
|
if s.Type == "ofd" && len(s.Data) > 0 {
|
||||||
|
reader, err := NewReader(bytes.NewReader(s.Data), int64(len(s.Data)))
|
||||||
|
if err == nil {
|
||||||
|
defer reader.Close()
|
||||||
|
doc, err := reader.Doc()
|
||||||
|
if err == nil {
|
||||||
|
renderer := NewRenderer(reader)
|
||||||
|
for _, pageRef := range doc.Pages.Page {
|
||||||
|
content, err := reader.PageContent(pageRef)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
sealBox, err := renderer.GetPageBox(content)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ctx.Push()
|
||||||
|
ctx.Translate(x, screenY)
|
||||||
|
ctx.Scale(w/sealBox.W, h/sealBox.H)
|
||||||
|
renderer.RenderPageToContext(ctx, content)
|
||||||
|
ctx.Pop()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if len(s.Data) > 0 {
|
if len(s.Data) > 0 {
|
||||||
img, _, err := image.Decode(bytes.NewReader(s.Data))
|
img, _, err := image.Decode(bytes.NewReader(s.Data))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ctx.Push()
|
ctx.Push()
|
||||||
screenY := pageH - (y + h)
|
|
||||||
ctx.Translate(x, screenY)
|
ctx.Translate(x, screenY)
|
||||||
ctx.Scale(w/float64(img.Bounds().Dx()), h/float64(img.Bounds().Dy()))
|
ctx.Scale(w/float64(img.Bounds().Dx()), h/float64(img.Bounds().Dy()))
|
||||||
ctx.DrawImage(0, 0, img, canvas.DPMM(1.0))
|
ctx.DrawImage(0, 0, img, canvas.DPMM(1.0))
|
||||||
@@ -615,7 +672,6 @@ func (r *Renderer) renderStamp(ctx *canvas.Context, s Stamp, pageH float64) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.Push()
|
ctx.Push()
|
||||||
screenY := pageH - (y + h)
|
|
||||||
ctx.SetStrokeColor(canvas.Red)
|
ctx.SetStrokeColor(canvas.Red)
|
||||||
ctx.SetStrokeWidth(0.5)
|
ctx.SetStrokeWidth(0.5)
|
||||||
ctx.SetFillColor(canvas.Transparent)
|
ctx.SetFillColor(canvas.Transparent)
|
||||||
|
|||||||
Reference in New Issue
Block a user