76 lines
2.5 KiB
Zig
76 lines
2.5 KiB
Zig
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 Rect_i = basic_models.Rect_i;
|
|
const Size_i = basic_models.Size_i;
|
|
|
|
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_f{ .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_f{ .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: Rect_i,
|
|
document: *const Document,
|
|
canvas_size: Size_i,
|
|
) void {
|
|
const scale_x: f32 = if (document.size.w > 0) @as(f32, @floatFromInt(canvas_size.w)) / document.size.w else 0;
|
|
const scale_y: f32 = if (document.size.h > 0) @as(f32, @floatFromInt(canvas_size.h)) / document.size.h 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);
|
|
}
|
|
}
|