source: Dev/branches/rest-dojo-ui/client/dojox/gfx/_base.js @ 260

Last change on this file since 260 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 19.9 KB
Line 
1define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sniff", "dojo/_base/window",
2            "dojo/_base/array","dojo/dom", "dojo/dom-construct","dojo/dom-geometry"],
3  function(lang, html, Color, has, win, arr, dom, domConstruct, domGeom){
4        // module:
5        //              dojox/gfx
6        // summary:
7        //              This module contains common core Graphics API used by different graphics renderers.
8        var g = lang.getObject("dojox.gfx", true),
9                b = g._base = {};
10        /*===== g = dojox.gfx; b = dojox.gfx._base; =====*/
11       
12        // candidates for dojox.style (work on VML and SVG nodes)
13        g._hasClass = function(/*DomNode*/node, /*String*/classStr){
14                //      summary:
15                //              Returns whether or not the specified classes are a portion of the
16                //              class list currently applied to the node.
17                // return (new RegExp('(^|\\s+)'+classStr+'(\\s+|$)')).test(node.className)     // Boolean
18                var cls = node.getAttribute("className");
19                return cls && (" " + cls + " ").indexOf(" " + classStr + " ") >= 0;  // Boolean
20        };
21        g._addClass = function(/*DomNode*/node, /*String*/classStr){
22                //      summary:
23                //              Adds the specified classes to the end of the class list on the
24                //              passed node.
25                var cls = node.getAttribute("className") || "";
26                if(!cls || (" " + cls + " ").indexOf(" " + classStr + " ") < 0){
27                        node.setAttribute("className", cls + (cls ? " " : "") + classStr);
28                }
29        };
30        g._removeClass = function(/*DomNode*/node, /*String*/classStr){
31                //      summary: Removes classes from node.
32                var cls = node.getAttribute("className");
33                if(cls){
34                        node.setAttribute(
35                                "className",
36                                cls.replace(new RegExp('(^|\\s+)' + classStr + '(\\s+|$)'), "$1$2")
37                        );
38                }
39        };
40
41        // candidate for dojox.html.metrics (dynamic font resize handler is not implemented here)
42
43        //      derived from Morris John's emResized measurer
44        b._getFontMeasurements = function(){
45                //      summary:
46                //              Returns an object that has pixel equivilents of standard font
47                //              size values.
48                var heights = {
49                        '1em': 0, '1ex': 0, '100%': 0, '12pt': 0, '16px': 0, 'xx-small': 0,
50                        'x-small': 0, 'small': 0, 'medium': 0, 'large': 0, 'x-large': 0,
51                        'xx-large': 0
52                };
53                var p;
54
55                if(has("ie")){
56                        //      we do a font-size fix if and only if one isn't applied already.
57                        //      NOTE: If someone set the fontSize on the HTML Element, this will kill it.
58                        win.doc.documentElement.style.fontSize="100%";
59                }
60
61                //      set up the measuring node.
62                var div = domConstruct.create("div", {style: {
63                                position: "absolute",
64                                left: "0",
65                                top: "-100px",
66                                width: "30px",
67                                height: "1000em",
68                                borderWidth: "0",
69                                margin: "0",
70                                padding: "0",
71                                outline: "none",
72                                lineHeight: "1",
73                                overflow: "hidden"
74                        }}, win.body());
75
76                //      do the measurements.
77                for(p in heights){
78                        div.style.fontSize = p;
79                        heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000;
80                }
81
82                win.body().removeChild(div);
83                return heights; //object
84        };
85
86        var fontMeasurements = null;
87
88        b._getCachedFontMeasurements = function(recalculate){
89                if(recalculate || !fontMeasurements){
90                        fontMeasurements = b._getFontMeasurements();
91                }
92                return fontMeasurements;
93        };
94
95        // candidate for dojox.html.metrics
96
97        var measuringNode = null, empty = {};
98        b._getTextBox = function(       /*String*/ text,
99                                                                /*Object*/ style,
100                                                                /*String?*/ className){
101                var m, s, al = arguments.length;
102                var i;
103                if(!measuringNode){
104                        measuringNode = domConstruct.create("div", {style: {
105                                position: "absolute",
106                                top: "-10000px",
107                                left: "0"
108                        }}, win.body());
109                }
110                m = measuringNode;
111                // reset styles
112                m.className = "";
113                s = m.style;
114                s.borderWidth = "0";
115                s.margin = "0";
116                s.padding = "0";
117                s.outline = "0";
118                // set new style
119                if(al > 1 && style){
120                        for(i in style){
121                                if(i in empty){ continue; }
122                                s[i] = style[i];
123                        }
124                }
125                // set classes
126                if(al > 2 && className){
127                        m.className = className;
128                }
129                // take a measure
130                m.innerHTML = text;
131
132                if(m["getBoundingClientRect"]){
133                        var bcr = m.getBoundingClientRect();
134                        return {l: bcr.left, t: bcr.top, w: bcr.width || (bcr.right - bcr.left), h: bcr.height || (bcr.bottom - bcr.top)};
135                }else{
136                        return domGeom.getMarginBox(m);
137                }
138        };
139
140        // candidate for dojo.dom
141
142        var uniqueId = 0;
143        b._getUniqueId = function(){
144                // summary: returns a unique string for use with any DOM element
145                var id;
146                do{
147                        id = dojo._scopeName + "xUnique" + (++uniqueId);
148                }while(dom.byId(id));
149                return id;
150        };
151
152        lang.mixin(g, {
153                //      summary:
154                //              defines constants, prototypes, and utility functions for the core Graphics API
155
156                // default shapes, which are used to fill in missing parameters
157                defaultPath: {
158                        //      summary:
159                        //              Defines the default Path prototype object.
160                        type: "path",
161                        //      type: String
162                        //              Specifies this object is a Path, default value 'path'.
163                        path: ""
164                        //      path: String
165                        //              The path commands. See W32C SVG 1.0 specification.
166                        //              Defaults to empty string value.
167                },
168                defaultPolyline: {
169                        //      summary:
170                        //              Defines the default PolyLine prototype.
171                        type: "polyline",
172                        //      type: String
173                        //              Specifies this object is a PolyLine, default value 'polyline'.
174                        points: []
175                        //      points: Array
176                        //              An array of point objects [{x:0,y:0},...] defining the default polyline's line segments. Value is an empty array [].
177                },
178                defaultRect: {
179                        //      summary:
180                        //              Defines the default Rect prototype.
181                        type: "rect",
182                        //      type: String
183                        //              Specifies this default object is a type of Rect. Value is 'rect'
184                        x: 0,
185                        //      x: Number
186                        //              The X coordinate of the default rectangles position, value 0.
187                        y: 0,
188                        //      y: Number
189                        //              The Y coordinate of the default rectangle's position, value 0.
190                        width: 100,
191                        //      width: Number
192                        //              The width of the default rectangle, value 100.
193                        height: 100,
194                        //      height: Number
195                        //              The height of the default rectangle, value 100.
196                        r: 0
197                        //      r: Number
198                        //              The corner radius for the default rectangle, value 0.
199                },
200                defaultEllipse: {
201                        //      summary:
202                        //              Defines the default Ellipse prototype.
203                        type: "ellipse",
204                        //      type: String
205                        //              Specifies that this object is a type of Ellipse, value is 'ellipse'
206                        cx: 0,
207                        //      cx: Number
208                        //              The X coordinate of the center of the ellipse, default value 0.
209                        cy: 0,
210                        //      cy: Number
211                        //              The Y coordinate of the center of the ellipse, default value 0.
212                        rx: 200,
213                        //      rx: Number
214                        //              The radius of the ellipse in the X direction, default value 200.
215                        ry: 100
216                        //      ry: Number
217                        //              The radius of the ellipse in the Y direction, default value 200.
218                },
219                defaultCircle: {
220                        //      summary:
221                        //              An object defining the default Circle prototype.
222                        type: "circle",
223                        //      type: String
224                        //              Specifies this object is a circle, value 'circle'
225                        cx: 0,
226                        //      cx: Number
227                        //              The X coordinate of the center of the circle, default value 0.
228                        cy: 0,
229                        //      cy: Number
230                        //              The Y coordinate of the center of the circle, default value 0.
231                        r: 100
232                        //      r: Number
233                        //              The radius, default value 100.
234                },
235                defaultLine: {
236                        //      summary:
237                        //              An pbject defining the default Line prototype.
238                        type: "line",
239                        //      type: String
240                        //              Specifies this is a Line, value 'line'
241                        x1: 0,
242                        //      x1: Number
243                        //              The X coordinate of the start of the line, default value 0.
244                        y1: 0,
245                        //      y1: Number
246                        //              The Y coordinate of the start of the line, default value 0.
247                        x2: 100,
248                        //      x2: Number
249                        //              The X coordinate of the end of the line, default value 100.
250                        y2: 100
251                        //      y2: Number
252                        //              The Y coordinate of the end of the line, default value 100.
253                },
254                defaultImage: {
255                        //      summary:
256                        //              Defines the default Image prototype.
257                        type: "image",
258                        //      type: String
259                        //              Specifies this object is an image, value 'image'.
260                        x: 0,
261                        //      x: Number
262                        //              The X coordinate of the image's position, default value 0.
263                        y: 0,
264                        //      y: Number
265                        //              The Y coordinate of the image's position, default value 0.
266                        width: 0,
267                        //      width: Number
268                        //              The width of the image, default value 0.
269                        height: 0,
270                        //      height:Number
271                        //              The height of the image, default value 0.
272                        src: ""
273                        //      src: String
274                        //              The src url of the image, defaults to empty string.
275                },
276                defaultText: {
277                        //      summary:
278                        //              Defines the default Text prototype.
279                        type: "text",
280                        //      type: String
281                        //              Specifies this is a Text shape, value 'text'.
282                        x: 0,
283                        //      x: Number
284                        //              The X coordinate of the text position, default value 0.
285                        y: 0,
286                        //      y: Number
287                        //              The Y coordinate of the text position, default value 0.
288                        text: "",
289                        //      text: String
290                        //              The text to be displayed, default value empty string.
291                        align: "start",
292                        //      align:  String
293                        //              The horizontal text alignment, one of 'start', 'end', 'center'. Default value 'start'.
294                        decoration: "none",
295                        //      decoration: String
296                        //              The text decoration , one of 'none', ... . Default value 'none'.
297                        rotated: false,
298                        //      rotated: Boolean
299                        //              Whether the text is rotated, boolean default value false.
300                        kerning: true
301                        //      kerning: Boolean
302                        //              Whether kerning is used on the text, boolean default value true.
303                },
304                defaultTextPath: {
305                        //      summary:
306                        //              Defines the default TextPath prototype.
307                        type: "textpath",
308                        //      type: String
309                        //              Specifies this is a TextPath, value 'textpath'.
310                        text: "",
311                        //      text: String
312                        //              The text to be displayed, default value empty string.
313                        align: "start",
314                        //      align: String
315                        //              The horizontal text alignment, one of 'start', 'end', 'center'. Default value 'start'.
316                        decoration: "none",
317                        //      decoration: String
318                        //              The text decoration , one of 'none', ... . Default value 'none'.
319                        rotated: false,
320                        //      rotated: Boolean
321                        //              Whether the text is rotated, boolean default value false.
322                        kerning: true
323                        //      kerning: Boolean
324                        //              Whether kerning is used on the text, boolean default value true.
325                },
326
327                // default stylistic attributes
328                defaultStroke: {
329                        //      summary:
330                        //              A stroke defines stylistic properties that are used when drawing a path. 
331                        //              This object defines the default Stroke prototype.
332                        type: "stroke",
333                        //      type: String
334                        //              Specifies this object is a type of Stroke, value 'stroke'.
335                        color: "black",
336                        //      color: String
337                        //              The color of the stroke, default value 'black'.
338                        style: "solid",
339                        //      style: String
340                        //              The style of the stroke, one of 'solid', ... . Default value 'solid'.
341                        width: 1,
342                        //      width: Number
343                        //              The width of a stroke, default value 1.
344                        cap: "butt",
345                        //      cap: String
346                        //              The endcap style of the path. One of 'butt', 'round', ... . Default value 'butt'.
347                        join: 4
348                        //      join: Number
349                        //              The join style to use when combining path segments. Default value 4.
350                },
351                defaultLinearGradient: {
352                        //      summary:
353                        //              An object defining the default stylistic properties used for Linear Gradient fills.
354                        //              Linear gradients are drawn along a virtual line, which results in appearance of a rotated pattern in a given direction/orientation.
355                        type: "linear",
356                        //      type: String
357                        //              Specifies this object is a Linear Gradient, value 'linear'
358                        x1: 0,
359                        //      x1: Number
360                        //              The X coordinate of the start of the virtual line along which the gradient is drawn, default value 0.
361                        y1: 0,
362                        //      y1: Number
363                        //              The Y coordinate of the start of the virtual line along which the gradient is drawn, default value 0.
364                        x2: 100,
365                        //      x2: Number
366                        //              The X coordinate of the end of the virtual line along which the gradient is drawn, default value 100.
367                        y2: 100,
368                        //      y2: Number
369                        //              The Y coordinate of the end of the virtual line along which the gradient is drawn, default value 100.
370                        colors: [
371                                { offset: 0, color: "black" }, { offset: 1, color: "white" }
372                        ]
373                        //      colors: Array
374                        //              An array of colors at given offsets (from the start of the line).  The start of the line is
375                        //              defined at offest 0 with the end of the line at offset 1.
376                        //              Default value, [{ offset: 0, color: 'black'},{offset: 1, color: 'white'}], is a gradient from black to white.
377                },
378                defaultRadialGradient: {
379                        // summary:
380                        //              An object specifying the default properties for RadialGradients using in fills patterns.
381                        type: "radial",
382                        //      type: String
383                        //              Specifies this is a RadialGradient, value 'radial'
384                        cx: 0,
385                        //      cx: Number
386                        //              The X coordinate of the center of the radial gradient, default value 0.
387                        cy: 0,
388                        //      cy: Number
389                        //              The Y coordinate of the center of the radial gradient, default value 0.
390                        r: 100,
391                        //      r: Number
392                        //              The radius to the end of the radial gradient, default value 100.
393                        colors: [
394                                { offset: 0, color: "black" }, { offset: 1, color: "white" }
395                        ]
396                        //      colors: Array
397                        //              An array of colors at given offsets (from the center of the radial gradient). 
398                        //              The center is defined at offest 0 with the outer edge of the gradient at offset 1.
399                        //              Default value, [{ offset: 0, color: 'black'},{offset: 1, color: 'white'}], is a gradient from black to white.
400                },
401                defaultPattern: {
402                        // summary:
403                        //              An object specifying the default properties for a Pattern using in fill operations.
404                        type: "pattern",
405                        // type: String
406                        //              Specifies this object is a Pattern, value 'pattern'.
407                        x: 0,
408                        //      x: Number
409                        //              The X coordinate of the position of the pattern, default value is 0.
410                        y: 0,
411                        //      y: Number
412                        //              The Y coordinate of the position of the pattern, default value is 0.
413                        width: 0,
414                        //      width: Number
415                        //              The width of the pattern image, default value is 0.
416                        height: 0,
417                        //      height: Number
418                        //              The height of the pattern image, default value is 0.
419                        src: ""
420                        //      src: String
421                        //              A url specifing the image to use for the pattern.
422                },
423                defaultFont: {
424                        // summary:
425                        //              An object specifying the default properties for a Font used in text operations.
426                        type: "font",
427                        // type: String
428                        //              Specifies this object is a Font, value 'font'.
429                        style: "normal",
430                        //      style: String
431                        //              The font style, one of 'normal', 'bold', default value 'normal'.
432                        variant: "normal",
433                        //      variant: String
434                        //              The font variant, one of 'normal', ... , default value 'normal'.
435                        weight: "normal",
436                        //      weight: String
437                        //              The font weight, one of 'normal', ..., default value 'normal'.
438                        size: "10pt",
439                        //      size: String
440                        //              The font size (including units), default value '10pt'.
441                        family: "serif"
442                        //      family: String
443                        //              The font family, one of 'serif', 'sanserif', ..., default value 'serif'.
444                },
445
446                getDefault: (function(){
447                        //      summary:
448                        //              Returns a function used to access default memoized prototype objects (see them defined above).
449                        var typeCtorCache = {};
450                        // a memoized delegate()
451                        return function(/*String*/ type){
452                                var t = typeCtorCache[type];
453                                if(t){
454                                        return new t();
455                                }
456                                t = typeCtorCache[type] = new Function();
457                                t.prototype = g[ "default" + type ];
458                                return new t();
459                        }
460                })(),
461
462                normalizeColor: function(/*dojo.Color|Array|string|Object*/ color){
463                        //      summary:
464                        //              converts any legal color representation to normalized
465                        //              dojo.Color object
466                        return (color instanceof Color) ? color : new Color(color); // dojo.Color
467                },
468                normalizeParameters: function(existed, update){
469                        //      summary:
470                        //              updates an existing object with properties from an 'update'
471                        //              object
472                        //      existed: Object
473                        //              the target object to be updated
474                        //      update:  Object
475                        //              the 'update' object, whose properties will be used to update
476                        //              the existed object
477                        var x;
478                        if(update){
479                                var empty = {};
480                                for(x in existed){
481                                        if(x in update && !(x in empty)){
482                                                existed[x] = update[x];
483                                        }
484                                }
485                        }
486                        return existed; // Object
487                },
488                makeParameters: function(defaults, update){
489                        //      summary:
490                        //              copies the original object, and all copied properties from the
491                        //              'update' object
492                        //      defaults: Object
493                        //              the object to be cloned before updating
494                        //      update:   Object
495                        //              the object, which properties are to be cloned during updating
496                        var i = null;
497                        if(!update){
498                                // return dojo.clone(defaults);
499                                return lang.delegate(defaults);
500                        }
501                        var result = {};
502                        for(i in defaults){
503                                if(!(i in result)){
504                                        result[i] = lang.clone((i in update) ? update[i] : defaults[i]);
505                                }
506                        }
507                        return result; // Object
508                },
509                formatNumber: function(x, addSpace){
510                        // summary: converts a number to a string using a fixed notation
511                        // x: Number
512                        //              number to be converted
513                        // addSpace: Boolean
514                        //              whether to add a space before a positive number
515                        var val = x.toString();
516                        if(val.indexOf("e") >= 0){
517                                val = x.toFixed(4);
518                        }else{
519                                var point = val.indexOf(".");
520                                if(point >= 0 && val.length - point > 5){
521                                        val = x.toFixed(4);
522                                }
523                        }
524                        if(x < 0){
525                                return val; // String
526                        }
527                        return addSpace ? " " + val : val; // String
528                },
529                // font operations
530                makeFontString: function(font){
531                        // summary: converts a font object to a CSS font string
532                        // font:        Object: font object (see dojox.gfx.defaultFont)
533                        return font.style + " " + font.variant + " " + font.weight + " " + font.size + " " + font.family; // Object
534                },
535                splitFontString: function(str){
536                        // summary:
537                        //              converts a CSS font string to a font object
538                        // description:
539                        //              Converts a CSS font string to a gfx font object. The CSS font
540                        //              string components should follow the W3C specified order
541                        //              (see http://www.w3.org/TR/CSS2/fonts.html#font-shorthand):
542                        //              style, variant, weight, size, optional line height (will be
543                        //              ignored), and family.
544                        // str: String
545                        //              a CSS font string
546                        var font = g.getDefault("Font");
547                        var t = str.split(/\s+/);
548                        do{
549                                if(t.length < 5){ break; }
550                                font.style   = t[0];
551                                font.variant = t[1];
552                                font.weight  = t[2];
553                                var i = t[3].indexOf("/");
554                                font.size = i < 0 ? t[3] : t[3].substring(0, i);
555                                var j = 4;
556                                if(i < 0){
557                                        if(t[4] == "/"){
558                                                j = 6;
559                                        }else if(t[4].charAt(0) == "/"){
560                                                j = 5;
561                                        }
562                                }
563                                if(j < t.length){
564                                        font.family = t.slice(j).join(" ");
565                                }
566                        }while(false);
567                        return font;    // Object
568                },
569                // length operations
570                cm_in_pt: 72 / 2.54,
571                        //      cm_in_pt: Number
572                        //              points per centimeter (constant)
573                mm_in_pt: 7.2 / 2.54,
574                        //      mm_in_pt: Number
575                        //              points per millimeter (constant)
576                px_in_pt: function(){
577                        //      summary: returns the current number of pixels per point.
578                        return g._base._getCachedFontMeasurements()["12pt"] / 12;       // Number
579                },
580                pt2px: function(len){
581                        //      summary: converts points to pixels
582                        //      len: Number
583                        //              a value in points
584                        return len * g.px_in_pt();      // Number
585                },
586                px2pt: function(len){
587                        //      summary: converts pixels to points
588                        //      len: Number
589                        //              a value in pixels
590                        return len / g.px_in_pt();      // Number
591                },
592                normalizedLength: function(len) {
593                        //      summary: converts any length value to pixels
594                        //      len: String
595                        //              a length, e.g., '12pc'
596                        if(len.length === 0){ return 0; }
597                        if(len.length > 2){
598                                var px_in_pt = g.px_in_pt();
599                                var val = parseFloat(len);
600                                switch(len.slice(-2)){
601                                        case "px": return val;
602                                        case "pt": return val * px_in_pt;
603                                        case "in": return val * 72 * px_in_pt;
604                                        case "pc": return val * 12 * px_in_pt;
605                                        case "mm": return val * g.mm_in_pt * px_in_pt;
606                                        case "cm": return val * g.cm_in_pt * px_in_pt;
607                                }
608                        }
609                        return parseFloat(len); // Number
610                },
611
612                pathVmlRegExp: /([A-Za-z]+)|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
613                        //      pathVmlRegExp: RegExp
614                        //              a constant regular expression used to split a SVG/VML path into primitive components
615                pathSvgRegExp: /([A-Za-z])|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
616                        //      pathVmlRegExp: RegExp
617                        //              a constant regular expression used to split a SVG/VML path into primitive components
618
619                equalSources: function(a /*Object*/, b /*Object*/){
620                        //      summary: compares event sources, returns true if they are equal
621                        //      a: first event source
622                        //      b: event source to compare against a
623                        return a && b && a === b;
624                },
625
626                switchTo: function(renderer/*String|Object*/){
627                        //      summary: switch the graphics implementation to the specified renderer.
628                        //      renderer:
629                        //              Either the string name of a renderer (eg. 'canvas', 'svg, ...) or the renderer
630                        //              object to switch to.
631                        var ns = typeof renderer == "string" ? g[renderer] : renderer;
632                        if(ns){
633                                arr.forEach(["Group", "Rect", "Ellipse", "Circle", "Line",
634                                                "Polyline", "Image", "Text", "Path", "TextPath",
635                                                "Surface", "createSurface", "fixTarget"], function(name){
636                                        g[name] = ns[name];
637                                });
638                        }
639                }
640        });
641        return g; // defaults object api
642});
Note: See TracBrowser for help on using the repository browser.