When I am drawing rectangles with the same or diferent opacity in the same page and multiple times, I am not getting the same result. The problem seems to happen when the library is traying to calculate the right color of the intersection of shapes.
Here I am adding a project to reproduce the problem. As you can see, It produces 10 documents and there is not always the same output. I am executing the code in:
openjdk version “11.0.16.1” or openjdk 17.0.5
package com.mycompany.asposeissues;
import com.aspose.pdf.*;
import com.aspose.pdf.drawing.Graph;
import com.aspose.pdf.drawing.Rectangle;
import com.mycompany.asposeissues.util.RandomUtilities;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public class Main {
private static final Color COLOR = Color.fromArgb(51, 0, 0, 255);
public static void main(String[] args) throws Exception {
Locale.setDefault(Locale.US);
// Initialize Aspose Pdf License
final var pdfLicense = new License();
final var stream =
Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream("Aspose.Total.Product.Family.lic");
pdfLicense.setLicense(stream);
var document = new Document();
var page1 = document.getPages().add();
drawRectangles(page1, generateNRectangles(page1, 30));
document.save("./test.pdf");
var randomRectangles = generateNRectangles(page1, 30);
for (int i = 0; i < 10; i++) {
document = new Document("./test.pdf");
page1 = document.getPages().get_Item(1);
drawRectangles(page1, randomRectangles);
document.save("random" + i + ".pdf");
}
}
private static List<Rectangle2D.Double> generateNRectangles(Page page, int count) {
var pageWidth = (float) page.getPageRect(true).getWidth();
var pageHeight = (float) page.getPageRect(true).getHeight();
List<Rectangle2D.Double> rectangles = new ArrayList<>();
for (int i = 0; i < count; i++) {
rectangles.add(RandomUtilities.generateRectangle(pageWidth, pageHeight, 50));
}
return rectangles;
}
private static void drawRectangles(Page page, List<Rectangle2D.Double> rectangles) {
final var pageInfo = page.getPageInfo();
final var marginInfo = page.getPageInfo().getMargin();
var graph = new Graph(
(float) (pageInfo.getWidth()),
(float) (pageInfo.getHeight()));
graph.setLeft(marginInfo.getLeft() * -1);
graph.setTop(marginInfo.getTop() * -1);
page.getParagraphs().add(graph);
for (var rect : rectangles) {
final var rectangle = new Rectangle((float) rect.getX(), (float) rect.getY(), (float) rect.getWidth(), (float) rect.getHeight());
rectangle.getGraphInfo().setFillColor(COLOR);
graph.getShapes().add(rectangle);
}
}
}
package com.mycompany.asposeissues.util;
import java.awt.geom.Rectangle2D;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Random;
public final class RandomUtilities {
public static final double BORDER_TOLERANCE_POINTS = 0.1d;
private static final int MINIMUM_SIZE_OF_RECTANGLE_SIDE = 5;
private static final Random RANDOM = new Random();
public static int getRandomInt(int max) {
return max == 0 ? 0 : RANDOM.nextInt(max);
}
public static int getRandomInt(int min, int max) {
return (int) ((Math.random() * ((max - min) + 1)) + min);
}
public static double getRandomDouble(double min, double max) {
return BigDecimal
.valueOf((Math.abs(RANDOM.nextDouble() * (max - min) + min)))
.setScale(2, RoundingMode.FLOOR)
.floatValue();
}
public static Rectangle2D.Double generateRectangle(float maxWidth, float maxHeight, final int borderFactor) {
if (getRandomInt(100) < borderFactor)
return generateRectangleInBorder(MINIMUM_SIZE_OF_RECTANGLE_SIDE, maxWidth, MINIMUM_SIZE_OF_RECTANGLE_SIDE, maxHeight);
else
return generateRectangleOutsideBorder(MINIMUM_SIZE_OF_RECTANGLE_SIDE, maxWidth, MINIMUM_SIZE_OF_RECTANGLE_SIDE, maxHeight);
}
public static Rectangle2D.Double generateRectangleOutsideBorder(float minWidth, float maxWidth,
float minHeight, float maxHeight) {
final var width = RandomUtilities.getRandomDouble(minWidth, maxWidth - BORDER_TOLERANCE_POINTS);
final var height = RandomUtilities.getRandomDouble(minHeight, maxHeight - BORDER_TOLERANCE_POINTS);
final var x = RandomUtilities.getRandomDouble(0, maxWidth - width - BORDER_TOLERANCE_POINTS);
final var y = RandomUtilities.getRandomDouble(0, maxHeight - height - BORDER_TOLERANCE_POINTS);
return new Rectangle2D.Double(x, y, width, height);
}
public static Rectangle2D.Double generateRectangleInBorder(float minWidth, float maxWidth,
float minHeight, float maxHeight) {
final var border = RandomUtilities.getRandomInt(1, 4);
final var rectangle = generateRectangleOutsideBorder(minWidth, maxWidth, minHeight, maxHeight);
double x = rectangle.x, y = rectangle.y;
switch (border) {
case 1: // Left
x = 0;
break;
case 2: // Top
y = 0;
break;
case 3: // Right
x = Math.max(0f, BigDecimal
.valueOf(maxWidth - rectangle.width - BORDER_TOLERANCE_POINTS) // contemplate rectangle border
.setScale(2, RoundingMode.FLOOR)
.floatValue());
break;
default: // Bottom
y = Math.max(0f, BigDecimal
.valueOf(maxHeight - rectangle.height - BORDER_TOLERANCE_POINTS) // contemplate rectangle border
.setScale(2, RoundingMode.FLOOR)
.floatValue());
break;
}
return new Rectangle2D.Double(x, y, rectangle.width, rectangle.height);
}
}
Here you have some examples
random6.pdf (5.2 KB)
random7.pdf (5.2 KB)
diff.jpg (665.2 KB)