Я использую так называемые списки выполнения для этой функции (обобщенные фигуры и их блиттинг). Я тоже видел их как варплисты. Форма кодируется как список выполнения, определяя его как набор горизонтальных линий, и каждая строка имеет два целочисленных значения (пропустить n пикселей, скопировать n пикселей).
Это означает, что вы можете рисовать целые линии, оставляя вам только операции рисования «по высоте».
Итак, прямоугольник определен (первые «пропускают» пиксели от верхнего уровня до левого угла (xorg, yorg). Прямоугольник width_rect wide, а width_pixels идет дальше на строку. Width_pixels может быть шире ширины картинка (байты выравнивания)
(yorg*width_pixels+xorg , width_rect),
(width_pixels-width_rect , width_rect),
(width_pixels-width_rect , width_rect),
(width_pixels-width_rect , width_rect),
..
..
Таким образом, вы можете сделать свои процедуры рисования довольно общими, а для простых, правильных форм (ребра, круги) требуется лишь небольшая математика для пересчета этих списков. Это значительно упростило мою форму.
Однако я рисую прямо на растровые изображения, а не на холсты, поэтому я не могу помочь с этой частью. Примитива, который эффективно рисует строку, и способа извлечь строку из графики должно быть достаточно.