github.com/phpdave11/gofpdf@v1.4.2/fpdftrans.go (about) 1 package gofpdf 2 3 import ( 4 "fmt" 5 "math" 6 ) 7 8 // Routines in this file are translated from the work of Moritz Wagner and 9 // Andreas Würmser. 10 11 // TransformMatrix is used for generalized transformations of text, drawings 12 // and images. 13 type TransformMatrix struct { 14 A, B, C, D, E, F float64 15 } 16 17 // TransformBegin sets up a transformation context for subsequent text, 18 // drawings and images. The typical usage is to immediately follow a call to 19 // this method with a call to one or more of the transformation methods such as 20 // TransformScale(), TransformSkew(), etc. This is followed by text, drawing or 21 // image output and finally a call to TransformEnd(). All transformation 22 // contexts must be properly ended prior to outputting the document. 23 func (f *Fpdf) TransformBegin() { 24 f.transformNest++ 25 f.out("q") 26 } 27 28 // TransformScaleX scales the width of the following text, drawings and images. 29 // scaleWd is the percentage scaling factor. (x, y) is center of scaling. 30 // 31 // The TransformBegin() example demonstrates this method. 32 func (f *Fpdf) TransformScaleX(scaleWd, x, y float64) { 33 f.TransformScale(scaleWd, 100, x, y) 34 } 35 36 // TransformScaleY scales the height of the following text, drawings and 37 // images. scaleHt is the percentage scaling factor. (x, y) is center of 38 // scaling. 39 // 40 // The TransformBegin() example demonstrates this method. 41 func (f *Fpdf) TransformScaleY(scaleHt, x, y float64) { 42 f.TransformScale(100, scaleHt, x, y) 43 } 44 45 // TransformScaleXY uniformly scales the width and height of the following 46 // text, drawings and images. s is the percentage scaling factor for both width 47 // and height. (x, y) is center of scaling. 48 // 49 // The TransformBegin() example demonstrates this method. 50 func (f *Fpdf) TransformScaleXY(s, x, y float64) { 51 f.TransformScale(s, s, x, y) 52 } 53 54 // TransformScale generally scales the following text, drawings and images. 55 // scaleWd and scaleHt are the percentage scaling factors for width and height. 56 // (x, y) is center of scaling. 57 // 58 // The TransformBegin() example demonstrates this method. 59 func (f *Fpdf) TransformScale(scaleWd, scaleHt, x, y float64) { 60 if scaleWd == 0 || scaleHt == 0 { 61 f.err = fmt.Errorf("scale factor cannot be zero") 62 return 63 } 64 y = (f.h - y) * f.k 65 x *= f.k 66 scaleWd /= 100 67 scaleHt /= 100 68 f.Transform(TransformMatrix{scaleWd, 0, 0, 69 scaleHt, x * (1 - scaleWd), y * (1 - scaleHt)}) 70 } 71 72 // TransformMirrorHorizontal horizontally mirrors the following text, drawings 73 // and images. x is the axis of reflection. 74 // 75 // The TransformBegin() example demonstrates this method. 76 func (f *Fpdf) TransformMirrorHorizontal(x float64) { 77 f.TransformScale(-100, 100, x, f.y) 78 } 79 80 // TransformMirrorVertical vertically mirrors the following text, drawings and 81 // images. y is the axis of reflection. 82 // 83 // The TransformBegin() example demonstrates this method. 84 func (f *Fpdf) TransformMirrorVertical(y float64) { 85 f.TransformScale(100, -100, f.x, y) 86 } 87 88 // TransformMirrorPoint symmetrically mirrors the following text, drawings and 89 // images on the point specified by (x, y). 90 // 91 // The TransformBegin() example demonstrates this method. 92 func (f *Fpdf) TransformMirrorPoint(x, y float64) { 93 f.TransformScale(-100, -100, x, y) 94 } 95 96 // TransformMirrorLine symmetrically mirrors the following text, drawings and 97 // images on the line defined by angle and the point (x, y). angles is 98 // specified in degrees and measured counter-clockwise from the 3 o'clock 99 // position. 100 // 101 // The TransformBegin() example demonstrates this method. 102 func (f *Fpdf) TransformMirrorLine(angle, x, y float64) { 103 f.TransformScale(-100, 100, x, y) 104 f.TransformRotate(-2*(angle-90), x, y) 105 } 106 107 // TransformTranslateX moves the following text, drawings and images 108 // horizontally by the amount specified by tx. 109 // 110 // The TransformBegin() example demonstrates this method. 111 func (f *Fpdf) TransformTranslateX(tx float64) { 112 f.TransformTranslate(tx, 0) 113 } 114 115 // TransformTranslateY moves the following text, drawings and images vertically 116 // by the amount specified by ty. 117 // 118 // The TransformBegin() example demonstrates this method. 119 func (f *Fpdf) TransformTranslateY(ty float64) { 120 f.TransformTranslate(0, ty) 121 } 122 123 // TransformTranslate moves the following text, drawings and images 124 // horizontally and vertically by the amounts specified by tx and ty. 125 // 126 // The TransformBegin() example demonstrates this method. 127 func (f *Fpdf) TransformTranslate(tx, ty float64) { 128 f.Transform(TransformMatrix{1, 0, 0, 1, tx * f.k, -ty * f.k}) 129 } 130 131 // TransformRotate rotates the following text, drawings and images around the 132 // center point (x, y). angle is specified in degrees and measured 133 // counter-clockwise from the 3 o'clock position. 134 // 135 // The TransformBegin() example demonstrates this method. 136 func (f *Fpdf) TransformRotate(angle, x, y float64) { 137 y = (f.h - y) * f.k 138 x *= f.k 139 angle = angle * math.Pi / 180 140 var tm TransformMatrix 141 tm.A = math.Cos(angle) 142 tm.B = math.Sin(angle) 143 tm.C = -tm.B 144 tm.D = tm.A 145 tm.E = x + tm.B*y - tm.A*x 146 tm.F = y - tm.A*y - tm.B*x 147 f.Transform(tm) 148 } 149 150 // TransformSkewX horizontally skews the following text, drawings and images 151 // keeping the point (x, y) stationary. angleX ranges from -90 degrees (skew to 152 // the left) to 90 degrees (skew to the right). 153 // 154 // The TransformBegin() example demonstrates this method. 155 func (f *Fpdf) TransformSkewX(angleX, x, y float64) { 156 f.TransformSkew(angleX, 0, x, y) 157 } 158 159 // TransformSkewY vertically skews the following text, drawings and images 160 // keeping the point (x, y) stationary. angleY ranges from -90 degrees (skew to 161 // the bottom) to 90 degrees (skew to the top). 162 // 163 // The TransformBegin() example demonstrates this method. 164 func (f *Fpdf) TransformSkewY(angleY, x, y float64) { 165 f.TransformSkew(0, angleY, x, y) 166 } 167 168 // TransformSkew generally skews the following text, drawings and images 169 // keeping the point (x, y) stationary. angleX ranges from -90 degrees (skew to 170 // the left) to 90 degrees (skew to the right). angleY ranges from -90 degrees 171 // (skew to the bottom) to 90 degrees (skew to the top). 172 // 173 // The TransformBegin() example demonstrates this method. 174 func (f *Fpdf) TransformSkew(angleX, angleY, x, y float64) { 175 if angleX <= -90 || angleX >= 90 || angleY <= -90 || angleY >= 90 { 176 f.err = fmt.Errorf("skew values must be between -90° and 90°") 177 return 178 } 179 x *= f.k 180 y = (f.h - y) * f.k 181 var tm TransformMatrix 182 tm.A = 1 183 tm.B = math.Tan(angleY * math.Pi / 180) 184 tm.C = math.Tan(angleX * math.Pi / 180) 185 tm.D = 1 186 tm.E = -tm.C * y 187 tm.F = -tm.B * x 188 f.Transform(tm) 189 } 190 191 // Transform generally transforms the following text, drawings and images 192 // according to the specified matrix. It is typically easier to use the various 193 // methods such as TransformRotate() and TransformMirrorVertical() instead. 194 func (f *Fpdf) Transform(tm TransformMatrix) { 195 if f.transformNest > 0 { 196 f.outf("%.5f %.5f %.5f %.5f %.5f %.5f cm", 197 tm.A, tm.B, tm.C, tm.D, tm.E, tm.F) 198 } else if f.err == nil { 199 f.err = fmt.Errorf("transformation context is not active") 200 } 201 } 202 203 // TransformEnd applies a transformation that was begun with a call to TransformBegin(). 204 // 205 // The TransformBegin() example demonstrates this method. 206 func (f *Fpdf) TransformEnd() { 207 if f.transformNest > 0 { 208 f.transformNest-- 209 f.out("Q") 210 } else { 211 f.err = fmt.Errorf("error attempting to end transformation operation out of sequence") 212 } 213 }