/**
  * Updates painted label layout and returns clipped or full label text.
  *
  * @param label label to process
  * @param fm label font metrics
  * @param width label width
  * @param height label height
  * @return clipped or full label text
  */
 protected String layout(final E label, final FontMetrics fm, final int width, final int height) {
   final Insets insets = label.getInsets(null);
   final String text = label.getText();
   final Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon();
   final Rectangle paintViewR = new Rectangle();
   paintViewR.x = insets.left;
   paintViewR.y = insets.top;
   paintViewR.width = width - (insets.left + insets.right);
   paintViewR.height = height - (insets.top + insets.bottom);
   paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0;
   paintTextR.x = paintTextR.y = paintTextR.width = paintTextR.height = 0;
   return layoutCL(label, fm, text, icon, paintViewR, paintIconR, paintTextR);
 }
  /** {@inheritDoc} */
  @Override
  public Dimension getPreferredSize(final E label) {
    final String text = label.getText();
    final Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon();
    final Insets insets = label.getInsets(null);
    final Font font = label.getFont();

    final int dx = insets.left + insets.right;
    final int dy = insets.top + insets.bottom;

    if ((icon == null) && ((text == null) || ((text != null) && (font == null)))) {
      return new Dimension(dx, dy);
    } else if ((text == null) || ((icon != null) && (font == null))) {
      return new Dimension(icon.getIconWidth() + dx, icon.getIconHeight() + dy);
    } else {
      final FontMetrics fm = label.getFontMetrics(font);

      final Rectangle iconR = new Rectangle();
      final Rectangle textR = new Rectangle();
      final Rectangle viewR = new Rectangle();
      iconR.x = iconR.y = iconR.width = iconR.height = 0;
      textR.x = textR.y = textR.width = textR.height = 0;
      viewR.x = dx;
      viewR.y = dy;
      viewR.width = viewR.height = Short.MAX_VALUE;

      layoutCL(label, fm, text, icon, viewR, iconR, textR);

      final int x1 = Math.min(iconR.x, textR.x);
      final int x2 = Math.max(iconR.x + iconR.width, textR.x + textR.width);
      final int y1 = Math.min(iconR.y, textR.y);
      final int y2 = Math.max(iconR.y + iconR.height, textR.y + textR.height);
      final Dimension rv = new Dimension(x2 - x1, y2 - y1);
      rv.width += dx;
      rv.height += dy;
      return rv;
    }
  }