Преглед на файлове

Support multi-line output

Luna Stadler преди 4 години
родител
ревизия
f828d4ac46
променени са 1 файла, в които са добавени 39 реда и са изтрити 27 реда
  1. 39 27
      zig/sdl/hello_sdl.zig

+ 39 - 27
zig/sdl/hello_sdl.zig

@ -42,14 +42,6 @@ pub fn main() !void {
42 42
    defer c.TTF_CloseFont(font);
43 43
    c.SDL_Log("Using font %s", font_file.ptr);
44 44
45
    const screen = c.SDL_CreateWindow("hello fonts", c.SDL_WINDOWPOS_CENTERED, c.SDL_WINDOWPOS_CENTERED, 600, 100, c.SDL_WINDOW_BORDERLESS) orelse {
46
        c.SDL_Log("Unable to create window: %s", c.SDL_GetError());
47
        return error.SDLInitializationFailed;
48
    };
49
    defer c.SDL_DestroyWindow(screen);
50
51
    var surface = c.SDL_GetWindowSurface(screen);
52
53 45
    // assume monospace font
54 46
    var glyph_width: c_int = 0;
55 47
    if (c.TTF_GlyphMetrics(font, 'g', null, null, null, null, &glyph_width) != 0) {
@ -58,12 +50,21 @@ pub fn main() !void {
58 50
    }
59 51
    var glyph_height = c.TTF_FontLineSkip(font);
60 52
61
    var msg = "howdy there, enby! 🐘                                          ".*;
53
    const window_width = glyph_width * 100;
54
    const window_height = glyph_height * 20;
55
    const screen = c.SDL_CreateWindow("hello fonts", c.SDL_WINDOWPOS_CENTERED, c.SDL_WINDOWPOS_CENTERED, window_width, window_height, c.SDL_WINDOW_BORDERLESS) orelse {
56
        c.SDL_Log("Unable to create window: %s", c.SDL_GetError());
57
        return error.SDLInitializationFailed;
58
    };
59
    defer c.SDL_DestroyWindow(screen);
60
61
    const renderer = c.SDL_CreateRenderer(screen, -1, c.SDL_RENDERER_ACCELERATED);
62
63
    var msg = "                                                                                                    ".*;
62 64
    var pos: usize = 0;
63
    var max_chars = std.math.min(@divTrunc(@intCast(usize, surface.*.w), @intCast(usize, glyph_width)), msg.len);
65
    var max_chars = std.math.min(@divTrunc(@intCast(usize, window_width), @intCast(usize, glyph_width)), msg.len);
64 66
65
    var result: ?[*:0]u8 = null;
66
    result = "";
67
    var result: []const u8 = "";
67 68
68 69
    const keyboardState = c.SDL_GetKeyboardState(null);
69 70
@ -136,24 +137,41 @@ pub fn main() !void {
136 137
            }
137 138
        }
138 139
140
        _ = c.SDL_RenderClear(renderer);
141
139 142
        // thanks to https://stackoverflow.com/questions/22886500/how-to-render-text-in-sdl2 for some actually useful code here
140 143
        const white: c.SDL_Color = c.SDL_Color{ .r = 255, .g = 255, .b = 255, .a = 255 };
141 144
        const black: c.SDL_Color = c.SDL_Color{ .r = 0, .g = 0, .b = 0, .a = 255 };
142 145
        // Shaded vs Solid gives a nicer output, with solid the output
143 146
        // was squiggly and not aligned with a baseline.
144 147
        const text = c.TTF_RenderUTF8_Shaded(font, &msg, white, black);
145
        _ = c.SDL_BlitSurface(text, null, surface, null);
146
147
        const result_text = c.TTF_RenderUTF8_Shaded(font, result, white, black);
148
        _ = c.SDL_BlitSurface(result_text, null, surface, &c.SDL_Rect{ .x = 0, .y = glyph_height, .w = surface.*.w, .h = surface.*.h - glyph_height });
148
        const texture = c.SDL_CreateTextureFromSurface(renderer, text);
149
        c.SDL_FreeSurface(text);
150
        _ = c.SDL_RenderCopy(renderer, texture, null, &c.SDL_Rect{ .x = 0, .y = 0, .w = window_width, .h = glyph_height });
151
152
        var i: c_int = 1;
153
        var lines = std.mem.split(result, "\n");
154
        var line = lines.next();
155
        while (line != null) {
156
            const line_c = try gpa.dupeZ(u8, line.?);
157
            const result_text = c.TTF_RenderUTF8_Shaded(font, line_c, white, black);
158
            gpa.free(line_c);
159
            const result_texture = c.SDL_CreateTextureFromSurface(renderer, result_text);
160
            _ = c.SDL_RenderCopy(renderer, result_texture, null, &c.SDL_Rect{ .x = 0, .y = i * glyph_height, .w = @intCast(c_int, line.?.len) * glyph_width, .h = glyph_height });
161
            c.SDL_FreeSurface(result_text);
162
            c.SDL_DestroyTexture(result_texture);
163
164
            i += 1;
165
            line = lines.next();
166
        }
149 167
150
        _ = c.SDL_UpdateWindowSurface(screen);
168
        _ = c.SDL_RenderPresent(renderer);
151 169
152 170
        c.SDL_Delay(16);
153 171
    }
154 172
}
155 173
156
fn runCommand(raw_cmd: []const u8, allocator: *std.mem.Allocator) !?[*:0]u8 {
174
fn runCommand(raw_cmd: []const u8, allocator: *std.mem.Allocator) ![]const u8 {
157 175
    const cmd = std.mem.trim(u8, std.mem.sliceTo(raw_cmd, 0), &std.ascii.spaces);
158 176
    const argv = if (std.mem.startsWith(u8, cmd, "go "))
159 177
        &[_][]const u8{ "go", "doc", cmd[3..] }
@ -171,19 +189,13 @@ fn runCommand(raw_cmd: []const u8, allocator: *std.mem.Allocator) !?[*:0]u8 {
171 189
        std.debug.print("'{s}' ", .{arg});
172 190
    }
173 191
    const result = try std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv });
174
    const buf = try allocator.allocSentinel(u8, 100, 0);
175
    std.mem.copy(u8, buf, result.stdout[0..std.math.min(100, result.stdout.len)]);
176
    var i: usize = result.stdout.len;
177
    while (i < buf.len) : (i += 1) {
178
        buf[i] = ' ';
179
    }
180
    buf[buf.len - 1] = 0;
181 192
    std.debug.print("stderr: '{s}'\n", .{result.stderr});
182 193
    defer {
183
        allocator.free(result.stdout);
194
        // FIXME: allocator.free(result.stdout);
184 195
        allocator.free(result.stderr);
185 196
    }
186
    return buf;
197
198
    return result.stdout;
187 199
}
188 200
189 201
// tests