blob: a4de5b74d6a20b37f7bd06ab994f04afc01f1993 [file] [log] [blame]
reedd2e7dfb2014-10-13 19:43:17 -07001function tostr(t)
2 local str = ""
3 for k, v in next, t do
4 if #str > 0 then
5 str = str .. ", "
6 end
7 if type(k) == "number" then
8 str = str .. "[" .. k .. "] = "
9 else
10 str = str .. tostring(k) .. " = "
11 end
12 if type(v) == "table" then
13 str = str .. "{ " .. tostr(v) .. " }"
14 elseif type(v) == "string" then
15 str = str .. '"' .. v .. '"'
16 else
17 str = str .. tostring(v)
18 end
19 end
20 return str
21end
22
23
24function trim_ws(s)
25 return s:match("^%s*(.*)")
26end
27
28function count_hypens(s)
29 local leftover = s:match("^-*(.*)")
30 return string.len(s) - string.len(leftover)
31end
32
33function parse_file(file)
34 local slides = {}
35 local block = {}
36
37 for line in file:lines() do
38 local s = trim_ws(line)
39 if #s == 0 then -- done with a block
40 if #block > 0 then
41 slides[#slides + 1] = block
42 block = {}
43 end
44 else
45 local n = count_hypens(s)
46 block[#block + 1] = {
47 indent = n,
48 text = trim_ws(s:sub(n + 1, -1))
49 }
50 end
51 end
52 return slides
53end
54
55function pretty_print_slide(slide)
56 io.write("{\n")
57 for i = 1, #slide do
58 local node = slide[i]
59 for j = 0, node.indent do
60 io.write(" ")
61 end
62 io.write("{ ")
63 io.write(tostr(node))
64 io.write(" },\n")
65 end
66 io.write("},\n")
67end
68
69function pretty_print_slides(slides)
70 io.write("gSlides = {\n")
71 for i = 1, #slides do
72 pretty_print_slide(slides[i])
73 end
74 io.write("}\n")
75end
76
77gSlides = parse_file(io.open("/skia/trunk/resources/slides_content.lua", "r"))
reed18ea7772014-10-11 11:28:07 -070078
reedbdc49ae2014-10-14 09:34:52 -070079function make_rect(l, t, r, b)
80 return { left = l, top = t, right = r, bottom = b }
81end
82
83function make_paint(typefacename, stylebits, size, color)
reed18ea7772014-10-11 11:28:07 -070084 local paint = Sk.newPaint();
85 paint:setAntiAlias(true)
reed09a1d672014-10-11 13:13:11 -070086 paint:setSubpixelText(true)
reedbdc49ae2014-10-14 09:34:52 -070087 paint:setTypeface(Sk.newTypeface(typefacename, stylebits))
reed18ea7772014-10-11 11:28:07 -070088 paint:setTextSize(size)
89 paint:setColor(color)
90 return paint
91end
92
reedbdc49ae2014-10-14 09:34:52 -070093function drawSlide(canvas, slide, template)
94 template = template.slide -- need to sniff the slide to know if we're title or slide
95
96 local x = template.margin_x
97 local y = template.margin_y
98
reedd2e7dfb2014-10-13 19:43:17 -070099 local scale = 1.15
reedd2e7dfb2014-10-13 19:43:17 -0700100 for i = 1, #slide do
101 local node = slide[i]
reedbdc49ae2014-10-14 09:34:52 -0700102 local paint = template[node.indent + 1]
reedd2e7dfb2014-10-13 19:43:17 -0700103 local fm = paint:getFontMetrics()
reedbdc49ae2014-10-14 09:34:52 -0700104 local x_offset = -fm.ascent * node.indent
105
reedd2e7dfb2014-10-13 19:43:17 -0700106 y = y - fm.ascent * scale
reedbdc49ae2014-10-14 09:34:52 -0700107 canvas:drawText(node.text, x + x_offset, y, paint)
reedd2e7dfb2014-10-13 19:43:17 -0700108 y = y + fm.descent * scale
reed18ea7772014-10-11 11:28:07 -0700109 end
110end
111
reedf355df52014-10-12 12:18:40 -0700112function slide_transition(prev, next, is_forward)
113 local rec = {
114 proc = function(self, canvas, drawSlideProc)
115 if self:isDone() then
116 drawSlideProc(canvas)
117 return nil
118 end
reed96affcd2014-10-13 12:38:04 -0700119 self.prevDrawable:draw(canvas, self.curr_x, 0)
120 self.nextDrawable:draw(canvas, self.curr_x + 640, 0)
reedf355df52014-10-12 12:18:40 -0700121 self.curr_x = self.curr_x + self.step_x
122 return self
123 end
124 }
125 if is_forward then
reed96affcd2014-10-13 12:38:04 -0700126 rec.prevDrawable = prev
127 rec.nextDrawable = next
reedf355df52014-10-12 12:18:40 -0700128 rec.curr_x = 0
129 rec.step_x = -15
130 rec.isDone = function (self) return self.curr_x <= -640 end
131 else
reed96affcd2014-10-13 12:38:04 -0700132 rec.prevDrawable = next
133 rec.nextDrawable = prev
reedf355df52014-10-12 12:18:40 -0700134 rec.curr_x = -640
135 rec.step_x = 15
136 rec.isDone = function (self) return self.curr_x >= 0 end
137 end
138 return rec
139end
140
reed0d76b952014-10-12 19:05:52 -0700141function fade_slide_transition(prev, next, is_forward)
142 local rec = {
reed96affcd2014-10-13 12:38:04 -0700143 prevDrawable = prev,
144 nextDrawable = next,
reed0d76b952014-10-12 19:05:52 -0700145 proc = function(self, canvas, drawSlideProc)
146 if self:isDone() then
147 drawSlideProc(canvas)
148 return nil
149 end
reed96affcd2014-10-13 12:38:04 -0700150 self.prevDrawable:draw(canvas, self.prev_x, 0, self.prev_a)
151 self.nextDrawable:draw(canvas, self.next_x, 0, self.next_a)
reed0d76b952014-10-12 19:05:52 -0700152 self:step()
153 return self
154 end
155 }
156 if is_forward then
157 rec.prev_x = 0
158 rec.prev_a = 1
159 rec.next_x = 640
160 rec.next_a = 0
161 rec.isDone = function (self) return self.next_x <= 0 end
162 rec.step = function (self)
163 self.next_x = self.next_x - 20
164 self.next_a = (640 - self.next_x) / 640
165 self.prev_a = 1 - self.next_a
166 end
167 else
168 rec.prev_x = 0
169 rec.prev_a = 1
170 rec.next_x = 0
171 rec.next_a = 0
172 rec.isDone = function (self) return self.prev_x >= 640 end
173 rec.step = function (self)
174 self.prev_x = self.prev_x + 20
175 self.prev_a = (640 - self.prev_x) / 640
176 self.next_a = 1 - self.prev_a
177 end
178 end
179 return rec
180end
181
reed18ea7772014-10-11 11:28:07 -0700182--------------------------------------------------------------------------------------
183
reedbdc49ae2014-10-14 09:34:52 -0700184function SkiaPoint_make_template()
185 local title = {
186 margin_x = 30,
187 margin_y = 100,
188 }
189 title[1] = make_paint("Arial", 1, 50, { a=1, r=0, g=0, b=0 })
190 title[1]:setTextAlign("center")
191 title[2] = make_paint("Arial", 1, 25, { a=1, r=.3, g=.3, b=.3 })
192 title[2]:setTextAlign("center")
reed18ea7772014-10-11 11:28:07 -0700193
reedbdc49ae2014-10-14 09:34:52 -0700194 local slide = {
195 margin_x = 20,
196 margin_y = 30,
197 }
198 slide[1] = make_paint("Arial", 1, 36, { a=1, r=0, g=0, b=0 })
199 slide[2] = make_paint("Arial", 0, 30, { a=1, r=0, g=0, b=0 })
200 slide[3] = make_paint("Arial", 0, 24, { a=1, r=.2, g=.2, b=.2 })
201
202 return {
203 title = title,
204 slide = slide,
205 }
206end
207
208gTemplate = SkiaPoint_make_template()
reed18ea7772014-10-11 11:28:07 -0700209
210gRedPaint = Sk.newPaint()
211gRedPaint:setAntiAlias(true)
212gRedPaint:setColor{a=1, r=1, g=0, b=0 }
213
reed09a1d672014-10-11 13:13:11 -0700214-- animation.proc is passed the canvas before drawing.
215-- The animation.proc returns itself or another animation (which means keep animating)
216-- or it returns nil, which stops the animation.
217--
218local gCurrAnimation
219
reedf355df52014-10-12 12:18:40 -0700220gSlideIndex = 1
221
222function next_slide()
223 local prev = gSlides[gSlideIndex]
224
225 gSlideIndex = gSlideIndex + 1
226 if gSlideIndex > #gSlides then
227 gSlideIndex = 1
228 end
229
230 spawn_transition(prev, gSlides[gSlideIndex], true)
231end
232
233function prev_slide()
234 local prev = gSlides[gSlideIndex]
235
236 gSlideIndex = gSlideIndex - 1
237 if gSlideIndex < 1 then
238 gSlideIndex = #gSlides
239 end
240
241 spawn_transition(prev, gSlides[gSlideIndex], false)
242end
243
reed96affcd2014-10-13 12:38:04 -0700244function new_drawable_picture(pic)
245 return {
246 picture = pic,
247 width = pic:width(),
248 height = pic:height(),
249 draw = function (self, canvas, x, y, paint)
250 canvas:drawPicture(self.picture, x, y, paint)
251 end
252 }
253end
254
255function new_drawable_image(img)
256 return {
257 image = img,
258 width = img:width(),
259 height = img:height(),
260 draw = function (self, canvas, x, y, paint)
261 canvas:drawImage(self.image, x, y, paint)
262 end
263 }
264end
reedf355df52014-10-12 12:18:40 -0700265
266function spawn_transition(prevSlide, nextSlide, is_forward)
267 local transition
268 if is_forward then
269 transition = prevSlide.transition
270 else
271 transition = nextSlide.transition
272 end
273
274 if not transition then
reedd2e7dfb2014-10-13 19:43:17 -0700275 transition = fade_slide_transition
reedf355df52014-10-12 12:18:40 -0700276 end
277
reed96affcd2014-10-13 12:38:04 -0700278 local rec = Sk.newPictureRecorder()
reedf355df52014-10-12 12:18:40 -0700279
reedbdc49ae2014-10-14 09:34:52 -0700280 drawSlide(rec:beginRecording(640, 480), prevSlide, gTemplate)
reed96affcd2014-10-13 12:38:04 -0700281 local prevDrawable = new_drawable_picture(rec:endRecording())
reedf355df52014-10-12 12:18:40 -0700282
reedbdc49ae2014-10-14 09:34:52 -0700283 drawSlide(rec:beginRecording(640, 480), nextSlide, gTemplate)
reed96affcd2014-10-13 12:38:04 -0700284 local nextDrawable = new_drawable_picture(rec:endRecording())
reedf355df52014-10-12 12:18:40 -0700285
reed96affcd2014-10-13 12:38:04 -0700286 gCurrAnimation = transition(prevDrawable, nextDrawable, is_forward)
reedf355df52014-10-12 12:18:40 -0700287end
288
289--------------------------------------------------------------------------------------
290
reed09a1d672014-10-11 13:13:11 -0700291function spawn_rotate_animation()
292 gCurrAnimation = {
293 angle = 0,
294 angle_delta = 5,
295 pivot_x = 320,
296 pivot_y = 240,
reedf355df52014-10-12 12:18:40 -0700297 proc = function (self, canvas, drawSlideProc)
298 if self.angle >= 360 then
299 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700300 return nil
301 end
reedf355df52014-10-12 12:18:40 -0700302 canvas:translate(self.pivot_x, self.pivot_y)
303 canvas:rotate(self.angle)
304 canvas:translate(-self.pivot_x, -self.pivot_y)
305 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700306
reedf355df52014-10-12 12:18:40 -0700307 self.angle = self.angle + self.angle_delta
308 return self
reed09a1d672014-10-11 13:13:11 -0700309 end
310 }
311end
312
313function spawn_scale_animation()
314 gCurrAnimation = {
315 scale = 1,
316 scale_delta = .95,
317 scale_limit = 0.2,
318 pivot_x = 320,
319 pivot_y = 240,
reedf355df52014-10-12 12:18:40 -0700320 proc = function (self, canvas, drawSlideProc)
321 if self.scale < self.scale_limit then
322 self.scale = self.scale_limit
323 self.scale_delta = 1 / self.scale_delta
reed09a1d672014-10-11 13:13:11 -0700324 end
reedf355df52014-10-12 12:18:40 -0700325 if self.scale > 1 then
326 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700327 return nil
328 end
reedf355df52014-10-12 12:18:40 -0700329 canvas:translate(self.pivot_x, self.pivot_y)
330 canvas:scale(self.scale, self.scale)
331 canvas:translate(-self.pivot_x, -self.pivot_y)
332 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700333
reedf355df52014-10-12 12:18:40 -0700334 self.scale = self.scale * self.scale_delta
335 return self
reed09a1d672014-10-11 13:13:11 -0700336 end
337 }
338end
339
reedbdc49ae2014-10-14 09:34:52 -0700340function onDrawContent(canvas, width, height)
341 local matrix = Sk.newMatrix()
342 matrix:setRectToRect(make_rect(0, 0, 640, 480), make_rect(0, 0, width, height), "center")
343 canvas:concat(matrix)
344
reedf355df52014-10-12 12:18:40 -0700345 local drawSlideProc = function(canvas)
reedbdc49ae2014-10-14 09:34:52 -0700346 drawSlide(canvas, gSlides[gSlideIndex], gTemplate)
reed09a1d672014-10-11 13:13:11 -0700347 end
348
reed09a1d672014-10-11 13:13:11 -0700349 if gCurrAnimation then
reedf355df52014-10-12 12:18:40 -0700350 gCurrAnimation = gCurrAnimation:proc(canvas, drawSlideProc)
reed09a1d672014-10-11 13:13:11 -0700351 return true
352 else
reedf355df52014-10-12 12:18:40 -0700353 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700354 return false
355 end
356end
357
358function onClickHandler(x, y)
359 return false
360end
361
362local keyProcs = {
363 n = next_slide,
364 p = prev_slide,
365 r = spawn_rotate_animation,
366 s = spawn_scale_animation,
367}
368
369function onCharHandler(uni)
370 local proc = keyProcs[uni]
371 if proc then
372 proc()
373 return true
374 end
375 return false
376end