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); } }