diff --git a/Report/sample_1.pdf b/Report/sample_1.pdf index 0cb8e30..18dd216 100644 Binary files a/Report/sample_1.pdf and b/Report/sample_1.pdf differ diff --git a/Report/zivro-open-project-report-with-code.md b/Report/zivro-open-project-report-with-code.md index 05ad92e..9afc05d 100644 --- a/Report/zivro-open-project-report-with-code.md +++ b/Report/zivro-open-project-report-with-code.md @@ -124,6 +124,14 @@ y_w &= t_y + (x_l \cdot s_x)\sin a + (y_l \cdot s_y)\cos a. \end{aligned} $$ +Обозначения: + +- `x_l, y_l` - локальные координаты точки объекта; +- `x_w, y_w` - мировые координаты точки в документе; +- `t_x, t_y` - перенос (`position`) текущего transform; +- `s_x, s_y` - масштаб по осям (`scale_x`, `scale_y`); +- `a` - угол поворота объекта (в радианах). + При композиции `parent * local` (в `Transform.compose`) выполняются шаги: 1. локальная позиция сначала масштабируется масштабом родителя; @@ -164,6 +172,15 @@ y_l &= \frac{dx\sin(-a)+dy\cos(-a)}{s_y}. \end{aligned} $$ +Обозначения: + +- `x_w, y_w` - мировые координаты точки; +- `x_l, y_l` - локальные координаты точки после обратного преобразования; +- `t_x, t_y` - перенос transform; +- `a` - угол поворота transform; +- `s_x, s_y` - масштаб transform; +- `dx, dy` - координаты точки после вычитания переноса. + Практический смысл: shape можно тестировать аналитически (по формулам) в "своей" удобной локальной системе, независимо от того, как он повернут и где расположен в документе. ### 6.3. Рисование линии: отсечение + дискретизация + толщина @@ -179,6 +196,13 @@ $$ P(t)=P_0+t(P_1-P_0),\quad t\in[0,1]. $$ +Обозначения: + +- `P_0, P_1` - начальная и конечная точки исходного отрезка; +- `P(t)` - точка на отрезке при параметре `t`; +- `t` - параметр интерполяции (`0` - начало, `1` - конец); +- `[t0, t1]` - допустимый интервал параметра после отсечения. + Для каждого ограничения (`x >= left`, `x <= right`, `y >= top`, `y <= bottom`) обновляется допустимый интервал `[t0, t1]`. Если после обработки ограничений `t0 > t1`, отрезок полностью вне экрана и пропускается. @@ -229,6 +253,13 @@ $$ n_x = \frac{x_l}{r_x},\quad n_y = \frac{y_l}{r_y},\quad d=n_x^2+n_y^2. $$ +Обозначения: + +- `x_l, y_l` - локальные координаты текущего пикселя (центра пикселя после обратного преобразования); +- `r_x, r_y` - полуоси эллипса по `x` и `y`; +- `n_x, n_y` - нормализованные координаты в системе эллипса; +- `d` - значение функции эллипса в нормализованной форме. + - `d = 1` соответствует идеальному контуру эллипса; - `d < 1` внутри; - `d > 1` снаружи. @@ -247,6 +278,12 @@ $$ inner^2 \le d \le outer^2. $$ +Обозначения: + +- `d` - нормализованная квадратичная дистанция из предыдущей формулы; +- `inner` - внутренний радиус полосы обводки в нормализованном пространстве; +- `outer` - внешний радиус полосы обводки в нормализованном пространстве. + Это даёт геометрически корректную полосу вокруг эллипса при произвольном повороте/масштабе объекта. #### 6.4.3. Дуга через угловой фильтр @@ -263,7 +300,7 @@ $$ В `broken.zig` ломаная строится как цепочка сегментов `P0->P1->...->Pn`, а при `closed` добавляется `Pn->P0`. -Для корректной заливки применяется двухфазный алгоритм. +Для корректной заливки применяется трёхфазный алгоритм. #### 6.5.1. Фаза 1: сбор пикселей границы @@ -303,6 +340,15 @@ C_{out} = C_{src} + (1-\alpha_{src})C_{dst}, \alpha_{out} = \alpha_{src} + (1-\alpha_{src})\alpha_{dst}. $$ +Обозначения: + +- `C_src` - цвет источника в PMA (`r,g,b` уже домножены на альфу); +- `C_dst` - текущий цвет пикселя в буфере до смешивания; +- `C_out` - результат смешивания; +- `\alpha_src` - альфа источника (с учётом `transform.opacity`); +- `\alpha_dst` - альфа пикселя назначения; +- `\alpha_out` - итоговая альфа после композиции. + В коде `C_src` уже premultiplied (или домножается на opacity трансформа в момент смешивания). Пошагово: @@ -1848,7 +1894,7 @@ pub fn example(self: CpuRenderEngine, canvas_size: Size_i, visible_rect: Rect_i) .Squares => renderSquares(pixels, canvas_size, visible_rect), } - return try dvui.textureCreate(pixels, width, height, .nearest, .rgba_8_8_8_8); + return try dvui.textureCreate(pixels, width, height, .nearest, .abgr_8_8_8_8); } pub fn renderEngine(self: *CpuRenderEngine) RenderEngine { @@ -1867,7 +1913,7 @@ pub fn renderDocument(self: *CpuRenderEngine, document: *const Document, canvas_ try cpu_draw.drawDocument(pixels, width, height, visible_rect, document, canvas_size, self._allocator); self._renderStats.render_time_ns = t.read(); - return try dvui.textureCreate(pixels, width, height, .nearest, .rgba_8_8_8_8); + return try dvui.textureCreate(pixels, width, height, .nearest, .abgr_8_8_8_8); } pub fn getStats(self: CpuRenderEngine) RenderStats { @@ -1919,7 +1965,7 @@ pub const RenderEngine = union(enum) { ```zig const RenderStats = @This(); -render_time_ns: u64, // Время рендера кадра в микросекундах +render_time_ns: u64, // Время рендера кадра в наносекундах ``` ### A.20. `src/render/cpu/broken.zig`