2
\$\begingroup\$

I am implementing a program to draw a box of text next to some other drawn object (that can have any position and dimensions) and the text box should always be visible, even if the drawn object's width is of the entire screen and vice versa. They should simply not overlap.

This is a code to position the text on some relatively good coordinates.

if(x > (box_w + 20)) box_x = x - (box_w + 20);
else                            box_x = w + 20;
if(y > (box_h + 20)) box_y = y - (box_h + 20);
else                            box_y = h + 20;
if(w > width - (box_h + 20) || x + w + box_w + 20 > width)
{
    box_x = 20;

    if(y < box_h + 20)
    {
        box_y = h + 20;
    }
    else box_y = y - (box_h + 20);
}

x, y, w, h are the coords and dimensions for the object; box_x, box_y, box_w and box_y are for the text box and width/height is the dimension of the area.

Here is schematically how this code positions text (darker blue) near the object (lighter blue) box positioning examples

It is quite obvious that it could have been written much better. To target performance, but more importantly - code space.

Can anyone suggest a better way to find good coordinates for the text box?

\$\endgroup\$
9
  • 1
    \$\begingroup\$ Could you add more of your code for context? This is not much to go on, just a series of conditionals, seeing the code that makes the box and draws it would help clarify. \$\endgroup\$
    – Phrancis
    Jun 28, 2018 at 23:49
  • \$\begingroup\$ @Phrancis it is not lacking much, just a drawing of box using the given coordinates and dimensions using cairo, I don't see how is this relevant. This code can be used on just about anything. \$\endgroup\$
    – Edenia
    Jun 28, 2018 at 23:51
  • \$\begingroup\$ There are many ways I could've reviewed this myself. There are many ways to do what I am trying to achieve (and most of those ways would be for sure better) \$\endgroup\$
    – Edenia
    Jun 28, 2018 at 23:53
  • \$\begingroup\$ Fair enough, I retracted my "unclear" vote. \$\endgroup\$
    – Phrancis
    Jun 28, 2018 at 23:53
  • 1
    \$\begingroup\$ Is it intended for the text-box to be positioned to the left/right of the image when possible, or is it always supposed to be above/below? Also, is the alignment of the box in images 2 / 3 the desired behavior, or an artifact of the current code? Typically I'd expect the alignment to be reversed in those cases. \$\endgroup\$
    – Errorsatz
    Jun 29, 2018 at 0:35

1 Answer 1

6
\$\begingroup\$

This is a definite candidate for using rect / point structures, but I don't know what the rest of your code-base looks like, so just talking about the algorithm alone, one approach would be:

void FindNonOverlappingPosition(
    uint canvasWidth, uint canvasHeight,
    uint x1, uint y1, uint width1, uint height1,
    uint width2, uint height2, uint spacing,
    uint* outX, uint* outY)
{
    // Position above if possible, below otherwise
    if (y1 >= height2 + spacing)
        *outY = y1 - (height2 + spacing);
    else
        *outY = y1 + height1 + spacing;

    // Position left-aligned if content is closer to the left of the canvas, right-aligned otherwise
    if (x1 < canvasWidth - width1)
        *outX = x1;
    else
        *outX = (x1 + width1) - width2;

    // Ensure that the box being positioned fits on the canvas
    if (*outX < 0)
        *outX = 0;
    else if (*outX + width2 > canvasWidth)
        *outX = canvasWidth - width2;
}

This fails in cases where an alignment according to those rules is impossible, such as the content taking up the entire height of the screen, or the text box being wider than the screen. You could check for those cases and return an error code if desired.

\$\endgroup\$
3
  • \$\begingroup\$ Yeah exactly, the algorithm itself is important. Functions in C should do only one thing. I have 3 functions and 1 to be reviewed (that one - with the algoriths) others are just drawing, nothing interesting. \$\endgroup\$
    – Edenia
    Jun 29, 2018 at 1:16
  • \$\begingroup\$ Several years ago I was drawing onto canvas in Game-Editor using SDL-inspired putpixel, setpen and lineto functions, now I use GTK+/Cairo \$\endgroup\$
    – Edenia
    Jun 29, 2018 at 1:17
  • 1
    \$\begingroup\$ I tested your code, it actually works. It aligns them differently, but aligns them properly. In a way it aligns them better. It would be even better if the text is aligned centered above/below when the object's width = canvas width \$\endgroup\$
    – Edenia
    Jun 29, 2018 at 1:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.