From b18f699d7b80e81fb937b6cbc09e5adee40a3bb8 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Thu, 24 Oct 2019 15:11:20 +0200
Subject: [PATCH] drawing of compartments uses border color, fill color, font
 color when necessary

---
 .../converter/graphics/ConverterParams.java   |  2 +-
 .../BottomSquareCompartmentConverter.java     | 63 ++++------------
 .../compartment/CompartmentConverter.java     | 72 ++++++++++++++++++-
 .../LeftSquareCompartmentConverter.java       | 63 ++++------------
 .../compartment/OvalCompartmentConverter.java | 67 +++--------------
 .../PathwayCompartmentConverter.java          |  4 +-
 .../RightSquareCompartmentConverter.java      | 70 ++++--------------
 .../SquareCompartmentConverter.java           | 63 +++-------------
 .../TopSquareCompartmentConverter.java        | 60 ++++------------
 .../graphics/GraphicsTestFunctions.java       | 10 +++
 .../graphics/bioEntity/AllBioEntityTests.java |  4 +-
 .../AllCompartmentConverterTests.java         | 11 +++
 .../PathwayCompartmentConverterTest.java      | 13 +++-
 .../SquareCompartmentConverterTest.java       | 63 ++++++++++++++++
 14 files changed, 239 insertions(+), 326 deletions(-)
 create mode 100644 converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/AllCompartmentConverterTests.java
 create mode 100644 converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/SquareCompartmentConverterTest.java

diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ConverterParams.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ConverterParams.java
index a791fe3f3d..ab6c5478e6 100644
--- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ConverterParams.java
+++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/ConverterParams.java
@@ -9,7 +9,7 @@ package lcsb.mapviewer.converter.graphics;
 public class ConverterParams {
 
   /**
-   * At which level the object is visualized. It helps to deterimine font size.
+   * At which level the object is visualized. It helps to determine font size.
    * However it's possible that this value is not required.
    */
   private int level = 0;
diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/BottomSquareCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/BottomSquareCompartmentConverter.java
index 006764b208..bcc0cbe079 100644
--- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/BottomSquareCompartmentConverter.java
+++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/BottomSquareCompartmentConverter.java
@@ -1,15 +1,12 @@
 package lcsb.mapviewer.converter.graphics.bioEntity.element.compartment;
 
-import java.awt.*;
+import java.awt.Shape;
 import java.awt.geom.*;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import lcsb.mapviewer.commands.ColorExtractor;
-import lcsb.mapviewer.converter.graphics.ConverterParams;
-import lcsb.mapviewer.converter.graphics.DrawingException;
-import lcsb.mapviewer.model.graphics.LineType;
 import lcsb.mapviewer.model.map.compartment.BottomSquareCompartment;
 import lcsb.mapviewer.model.map.layout.ColorSchema;
 import lcsb.mapviewer.model.map.species.Species;
@@ -40,55 +37,19 @@ public class BottomSquareCompartmentConverter extends CompartmentConverter<Botto
   }
 
   @Override
-  protected void drawImpl(final BottomSquareCompartment compartment, final Graphics2D graphics,
-      final ConverterParams params) throws DrawingException {
-    // keep the old values of colors and line
-    Color oldColor = graphics.getColor();
-    Stroke oldStroke = graphics.getStroke();
+  protected Shape getOuterShape(BottomSquareCompartment compartment) {
+    return new Line2D.Double(0, compartment.getY(), compartment.getWidth(), compartment.getY());
+  }
 
-    // create shape of the compartment
-    Shape s1 = new Line2D.Double(0, compartment.getY(), compartment.getWidth(), compartment.getY());
-    Shape s3 = new Line2D.Double(0, compartment.getY() + compartment.getThickness(), compartment.getWidth(),
+  @Override
+  protected Shape getInnerShape(BottomSquareCompartment compartment) {
+    return new Line2D.Double(0, compartment.getY() + compartment.getThickness(), compartment.getWidth(),
         compartment.getY() + compartment.getThickness());
-    Area a1 = new Area(
-        new Rectangle2D.Double(0.0, compartment.getY(), compartment.getWidth(), compartment.getHeight()));
-
-    Color c1 = compartment.getFillColor();
-    Color c2 = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), HIGH_ALPHA_LEVEL);
-    if (c1.equals(Color.WHITE)) {
-      c1 = Color.BLACK;
-    }
-
-    // fill the background
-    boolean fill = !isTransparent(compartment, params);
-    if (fill) {
-      graphics.setColor(c1);
-    } else {
-      Color bgAlphaColor = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), getAlphaLevel());
-      graphics.setColor(bgAlphaColor);
-    }
-    graphics.fill(s1);
-
-    // create borders
-    graphics.setColor(c1);
-    graphics.setStroke(LineType.SOLID_BOLD.getStroke());
-    graphics.draw(s1);
-    graphics.setStroke(LineType.SOLID.getStroke());
-    graphics.draw(s3);
-    graphics.setColor(c2);
-    if (fill) {
-      graphics.fill(a1);
-    }
-    // restore color and line type
-    graphics.setColor(oldColor);
-    graphics.setStroke(oldStroke);
+  }
 
