blob: cf1a1a6229fedf3180a9aee368751ac22b307f2e [file] [log] [blame]
reed1b6ab442014-11-03 19:55:41 -08001gShowBounds = false
reed86217d82014-10-25 20:44:40 -07002
3gPath = "/skia/trunk/resources/"
4
5function load_file(file)
reed07dada72014-10-29 20:36:05 -07006 local prev_path = package.path
reed86217d82014-10-25 20:44:40 -07007 package.path = package.path .. ";" .. gPath .. file .. ".lua"
8 require(file)
reed07dada72014-10-29 20:36:05 -07009 package.path = prev_path
reedd2e7dfb2014-10-13 19:43:17 -070010end
11
reed86217d82014-10-25 20:44:40 -070012load_file("slides_utils")
reedd2e7dfb2014-10-13 19:43:17 -070013
reedde330ff2014-11-02 19:19:34 -080014gSlides = parse_file(io.open("/skia/trunk/resources/slides_content2.lua", "r"))
reed18ea7772014-10-11 11:28:07 -070015
reedbdc49ae2014-10-14 09:34:52 -070016function make_rect(l, t, r, b)
17 return { left = l, top = t, right = r, bottom = b }
18end
19
20function make_paint(typefacename, stylebits, size, color)
reed18ea7772014-10-11 11:28:07 -070021 local paint = Sk.newPaint();
22 paint:setAntiAlias(true)
reed09a1d672014-10-11 13:13:11 -070023 paint:setSubpixelText(true)
reedbdc49ae2014-10-14 09:34:52 -070024 paint:setTypeface(Sk.newTypeface(typefacename, stylebits))
reed18ea7772014-10-11 11:28:07 -070025 paint:setTextSize(size)
26 paint:setColor(color)
27 return paint
28end
29
reedbb8a0ab2014-11-03 22:32:07 -080030function center_rect(sw, sh, dst)
31 local dw = dst.right - dst.left
32 local dh = dst.bottom - dst.top
33
34 local rw, rh
35
36 if sw / sh > dw / dh then
37 rw = dw
38 rh = sh * dw / sw
39 else
40 rh = dh
41 rw = sw * dh / sh
42 end
43
44 local x = dst.left + ((sw - rw) / 2)
45 local y = dst.top + ((sh - rh) / 2)
46 return make_rect(x, y, x + rw, y + rh)
47end
48
49function draw_image_centered(canvas, image)
50 local sw = image:width()
51 local sh = image:height()
52 local dstR = center_rect(image:width(), image:height(), make_rect(20, 20, 620, 460))
53 canvas:drawImageRect(image, nil, dstR)
54end
55
reed9e233b22014-11-03 12:18:24 -080056function draw_bullet(canvas, x, y, paint, indent)
57 if 0 == indent then
58 return
59 end
60 local ps = paint:getTextSize()
61 local cx = x - ps * .8
62 local cy = y - ps * .4
63 local radius = ps * .2
64 canvas:drawCircle(cx, cy, radius, paint)
65end
66
reed1b6ab442014-11-03 19:55:41 -080067function stroke_rect(canvas, rect, color)
68 local paint = Sk.newPaint()
69 paint:setStroke(true);
70 paint:setColor(color)
71 canvas:drawRect(rect, paint)
72end
73
reedde330ff2014-11-02 19:19:34 -080074function drawSlide(canvas, slide, master_template)
reedbb8a0ab2014-11-03 22:32:07 -080075
76 if #slide == 1 then
77 template = master_template.title
78 canvas:drawText(slide[1].text, 320, 240, template[1])
79 return
80 end
81
82 template = master_template.slide
reedbdc49ae2014-10-14 09:34:52 -070083
84 local x = template.margin_x
85 local y = template.margin_y
reed9e233b22014-11-03 12:18:24 -080086 local scale = 1.25
reedbdc49ae2014-10-14 09:34:52 -070087
reedde330ff2014-11-02 19:19:34 -080088 if slide.blockstyle == "code" then
89 local paint = master_template.codePaint
90 local fm = paint:getFontMetrics()
91 local height = #slide * (fm.descent - fm.ascent)
92 y = (480 - height) / 2
93 for i = 1, #slide do
94 local node = slide[i]
reed9e233b22014-11-03 12:18:24 -080095 y = y - fm.ascent * scale
reedde330ff2014-11-02 19:19:34 -080096 canvas:drawText(node.text, x, y, paint)
reed9e233b22014-11-03 12:18:24 -080097 y = y + fm.descent * scale
reedde330ff2014-11-02 19:19:34 -080098 end
99 return
100 end
101
reedd2e7dfb2014-10-13 19:43:17 -0700102 for i = 1, #slide do
103 local node = slide[i]
reed9fbc3f32014-10-21 07:12:58 -0700104 local paint = template[node.indent + 1].paint
105 local extra_dy = template[node.indent + 1].extra_dy
reedd2e7dfb2014-10-13 19:43:17 -0700106 local fm = paint:getFontMetrics()
reed9e233b22014-11-03 12:18:24 -0800107 local x_offset = -fm.ascent * node.indent * 1.25
reedbdc49ae2014-10-14 09:34:52 -0700108
reed1b6ab442014-11-03 19:55:41 -0800109 local bounds = make_rect(x + x_offset, y, 620, 640)
110 local blob, newBottom = Sk.newTextBlob(node.text, bounds, paint)
111 draw_bullet(canvas, x + x_offset, y - fm.ascent, paint, node.indent)
112 canvas:drawTextBlob(blob, 0, 0, paint)
113 y = newBottom + paint:getTextSize() * .5
114
115 if gShowBounds then
116 bounds.bottom = newBottom
117 stroke_rect(canvas, bounds, {a=1,r=0,g=1,b=0})
118 stroke_rect(canvas, blob:bounds(), {a=1,r=1,g=0,b=0})
119 end
120
reed9fbc3f32014-10-21 07:12:58 -0700121 end
122end
123
reed18ea7772014-10-11 11:28:07 -0700124--------------------------------------------------------------------------------------
reed9fbc3f32014-10-21 07:12:58 -0700125function make_tmpl(paint, extra_dy)
126 return { paint = paint, extra_dy = extra_dy }
127end
reed18ea7772014-10-11 11:28:07 -0700128
reedbdc49ae2014-10-14 09:34:52 -0700129function SkiaPoint_make_template()
130 local title = {
131 margin_x = 30,
132 margin_y = 100,
133 }
reed9e233b22014-11-03 12:18:24 -0800134 title[1] = make_paint("Arial", 1, 45, { a=1, r=1, g=1, b=1 })
reedbdc49ae2014-10-14 09:34:52 -0700135 title[1]:setTextAlign("center")
reed9fbc3f32014-10-21 07:12:58 -0700136 title[2] = make_paint("Arial", 1, 25, { a=1, r=.75, g=.75, b=.75 })
reedbdc49ae2014-10-14 09:34:52 -0700137 title[2]:setTextAlign("center")
reed18ea7772014-10-11 11:28:07 -0700138
reedbdc49ae2014-10-14 09:34:52 -0700139 local slide = {
140 margin_x = 20,
reed9fbc3f32014-10-21 07:12:58 -0700141 margin_y = 25,
reedbdc49ae2014-10-14 09:34:52 -0700142 }
reed9e233b22014-11-03 12:18:24 -0800143 slide[1] = make_tmpl(make_paint("Arial", 1, 35, { a=1, r=1, g=1, b=1 }), 18)
144 slide[2] = make_tmpl(make_paint("Arial", 0, 25, { a=1, r=1, g=1, b=1 }), 0)
145 slide[3] = make_tmpl(make_paint("Arial", 0, 20, { a=1, r=.9, g=.9, b=.9 }), 0)
reedbdc49ae2014-10-14 09:34:52 -0700146
147 return {
148 title = title,
149 slide = slide,
reed9e233b22014-11-03 12:18:24 -0800150 codePaint = make_paint("Courier", 0, 20, { a=1, r=.9, g=.9, b=.9 }),
reedbdc49ae2014-10-14 09:34:52 -0700151 }
152end
153
154gTemplate = SkiaPoint_make_template()
reed18ea7772014-10-11 11:28:07 -0700155
156gRedPaint = Sk.newPaint()
157gRedPaint:setAntiAlias(true)
158gRedPaint:setColor{a=1, r=1, g=0, b=0 }
159
reed09a1d672014-10-11 13:13:11 -0700160-- animation.proc is passed the canvas before drawing.
161-- The animation.proc returns itself or another animation (which means keep animating)
162-- or it returns nil, which stops the animation.
163--
164local gCurrAnimation
165
reedf355df52014-10-12 12:18:40 -0700166gSlideIndex = 1
167
reed96affcd2014-10-13 12:38:04 -0700168function new_drawable_picture(pic)
169 return {
170 picture = pic,
171 width = pic:width(),
172 height = pic:height(),
173 draw = function (self, canvas, x, y, paint)
174 canvas:drawPicture(self.picture, x, y, paint)
175 end
176 }
177end
178
179function new_drawable_image(img)
180 return {
181 image = img,
182 width = img:width(),
183 height = img:height(),
184 draw = function (self, canvas, x, y, paint)
185 canvas:drawImage(self.image, x, y, paint)
186 end
187 }
188end
reedf355df52014-10-12 12:18:40 -0700189
reed86217d82014-10-25 20:44:40 -0700190function new_drawable_slide(slide)
191 return {
192 slide = slide,
193 draw = function (self, canvas, x, y, paint)
194 if (nil == paint or ("number" == type(paint) and (1 == paint))) then
195 canvas:save()
196 else
197 canvas:saveLayer(paint)
198 end
199 canvas:translate(x, y)
200 drawSlide(canvas, self.slide, gTemplate)
201 canvas:restore()
202 end
203 }
204end
205
206function next_slide()
207 local prev = gSlides[gSlideIndex]
208
reedbb8a0ab2014-11-03 22:32:07 -0800209 if gSlideIndex < #gSlides then
210 gSlideIndex = gSlideIndex + 1
211 spawn_transition(prev, gSlides[gSlideIndex], true)
reed86217d82014-10-25 20:44:40 -0700212 end
reed86217d82014-10-25 20:44:40 -0700213end
214
215function prev_slide()
216 local prev = gSlides[gSlideIndex]
217
reedbb8a0ab2014-11-03 22:32:07 -0800218 if gSlideIndex > 1 then
219 gSlideIndex = gSlideIndex - 1
220 spawn_transition(prev, gSlides[gSlideIndex], false)
reed86217d82014-10-25 20:44:40 -0700221 end
reed86217d82014-10-25 20:44:40 -0700222end
223
reed468b1812014-10-19 11:42:54 -0700224function convert_to_picture_drawable(slide)
225 local rec = Sk.newPictureRecorder()
226 drawSlide(rec:beginRecording(640, 480), slide, gTemplate)
227 return new_drawable_picture(rec:endRecording())
228end
229
230function convert_to_image_drawable(slide)
231 local surf = Sk.newRasterSurface(640, 480)
232 drawSlide(surf:getCanvas(), slide, gTemplate)
233 return new_drawable_image(surf:newImageSnapshot())
234end
235
reed86217d82014-10-25 20:44:40 -0700236gMakeDrawable = new_drawable_slide
reed468b1812014-10-19 11:42:54 -0700237
reed07dada72014-10-29 20:36:05 -0700238load_file("slides_transitions")
239
reedf355df52014-10-12 12:18:40 -0700240function spawn_transition(prevSlide, nextSlide, is_forward)
241 local transition
242 if is_forward then
reed07dada72014-10-29 20:36:05 -0700243 transition = gTransitionTable[nextSlide.transition]
reedf355df52014-10-12 12:18:40 -0700244 else
reed07dada72014-10-29 20:36:05 -0700245 transition = gTransitionTable[prevSlide.transition]
reedf355df52014-10-12 12:18:40 -0700246 end
247
248 if not transition then
reedd2e7dfb2014-10-13 19:43:17 -0700249 transition = fade_slide_transition
reedf355df52014-10-12 12:18:40 -0700250 end
251
reed468b1812014-10-19 11:42:54 -0700252 local prevDrawable = gMakeDrawable(prevSlide)
253 local nextDrawable = gMakeDrawable(nextSlide)
reed96affcd2014-10-13 12:38:04 -0700254 gCurrAnimation = transition(prevDrawable, nextDrawable, is_forward)
reedf355df52014-10-12 12:18:40 -0700255end
256
257--------------------------------------------------------------------------------------
258
reed09a1d672014-10-11 13:13:11 -0700259function spawn_rotate_animation()
260 gCurrAnimation = {
261 angle = 0,
262 angle_delta = 5,
263 pivot_x = 320,
264 pivot_y = 240,
reedf355df52014-10-12 12:18:40 -0700265 proc = function (self, canvas, drawSlideProc)
266 if self.angle >= 360 then
267 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700268 return nil
269 end
reedf355df52014-10-12 12:18:40 -0700270 canvas:translate(self.pivot_x, self.pivot_y)
271 canvas:rotate(self.angle)
272 canvas:translate(-self.pivot_x, -self.pivot_y)
273 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700274
reedf355df52014-10-12 12:18:40 -0700275 self.angle = self.angle + self.angle_delta
276 return self
reed09a1d672014-10-11 13:13:11 -0700277 end
278 }
279end
280
281function spawn_scale_animation()
282 gCurrAnimation = {
283 scale = 1,
284 scale_delta = .95,
285 scale_limit = 0.2,
286 pivot_x = 320,
287 pivot_y = 240,
reedf355df52014-10-12 12:18:40 -0700288 proc = function (self, canvas, drawSlideProc)
289 if self.scale < self.scale_limit then
290 self.scale = self.scale_limit
291 self.scale_delta = 1 / self.scale_delta
reed09a1d672014-10-11 13:13:11 -0700292 end
reedf355df52014-10-12 12:18:40 -0700293 if self.scale > 1 then
294 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700295 return nil
296 end
reedf355df52014-10-12 12:18:40 -0700297 canvas:translate(self.pivot_x, self.pivot_y)
298 canvas:scale(self.scale, self.scale)
299 canvas:translate(-self.pivot_x, -self.pivot_y)
300 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700301
reedf355df52014-10-12 12:18:40 -0700302 self.scale = self.scale * self.scale_delta
303 return self
reed09a1d672014-10-11 13:13:11 -0700304 end
305 }
306end
307
reed9fbc3f32014-10-21 07:12:58 -0700308local bgPaint = nil
309
310function draw_bg(canvas)
311 if not bgPaint then
312 bgPaint = Sk.newPaint()
313 local grad = Sk.newLinearGradient( 0, 0, { a=1, r=0, g=0, b=.3 },
314 640, 480, { a=1, r=0, g=0, b=.8 })
315 bgPaint:setShader(grad)
reedbb8a0ab2014-11-03 22:32:07 -0800316 bgPaint:setDither(true)
reed9fbc3f32014-10-21 07:12:58 -0700317 end
318
319 canvas:drawPaint(bgPaint)
320end
321
reedbdc49ae2014-10-14 09:34:52 -0700322function onDrawContent(canvas, width, height)
323 local matrix = Sk.newMatrix()
324 matrix:setRectToRect(make_rect(0, 0, 640, 480), make_rect(0, 0, width, height), "center")
325 canvas:concat(matrix)
326
reed9fbc3f32014-10-21 07:12:58 -0700327 draw_bg(canvas)
328
reedf355df52014-10-12 12:18:40 -0700329 local drawSlideProc = function(canvas)
reedbdc49ae2014-10-14 09:34:52 -0700330 drawSlide(canvas, gSlides[gSlideIndex], gTemplate)
reed09a1d672014-10-11 13:13:11 -0700331 end
332
reed09a1d672014-10-11 13:13:11 -0700333 if gCurrAnimation then
reedf355df52014-10-12 12:18:40 -0700334 gCurrAnimation = gCurrAnimation:proc(canvas, drawSlideProc)
reed09a1d672014-10-11 13:13:11 -0700335 return true
336 else
reedf355df52014-10-12 12:18:40 -0700337 drawSlideProc(canvas)
reed09a1d672014-10-11 13:13:11 -0700338 return false
339 end
340end
341
342function onClickHandler(x, y)
343 return false
344end
345
346local keyProcs = {
347 n = next_slide,
348 p = prev_slide,
349 r = spawn_rotate_animation,
350 s = spawn_scale_animation,
reedc7663982014-10-21 10:46:01 -0700351 ["="] = function () scale_text_delta(gTemplate, 1) end,
352 ["-"] = function () scale_text_delta(gTemplate, -1) end,
reed1b6ab442014-11-03 19:55:41 -0800353
354 b = function () gShowBounds = not gShowBounds end,
reed09a1d672014-10-11 13:13:11 -0700355}
356
357function onCharHandler(uni)
358 local proc = keyProcs[uni]
359 if proc then
360 proc()
361 return true
362 end
363 return false
364end