feat: Добавил толщину линий, унифицировал геометрию
Переименовал основные геометрические модели (Point, Size, Rect, Scale, Radii), явно разделив их на типы с плавающей точкой (_f) и целочисленные (_i). Обновил использование этих типов во всем проекте для улучшения типобезопасности и ясности. Ввел новое свойство thickness для объектов и реализовал его применение при отрисовке линий и ломаных. Добавил Point2_i для целочисленных координат буфера в конвейере отрисовки.
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
const std = @import("std");
|
||||
const Document = @import("../../models/Document.zig");
|
||||
const pipeline = @import("pipeline.zig");
|
||||
const DrawContext = pipeline.DrawContext;
|
||||
@@ -6,6 +5,7 @@ const Color = @import("dvui").Color;
|
||||
|
||||
const Object = Document.Object;
|
||||
const default_stroke: Color.PMA = .{ .r = 0, .g = 0, .b = 0, .a = 255 };
|
||||
const default_thickness: f32 = 2.0;
|
||||
|
||||
/// Рисует линию в локальных координатах: от (0,0) до end_point. Растеризация в координатах буфера (без пробелов при зуме).
|
||||
pub fn draw(ctx: *DrawContext, obj: *const Object) void {
|
||||
@@ -13,25 +13,21 @@ pub fn draw(ctx: *DrawContext, obj: *const Object) void {
|
||||
const end_x = ep_prop.end_point.x;
|
||||
const end_y = ep_prop.end_point.y;
|
||||
const stroke = if (obj.getProperty(.stroke_rgba)) |s| pipeline.rgbaToPma(s.stroke_rgba) else default_stroke;
|
||||
|
||||
drawLine(ctx, 0, 0, end_x, end_y, stroke);
|
||||
const thickness = if (obj.getProperty(.thickness)) |t| t.thickness else default_thickness;
|
||||
drawLine(ctx, 0, 0, end_x, end_y, stroke, thickness);
|
||||
}
|
||||
|
||||
/// Линия по локальным координатам фигуры: переводит концы в буфер и рисует в пикселях буфера.
|
||||
pub fn drawLine(ctx: *DrawContext, x0: f32, y0: f32, x1: f32, y1: f32, color: Color.PMA) void {
|
||||
pub fn drawLine(ctx: *DrawContext, x0: f32, y0: f32, x1: f32, y1: f32, color: Color.PMA, thickness: f32) void {
|
||||
const w0 = ctx.localToWorld(x0, y0);
|
||||
const w1 = ctx.localToWorld(x1, y1);
|
||||
const b0 = ctx.worldToBufferF(w0.x, w0.y);
|
||||
const b1 = ctx.worldToBufferF(w1.x, w1.y);
|
||||
const bx0: i32 = @intFromFloat(std.math.round(b0.x));
|
||||
const by0: i32 = @intFromFloat(std.math.round(b0.y));
|
||||
const bx1: i32 = @intFromFloat(std.math.round(b1.x));
|
||||
const by1: i32 = @intFromFloat(std.math.round(b1.y));
|
||||
drawLineInBuffer(ctx, bx0, by0, bx1, by1, color);
|
||||
const b0 = ctx.worldToBuffer(w0.x, w0.y);
|
||||
const b1 = ctx.worldToBuffer(w1.x, w1.y);
|
||||
drawLineInBuffer(ctx, b0.x, b0.y, b1.x, b1.y, color, thickness);
|
||||
}
|
||||
|
||||
/// Брезенхем в координатах буфера; пиксели вне [0, buf_width) x [0, buf_height) пропускаются.
|
||||
pub fn drawLineInBuffer(ctx: *DrawContext, bx0: i32, by0: i32, bx1: i32, by1: i32, color: Color.PMA) void {
|
||||
fn drawLineInBuffer(ctx: *DrawContext, bx0: i32, by0: i32, bx1: i32, by1: i32, color: Color.PMA, thickness: f32) void {
|
||||
const bw: i32 = @intCast(ctx.buf_width);
|
||||
const bh: i32 = @intCast(ctx.buf_height);
|
||||
const dx: i32 = @intCast(@abs(bx1 - bx0));
|
||||
@@ -42,6 +38,8 @@ pub fn drawLineInBuffer(ctx: *DrawContext, bx0: i32, by0: i32, bx1: i32, by1: i3
|
||||
var x = bx0;
|
||||
var y = by0;
|
||||
|
||||
_ = thickness;
|
||||
|
||||
while (true) {
|
||||
if (x >= 0 and x < bw and y >= 0 and y < bh) {
|
||||
ctx.blendPixelAtBuffer(@intCast(x), @intCast(y), color);
|
||||
|
||||
Reference in New Issue
Block a user