-    // draw description
-    if (fill) {
-      Point2D tmpPoint = compartment.getNamePoint();
-      compartment.setNamePoint(compartment.getCenter());
-      drawText(compartment, graphics, params);
-      compartment.setNamePoint(tmpPoint);
-    }
+  @Override
+  protected Shape getBorderShape(BottomSquareCompartment compartment) {
+    return new Area(new Rectangle2D.Double(0.0, compartment.getY(), compartment.getWidth(), compartment.getHeight()));
   }
+
 }
diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/CompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/CompartmentConverter.java
index 7efa86da7d..55e39c75eb 100644
--- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/CompartmentConverter.java
+++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/CompartmentConverter.java
@@ -1,7 +1,7 @@
 package lcsb.mapviewer.converter.graphics.bioEntity.element.compartment;
 
 import java.awt.*;
-import java.awt.geom.Rectangle2D;
+import java.awt.geom.*;
 import java.util.List;
 
 import org.apache.logging.log4j.LogManager;
@@ -9,6 +9,7 @@ import org.apache.logging.log4j.Logger;
 
 import lcsb.mapviewer.commands.ColorExtractor;
 import lcsb.mapviewer.common.Configuration;
+import lcsb.mapviewer.common.exception.NotImplementedException;
 import lcsb.mapviewer.common.geometry.LineTransformation;
 import lcsb.mapviewer.converter.graphics.ConverterParams;
 import lcsb.mapviewer.converter.graphics.DrawingException;
@@ -16,6 +17,7 @@ import lcsb.mapviewer.converter.graphics.bioEntity.element.ElementConverter;
 import lcsb.mapviewer.converter.graphics.geometry.FontFinder;
 import lcsb.mapviewer.converter.graphics.geometry.RectangleTooSmallException;
 import lcsb.mapviewer.converter.graphics.placefinder.PlaceFinder;
+import lcsb.mapviewer.model.graphics.LineType;
 import lcsb.mapviewer.model.map.compartment.Compartment;
 import lcsb.mapviewer.model.map.layout.ColorSchema;
 import lcsb.mapviewer.modelutils.map.ElementUtils;
@@ -58,7 +60,7 @@ public abstract class CompartmentConverter<T extends Compartment> extends Elemen
    */
   private LineTransformation lineTransformation = new LineTransformation();
   /**
-   * Class used for finding place to draw desciption of the compartment.
+   * Class used for finding place to draw description of the compartment.
    */
   private PlaceFinder placeFinder;
 
@@ -114,6 +116,68 @@ public abstract class CompartmentConverter<T extends Compartment> extends Elemen
     this.lineTransformation = lineTransformation;
   }
 
