public Rectangle getVisualBounds(JComponent c, int type, int width, int height) {
    Rectangle bounds = new Rectangle(0, 0, width, height);
    if (type == VisuallyLayoutable.CLIP_BOUNDS) {
      return bounds;
    }

    AbstractButton b = (AbstractButton) c;

    if (type == VisuallyLayoutable.COMPONENT_BOUNDS
        && b.getBorder() != null
        && b.isBorderPainted()) {
      Border border = b.getBorder();
      if (border instanceof BackgroundBorder) {
        border = ((BackgroundBorder) border).getBackgroundBorder();
        if (border instanceof VisualMargin) {
          InsetsUtil.subtractInto(((VisualMargin) border).getVisualMargin(c), bounds);
        } else if (border instanceof QuaquaButtonBorder) {
          InsetsUtil.subtractInto(((QuaquaButtonBorder) border).getVisualMargin(c), bounds);
        }
      }
      return bounds;
    }

    String text = b.getText();
    boolean isEmpty = (text == null || text.length() == 0);
    if (isEmpty) {
      text = " ";
    }
    Icon icon = (b.isEnabled()) ? b.getIcon() : b.getDisabledIcon();

    if ((icon == null) && (text == null)) {
      return null;
    }

    FontMetrics fm = c.getFontMetrics(c.getFont());
    Insets insets = c.getInsets(viewInsets);

    viewR.x = insets.left;
    viewR.y = insets.top;
    viewR.width = width - (insets.left + insets.right);
    viewR.height = height - (insets.top + insets.bottom);

    iconR.x = iconR.y = iconR.width = iconR.height = 0;
    textR.x = textR.y = textR.width = textR.height = 0;

    String clippedText = layoutCL(b, fm, text, icon, viewR, iconR, textR);

    Rectangle textBounds = Fonts.getPerceivedBounds(text, c.getFont(), c);
    if (isEmpty) {
      textBounds.width = 0;
    }
    int ascent = fm.getAscent();
    textR.x += textBounds.x;
    textR.width = textBounds.width;
    textR.y += ascent + textBounds.y;
    textR.height -= fm.getHeight() - textBounds.height;

    bounds.setBounds(textR);
    return bounds;
  }
  /**
   * Method which renders the text of the current button.
   *
   * <p>
   *
   * @param g Graphics context
   * @param b Current button to render
   * @param textRect Bounding rectangle to render the text.
   * @param text String to render
   * @since 1.4
   */
  @Override
  protected void paintText(Graphics g, AbstractButton b, Rectangle textRect, String text) {
    ButtonModel model = b.getModel();
    FontMetrics fm = g.getFontMetrics();
    int mnemonicIndex = Methods.invokeGetter(b, "getDisplayedMnemonicIndex", -1);
    boolean borderHasPressedCue = borderHasPressedCue(b);

    /* Draw the Text */
    if (model.isPressed() && model.isArmed() && !borderHasPressedCue) {
      g.setColor(new Color(0xa0000000, true));
      QuaquaUtilities.drawStringUnderlineCharAt(
          g,
          text,
          mnemonicIndex,
          textRect.x + getTextShiftOffset(),
          textRect.y + fm.getAscent() + getTextShiftOffset() + 1);
    }

    if (model.isEnabled()) {
      /** * paint the text normally */
      g.setColor(b.getForeground());
    } else {
      Color c = UIManager.getColor(getPropertyPrefix() + "disabledForeground");
      g.setColor((c != null) ? c : b.getForeground());
    }
    QuaquaUtilities.drawStringUnderlineCharAt(
        g,
        text,
        mnemonicIndex,
        textRect.x + getTextShiftOffset(),
        textRect.y + fm.getAscent() + getTextShiftOffset());
  }