Ok. I understand what you did. That's interesting.
Note that drawing on a canvas outside an OnPaint event does not work on MacOS. Does someone know how to bypass this ?
If we need to paint everything, well, the speed will not be so high. It would still be useful if the rendering of the tile content is slow, so that it works like a buffer.
We can try to go toward implementing it in the library. First of all, it should be in a class. To do so, create a separate unit with a type definition, something like :
type TTiledSurface = class
...
And every procedure that is linked to this subject should be moved into it (MarkDrawTiles, Draw). Some variable names are not really understandable, for example b_image for BackgroundImage. Also add BackgroundColor, so that if there is no BackgroundImage, the tile is filled with this color.
CreateImages should be split into two parts. One is about freeing previous tiles and resizing the array.
Another is about what the user wants to do. In your example, you set the background image. This can be handled for example in a virtual procedure. Do you know what this is ?