Skip to content

Instantly share code, notes, and snippets.

@ohai
Created December 13, 2014 04:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ohai/fb18f6c313ce669911a3 to your computer and use it in GitHub Desktop.
Save ohai/fb18f6c313ce669911a3 to your computer and use it in GitHub Desktop.
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