Hello,

I'm working on filling text to arbitrary shapes, where I hit the named problem.
It's not easy to reproduce, as it depends on fontsize and shape ...

So using the attached code reproduces the attached image.

I use the call Shape.contains(double x, double y, double w, double h) where 
the apidoc says: "Tests if the interior of the Shape entirely contains the 
specified rectangular area."

reaching the last line, there should be no match at all, as most of the given 
rectangle is outside the shape (for all succeeding tests).
To verify my understanding I draw the tested rectangle when the contains-
method returns true.

May be, my sample hits the insideness of a point (from Shape-apidocs), where 
the point lies on the shape boundary and the succeeding point is inside the 
shape.
That might be true for the base point of the rectangle, but it is never true, 
for the entire rectangle.

So this might be considered a bug.


kind regards

Gero

<<attachment: Java2DFailure-3.png>>

@Override
public void paint(Graphics2D g) {
    super.paint(g); // draws the shape with border
    FontMetrics fm = g.getFontMetrics();
    Vector<String> words = new Vector<String>(Arrays.asList(getText().split("\\s")));
    int mx = getX() + getWidth();
    int yMax = getY() + getHeight();
    int curY = getY() + fm.getDescent();
    int firstX = 0;
    int lastX = 0;
    Rectangle2D bounds;

    while (curY < yMax) {
        bounds = fm.getStringBounds(getText().substring(0, 1), g);

        for (int x = getX(); x < mx; x += bounds.getWidth()) {
            if (getShape().contains(x, curY, bounds.getWidth(), bounds.getHeight())) {
                firstX = x;
                break;
            }
        }

        for (int x = mx; x > getX(); x -= bounds.getWidth()) {
            if (getShape().contains(x, curY, bounds.getWidth(), bounds.getHeight())) {
                lastX = x;
                break;
            }
        }
        int lineLength = lastX - firstX;
        g.drawRect(firstX, curY, (int) bounds.getWidth(), (int) bounds.getHeight());

        curY += fm.getAscent();
        String line = null;
        StringBuilder check = new StringBuilder(words.remove(0));

        check.append(" ").append(words.get(0));
        bounds = fm.getStringBounds(check.toString(), g);

        while (bounds.getWidth() < lineLength) {
            words.remove(0);
            line = check.toString();
            check = new StringBuilder(line);

            check.append(" ").append(words.get(0));
            bounds = fm.getStringBounds(check.toString(), g);
        }
        if (line == null)
            break;
        g.drawString(line, firstX, curY);
        curY += fm.getHeight();
    }
}

Reply via email to