Создание новых фигур
--------------------

Для создания новой фигуры следует выполнить следующие действия

1. Создать новый модуль в пакете ``frame_stamp.shape``

2. Создать класс, наследованный от ``frame_stamp.shape.base_shape.BaseShape``

3. Определить имя новой фигуры в атрибуте ``shape_name``

4. Определить метод ``draw_shape()`` для описания процесса рендера фигуры.

Метод ``draw_shape()`` принимает такие аргументы:

shape_canvas
  Подготовленный объект PIL.Image на котором можно рендерить. Размер будет равен размеру фигуры плюс офсеты с учетом возможного поворота фигуры.

canvas_size
  Размер подготовленного канваса.

center
  Объект Point с координатами центра.

zero_point
  Смещение нуля от текущего нуля координат в реальное начало координат без учёта добавленного запаса канваса.
  Просто добавляйте эти координаты перед рендером элементов.

Во время рисования ненужно заботиться о повороте фигуры, это происходит отдельно перед наложением её на основную картинку.
Также отдельно происходит рисование градиента.

Результат может быть передан в основной рендер двумя способами:

- Ничего не возвращать, результат рендера будет взят из исходного канваса.

- Вернуть новое изображение. Например оно было пересоздано по каким-либо причинам.

5. Если фигура достаточно сложная или составная то можно переопределить метод ``render()``
Этот метод в качестве аргумента получает размер канваса и должен через ``yield`` возвращать
нужное количество новых фигур вместе с координатами вставки


.. code-block:: python

    def render(self, size, **kwargs):
        ...
        for i in some:
          yield shape, (x, y)
        ...

.. note:: Движок использует библиотеку `Pillow` для рисования фигур.


6. Добавить импорт вашего класса в файле ``frame_stamp/shapes/__init__.py``


Пример
======

Ниже приведён пример создания новой фигуры. Эта фигура рисует круги.

.. code-block:: python

    from .base_shape import BaseShape
    from PIL import ImageDraw

    class CircleShape(BaseShape):
        shape_name = 'circle'

        @property
        def radius(self):
            return self._eval_parameter('radius', default=0)

        def draw_shape(self, shape_canvas, canvas_size, center, zero_point, **kwargs):
            canvas = self._get_canvas(size)
            img = ImageDraw.Draw(shape_canvas)
            img.ellipse((self.x-(self.radius/2),
                         self.y-(self.radius/2),
                         self.x+(self.radius/2),
                         self.y+(self.radius/2),), fill=self.color)


Теперь в шаблонах можно использовать новый тип фигуры ``circle`` с параметром ``radius``.

