Mercurial > MadButterfly
changeset 906:62ef69e02e85
branch merge
author | Shih-Yuan Lee (FourDollars) <fourdollars@gmail.com> |
---|---|
date | Sun, 03 Oct 2010 18:15:00 +0800 |
parents | e3a5e05f00c1 (current diff) e86b4d56ddea (diff) |
children | 095cf170f5fd |
files | |
diffstat | 13 files changed, 1113 insertions(+), 413 deletions(-) [+] |
line wrap: on
line diff
--- a/include/mb_types.h Sun Oct 03 18:12:11 2010 +0800 +++ b/include/mb_types.h Sun Oct 03 18:15:00 2010 +0800 @@ -82,7 +82,7 @@ struct _paint { int pnt_type; int flags; - void (*prepare)(paint_t *paint, mbe_t *cr); + void (*prepare)(paint_t *paint, mbe_t *cr, shape_t *sh); void (*free)(struct _redraw_man *rdman, paint_t *paint); STAILQ(shnode_t) members; paint_t *pnt_next; /*!< \brief Collect all paints of a rdman. */ @@ -175,6 +175,12 @@ * cached. */ area_t *pcache_cur_area; /*!< Current area for parent cached. */ area_t *pcache_last_area; /*!< Last area for parent cached. */ + co_aix cache_2_pdev[6]; /*!< Transfrom matrix from space of + * cached one to its parent. */ + co_aix cache_2_pdev_rev[6]; /*!< Reverse of cache_2_pdev. */ + co_aix aggr_2_pdev[6]; /*!< Aggregation of cache_2_pdev from root */ + co_aix aggr_2_pdev_rev[6]; /*!< Aggregation of cache_2_pdev_rev + * from root */ } coord_canvas_info_t; /*! \brief A coordination system. @@ -367,6 +373,10 @@ #define _coord_get_dirty_areas(coord) (&(coord)->canvas_info->dirty_areas) #define _coord_get_aggr_dirty_areas(coord) \ ((coord)->canvas_info->aggr_dirty_areas) +#define coord_get_2pdev(coord) ((coord)->canvas_info->cache_2_pdev) +#define coord_get_2pdev_rev(coord) ((coord)->canvas_info->cache_2_pdev_rev) +#define coord_get_aggr2pdev(coord) ((coord)->canvas_info->aggr_2_pdev) +#define coord_get_aggr2pdev_rev(coord) ((coord)->canvas_info->aggr_2_pdev_rev) /* @} */
--- a/nodejs/animate.js Sun Oct 03 18:12:11 2010 +0800 +++ b/nodejs/animate.js Sun Oct 03 18:15:00 2010 +0800 @@ -9,84 +9,50 @@ var ffs = 12; var frame_interval = 1000 / ffs; -function linear_draw() { - var percent; +function shift_draw(percent) { + var x, y; - percent = (Date.now() - this._start_tm) / this.duration; - if(percent >= 1) { - percent = 1; - if (this.obj.timer) { - this.obj.timer.stop(); - delete this.obj.timer; - } - } - this.obj.x = (this.targetx-this.startposx)*percent+this.startposx; - this.obj.y = (this.targety-this.startposy)*percent+this.startposy; + x = (this.targetx - this.startposx) * percent + this.startposx; + y = (this.targety - this.startposy) * percent + this.startposy; + this.obj.center.move(x, y); this.app.refresh(); } -function linear_draw_start() { - var obj = this.obj; - var self = this; - - if(obj.timer) - obj.timer.stop(); - - this._start_tm = Date.now(); - obj.timer = setInterval(function() { self.draw(); }, frame_interval); -} - -function linear(app,obj,shiftx,shifty,duration) { - obj.animated_linear = this; +function shift(app,obj,shiftx,shifty) { + obj.animated_shift = this; this.app = app; this.obj = obj; this.end = 0; - this.targetx = shiftx + obj.x; - this.targety = shifty + obj.y; - this.startposx = obj.x; - this.startposy = obj.y; - this.duration = duration*1000; + this.targetx = shiftx + obj.center.x; + this.targety = shifty + obj.center.y; + this.startposx = obj.center.x; + this.startposy = obj.center.y; } -exports.linear = linear; -linear.prototype.start = linear_draw_start; -linear.prototype.draw = linear_draw; +exports.shift = shift; +shift.prototype.draw = shift_draw; /* ------------------------------------------------------------ */ function rotate(app, obj, ang, duration) { this._app = app; this._obj = obj; this._ang = ang; - this._duration = duration * 1000; + this._start_mtx = [obj[0], obj[1], obj[2], obj[3], obj[4], obj[5]]; } -function rotate_start() { - var obj = this._obj; - var self = this; - - this._start_mtx = [obj[0], obj[1], obj[2], obj[3], obj[4], obj[5]]; - this._start_tm = Date.now(); - obj.timer = setInterval(function() { self.draw(); }, frame_interval); -} - -function rotate_draw() { +function rotate_draw(percent) { var percent; var ang; var sv, cv; var obj = this._obj; var mtx, shift; - percent = (Date.now() - this._start_tm) / this._duration; - if(percent >= 1) { - percent = 1; - obj.timer.stop(); - } ang = percent * this._ang; sv = Math.sin(ang); cv = Math.cos(ang); mtx = [cv, -sv, 0, sv, cv, 0]; - + sys.puts('x='+obj.center.x+',y='+obj.center.y); shift = [1, 0, -obj.center.x, 0, 1, -obj.center.y]; mtx = multiply(mtx, shift); shift = [1, 0, obj.center.x, 0, 1, obj.center.y]; @@ -103,7 +69,6 @@ this._app.refresh(); } -rotate.prototype.start = rotate_start; rotate.prototype.draw = rotate_draw; exports.rotate = rotate; @@ -119,59 +84,56 @@ } -function scale_draw() { - if (this.end == 1) return; - var percent = (Date.now() - this.starttime)/this.duration; - if (percent > 1) percent = 1; - var sx = (this.targetx-this.startsx)*percent+this.startsx; - var sy = (this.targety-this.startsy)*percent+this.startsy; - var t=[sx,0,0,0,sy,0]; - this.obj[0] = sx; - this.obj[4] = sy; - this.obj[2] = this.origin_offset_x - (sx-this.startsx)*this.obj.center.x; - this.obj[5] = this.origin_offset_y - (sy-this.startsy)*this.obj.center.y; +function scale_draw(percent) { + var sx = 1 + (this.totalsx - 1) * percent; + var sy = 1 + (this.totalsy - 1) * percent; + var sh1 = [1, 0, -this.center_x, 0, 1, -this.center_y]; + var sh2 = [1, 0, this.center_x, 0, 1, this.center_y]; + var scale = [sx, 0, 0, 0, sy, 0]; + var obj = this.obj; + var mtx; + + mtx = multiply(scale, sh1); + mtx = multiply(sh2, mtx); + mtx = multiply(this.orig_mtx, mtx); + obj[0] = mtx[0]; + obj[1] = mtx[1]; + obj[2] = mtx[2]; + obj[3] = mtx[3]; + obj[4] = mtx[4]; + obj[5] = mtx[5]; this.app.refresh(); - var self = this; - if (percent < 1) { - this.obj.timer=setTimeout(function() { self.draw();}, frame_interval); - return; - } - this.app.refresh(); - this.obj.animated_scale = null; } -function scale(app,obj,targetx,targety, duration) { +function scale(app, obj, fact_x, fact_y, duration) { + var bbox; + try { if (obj.animated_scale) { - //obj[0] = obj.animated_scale.targetx; - //obj[4] = obj.animated_scale.targety; - //obj[2] = obj.animated_scale.final_offset_x; - //obj[5] = obj.aninated_scale.final_offset_y; obj.animated_scale.end = 1; } } catch(e) { } + + bbox = obj.bbox; + bbox.update(); obj.animated_scale = this; this.app = app; this.obj = obj; this.end = 0; this.starttime = Date.now(); - this.startsx = obj[0]; - this.startsy = obj[4]; - this.targetx = targetx; - this.targety = targety; + this.totalsx = fact_x * bbox.orig.width / bbox.width; + this.totalsy = fact_y * bbox.orig.height / bbox.height; this.duration = duration*1000; - this.origin_offset_x = obj[2]; - this.origin_offset_y = obj[5]; - this.final_offset_x = this.origin_offset_x-(targetx-this.startsx)*obj.center.x; - this.final_offset_y = this.origin_offset_y-(targety-this.startsy)*obj.center.y; + this.center_x = obj.center.rel.x; + this.center_y = obj.center.rel.y; + this.orig_mtx = [obj[0], obj[1], obj[2], obj[3], obj[4], obj[5]]; } exports.scale = scale; -scale.prototype.start = scale_draw; scale.prototype.draw = scale_draw; function holder(app, coord) { @@ -212,20 +174,11 @@ -function alpha_draw() { +function alpha_draw(percent) { if (this.end == 1) return; - var percent = (Date.now() - this.starttime)/this.duration; - if (percent > 1) percent = 1; var sx = (this.targetalpha-this.startalpha)*percent+this.startalpha; this.obj.opacity=sx; - - this.app.refresh(); - var self = this; - if (percent < 1) { - this.obj.timer=setTimeout(function() { self.draw();}, frame_interval); - return; - } this.app.refresh(); this.obj.animated_alpha = null; } @@ -248,6 +201,120 @@ this.duration = duration*1000; } -alpha.prototype.start = alpha_draw; alpha.prototype.draw = alpha_draw; exports.alpha = alpha; + +function linear_update() +{ + var now = Date.now(); + var i; + + sys.puts("real time is "+now); + sys.puts("end is "+this.end); + if (now >= this.end) { + this.timer.stop(); + now = this.end; + } + if (now < this.startmove) return; + sys.puts("now is "+now+" offset is "+(now-this.startmove)); + var per = (now-this.startmove)/this.duration/1000; + if (per > 1) per = 1; + this.action.draw(per); +} + +function linear_start() +{ + var self = this; + if (this.timer) + this.timer.stop(); + this.timer = setInterval(function() { self.update();}, frame_interval); + this.startmove = Date.now()+this.starttime*1000; + this.end = this.startmove+this.duration*1000; +} +function linear_stop() +{ + if (this.timer) { + this.timer.stop(); + this.timer = null; + } +} + +function linear_finish() +{ + this.action.draw(1); +} +function linear(action,start, duration) +{ + this.action = action; + this.duration = duration; + this.starttime = start; + this.timer=null; +} +linear.prototype.update = linear_update; +linear.prototype.start = linear_start; +linear.prototype.stop = linear_stop; +linear.prototype.finish = linear_finish; +exports.linear = linear; + + +/* Following functions is not defined completed. + Mark it out to prevent error message. + +function multilinear(action,start,stages) { + sys.puts("Multilinear word is not implemented yet"); +} + +exports.multilinear = multilinear; +multilinear.prototype.update = multilinear_update; +multilinear.prototype.start = multilinear_start; +multilinear.prototype.stop = multilinear_stop; +multilinear.prototype.finish = multilinear_finish; + +function exponential(action,start,stages) { + sys.puts("exponential word is not implemented yet"); +} + +exports.exponential = exponential; +exponential.prototype.update = exponential_update; +exponential.prototype.start = exponential_start; +exponential.prototype.stop = exponential_stop; +exponential.prototype.finish = exponential_finish; + +*/ + +function program(words) +{ + this.words = wrods; +} + +program.prototype.start=function() { + for(w in this.words) { + w.start(); + } +} + +program.prototype.step=function(s) { + sys.puts("This function is not implemented yet"); +} +program.prototype.stop=function() { + for(w in this.words) { + w.stop(); + } +} +program.prototype.finish=function() { + for(w in this.words) { + w.finish(); + } +} + +exports.run = function(actions,start,duration) { + for(a in actions) { + var li = new linear(actions[a],start,duration); + sys.puts(li); + li.start(); + } +} +exports.runexp=function(actions,start,exp) { + sys.puts("This function is not implemented yet"); +} +
--- a/nodejs/desktop.svg Sun Oct 03 18:12:11 2010 +0800 +++ b/nodejs/desktop.svg Sun Oct 03 18:15:00 2010 +0800 @@ -154,15 +154,15 @@ inkscape:pageshadow="2" inkscape:zoom="1.56875" inkscape:cx="207.9" - inkscape:cy="240" + inkscape:cy="290.99601" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" - inkscape:window-width="1920" - inkscape:window-height="1006" - inkscape:window-x="0" - inkscape:window-y="25" - inkscape:window-maximized="1" /> + inkscape:window-width="1440" + inkscape:window-height="900" + inkscape:window-x="-1" + inkscape:window-y="-1" + inkscape:window-maximized="0" /> <metadata id="metadata7"> <rdf:RDF> @@ -217,13 +217,13 @@ transform="translate(-27.274116,-798.02051)" mbname="video" inkscape:transform-center-x="0" - inkscape:transform-center-y="0" + inkscape:transform-center-y="42.294399" inkscape:bbox-x="35.992421" inkscape:bbox-y="383.87928" inkscape:bbox-width="85.598946" inkscape:bbox-height="84.588799"> <image - sodipodi:absref="/home/wycc/devel/md3/MadButterfly/nodejs/video.png" + sodipodi:absref="/usr/home/thinker/progm/MadButterfly/nodejs/video.png" xlink:href="video.png" width="85.598946" height="84.588799" @@ -242,13 +242,13 @@ transform="translate(126.77414,-798.02053)" mbname="audio" inkscape:transform-center-x="0" - inkscape:transform-center-y="0" + inkscape:transform-center-y="38.464287" inkscape:bbox-x="189.7836" inkscape:bbox-y="386.37278" inkscape:bbox-width="86.5" inkscape:bbox-height="76.928574"> <image - sodipodi:absref="/home/wycc/devel/md3/MadButterfly/nodejs/music.png" + sodipodi:absref="/usr/home/thinker/progm/MadButterfly/nodejs/music.png" xlink:href="music.png" width="86.5" height="76.928574" @@ -267,13 +267,13 @@ transform="translate(290.67139,-799.03067)" mbname="picture" inkscape:transform-center-x="0" - inkscape:transform-center-y="0" + inkscape:transform-center-y="38.07143" inkscape:bbox-x="354.2955" inkscape:bbox-y="392.95458" inkscape:bbox-width="84" inkscape:bbox-height="76.14286"> <image - sodipodi:absref="/home/wycc/devel/md3/MadButterfly/nodejs/photo.png" + sodipodi:absref="/usr/home/thinker/progm/MadButterfly/nodejs/photo.png" xlink:href="photo.png" width="84" height="76.14286" @@ -292,13 +292,13 @@ transform="translate(462.9024,-794.99007)" mbname="setting" inkscape:transform-center-x="0" - inkscape:transform-center-y="0" + inkscape:transform-center-y="37.57143" inkscape:bbox-x="526.42387" inkscape:bbox-y="389.0568" inkscape:bbox-width="84.571426" inkscape:bbox-height="75.14286"> <image - sodipodi:absref="/home/wycc/devel/md3/MadButterfly/nodejs/tool.png" + sodipodi:absref="/usr/home/thinker/progm/MadButterfly/nodejs/tool.png" xlink:href="tool.png" width="84.571426" height="75.14286" @@ -336,8 +336,8 @@ id="text2931" inkscape:transform-center-x="0" inkscape:transform-center-y="0" - inkscape:bbox-x="140.30434" - inkscape:bbox-y="273.84843" + inkscape:bbox-x="126.28044" + inkscape:bbox-y="271.84843" inkscape:bbox-width="488.15625" inkscape:bbox-height="32.382812" mbname="line1"><tspan @@ -348,8 +348,8 @@ y="185.925" id="tspan2935" style="font-size:16px" - inkscape:bbox-x="140.56215" - inkscape:bbox-y="290.74687" + inkscape:bbox-x="126.53825" + inkscape:bbox-y="288.74687" inkscape:bbox-width="487.89844" inkscape:bbox-height="15.484375">Lim JeongHee (J.Lim) & JoKwon (2AM) - The Road to Break Up</tspan><tspan sodipodi:role="line" @@ -358,8 +358,8 @@ x="124.96794" y="205.925" style="font-size:16px" - inkscape:bbox-x="140.30434" - inkscape:bbox-y="273.84843" + inkscape:bbox-x="126.28044" + inkscape:bbox-y="271.84843" inkscape:bbox-width="75.335938" inkscape:bbox-height="12.101562" id="tspan2941">7:00-7:30</tspan></text> @@ -372,7 +372,7 @@ inkscape:transform-center-x="0" inkscape:transform-center-y="0" inkscape:bbox-x="126.28044" - inkscape:bbox-y="212.01578" + inkscape:bbox-y="210.01578" inkscape:bbox-width="488.15625" inkscape:bbox-height="32.382812" mbname="line2"><tspan @@ -384,7 +384,7 @@ id="tspan2935-1" style="font-size:16px" inkscape:bbox-x="126.53825" - inkscape:bbox-y="228.91422" + inkscape:bbox-y="226.91422" inkscape:bbox-width="487.89844" inkscape:bbox-height="15.484375">Lim JeongHee (J.Lim) & JoKwon (2AM) - The Road to Break Up</tspan><tspan sodipodi:role="line" @@ -394,7 +394,7 @@ y="267.75766" style="font-size:16px" inkscape:bbox-x="126.28044" - inkscape:bbox-y="212.01578" + inkscape:bbox-y="210.01578" inkscape:bbox-width="75.335938" inkscape:bbox-height="12.101562" id="tspan2941-9">7:30-8:30</tspan></text> @@ -407,7 +407,7 @@ inkscape:transform-center-x="0" inkscape:transform-center-y="0" inkscape:bbox-x="126.05388" - inkscape:bbox-y="150.18311" + inkscape:bbox-y="152.18311" inkscape:bbox-width="488.38281" inkscape:bbox-height="32.382812" mbname="line3"><tspan @@ -419,7 +419,7 @@ id="tspan2935-2" style="font-size:16px" inkscape:bbox-x="126.53825" - inkscape:bbox-y="167.08154" + inkscape:bbox-y="169.08154" inkscape:bbox-width="487.89844" inkscape:bbox-height="15.484375">Lim JeongHee (J.Lim) & JoKwon (2AM) - The Road to Break Up</tspan><tspan sodipodi:role="line" @@ -429,8 +429,8 @@ y="329.59033" style="font-size:16px" inkscape:bbox-x="126.05388" - inkscape:bbox-y="150.18311" - inkscape:bbox-width="85.75" + inkscape:bbox-y="152.18311" + inkscape:bbox-width="75.5625" inkscape:bbox-height="12.101562" id="tspan2941-0">8:30-9:30</tspan></text> <text @@ -442,7 +442,7 @@ inkscape:transform-center-x="0" inkscape:transform-center-y="0" inkscape:bbox-x="125.97575" - inkscape:bbox-y="88.350433" + inkscape:bbox-y="90.350433" inkscape:bbox-width="488.46094" inkscape:bbox-height="32.382812" mbname="line4"><tspan @@ -454,7 +454,7 @@ id="tspan2935-11" style="font-size:16px" inkscape:bbox-x="126.53825" - inkscape:bbox-y="105.24887" + inkscape:bbox-y="107.24887" inkscape:bbox-width="487.89844" inkscape:bbox-height="15.484375">Lim JeongHee (J.Lim) & JoKwon (2AM) - The Road to Break Up</tspan><tspan sodipodi:role="line" @@ -464,7 +464,7 @@ y="391.423" style="font-size:16px" inkscape:bbox-x="125.97575" - inkscape:bbox-y="88.350433" + inkscape:bbox-y="90.350433" inkscape:bbox-width="85.828125" inkscape:bbox-height="12.101562" id="tspan2941-90">9:30-10:30</tspan></text> @@ -477,7 +477,7 @@ inkscape:transform-center-x="0" inkscape:transform-center-y="0" inkscape:bbox-x="126.53825" - inkscape:bbox-y="26.517761" + inkscape:bbox-y="28.517761" inkscape:bbox-width="487.89844" inkscape:bbox-height="32.382812" mbname="line5"><tspan @@ -489,7 +489,7 @@ id="tspan2935-7" style="font-size:16px" inkscape:bbox-x="126.53825" - inkscape:bbox-y="43.416199" + inkscape:bbox-y="45.416199" inkscape:bbox-width="487.89844" inkscape:bbox-height="15.484375">Lim JeongHee (J.Lim) & JoKwon (2AM) - The Road to Break Up</tspan><tspan sodipodi:role="line" @@ -499,7 +499,7 @@ y="453.25568" style="font-size:16px" inkscape:bbox-x="126.72575" - inkscape:bbox-y="26.517761" + inkscape:bbox-y="28.517761" inkscape:bbox-width="95.265625" inkscape:bbox-height="12.101562" id="tspan2941-7">10:30-11:30</tspan></text>
--- a/nodejs/mbapp.js Sun Oct 03 18:12:11 2010 +0800 +++ b/nodejs/mbapp.js Sun Oct 03 18:15:00 2010 +0800 @@ -5,6 +5,79 @@ var sys = require("sys"); var ldr = mbfly.img_ldr_new("."); +function _reverse(m1) { + var rev = new Array(1, 0, 0, 0, 1, 0); + var m = new Array(m1[0], m1[1], m1[2], m1[3], m1[4], m1[5]); + + rev[3] = -m[3] / m[0]; + m[3] = 0; + m[4] += rev[3] * m[1]; + m[5] += rev[3] * m[2]; + + rev[1] = -m[1] / m[4]; + rev[0] += rev[1] * rev[3]; + m[1] = 0; + m[2] += rev[1] * m[5]; + + rev[2] = -m[2]; + rev[5] = -m[5]; + + rev[0] = rev[0] / m[0]; + rev[1] = rev[1] / m[0]; + rev[2] = rev[2] / m[0]; + + rev[3] = rev[3] / m[4]; + rev[4] = rev[4] / m[4]; + rev[5] = rev[5] / m[4]; + + return rev; +} + +function _decorate_mb_rt(mb_rt) { + var coord; + + mb_rt._mbapp_saved_coord_new = mb_rt.coord_new; + mb_rt.coord_new = function(parent) { + var coord; + + coord = this._mbapp_saved_coord_new(parent); + coord.type = "coord"; + coord.children = []; + coord._mbapp_saved_mtx = [coord[0], coord[1], coord[2], + coord[3], coord[4], coord[5]]; + coord._mbapp_saved_rev_mtx = _reverse(coord._mbapp_saved_mtx); + coord.parent = parent; + coord._mbapp_saved_add_shape = coord.add_shape; + coord.add_shape = function(shape) { + var coord; + + this._mbapp_saved_add_shape(shape); + shape.parent = this; + this.children.push(shape); + } + + parent.children.push(coord); + + return coord; + }; + + /* + * Decorate root coord + */ + coord = mb_rt.root; + coord.type = "coord"; + coord.children = []; + coord._mbapp_saved_mtx = [coord[0], coord[1], coord[2], + coord[3], coord[4], coord[5]]; + coord._mbapp_saved_rev_mtx = _reverse(coord._mbapp_saved_mtx); + coord._mbapp_saved_add_shape = coord.add_shape; + coord.add_shape = function(shape) { + var coord; + + this._mbapp_saved_add_shape(shape); + shape.parent = this; + } +} app=function(display, w, h) { var self = this; @@ -18,6 +91,7 @@ h = 480; mb_rt = this.mb_rt = new mbfly.mb_rt(display, w, h); + _decorate_mb_rt(mb_rt); var background = mb_rt.rect_new(0, 0, 720, 480, 0, 0); var paint = mb_rt.paint_color_new(1, 1, 1, 1); paint.fill(background); @@ -32,7 +106,6 @@ } app.prototype.KeyPress = function(evt) { - sys.puts(evt.sym); if (this.onKeyPress) this.onKeyPress(evt.sym); if (evt.sym in this.keymap) this.keymap[evt.sym](); } @@ -52,7 +125,7 @@ return this.mb_rt.kbevents.add_event_observer(type,f); } app.prototype.refresh=function() { - this.mb_rt.redraw_all(); + this.mb_rt.redraw_changed(); this.mb_rt.flush(); } app.prototype.dump=function() { @@ -79,6 +152,7 @@ throw "Invalid argument"; mb_rt = this.mb_rt = new mbfly.mb_rt_with_win(display, win); + _decorate_mb_rt(mb_rt); background = mb_rt.rect_new(0, 0, 720, 480, 0, 0); paint = mb_rt.paint_color_new(1, 1, 1, 1); paint.fill(background);
--- a/nodejs/phone.js Sun Oct 03 18:12:11 2010 +0800 +++ b/nodejs/phone.js Sun Oct 03 18:15:00 2010 +0800 @@ -41,19 +41,19 @@ }); icon.mouse_event.add_event_observer(4, function(evt) { pressholder.go_center(evt.cur_tgt); - var rotate = new animate.rotate(app, evt.cur_tgt, 2 * 3.1415, 0.7); - rotate.start(); + var rotate = new animate.rotate(app, evt.cur_tgt, 2 * 3.1415); + animate.run([rotate], 0, 0.7); }); } var sw = 0; -var dock_up = new animate.linear(app, dock, 0, -300, 0.5); -var dock_down = new animate.linear(app, dock, 0, 0, 0.2); +var dock_up = new animate.shift(app, dock, 0, -300); +var dock_down = new animate.shift(app, dock, 0, 0); dock.mouse_event.add_event_observer(4, function(evt) { if(sw == 0) { - dock_up.start(); + animate.run([dock_up], 0, 0.5); } else { - dock_down.start(); + animate.run([dock_down], 0, 0.2); } sw = sw ^ 1; });
--- a/nodejs/shapes.cc Sun Oct 03 18:12:11 2010 +0800 +++ b/nodejs/shapes.cc Sun Oct 03 18:15:00 2010 +0800 @@ -70,6 +70,25 @@ } } +static void +xnjsmb_sh_stext_set_text(shape_t *sh, Handle<Object> self, + const char *txt) { + Handle<Object> rt; + redraw_man_t *rdman; + + sh_stext_set_text(sh, txt); + + /* + * Mark changed. + */ + rt = GET(self, "mbrt")->ToObject(); + ASSERT(rt != NULL); + rdman = xnjsmb_rt_rdman(rt); + + if(sh_get_coord(sh)) + rdman_shape_changed(rdman, sh); +} + /*! \brief Set style blocks for a stext object from JS. * * A style block is style setting of a chip of text. It is a 3-tuple,
--- a/nodejs/shapes.m4 Sun Oct 03 18:12:11 2010 +0800 +++ b/nodejs/shapes.m4 Sun Oct 03 18:15:00 2010 +0800 @@ -12,7 +12,8 @@ (([INHERIT], [shape]), ([STMOD], [xnjsmb_shape_mod]))) STRUCT([stext], [shape_t], [], - [METHOD([set_text], [sh_stext_set_text], (STR([txt])), 1, []), + [METHOD([set_text], [xnjsmb_sh_stext_set_text], + (SELF, STR([txt])), 1, []), METHOD([set_style], [xnjsmb_sh_stext_set_style], (SELF, ARRAY([blks]), ERR), 1, [])], (([INHERIT], [shape]), ([STMOD], [xnjsmb_shape_mod])))
--- a/nodejs/svg.js Sun Oct 03 18:12:11 2010 +0800 +++ b/nodejs/svg.js Sun Oct 03 18:15:00 2010 +0800 @@ -12,6 +12,26 @@ "red": [1, 0, 0] }; +function parse_color(color) { + var r, g, b; + var c; + + if (color[0] == "#") { + r = parseInt(color.substring(1, 3), 16) / 255; + g = parseInt(color.substring(3, 5), 16) / 255; + b = parseInt(color.substring(5, 7), 16) / 255; + } else if(_std_colors[color]) { + c = _std_colors[color]; + r = c[0]; + g = c[1]; + b = c[2]; + } else { + r = g = b = 0; + } + + return [r, g, b]; +} + exports.loadSVG=function(mb_rt,root,filename) { return new loadSVG(mb_rt, root, filename); }; @@ -27,6 +47,7 @@ this.mb_rt = mb_rt; this.stop_ref={}; this.gradients={}; + this.radials = {}; root.center=new Object(); root.center.x = 10000; root.center.y = 10000; @@ -85,6 +106,33 @@ } +function parse_style(node) { + var style_attr; + var style; + var parts, part; + var kv, key, value; + var content = {}; + var i; + + style_attr = node.attr('style'); + if(!style_attr) + return content; + + style = style_attr.value(); + parts = style.split(';'); + for(i = 0; i < parts.length; i++) { + part = parts[i].trim(); + if(part) { + kv = part.split(':'); + key = kv[0].trim(); + value = kv[1].trim(); + content[key] = value; + } + } + + return content; +} + function parseColor(c) { if (c[0] == '#') { @@ -138,29 +186,62 @@ this.text.set_text(text); } -loadSVG.prototype.parseTSpan = function(coord, n,style) { +function _parse_font_size(fn_sz_str) { + var pos; + + pos = fn_sz_str.search("px"); + if(pos >= 0) + fn_sz_str = fn_sz_str.substring(0, pos); + pos = fn_sz_str.search("pt"); + if(pos >= 0) + fn_sz_str = fn_sz_str.substring(0, pos); + + return parseFloat(fn_sz_str); +} + +loadSVG.prototype.parseTSpan = function(coord, n, pstyle) { var x = getInteger(n,'x'); var y = getInteger(n,'y'); var tcoord = this.mb_rt.coord_new(coord); - var nodes = n.childNodes(); + var style; + var family = "Courier"; + var weight = 80; + var slant = 0; + var sz = 10; + var face; var k; - var obj = this.mb_rt.stext_new(n.text(),x,y); - parseTextStyle(style,n); - style.paint = this.mb_rt.paint_color_new(1,1,1,1); - style.face=this.mb_rt.font_face_query(style.family, 2, 100); - obj.set_style([[20,style.face,style.fs]]); - style.paint.fill(obj); + + style = parse_style(n); + for(k in pstyle) { + if(k in style) + continue; + style[k] = pstyle[k]; + } + + if("font-family" in style) + family = style["font-family"]; + if("font-size" in style) + sz = _parse_font_size(style["font-size"]); + if("font-weight" in style) { + if(style["font-weight"] == "bold") + weight = 200; + } + if("font-style" in style) { + if(style["font-style"] == "oblique") + slant = 110; + } + + face = this.mb_rt.font_face_query(family, slant, weight); + obj.set_style([[n.text().length, face, sz]]); + tcoord.add_shape(obj); - for(k in nodes) { - var name = nodes[k].name(); - if (name == "tspan") { - this.parseTSpan(tcoord,nodes[k]); - } else { - } - } - tcoord.set_text=tspan_set_text; + tcoord.set_text = tspan_set_text; tcoord.text = obj; + + this._set_paint_style(style, obj); + this._set_bbox(n, obj); + make_mbnames(this.mb_rt, n, tcoord); }; @@ -179,8 +260,15 @@ paint = this.mb_rt.paint_color_new(c[0], c[1], c[2], alpha); } else if (color.substring(0,3) == 'url') { var id = color.substring(5, color.length-1); - var gr = this.gradients[id]; - paint = this.mb_rt.paint_linear_new(gr[0],gr[1],gr[2],gr[3]); + if(id in this.gradients) { + var gr = this.gradients[id]; + paint = this.mb_rt.paint_linear_new(gr[0],gr[1],gr[2],gr[3]); + } else { + var radial = this.radials[id]; + paint = this.mb_rt.paint_radial_new(radial[0], + radial[1], + radial[2]); + } paint.set_stops(this.stop_ref[id]); } else { paint = this.mb_rt.paint_color_new(0,0,0,1); @@ -246,121 +334,437 @@ coord.center.y = miny; }; +function _mul(m1, m2) { + var res = new Array(); + + res.push(m1[0] * m2[0] + m1[1] * m2[3]); + res.push(m1[0] * m2[1] + m1[1] * m2[4]); + res.push(m1[0] * m2[2] + m1[1] * m2[5] + m1[2]); + res.push(m1[3] * m2[0] + m1[4] * m2[3]); + res.push(m1[3] * m2[1] + m1[4] * m2[4]); + res.push(m1[3] * m2[2] + m1[4] * m2[5] + m1[5]); + + return res; +} + +function _pnt_transform(x, y, matrix) { + var rx, ry; + + rx = x * matrix[0] + y * matrix[1] + matrix[2]; + ry = x * matrix[3] + y * matrix[4] + matrix[5]; + return new Array(rx, ry); +} + +function _shift_transform(x, y, matrix) { + var rx, ry; + + rx = x * matrix[0] + y * matrix[1]; + ry = x * matrix[3] + y * matrix[4]; + return new Array(rx, ry); +} + +function _transform_bbox(bbox, matrix) { + var min_x, min_y, max_x, max_y; + var x, y; + var pnt; + var pnts = new Array(); + var i; + + pnt = _pnt_transform(bbox.x, bbox.y, matrix); + pnts.push(pnt); + pnt = _pnt_transform(bbox.x + bbox.width, bbox.y, matrix); + pnts.push(pnt); + pnt = _pnt_transform(bbox.x, bbox.y + bbox.height, matrix); + pnts.push(pnt); + pnt = _pnt_transform(bbox.x + bbox.width, bbox.y + bbox.height, matrix); + pnts.push(pnt); + + min_x = max_x = pnts[0][0]; + min_y = max_y = pnts[0][1]; + for(i = 1; i < pnts.length; i++) { + pnt = pnts[i]; + if(pnt[0] < min_x) + min_x = pnt[0]; + if(pnt[1] < min_y) + min_y = pnt[1]; + if(pnt[0] > max_x) + max_x = pnt[0]; + if(pnt[1] > max_y) + max_y = pnt[1]; + } + + bbox.x = min_x; + bbox.y = min_y; + bbox.width = max_x - min_x; + bbox.height = max_y - min_y; +} + +function _reverse(m1) { + var rev = new Array(1, 0, 0, 0, 1, 0); + var m = new Array(m1[0], m1[1], m1[2], m1[3], m1[4], m1[5]); + + rev[3] = -m[3] / m[0]; + m[3] = 0; + m[4] += rev[3] * m[1]; + m[5] += rev[3] * m[2]; + + rev[1] = -m[1] / m[4]; + rev[0] += rev[1] * rev[3]; + m[1] = 0; + m[2] += rev[1] * m[5]; + + rev[2] = -m[2]; + rev[5] = -m[5]; + + rev[0] = rev[0] / m[0]; + rev[1] = rev[1] / m[0]; + rev[2] = rev[2] / m[0]; + + rev[3] = rev[3] / m[4]; + rev[4] = rev[4] / m[4]; + rev[5] = rev[5] / m[4]; + + return rev; +} + +var _bbox_proto = { + _get_ac_saved_rev: function() { + var c = this.owner; + var mtx; + + if(c.type != "coord") + c = c.parent; // is a shape! + + mtx = c._mbapp_saved_rev_mtx; + while(c.parent && typeof c.parent != "undefined") { + c = c.parent; + mtx = _mul(mtx, c._mbapp_saved_rev_mtx); + } + + return mtx; + }, + + _get_ac_mtx: function() { + var c = this.owner; + var mtx; + + if(c.type != "coord") + c = c.parent; // is a shape! + + mtx = [c[0], c[1], c[2], c[3], c[4], c[5]]; + while(c.parent) { + c = c.parent; + mtx = _mul(c, mtx); + } + + return mtx; + }, + + _saved_to_current: function() { + var r; + + r = _mul(this._get_ac_mtx(), this._get_ac_saved_rev()); + + return r; + }, + + /*! \brief Update x, y, width, and height of the bbox. + */ + update: function() { + var mtx; + + this.x = this.orig.x; + this.y = this.orig.y; + this.width = this.orig.width; + this.height = this.orig.height; + + mtx = this._saved_to_current(); + _transform_bbox(this, mtx); + }, +}; + +var _center_proto = { + _get_ac_saved_rev: function() { + var c = this.owner; + var mtx; + + if(c.type != "coord") + c = c.parent; // is a shape! + + mtx = c._mbapp_saved_rev_mtx; + while(c.parent && typeof c.parent != "undefined") { + c = c.parent; + mtx = _mul(mtx, c._mbapp_saved_rev_mtx); + } + + return mtx; + }, + + _get_ac_mtx: function() { + var c = this.owner; + var mtx; + + if(c.type != "coord") + c = c.parent; // is a shape! + + mtx = [c[0], c[1], c[2], c[3], c[4], c[5]]; + while(c.parent) { + c = c.parent; + mtx = _mul(c, mtx); + } + + return mtx; + }, + + _get_ac_rev: function() { + var c = this.owner; + var mtx; + + if(c.type != "coord") + c = c.parent; // is a shape! + + mtx = _reverse([c[0], c[1], c[2], c[3], c[4], c[5]]); + while(c.parent) { + c = c.parent; + mtx = _mul(mtx, _reverse([c[0], c[1], c[2], c[3], c[4], c[5]])); + } + + return mtx; + }, + + _saved_to_current: function() { + var r; + + r = _mul(this._get_ac_mtx(), this._get_ac_saved_rev()); + + return r; + }, + + /*! \brief Update x, y of center point of an object. + */ + update: function() { + var mtx; + var xy; + + mtx = this._saved_to_current(); + xy = _pnt_transform(this.orig.x, this.orig.y, mtx); + + this._x = xy[0]; + this._y = xy[1]; + }, + + /*! \brief Move owner object to make center at (x, y). + */ + move: function(x, y) { + var mtx; + var xdiff = x - this._x; + var ydiff = y - this._y; + var shiftxy; + var c; + + mtx = this._get_ac_rev(); + shiftxy = _shift_transform(xdiff, ydiff, mtx); + + c = this.owner; + if(c.type != "coord") + c = c.parent; + + c[2] += shiftxy[0]; + c[5] += shiftxy[1]; + + this._x = x; + this._y = y; + }, + + /*! \brief Move owner object to make center at position specified by pnt. + */ + move_pnt: function(pnt) { + this.move(pnt.x, pnt.y); + }, + + /*! \brief Prevent user to modify value. + */ + get x() { return this._x; }, + + /*! \brief Prevent user to modify value. + */ + get y() { return this._y; }, + + get rel() { + var rev; + var xy; + + rev = this._get_ac_rev(); + xy = _pnt_transform(this.orig.x, this.orig.y, rev); + + return {x: xy[0], y: xy[1]}; + }, +}; loadSVG.prototype._set_bbox = function(node, tgt) { var a; var vstr; var bbox, center; + var orig; a = node.attr("bbox-x"); - sys.puts("a="+a); if(!a) return 0; + /* bbox.orig is initial values of bbox. The bbox is recomputed + * according bbox.orig and current matrix. See bbox.update(). + */ tgt.bbox = bbox = new Object(); + bbox.orig = orig = new Object(); + bbox.owner = tgt; + bbox.__proto__ = _bbox_proto; vstr = a.value(); - bbox.x = parseFloat(vstr); + orig.x = parseFloat(vstr); a = node.attr("bbox-y"); vstr = a.value(); - bbox.y = this.height - parseFloat(vstr); + orig.y = this.height - parseFloat(vstr); a = node.attr("bbox-width"); vstr = a.value(); - bbox.width = parseFloat(vstr); + orig.width = parseFloat(vstr); a = node.attr("bbox-height"); vstr = a.value(); - bbox.height = parseFloat(vstr); - bbox.y -= bbox.height; + orig.height = parseFloat(vstr); + orig.y -= orig.height; + + bbox.update(); + /* center.orig is initial values of center. The center is + * recomputed according center.orig and current matrix. See + * center.update(). + */ tgt.center = center = new Object(); + center.orig = orig = new Object(); - center.x = bbox.width / 2 + bbox.x; - center.y = bbox.height / 2 + bbox.y; - //center.x = bbox.x; - //center.y = bbox.y; + orig.x = bbox.orig.width / 2 + bbox.orig.x; + orig.y = bbox.orig.height / 2 + bbox.orig.y; a = node.attr("transform-center-x"); - if(!a) - return 1; + if(a) { + vstr = a.value(); + orig.x += parseFloat(vstr); + a = node.attr("transform-center-y"); + vstr = a.value(); + orig.y -= parseFloat(vstr); + } + center.__proto__ = _center_proto; + center.owner = tgt; + center.update(); - vstr = a.value(); - center.x += parseFloat(vstr); - a = node.attr("transform-center-y"); - vstr = a.value(); - center.y -= parseFloat(vstr); return 1; } -loadSVG.prototype._set_paint = function(node, tgt) { - var style = node.attr('style'); +loadSVG.prototype._set_paint_style = function(style, tgt) { var paint; var fill_alpha = 1; var stroke_alpha = 1; + var alpha = 1; var fill_color; var stroke_color; - var black_paint; + var stroke_width = 1; var i; - if(style != null) { - var items = style.value().split(';'); - var alpha; - - for(i in items) { - var f = items[i].split(':'); - if (f[0] == 'opacity') { - alpha = f[1]; - } else if (f[0] == 'fill') { - fill_color = f[1]; - } else if (f[0] == 'fill-opacity') { - fill_alpha = parseFloat(f[1]); - } else if (f[0] == 'stroke') { - stroke_color = f[1]; - } else if (f[0] == 'stroke-width') { - tgt.stroke_width = parseFloat(f[1]); - } else if (f[0] == 'stroke-opacity') { - stroke_alpha = parseFloat(f[1]); - } else if (f[0] == 'display') { - if(f[1] == 'none') - return; - } - } - + if(style) { + if('opacity' in style) + alpha = parseFloat(style['opacity']); + if('fill' in style) + fill_color = style['fill']; + if('fill-opacity' in style) + fill_alpha = parseFloat(style['fill-opacity']); + if('stroke' in style) + stroke_color = style['stroke']; + if('stroke-width' in style) + stroke_width = parseFloat(style['stroke-width']); + if('stroke-opacity' in style) + stroke_alpha = parseFloat(style['stroke-opacity']); + if('display' in style && style['display'] == 'none') + return; } - if(!fill_color || !stroke_color) - black_paint = this.mb_rt.paint_color_new(0, 0, 0, 1); - if(fill_color) { if(fill_color != "none") { paint = this._prepare_paint_color(fill_color, fill_alpha); paint.fill(tgt); } - } else { - black_paint.fill(tgt); } if(stroke_color) { if(stroke_color != "none") { paint = this._prepare_paint_color(stroke_color, stroke_alpha); paint.stroke(tgt); } - } else { - black_paint.stroke(tgt); } + + tgt.stroke_width = stroke_width; + + if(alpha < 1) + tgt.parent.opacity = alpha; }; +loadSVG.prototype._set_paint = function(node, tgt) { + var style; + + style = parse_style(node); + this._set_paint_style(style, tgt); +}; + +function formalize_path_data(d) { + var posM, posm; + var pos; + var nums = "0123456789+-."; + var rel = false; + var cmd; + + posM = d.search("M"); + posm = d.search("m"); + pos = posm < posM? posm: posM; + if(pos == -1) + pos = posM == -1? posm: posM; + if(pos == -1) + return d; + + if(posm == pos) + rel = true; + + pos = pos + 1; + while(pos < d.length && " ,".search(d[pos]) >= 0) + pos++; + while(pos < d.length && nums.search(d[pos]) >= 0) + pos++; + while(pos < d.length && " ,".search(d[pos]) >= 0) + pos++; + while(pos < d.length && nums.search(d[pos]) >= 0) + pos++; + while(pos < d.length && " ,".search(d[pos]) >= 0) + pos++; + if(nums.search(d[pos]) >= 0) { + if(rel) + cmd = "l"; + else + cmd = "L"; + d = d.substring(0, pos) + cmd + formalize_path_data(d.substring(pos)); + } + return d; +} + loadSVG.prototype.parsePath=function(accu, coord,id, n) { - var d = n.attr('d').value(); + var d = formalize_path_data(n.attr('d').value()); var style = n.attr('style'); var path = this.mb_rt.path_new(d); - - guessPathBoundingBox(coord,d); - this._set_bbox(n, path); + var pcoord = this.mb_rt.coord_new(coord); + + guessPathBoundingBox(pcoord,d); + pcoord.add_shape(path); this._set_paint(n, path); - coord.add_shape(path); + this._set_bbox(n, path); - make_mbnames(this.mb_rt, n, path); + make_mbnames(this.mb_rt, n, pcoord); }; loadSVG.prototype.parseText=function(accu,coord,id, n) @@ -368,7 +772,7 @@ var x = getInteger(n,'x'); var y = getInteger(n,'y'); var tcoord = this.mb_rt.coord_new(coord); - var style = new Object(); + var style; if (n.attr('x')) { var nx = coord[0]*x+coord[1]*y+coord[2]; @@ -380,9 +784,7 @@ if (coord.center.y > ny) coord.center.y = ny; } - style.fs = 20; - style.family = 'courier'; - parseTextStyle(style,n); + style = parse_style(n); var nodes = n.childNodes(); var k; for(k in nodes) { @@ -392,16 +794,7 @@ } else { } } - sys.puts(y); - if (this._set_bbox(n, tcoord)) { - tcoord.center.x -= tcoord[2]; - tcoord.center.y -= tcoord[5]; - tcoord._x = tcoord.center.x; - tcoord._y = tcoord.center.y; - } else { - tcoord._x = coord.center.x; - tcoord._y = coord.center.y; - } + this._set_bbox(n, tcoord); make_mbnames(this.mb_rt, n, tcoord); }; @@ -478,25 +871,9 @@ parseTransform(tcoord,trans.value()); var rect = this.mb_rt.rect_new(x,y,w,h,10, 10); + tcoord.add_shape(rect); this._set_paint(n, rect); - if (this._set_bbox(n, tcoord)) { - tcoord.center.x -= tcoord[2]; - tcoord.center.y -= tcoord[5]; - } else { - if (trans) { - rx = tcoord[0]*x+tcoord[1]*y+tcoord[2]; - ry = tcoord[3]*x+tcoord[4]*y+tcoord[5]; - if (tcoord.center.x > rx) - tcoord.center.x = rx; - if (tcoord.center.y > ry) - tcoord.center.y = ry; - } - } - sys.puts("center.x="+tcoord.center.x); - sys.puts("center.y="+tcoord.center.y); - tcoord._x = tcoord.center.x; - tcoord._y = tcoord.center.y; - tcoord.add_shape(rect); + this._set_bbox(n, tcoord); make_mbnames(this.mb_rt, n, tcoord); }; @@ -555,7 +932,7 @@ style = {}; parseGroupStyle(style, n); if(style.opacity) { - sys.puts(style.opacity); + sys.puts("opacity=" + style.opacity); coord.opacity=style.opacity; } @@ -583,13 +960,7 @@ if (root.center.y > coord.center.y) root.center.y = coord.center.y; - if (this._set_bbox(n, coord)) { - coord.center.x -= accu[2]; - coord.center.y -= accu[5]; - } - coord._x = coord.center.x; - coord._y = coord.center.y; - sys.puts("coord.center.x="+coord.center.x+",coord.center.y="+coord.center.y); + this._set_bbox(n, coord); make_mbnames(this.mb_rt, n, coord); }; @@ -641,12 +1012,54 @@ paint.fill(img); tcoord.add_shape(img); - if (this._set_bbox(n, img)) { - img.center.x -= accu[2]+coord[2]; - img.center.y -= accu[5]+coord[5]; + this._set_bbox(n, img); + + make_mbnames(this.mb_rt, n, img); +}; + +function _parse_stops(n) { + var children; + var child; + var style; + var color; + var rgb; + var opacity; + var r, g, b, a; + var offset_atr, offset; + var stops = []; + var i; + + children = n.childNodes(); + for(i = 0; i < children.length; i++) { + child = children[i]; + if(child.name() == "stop") { + style = parse_style(child); + + color = style["stop-color"]; + if(color) { + rgb = parse_color(color); + r = rgb[0]; + g = rgb[1]; + b = rgb[2]; + } + + opacity = style["stop-opacity"]; + if(opacity) + a = parseFloat(opacity); + else + a = 1; + + offset_attr = child.attr("offset"); + if(offset_attr) + offset = parseFloat(offset_attr.value()); + else + offset = 0; + + stops.push([offset, r, g, b, a]); + } } - make_mbnames(this.mb_rt, n, img); + return stops; }; loadSVG.prototype._MB_parseLinearGradient=function(root,n) @@ -654,71 +1067,111 @@ var id = n.attr('id'); var k; var nodes = n.childNodes(); + var mtx = [1, 0, 0, 0, 1, 0]; if (id == null) return; + id = id.value(); + var x1 = n.attr("x1"); var y1 = n.attr("y1"); var x2 = n.attr("x2"); var y2 = n.attr("y2"); + var xy; var gr; var color, opacity; var stops; var r,g,b; - stops=[]; - for(k in nodes) { - var ss = nodes[k]; - if (ss.name()=="stop") { - var style = ss.attr("style").value(); - var items = style.split(';'); - var off = parseInt(ss.attr('offset').value()); - color = 'black'; - opacity = 1; - for (i in items) { - it = items[i]; - var f = it.split(':'); - k = f[0]; - v = f[1]; - if (k == 'stop-color') { - color = v.substring(1); - if (v == 'white') { - r = 1; - g = 1; - b = 1; - } else if (v == 'black') { - r = 0; - g = 0; - b = 0; - } else { - r = parseInt(color.substring(0,2),16)/255.0; - g = parseInt(color.substring(2,4),16)/255.0; - b = parseInt(color.substring(4,6),16)/255.0; - } - } else if (k=='stop-opacity') { - opacity = parseFloat(v); - } - } - stops.push([off, r,g,b,opacity]); - } + + if(x1) + x1 = parseFloat(x1.value()); + if(x2) + x2 = parseFloat(x2.value()); + if(y1) + y1 = parseFloat(y1.value()); + if(y2) + y2 = parseFloat(y2.value()); + + stops = _parse_stops(n); + + var href = n.attr('href'); + if(href != null) { + href = href.value(); + var hrefid = href.substring(1); + pstops = this.stop_ref[hrefid]; + stops = pstops.concat(stops); + + var hrefgr = this.gradients[hrefid]; + if(typeof x1 == "undefined") + x1 = hrefgr[0]; + if(typeof y1 == "undefined") + y1 = hrefgr[1]; + if(typeof x2 == "undefined") + x2 = hrefgr[2]; + if(typeof y2 == "undefined") + y2 = hrefgr[3]; } - var href = n.attr('href'); - if (href != null) { - href = href.value(); - pstops = this.stop_ref[href.substring(1)]; - stops = pstops.concat(stops); + + if(n.attr("gradientTransform")) { + parseTransform(mtx, n.attr("gradientTransform").value()); + xy = _pnt_transform(x1, y1, mtx); + x1 = xy[0]; + y1 = xy[1]; + xy = _pnt_transform(x2, y2, mtx); + x2 = xy[0]; + y2 = xy[1]; } - id = id.value(); + this.stop_ref[id] = stops; - if (x1) - x1 = parseFloat(x1.value()); - if (x2) - x2 = parseFloat(x2.value()); - if (y1) - y1 = parseFloat(y1.value()); - if (y2) - y2 = parseFloat(y2.value()); this.gradients[id] = [x1,y1,x2,y2]; }; +loadSVG.prototype._MB_parseRadialGradient = function(root,n) { + var stops; + var cx, cy; + var xy; + var mtx = [1, 0, 0, 0, 1, 0]; + var id; + var href; + var r; + + id = n.attr("id"); + if(!id) + throw "Require an id"; + id = id.value(); + + stops = _parse_stops(n); + + cx = n.attr("cx"); + if(!cx) + throw "Miss cx attribute"; + cy = n.attr("cy"); + if(!cy) + throw "Miss cy attribute"; + cx = parseFloat(cx.value()); + cy = parseFloat(cy.value()); + + r = n.attr("r"); + if(!r) + throw "Miss r attribute"; + r = parseFloat(r.value()); + + href = n.attr("href"); + if(href) { + href = href.value().substring(1); + stops = this.stop_ref[href]; + } + + if(n.attr("gradientTransform")) { + parseTransform(mtx, n.attr("gradientTransform").value()); + xy = _pnt_transform(cx, cy, mtx); + cx = xy[0]; + cy = xy[1]; + } + + this.radials[id] = [cx, cy, r]; + this.stop_ref[id] = stops; +} + loadSVG.prototype.parseDefs=function(root,n) { var k; @@ -728,6 +1181,8 @@ var name = nodes[k].name(); if (name == "linearGradient") { this._MB_parseLinearGradient(root,nodes[k]); + } else if(name == "radialGradient") { + this._MB_parseRadialGradient(root,nodes[k]); } } };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nodejs/svgviewer.js Sun Oct 03 18:15:00 2010 +0800 @@ -0,0 +1,8 @@ +// -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- +// vim: sw=4:ts=8:sts=4 +var svg = require("./svg"); +var mbapp = require("./mbapp"); + +app = new mbapp.app(); +app.loadSVG("test.svg"); +app.loop();
--- a/nodejs/testdesktop.js Sun Oct 03 18:12:11 2010 +0800 +++ b/nodejs/testdesktop.js Sun Oct 03 18:15:00 2010 +0800 @@ -1,3 +1,4 @@ +// -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- // vim: sw=4:ts=8:sts=4 var svg = require("./svg"); var mbapp = require("./mbapp"); @@ -16,97 +17,110 @@ setting = app.get("setting"); lightbar = app.get("lightbar"); -lines=[app.get("line1"),app.get("line2"),app.get("line3"), app.get("line4"),app.get("line5")]; -for(i=0;i<lines.length;i++) { - sys.puts("["+i+"]="+lines[i].y); +lines = []; +for(i = 0; i < 5; i++) { + line = app.get("line" + (i + 1)); + lines.push(line); } line=0; -items=[video,audio,picture,setting]; +items=[video, audio, picture, setting]; + item = 0; -an = new animate.scale(app,items[item],1,1.5,0.1); -an.start(); + +animate.run([new animate.scale(app,items[item], 1, 1.5)], 0, 0.1); app.refresh(); + app.addKeyListener(mbapp.KEY_LEFT, function() { - var old = items[item]; - item = item - 1; - if (item == -1) { - item = 0; - return; - } - var target = items[item]; - var an = new animate.scale(app,old,1,1,0.1); - an.start(); - an = new animate.scale(app,target,1,1.5,0.3); - an.start(); + var old = items[item]; + item = item - 1; + if (item == -1) { + item = 0; + return; + } + + var target = items[item]; + + old.bbox.update(); + target.bbox.update(); + + var an = new animate.scale(app, old, 1, 1); + animate.run([an], 0, 0.1); + an = new animate.scale(app, target, 1, 1.5); + animate.run([an], 0, 0.3); }); app.addKeyListener(mbapp.KEY_RIGHT, function() { - var old = items[item]; - item = item + 1; - if (item == items.length) { - item = item - 1; - return; - } - var target = items[item]; - var an = new animate.scale(app,old,1,1,0.1); - an.start(); - an = new animate.scale(app,target,1,1.5,0.3); - an.start(); + var old = items[item]; + item = item + 1; + if (item == items.length) { + item = item - 1; + return; + } + + var target = items[item]; + + old.bbox.update(); + target.bbox.update(); + + var an = new animate.scale(app, old, 1, 1); + animate.run([an], 0, 0.1); + an = new animate.scale(app, target, 1, 1.5); + animate.run([an], 0, 0.3); }); app.addKeyListener(mbapp.KEY_UP, function() { - var old = lines[line]; - line = line - 1; - if (line == -1) { - line = 0; - return; - } - var target = lines[line]; - var sy = target.y-lightbar.y; - sys.puts(sy); - var an = new animate.linear(app,lightbar,0,sy,0.3); - an.start(); + var old = lines[line]; + line = line - 1; + if (line == -1) { + line = 0; + return; + } + var target = lines[line]; + var sy = target.center.y - lightbar.center.y; + sys.puts(sy); + var an = new animate.shift(app, lightbar, 0, sy); + animate.run([an], 0, 0.3); }); app.addKeyListener(mbapp.KEY_DOWN, function() { - var old = lines[line]; - line = line + 1; - if (line == lines.length) { - line = line - 1; - return; - } - var target = lines[line]; - var sy = target.y-lightbar.y; - sys.puts("line="+line); - sys.puts("sy="+sy); - sys.puts("target.y="+target.y); - sys.puts("lightbar.y="+lightbar.y); - var an = new animate.linear(app,lightbar,0,sy,0.3); - an.start(); + var old = lines[line]; + line = line + 1; + if (line == lines.length) { + line = line - 1; + return; + } + var target = lines[line]; + var sy = target.center.y - lightbar.center.y; + sys.puts("line="+line); + sys.puts("sy="+sy); + sys.puts("target.y="+target.center.y); + sys.puts("lightbar.y="+lightbar.center.y); + var an = new animate.shift(app, lightbar, 0, sy); + animate.run([an], 0, 0.3); }); app.addKeyListener(mbapp.KEY_ENTER, function() { - var target = items[item]; - var sx = 500-target.x; - var sy = 220-target.y; - sys.puts("target "+sx+','+sy); - var an = new animate.linear(app,target,sx,sy,1); - an.start(); - for(i=0;i<items.length;i++) { - if (i == item) continue; - var x = Math.random(); - var y = Math.random(); - if (x > 0.5) x = 900; - else x = -500; - if (y > 0.5) y = 900; - else y = -500; - sx = x-items[i].x; - sy = y-items[i].y; - an = new animate.linear(app,items[i], sx,sy,2); - an.start(); - alpha = new animate.alpha(app,items[i],0, 1); - alpha.start(); - } + var target = items[item]; + var sx = 500 - target.center.x; + var sy = 220 - target.center.y; + sys.puts("target "+sx+','+sy); + var an = new animate.shift(app,target,sx,sy,1); + an.start(); + for(i=0;i<items.length;i++) { + if (i == item) continue; + var x = Math.random(); + var y = Math.random(); + if (x > 0.5) x = 900; + else x = -500; + if (y > 0.5) y = 900; + else y = -500; + sx = x - items[i].center.x; + sy = y - items[i].center.y; + an = new animate.shift(app,items[i], sx, sy); + animate.run([an], 0, 2); + alpha = new animate.alpha(app,items[i], 0); + animate.run([an], 0, 1); + } }); app.loop();
--- a/src/graph_engine_cairo.c Sun Oct 03 18:12:11 2010 +0800 +++ b/src/graph_engine_cairo.c Sun Oct 03 18:15:00 2010 +0800 @@ -19,7 +19,7 @@ */ static FcPattern *query_font_pattern(const char *family, int slant, int weight) { - FcPattern *ptn, *p, *fn_ptn; + FcPattern *ptn, *fn_ptn; FcValue val; FcConfig *cfg; FcBool r; @@ -32,8 +32,7 @@ cfg = FcConfigGetCurrent(); ptn = FcPatternCreate(); - p = FcPatternCreate(); - if(ptn == NULL || p == NULL) + if(ptn == NULL) goto err; val.type = FcTypeString; @@ -48,17 +47,17 @@ val.u.i = weight; FcPatternAdd(ptn, "weight", val, FcTrue); - r = FcConfigSubstituteWithPat(cfg, ptn, NULL, FcMatchPattern); + FcDefaultSubstitute(ptn); + + r = FcConfigSubstituteWithPat(cfg, ptn, ptn, FcMatchPattern); if(!r) goto err; - r = FcConfigSubstituteWithPat(cfg, p, ptn, FcMatchFont); + r = FcConfigSubstituteWithPat(cfg, ptn, ptn, FcMatchFont); if(!r) goto err; - FcDefaultSubstitute(p); - - fn_ptn = FcFontMatch(cfg, p, &result); + fn_ptn = FcFontMatch(cfg, ptn, &result); /* It is supposed to return FcResultMatch. But, it is no, now. * I don't know why. Someone should figure out the issue. @@ -73,15 +72,12 @@ goto err; FcPatternDestroy(ptn); - FcPatternDestroy(p); return fn_ptn; err: if(ptn) FcPatternDestroy(ptn); - if(p) - FcPatternDestroy(p); return NULL; }
--- a/src/paint.c Sun Oct 03 18:12:11 2010 +0800 +++ b/src/paint.c Sun Oct 03 18:15:00 2010 +0800 @@ -17,7 +17,7 @@ int _paint_color_size = sizeof(paint_color_t); -static void paint_color_prepare(paint_t *paint, mbe_t *cr) { +static void paint_color_prepare(paint_t *paint, mbe_t *cr, shape_t *sh) { paint_color_t *color = (paint_color_t *)paint; mbe_set_source_rgba(cr, color->r, color->g, color->b, color->a); @@ -84,17 +84,27 @@ int _paint_linear_size = sizeof(paint_linear_t); -static void paint_linear_prepare(paint_t *paint, mbe_t *cr) { +static void paint_linear_prepare(paint_t *paint, mbe_t *cr, shape_t *sh) { paint_linear_t *linear = (paint_linear_t *)paint; mbe_pattern_t *ptn; + co_aix x1, y1; + co_aix x2, y2; + co_aix *mtx; ptn = linear->ptn; if(linear->flags & LIF_DIRTY) { + mtx = sh_get_aggr_matrix(sh); + x1 = linear->x1; + y1 = linear->y1; + matrix_trans_pos(mtx, &x1, &y1); + x2 = linear->x2; + y2 = linear->y2; + matrix_trans_pos(mtx, &x2, &y2); + if(ptn) mbe_pattern_destroy(ptn); linear->flags &= ~LIF_DIRTY; - ptn = mbe_pattern_create_linear(linear->x1, linear->y1, - linear->x2, linear->y2, + ptn = mbe_pattern_create_linear(x1, y1, x2, y2, linear->stops, linear->n_stops); ASSERT(ptn != NULL); linear->ptn = ptn; @@ -174,13 +184,20 @@ int _paint_radial_size = sizeof(paint_radial_t); -static void paint_radial_prepare(paint_t *paint, mbe_t *cr) { +static void paint_radial_prepare(paint_t *paint, mbe_t *cr, shape_t *sh) { paint_radial_t *radial = (paint_radial_t *)paint; mbe_pattern_t *ptn; + co_aix cx, cy; + co_aix *mtx; if(radial->flags & RDF_DIRTY) { - ptn = mbe_pattern_create_radial(radial->cx, radial->cy, 0, - radial->cx, radial->cy, + mtx = sh_get_aggr_matrix(sh); + cx = radial->cx; + cy = radial->cy; + matrix_trans_pos(mtx, &cx, &cy); + + ptn = mbe_pattern_create_radial(cx, cy, 0, + cx, cy, radial->r, radial->stops, radial->n_stops); @@ -256,7 +273,7 @@ int _paint_image_size = sizeof(paint_image_t); static -void paint_image_prepare(paint_t *paint, mbe_t *cr) { +void paint_image_prepare(paint_t *paint, mbe_t *cr, shape_t *sh) { paint_image_t *paint_img = (paint_image_t *)paint; mb_img_data_t *img_data;
--- a/src/redraw_man.c Sun Oct 03 18:12:11 2010 +0800 +++ b/src/redraw_man.c Sun Oct 03 18:15:00 2010 +0800 @@ -612,6 +612,7 @@ coord_canvas_info_new(redraw_man_t *rdman, coord_t *coord, mbe_t *canvas) { coord_canvas_info_t *info; + static co_aix id[6] = {1, 0, 0, 0, 1, 0}; info = (coord_canvas_info_t *)elmpool_elm_alloc(rdman->coord_canvas_pool); if(info == NULL) @@ -624,6 +625,10 @@ bzero(info->pcache_areas, sizeof(area_t) * 2); info->pcache_cur_area = &info->pcache_areas[0]; info->pcache_last_area = &info->pcache_areas[1]; + memcpy(info->cache_2_pdev, id, sizeof(co_aix) * 6); + memcpy(info->cache_2_pdev_rev, id, sizeof(co_aix) * 6); + memcpy(info->aggr_2_pdev, id, sizeof(co_aix) * 6); + memcpy(info->aggr_2_pdev_rev, id, sizeof(co_aix) * 6); return info; } @@ -1310,8 +1315,8 @@ /* \brief Compute matrix from cached canvas to parent device space. */ -static void compute_cached_2_pdev_matrix(coord_t *coord, - co_aix canvas2pdev_matrix[6]) { +static void compute_cached_2_pdev_matrix(coord_t *coord) { + co_aix *canvas2pdev_matrix = coord_get_2pdev(coord); coord_t *parent; co_aix *aggr; co_aix *matrix, *paggr; @@ -1337,6 +1342,8 @@ canvas2p[5] = shift_y; matrix_mul(paggr, canvas2p, canvas2pdev_matrix); + + compute_reverse(canvas2pdev_matrix, coord_get_2pdev_rev(coord)); } /*! \brief Compute area in parent cached coord for a cached coord. @@ -1351,7 +1358,7 @@ * ancestral cached coord. */ static void compute_pcache_area(coord_t *coord) { - co_aix cached2pdev[6]; + co_aix *cached2pdev = coord_get_2pdev(coord); int c_w, c_h; canvas_t *canvas; coord_canvas_info_t *canvas_info; @@ -1360,7 +1367,6 @@ canvas_info = coord->canvas_info; SWAP(canvas_info->pcache_cur_area, canvas_info->pcache_last_area, area_t *); - compute_cached_2_pdev_matrix(coord, cached2pdev); canvas = _coord_get_canvas(coord); canvas_get_size(canvas, &c_w, &c_h); @@ -1766,6 +1772,7 @@ coord = all_zeroing->ds[i]; if(coord_is_zeroing(coord)) zeroing_coord(rdman, coord); + compute_cached_2_pdev_matrix(coord); /* This is required by ancester cached ones to perform * zeroing. */ @@ -1775,6 +1782,34 @@ return OK; } +/*! \brief Update aggregated cache_2_pdev matrix for cached coords. + * + * This is perfromed from root to leaves. Aggregated cache_2_pdev is + * named as aggr_2_pdev field of canvas_info_t. It is the matrix to + * transform a point from space of a cached coord to the space of root + * coord. + */ +static int +update_aggr_pdev(redraw_man_t *rdman) { + int i; + coords_t *all_zeroing; + coord_t *coord, *parent_cached; + + all_zeroing = &rdman->zeroing_coords; + for(i = 0; i < all_zeroing->num; i++) { + coord = all_zeroing->ds[i]; + parent_cached = coord_get_cached(coord_get_parent(coord)); + matrix_mul(coord_get_2pdev(parent_cached), + coord_get_2pdev(coord), + coord_get_aggr2pdev(coord)); + matrix_mul(coord_get_2pdev_rev(coord), + coord_get_2pdev_rev(parent_cached), + coord_get_aggr2pdev_rev(coord)); + } + + return OK; +} + /*! \brief Add aggregated dirty areas to ancestor. * * Dirty areas are aggregated into two areas. It assumes that even or odd @@ -1786,7 +1821,7 @@ int i; int n_areas; co_aix poses0[2][2], poses1[2][2]; - co_aix canvas2pdev_matrix[6]; + co_aix *canvas2pdev_matrix; area_t **areas, *area; area_t *area0, *area1; coord_t *parent, *pcached_coord; @@ -1863,7 +1898,7 @@ parent = coord_get_parent(coord); pcached_coord = coord_get_cached(parent); - compute_cached_2_pdev_matrix(coord, canvas2pdev_matrix); + canvas2pdev_matrix = coord_get_2pdev(coord); /* Add dirty areas to parent cached coord. */ matrix_trans_pos(canvas2pdev_matrix, poses0[0], poses0[0] + 1); @@ -2032,6 +2067,10 @@ if(r != OK) return ERR; + r = update_aggr_pdev(rdman); + if(r != OK) + return ERR; + /* * Clear all flags setted by zeroing. */ @@ -2129,7 +2168,7 @@ fill = shape->fill; if(shape->fill) { - fill->prepare(fill, cr); + fill->prepare(fill, cr, shape); if(shape->stroke) fill_path_preserve(rdman, cr); else @@ -2138,7 +2177,7 @@ stroke = shape->stroke; if(stroke) { - stroke->prepare(stroke, cr); + stroke->prepare(stroke, cr, shape); set_shape_stroke_param(shape, cr); stroke_path(rdman, cr); } @@ -2209,22 +2248,20 @@ static void update_cached_canvas_2_parent(redraw_man_t *rdman, coord_t *coord) { mbe_t *pcanvas, *canvas; - co_aix reverse[6]; - co_aix canvas2pdev_matrix[6]; + co_aix *c2pdev_reverse; if(coord_is_root(coord)) return; - compute_cached_2_pdev_matrix(coord, canvas2pdev_matrix); - compute_reverse(canvas2pdev_matrix, reverse); + c2pdev_reverse = coord_get_2pdev_rev(coord); canvas = _coord_get_canvas(coord); pcanvas = _coord_get_canvas(coord->parent); #ifndef UNITTEST - _update_cached_canvas_2_parent(rdman, reverse, canvas, pcanvas, + _update_cached_canvas_2_parent(rdman, c2pdev_reverse, canvas, pcanvas, coord->opacity); #else - memcpy(((mock_mbe_t *)canvas)->parent_2_cache, reverse, + memcpy(((mock_mbe_t *)canvas)->parent_2_cache, c2pdev_reverse, sizeof(co_aix) * 6); #endif } @@ -2344,8 +2381,10 @@ draw_dirty_cached_coord(rdman, coord); coord_set_flags(coord, COF_TEMP_MARK); } - for(i = 0; i < num; i++) + for(i = 0; i < num; i++) { + coord = zeroings[i]; coord_clear_flags(coord, COF_TEMP_MARK); + } draw_dirty_cached_coord(rdman, rdman->root_coord); }