11b6ab4417e0edef3b91d150e6650205f49f04d17reedgShowBounds = false
27b8646669f5b1e2daddf53764bcde62d743ff076reedgUseBlurInTransitions = false
318ea777638f1494b068ba4ca1a5d6725a0e80cf1reed
486217d831d70949f9dde6a60f821d3f357558bdfreedgPath = "/skia/trunk/resources/"
5d2e7dfba212557e2ef7c570c297b00683a603916reed
686217d831d70949f9dde6a60f821d3f357558bdfreedfunction load_file(file)
707dada770b0af4955031806f0c1b8016fa49b65ereed    local prev_path = package.path
886217d831d70949f9dde6a60f821d3f357558bdfreed    package.path = package.path .. ";" .. gPath .. file .. ".lua"
986217d831d70949f9dde6a60f821d3f357558bdfreed    require(file)
1007dada770b0af4955031806f0c1b8016fa49b65ereed    package.path = prev_path
11d2e7dfba212557e2ef7c570c297b00683a603916reedend
12d2e7dfba212557e2ef7c570c297b00683a603916reed
1386217d831d70949f9dde6a60f821d3f357558bdfreedload_file("slides_utils")
14d2e7dfba212557e2ef7c570c297b00683a603916reed
15de330ffc5632b91a1025235e4633a1ddbb846aa4reedgSlides = parse_file(io.open("/skia/trunk/resources/slides_content2.lua", "r"))
16d2e7dfba212557e2ef7c570c297b00683a603916reed
17bdc49ae0d422b8fe1957af570c4f4e63272f5285reedfunction make_rect(l, t, r, b)
18bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    return { left = l, top = t, right = r, bottom = b }
19bdc49ae0d422b8fe1957af570c4f4e63272f5285reedend
20bdc49ae0d422b8fe1957af570c4f4e63272f5285reed
21bdc49ae0d422b8fe1957af570c4f4e63272f5285reedfunction make_paint(typefacename, stylebits, size, color)
22d2e7dfba212557e2ef7c570c297b00683a603916reed    local paint = Sk.newPaint();
23d2e7dfba212557e2ef7c570c297b00683a603916reed    paint:setAntiAlias(true)
24d2e7dfba212557e2ef7c570c297b00683a603916reed    paint:setSubpixelText(true)
25bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    paint:setTypeface(Sk.newTypeface(typefacename, stylebits))
26d2e7dfba212557e2ef7c570c297b00683a603916reed    paint:setTextSize(size)
27d2e7dfba212557e2ef7c570c297b00683a603916reed    paint:setColor(color)
28d2e7dfba212557e2ef7c570c297b00683a603916reed    return paint
2918ea777638f1494b068ba4ca1a5d6725a0e80cf1reedend
3018ea777638f1494b068ba4ca1a5d6725a0e80cf1reed
319e233b2082f685401b985472036fe7f95f35c93areedfunction draw_bullet(canvas, x, y, paint, indent)
329e233b2082f685401b985472036fe7f95f35c93areed    if 0 == indent then
339e233b2082f685401b985472036fe7f95f35c93areed        return
349e233b2082f685401b985472036fe7f95f35c93areed    end
359e233b2082f685401b985472036fe7f95f35c93areed    local ps = paint:getTextSize()
369e233b2082f685401b985472036fe7f95f35c93areed    local cx = x - ps * .8
379e233b2082f685401b985472036fe7f95f35c93areed    local cy = y - ps * .4
389e233b2082f685401b985472036fe7f95f35c93areed    local radius = ps * .2
399e233b2082f685401b985472036fe7f95f35c93areed    canvas:drawCircle(cx, cy, radius, paint)
409e233b2082f685401b985472036fe7f95f35c93areedend
419e233b2082f685401b985472036fe7f95f35c93areed
421b6ab4417e0edef3b91d150e6650205f49f04d17reedfunction stroke_rect(canvas, rect, color)
431b6ab4417e0edef3b91d150e6650205f49f04d17reed    local paint = Sk.newPaint()
441b6ab4417e0edef3b91d150e6650205f49f04d17reed    paint:setStroke(true);
451b6ab4417e0edef3b91d150e6650205f49f04d17reed    paint:setColor(color)
461b6ab4417e0edef3b91d150e6650205f49f04d17reed    canvas:drawRect(rect, paint)
471b6ab4417e0edef3b91d150e6650205f49f04d17reedend
481b6ab4417e0edef3b91d150e6650205f49f04d17reed
49de330ffc5632b91a1025235e4633a1ddbb846aa4reedfunction drawSlide(canvas, slide, master_template)
50bb8a0ababab1aa2693a2a97733524ee367da1791reed
51bb8a0ababab1aa2693a2a97733524ee367da1791reed    if #slide == 1 then
52bb8a0ababab1aa2693a2a97733524ee367da1791reed        template = master_template.title
53bb8a0ababab1aa2693a2a97733524ee367da1791reed        canvas:drawText(slide[1].text, 320, 240, template[1])
54bb8a0ababab1aa2693a2a97733524ee367da1791reed        return
55bb8a0ababab1aa2693a2a97733524ee367da1791reed    end
56bb8a0ababab1aa2693a2a97733524ee367da1791reed
57bb8a0ababab1aa2693a2a97733524ee367da1791reed    template = master_template.slide
58bdc49ae0d422b8fe1957af570c4f4e63272f5285reed
59bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    local x = template.margin_x
60bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    local y = template.margin_y
619e233b2082f685401b985472036fe7f95f35c93areed    local scale = 1.25
62bdc49ae0d422b8fe1957af570c4f4e63272f5285reed
63de330ffc5632b91a1025235e4633a1ddbb846aa4reed    if slide.blockstyle == "code" then
64de330ffc5632b91a1025235e4633a1ddbb846aa4reed        local paint = master_template.codePaint
65de330ffc5632b91a1025235e4633a1ddbb846aa4reed        local fm = paint:getFontMetrics()
66de330ffc5632b91a1025235e4633a1ddbb846aa4reed        local height = #slide * (fm.descent - fm.ascent)
67de330ffc5632b91a1025235e4633a1ddbb846aa4reed        y = (480 - height) / 2
68de330ffc5632b91a1025235e4633a1ddbb846aa4reed        for i = 1, #slide do
69de330ffc5632b91a1025235e4633a1ddbb846aa4reed            local node = slide[i]
709e233b2082f685401b985472036fe7f95f35c93areed            y = y - fm.ascent * scale
71de330ffc5632b91a1025235e4633a1ddbb846aa4reed            canvas:drawText(node.text, x, y, paint)
729e233b2082f685401b985472036fe7f95f35c93areed            y = y + fm.descent * scale
73de330ffc5632b91a1025235e4633a1ddbb846aa4reed        end
74de330ffc5632b91a1025235e4633a1ddbb846aa4reed        return
75de330ffc5632b91a1025235e4633a1ddbb846aa4reed    end
76de330ffc5632b91a1025235e4633a1ddbb846aa4reed
77d2e7dfba212557e2ef7c570c297b00683a603916reed    for i = 1, #slide do
78d2e7dfba212557e2ef7c570c297b00683a603916reed        local node = slide[i]
799fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed        local paint = template[node.indent + 1].paint
809fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed        local extra_dy = template[node.indent + 1].extra_dy
81d2e7dfba212557e2ef7c570c297b00683a603916reed        local fm = paint:getFontMetrics()
829e233b2082f685401b985472036fe7f95f35c93areed        local x_offset = -fm.ascent * node.indent * 1.25
83bdc49ae0d422b8fe1957af570c4f4e63272f5285reed
841b6ab4417e0edef3b91d150e6650205f49f04d17reed        local bounds = make_rect(x + x_offset, y, 620, 640)
851b6ab4417e0edef3b91d150e6650205f49f04d17reed        local blob, newBottom = Sk.newTextBlob(node.text, bounds, paint)
861b6ab4417e0edef3b91d150e6650205f49f04d17reed        draw_bullet(canvas, x + x_offset, y - fm.ascent, paint, node.indent)
871b6ab4417e0edef3b91d150e6650205f49f04d17reed        canvas:drawTextBlob(blob, 0, 0, paint)
8836c9c11ed97d6c6f49bfdad53537a459b9e4b41dreed        y = newBottom + paint:getTextSize() * .5 + extra_dy
891b6ab4417e0edef3b91d150e6650205f49f04d17reed
901b6ab4417e0edef3b91d150e6650205f49f04d17reed        if gShowBounds then
911b6ab4417e0edef3b91d150e6650205f49f04d17reed            bounds.bottom = newBottom
921b6ab4417e0edef3b91d150e6650205f49f04d17reed            stroke_rect(canvas, bounds, {a=1,r=0,g=1,b=0})
931b6ab4417e0edef3b91d150e6650205f49f04d17reed            stroke_rect(canvas, blob:bounds(), {a=1,r=1,g=0,b=0})
941b6ab4417e0edef3b91d150e6650205f49f04d17reed        end
951b6ab4417e0edef3b91d150e6650205f49f04d17reed
969fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed    end
979fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reedend
989fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed
9918ea777638f1494b068ba4ca1a5d6725a0e80cf1reed--------------------------------------------------------------------------------------
1009fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reedfunction make_tmpl(paint, extra_dy)
1019fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed    return { paint = paint, extra_dy = extra_dy }
1029fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reedend
10318ea777638f1494b068ba4ca1a5d6725a0e80cf1reed
104bdc49ae0d422b8fe1957af570c4f4e63272f5285reedfunction SkiaPoint_make_template()
105bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    local title = {
106bdc49ae0d422b8fe1957af570c4f4e63272f5285reed        margin_x = 30,
107bdc49ae0d422b8fe1957af570c4f4e63272f5285reed        margin_y = 100,
108bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    }
1099e233b2082f685401b985472036fe7f95f35c93areed    title[1] = make_paint("Arial", 1, 45, { a=1, r=1, g=1, b=1 })
110bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    title[1]:setTextAlign("center")
1119fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed    title[2] = make_paint("Arial", 1, 25, { a=1, r=.75, g=.75, b=.75 })
112bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    title[2]:setTextAlign("center")
113bdc49ae0d422b8fe1957af570c4f4e63272f5285reed
114bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    local slide = {
115bdc49ae0d422b8fe1957af570c4f4e63272f5285reed        margin_x = 20,
1169fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed        margin_y = 25,
117bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    }
1189e233b2082f685401b985472036fe7f95f35c93areed    slide[1] = make_tmpl(make_paint("Arial", 1, 35, { a=1, r=1, g=1, b=1 }), 18)
11936c9c11ed97d6c6f49bfdad53537a459b9e4b41dreed    slide[2] = make_tmpl(make_paint("Arial", 0, 25, { a=1, r=1, g=1, b=1 }), 10)
12036c9c11ed97d6c6f49bfdad53537a459b9e4b41dreed    slide[3] = make_tmpl(make_paint("Arial", 0, 20, { a=1, r=.9, g=.9, b=.9 }), 5)
12118ea777638f1494b068ba4ca1a5d6725a0e80cf1reed
122bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    return {
123bdc49ae0d422b8fe1957af570c4f4e63272f5285reed        title = title,
124bdc49ae0d422b8fe1957af570c4f4e63272f5285reed        slide = slide,
1259e233b2082f685401b985472036fe7f95f35c93areed        codePaint = make_paint("Courier", 0, 20, { a=1, r=.9, g=.9, b=.9 }),
126bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    }
127bdc49ae0d422b8fe1957af570c4f4e63272f5285reedend
128bdc49ae0d422b8fe1957af570c4f4e63272f5285reed
129bdc49ae0d422b8fe1957af570c4f4e63272f5285reedgTemplate = SkiaPoint_make_template()
13018ea777638f1494b068ba4ca1a5d6725a0e80cf1reed
13118ea777638f1494b068ba4ca1a5d6725a0e80cf1reedgRedPaint = Sk.newPaint()
13218ea777638f1494b068ba4ca1a5d6725a0e80cf1reedgRedPaint:setAntiAlias(true)
13318ea777638f1494b068ba4ca1a5d6725a0e80cf1reedgRedPaint:setColor{a=1, r=1, g=0, b=0 }
13418ea777638f1494b068ba4ca1a5d6725a0e80cf1reed
135f355df58517691b05be8bc3f0e99331ede6c4d44reed-- animation.proc is passed the canvas before drawing.
136f355df58517691b05be8bc3f0e99331ede6c4d44reed-- The animation.proc returns itself or another animation (which means keep animating)
137f355df58517691b05be8bc3f0e99331ede6c4d44reed-- or it returns nil, which stops the animation.
138f355df58517691b05be8bc3f0e99331ede6c4d44reed--
139f355df58517691b05be8bc3f0e99331ede6c4d44reedlocal gCurrAnimation
14009a1d6751c5c7c09d72ff8e195148509d2cb87cereed
14118ea777638f1494b068ba4ca1a5d6725a0e80cf1reedgSlideIndex = 1
14218ea777638f1494b068ba4ca1a5d6725a0e80cf1reed
1437b8646669f5b1e2daddf53764bcde62d743ff076reed-----------------------------------------------------------------------------
1447b8646669f5b1e2daddf53764bcde62d743ff076reed
14596affcde22a675e3629b9da490bb45a0ab07fa2breedfunction new_drawable_picture(pic)
14696affcde22a675e3629b9da490bb45a0ab07fa2breed    return {
14796affcde22a675e3629b9da490bb45a0ab07fa2breed        picture = pic,
14896affcde22a675e3629b9da490bb45a0ab07fa2breed        width = pic:width(),
14996affcde22a675e3629b9da490bb45a0ab07fa2breed        height = pic:height(),
15096affcde22a675e3629b9da490bb45a0ab07fa2breed        draw = function (self, canvas, x, y, paint)
15196affcde22a675e3629b9da490bb45a0ab07fa2breed            canvas:drawPicture(self.picture, x, y, paint)
15296affcde22a675e3629b9da490bb45a0ab07fa2breed        end
15396affcde22a675e3629b9da490bb45a0ab07fa2breed    }
15496affcde22a675e3629b9da490bb45a0ab07fa2breedend
15596affcde22a675e3629b9da490bb45a0ab07fa2breed
15696affcde22a675e3629b9da490bb45a0ab07fa2breedfunction new_drawable_image(img)
15796affcde22a675e3629b9da490bb45a0ab07fa2breed    return {
15896affcde22a675e3629b9da490bb45a0ab07fa2breed        image = img,
15996affcde22a675e3629b9da490bb45a0ab07fa2breed        width = img:width(),
16096affcde22a675e3629b9da490bb45a0ab07fa2breed        height = img:height(),
16196affcde22a675e3629b9da490bb45a0ab07fa2breed        draw = function (self, canvas, x, y, paint)
16296affcde22a675e3629b9da490bb45a0ab07fa2breed            canvas:drawImage(self.image, x, y, paint)
16396affcde22a675e3629b9da490bb45a0ab07fa2breed        end
16496affcde22a675e3629b9da490bb45a0ab07fa2breed    }
16596affcde22a675e3629b9da490bb45a0ab07fa2breedend
16618ea777638f1494b068ba4ca1a5d6725a0e80cf1reed
1677b8646669f5b1e2daddf53764bcde62d743ff076reedfunction convert_to_picture_drawable(slide)
1687b8646669f5b1e2daddf53764bcde62d743ff076reed    local rec = Sk.newPictureRecorder()
1697b8646669f5b1e2daddf53764bcde62d743ff076reed    drawSlide(rec:beginRecording(640, 480), slide, gTemplate)
1707b8646669f5b1e2daddf53764bcde62d743ff076reed    return new_drawable_picture(rec:endRecording())
1717b8646669f5b1e2daddf53764bcde62d743ff076reedend
1727b8646669f5b1e2daddf53764bcde62d743ff076reed
1737b8646669f5b1e2daddf53764bcde62d743ff076reedfunction convert_to_image_drawable(slide)
1747b8646669f5b1e2daddf53764bcde62d743ff076reed    local surf = Sk.newRasterSurface(640, 480)
1757b8646669f5b1e2daddf53764bcde62d743ff076reed    drawSlide(surf:getCanvas(), slide, gTemplate)
1767b8646669f5b1e2daddf53764bcde62d743ff076reed    return new_drawable_image(surf:newImageSnapshot())
1777b8646669f5b1e2daddf53764bcde62d743ff076reedend
1787b8646669f5b1e2daddf53764bcde62d743ff076reed
17986217d831d70949f9dde6a60f821d3f357558bdfreedfunction new_drawable_slide(slide)
18086217d831d70949f9dde6a60f821d3f357558bdfreed    return {
18186217d831d70949f9dde6a60f821d3f357558bdfreed        slide = slide,
18286217d831d70949f9dde6a60f821d3f357558bdfreed        draw = function (self, canvas, x, y, paint)
18386217d831d70949f9dde6a60f821d3f357558bdfreed            if (nil == paint or ("number" == type(paint) and (1 == paint))) then
18486217d831d70949f9dde6a60f821d3f357558bdfreed                canvas:save()
18586217d831d70949f9dde6a60f821d3f357558bdfreed            else
18686217d831d70949f9dde6a60f821d3f357558bdfreed                canvas:saveLayer(paint)
18786217d831d70949f9dde6a60f821d3f357558bdfreed            end
18886217d831d70949f9dde6a60f821d3f357558bdfreed            canvas:translate(x, y)
18986217d831d70949f9dde6a60f821d3f357558bdfreed            drawSlide(canvas, self.slide, gTemplate)
19086217d831d70949f9dde6a60f821d3f357558bdfreed            canvas:restore()
19186217d831d70949f9dde6a60f821d3f357558bdfreed        end
19286217d831d70949f9dde6a60f821d3f357558bdfreed    }
19386217d831d70949f9dde6a60f821d3f357558bdfreedend
19486217d831d70949f9dde6a60f821d3f357558bdfreed
1957b8646669f5b1e2daddf53764bcde62d743ff076reedgNewDrawableFactory = {
1967b8646669f5b1e2daddf53764bcde62d743ff076reed    default = new_drawable_slide,
1977b8646669f5b1e2daddf53764bcde62d743ff076reed    picture = convert_to_picture_drawable,
1987b8646669f5b1e2daddf53764bcde62d743ff076reed    image = convert_to_image_drawable,
1997b8646669f5b1e2daddf53764bcde62d743ff076reed}
2007b8646669f5b1e2daddf53764bcde62d743ff076reed
2017b8646669f5b1e2daddf53764bcde62d743ff076reed-----------------------------------------------------------------------------
2027b8646669f5b1e2daddf53764bcde62d743ff076reed
20386217d831d70949f9dde6a60f821d3f357558bdfreedfunction next_slide()
20486217d831d70949f9dde6a60f821d3f357558bdfreed    local prev = gSlides[gSlideIndex]
20586217d831d70949f9dde6a60f821d3f357558bdfreed
206bb8a0ababab1aa2693a2a97733524ee367da1791reed    if gSlideIndex < #gSlides then
207bb8a0ababab1aa2693a2a97733524ee367da1791reed        gSlideIndex = gSlideIndex + 1
208bb8a0ababab1aa2693a2a97733524ee367da1791reed        spawn_transition(prev, gSlides[gSlideIndex], true)
20986217d831d70949f9dde6a60f821d3f357558bdfreed    end
21086217d831d70949f9dde6a60f821d3f357558bdfreedend
21186217d831d70949f9dde6a60f821d3f357558bdfreed
21286217d831d70949f9dde6a60f821d3f357558bdfreedfunction prev_slide()
21386217d831d70949f9dde6a60f821d3f357558bdfreed    local prev = gSlides[gSlideIndex]
21486217d831d70949f9dde6a60f821d3f357558bdfreed
215bb8a0ababab1aa2693a2a97733524ee367da1791reed    if gSlideIndex > 1 then
216bb8a0ababab1aa2693a2a97733524ee367da1791reed        gSlideIndex = gSlideIndex - 1
217bb8a0ababab1aa2693a2a97733524ee367da1791reed        spawn_transition(prev, gSlides[gSlideIndex], false)
21886217d831d70949f9dde6a60f821d3f357558bdfreed    end
21986217d831d70949f9dde6a60f821d3f357558bdfreedend
22086217d831d70949f9dde6a60f821d3f357558bdfreed
2217b8646669f5b1e2daddf53764bcde62d743ff076reedgDrawableType = "default"
222468b1815d29d9bbe513f2d8eb4afc0b066715b52reed
22307dada770b0af4955031806f0c1b8016fa49b65ereedload_file("slides_transitions")
22407dada770b0af4955031806f0c1b8016fa49b65ereed
225f355df58517691b05be8bc3f0e99331ede6c4d44reedfunction spawn_transition(prevSlide, nextSlide, is_forward)
226f355df58517691b05be8bc3f0e99331ede6c4d44reed    local transition
227f355df58517691b05be8bc3f0e99331ede6c4d44reed    if is_forward then
22807dada770b0af4955031806f0c1b8016fa49b65ereed        transition = gTransitionTable[nextSlide.transition]
229f355df58517691b05be8bc3f0e99331ede6c4d44reed    else
23007dada770b0af4955031806f0c1b8016fa49b65ereed        transition = gTransitionTable[prevSlide.transition]
231f355df58517691b05be8bc3f0e99331ede6c4d44reed    end
232f355df58517691b05be8bc3f0e99331ede6c4d44reed
233f355df58517691b05be8bc3f0e99331ede6c4d44reed    if not transition then
234d2e7dfba212557e2ef7c570c297b00683a603916reed        transition = fade_slide_transition
235f355df58517691b05be8bc3f0e99331ede6c4d44reed    end
236f355df58517691b05be8bc3f0e99331ede6c4d44reed
2377b8646669f5b1e2daddf53764bcde62d743ff076reed    local prevDrawable = gNewDrawableFactory[gDrawableType](prevSlide)
2387b8646669f5b1e2daddf53764bcde62d743ff076reed    local nextDrawable = gNewDrawableFactory[gDrawableType](nextSlide)
23996affcde22a675e3629b9da490bb45a0ab07fa2breed    gCurrAnimation = transition(prevDrawable, nextDrawable, is_forward)
240f355df58517691b05be8bc3f0e99331ede6c4d44reedend
241f355df58517691b05be8bc3f0e99331ede6c4d44reed
242f355df58517691b05be8bc3f0e99331ede6c4d44reed--------------------------------------------------------------------------------------
24309a1d6751c5c7c09d72ff8e195148509d2cb87cereed
24409a1d6751c5c7c09d72ff8e195148509d2cb87cereedfunction spawn_rotate_animation()
24509a1d6751c5c7c09d72ff8e195148509d2cb87cereed    gCurrAnimation = {
24609a1d6751c5c7c09d72ff8e195148509d2cb87cereed        angle = 0,
24709a1d6751c5c7c09d72ff8e195148509d2cb87cereed        angle_delta = 5,
24809a1d6751c5c7c09d72ff8e195148509d2cb87cereed        pivot_x = 320,
24909a1d6751c5c7c09d72ff8e195148509d2cb87cereed        pivot_y = 240,
250f355df58517691b05be8bc3f0e99331ede6c4d44reed        proc = function (self, canvas, drawSlideProc)
251f355df58517691b05be8bc3f0e99331ede6c4d44reed            if self.angle >= 360 then
252f355df58517691b05be8bc3f0e99331ede6c4d44reed                drawSlideProc(canvas)
25309a1d6751c5c7c09d72ff8e195148509d2cb87cereed                return nil
25409a1d6751c5c7c09d72ff8e195148509d2cb87cereed            end
255f355df58517691b05be8bc3f0e99331ede6c4d44reed            canvas:translate(self.pivot_x, self.pivot_y)
256f355df58517691b05be8bc3f0e99331ede6c4d44reed            canvas:rotate(self.angle)
257f355df58517691b05be8bc3f0e99331ede6c4d44reed            canvas:translate(-self.pivot_x, -self.pivot_y)
258f355df58517691b05be8bc3f0e99331ede6c4d44reed            drawSlideProc(canvas)
25909a1d6751c5c7c09d72ff8e195148509d2cb87cereed
260f355df58517691b05be8bc3f0e99331ede6c4d44reed            self.angle = self.angle + self.angle_delta
261f355df58517691b05be8bc3f0e99331ede6c4d44reed            return self
26209a1d6751c5c7c09d72ff8e195148509d2cb87cereed        end
26309a1d6751c5c7c09d72ff8e195148509d2cb87cereed    }
26409a1d6751c5c7c09d72ff8e195148509d2cb87cereedend
26509a1d6751c5c7c09d72ff8e195148509d2cb87cereed
26609a1d6751c5c7c09d72ff8e195148509d2cb87cereedfunction spawn_scale_animation()
26709a1d6751c5c7c09d72ff8e195148509d2cb87cereed    gCurrAnimation = {
26809a1d6751c5c7c09d72ff8e195148509d2cb87cereed        scale = 1,
26909a1d6751c5c7c09d72ff8e195148509d2cb87cereed        scale_delta = .95,
27009a1d6751c5c7c09d72ff8e195148509d2cb87cereed        scale_limit = 0.2,
27109a1d6751c5c7c09d72ff8e195148509d2cb87cereed        pivot_x = 320,
27209a1d6751c5c7c09d72ff8e195148509d2cb87cereed        pivot_y = 240,
273f355df58517691b05be8bc3f0e99331ede6c4d44reed        proc = function (self, canvas, drawSlideProc)
274f355df58517691b05be8bc3f0e99331ede6c4d44reed            if self.scale < self.scale_limit then
275f355df58517691b05be8bc3f0e99331ede6c4d44reed                self.scale = self.scale_limit
276f355df58517691b05be8bc3f0e99331ede6c4d44reed                self.scale_delta = 1 / self.scale_delta
27709a1d6751c5c7c09d72ff8e195148509d2cb87cereed            end
278f355df58517691b05be8bc3f0e99331ede6c4d44reed            if self.scale > 1 then
279f355df58517691b05be8bc3f0e99331ede6c4d44reed                drawSlideProc(canvas)
28009a1d6751c5c7c09d72ff8e195148509d2cb87cereed                return nil
28109a1d6751c5c7c09d72ff8e195148509d2cb87cereed            end
282f355df58517691b05be8bc3f0e99331ede6c4d44reed            canvas:translate(self.pivot_x, self.pivot_y)
283f355df58517691b05be8bc3f0e99331ede6c4d44reed            canvas:scale(self.scale, self.scale)
284f355df58517691b05be8bc3f0e99331ede6c4d44reed            canvas:translate(-self.pivot_x, -self.pivot_y)
285f355df58517691b05be8bc3f0e99331ede6c4d44reed            drawSlideProc(canvas)
28609a1d6751c5c7c09d72ff8e195148509d2cb87cereed
287f355df58517691b05be8bc3f0e99331ede6c4d44reed            self.scale = self.scale * self.scale_delta
288f355df58517691b05be8bc3f0e99331ede6c4d44reed            return self
28909a1d6751c5c7c09d72ff8e195148509d2cb87cereed        end
29009a1d6751c5c7c09d72ff8e195148509d2cb87cereed    }
29109a1d6751c5c7c09d72ff8e195148509d2cb87cereedend
29209a1d6751c5c7c09d72ff8e195148509d2cb87cereed
2939fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reedlocal bgPaint = nil
2949fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed
2959fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reedfunction draw_bg(canvas)
2969fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed    if not bgPaint then
2979fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed        bgPaint = Sk.newPaint()
2989fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed        local grad = Sk.newLinearGradient(  0,   0, { a=1, r=0, g=0, b=.3 },
2999fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed                                          640, 480, { a=1, r=0, g=0, b=.8 })
3009fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed        bgPaint:setShader(grad)
301bb8a0ababab1aa2693a2a97733524ee367da1791reed        bgPaint:setDither(true)
3029fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed    end
3039fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed
3049fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed    canvas:drawPaint(bgPaint)
3059fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reedend
3069fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed
307bdc49ae0d422b8fe1957af570c4f4e63272f5285reedfunction onDrawContent(canvas, width, height)
308bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    local matrix = Sk.newMatrix()
309bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    matrix:setRectToRect(make_rect(0, 0, 640, 480), make_rect(0, 0, width, height), "center")
310bdc49ae0d422b8fe1957af570c4f4e63272f5285reed    canvas:concat(matrix)
311bdc49ae0d422b8fe1957af570c4f4e63272f5285reed
3129fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed    draw_bg(canvas)
3139fbc3f31c0c7095f4f25ad3d2d17731bb63c0817reed
314f355df58517691b05be8bc3f0e99331ede6c4d44reed    local drawSlideProc = function(canvas)
315bdc49ae0d422b8fe1957af570c4f4e63272f5285reed        drawSlide(canvas, gSlides[gSlideIndex], gTemplate)
31609a1d6751c5c7c09d72ff8e195148509d2cb87cereed    end
31709a1d6751c5c7c09d72ff8e195148509d2cb87cereed
31809a1d6751c5c7c09d72ff8e195148509d2cb87cereed    if gCurrAnimation then
319f355df58517691b05be8bc3f0e99331ede6c4d44reed        gCurrAnimation = gCurrAnimation:proc(canvas, drawSlideProc)
32009a1d6751c5c7c09d72ff8e195148509d2cb87cereed        return true
32109a1d6751c5c7c09d72ff8e195148509d2cb87cereed    else
322f355df58517691b05be8bc3f0e99331ede6c4d44reed        drawSlideProc(canvas)
32309a1d6751c5c7c09d72ff8e195148509d2cb87cereed        return false
32409a1d6751c5c7c09d72ff8e195148509d2cb87cereed    end
32518ea777638f1494b068ba4ca1a5d6725a0e80cf1reedend
32618ea777638f1494b068ba4ca1a5d6725a0e80cf1reed
32718ea777638f1494b068ba4ca1a5d6725a0e80cf1reedfunction onClickHandler(x, y)
32818ea777638f1494b068ba4ca1a5d6725a0e80cf1reed    return false
32918ea777638f1494b068ba4ca1a5d6725a0e80cf1reedend
33018ea777638f1494b068ba4ca1a5d6725a0e80cf1reed
33109a1d6751c5c7c09d72ff8e195148509d2cb87cereedlocal keyProcs = {
33209a1d6751c5c7c09d72ff8e195148509d2cb87cereed    n = next_slide,
33309a1d6751c5c7c09d72ff8e195148509d2cb87cereed    p = prev_slide,
33409a1d6751c5c7c09d72ff8e195148509d2cb87cereed    r = spawn_rotate_animation,
33509a1d6751c5c7c09d72ff8e195148509d2cb87cereed    s = spawn_scale_animation,
336c7663981c9864773de455ece42335dd13fc74b88reed    ["="] = function () scale_text_delta(gTemplate, 1) end,
337c7663981c9864773de455ece42335dd13fc74b88reed    ["-"] = function () scale_text_delta(gTemplate, -1) end,
3381b6ab4417e0edef3b91d150e6650205f49f04d17reed
3391b6ab4417e0edef3b91d150e6650205f49f04d17reed    b = function () gShowBounds = not gShowBounds end,
3407b8646669f5b1e2daddf53764bcde62d743ff076reed    B = function () gUseBlurInTransitions = not gUseBlurInTransitions end,
3417b8646669f5b1e2daddf53764bcde62d743ff076reed
3427b8646669f5b1e2daddf53764bcde62d743ff076reed    ["1"] = function () gDrawableType = "default" end,
3437b8646669f5b1e2daddf53764bcde62d743ff076reed    ["2"] = function () gDrawableType = "picture" end,
3447b8646669f5b1e2daddf53764bcde62d743ff076reed    ["3"] = function () gDrawableType = "image" end,
34509a1d6751c5c7c09d72ff8e195148509d2cb87cereed}
34609a1d6751c5c7c09d72ff8e195148509d2cb87cereed
34709a1d6751c5c7c09d72ff8e195148509d2cb87cereedfunction onCharHandler(uni)
34809a1d6751c5c7c09d72ff8e195148509d2cb87cereed    local proc = keyProcs[uni]
34909a1d6751c5c7c09d72ff8e195148509d2cb87cereed    if proc then
35009a1d6751c5c7c09d72ff8e195148509d2cb87cereed        proc()
35109a1d6751c5c7c09d72ff8e195148509d2cb87cereed        return true
35218ea777638f1494b068ba4ca1a5d6725a0e80cf1reed    end
35309a1d6751c5c7c09d72ff8e195148509d2cb87cereed    return false
35418ea777638f1494b068ba4ca1a5d6725a0e80cf1reedend
355