+  @Override
+  protected void drawImpl(T compartment, Graphics2D graphics, ConverterParams params) throws DrawingException {
+    // keep the old values of color and line type
+    Color oldColor = graphics.getColor();
+    Stroke oldStroke = graphics.getStroke();
+
+    Shape s1 = getOuterShape(compartment);
+    Shape s3 = getInnerShape(compartment);
+    Shape a1 = getBorderShape(compartment);
+
+    Color borderColor = compartment.getBorderColor();
+
+    Color fillColor = compartment.getFillColor();
+
+    // fill the background
+    boolean fill = !isTransparent(compartment, params);
+    if (fill) {
+      graphics.setColor(fillColor);
+    } else {
+      Color bgAlphaColor = new Color(fillColor.getRed(), fillColor.getGreen(), fillColor.getBlue(), getAlphaLevel());
+      graphics.setColor(bgAlphaColor);
+    }
+    graphics.fill(s1);
+
+    // create borders
+    graphics.setColor(borderColor);
+    graphics.setStroke(LineType.SOLID_BOLD.getStroke());
+    graphics.draw(s1);
+    graphics.setStroke(LineType.SOLID.getStroke());
+    graphics.draw(s3);
+
+    fillColor = new Color(fillColor.getRed(), fillColor.getGreen(), fillColor.getBlue(), HIGH_ALPHA_LEVEL);
+    graphics.setColor(fillColor);
+    graphics.fill(a1);
+
+    // restore color and line type
+    graphics.setColor(oldColor);
+    graphics.setStroke(oldStroke);
+
+    // draw description
+    if (fill) {
+      Point2D tmpPoint = compartment.getNamePoint();
+      compartment.setNamePoint(compartment.getCenter());
+      drawText(compartment, graphics, params);
+      compartment.setNamePoint(tmpPoint);
+    }
+  }
+
+  protected Shape getOuterShape(T compartment) {
+    throw new NotImplementedException();
+  }
+
+  protected Shape getInnerShape(T compartment) {
+    throw new NotImplementedException();
+  }
+
+  protected Shape getBorderShape(T compartment) {
+    Area result = new Area(getOuterShape(compartment));
+    result.subtract(new Area(getInnerShape(compartment)));
+    return result;
+  }
+
   @Override
   public void draw(T alias, Graphics2D graphics, ConverterParams params,
       List<ColorSchema> visualizedLayoutsColorSchemas) throws DrawingException {
@@ -172,13 +236,17 @@ public abstract class CompartmentConverter<T extends Compartment> extends Elemen
       fontSize = compartment.getFontSize() * params.getScale();
     }
     String fontName = Font.SANS_SERIF;
+    Color tmpColor = graphics.getColor();
     try {
+      graphics.setColor(compartment.getFontColor());
       fontSize = FontFinder.findMaxFontSize((int) Math.round(fontSize), fontName, graphics, border,
           compartment.getName());
       FontFinder.drawText((int) fontSize, fontName, graphics, border, compartment.getName(), textCentered);
     } catch (RectangleTooSmallException e) {
       // if it's too small then don't draw
       return;
+    } finally {
+      graphics.setColor(tmpColor);
     }
   }
 
diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/LeftSquareCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/LeftSquareCompartmentConverter.java
index ae887428b0..740946931e 100644
--- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/LeftSquareCompartmentConverter.java
+++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/LeftSquareCompartmentConverter.java
@@ -1,15 +1,12 @@
 package lcsb.mapviewer.converter.graphics.bioEntity.element.compartment;
 
-import java.awt.*;
+import java.awt.Shape;
 import java.awt.geom.*;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import lcsb.mapviewer.commands.ColorExtractor;
-import lcsb.mapviewer.converter.graphics.ConverterParams;
-import lcsb.mapviewer.converter.graphics.DrawingException;
-import lcsb.mapviewer.model.graphics.LineType;
 import lcsb.mapviewer.model.map.compartment.LeftSquareCompartment;
 import lcsb.mapviewer.model.map.layout.ColorSchema;
 
@@ -40,56 +37,20 @@ public class LeftSquareCompartmentConverter extends CompartmentConverter<LeftSqu
   }
 
   @Override
-  protected void drawImpl(final LeftSquareCompartment compartment, final Graphics2D graphics,
-      final ConverterParams params) throws DrawingException {
-    // keep the old values of color and line type
-    Color oldColor = graphics.getColor();
-    Stroke oldStroke = graphics.getStroke();
+  protected Shape getOuterShape(LeftSquareCompartment compartment) {
+    return new Line2D.Double(compartment.getWidth(), compartment.getHeight(), compartment.getWidth(), 0);
+  }
 
-    // create shape of the compartment
-    Shape s1 = new Line2D.Double(compartment.getWidth(), compartment.getHeight(), compartment.getWidth(), 0);
-    Shape s3 = new Line2D.Double(
+  @Override
+  protected Shape getInnerShape(LeftSquareCompartment compartment) {
+    return new Line2D.Double(
         compartment.getWidth() - compartment.getThickness(), 0, compartment.getWidth() - compartment.getThickness(),
         compartment.getHeight());
-    Area a1 = new Area(new Rectangle2D.Double(0.0, 0.0, compartment.getWidth(), compartment.getHeight()));
-
-    Color c1 = compartment.getFillColor();
-    Color c2 = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), HIGH_ALPHA_LEVEL);
-    if (c1.equals(Color.WHITE)) {
-      c1 = Color.BLACK;
-    }
-
-    // fill the background
-    boolean fill = !isTransparent(compartment, params);
-    if (fill) {
-      graphics.setColor(c1);
-    } else {
-      Color bgAlphaColor = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), getAlphaLevel());
-      graphics.setColor(bgAlphaColor);
-    }
-    graphics.fill(s1);
-
-    // create borders
-    graphics.setColor(c1);
-    graphics.setStroke(LineType.SOLID_BOLD.getStroke());
-    graphics.draw(s1);
-    graphics.setStroke(LineType.SOLID.getStroke());
-    graphics.draw(s3);
-    graphics.setColor(c2);
-    if (fill) {
-      graphics.fill(a1);
-    }
-
-    // restore color and line type
-    graphics.setColor(oldColor);
-    graphics.setStroke(oldStroke);
+  }
 
