mirror of
https://github.com/unidoc/unipdf.git
synced 2025-05-05 19:30:30 +08:00
Text generating operators in content creator. Some refactoring of annotator.
This commit is contained in:
parent
36aaf59139
commit
5a7469958d
@ -10,171 +10,8 @@ import (
|
|||||||
pdf "github.com/unidoc/unidoc/pdf/model"
|
pdf "github.com/unidoc/unidoc/pdf/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The currently supported line ending styles are None, Arrow (ClosedArrow) and Butt.
|
|
||||||
type LineEndingStyle int
|
|
||||||
|
|
||||||
const (
|
|
||||||
LineEndingStyleNone LineEndingStyle = 0
|
|
||||||
LineEndingStyleArrow LineEndingStyle = 1
|
|
||||||
LineEndingStyleButt LineEndingStyle = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
// Defines a line between point 1 (X1,Y1) and point 2 (X2,Y2). The line ending styles can be none (regular line),
|
|
||||||
// or arrows at either end. The line also has a specified width, color and opacity.
|
|
||||||
type LineAnnotationDef struct {
|
|
||||||
X1 float64
|
|
||||||
Y1 float64
|
|
||||||
X2 float64
|
|
||||||
Y2 float64
|
|
||||||
LineColor *pdf.PdfColorDeviceRGB
|
|
||||||
Opacity float64 // Alpha value (0-1).
|
|
||||||
LineWidth float64
|
|
||||||
LineEndingStyle1 LineEndingStyle // Line ending style of point 1.
|
|
||||||
LineEndingStyle2 LineEndingStyle // Line ending style of point 2.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a line annotation object that can be added to page PDF annotations.
|
|
||||||
func CreateLineAnnotation(lineDef LineAnnotationDef) (*pdf.PdfAnnotation, error) {
|
|
||||||
// Line annotation.
|
|
||||||
lineAnnotation := pdf.NewPdfAnnotationLine()
|
|
||||||
|
|
||||||
// Line endpoint locations.
|
|
||||||
lineAnnotation.L = pdfcore.MakeArrayFromFloats([]float64{lineDef.X1, lineDef.Y1, lineDef.X2, lineDef.Y2})
|
|
||||||
|
|
||||||
// Line endings.
|
|
||||||
le1 := pdfcore.MakeName("None")
|
|
||||||
if lineDef.LineEndingStyle1 == LineEndingStyleArrow {
|
|
||||||
le1 = pdfcore.MakeName("ClosedArrow")
|
|
||||||
}
|
|
||||||
le2 := pdfcore.MakeName("None")
|
|
||||||
if lineDef.LineEndingStyle2 == LineEndingStyleArrow {
|
|
||||||
le2 = pdfcore.MakeName("ClosedArrow")
|
|
||||||
}
|
|
||||||
lineAnnotation.LE = pdfcore.MakeArray(le1, le2)
|
|
||||||
|
|
||||||
// Opacity.
|
|
||||||
if lineDef.Opacity < 1.0 {
|
|
||||||
lineAnnotation.CA = pdfcore.MakeFloat(lineDef.Opacity)
|
|
||||||
}
|
|
||||||
|
|
||||||
r, g, b := lineDef.LineColor.R(), lineDef.LineColor.G(), lineDef.LineColor.B()
|
|
||||||
lineAnnotation.IC = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) // fill color of line endings, rgb 0-1.
|
|
||||||
lineAnnotation.C = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) // line color, rgb 0-1.
|
|
||||||
bs := pdf.NewBorderStyle()
|
|
||||||
bs.SetBorderWidth(lineDef.LineWidth) // Line width: 3 points.
|
|
||||||
lineAnnotation.BS = bs.ToPdfObject()
|
|
||||||
|
|
||||||
// Make the appearance stream (for uniform appearance).
|
|
||||||
apDict, bbox, err := makeLineAnnotationAppearanceStream(lineDef)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
lineAnnotation.AP = apDict
|
|
||||||
|
|
||||||
// The rect specifies the location and dimensions of the annotation. Technically if the annotation could not
|
|
||||||
// be displayed if it goes outside these bounds, although rarely enforced.
|
|
||||||
lineAnnotation.Rect = pdfcore.MakeArrayFromFloats([]float64{bbox.Llx, bbox.Lly, bbox.Urx, bbox.Ury})
|
|
||||||
|
|
||||||
return lineAnnotation.PdfAnnotation, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// A rectangle defined with a specified Width and Height and a lower left corner at (X,Y). The rectangle can
|
|
||||||
// optionally have a border and a filling color.
|
|
||||||
// The Width/Height includes the border (if any specified).
|
|
||||||
type RectangleAnnotationDef struct {
|
|
||||||
X float64
|
|
||||||
Y float64
|
|
||||||
Width float64
|
|
||||||
Height float64
|
|
||||||
FillEnabled bool // Show fill?
|
|
||||||
FillColor *pdf.PdfColorDeviceRGB
|
|
||||||
BorderEnabled bool // Show border?
|
|
||||||
BorderWidth float64
|
|
||||||
BorderColor *pdf.PdfColorDeviceRGB
|
|
||||||
Opacity float64 // Alpha value (0-1).
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a rectangle annotation object that can be added to page PDF annotations.
|
|
||||||
func CreateRectangleAnnotation(rectDef RectangleAnnotationDef) (*pdf.PdfAnnotation, error) {
|
|
||||||
rectAnnotation := pdf.NewPdfAnnotationSquare()
|
|
||||||
|
|
||||||
if rectDef.BorderEnabled {
|
|
||||||
r, g, b := rectDef.BorderColor.R(), rectDef.BorderColor.G(), rectDef.BorderColor.B()
|
|
||||||
rectAnnotation.C = pdfcore.MakeArrayFromFloats([]float64{r, g, b})
|
|
||||||
bs := pdf.NewBorderStyle()
|
|
||||||
bs.SetBorderWidth(rectDef.BorderWidth)
|
|
||||||
rectAnnotation.BS = bs.ToPdfObject()
|
|
||||||
}
|
|
||||||
|
|
||||||
if rectDef.FillEnabled {
|
|
||||||
r, g, b := rectDef.FillColor.R(), rectDef.FillColor.G(), rectDef.FillColor.B()
|
|
||||||
rectAnnotation.IC = pdfcore.MakeArrayFromFloats([]float64{r, g, b})
|
|
||||||
} else {
|
|
||||||
rectAnnotation.IC = pdfcore.MakeArrayFromIntegers([]int{}) // No fill.
|
|
||||||
}
|
|
||||||
|
|
||||||
if rectDef.Opacity < 1.0 {
|
|
||||||
rectAnnotation.CA = pdfcore.MakeFloat(rectDef.Opacity)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the appearance stream (for uniform appearance).
|
|
||||||
apDict, bbox, err := makeRectangleAnnotationAppearanceStream(rectDef)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
rectAnnotation.AP = apDict
|
|
||||||
rectAnnotation.Rect = pdfcore.MakeArrayFromFloats([]float64{bbox.Llx, bbox.Lly, bbox.Urx, bbox.Ury})
|
|
||||||
|
|
||||||
return rectAnnotation.PdfAnnotation, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type CircleAnnotationDef struct {
|
|
||||||
X float64
|
|
||||||
Y float64
|
|
||||||
Width float64
|
|
||||||
Height float64
|
|
||||||
FillEnabled bool // Show fill?
|
|
||||||
FillColor *pdf.PdfColorDeviceRGB
|
|
||||||
BorderEnabled bool // Show border?
|
|
||||||
BorderWidth float64
|
|
||||||
BorderColor *pdf.PdfColorDeviceRGB
|
|
||||||
Opacity float64 // Alpha value (0-1).
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a circle/ellipse annotation object with appearance stream that can be added to page PDF annotations.
|
|
||||||
func CreateCircleAnnotation(circDef CircleAnnotationDef) (*pdf.PdfAnnotation, error) {
|
|
||||||
circAnnotation := pdf.NewPdfAnnotationCircle()
|
|
||||||
|
|
||||||
if circDef.BorderEnabled {
|
|
||||||
r, g, b := circDef.BorderColor.R(), circDef.BorderColor.G(), circDef.BorderColor.B()
|
|
||||||
circAnnotation.C = pdfcore.MakeArrayFromFloats([]float64{r, g, b})
|
|
||||||
bs := pdf.NewBorderStyle()
|
|
||||||
bs.SetBorderWidth(circDef.BorderWidth)
|
|
||||||
circAnnotation.BS = bs.ToPdfObject()
|
|
||||||
}
|
|
||||||
|
|
||||||
if circDef.FillEnabled {
|
|
||||||
r, g, b := circDef.FillColor.R(), circDef.FillColor.G(), circDef.FillColor.B()
|
|
||||||
circAnnotation.IC = pdfcore.MakeArrayFromFloats([]float64{r, g, b})
|
|
||||||
} else {
|
|
||||||
circAnnotation.IC = pdfcore.MakeArrayFromIntegers([]int{}) // No fill.
|
|
||||||
}
|
|
||||||
|
|
||||||
if circDef.Opacity < 1.0 {
|
|
||||||
circAnnotation.CA = pdfcore.MakeFloat(circDef.Opacity)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the appearance stream (for uniform appearance).
|
|
||||||
apDict, bbox, err := makeCircleAnnotationAppearanceStream(circDef)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
circAnnotation.AP = apDict
|
|
||||||
circAnnotation.Rect = pdfcore.MakeArrayFromFloats([]float64{bbox.Llx, bbox.Lly, bbox.Urx, bbox.Ury})
|
|
||||||
|
|
||||||
return circAnnotation.PdfAnnotation, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -14,14 +14,53 @@ import (
|
|||||||
pdf "github.com/unidoc/unidoc/pdf/model"
|
pdf "github.com/unidoc/unidoc/pdf/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Make the bezier path with the content creator.
|
type CircleAnnotationDef struct {
|
||||||
func drawBezierPathWithCreator(bpath draw.CubicBezierPath, creator *pdfcontent.ContentCreator) {
|
X float64
|
||||||
for idx, c := range bpath.Curves {
|
Y float64
|
||||||
if idx == 0 {
|
Width float64
|
||||||
creator.Add_m(c.P0.X, c.P0.Y)
|
Height float64
|
||||||
}
|
FillEnabled bool // Show fill?
|
||||||
creator.Add_c(c.P1.X, c.P1.Y, c.P2.X, c.P2.Y, c.P3.X, c.P3.Y)
|
FillColor *pdf.PdfColorDeviceRGB
|
||||||
|
BorderEnabled bool // Show border?
|
||||||
|
BorderWidth float64
|
||||||
|
BorderColor *pdf.PdfColorDeviceRGB
|
||||||
|
Opacity float64 // Alpha value (0-1).
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a circle/ellipse annotation object with appearance stream that can be added to page PDF annotations.
|
||||||
|
func CreateCircleAnnotation(circDef CircleAnnotationDef) (*pdf.PdfAnnotation, error) {
|
||||||
|
circAnnotation := pdf.NewPdfAnnotationCircle()
|
||||||
|
|
||||||
|
if circDef.BorderEnabled {
|
||||||
|
r, g, b := circDef.BorderColor.R(), circDef.BorderColor.G(), circDef.BorderColor.B()
|
||||||
|
circAnnotation.C = pdfcore.MakeArrayFromFloats([]float64{r, g, b})
|
||||||
|
bs := pdf.NewBorderStyle()
|
||||||
|
bs.SetBorderWidth(circDef.BorderWidth)
|
||||||
|
circAnnotation.BS = bs.ToPdfObject()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if circDef.FillEnabled {
|
||||||
|
r, g, b := circDef.FillColor.R(), circDef.FillColor.G(), circDef.FillColor.B()
|
||||||
|
circAnnotation.IC = pdfcore.MakeArrayFromFloats([]float64{r, g, b})
|
||||||
|
} else {
|
||||||
|
circAnnotation.IC = pdfcore.MakeArrayFromIntegers([]int{}) // No fill.
|
||||||
|
}
|
||||||
|
|
||||||
|
if circDef.Opacity < 1.0 {
|
||||||
|
circAnnotation.CA = pdfcore.MakeFloat(circDef.Opacity)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the appearance stream (for uniform appearance).
|
||||||
|
apDict, bbox, err := makeCircleAnnotationAppearanceStream(circDef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
circAnnotation.AP = apDict
|
||||||
|
circAnnotation.Rect = pdfcore.MakeArrayFromFloats([]float64{bbox.Llx, bbox.Lly, bbox.Urx, bbox.Ury})
|
||||||
|
|
||||||
|
return circAnnotation.PdfAnnotation, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeCircleAnnotationAppearanceStream(circDef CircleAnnotationDef) (*pdfcore.PdfObjectDictionary, *pdf.PdfRectangle, error) {
|
func makeCircleAnnotationAppearanceStream(circDef CircleAnnotationDef) (*pdfcore.PdfObjectDictionary, *pdf.PdfRectangle, error) {
|
||||||
|
@ -15,15 +15,72 @@ import (
|
|||||||
pdf "github.com/unidoc/unidoc/pdf/model"
|
pdf "github.com/unidoc/unidoc/pdf/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Make the path with the content creator.
|
// The currently supported line ending styles are None, Arrow (ClosedArrow) and Butt.
|
||||||
func drawPathWithCreator(path draw.Path, creator *pdfcontent.ContentCreator) {
|
type LineEndingStyle int
|
||||||
for idx, p := range path.Points {
|
|
||||||
if idx == 0 {
|
const (
|
||||||
creator.Add_m(p.X, p.Y)
|
LineEndingStyleNone LineEndingStyle = 0
|
||||||
} else {
|
LineEndingStyleArrow LineEndingStyle = 1
|
||||||
creator.Add_l(p.X, p.Y)
|
LineEndingStyleButt LineEndingStyle = 2
|
||||||
}
|
)
|
||||||
|
|
||||||
|
// Defines a line between point 1 (X1,Y1) and point 2 (X2,Y2). The line ending styles can be none (regular line),
|
||||||
|
// or arrows at either end. The line also has a specified width, color and opacity.
|
||||||
|
type LineAnnotationDef struct {
|
||||||
|
X1 float64
|
||||||
|
Y1 float64
|
||||||
|
X2 float64
|
||||||
|
Y2 float64
|
||||||
|
LineColor *pdf.PdfColorDeviceRGB
|
||||||
|
Opacity float64 // Alpha value (0-1).
|
||||||
|
LineWidth float64
|
||||||
|
LineEndingStyle1 LineEndingStyle // Line ending style of point 1.
|
||||||
|
LineEndingStyle2 LineEndingStyle // Line ending style of point 2.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a line annotation object that can be added to page PDF annotations.
|
||||||
|
func CreateLineAnnotation(lineDef LineAnnotationDef) (*pdf.PdfAnnotation, error) {
|
||||||
|
// Line annotation.
|
||||||
|
lineAnnotation := pdf.NewPdfAnnotationLine()
|
||||||
|
|
||||||
|
// Line endpoint locations.
|
||||||
|
lineAnnotation.L = pdfcore.MakeArrayFromFloats([]float64{lineDef.X1, lineDef.Y1, lineDef.X2, lineDef.Y2})
|
||||||
|
|
||||||
|
// Line endings.
|
||||||
|
le1 := pdfcore.MakeName("None")
|
||||||
|
if lineDef.LineEndingStyle1 == LineEndingStyleArrow {
|
||||||
|
le1 = pdfcore.MakeName("ClosedArrow")
|
||||||
}
|
}
|
||||||
|
le2 := pdfcore.MakeName("None")
|
||||||
|
if lineDef.LineEndingStyle2 == LineEndingStyleArrow {
|
||||||
|
le2 = pdfcore.MakeName("ClosedArrow")
|
||||||
|
}
|
||||||
|
lineAnnotation.LE = pdfcore.MakeArray(le1, le2)
|
||||||
|
|
||||||
|
// Opacity.
|
||||||
|
if lineDef.Opacity < 1.0 {
|
||||||
|
lineAnnotation.CA = pdfcore.MakeFloat(lineDef.Opacity)
|
||||||
|
}
|
||||||
|
|
||||||
|
r, g, b := lineDef.LineColor.R(), lineDef.LineColor.G(), lineDef.LineColor.B()
|
||||||
|
lineAnnotation.IC = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) // fill color of line endings, rgb 0-1.
|
||||||
|
lineAnnotation.C = pdfcore.MakeArrayFromFloats([]float64{r, g, b}) // line color, rgb 0-1.
|
||||||
|
bs := pdf.NewBorderStyle()
|
||||||
|
bs.SetBorderWidth(lineDef.LineWidth) // Line width: 3 points.
|
||||||
|
lineAnnotation.BS = bs.ToPdfObject()
|
||||||
|
|
||||||
|
// Make the appearance stream (for uniform appearance).
|
||||||
|
apDict, bbox, err := makeLineAnnotationAppearanceStream(lineDef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
lineAnnotation.AP = apDict
|
||||||
|
|
||||||
|
// The rect specifies the location and dimensions of the annotation. Technically if the annotation could not
|
||||||
|
// be displayed if it goes outside these bounds, although rarely enforced.
|
||||||
|
lineAnnotation.Rect = pdfcore.MakeArrayFromFloats([]float64{bbox.Llx, bbox.Lly, bbox.Urx, bbox.Ury})
|
||||||
|
|
||||||
|
return lineAnnotation.PdfAnnotation, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeLineAnnotationAppearanceStream(lineDef LineAnnotationDef) (*pdfcore.PdfObjectDictionary, *pdf.PdfRectangle, error) {
|
func makeLineAnnotationAppearanceStream(lineDef LineAnnotationDef) (*pdfcore.PdfObjectDictionary, *pdf.PdfRectangle, error) {
|
||||||
|
@ -14,6 +14,58 @@ import (
|
|||||||
pdf "github.com/unidoc/unidoc/pdf/model"
|
pdf "github.com/unidoc/unidoc/pdf/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// A rectangle defined with a specified Width and Height and a lower left corner at (X,Y). The rectangle can
|
||||||
|
// optionally have a border and a filling color.
|
||||||
|
// The Width/Height includes the border (if any specified).
|
||||||
|
type RectangleAnnotationDef struct {
|
||||||
|
X float64
|
||||||
|
Y float64
|
||||||
|
Width float64
|
||||||
|
Height float64
|
||||||
|
FillEnabled bool // Show fill?
|
||||||
|
FillColor *pdf.PdfColorDeviceRGB
|
||||||
|
BorderEnabled bool // Show border?
|
||||||
|
BorderWidth float64
|
||||||
|
BorderColor *pdf.PdfColorDeviceRGB
|
||||||
|
Opacity float64 // Alpha value (0-1).
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a rectangle annotation object that can be added to page PDF annotations.
|
||||||
|
func CreateRectangleAnnotation(rectDef RectangleAnnotationDef) (*pdf.PdfAnnotation, error) {
|
||||||
|
rectAnnotation := pdf.NewPdfAnnotationSquare()
|
||||||
|
|
||||||
|
if rectDef.BorderEnabled {
|
||||||
|
r, g, b := rectDef.BorderColor.R(), rectDef.BorderColor.G(), rectDef.BorderColor.B()
|
||||||
|
rectAnnotation.C = pdfcore.MakeArrayFromFloats([]float64{r, g, b})
|
||||||
|
bs := pdf.NewBorderStyle()
|
||||||
|
bs.SetBorderWidth(rectDef.BorderWidth)
|
||||||
|
rectAnnotation.BS = bs.ToPdfObject()
|
||||||
|
}
|
||||||
|
|
||||||
|
if rectDef.FillEnabled {
|
||||||
|
r, g, b := rectDef.FillColor.R(), rectDef.FillColor.G(), rectDef.FillColor.B()
|
||||||
|
rectAnnotation.IC = pdfcore.MakeArrayFromFloats([]float64{r, g, b})
|
||||||
|
} else {
|
||||||
|
rectAnnotation.IC = pdfcore.MakeArrayFromIntegers([]int{}) // No fill.
|
||||||
|
}
|
||||||
|
|
||||||
|
if rectDef.Opacity < 1.0 {
|
||||||
|
rectAnnotation.CA = pdfcore.MakeFloat(rectDef.Opacity)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the appearance stream (for uniform appearance).
|
||||||
|
apDict, bbox, err := makeRectangleAnnotationAppearanceStream(rectDef)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rectAnnotation.AP = apDict
|
||||||
|
rectAnnotation.Rect = pdfcore.MakeArrayFromFloats([]float64{bbox.Llx, bbox.Lly, bbox.Urx, bbox.Ury})
|
||||||
|
|
||||||
|
return rectAnnotation.PdfAnnotation, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func makeRectangleAnnotationAppearanceStream(rectDef RectangleAnnotationDef) (*pdfcore.PdfObjectDictionary, *pdf.PdfRectangle, error) {
|
func makeRectangleAnnotationAppearanceStream(rectDef RectangleAnnotationDef) (*pdfcore.PdfObjectDictionary, *pdf.PdfRectangle, error) {
|
||||||
form := pdf.NewXObjectForm()
|
form := pdf.NewXObjectForm()
|
||||||
form.Resources = pdf.NewPdfPageResources()
|
form.Resources = pdf.NewPdfPageResources()
|
||||||
|
27
pdf/annotator/utils.go
Normal file
27
pdf/annotator/utils.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package annotator
|
||||||
|
|
||||||
|
import (
|
||||||
|
pdfcontent "github.com/unidoc/unidoc/pdf/contentstream"
|
||||||
|
"github.com/unidoc/unidoc/pdf/contentstream/draw"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Make the path with the content creator.
|
||||||
|
func drawPathWithCreator(path draw.Path, creator *pdfcontent.ContentCreator) {
|
||||||
|
for idx, p := range path.Points {
|
||||||
|
if idx == 0 {
|
||||||
|
creator.Add_m(p.X, p.Y)
|
||||||
|
} else {
|
||||||
|
creator.Add_l(p.X, p.Y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the bezier path with the content creator.
|
||||||
|
func drawBezierPathWithCreator(bpath draw.CubicBezierPath, creator *pdfcontent.ContentCreator) {
|
||||||
|
for idx, c := range bpath.Curves {
|
||||||
|
if idx == 0 {
|
||||||
|
creator.Add_m(c.P0.X, c.P0.Y)
|
||||||
|
}
|
||||||
|
creator.Add_c(c.P1.X, c.P1.Y, c.P2.X, c.P2.Y, c.P3.X, c.P3.Y)
|
||||||
|
}
|
||||||
|
}
|
@ -414,7 +414,6 @@ func (this *ContentCreator) Add_k(c, m, y, k float64) *ContentCreator {
|
|||||||
|
|
||||||
/* Shading operators. */
|
/* Shading operators. */
|
||||||
|
|
||||||
// sh: Paint the shape and color described by a shading dictionary.
|
|
||||||
func (this *ContentCreator) Add_sh(name PdfObjectName) *ContentCreator {
|
func (this *ContentCreator) Add_sh(name PdfObjectName) *ContentCreator {
|
||||||
op := ContentStreamOperation{}
|
op := ContentStreamOperation{}
|
||||||
op.Operand = "sh"
|
op.Operand = "sh"
|
||||||
@ -422,3 +421,163 @@ func (this *ContentCreator) Add_sh(name PdfObjectName) *ContentCreator {
|
|||||||
this.operands = append(this.operands, &op)
|
this.operands = append(this.operands, &op)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Text related operators */
|
||||||
|
|
||||||
|
/* Text state operators */
|
||||||
|
|
||||||
|
// BT: Begin text.
|
||||||
|
func (this *ContentCreator) Add_BT() *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "BT"
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// ET: End text.
|
||||||
|
func (this *ContentCreator) Add_ET() *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "ET"
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tc: Set character spacing.
|
||||||
|
func (this *ContentCreator) Add_Tc(charSpace float64) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "Tc"
|
||||||
|
op.Params = makeParamsFromFloats([]float64{charSpace})
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tw: Set word spacing.
|
||||||
|
func (this *ContentCreator) Add_Tw(wordSpace float64) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "Tw"
|
||||||
|
op.Params = makeParamsFromFloats([]float64{wordSpace})
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tz: Set horizontal scaling.
|
||||||
|
func (this *ContentCreator) Add_Tz(scale float64) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "Tz"
|
||||||
|
op.Params = makeParamsFromFloats([]float64{scale})
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// TL: Set leading.
|
||||||
|
func (this *ContentCreator) Add_Tl(leading float64) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "Tl"
|
||||||
|
op.Params = makeParamsFromFloats([]float64{leading})
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tf: Set font and font size.
|
||||||
|
func (this *ContentCreator) Add_Tf(fontName PdfObjectName, fontSize float64) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "Tf"
|
||||||
|
op.Params = makeParamsFromNames([]PdfObjectName{fontName})
|
||||||
|
op.Params = append(op.Params, makeParamsFromFloats([]float64{fontSize})...)
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tr: Set text rendering mode.
|
||||||
|
func (this *ContentCreator) Add_Tr(render int64) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "Tr"
|
||||||
|
op.Params = makeParamsFromInts([]int64{render})
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ts: Set text rise.
|
||||||
|
func (this *ContentCreator) Add_Ts(rise float64) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "Ts"
|
||||||
|
op.Params = makeParamsFromFloats([]float64{rise})
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text positioning operators. */
|
||||||
|
|
||||||
|
// Td: Move to start of next line with offset (tx, ty).
|
||||||
|
func (this *ContentCreator) Add_Td(tx, ty float64) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "Td"
|
||||||
|
op.Params = makeParamsFromFloats([]float64{tx, ty})
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// TD: Move to start of next line with offset (tx, ty).
|
||||||
|
func (this *ContentCreator) Add_TD(tx, ty float64) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "TD"
|
||||||
|
op.Params = makeParamsFromFloats([]float64{tx, ty})
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tm: Set the text line matrix.
|
||||||
|
func (this *ContentCreator) Add_Tm(a, b, c, d, e, f float64) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "Tm"
|
||||||
|
op.Params = makeParamsFromFloats([]float64{a, b, c, d, e, f})
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// T*: Move to the start of next line.
|
||||||
|
func (this *ContentCreator) Add_Tstar() *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "T*"
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text showing operators */
|
||||||
|
|
||||||
|
// Tj: Show a text string.
|
||||||
|
func (this *ContentCreator) Add_Tj(textstr PdfObjectString) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "Tj"
|
||||||
|
op.Params = makeParamsFromStrings([]PdfObjectString{textstr})
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// ': Move to next line and show a string.
|
||||||
|
func (this *ContentCreator) Add_quote(textstr PdfObjectString) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "'"
|
||||||
|
op.Params = makeParamsFromStrings([]PdfObjectString{textstr})
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// '': Move to next line and show a string, using aw and ac as word and character spacing respectively.
|
||||||
|
func (this *ContentCreator) Add_quotes(textstr PdfObjectString, aw, ac float64) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "''"
|
||||||
|
op.Params = makeParamsFromFloats([]float64{aw, ac})
|
||||||
|
op.Params = append(op.Params, makeParamsFromStrings([]PdfObjectString{textstr})...)
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
// TJ. Show one or more text string. Array of numbers (displacement) and strings.
|
||||||
|
func (this *ContentCreator) Add_TJ(vals ...PdfObject) *ContentCreator {
|
||||||
|
op := ContentStreamOperation{}
|
||||||
|
op.Operand = "TJ"
|
||||||
|
op.Params = vals
|
||||||
|
this.operands = append(this.operands, &op)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
@ -23,6 +23,14 @@ func makeParamsFromNames(vals []PdfObjectName) []PdfObject {
|
|||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeParamsFromStrings(vals []PdfObjectString) []PdfObject {
|
||||||
|
params := []PdfObject{}
|
||||||
|
for _, val := range vals {
|
||||||
|
params = append(params, MakeString(string(val)))
|
||||||
|
}
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
func makeParamsFromInts(vals []int64) []PdfObject {
|
func makeParamsFromInts(vals []int64) []PdfObject {
|
||||||
params := []PdfObject{}
|
params := []PdfObject{}
|
||||||
for _, val := range vals {
|
for _, val := range vals {
|
||||||
|
@ -554,6 +554,26 @@ func (this *PdfPage) HasImageResource(name PdfObjectName) bool {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if has font resource by name.
|
||||||
|
func (this *PdfPage) HasFontByName(name PdfObjectName) bool {
|
||||||
|
resources, err := this.GetResources()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fontDict, has := resources.Font.(*PdfObjectDictionary)
|
||||||
|
if !has {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, has := (*fontDict)[name]; has {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a graphics state to the XObject resources.
|
// Add a graphics state to the XObject resources.
|
||||||
|
@ -15,8 +15,7 @@ import (
|
|||||||
// Page resources model.
|
// Page resources model.
|
||||||
// Implements PdfModel.
|
// Implements PdfModel.
|
||||||
type PdfPageResources struct {
|
type PdfPageResources struct {
|
||||||
ExtGState PdfObject
|
ExtGState PdfObject
|
||||||
//ColorSpace PdfObject
|
|
||||||
ColorSpace *PdfPageResourcesColorspaces
|
ColorSpace *PdfPageResourcesColorspaces
|
||||||
Pattern PdfObject
|
Pattern PdfObject
|
||||||
Shading PdfObject
|
Shading PdfObject
|
||||||
|
Loading…
x
Reference in New Issue
Block a user