public synchronized BufferedImage filter(BufferedImage src, BufferedImage dest) {
		if (dest == null)
			dest = createCompatibleDestImage(src, null);
		float xc = mx;
		float yc = my;
		float r0 = rw;
		float rrh = rh;
		Graphics2D g2d = dest.createGraphics();
		g2d.drawImage(src, null, 0, 0);
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2d.setPaint(rw > 30 ? new Color(red, green, blue, 0.2f) : new Color(1f, 0f, 1f, 0.2f));
		Shape oldClip = g2d.getClip();
		g2d.setClip(needClip);
		if (drawImage && internalImage != null && drawMode == GLASS_AS_RECTANGLE) {
			Composite oldComp = g2d.getComposite();
			Color oldColor = g2d.getColor();
			g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.85f));
			g2d.drawImage(internalImage, null, Math.round(xc - r0), Math.round(yc - rrh - 1));
			g2d.setComposite(oldComp);
			g2d.setColor(oldColor);
		}
		else {
			int y = Math.round(yc - rrh - 1);
			int h = Math.round(2 * rrh);
			if (drawMode == GLASS_AS_RECTANGLE) {
				g2d.fillRoundRect(Math.round(xc - 2 * r0), y, Math.round(r0), h, cornerRadius, cornerRadius);
				g2d.fillRoundRect(Math.round(xc), y, Math.round(r0), h, cornerRadius, cornerRadius);
				g2d.setColor(new Color(1f, 1f, 1f, 0.1f));
				g2d.fillRect(Math.round(xc - r0), y, Math.round(r0), h);
			}
			else {
				g2d.fillOval(Math.round(xc - r0), Math.round(yc - r0), 2 * Math.round(r0), 2 * Math.round(r0));
			}
			g2d.setStroke(stroke);
			g2d.setPaint(rw > 30 ? new Color(red2, green2, blue2, 0.5f) : new Color(0.7f, 0f, 0.7f, 0.5f));
			if (drawMode == GLASS_AS_RECTANGLE) {
				g2d.drawRoundRect(Math.round(xc - 2 * r0), y, Math.round(3 * r0), h, cornerRadius, cornerRadius);
				g2d.setStroke(thinStroke);
				g2d.drawLine(Math.round(xc - r0), y, Math.round(xc - r0), y + h);
				g2d.drawLine(Math.round(xc), y, Math.round(xc), y + h);
			}
			else {
				g2d.drawOval(Math.round(xc - r0), Math.round(yc - r0), 2 * Math.round(r0), 2 * Math.round(r0));
			}
		}
		g2d.setClip(oldClip);
		g2d.drawImage(dest, 0, 0, null);
		g2d.dispose();
		return dest;
	}