Home | History | Annotate | Download | only in resources
      1 gShowBounds = false
      2 gUseBlurInTransitions = false
      3 
      4 gPath = "/skia/trunk/resources/"
      5 
      6 function load_file(file)
      7     local prev_path = package.path
      8     package.path = package.path .. ";" .. gPath .. file .. ".lua"
      9     require(file)
     10     package.path = prev_path
     11 end
     12 
     13 load_file("slides_utils")
     14 
     15 gSlides = parse_file(io.open("/skia/trunk/resources/slides_content2.lua", "r"))
     16 
     17 function make_rect(l, t, r, b)
     18     return { left = l, top = t, right = r, bottom = b }
     19 end
     20 
     21 function make_paint(typefacename, stylebits, size, color)
     22     local paint = Sk.newPaint();
     23     paint:setAntiAlias(true)
     24     paint:setSubpixelText(true)
     25     paint:setTypeface(Sk.newTypeface(typefacename, stylebits))
     26     paint:setTextSize(size)
     27     paint:setColor(color)
     28     return paint
     29 end
     30 
     31 function draw_bullet(canvas, x, y, paint, indent)
     32     if 0 == indent then
     33         return
     34     end
     35     local ps = paint:getTextSize()
     36     local cx = x - ps * .8
     37     local cy = y - ps * .4
     38     local radius = ps * .2
     39     canvas:drawCircle(cx, cy, radius, paint)
     40 end
     41 
     42 function stroke_rect(canvas, rect, color)
     43     local paint = Sk.newPaint()
     44     paint:setStroke(true);
     45     paint:setColor(color)
     46     canvas:drawRect(rect, paint)
     47 end
     48 
     49 function drawSlide(canvas, slide, master_template)
     50 
     51     if #slide == 1 then
     52         template = master_template.title
     53         canvas:drawText(slide[1].text, 320, 240, template[1])
     54         return
     55     end
     56 
     57     template = master_template.slide
     58 
     59     local x = template.margin_x
     60     local y = template.margin_y
     61     local scale = 1.25
     62 
     63     if slide.blockstyle == "code" then
     64         local paint = master_template.codePaint
     65         local fm = paint:getFontMetrics()
     66         local height = #slide * (fm.descent - fm.ascent)
     67         y = (480 - height) / 2
     68         for i = 1, #slide do
     69             local node = slide[i]
     70             y = y - fm.ascent * scale
     71             canvas:drawText(node.text, x, y, paint)
     72             y = y + fm.descent * scale
     73         end
     74         return
     75     end
     76 
     77     for i = 1, #slide do
     78         local node = slide[i]
     79         local paint = template[node.indent + 1].paint
     80         local extra_dy = template[node.indent + 1].extra_dy
     81         local fm = paint:getFontMetrics()
     82         local x_offset = -fm.ascent * node.indent * 1.25
     83 
     84         local bounds = make_rect(x + x_offset, y, 620, 640)
     85         local blob, newBottom = Sk.newTextBlob(node.text, bounds, paint)
     86         draw_bullet(canvas, x + x_offset, y - fm.ascent, paint, node.indent)
     87         canvas:drawTextBlob(blob, 0, 0, paint)
     88         y = newBottom + paint:getTextSize() * .5 + extra_dy
     89 
     90         if gShowBounds then
     91             bounds.bottom = newBottom
     92             stroke_rect(canvas, bounds, {a=1,r=0,g=1,b=0})
     93             stroke_rect(canvas, blob:bounds(), {a=1,r=1,g=0,b=0})
     94         end
     95 
     96     end
     97 end
     98 
     99 --------------------------------------------------------------------------------------
    100 function make_tmpl(paint, extra_dy)
    101     return { paint = paint, extra_dy = extra_dy }
    102 end
    103 
    104 function SkiaPoint_make_template()
    105     local title = {
    106         margin_x = 30,
    107         margin_y = 100,
    108     }
    109     title[1] = make_paint("Arial", 1, 45, { a=1, r=1, g=1, b=1 })
    110     title[1]:setTextAlign("center")
    111     title[2] = make_paint("Arial", 1, 25, { a=1, r=.75, g=.75, b=.75 })
    112     title[2]:setTextAlign("center")
    113 
    114     local slide = {
    115         margin_x = 20,
    116         margin_y = 25,
    117     }
    118     slide[1] = make_tmpl(make_paint("Arial", 1, 35, { a=1, r=1, g=1, b=1 }), 18)
    119     slide[2] = make_tmpl(make_paint("Arial", 0, 25, { a=1, r=1, g=1, b=1 }), 10)
    120     slide[3] = make_tmpl(make_paint("Arial", 0, 20, { a=1, r=.9, g=.9, b=.9 }), 5)
    121 
    122     return {
    123         title = title,
    124         slide = slide,
    125         codePaint = make_paint("Courier", 0, 20, { a=1, r=.9, g=.9, b=.9 }),
    126     }
    127 end
    128 
    129 gTemplate = SkiaPoint_make_template()
    130 
    131 gRedPaint = Sk.newPaint()
    132 gRedPaint:setAntiAlias(true)
    133 gRedPaint:setColor{a=1, r=1, g=0, b=0 }
    134 
    135 -- animation.proc is passed the canvas before drawing.
    136 -- The animation.proc returns itself or another animation (which means keep animating)
    137 -- or it returns nil, which stops the animation.
    138 --
    139 local gCurrAnimation
    140 
    141 gSlideIndex = 1
    142 
    143 -----------------------------------------------------------------------------
    144 
    145 function new_drawable_picture(pic)
    146     return {
    147         picture = pic,
    148         width = pic:width(),
    149         height = pic:height(),
    150         draw = function (self, canvas, x, y, paint)
    151             canvas:drawPicture(self.picture, x, y, paint)
    152         end
    153     }
    154 end
    155 
    156 function new_drawable_image(img)
    157     return {
    158         image = img,
    159         width = img:width(),
    160         height = img:height(),
    161         draw = function (self, canvas, x, y, paint)
    162             canvas:drawImage(self.image, x, y, paint)
    163         end
    164     }
    165 end
    166 
    167 function convert_to_picture_drawable(slide)
    168     local rec = Sk.newPictureRecorder()
    169     drawSlide(rec:beginRecording(640, 480), slide, gTemplate)
    170     return new_drawable_picture(rec:endRecording())
    171 end
    172 
    173 function convert_to_image_drawable(slide)
    174     local surf = Sk.newRasterSurface(640, 480)
    175     drawSlide(surf:getCanvas(), slide, gTemplate)
    176     return new_drawable_image(surf:newImageSnapshot())
    177 end
    178 
    179 function new_drawable_slide(slide)
    180     return {
    181         slide = slide,
    182         draw = function (self, canvas, x, y, paint)
    183             if (nil == paint or ("number" == type(paint) and (1 == paint))) then
    184                 canvas:save()
    185             else
    186                 canvas:saveLayer(paint)
    187             end
    188             canvas:translate(x, y)
    189             drawSlide(canvas, self.slide, gTemplate)
    190             canvas:restore()
    191         end
    192     }
    193 end
    194 
    195 gNewDrawableFactory = {
    196     default = new_drawable_slide,
    197     picture = convert_to_picture_drawable,
    198     image = convert_to_image_drawable,
    199 }
    200 
    201 -----------------------------------------------------------------------------
    202 
    203 function next_slide()
    204     local prev = gSlides[gSlideIndex]
    205 
    206     if gSlideIndex < #gSlides then
    207         gSlideIndex = gSlideIndex + 1
    208         spawn_transition(prev, gSlides[gSlideIndex], true)
    209     end
    210 end
    211 
    212 function prev_slide()
    213     local prev = gSlides[gSlideIndex]
    214 
    215     if gSlideIndex > 1 then
    216         gSlideIndex = gSlideIndex - 1
    217         spawn_transition(prev, gSlides[gSlideIndex], false)
    218     end
    219 end
    220 
    221 gDrawableType = "default"
    222 
    223 load_file("slides_transitions")
    224 
    225 function spawn_transition(prevSlide, nextSlide, is_forward)
    226     local transition
    227     if is_forward then
    228         transition = gTransitionTable[nextSlide.transition]
    229     else
    230         transition = gTransitionTable[prevSlide.transition]
    231     end
    232 
    233     if not transition then
    234         transition = fade_slide_transition
    235     end
    236 
    237     local prevDrawable = gNewDrawableFactory[gDrawableType](prevSlide)
    238     local nextDrawable = gNewDrawableFactory[gDrawableType](nextSlide)
    239     gCurrAnimation = transition(prevDrawable, nextDrawable, is_forward)
    240 end
    241 
    242 --------------------------------------------------------------------------------------
    243 
    244 function spawn_rotate_animation()
    245     gCurrAnimation = {
    246         angle = 0,
    247         angle_delta = 5,
    248         pivot_x = 320,
    249         pivot_y = 240,
    250         proc = function (self, canvas, drawSlideProc)
    251             if self.angle >= 360 then
    252                 drawSlideProc(canvas)
    253                 return nil
    254             end
    255             canvas:translate(self.pivot_x, self.pivot_y)
    256             canvas:rotate(self.angle)
    257             canvas:translate(-self.pivot_x, -self.pivot_y)
    258             drawSlideProc(canvas)
    259 
    260             self.angle = self.angle + self.angle_delta
    261             return self
    262         end
    263     }
    264 end
    265 
    266 function spawn_scale_animation()
    267     gCurrAnimation = {
    268         scale = 1,
    269         scale_delta = .95,
    270         scale_limit = 0.2,
    271         pivot_x = 320,
    272         pivot_y = 240,
    273         proc = function (self, canvas, drawSlideProc)
    274             if self.scale < self.scale_limit then
    275                 self.scale = self.scale_limit
    276                 self.scale_delta = 1 / self.scale_delta
    277             end
    278             if self.scale > 1 then
    279                 drawSlideProc(canvas)
    280                 return nil
    281             end
    282             canvas:translate(self.pivot_x, self.pivot_y)
    283             canvas:scale(self.scale, self.scale)
    284             canvas:translate(-self.pivot_x, -self.pivot_y)
    285             drawSlideProc(canvas)
    286 
    287             self.scale = self.scale * self.scale_delta
    288             return self
    289         end
    290     }
    291 end
    292 
    293 local bgPaint = nil
    294 
    295 function draw_bg(canvas)
    296     if not bgPaint then
    297         bgPaint = Sk.newPaint()
    298         local grad = Sk.newLinearGradient(  0,   0, { a=1, r=0, g=0, b=.3 },
    299                                           640, 480, { a=1, r=0, g=0, b=.8 })
    300         bgPaint:setShader(grad)
    301         bgPaint:setDither(true)
    302     end
    303 
    304     canvas:drawPaint(bgPaint)
    305 end
    306 
    307 function onDrawContent(canvas, width, height)
    308     local matrix = Sk.newMatrix()
    309     matrix:setRectToRect(make_rect(0, 0, 640, 480), make_rect(0, 0, width, height), "center")
    310     canvas:concat(matrix)
    311 
    312     draw_bg(canvas)
    313 
    314     local drawSlideProc = function(canvas)
    315         drawSlide(canvas, gSlides[gSlideIndex], gTemplate)
    316     end
    317 
    318     if gCurrAnimation then
    319         gCurrAnimation = gCurrAnimation:proc(canvas, drawSlideProc)
    320         return true
    321     else
    322         drawSlideProc(canvas)
    323         return false
    324     end
    325 end
    326 
    327 function onClickHandler(x, y)
    328     return false
    329 end
    330 
    331 local keyProcs = {
    332     n = next_slide,
    333     p = prev_slide,
    334     r = spawn_rotate_animation,
    335     s = spawn_scale_animation,
    336     ["="] = function () scale_text_delta(gTemplate, 1) end,
    337     ["-"] = function () scale_text_delta(gTemplate, -1) end,
    338 
    339     b = function () gShowBounds = not gShowBounds end,
    340     B = function () gUseBlurInTransitions = not gUseBlurInTransitions end,
    341 
    342     ["1"] = function () gDrawableType = "default" end,
    343     ["2"] = function () gDrawableType = "picture" end,
    344     ["3"] = function () gDrawableType = "image" end,
    345 }
    346 
    347 function onCharHandler(uni)
    348     local proc = keyProcs[uni]
    349     if proc then
    350         proc()
    351         return true
    352     end
    353     return false
    354 end
    355