Browse Source

Support multi-line output

Luna Stadler 4 years ago
parent
commit
f828d4ac46
1 changed files with 39 additions and 27 deletions
  1. 39 27
      zig/sdl/hello_sdl.zig

+ 39 - 27
zig/sdl/hello_sdl.zig

42
    defer c.TTF_CloseFont(font);
42
    defer c.TTF_CloseFont(font);
43
    c.SDL_Log("Using font %s", font_file.ptr);
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
    // assume monospace font
45
    // assume monospace font
54
    var glyph_width: c_int = 0;
46
    var glyph_width: c_int = 0;
55
    if (c.TTF_GlyphMetrics(font, 'g', null, null, null, null, &glyph_width) != 0) {
47
    if (c.TTF_GlyphMetrics(font, 'g', null, null, null, null, &glyph_width) != 0) {
58
    }
50
    }
59
    var glyph_height = c.TTF_FontLineSkip(font);
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
    var pos: usize = 0;
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
    const keyboardState = c.SDL_GetKeyboardState(null);
69
    const keyboardState = c.SDL_GetKeyboardState(null);
69
70
136
            }
137
            }
137
        }
138
        }
138
139
140
        _ = c.SDL_RenderClear(renderer);
141
139
        // thanks to https://stackoverflow.com/questions/22886500/how-to-render-text-in-sdl2 for some actually useful code here
142
        // thanks to https://stackoverflow.com/questions/22886500/how-to-render-text-in-sdl2 for some actually useful code here
140
        const white: c.SDL_Color = c.SDL_Color{ .r = 255, .g = 255, .b = 255, .a = 255 };
143
        const white: c.SDL_Color = c.SDL_Color{ .r = 255, .g = 255, .b = 255, .a = 255 };
141
        const black: c.SDL_Color = c.SDL_Color{ .r = 0, .g = 0, .b = 0, .a = 255 };
144
        const black: c.SDL_Color = c.SDL_Color{ .r = 0, .g = 0, .b = 0, .a = 255 };
142
        // Shaded vs Solid gives a nicer output, with solid the output
145
        // Shaded vs Solid gives a nicer output, with solid the output
143
        // was squiggly and not aligned with a baseline.
146
        // was squiggly and not aligned with a baseline.
144
        const text = c.TTF_RenderUTF8_Shaded(font, &msg, white, black);
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
        c.SDL_Delay(16);
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
    const cmd = std.mem.trim(u8, std.mem.sliceTo(raw_cmd, 0), &std.ascii.spaces);
175
    const cmd = std.mem.trim(u8, std.mem.sliceTo(raw_cmd, 0), &std.ascii.spaces);
158
    const argv = if (std.mem.startsWith(u8, cmd, "go "))
176
    const argv = if (std.mem.startsWith(u8, cmd, "go "))
159
        &[_][]const u8{ "go", "doc", cmd[3..] }
177
        &[_][]const u8{ "go", "doc", cmd[3..] }
171
        std.debug.print("'{s}' ", .{arg});
189
        std.debug.print("'{s}' ", .{arg});
172
    }
190
    }
173
    const result = try std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv });
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
    std.debug.print("stderr: '{s}'\n", .{result.stderr});
192
    std.debug.print("stderr: '{s}'\n", .{result.stderr});
182
    defer {
193
    defer {
183
        allocator.free(result.stdout);
194
        // FIXME: allocator.free(result.stdout);
184
        allocator.free(result.stderr);
195
        allocator.free(result.stderr);
185
    }
196
    }
186
    return buf;
197
198
    return result.stdout;
187
}
199
}
188
200
189
// tests
201
// tests