-    // draw description
-    if (fill) {
-      Point2D tmpPoint = compartment.getNamePoint();
-      compartment.setNamePoint(compartment.getCenter());
-      drawText(compartment, graphics, params);
-      compartment.setNamePoint(tmpPoint);
-    }
+  @Override
+  protected Shape getBorderShape(LeftSquareCompartment compartment) {
+    return new Area(new Rectangle2D.Double(0.0, 0.0, compartment.getWidth(), compartment.getHeight()));
   }
+
 }
diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/OvalCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/OvalCompartmentConverter.java
index 137197ae93..c2427eca0f 100644
--- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/OvalCompartmentConverter.java
+++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/OvalCompartmentConverter.java
@@ -1,12 +1,9 @@
 package lcsb.mapviewer.converter.graphics.bioEntity.element.compartment;
 
-import java.awt.*;
-import java.awt.geom.*;
+import java.awt.Shape;
+import java.awt.geom.Ellipse2D;
 
 import lcsb.mapviewer.commands.ColorExtractor;
-import lcsb.mapviewer.converter.graphics.ConverterParams;
-import lcsb.mapviewer.converter.graphics.DrawingException;
-import lcsb.mapviewer.model.graphics.LineType;
 import lcsb.mapviewer.model.map.compartment.Compartment;
 import lcsb.mapviewer.model.map.compartment.OvalCompartment;
 import lcsb.mapviewer.model.map.layout.ColorSchema;
@@ -44,61 +41,15 @@ public class OvalCompartmentConverter extends CompartmentConverter<OvalCompartme
   }
 
   @Override
-  protected void drawImpl(final OvalCompartment compartment, final Graphics2D graphics, final ConverterParams params)
-      throws DrawingException {
-    // keep the old values of color and line type
-    Color oldColor = graphics.getColor();
-    Stroke oldStroke = graphics.getStroke();
+  protected Shape getOuterShape(OvalCompartment compartment) {
+    return getShape(compartment);
+  }
 
-    // create shape of the compartment
-    Shape s1 = getShape(compartment);
+  @Override
+  protected Shape getInnerShape(OvalCompartment compartment) {
     compartment.increaseBorder(-compartment.getThickness());
-    Shape s3 = getShape(compartment);
+    Shape result = getShape(compartment);
     compartment.increaseBorder(compartment.getThickness());
-
-    Color c1 = compartment.getFillColor();
-    Color c2 = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), HIGH_ALPHA_LEVEL);
-    if (c1.equals(Color.WHITE)) {
-      c1 = Color.BLACK;
-    }
-
-    Area a1 = new Area(s1);
-    a1.subtract(new Area(s3));
-
-    // fill the background
-    boolean fill = !isTransparent(compartment, params);
-    if (fill) {
-      graphics.setColor(c1);
-    } else {
-      Color bgAlphaColor = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), getAlphaLevel());
-      graphics.setColor(bgAlphaColor);
-    }
-    graphics.fill(s1);
-
-    // create borders
-    graphics.setColor(c1);
-    graphics.setStroke(LineType.SOLID_BOLD.getStroke());
-    graphics.draw(s1);
-    graphics.setStroke(LineType.SOLID.getStroke());
-    graphics.draw(s3);
-    graphics.setColor(c2);
-    graphics.fill(a1);
-
-    // restore color and line type
-    graphics.setColor(oldColor);
-    graphics.setStroke(oldStroke);
-
-    // draw description
-    if (fill) {
-      Point2D tmpPoint = compartment.getNamePoint();
-      compartment.setNamePoint(compartment.getCenter());
-      drawText(compartment, graphics, params);
-      compartment.setNamePoint(tmpPoint);
-    } else {
-      if (!compartment.containsIdenticalSpecies()) {
-        drawText(compartment, graphics, params);
-      }
-    }
+    return result;
   }
-
 }
diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/PathwayCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/PathwayCompartmentConverter.java
index 2a33cb022c..f09140b584 100644
--- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/PathwayCompartmentConverter.java
+++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/PathwayCompartmentConverter.java
@@ -42,7 +42,7 @@ public class PathwayCompartmentConverter extends CompartmentConverter<PathwayCom
     Shape shape = new Rectangle2D.Double(compartment.getX(), compartment.getY(), compartment.getWidth(),
         compartment.getHeight());
 
