comparison nodejs/svg.js @ 854:eff2f580b536 abs_n_rel_center

Use accessor to return bbox values
author Thinker K.F. Li <thinker@codemud.net>
date Mon, 20 Sep 2010 22:43:43 +0800
parents 0027379c962e
children ea1e88c40548
comparison
equal deleted inserted replaced
853:13e0953c3fb3 854:eff2f580b536
244 coord.center.x = minx; 244 coord.center.x = minx;
245 if (coord.center.y > miny) 245 if (coord.center.y > miny)
246 coord.center.y = miny; 246 coord.center.y = miny;
247 }; 247 };
248 248
249 function _mul(m1, m2) {
250 var res = new Array();
251
252 res.push(m1[0] * m2[0] + m1[1] * m2[3]);
253 res.push(m1[0] * m2[1] + m1[1] * m2[4]);
254 res.push(m1[0] * m2[2] + m1[1] * m2[5] + m1[2]);
255 res.push(m1[3] * m2[0] + m1[4] * m2[3]);
256 res.push(m1[3] * m2[1] + m1[4] * m2[4]);
257 res.push(m1[3] * m2[2] + m1[4] * m2[5] + m1[5]);
258
259 return res;
260 }
261
262 function _pnt_transform(x, y, matrix) {
263 var rx, ry;
264
265 rx = x * matrix[0] + y * matrix[1] + matrix[2];
266 ry = x * matrix[3] + y * matrix[4] + matrix[5];
267 return new Array(rx, ry);
268 }
269
270 function _shift_transform(x, y, matrix) {
271 var rx, ry;
272
273 rx = x * matrix[0] + y * matrix[1];
274 ry = x * matrix[3] + y * matrix[4];
275 return new Array(rx, ry);
276 }
277
278 function _transform_bbox(bbox, matrix) {
279 var min_x, min_y, max_x, max_y;
280 var x, y;
281 var pnt;
282 var pnts = new Array();
283 var i;
284
285 pnt = _pnt_transform(bbox.x, bbox.y, matrix);
286 pnts.push(pnt);
287 pnt = _pnt_transform(bbox.x + bbox.width, bbox.y, matrix);
288 pnts.push(pnt);
289 pnt = _pnt_transform(bbox.x, bbox.y + bbox.height, matrix);
290 pnts.push(pnt);
291 pnt = _pnt_transform(bbox.x + bbox.width, bbox.y + bbox.height, matrix);
292 pnts.push(pnt);
293
294 min_x = max_x = pnts[0][0];
295 min_y = max_y = pnts[0][1];
296 for(i = 1; i < pnts.length; i++) {
297 pnt = pnts[i];
298 if(pnt[0] < min_x)
299 min_x = pnt[0];
300 if(pnt[1] < min_y)
301 min_y = pnt[1];
302 if(pnt[0] > max_x)
303 max_x = pnt[0];
304 if(pnt[1] > max_y)
305 max_y = pnt[1];
306 }
307
308 bbox.x = min_x;
309 bbox.y = min_y;
310 bbox.width = max_x - min_x;
311 bbox.height = max_y - min_y;
312 }
313
314 function _reverse(m1) {
315 var rev = new Array(1, 0, 0, 0, 1, 0);
316 var m = new Array(m1[0], m1[1], m1[2], m1[3], m1[4], m1[5]);
317
318 rev[3] = -m[3] / m[0];
319 m[3] = 0;
320 m[4] += rev[3] * m[1];
321 m[5] += rev[3] * m[2];
322
323 rev[1] = -m[1] / m[4];
324 rev[0] += rev[1] * rev[3];
325 m[1] = 0;
326 m[2] += rev[1] * m[5];
327
328 rev[2] = -m[2];
329 rev[5] = -m[5];
330
331 rev[0] = rev[0] / m[0];
332 rev[1] = rev[1] / m[0];
333 rev[2] = rev[2] / m[0];
334
335 rev[3] = rev[3] / m[4];
336 rev[4] = rev[4] / m[4];
337 rev[5] = rev[5] / m[4];
338
339 return rev;
340 }
341
342 var _bbox_proto = {
343 _get_ac_saved_rev: function() {
344 var c = this.owner;
345 var mtx;
346
347 if(c.type != "coord")
348 c = c.parent; // is a shape!
349
350 mtx = c._mbapp_saved_rev_mtx;
351 while(c.parent && typeof c.parent != "undefined") {
352 c = c.parent;
353 mtx = _mul(mtx, c._mbapp_saved_rev_mtx);
354 }
355
356 return mtx;
357 },
358
359 _get_ac_mtx: function() {
360 var c = this.owner;
361 var mtx;
362
363 if(c.type != "coord")
364 c = c.parent; // is a shape!
365
366 mtx = [c[0], c[1], c[2], c[3], c[4], c[5]];
367 while(c.parent) {
368 c = c.parent;
369 mtx = _mul(c, mtx);
370 }
371
372 return mtx;
373 },
374
375 _saved_to_current: function() {
376 var r;
377
378 r = _mul(this._get_ac_mtx(), this._get_ac_saved_rev());
379
380 return r;
381 },
382
383 /*! \brief Update x, y, width, and height of the bbox.
384 */
385 update: function() {
386 var mtx;
387
388 this.x = this._svg_saved_x;
389 this.y = this._svg_saved_y;
390 this.width = this._svg_saved_width;
391 this.height = this._svg_saved_height;
392
393 mtx = this._saved_to_current();
394 _transform_bbox(this, mtx);
395 },
396 };
397
398 var _center_proto = {
399 _get_ac_saved_rev: function() {
400 var c = this.owner;
401 var mtx;
402
403 if(c.type != "coord")
404 c = c.parent; // is a shape!
405
406 mtx = c._mbapp_saved_rev_mtx;
407 while(c.parent && typeof c.parent != "undefined") {
408 c = c.parent;
409 mtx = _mul(mtx, c._mbapp_saved_rev_mtx);
410 }
411
412 return mtx;
413 },
414
415 _get_ac_mtx: function() {
416 var c = this.owner;
417 var mtx;
418
419 if(c.type != "coord")
420 c = c.parent; // is a shape!
421
422 mtx = [c[0], c[1], c[2], c[3], c[4], c[5]];
423 while(c.parent) {
424 c = c.parent;
425 mtx = _mul(c, mtx);
426 }
427
428 return mtx;
429 },
430
431 _get_ac_rev: function() {
432 var c = this.owner;
433 var mtx;
434
435 if(c.type != "coord")
436 c = c.parent; // is a shape!
437
438 mtx = _reverse([c[0], c[1], c[2], c[3], c[4], c[5]]);
439 while(c.parent) {
440 c = c.parent;
441 mtx = _mul(mtx, _reverse([c[0], c[1], c[2], c[3], c[4], c[5]]));
442 }
443
444 return mtx;
445 },
446
447 _saved_to_current: function() {
448 var r;
449
450 r = _mul(this._get_ac_mtx(), this._get_ac_saved_rev());
451
452 return r;
453 },
454
455 /*! \brief Update x, y of center point of an object.
456 */
457 update: function() {
458 var mtx;
459 var xy;
460
461 mtx = this._saved_to_current();
462 xy = _pnt_transform(this._svg_saved_x, this._svg_saved_y, mtx);
463
464 this._x = xy[0];
465 this._y = xy[1];
466 },
467
468 /*! \brief Move owner object to make center at (x, y).
469 */
470 move: function(x, y) {
471 var mtx;
472 var xdiff = x - this._x;
473 var ydiff = y - this._y;
474 var shiftxy;
475 var c;
476
477 mtx = this._get_ac_rev();
478 shiftxy = _shift_transform(xdiff, ydiff, mtx);
479
480 c = this.owner;
481 if(c.type != "coord")
482 c = c.parent;
483
484 c[2] += shiftxy[0];
485 c[5] += shiftxy[1];
486
487 this._x = x;
488 this._y = y;
489 },
490
491 /*! \brief Move owner object to make center at position specified by pnt.
492 */
493 move_pnt: function(pnt) {
494 this.move(pnt.x, pnt.y);
495 },
496
497 /*! \brief Prevent user to modify value.
498 */
499 get x() { return this._x; },
500
501 /*! \brief Prevent user to modify value.
502 */
503 get y() { return this._y; },
504 };
249 505
250 loadSVG.prototype._set_bbox = function(node, tgt) { 506 loadSVG.prototype._set_bbox = function(node, tgt) {
251 var a; 507 var a;
252 var vstr; 508 var vstr;
253 var bbox, center; 509 var bbox, center;
256 sys.puts("a="+a); 512 sys.puts("a="+a);
257 if(!a) 513 if(!a)
258 return 0; 514 return 0;
259 515
260 tgt.bbox = bbox = new Object(); 516 tgt.bbox = bbox = new Object();
517 bbox.owner = tgt;
518 bbox.__proto__ = _bbox_proto;
261 vstr = a.value(); 519 vstr = a.value();
262 bbox.x = parseFloat(vstr); 520 bbox._svg_saved_x = parseFloat(vstr);
263 521
264 a = node.attr("bbox-y"); 522 a = node.attr("bbox-y");
265 vstr = a.value(); 523 vstr = a.value();
266 bbox.y = this.height - parseFloat(vstr); 524 bbox._svg_saved_y = this.height - parseFloat(vstr);
267 525
268 a = node.attr("bbox-width"); 526 a = node.attr("bbox-width");
269 vstr = a.value(); 527 vstr = a.value();
270 bbox.width = parseFloat(vstr); 528 bbox._svg_saved_width = parseFloat(vstr);
271 529
272 a = node.attr("bbox-height"); 530 a = node.attr("bbox-height");
273 vstr = a.value(); 531 vstr = a.value();
274 bbox.height = parseFloat(vstr); 532 bbox._svg_saved_height = parseFloat(vstr);
275 bbox.y -= bbox.height; 533 bbox._svg_saved_y -= bbox._svg_saved_height;
534
535 bbox.update();
276 536
277 tgt.center = center = new Object(); 537 tgt.center = center = new Object();
278 538
279 center.x = bbox.width / 2 + bbox.x; 539 center._svg_saved_x = bbox._svg_saved_width / 2 + bbox._svg_saved_x;
280 center.y = bbox.height / 2 + bbox.y; 540 center._svg_saved_y = bbox._svg_saved_height / 2 + bbox._svg_saved_y;
281 a = node.attr("transform-center-x"); 541 a = node.attr("transform-center-x");
282 if(!a) 542 if(a) {
283 return 1; 543 vstr = a.value();
284 544 center._svg_saved_x += parseFloat(vstr);
285 vstr = a.value(); 545 a = node.attr("transform-center-y");
286 center.x += parseFloat(vstr); 546 vstr = a.value();
287 a = node.attr("transform-center-y"); 547 center._svg_saved_y -= parseFloat(vstr);
288 vstr = a.value(); 548 }
289 center.y -= parseFloat(vstr); 549 center.__proto__ = _center_proto;
550 center.owner = tgt;
551 center.update();
552
290 return 1; 553 return 1;
291 } 554 }
292 555
293 loadSVG.prototype._set_paint = function(node, tgt) { 556 loadSVG.prototype._set_paint = function(node, tgt) {
294 var style = node.attr('style'); 557 var style = node.attr('style');
352 var d = n.attr('d').value(); 615 var d = n.attr('d').value();
353 var style = n.attr('style'); 616 var style = n.attr('style');
354 var path = this.mb_rt.path_new(d); 617 var path = this.mb_rt.path_new(d);
355 618
356 guessPathBoundingBox(coord,d); 619 guessPathBoundingBox(coord,d);
620 coord.add_shape(path);
621 this._set_paint(n, path);
357 this._set_bbox(n, path); 622 this._set_bbox(n, path);
358 this._set_paint(n, path);
359 coord.add_shape(path);
360 623
361 make_mbnames(this.mb_rt, n, path); 624 make_mbnames(this.mb_rt, n, path);
362 }; 625 };
363 626
364 loadSVG.prototype.parseText=function(accu,coord,id, n) 627 loadSVG.prototype.parseText=function(accu,coord,id, n)
389 this.parseTSpan(tcoord,nodes[k],style); 652 this.parseTSpan(tcoord,nodes[k],style);
390 } else { 653 } else {
391 } 654 }
392 } 655 }
393 sys.puts(y); 656 sys.puts(y);
394 if (this._set_bbox(n, tcoord)) { 657 this._set_bbox(n, tcoord);
395 tcoord.center.x -= tcoord[2];
396 tcoord.center.y -= tcoord[5];
397 tcoord._x = tcoord.center.x;
398 tcoord._y = tcoord.center.y;
399 } else {
400 tcoord._x = coord.center.x;
401 tcoord._y = coord.center.y;
402 }
403 658
404 make_mbnames(this.mb_rt, n, tcoord); 659 make_mbnames(this.mb_rt, n, tcoord);
405 }; 660 };
406 661
407 662
474 729
475 if (trans) 730 if (trans)
476 parseTransform(tcoord,trans.value()); 731 parseTransform(tcoord,trans.value());
477 732
478 var rect = this.mb_rt.rect_new(x,y,w,h,10, 10); 733 var rect = this.mb_rt.rect_new(x,y,w,h,10, 10);
734 tcoord.add_shape(rect);
479 this._set_paint(n, rect); 735 this._set_paint(n, rect);
480 if (this._set_bbox(n, tcoord)) { 736 this._set_bbox(n, tcoord);
481 tcoord.center.x -= tcoord[2];
482 tcoord.center.y -= tcoord[5];
483 } else {
484 if (trans) {
485 rx = tcoord[0]*x+tcoord[1]*y+tcoord[2];
486 ry = tcoord[3]*x+tcoord[4]*y+tcoord[5];
487 if (tcoord.center.x > rx)
488 tcoord.center.x = rx;
489 if (tcoord.center.y > ry)
490 tcoord.center.y = ry;
491 }
492 }
493 sys.puts("center.x="+tcoord.center.x);
494 sys.puts("center.y="+tcoord.center.y);
495 tcoord._x = tcoord.center.x;
496 tcoord._y = tcoord.center.y;
497 tcoord.add_shape(rect);
498 737
499 make_mbnames(this.mb_rt, n, tcoord); 738 make_mbnames(this.mb_rt, n, tcoord);
500 }; 739 };
501 740
502 // When we parse a group, we need to calculate the origin of the group 741 // When we parse a group, we need to calculate the origin of the group
579 if (root.center.x > coord.center.x) 818 if (root.center.x > coord.center.x)
580 root.center.x = coord.center.x; 819 root.center.x = coord.center.x;
581 if (root.center.y > coord.center.y) 820 if (root.center.y > coord.center.y)
582 root.center.y = coord.center.y; 821 root.center.y = coord.center.y;
583 822
584 if (this._set_bbox(n, coord)) { 823 this._set_bbox(n, coord);
585 coord.center.x -= accu[2];
586 coord.center.y -= accu[5];
587 }
588 coord._x = coord.center.x;
589 coord._y = coord.center.y;
590 sys.puts("coord.center.x="+coord.center.x+",coord.center.y="+coord.center.y);
591 824
592 make_mbnames(this.mb_rt, n, coord); 825 make_mbnames(this.mb_rt, n, coord);
593 }; 826 };
594 827
595 loadSVG.prototype.parseImage=function(accu,coord,id, n) 828 loadSVG.prototype.parseImage=function(accu,coord,id, n)
637 var img_data = ldr.load(ref); 870 var img_data = ldr.load(ref);
638 var paint = this.mb_rt.paint_image_new(img_data); 871 var paint = this.mb_rt.paint_image_new(img_data);
639 paint.fill(img); 872 paint.fill(img);
640 tcoord.add_shape(img); 873 tcoord.add_shape(img);
641 874
642 if (this._set_bbox(n, img)) { 875 this._set_bbox(n, img);
643 img.center.x -= accu[2]+coord[2]; 876
644 img.center.y -= accu[5]+coord[5];
645 }
646
647 make_mbnames(this.mb_rt, n, img); 877 make_mbnames(this.mb_rt, n, img);
648 }; 878 };
649 879
650 loadSVG.prototype._MB_parseLinearGradient=function(root,n) 880 loadSVG.prototype._MB_parseLinearGradient=function(root,n)
651 { 881 {