-
Notifications
You must be signed in to change notification settings - Fork 52
Description
When testing with different diagrams, we noticed some inconsistencies when drawing on the non-diagram layers. Simple Workflow was:
1.Get bounds from a figure on the diagram layer
2. Translate bounds to FEEDBACK_LAYER
3. Use translated bounds to create an overlay figure on feedback layer
In most cases it worked correctly, but there were multiple cases, where the figure on the feedback layer was rendered a bit shifted. When having a look into it, the reason was quite obvious - rounding issues caused by Translatable#performScale. You'll find a simple snippet to see the difference when using a Translatable with and without precision.
For the Snippet the output is:
Start Bounds 10/10 52/52
Bounds 17/17 92/92
Precision Bounds 17/17 91/91
--------------------------------------------------------------------------------------------------------------
Start Bounds 10/52 52/52
Bounds 17/91 92/91
Precision Bounds 17/91 91/91
--------------------------------------------------------------------------------------------------------------
Start Bounds 52/10 52/52
Bounds 91/17 91/92
Precision Bounds 91/17 91/91
--------------------------------------------------------------------------------------------------------------
Start Bounds 52/52 52/52
Bounds 91/91 91/91
Precision Bounds 91/91 91/91
--------------------------------------------------------------------------------------------------------------
Question from me is, can we do something about it? With the additional monitor scale layer these rounding issues will become more visible, because you have up to two different layers with two separate roundings involved. Looking at the call hierarchy the only callers of Translatable#performScale are IScalablePaneHelper#translateToParent and IScalablePaneHelper#translateFromParent.
import org.eclipse.draw2d.geometry.PrecisionRectangle;
import org.eclipse.draw2d.geometry.Rectangle;
public class TranslationRoundingExample {
public static void main(String[] args) {
Figure root = new Figure();
root.setBounds(new Rectangle(0, 0, 1200, 1200));
root.setBounds(new Rectangle(0, 0, 100, 100));
ScalableFigure f1 = new ScalableLayeredPane();
f1.setBounds(new Rectangle(0, 0, 100, 100));
f1.setScale(1.75f);
IFigure f2 = new Figure();
root.add(f1);
f1.add(f2);
calculateAndPrint(f2, new Rectangle(10, 10, 52, 52));
calculateAndPrint(f2, new Rectangle(10, 52, 52, 52));
calculateAndPrint(f2, new Rectangle(52, 10, 52, 52));
calculateAndPrint(f2, new Rectangle(52, 52, 52, 52));
}
private static void calculateAndPrint(IFigure f2, Rectangle startBounds) {
Rectangle bounds = startBounds.getCopy();
f2.translateToAbsolute(bounds);
Rectangle precisionBounds = new PrecisionRectangle(startBounds.getCopy());
f2.translateToAbsolute(precisionBounds);
System.out.println(String.format("Start Bounds %s/%s %s/%s", startBounds.x(), startBounds.y(),
startBounds.width(), startBounds.height()));
System.out
.println(String.format("Bounds %s/%s %s/%s", bounds.x(), bounds.y(), bounds.width(), bounds.height()));
System.out.println(String.format("Precision Bounds %s/%s %s/%s", precisionBounds.x(), precisionBounds.y(),
precisionBounds.width(), precisionBounds.height()));
System.out.println(
"--------------------------------------------------------------------------------------------------------------");
}
}