-    Color color = compartment.getFontColor();
+    Color borderColor = compartment.getBorderColor();
     Color backgroundColor = compartment.getFillColor();
 
     // fill the background
@@ -55,7 +55,7 @@ public class PathwayCompartmentConverter extends CompartmentConverter<PathwayCom
     graphics.fill(shape);
 
     // draw the border
-    graphics.setColor(color);
+    graphics.setColor(borderColor);
     graphics.setStroke(LineType.SOLID_BOLD.getStroke());
     graphics.draw(shape);
 
diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/RightSquareCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/RightSquareCompartmentConverter.java
index 4d7e1f657d..c5e8c0de4d 100644
--- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/RightSquareCompartmentConverter.java
+++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/RightSquareCompartmentConverter.java
@@ -1,15 +1,12 @@
 package lcsb.mapviewer.converter.graphics.bioEntity.element.compartment;
 
-import java.awt.*;
+import java.awt.Shape;
 import java.awt.geom.*;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import lcsb.mapviewer.commands.ColorExtractor;
-import lcsb.mapviewer.converter.graphics.ConverterParams;
-import lcsb.mapviewer.converter.graphics.DrawingException;
-import lcsb.mapviewer.model.graphics.LineType;
 import lcsb.mapviewer.model.map.compartment.RightSquareCompartment;
 import lcsb.mapviewer.model.map.layout.ColorSchema;
 import lcsb.mapviewer.model.map.species.Species;
@@ -40,62 +37,19 @@ public class RightSquareCompartmentConverter extends CompartmentConverter<RightS
   }
 
   @Override
-  protected void drawImpl(final RightSquareCompartment compartment, final Graphics2D graphics,
-      final ConverterParams params) throws DrawingException {
-    // keep the old values of color and line type
-    Color oldColor = graphics.getColor();
-    Stroke oldStroke = graphics.getStroke();
+  protected Shape getOuterShape(RightSquareCompartment compartment) {
+    return new Line2D.Double(compartment.getX(), compartment.getHeight(), compartment.getX(), 0);
+  }
 
-    // create shape of the compartment
-    Shape s1 = new Line2D.Double(compartment.getX(), compartment.getHeight(), compartment.getX(), 0);
-    Shape s3 = new Line2D.Double(compartment.getX() + compartment.getThickness(), compartment.getHeight(),
+  @Override
+  protected Shape getInnerShape(RightSquareCompartment compartment) {
+    return new Line2D.Double(compartment.getX() + compartment.getThickness(), compartment.getHeight(),
         compartment.getX(), 0);
-    Area a1 = new Area(
-        new Rectangle2D.Double(compartment.getX(), 0.0, compartment.getWidth(), compartment.getHeight()));
-
-    Color c1 = compartment.getFillColor();
-    Color c2 = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), HIGH_ALPHA_LEVEL);
-    if (c1.equals(Color.WHITE)) {
-      c1 = Color.BLACK;
-    }
-
-    // fill the background
-    boolean fill = !isTransparent(compartment, params);
-    if (fill) {
-      graphics.setColor(c1);
-    } else {
-      Color bgAlphaColor = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), getAlphaLevel());
-      graphics.setColor(bgAlphaColor);
-    }
-    graphics.fill(s1);
-
-    // create borders
-    graphics.setColor(c1);
-    graphics.setStroke(LineType.SOLID_BOLD.getStroke());
-    graphics.draw(s1);
-    graphics.setStroke(LineType.SOLID.getStroke());
-    graphics.draw(s3);
-    graphics.setColor(c2);
-    if (fill) {
-      graphics.fill(a1);
-    }
-    // restore color and line type
-    graphics.setColor(oldColor);
-    graphics.setStroke(oldStroke);
-
-    // three lines below are only temporary fix...
-    double x = compartment.getNamePoint().getX() - compartment.getX();
-    double y = compartment.getNamePoint().getY();
-    compartment.getNamePoint().setLocation(x, y);
+  }
 
-    // draw description
-    if (fill) {
-      Point2D tmpPoint = compartment.getNamePoint();
-      compartment.setNamePoint(compartment.getCenter());
-      drawText(compartment, graphics, params);
-      compartment.setNamePoint(tmpPoint);
-    }
-    x += compartment.getX();
-    compartment.getNamePoint().setLocation(x, y);
+  @Override
+  protected Shape getBorderShape(RightSquareCompartment compartment) {
+    return new Area(
+        new Rectangle2D.Double(compartment.getX(), 0.0, compartment.getWidth(), compartment.getHeight()));
   }
 }
diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/SquareCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/SquareCompartmentConverter.java
index fc9ea262ff..46b3d36374 100644
--- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/SquareCompartmentConverter.java
+++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/SquareCompartmentConverter.java
@@ -1,15 +1,13 @@
 package lcsb.mapviewer.converter.graphics.bioEntity.element.compartment;
 
-import java.awt.*;
-import java.awt.geom.*;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.geom.RoundRectangle2D;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import lcsb.mapviewer.commands.ColorExtractor;
-import lcsb.mapviewer.converter.graphics.ConverterParams;
-import lcsb.mapviewer.converter.graphics.DrawingException;
-import lcsb.mapviewer.model.graphics.LineType;
 import lcsb.mapviewer.model.map.compartment.Compartment;
 import lcsb.mapviewer.model.map.compartment.SquareCompartment;
 import lcsb.mapviewer.model.map.layout.ColorSchema;
@@ -58,56 +56,15 @@ public class SquareCompartmentConverter extends CompartmentConverter<SquareCompa
   }
 
   @Override
-  protected void drawImpl(final SquareCompartment compartment, final Graphics2D graphics, final ConverterParams params)
-      throws DrawingException {
-    // keep the old values of color and line type
-    Color oldColor = graphics.getColor();
-    Stroke oldStroke = graphics.getStroke();
+  protected Shape getOuterShape(SquareCompartment compartment) {
+    return getShape(compartment);
+  }
 
-    // create shape of the compartment
-    Shape s1 = getShape(compartment);
+  @Override
+  protected Shape getInnerShape(SquareCompartment compartment) {
     compartment.increaseBorder(-compartment.getThickness());
-    Shape s3 = getShape(compartment);
+    Shape result = getShape(compartment);
     compartment.increaseBorder(compartment.getThickness());
-
-    Color c1 = compartment.getFillColor();
-    Color c2 = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), HIGH_ALPHA_LEVEL);
-    if (c1.equals(Color.WHITE)) {
-      c1 = Color.BLACK;
-    }
-
-    Area a1 = new Area(s1);
-    a1.subtract(new Area(s3));
-
-    // fill the background
-    boolean fill = !isTransparent(compartment, params);
-    if (fill) {
-      graphics.setColor(c1);
-    } else {
-      Color bgAlphaColor = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), getAlphaLevel());
-      graphics.setColor(bgAlphaColor);
-    }
-    graphics.fill(s1);
-
-    // create borders
-    graphics.setColor(c1);
-    graphics.setStroke(LineType.SOLID_BOLD.getStroke());
-    graphics.draw(s1);
-    graphics.setStroke(LineType.SOLID.getStroke());
-    graphics.draw(s3);
-    graphics.setColor(c2);
-    graphics.fill(a1);
-
-    // restore color and line type
-    graphics.setColor(oldColor);
-    graphics.setStroke(oldStroke);
-
-    // draw description
-    if (fill) {
-      Point2D tmpPoint = compartment.getNamePoint();
-      compartment.setNamePoint(compartment.getCenter());
-      drawText(compartment, graphics, params);
-      compartment.setNamePoint(tmpPoint);
-    }
+    return result;
   }
 }
diff --git a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/TopSquareCompartmentConverter.java b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/TopSquareCompartmentConverter.java
index 144bcbaa9a..76b9f4bf50 100644
--- a/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/TopSquareCompartmentConverter.java
+++ b/converter-graphics/src/main/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/TopSquareCompartmentConverter.java
@@ -1,15 +1,13 @@
 package lcsb.mapviewer.converter.graphics.bioEntity.element.compartment;
 
-import java.awt.*;
+import java.awt.Graphics2D;
+import java.awt.Shape;
 import java.awt.geom.*;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import lcsb.mapviewer.commands.ColorExtractor;
-import lcsb.mapviewer.converter.graphics.ConverterParams;
-import lcsb.mapviewer.converter.graphics.DrawingException;
-import lcsb.mapviewer.model.graphics.LineType;
 import lcsb.mapviewer.model.map.compartment.TopSquareCompartment;
 import lcsb.mapviewer.model.map.layout.ColorSchema;
 import lcsb.mapviewer.model.map.species.Species;
@@ -40,52 +38,20 @@ public class TopSquareCompartmentConverter extends CompartmentConverter<TopSquar
   }
 
   @Override
