Search code examples
phppdfpdflib

PDFlib PHP return dynamic height of two elements side by side


So, I have two elements side by side. Each of those elements contains a list and can be dynamic in their own height. But I have two problems with this.

1.) How can I give the height of the highest element to the next element under those two? I know I can return the height value, but as of now this does not work as I want it to. If I return the height value of the left element, the right element, will not have the right start point in height and if I just return the height value of one, the next element will only get it's start point from that element. Means if I, for example, return the height value of the right element, the next element will get it's startpoint from that. But if the left element is longer than the right one, it doesn't display correctly. How can I achieve what I'm trying to do here?

2.) The other problem is that the output as of now isn't correct. The items of the list come from an array. To display them I created a foreach loop which creates it's own textflow for every list item. The height of the next item will then be adjusted inside of that loop. The first two items display correctly as of now, but the third one and every item that comes after that doesn't get their right height value and will be displayed under the second one. Does anyone know what I'm doing wrong here?

I have created two functions, one for the left element and one for the right. My Code as of now looks like this... Function for left element:

private function createProductProfile(\PDFlib $p, int $y, int $fontLightRegular, int $elementStartLeft, int $elementStartHalf, int $elementEndRight, array $arrInput)
    {
        // Variable Declaration
        $productProfileContent = $arrInput['productProfile']['profileContent'];

        $right_x = $elementStartHalf - 20;
        $left_x = $elementStartLeft + 10;
        $right_y = $y;
        $left_y = $right_y - 20;

        // output every element of productProfileContent array as textflow
        foreach ($productProfileContent as $profile) {
            $this->placeHyphen($p, $elementStartLeft, $y);

            $optlistProfile = 'font=' . $fontLightRegular . ' fontsize=10 fillcolor=black wordspacing=0';

            $tfProfile = $p->add_textflow(0, $profile, $optlistProfile);
            if ($tfProfile == 0) {
                throw new Exception('Error: ' . $p->get_errmsg());
            }

            // Gebe Textflow aus
            $resultProfile = $p->fit_textflow($tfProfile, $left_x, $left_y, $right_x, $right_y, '');

            $right_y = $right_y - 20;
            $y = $y - 20;
        }
    }

And here's the function for the right element:

private function createProductAdvantages(\PDFlib $p, int &$y, int $fontLightRegular, int $elementStartLeft, int $elementStartHalf, int $elementEndRight, array $arrInput)
    {
        // Variable Declaration
        $productAdvantagesContent = $arrInput['productAdvantages']['advantagesContent'];

        $right_x = $elementEndRight;
        $left_x = $elementStartHalf + 30;
        $right_y = $y;
        $left_y = $right_y - 20;

        // output every element of $productAdvantagesContent array as textflow
        foreach ($productAdvantagesContent as $advantages) {
            $this->placeHyphen($p, $elementStartHalf + 20, $y);

            $optlistAdvantages = 'font=' . $fontLightRegular . ' fontsize=10 fillcolor=black wordspacing=0';

            $tfAdvantages = $p->add_textflow(0, $advantages, $optlistAdvantages);
            if ($tfAdvantages == 0) {
                throw new Exception('Error: ' . $p->get_errmsg());
            }

            // Gebe Textflow aus
            $resultAdvantages = $p->fit_textflow($tfAdvantages, $left_x, $left_y, $right_x, $right_y, '');

            $right_y = $right_y - 20;
            $y = $y - 20;
        }
    }

Also here's an image of the current output. As you can see, the hyphens will be displayed correctly, but not the array items: current generated output


Solution

  • Currently your code assumes that you always need the complete specified fitbox (So the height of the box at fit_textflow).

        // Gebe Textflow aus
        $resultProfile = $p->fit_textflow($tfProfile, $left_x, $left_y, $right_x, $right_y, '');
    
        $right_y = $right_y - 20;
        $y = $y - 20;
    

    I suspect that is not the case most of the time. Therefore, after fit_textflow() you should pick up the final position of the text and continue calculating with it. You can do this with info_textflow().

        // Gebe Textflow aus
        $resultProfile = $p->fit_textflow($tfProfile, $left_x, $left_y, $right_x, $right_y, '');
        $lly = $p->info_textflow($tfProfile, "y1");
        // now you can work with the lower left y position for further calculation
    

    Second, if you want to keep the output for the left and right columns in sync, you then need to retrieve those value for left and right, and then use the new Y starting point of the lower value.

    On the other hand, it sounds to me like you could also think of your layout as a table layout with two columns. In that case you would simply create Textflow cells and when placing the content PDFlib would then generate the layout accordingly. Maybe you could give this some thought?