Первая растеризация

This commit is contained in:
2026-02-24 21:56:15 +03:00
parent ef768e9fe7
commit e5dd455d14
8 changed files with 376 additions and 85 deletions

76
src/render/cpu/draw.zig Normal file
View File

@@ -0,0 +1,76 @@
const std = @import("std");
const Document = @import("../../models/Document.zig");
const pipeline = @import("pipeline.zig");
const line = @import("line.zig");
const ellipse = @import("ellipse.zig");
const broken = @import("broken.zig");
const arc = @import("arc.zig");
const basic_models = @import("../../models/basic_models.zig");
const ImageRect = basic_models.ImageRect;
const ImageSize = basic_models.ImageSize;
const Object = Document.Object;
const DrawContext = pipeline.DrawContext;
const Transform = pipeline.Transform;
fn getLocalTransform(obj: *const Object) Transform {
const pos = if (obj.getProperty(.position)) |p| p.position else basic_models.Point2{ .x = 0, .y = 0 };
const angle = if (obj.getProperty(.angle)) |p| p.angle else 0;
const scale = if (obj.getProperty(.scale)) |p| p.scale else basic_models.Scale2{ .scale_x = 1, .scale_y = 1 };
const opacity = if (obj.getProperty(.opacity)) |p| p.opacity else 1.0;
return .{
.position = pos,
.angle = angle,
.scale = scale,
.opacity = opacity,
};
}
fn isVisible(obj: *const Object) bool {
return if (obj.getProperty(.visible)) |p| p.visible else true;
}
fn drawObject(ctx: *DrawContext, obj: *const Object, parent_transform: Transform) void {
if (!isVisible(obj)) return;
const local = getLocalTransform(obj);
const world = Transform.compose(parent_transform, local);
ctx.setTransform(world);
switch (obj.shape) {
.line => line.draw(ctx, obj),
.ellipse => ellipse.draw(ctx, obj),
.broken => broken.draw(ctx, obj),
.arc => arc.draw(ctx, obj),
}
for (obj.children.items) |*child| {
drawObject(ctx, child, world);
}
}
/// Рекурсивно рисует документ в буфер: сначала корневые объекты по порядку, затем их потомков (каждый следующий поверх предыдущего).
pub fn drawDocument(
pixels: []@import("dvui").Color.PMA,
buf_width: u32,
buf_height: u32,
visible_rect: ImageRect,
document: *const Document,
canvas_size: ImageSize,
) void {
const scale_x: f32 = if (document.size.width > 0) @as(f32, @floatFromInt(canvas_size.w)) / document.size.width else 0;
const scale_y: f32 = if (document.size.height > 0) @as(f32, @floatFromInt(canvas_size.h)) / document.size.height else 0;
var ctx = DrawContext{
.pixels = pixels,
.buf_width = buf_width,
.buf_height = buf_height,
.visible_rect = visible_rect,
.scale_x = scale_x,
.scale_y = scale_y,
};
const identity = Transform{};
for (document.objects.items) |*obj| {
drawObject(&ctx, obj, identity);
}
}