/** * This method creates {@link AffineTransform} instance that could be used * to transform content inside the occupied area, * considering the centre of the occupiedArea as the origin of a coordinate system for transformation. * * @return {@link AffineTransform} that transforms the content and places it inside occupied area. */ private AffineTransform createTransformationInsideOccupiedArea() { Rectangle backgroundArea = applyMargins(occupiedArea.clone().getBBox(), false); float x = backgroundArea.getX(); float y = backgroundArea.getY(); float height = backgroundArea.getHeight(); float width = backgroundArea.getWidth(); AffineTransform transform = AffineTransform.getTranslateInstance(-1 * (x + width / 2), -1 * (y + height / 2)); transform.preConcatenate(Transform.getAffineTransform(this.<Transform>getProperty(Property.TRANSFORM), width, height)); transform.preConcatenate(AffineTransform.getTranslateInstance(x + width / 2, y + height / 2)); return transform; }
/** * This method creates {@link AffineTransform} instance that could be used * to transform content inside the occupied area, * considering the centre of the occupiedArea as the origin of a coordinate system for transformation. * * @return {@link AffineTransform} that transforms the content and places it inside occupied area. */ private AffineTransform createTransformationInsideOccupiedArea() { Rectangle backgroundArea = applyMargins(occupiedArea.clone().getBBox(), false); float x = backgroundArea.getX(); float y = backgroundArea.getY(); float height = backgroundArea.getHeight(); float width = backgroundArea.getWidth(); AffineTransform transform = AffineTransform.getTranslateInstance(-1 * (x + width / 2), -1 * (y + height / 2)); transform.preConcatenate(Transform.getAffineTransform(this.<Transform>getProperty(Property.TRANSFORM), width, height)); transform.preConcatenate(AffineTransform.getTranslateInstance(x + width / 2, y + height / 2)); return transform; }
/** * Converts the {@link Transform} instance, i.e. the list of {@link SingleTransform} instances, * to the equivalent {@link AffineTransform} instance relatively to the available area, * including resolving of percent values to point values. * * @param t a {@link Transform} instance to convert * @param width the width of available area, the point value of which is equivalent to 100% for percentage resolving * @param height the height of available area, the point value of which is equivalent to 100% for percentage resolving */ public static AffineTransform getAffineTransform(Transform t, float width, float height) { List<SingleTransform> multipleTransform = t.getMultipleTransform(); AffineTransform affineTransform = new AffineTransform(); for (int k = multipleTransform.size() - 1; k >= 0; k--) { SingleTransform transform = multipleTransform.get(k); float[] floats = new float[6]; for (int i = 0; i < 4; i++) floats[i] = transform.getFloats()[i]; for (int i = 4; i < 6; i++) floats[i] = transform.getUnitValues()[i - 4].getUnitType() == UnitValue.POINT ? transform.getUnitValues()[i - 4].getValue() : transform.getUnitValues()[i - 4].getValue() / 100 * (i == 4 ? width : height); affineTransform.preConcatenate(new AffineTransform(floats)); } return affineTransform; }
/** * Converts the {@link Transform} instance, i.e. the list of {@link SingleTransform} instances, * to the equivalent {@link AffineTransform} instance relatively to the available area, * including resolving of percent values to point values. * * @param t a {@link Transform} instance to convert * @param width the width of available area, the point value of which is equivalent to 100% for percentage resolving * @param height the height of available area, the point value of which is equivalent to 100% for percentage resolving */ public static AffineTransform getAffineTransform(Transform t, float width, float height) { List<SingleTransform> multipleTransform = t.getMultipleTransform(); AffineTransform affineTransform = new AffineTransform(); for (int k = multipleTransform.size() - 1; k >= 0; k--) { SingleTransform transform = multipleTransform.get(k); float[] floats = new float[6]; for (int i = 0; i < 4; i++) floats[i] = transform.getFloats()[i]; for (int i = 4; i < 6; i++) floats[i] = transform.getUnitValues()[i - 4].getUnitType() == UnitValue.POINT ? transform.getUnitValues()[i - 4].getValue() : transform.getUnitValues()[i - 4].getValue() / 100 * (i == 4 ? width : height); affineTransform.preConcatenate(new AffineTransform(floats)); } return affineTransform; }
/** * This method creates {@link AffineTransform} instance that could be used * to rotate content inside the occupied area. Be aware that it should be used only after * layout rendering is finished and correct occupied area for the rotated element is calculated. * * @return {@link AffineTransform} that rotates the content and places it inside occupied area. */ protected AffineTransform createRotationTransformInsideOccupiedArea() { Float angle = this.<Float>getProperty(Property.ROTATION_ANGLE); AffineTransform rotationTransform = AffineTransform.getRotateInstance((float) angle); Rectangle contentBox = this.getOccupiedAreaBBox(); List<Point> rotatedContentBoxPoints = transformPoints(rectangleToPointsList(contentBox), rotationTransform); // Occupied area for rotated elements is already calculated on layout in such way to enclose rotated content; // therefore we can simply rotate content as is and then shift it to the occupied area. float[] shift = calculateShiftToPositionBBoxOfPointsAt(occupiedArea.getBBox().getLeft(), occupiedArea.getBBox().getTop(), rotatedContentBoxPoints); rotationTransform.preConcatenate(AffineTransform.getTranslateInstance(shift[0], shift[1])); return rotationTransform; }
/** * This method creates {@link AffineTransform} instance that could be used * to rotate content inside the occupied area. Be aware that it should be used only after * layout rendering is finished and correct occupied area for the rotated element is calculated. * * @return {@link AffineTransform} that rotates the content and places it inside occupied area. */ protected AffineTransform createRotationTransformInsideOccupiedArea() { Float angle = this.<Float>getProperty(Property.ROTATION_ANGLE); AffineTransform rotationTransform = AffineTransform.getRotateInstance((float) angle); Rectangle contentBox = this.getOccupiedAreaBBox(); List<Point> rotatedContentBoxPoints = transformPoints(rectangleToPointsList(contentBox), rotationTransform); // Occupied area for rotated elements is already calculated on layout in such way to enclose rotated content; // therefore we can simply rotate content as is and then shift it to the occupied area. float[] shift = calculateShiftToPositionBBoxOfPointsAt(occupiedArea.getBBox().getLeft(), occupiedArea.getBBox().getTop(), rotatedContentBoxPoints); rotationTransform.preConcatenate(AffineTransform.getTranslateInstance(shift[0], shift[1])); return rotationTransform; }
float scaleX = transformedRect.getWidth() == 0 ? 1 : annotBBox.getWidth() / transformedRect.getWidth(); float scaleY = transformedRect.getHeight() == 0 ? 1 : annotBBox.getHeight() / transformedRect.getHeight(); at.preConcatenate(AffineTransform.getScaleInstance(scaleX, scaleY)); at.preConcatenate(AffineTransform.getTranslateInstance(annotBBox.getX(), annotBBox.getY()));
float scaleX = transformedRect.getWidth() == 0 ? 1 : annotBBox.getWidth() / transformedRect.getWidth(); float scaleY = transformedRect.getHeight() == 0 ? 1 : annotBBox.getHeight() / transformedRect.getHeight(); at.preConcatenate(AffineTransform.getScaleInstance(scaleX, scaleY)); at.preConcatenate(AffineTransform.getTranslateInstance(annotBBox.getX(), annotBBox.getY()));