-
Notifications
You must be signed in to change notification settings - Fork 1
/
ledsign_text_renderer
executable file
·114 lines (106 loc) · 4.13 KB
/
ledsign_text_renderer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/opt/local/bin/ruby1.9
require 'sinatra'
require 'cairo'
require 'pango'
require 'bmix'
# set :port, 9494
ALIGN={"center"=>Pango::ALIGN_CENTER,"left"=>Pango::ALIGN_LEFT,"right"=>Pango::ALIGN_RIGHT}
def get_resized_font_size(surface, layout, font_name, font_size, font_min_size)
font_desired_size = font_size
fontdesc = Pango::FontDescription.new("#{font_name} #{font_size}")
layout.set_font_description fontdesc
while(layout.pixel_extents[1].width > surface.width \
|| layout.pixel_extents[1].height > surface.height) do
font_size -= 1
fontdesc.set_size font_size * Pango::SCALE
layout.set_font_description fontdesc
if(font_size < font_min_size) then
# we can't render this much text big enough to be readable
# set the font size back to what we were given originally and give up
font_size = font_desired_size
fontdesc.set_size font_size * Pango::SCALE
layout.set_font_description fontdesc
return -1
end
end
font_size
end
def scroll_text(surface, ctx, layout, voffset, bmix)
left = 0
frame = 0
sleep_time = 0.025
step = 2
layout.set_width -1 # don't wrap if we're scrolling
scroll_seconds = (layout.pixel_extents[1].width + surface.width) / step * sleep_time
while(scroll_seconds > 8) do
scroll_seconds = (layout.pixel_extents[1].width + surface.width) / step * sleep_time
step += 1
end
puts "Expecting to scroll text for #{scroll_seconds} seconds using step #{step}."
while(layout.pixel_extents[1].width + left >= surface.width - 3) do
frame += 1
ctx.move_to left, voffset
ctx.set_source_color(:black)
ctx.paint
ctx.set_source_color(:white)
ctx.show_pango_layout layout
bmix.send_frame surface
sleep 0.025
left -= step
end
return "Successfully rendered #{frame} frames of scrolling text."
end
get '/signservice/SignService' do
msg = params[:Message] || "Get Ready For A Whole Bunch of Ostriches and Cats"
wrap = params[:WrapMethod] || 'best'
font_name = params[:FontName] || "Sans"
font_size_str = params[:FontSize] || "12"
font_size = font_size_str.to_i
font_min_size_str = params[:FontMinSize] || "6"
font_min_size = font_min_size_str.to_i
alignment = ALIGN["center"]
text_align = params[:Align] || "center"
alignment = ALIGN[text_align] if ALIGN.has_key?text_align
port_str = params[:Port] || "2324"
port = port_str.to_i
voffset_str = params[:VOffset] || "0"
voffset = voffset_str.to_i
bmix = Bmix::Sender.new("sign0.hacklab.to",port)
surface = Cairo::ImageSurface.new(Cairo::Format::ARGB32, 96, 32)
ctx = Cairo::Context.new(surface)
ctx.set_source_color(:white)
layout = ctx.create_pango_layout
ctx.move_to 0,voffset
# puts "MSG: #{msg}"
layout.set_text(msg)
fontdesc = Pango::FontDescription.new("#{font_name} #{font_size}")
layout.set_font_description fontdesc
case wrap
when 'wrap'
layout.set_wrap(Pango::WRAP_WORD)
when 'resize'
layout.set_width surface.width * Pango::SCALE
font_size = get_resized_font_size(surface, layout, font_name, font_size, font_min_size)
if(font_size < 0) then
return "Unable to render #{msg.length} characters of text in a readable font."
end
fontdesc = Pango::FontDescription.new("#{font_name} #{font_size}")
layout.set_font_description fontdesc
when 'best'
# try to resize the text to fit, if it won't fit then scroll it
layout.set_width surface.width * Pango::SCALE
font_size = get_resized_font_size(surface, layout, font_name, font_size, font_min_size)
if(font_size < 0) then
return scroll_text surface, ctx, layout, voffset, bmix
end
fontdesc = Pango::FontDescription.new("#{font_name} #{font_size}")
layout.set_font_description fontdesc
when 'scroll'
return scroll_text surface, ctx, layout, voffset, bmix
end
layout.set_width surface.width * Pango::SCALE
layout.set_alignment alignment
ctx.show_pango_layout layout
bmix.send_frame surface
"Successfully rendered #{msg.length} characters to the sign in size #{font_size} using wrap method '#{wrap}'. Extents are #{layout.pixel_extents[1].width} x #{layout.pixel_extents[1].height}."
end