Векторная графика в FastReport .NET 2019.4. Скрипт

30.07.2019

В первой части статьи мы рассмотрели нововведения FastReport .NET 2019.4 по части векторной графики. Теперь кривые и полигоны можно строить кривыми Безье. В этой статье мы рассмотрим возможность создания кривых с помощью скрипта отчета.

На данный момент существует два способа создать кривые из кода: использовать объект PolyLineObject или загрузить полигон из SVG.

Как вы знаете любой объект отчета доступен в скрипте отчета, поэтому мы можем использовать PolyLineObject чтобы задать точки и соединить их для создания фигуры. Выполнить код следует перед отображением объекта, а значит нужно создать обработчик события BeforePrint для объекта Polygon. Давайте рассмотрим на реальном примере.

Добавляем объект Polygon на страницу отчета. Чтобы не создавать ключевые точки фигуры просто нажмите Esc. В инспекторе свойств объекта выбираем События. Создаем обработчик события BeforePrint:

 

В обработчике напишем следующий код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
private void Polygon4_BeforePrint(object sender, EventArgs e)
 {
 //Создаем фигуру звезда
 int spikes = 5; //Количество вершин
 PolyLineObject obj = sender as PolyLineObject;
 PolyLineObject.PolyPointCollection points = obj.Points;
 points.Clear();
 const float outerRadius = 70; //Внешний радиум
 const float innerRadius = 30; //Внутренний радиус
 float rot = (float)(Math.PI / 2 * 3); //Угол наклона
 const float cx = 0;
 const float cy = 0;
 float x = cx;
 float y = cy;
 float step = (float)(Math.PI / spikes); //Шаг создания вершин
 obj.Width = 100;
 obj.Height = 100;
 obj.CenterX = 50;
 obj.CenterY = 50;
 points.Add(new PolyLineObject.PolyPoint(cx, cy - outerRadius)); //Добавляем точки
 for (int i = 0; i < spikes; i++)
 {
 //Координаты внутренних точек
 x = cx + (float)Math.Cos(rot) * outerRadius;
 y = cy + (float)Math.Sin(rot) * outerRadius;
 points.Add(new PolyLineObject.PolyPoint(x, y));
 rot += step; //Переход к следующей точке
 //Координаты внешних точек
 x = cx + (float)Math.Cos(rot) * innerRadius;
 y = cy + (float)Math.Sin(rot) * innerRadius;
 points.Add(new PolyLineObject.PolyPoint(x, y));
 rot += step;
 }
 }

В результате мы получим звезду:

 

В приведенном примере мы производили расчет координат для построения фигуры, но если у вас уже есть список координат, то просто добавляем их в коллекцию точек:  points.Add(new PolyLineObject.PolyPoint(x, y));

Но что если фигура гораздо сложнее приведенного примера? Количество кода для ее создания будет очень велико. В этом случае можно воспользоваться объектом SVG. Например, его свойством path. Мы можем конвертировать набор элементов пути svg изображения в точки и построить по ним полигон. Важно учитывать кривые Безье. Как это сделать, вы увидите ниже в коде:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
private void PolyLine2_BeforePrint(object sender, EventArgs e)
 {
 PolyLineObject obj = sender as PolyLineObject;
 PolyLineObject.PolyPointCollection points = obj.Points;
 points.Clear ();
 //Построитель SVG по пути
 SvgPathBuilder builder = new SvgPathBuilder ();
 //Загружаем список сегментов из строки
 SvgPathSegmentList list = builder.ConvertFromString ("M91.734 10.5L66.6384 59.025 10.5 66.8258l40.643 37.749-9.5696 53.327 50.2094-25.1932 50.234 25.1582-9.6124-53.321 40.6154-37.778-56.1505-7.76z") as SvgPathSegmentList; 
 GraphicsPath _path = new GraphicsPath ();
 foreach (SvgPathSegment segment in list) {
 segment.AddToPath (_path);
 }
 PolyLineObject.PolyPoint point = null;
 for (int i = 0; i < _path.PointCount; i++) {
 PointF pnt = _path.PathPoints[i];
 byte type = _path.PathTypes[i];
 //Если кривая, то считать три точки подряд и задать направляющие искривления
 if (type == 3) {
 PointF pnt1 = _path.PathPoints[i];
 PointF pnt2 = _path.PathPoints[i + 1];
 PointF pnt3 = _path.PathPoints[i + 2];
 i += 2;
 //Искривление вправо
 point.RightCurve = new PolyLineObject.PolyPoint (pnt1.X - point.X,
 pnt1.Y - point.Y);
 //Точка
 point = new PolyLineObject.PolyPoint (pnt3.X, pnt3.Y);
 //Искривление влево
 point.LeftCurve = new PolyLineObject.PolyPoint (pnt2.X - point.X,
 pnt2.Y - point.Y);
 } else {
 //Обычная точка
 point = new PolyLineObject.PolyPoint (pnt.X, pnt.Y);
 }
 //Добавляем точки
 points.Add (point);
 }
 obj.CenterX = 0;
 obj.CenterY = 0;
 obj.RecalculateBounds ();
 obj.Top = 0;
 obj.Left = 0;
 }
 }

Этот код отобразит нам звезду такого вида:

 

В список типа SvgPathSegmentList мы помещаем элементы из тега path SVG файла. Затем, получаем координаты точек и добавляем их в объект PolyLine. В этом примере мы отобразили объект прямыми отрезками, но вы также можете использовать кривые, например:

      SvgPathSegmentList list = builder.ConvertFromString ("m101.87775,57.26873c31.12829,-82.10042 153.08994,0 0,105.55768c-153.08994,-105.55768 -31.12829,-187.65809 0,-105.55768z") as SvgPathSegmentList;     

В результате получим:

 

Нужно учитывать, что координатная плоскость – это бэнд, на котором расположен объект Кривая или Полигон. Поэтому не важно в каком месте на бэнде вы расположили объект. Отображаться он будет согласно заданным координатам.

Используя второй рассмотренный нами способ создания полигона из скрипта, вы сможете отображать уже созданные ранее векторные рисунки. Нет необходимости тратить уйму времени на ручное создание полигона.

1 ноября 2024

Новые возможности редактора отчетов FastReport VCL

Рассматриваем новые возможности редактора отчетов: выносные линии, подсветка пересекающихся объектов, обновлённые деревья отчетов и данных.
30 октября 2024

Использование стилей при создании отчетов в FastReport VCL

В статье подробно рассматривается одна из новых возможностей FastReport VCL – применение стилей и страниц стилей.
28 октября 2024

Как настроить WSL 2 для работы с FastReport и FastCube

В этой статье попробуем вместе разобраться, как настроить WSL 2 для работы с компонентами FastReport и FastCube в Lazarus для Linux.