-
-
Save ohai/fb18f6c313ce669911a3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'sdl2' | |
require 'optparse' | |
require 'tmpdir' | |
class App | |
include SDL2 | |
def initialize | |
@width = @height = nil | |
@fullscreen = false | |
end | |
def options | |
opts = OptionParser.new("USAGE: ptool.rb [OPTIONS] PDFFILE") | |
opts.on("-w WIDTH", Integer){|w| @width = w } | |
opts.on("-h HEIGHT", Integer){|h| @height = h } | |
opts.on("-f"){ @fullscreen = true } | |
opts | |
end | |
def run(argv) | |
SDL2.init(SDL2::INIT_EVERYTHING) | |
options.parse!(argv) | |
pdffile = argv.shift | |
show_usage_and_exit if pdffile.nil? | |
open_window | |
Dir.mktmpdir do |dir| | |
prepare_pdf(dir, pdffile) | |
@ppmfiles = Dir.glob(File.join(dir, "/p*.ppm")).sort_by{|path| | |
/p-(\d+)\.ppm\Z/.match(path)[1].to_i | |
} | |
@pages = @ppmfiles.map{|path| @renderer.load_texture(path) } | |
@current = 0 | |
@extra = method(:do_nothing) | |
@blend_modes = [BLENDMODE_NONE, BLENDMODE_BLEND, BLENDMODE_ADD, BLENDMODE_MOD] | |
show_page | |
@renderer.draw_blend_mode = new_blend_mode | |
Mouse::Cursor.hide | |
@add_blend_demo = AddBlendDemo.new(@window, @renderer) | |
loop do | |
while ev = Event.poll | |
quit = handle_event(ev) | |
return if quit | |
end | |
@extra.call | |
sleep 0.01 | |
@renderer.present | |
end | |
end | |
end | |
def show_usage_and_exit | |
print options.help | |
exit | |
end | |
def open_window | |
if @fullscreen | |
mode = desktop_mode() | |
@width ||= mode.w | |
@height ||= mode.h | |
x = y = 0 | |
else | |
@width ||= 640 | |
@height ||= 480 | |
x = y = Window::POS_CENTERED | |
end | |
flags = 0 | |
flags |= Window::FULLSCREEN_DESKTOP if @fullscreen | |
flags |= Window::OPENGL | |
@window = Window.create("ptool", x, y, @width, @height, flags) | |
@renderer = @window.create_renderer(-1, 0) | |
end | |
def desktop_mode | |
window = Window.create("checker", 0, 0, 40, 40, 0) | |
mode = window.display.desktop_mode | |
window.destroy | |
mode | |
end | |
def prepare_pdf(dir, pdffile) | |
prefix = "p" | |
system("pdftoppm", "-scale-to-x", @width.to_s, "-scale-to-y", @height.to_s, | |
pdffile, File.join(dir, prefix)) | |
end | |
def handle_event(ev) | |
case ev | |
when Event::Quit | |
return true | |
when Event::KeyDown | |
case ev.sym | |
when Key::ESCAPE | |
return true | |
when Key::LEFT | |
@current -= 1 | |
@current = 0 if @current < 0 | |
show_page | |
when Key::RIGHT | |
@current += 1 | |
@current = @pages.size - 1 if @current >= @pages.size | |
show_page | |
when Key::R | |
angle = 0.0 | |
@extra = proc{ | |
angle += 0.3 | |
@renderer.clear | |
@renderer.copy_ex(@pages[@current], nil, nil, angle, nil, 0) | |
} | |
when Key::SPACE | |
@extra = method(:do_nothing) | |
show_page | |
when Key::Z | |
scale = 1.0 | |
ds = -0.01 | |
@extra = proc{ | |
scale += ds | |
ds *= -1 if flip_scale?(scale, ds) | |
w = (@width*scale).ceil | |
h = (@height*scale).ceil | |
@renderer.clear | |
@renderer.copy(@pages[@current], nil, Rect.new(0,0,w,h)) | |
} | |
when Key::B | |
@renderer.draw_blend_mode = new_blend_mode | |
when Key::S | |
@extra = method(:do_nothing) | |
when Key::P | |
@extra = proc { | |
case rand(10) | |
when 0 | |
x1 = rand(@width); y1 = rand(@height) | |
x2 = rand(@width); y2 = rand(@height) | |
set_random_color | |
@renderer.draw_line(x1, x2, y1, y2) | |
when 1 | |
set_random_color | |
@renderer.draw_rect(random_rect) | |
when 2 | |
set_random_color | |
@renderer.fill_rect(random_rect) | |
end | |
} | |
when Key::A | |
@add_blend_demo.update | |
end | |
end | |
return false | |
end | |
def show_page | |
page = @pages[@current] | |
@renderer.copy(page, nil, nil) | |
end | |
def do_nothing | |
end | |
def flip_scale?(scale, ds) | |
(scale < 0.5 && ds < 0) || (scale > 1.0 && ds > 0) | |
end | |
def set_random_color | |
@renderer.draw_color = [rand(255), rand(255), rand(255), 128+rand(128)] | |
end | |
def random_rect | |
x = rand(@width) | |
y = rand(@height) | |
Rect.new(x, y, rand(@width - x), rand(@height - y)) | |
end | |
def new_blend_mode | |
new_mode = @blend_modes.shift | |
@blend_modes.push(new_mode) | |
new_mode | |
end | |
class AddBlendDemo | |
def initialize(window, renderer) | |
@window = window | |
@renderer = window.renderer | |
prepare_textures | |
@events = [method(:show_wallpaper), method(:show_flicker), method(:show_blending)] | |
end | |
def prepare_textures | |
@wallpaper = @renderer.load_texture("rftg-wallpaper.jpg") | |
@flicker = @renderer.load_texture("flicker.png") | |
end | |
def update | |
@events.first.call | |
@events.push(@events.shift) | |
end | |
def show_wallpaper | |
@renderer.copy(@wallpaper, nil, nil) | |
end | |
def show_flicker | |
@flicker.blend_mode = SDL2::BLENDMODE_NONE | |
@renderer.copy(@flicker, nil, nil) | |
end | |
def show_blending | |
@renderer.copy(@wallpaper, nil, nil) | |
@flicker.blend_mode = SDL2::BLENDMODE_ADD | |
@renderer.copy(@flicker, nil, nil) | |
end | |
end | |
end | |
if __FILE__ == $0 | |
App.new.run(ARGV) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment