123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- package gofpdf
- import (
- "fmt"
- "math"
- )
- // Routines in this file are translated from the work of Moritz Wagner and
- // Andreas Würmser.
- // TransformMatrix is used for generalized transformations of text, drawings
- // and images.
- type TransformMatrix struct {
- A, B, C, D, E, F float64
- }
- // TransformBegin sets up a transformation context for subsequent text,
- // drawings and images. The typical usage is to immediately follow a call to
- // this method with a call to one or more of the transformation methods such as
- // TransformScale(), TransformSkew(), etc. This is followed by text, drawing or
- // image output and finally a call to TransformEnd(). All transformation
- // contexts must be properly ended prior to outputting the document.
- func (f *Fpdf) TransformBegin() {
- f.transformNest++
- f.out("q")
- }
- // TransformScaleX scales the width of the following text, drawings and images.
- // scaleWd is the percentage scaling factor. (x, y) is center of scaling.
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformScaleX(scaleWd, x, y float64) {
- f.TransformScale(scaleWd, 100, x, y)
- }
- // TransformScaleY scales the height of the following text, drawings and
- // images. scaleHt is the percentage scaling factor. (x, y) is center of
- // scaling.
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformScaleY(scaleHt, x, y float64) {
- f.TransformScale(100, scaleHt, x, y)
- }
- // TransformScaleXY uniformly scales the width and height of the following
- // text, drawings and images. s is the percentage scaling factor for both width
- // and height. (x, y) is center of scaling.
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformScaleXY(s, x, y float64) {
- f.TransformScale(s, s, x, y)
- }
- // TransformScale generally scales the following text, drawings and images.
- // scaleWd and scaleHt are the percentage scaling factors for width and height.
- // (x, y) is center of scaling.
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformScale(scaleWd, scaleHt, x, y float64) {
- if scaleWd == 0 || scaleHt == 0 {
- f.err = fmt.Errorf("scale factor cannot be zero")
- return
- }
- y = (f.h - y) * f.k
- x *= f.k
- scaleWd /= 100
- scaleHt /= 100
- f.Transform(TransformMatrix{scaleWd, 0, 0,
- scaleHt, x * (1 - scaleWd), y * (1 - scaleHt)})
- }
- // TransformMirrorHorizontal horizontally mirrors the following text, drawings
- // and images. x is the axis of reflection.
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformMirrorHorizontal(x float64) {
- f.TransformScale(-100, 100, x, f.y)
- }
- // TransformMirrorVertical vertically mirrors the following text, drawings and
- // images. y is the axis of reflection.
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformMirrorVertical(y float64) {
- f.TransformScale(100, -100, f.x, y)
- }
- // TransformMirrorPoint symmetrically mirrors the following text, drawings and
- // images on the point specified by (x, y).
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformMirrorPoint(x, y float64) {
- f.TransformScale(-100, -100, x, y)
- }
- // TransformMirrorLine symmetrically mirrors the following text, drawings and
- // images on the line defined by angle and the point (x, y). angles is
- // specified in degrees and measured counter-clockwise from the 3 o'clock
- // position.
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformMirrorLine(angle, x, y float64) {
- f.TransformScale(-100, 100, x, y)
- f.TransformRotate(-2*(angle-90), x, y)
- }
- // TransformTranslateX moves the following text, drawings and images
- // horizontally by the amount specified by tx.
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformTranslateX(tx float64) {
- f.TransformTranslate(tx, 0)
- }
- // TransformTranslateY moves the following text, drawings and images vertically
- // by the amount specified by ty.
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformTranslateY(ty float64) {
- f.TransformTranslate(0, ty)
- }
- // TransformTranslate moves the following text, drawings and images
- // horizontally and vertically by the amounts specified by tx and ty.
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformTranslate(tx, ty float64) {
- f.Transform(TransformMatrix{1, 0, 0, 1, tx * f.k, -ty * f.k})
- }
- // TransformRotate rotates the following text, drawings and images around the
- // center point (x, y). angle is specified in degrees and measured
- // counter-clockwise from the 3 o'clock position.
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformRotate(angle, x, y float64) {
- y = (f.h - y) * f.k
- x *= f.k
- angle = angle * math.Pi / 180
- var tm TransformMatrix
- tm.A = math.Cos(angle)
- tm.B = math.Sin(angle)
- tm.C = -tm.B
- tm.D = tm.A
- tm.E = x + tm.B*y - tm.A*x
- tm.F = y - tm.A*y - tm.B*x
- f.Transform(tm)
- }
- // TransformSkewX horizontally skews the following text, drawings and images
- // keeping the point (x, y) stationary. angleX ranges from -90 degrees (skew to
- // the left) to 90 degrees (skew to the right).
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformSkewX(angleX, x, y float64) {
- f.TransformSkew(angleX, 0, x, y)
- }
- // TransformSkewY vertically skews the following text, drawings and images
- // keeping the point (x, y) stationary. angleY ranges from -90 degrees (skew to
- // the bottom) to 90 degrees (skew to the top).
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformSkewY(angleY, x, y float64) {
- f.TransformSkew(0, angleY, x, y)
- }
- // TransformSkew generally skews the following text, drawings and images
- // keeping the point (x, y) stationary. angleX ranges from -90 degrees (skew to
- // the left) to 90 degrees (skew to the right). angleY ranges from -90 degrees
- // (skew to the bottom) to 90 degrees (skew to the top).
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformSkew(angleX, angleY, x, y float64) {
- if angleX <= -90 || angleX >= 90 || angleY <= -90 || angleY >= 90 {
- f.err = fmt.Errorf("skew values must be between -90° and 90°")
- return
- }
- x *= f.k
- y = (f.h - y) * f.k
- var tm TransformMatrix
- tm.A = 1
- tm.B = math.Tan(angleY * math.Pi / 180)
- tm.C = math.Tan(angleX * math.Pi / 180)
- tm.D = 1
- tm.E = -tm.C * y
- tm.F = -tm.B * x
- f.Transform(tm)
- }
- // Transform generally transforms the following text, drawings and images
- // according to the specified matrix. It is typically easier to use the various
- // methods such as TransformRotate() and TransformMirrorVertical() instead.
- func (f *Fpdf) Transform(tm TransformMatrix) {
- if f.transformNest > 0 {
- f.outf("%.5f %.5f %.5f %.5f %.5f %.5f cm",
- tm.A, tm.B, tm.C, tm.D, tm.E, tm.F)
- } else if f.err == nil {
- f.err = fmt.Errorf("transformation context is not active")
- }
- }
- // TransformEnd applies a transformation that was begun with a call to TransformBegin().
- //
- // The TransformBegin() example demonstrates this method.
- func (f *Fpdf) TransformEnd() {
- if f.transformNest > 0 {
- f.transformNest--
- f.out("Q")
- } else {
- f.err = fmt.Errorf("error attempting to end transformation operation out of sequence")
- }
- }
|