1
\$\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\$
  • 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 '18 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 '18 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 '18 at 23:53
  • \$\begingroup\$ Fair enough, I retracted my "unclear" vote. \$\endgroup\$ – Phrancis Jun 28 '18 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 '18 at 0:35
5
\$\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\$
  • \$\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 '18 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 '18 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 '18 at 1:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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