@Override
 public void fillRectangle(BoundingBox2d rect) {
   fillShape(
       new Rectangle2D.Double(
           rect.getLowerLeft().getX(),
           rect.getLowerLeft().getY(),
           rect.getWidth(),
           rect.getHeight()));
 }
  @Override
  public void drawString(String string, BoundingBox2d bounds, double padding) {
    FontMetrics metrics = pipe.getFontMetrics(pipe.getFont());

    final double stringWidth = metrics.stringWidth(string);
    final double stringHeight = metrics.getHeight();

    // calculate scale, so that bb fits into bounds - padding
    final double sx = bounds.getWidth() / (stringWidth + padding);
    final double sy = bounds.getHeight() / (stringHeight + padding);

    final double scale = Math.min(sx, sy);

    java.awt.Font oldFont = pipe.getFont();
    java.awt.Font scaledFont = oldFont.deriveFont((float) (oldFont.getSize2D() * scale));

    // position b inside bounds
    final double x = bounds.getLocation().getX() + (bounds.getWidth() - stringWidth * scale) / 2;
    final double y =
        bounds.getLocation().getY()
            + bounds.getHeight()
            - (bounds.getHeight() - scaledFont.getSize2D()) / 2;

    pipe.setFont(scaledFont);
    try {
      pipe.drawString(string, (float) x, (float) y);
    } finally {
      pipe.setFont(oldFont);
    }
  }