@@ -51,13 +51,15 @@ This file is part of the iText (R) project.
51
51
import com .itextpdf .kernel .pdf .canvas .PdfCanvas ;
52
52
import com .itextpdf .kernel .pdf .canvas .PdfPatternCanvas ;
53
53
import com .itextpdf .kernel .pdf .colorspace .PdfPattern ;
54
+ import com .itextpdf .svg .SvgConstants ;
54
55
import com .itextpdf .svg .SvgConstants .Attributes ;
55
56
import com .itextpdf .svg .SvgConstants .Values ;
56
57
import com .itextpdf .svg .exceptions .SvgLogMessageConstant ;
57
58
import com .itextpdf .svg .renderers .ISvgNodeRenderer ;
58
59
import com .itextpdf .svg .renderers .ISvgPaintServer ;
59
60
import com .itextpdf .svg .renderers .SvgDrawContext ;
60
61
import com .itextpdf .svg .utils .SvgCoordinateUtils ;
62
+ import com .itextpdf .svg .utils .TransformUtils ;
61
63
62
64
import org .slf4j .Logger ;
63
65
import org .slf4j .LoggerFactory ;
@@ -112,12 +114,16 @@ private PdfPattern.Tiling createTilingPattern(SvgDrawContext context,
112
114
return null ;
113
115
}
114
116
115
- // transform user space to target pattern rectangle origin and scale
116
- final AffineTransform patternAffineTransform = context .getCurrentCanvasTransform ();
117
+ // we have to consider transforming an element that use pattern in corresponding with SVG logic
118
+ final AffineTransform patternMatrixTransform = context .getCurrentCanvasTransform ();
119
+
120
+ patternMatrixTransform .concatenate (getPatternTransform ());
121
+
117
122
if (isObjectBoundingBoxInPatternUnits ) {
118
- patternAffineTransform .concatenate (getTransformToUserSpaceOnUse (objectBoundingBox ));
123
+ patternMatrixTransform .concatenate (getTransformToUserSpaceOnUse (objectBoundingBox ));
119
124
}
120
- patternAffineTransform .translate (originalPatternRectangle .getX (), originalPatternRectangle .getY ());
125
+
126
+ patternMatrixTransform .translate (originalPatternRectangle .getX (), originalPatternRectangle .getY ());
121
127
122
128
final float [] viewBoxValues = getViewBoxValues ();
123
129
Rectangle bbox ;
@@ -134,7 +140,7 @@ private PdfPattern.Tiling createTilingPattern(SvgDrawContext context,
134
140
scaleX = CONVERT_COEFF / objectBoundingBox .getWidth ();
135
141
scaleY = CONVERT_COEFF / objectBoundingBox .getHeight ();
136
142
}
137
- patternAffineTransform .scale (scaleX , scaleY );
143
+ patternMatrixTransform .scale (scaleX , scaleY );
138
144
xStep /= scaleX ;
139
145
yStep /= scaleY ;
140
146
}
@@ -149,30 +155,30 @@ private PdfPattern.Tiling createTilingPattern(SvgDrawContext context,
149
155
if (isObjectBoundingBoxInPatternUnits ) {
150
156
double scaleX = CONVERT_COEFF / objectBoundingBox .getWidth ();
151
157
double scaleY = CONVERT_COEFF / objectBoundingBox .getHeight ();
152
- patternAffineTransform .scale (scaleX , scaleY );
158
+ patternMatrixTransform .scale (scaleX , scaleY );
153
159
xStep /= scaleX ;
154
160
yStep /= scaleY ;
155
161
}
156
162
157
163
Rectangle viewBox = new Rectangle (viewBoxValues [0 ], viewBoxValues [1 ], viewBoxValues [2 ], viewBoxValues [3 ]);
158
164
Rectangle appliedViewBox = calculateAppliedViewBox (viewBox , xStep , yStep );
159
165
160
- patternAffineTransform .translate (appliedViewBox .getX (), appliedViewBox .getY ());
166
+ patternMatrixTransform .translate (appliedViewBox .getX (), appliedViewBox .getY ());
161
167
162
168
double scaleX = (double ) appliedViewBox .getWidth () / (double ) viewBox .getWidth ();
163
169
double scaleY = (double ) appliedViewBox .getHeight () / (double ) viewBox .getHeight ();
164
- patternAffineTransform .scale (scaleX , scaleY );
170
+ patternMatrixTransform .scale (scaleX , scaleY );
165
171
xStep /= scaleX ;
166
172
yStep /= scaleY ;
167
173
168
- patternAffineTransform .translate (-viewBox .getX (), -viewBox .getY ());
174
+ patternMatrixTransform .translate (-viewBox .getX (), -viewBox .getY ());
169
175
170
176
double bboxXOriginal = viewBox .getX () - appliedViewBox .getX () / scaleX ;
171
177
double bboxYOriginal = viewBox .getY () - appliedViewBox .getY () / scaleY ;
172
178
bbox = new Rectangle ((float ) bboxXOriginal , (float ) bboxYOriginal , (float ) xStep , (float ) yStep );
173
179
}
174
180
175
- return createColoredTilingPatternInstance (patternAffineTransform , bbox , xStep , yStep );
181
+ return createColoredTilingPatternInstance (patternMatrixTransform , bbox , xStep , yStep );
176
182
}
177
183
178
184
private Rectangle calculateAppliedViewBox (Rectangle viewBox , double xStep , double yStep ) {
@@ -308,4 +314,12 @@ private static boolean isViewBoxInvalid(float[] viewBoxValues) {
308
314
return false ;
309
315
}
310
316
}
317
+
318
+ private AffineTransform getPatternTransform () {
319
+ String patternTransform = getAttribute (SvgConstants .Attributes .PATTERN_TRANSFORM );
320
+ if (patternTransform != null && !patternTransform .isEmpty ()) {
321
+ return TransformUtils .parseTransform (patternTransform );
322
+ }
323
+ return new AffineTransform ();
324
+ }
311
325
}
0 commit comments