-  protected void drawImpl(final TopSquareCompartment compartment, final Graphics2D graphics,
-      final ConverterParams params) throws DrawingException {
-    Color oldColor = graphics.getColor();
-    Stroke oldStroke = graphics.getStroke();
+  protected Shape getOuterShape(TopSquareCompartment compartment) {
+    return new Line2D.Double(0, compartment.getHeight(), compartment.getWidth(), compartment.getHeight());
+  }
 
-    Shape s1 = new Line2D.Double(0, compartment.getHeight(), compartment.getWidth(), compartment.getHeight());
-    Shape s3 = new Line2D.Double(
+  @Override
+  protected Shape getInnerShape(TopSquareCompartment compartment) {
+    return new Line2D.Double(
         0, compartment.getHeight() - compartment.getThickness(), compartment.getWidth(),
         compartment.getHeight() - compartment.getThickness());
-    Area a1 = new Area(new Rectangle2D.Double(0.0, 0.0, compartment.getWidth(), compartment.getHeight()));
-
-    Color c1 = compartment.getFillColor();
-    Color c2 = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), HIGH_ALPHA_LEVEL);
-    if (c1.equals(Color.WHITE)) {
-      c1 = Color.BLACK;
-    }
-
-    // fill the background
-    boolean fill = !isTransparent(compartment, params);
-    if (fill) {
-      graphics.setColor(c1);
-    } else {
-      Color bgAlphaColor = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), getAlphaLevel());
-      graphics.setColor(bgAlphaColor);
-    }
-    graphics.fill(s1);
-
-    graphics.setColor(c1);
-    graphics.setStroke(LineType.SOLID_BOLD.getStroke());
-    graphics.draw(s1);
-    graphics.setStroke(LineType.SOLID.getStroke());
-    graphics.draw(s3);
-    graphics.setColor(c2);
-    if (fill) {
-      graphics.fill(a1);
-    }
+  }
 
-    // restore color and line type
-    graphics.setColor(oldColor);
-    graphics.setStroke(oldStroke);
-    // draw description
-    if (fill) {
-      Point2D tmpPoint = compartment.getNamePoint();
-      compartment.setNamePoint(compartment.getCenter());
-      drawText(compartment, graphics, params);
-      compartment.setNamePoint(tmpPoint);
-    }
+  @Override
+  protected Shape getBorderShape(TopSquareCompartment compartment) {
+    return new Area(new Rectangle2D.Double(0.0, 0.0, compartment.getWidth(), compartment.getHeight()));
   }
+
 }
diff --git a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/GraphicsTestFunctions.java b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/GraphicsTestFunctions.java
index 5cbfae2e29..03878d2b11 100644
--- a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/GraphicsTestFunctions.java
+++ b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/GraphicsTestFunctions.java
@@ -6,6 +6,8 @@ import static org.mockito.Mockito.when;
 import java.awt.*;
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.junit.Rule;
 import org.mockito.Mockito;
@@ -79,4 +81,12 @@ public abstract class GraphicsTestFunctions {
     return complex;
   }
 
+  protected List<Color> removeAlpha(List<Color> allValues) {
+    List<Color> result = new ArrayList<>();
+    for (Color color : allValues) {
+      result.add(new Color(color.getRGB()));
+    }
+    return result;
+  }
+
 }
diff --git a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/AllBioEntityTests.java b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/AllBioEntityTests.java
index ba27b1c2f4..ef4d02e423 100644
--- a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/AllBioEntityTests.java
+++ b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/AllBioEntityTests.java
@@ -4,16 +4,16 @@ import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 import org.junit.runners.Suite.SuiteClasses;
 
