Первая растеризация
This commit is contained in:
76
src/render/cpu/draw.zig
Normal file
76
src/render/cpu/draw.zig
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user