I can only give you a partial answer here without Python, but if most of your geometries are regular then the following might work.
1. Rule-based Labeling
Firstly, to independently manage two separate labels, use Rule-based labeling.
This lets you have separate labels for the same feature with settings independent of each other. Below I have two separate labels for the fields PFI and GeomArea.
2. Data-defined label coordinates and rotation
Secondly, you can set the X and Y coordinates and rotation of the labels relative to the feature geometry if you go to the Placement tab of the label and use a Data-Defined override in the Coordinate X, Coordinate Y and Rotation fields. Below is a screenshot of these settings in the PFI label I have set up above.
Now, for the expressions to use in the data-defined override.
3. Setting coordinates
Determining the top-right and bottom-left corner of the polygons wasn't straightforward - if anyone has a better approach please share, this probably isn't optimal.
I found the top-right and bottom-left corners of the bounding box of each polygon - which was often outside the polygon itself - then looked for the closest nodes on the polygon to those corners, and used those two locations as the "anchor point" for the respective labels.
Here is the X coordinate expression (for bottom left. For top right change x/y_min to x/y_max):
And the Y coordinate expression (for bottom left. For top right change x/y_min to x/y_max):
4. Setting rotation
This was more complex and convoluted as the label "anchor point" location would sometimes be on the very corner of the polygon, so the interpolated angle at that point would be really off sometimes.
So I would get the angle of a point just a little more "rightwards" along the "bottom line" of the polygon to make sure it was not at a corner.
To do so I had to
make sure the polygon boundaries were all drawn in the same order using
get the distance value of the "anchor point" location along the polygon boundary with
subtract -0.5 projected CRS units from that distance (plus and modulo the polygon boundary length - in case the anchor point is on or near the starting point of the polygon boundary)
find the point along the polygon boundary with the distance from #3 - this is the "rightward point"
get the angle of that point with
This is the expression I ended up using (for bottom left. For top right change x/y_min to x/y_max):
y_min(bounds($geometry)))))-0.5 + perimeter($geometry))
Here are the results with some very regular polygons. It's not perfect when the bottom edge is all slanted, but it's a start.
Note the red and green dots are the "anchor points" and the yellow and blue dots are the points used for getting label rotation.
4. More effective application
Calculating all of the above on the fly will be very resource-intensive.
So I suggest you create 4 fields in your data for each of the 4 values (top-right label anchor coords, top-right rotation, bottom-left label anchor coords, bottom-left rotation) using the above expressions in Field Calculator.
5. Further modification
To increase or decrease the "padding" you may have to add or subtract a couple of units from the X and Y coordinates appropriately. You might want this to be proportionate to the geometry area (
As for the scalable size, explore using Map Units instead of Millimeters, and the Size Assistant (click the data-defined box next to Size when setting labels, and click Assistant...), and for Source try
$area and use that to help scale your labels to the size of the polygon.