-import lcsb.mapviewer.converter.graphics.bioEntity.element.compartment.PathwayCompartmentConverterTest;
+import lcsb.mapviewer.converter.graphics.bioEntity.element.compartment.AllCompartmentConverterTests;
 import lcsb.mapviewer.converter.graphics.bioEntity.element.species.AllSpeciesConverterTests;
 import lcsb.mapviewer.converter.graphics.bioEntity.reaction.AllReactionTests;
 
 @RunWith(Suite.class)
 @SuiteClasses({
+    AllCompartmentConverterTests.class,
     AllSpeciesConverterTests.class,
     AllReactionTests.class,
     BioEntityConverterImplTest.class,
-    PathwayCompartmentConverterTest.class,
 })
 public class AllBioEntityTests {
 
diff --git a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/AllCompartmentConverterTests.java b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/AllCompartmentConverterTests.java
new file mode 100644
index 0000000000..822c73b6d3
--- /dev/null
+++ b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/AllCompartmentConverterTests.java
@@ -0,0 +1,11 @@
+package lcsb.mapviewer.converter.graphics.bioEntity.element.compartment;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({ PathwayCompartmentConverterTest.class, SquareCompartmentConverterTest.class })
+public class AllCompartmentConverterTests {
+
+}
diff --git a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/PathwayCompartmentConverterTest.java b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/PathwayCompartmentConverterTest.java
index e8f7b76419..70f1c48b7e 100644
--- a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/PathwayCompartmentConverterTest.java
+++ b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/PathwayCompartmentConverterTest.java
@@ -1,9 +1,12 @@
 package lcsb.mapviewer.converter.graphics.bioEntity.element.compartment;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.atLeastOnce;
 
 import java.awt.*;
 import java.awt.image.BufferedImage;
+import java.util.List;
 
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
@@ -36,12 +39,20 @@ public class PathwayCompartmentConverterTest extends GraphicsTestFunctions {
     pathway.setWidth(100);
     pathway.setHeight(200);
     pathway.setFillColor(Color.BLUE);
+    pathway.setBorderColor(Color.ORANGE);
+    pathway.setFontColor(Color.RED);
     pathway.setTransparencyLevel("12");
     model.addElement(pathway);
 
     converter.draw(pathway, graphics, new ConverterParams().nested(true));
 
-    Mockito.verify(graphics).setColor(Color.BLUE);
+    ArgumentCaptor<Color> argument = ArgumentCaptor.forClass(Color.class);
+    Mockito.verify(graphics, atLeastOnce()).setColor(argument.capture());
+    List<Color> values = removeAlpha(argument.getAllValues());
+
+    assertTrue("Fill colour wasn't used", values.contains(Color.BLUE));
+    assertTrue("Border colour wasn't used", values.contains(Color.ORANGE));
+    assertTrue("Font colour wasn't used", values.contains(Color.RED));
   }
 
   @Test
diff --git a/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/SquareCompartmentConverterTest.java b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/SquareCompartmentConverterTest.java
new file mode 100644
index 0000000000..8c2d15812c
--- /dev/null
+++ b/converter-graphics/src/test/java/lcsb/mapviewer/converter/graphics/bioEntity/element/compartment/SquareCompartmentConverterTest.java
@@ -0,0 +1,63 @@
+package lcsb.mapviewer.converter.graphics.bioEntity.element.compartment;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.atLeastOnce;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.util.List;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+import lcsb.mapviewer.commands.ColorExtractor;
+import lcsb.mapviewer.converter.graphics.ConverterParams;
+import lcsb.mapviewer.converter.graphics.GraphicsTestFunctions;
+import lcsb.mapviewer.model.map.compartment.SquareCompartment;
+import lcsb.mapviewer.model.map.model.Model;
+import lcsb.mapviewer.model.map.model.ModelFullIndexed;
+
+public class SquareCompartmentConverterTest extends GraphicsTestFunctions {
+
+  Logger logger = LogManager.getLogger();
+
+  ColorExtractor colorExtractor = new ColorExtractor(Color.RED, Color.GREEN, Color.BLUE);
+  SquareCompartmentConverter converter = new SquareCompartmentConverter(colorExtractor);
+
+  @Test
+  public void testDrawSolidAndColorUsage() throws Exception {
+    int size = 600;
+    Model model = new ModelFullIndexed(null);
+
+    BufferedImage bi = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
+    Graphics2D graphics = Mockito.spy(bi.createGraphics());
+
+    SquareCompartment pathway = new SquareCompartment("id");
+    pathway.setX(10);
+    pathway.setY(10);
+    pathway.setWidth(100);
+    pathway.setHeight(200);
+    pathway.setFillColor(Color.BLUE);
+    pathway.setBorderColor(Color.YELLOW);
+    pathway.setFontColor(Color.GREEN);
+    pathway.setName("xyz");
+    pathway.setTransparencyLevel("100");
+    model.addElement(pathway);
+
+    converter.draw(pathway, graphics, new ConverterParams().nested(true));
+
+    ArgumentCaptor<Color> argument = ArgumentCaptor.forClass(Color.class);
+    Mockito.verify(graphics, atLeastOnce()).setColor(argument.capture());
+    List<Color> values = removeAlpha(argument.getAllValues());
+
+    assertTrue("Fill colour wasn't used", values.contains(Color.BLUE));
+    assertTrue("Border colour wasn't used", values.contains(Color.YELLOW));
+    assertTrue("Font colour wasn't used", values.contains(Color.GREEN));
+
+  }
+
+}
-- 
GitLab