Changeset 7033
- Timestamp:
- 01/16/07 13:00:00 (2 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 5 modified
-
src/gfx/common.js (modified) (3 diffs)
-
src/gfx/matrix.js (modified) (1 diff)
-
src/gfx/shape.js (modified) (8 diffs)
-
src/gfx/svg.js (modified) (6 diffs)
-
src/gfx/vml.js (modified) (9 diffs)
-
tests/gfx/test_text.html (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gfx/common.js
r6900 r7033 17 17 defaultLine: {type: "line", x1: 0, y1: 0, x2: 100, y2: 100}, 18 18 defaultImage: {type: "image", x: 0, y: 0, width: 0, height: 0, src: ""}, 19 defaultText: {type: "text", x: 0, y: 0, text: "", 20 align: "left", decoration: "none", rotated: false, kerning: true, spacing: "normal" }, 21 defaultTextPath: {type: "textpath", text: ""}, 19 22 20 // default geometric attributes (a stroke, and fills)23 // default geometric attributes 21 24 defaultStroke: {color: "black", width: 1, cap: "butt", join: 4}, 22 25 defaultLinearGradient: {type: "linear", x1: 0, y1: 0, x2: 100, y2: 100, … … 25 28 colors: [{offset: 0, color: "black"}, {offset: 1, color: "white"}]}, 26 29 defaultPattern: {type: "pattern", x: 0, y: 0, width: 0, height: 0, src: ""}, 30 defaultFont: {type: "font", style: "normal", variant: "normal", weight: "normal", 31 size: "10pt", family: "serif"}, 27 32 28 33 normalizeColor: function(/*Color*/ color){ … … 75 80 return addSpace ? " " + val : val; // String 76 81 }, 82 // font operations 83 makeFontString: function(font){ 84 // summary: converts a font object to a CSS font string 85 // font: Object: font object (see dojo.gfx.defaultFont) 86 return font.style + " " + font.variant + " " + font.weight + " " + font.size + " " + font.family; // Object 87 }, 88 splitFontString: function(str){ 89 // summary: converts a CSS font string to a font object 90 // str: String: a CSS font string 91 var font = dojo.lang.shallowCopy(dojo.gfx.defaultFont); 92 var t = str.split(/\s+/); 93 do{ 94 if(t.length < 5){ break; } 95 font.style = t[0]; 96 font.varian = t[1]; 97 font.weight = t[2]; 98 var i = t[3].indexOf("/"); 99 font.size = i < 0 ? t[3] : t[3].substring(0, i); 100 var j = 4; 101 if(i < 0){ 102 if(t[4] == "/"){ 103 j = 6; 104 break; 105 } 106 if(t[4].substr(0, 1) == "/"){ 107 j = 5; 108 break; 109 } 110 } 111 if(j + 3 > t.length){ break; } 112 font.size = t[j]; 113 font.family = t[j + 1]; 114 }while(false); 115 return font; // Object 116 }, 77 117 78 118 // a constant used to split a SVG/VML path into primitive components -
trunk/src/gfx/matrix.js
r6437 r7033 395 395 396 396 }); 397 398 // propagate Matrix2D up 399 dojo.gfx.Matrix2D = dojo.gfx.matrix.Matrix2D; -
trunk/src/gfx/shape.js
r6840 r7033 218 218 // summary: returns the cumulative ("real") transformation matrix 219 219 // by combining the shape's matrix with its parent's matrix 220 return this.parentMatrix ? new dojo.gfx.matrix.Matrix2D([this.parentMatrix, this.matrix]) : this.matrix; // dojo.gfx. matrix.Matrix220 return this.parentMatrix ? new dojo.gfx.matrix.Matrix2D([this.parentMatrix, this.matrix]) : this.matrix; // dojo.gfx.Matrix2D 221 221 } 222 222 }); 223 223 224 224 dojo.declare("dojo.gfx.shape.VirtualGroup", dojo.gfx.Shape, 225 226 225 function() { 227 226 // summary: a virtual group of shapes, which can be used … … 276 275 277 276 dojo.declare("dojo.gfx.shape.Rect", dojo.gfx.Shape, 278 279 277 function(rawNode) { 280 278 // summary: a generic rectangle … … 291 289 292 290 dojo.declare("dojo.gfx.shape.Ellipse", dojo.gfx.Shape, 293 function(rawNode) {294 // summary: a generic ellipse295 // rawNode: Node: a DOM Node296 this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultEllipse, true);297 this.attach(rawNode);298 },291 function(rawNode) { 292 // summary: a generic ellipse 293 // rawNode: Node: a DOM Node 294 this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultEllipse, true); 295 this.attach(rawNode); 296 }, 299 297 { 300 298 getBoundingBox: function(){ … … 310 308 311 309 dojo.declare("dojo.gfx.shape.Circle", dojo.gfx.Shape, 312 function(rawNode) {313 // summary: a generic circle314 // (this is a helper object, which is defined for convenience)315 // rawNode: Node: a DOM Node316 this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultCircle, true);317 this.attach(rawNode);318 },310 function(rawNode) { 311 // summary: a generic circle 312 // (this is a helper object, which is defined for convenience) 313 // rawNode: Node: a DOM Node 314 this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultCircle, true); 315 this.attach(rawNode); 316 }, 319 317 { 320 318 getBoundingBox: function(){ … … 330 328 331 329 dojo.declare("dojo.gfx.shape.Line", dojo.gfx.Shape, 332 function(rawNode) {333 // summary: a generic line334 // (this is a helper object, which is defined for convenience)335 // rawNode: Node: a DOM Node336 this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultLine, true);337 this.attach(rawNode);338 },330 function(rawNode) { 331 // summary: a generic line 332 // (this is a helper object, which is defined for convenience) 333 // rawNode: Node: a DOM Node 334 this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultLine, true); 335 this.attach(rawNode); 336 }, 339 337 { 340 338 getBoundingBox: function(){ … … 354 352 355 353 dojo.declare("dojo.gfx.shape.Polyline", dojo.gfx.Shape, 356 function(rawNode) {357 // summary: a generic polyline/polygon358 // (this is a helper object, which is defined for convenience)359 // rawNode: Node: a DOM Node360 this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultPolyline, true);361 this.attach(rawNode);362 },354 function(rawNode) { 355 // summary: a generic polyline/polygon 356 // (this is a helper object, which is defined for convenience) 357 // rawNode: Node: a DOM Node 358 this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultPolyline, true); 359 this.attach(rawNode); 360 }, 363 361 { 364 362 getBoundingBox: function(){ … … 388 386 389 387 dojo.declare("dojo.gfx.shape.Image", dojo.gfx.Shape, 390 function(rawNode) {391 // summary: a generic image392 // (this is a helper object, which is defined for convenience)393 // rawNode: Node: a DOM Node394 this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultImage, true);395 this.attach(rawNode);396 },388 function(rawNode) { 389 // summary: a generic image 390 // (this is a helper object, which is defined for convenience) 391 // rawNode: Node: a DOM Node 392 this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultImage, true); 393 this.attach(rawNode); 394 }, 397 395 { 398 396 getBoundingBox: function(){ … … 410 408 } 411 409 }); 410 411 dojo.declare("dojo.gfx.shape.Text", dojo.gfx.Shape, 412 function(rawNode) { 413 // summary: a generic text 414 // rawNode: Node: a DOM Node 415 this.fontStyle = null; 416 this.shape = dojo.lang.shallowCopy(dojo.gfx.defaultText, true); 417 this.attach(rawNode); 418 }, 419 {} 420 ); 421 422 dojo.gfx._font = { 423 getFont: function(){ 424 // summary: returns the current font object or null (see dojo.gfx.defaultFont) 425 return this.fontStyle; // Object 426 } 427 }; 428 429 dojo.lang.extend(dojo.gfx.shape.Text, dojo.gfx._font); 430 delete dojo.gfx._font; -
trunk/src/gfx/svg.js
r7021 r7033 239 239 if(rawNode){ 240 240 var fill = rawNode.getAttribute("fill"); 241 if(fill == "none"){ return ; }241 if(fill == "none"){ return null; } 242 242 var ref = dojo.gfx.svg.getRef(fill); 243 243 if(ref){ … … 291 291 // summary: deduces a stroke style from a Node. 292 292 // rawNode: Node: an SVG node 293 if(!rawNode){ return ; }293 if(!rawNode){ return null; } 294 294 var stroke = rawNode.getAttribute("stroke"); 295 295 if(stroke == null || stroke == "none") return null; … … 493 493 dojo.gfx.Path.nodeType = "path"; 494 494 495 dojo.gfx._creators = { 495 dojo.declare("dojo.gfx.Text", dojo.gfx.shape.Text, { 496 // summary: an anchored text (SVG) 497 498 attachShape: function(rawNode){ 499 // summary: builds a text shape from a Node. 500 // rawNode: Node: an SVG node 501 var shape = null; 502 if(rawNode){ 503 shape = dojo.lang.shallowCopy(dojo.gfx.defaultText, true); 504 shape.x = rawNode.getAttribute("x"); 505 shape.y = rawNode.getAttribute("y"); 506 shape.align = rawNode.getAttribute("text-anchor"); 507 shape.decoration = rawNode.getAttribute("text-decoration"); 508 shape.rotated = parseFloat(rawNode.getAttribute("rotate")) != 0; 509 shape.kerning = rawNode.getAttribute("kerning") == "auto"; 510 shape.text = rawNode.firstChild.nodeValue; 511 } 512 return shape; // dojo.gfx.shape.Text 513 }, 514 setShape: function(newShape){ 515 // summary: sets a text shape object (SVG) 516 // newShape: Object: a text shape object 517 this.shape = dojo.gfx.makeParameters(this.shape, newShape); 518 this.bbox = null; 519 var r = this.rawNode; 520 var s = this.shape; 521 r.setAttribute("x", s.x); 522 r.setAttribute("y", s.y); 523 r.setAttribute("text-anchor", s.align); 524 r.setAttribute("text-decoration", s.decoration); 525 r.setAttribute("rotate", s.rotated ? 90 : 0); 526 r.setAttribute("kerning", s.kerning ? "auto" : 0); 527 r.appendChild(document.createTextNode(s.text)); 528 return this; // self 529 } 530 }); 531 dojo.gfx.Text.nodeType = "text"; 532 533 dojo.gfx.svg._font = { 534 setFont: function(font){ 535 // summary: sets a font object (SVG) 536 // font: Object: a font object (see dojo.gfx.defaultFont) or a string 537 var f = this.fontStyle = typeof font == "string" ? dojo.gfx.splitFontString(font) : 538 dojo.gfx.makeParameters(dojo.gfx.defaultFont, font); 539 // next line doesn't work in Firefox 2 or Opera 9 540 //this.rawNode.setAttribute("font", dojo.gfx.makeFontString(this.fontStyle)); 541 this.rawNode.setAttribute("font-style", f.style); 542 this.rawNode.setAttribute("font-variant", f.variant); 543 this.rawNode.setAttribute("font-weight", f.weight); 544 this.rawNode.setAttribute("font-size", f.size); 545 this.rawNode.setAttribute("font-family", f.family); 546 }, 547 attachFont: function(rawNode){ 548 // summary: deduces a font style from a Node. 549 // rawNode: Node: an SVG node 550 if(!rawNode){ return null; } 551 var fontStyle = dojo.lang.shallowCopy(dojo.gfx.defaultFont, true); 552 fontStyle.style = rawNode.getAttribute("font-style"); 553 fontStyle.variant = rawNode.getAttribute("font-variant"); 554 fontStyle.weight = rawNode.getAttribute("font-weight"); 555 fontStyle.size = rawNode.getAttribute("font-size"); 556 fontStyle.family = rawNode.getAttribute("font-family"); 557 return fontStyle; // Object 558 }, 559 attach: function(rawNode){ 560 // summary: reconstructs all shape parameters from a Node. 561 // rawNode: Node: an SVG node 562 dojo.gfx.Shape.prototype.attach.call(this, rawNode); 563 if(rawNode) { 564 this.fontStyle = this.attachFont(rawNode); 565 } 566 } 567 }; 568 569 dojo.lang.extend(dojo.gfx.Text, dojo.gfx.svg._font); 570 delete dojo.gfx.svg._font; 571 572 dojo.gfx.svg._creators = { 496 573 // summary: SVG shape creators 497 574 createPath: function(path){ … … 530 607 // image: Object: an image object (see dojo.gfx.defaultImage) 531 608 return this.createObject(dojo.gfx.Image, image); // dojo.gfx.Image 609 }, 610 createText: function(text){ 611 // summary: creates an SVG text shape 612 // text: Object: a text object (see dojo.gfx.defaultText) 613 return this.createObject(dojo.gfx.Text, text); // dojo.gfx.Text 532 614 }, 533 615 createGroup: function(){ … … 599 681 s = new dojo.gfx.Image(); 600 682 break; 683 case dojo.gfx.Text.nodeType: 684 s = new dojo.gfx.Text(); 685 break; 601 686 default: 602 687 dojo.debug("FATAL ERROR! tagName = " + node.tagName); … … 658 743 }; 659 744 660 dojo.lang.extend(dojo.gfx.Group, dojo.gfx. _creators);661 dojo.lang.extend(dojo.gfx.Surface, dojo.gfx. _creators);662 663 delete dojo.gfx. _creators;745 dojo.lang.extend(dojo.gfx.Group, dojo.gfx.svg._creators); 746 dojo.lang.extend(dojo.gfx.Surface, dojo.gfx.svg._creators); 747 748 delete dojo.gfx.svg._creators; 664 749 665 750 // Gradient and pattern -
trunk/src/gfx/vml.js
r7020 r7033 47 47 48 48 dojo.gfx.vml.normalizedLength = function(len) { 49 // summary: converts any length value to p oints49 // summary: converts any length value to pixels 50 50 // len: String: a length, e.g., "12pc" 51 51 if(len.length == 0) return 0; … … 331 331 this.rawNode = rawNode; 332 332 this.shape = this.attachShape(rawNode); 333 if("attachFill" in this){ 334 this.fontStyle = this.attachFont(rawNode); 335 } 333 336 this.fillStyle = this.attachFill(rawNode); 334 337 this.strokeStyle = this.attachStroke(rawNode); … … 615 618 dojo.gfx.Polyline.nodeType = "shape"; 616 619 617 dojo.declare("dojo.gfx.Image", dojo.gfx.shape.Image, { 620 dojo.declare("dojo.gfx.Image", dojo.gfx.shape.Image, 621 function(rawNode){ 622 if(rawNode) rawNode.setAttribute("dojoGfxType", "image"); 623 }, { 618 624 // summary: an image (VML) 619 625 … … 688 694 } 689 695 }); 690 dojo.gfx.Image.nodeType = " image";696 dojo.gfx.Image.nodeType = "div"; 691 697 692 698 dojo.gfx.path._calcArc = function(alpha){ … … 1129 1135 dojo.gfx.Path.nodeType = "shape"; 1130 1136 1131 1132 dojo.gfx._creators = { 1137 dojo.declare("dojo.gfx.Text", dojo.gfx.shape.Text, 1138 function(rawNode){ 1139 if(rawNode) rawNode.setAttribute("dojoGfxType", "text"); 1140 this.fontStyle = null; 1141 }, { 1142 // summary: an anchored text (SVG) 1143 1144 attachShape: function(rawNode){ 1145 // summary: builds a text shape from a Node. 1146 // rawNode: Node: an SVG node 1147 var shape = null; 1148 /* 1149 if(rawNode){ 1150 shape = dojo.lang.shallowCopy(dojo.gfx.defaultText, true); 1151 shape.x = rawNode.getAttribute("x"); 1152 shape.y = rawNode.getAttribute("y"); 1153 shape.align = rawNode.getAttribute("text-anchor"); 1154 shape.decoration = rawNode.getAttribute("text-decoration"); 1155 shape.rotated = parseFloat(rawNode.getAttribute("rotate")) != 0; 1156 shape.text = rawNode.firstChild.nodeValue; 1157 } 1158 */ 1159 return shape; // dojo.gfx.shape.Text 1160 }, 1161 _alignment: {start: "left", middle: "center", end: "right"}, 1162 setShape: function(newShape){ 1163 // summary: sets a text shape object (SVG) 1164 // newShape: Object: a text shape object 1165 this.shape = dojo.gfx.makeParameters(this.shape, newShape); 1166 this.bbox = null; 1167 var r = this.rawNode; 1168 var s = this.shape; 1169 var x = s.x; 1170 var y = s.y.toFixed(); 1171 switch(s.align){ 1172 case "middle": 1173 x -= 5; 1174 break; 1175 case "end": 1176 x -= 10; 1177 break; 1178 } 1179 this.rawNode.path.v = "m" + x.toFixed() + "," + y + 1180 "l" + (x + 10).toFixed() + "," + y + "e"; 1181 // find path and text path 1182 var p = null, t = null; 1183 var c = r.childNodes; 1184 for(var i = 0; i < c.length; ++i){ 1185 var tag = c[i].tagName; 1186 if(tag == "path"){ 1187 p = c[i]; 1188 if(t) break; 1189 }else if(tag == "textpath"){ 1190 t = c[i]; 1191 if(p) break; 1192 } 1193 } 1194 if(!p){ 1195 p = document.createElement("v:path"); 1196 r.appendChild(p); 1197 } 1198 if(!t){ 1199 t = document.createElement("v:textpath"); 1200 r.appendChild(t); 1201 } 1202 p.textPathOk = true; 1203 t.on = true; 1204 var a = this._alignment[s.align]; 1205 t.style["v-text-anchor"] = "bottom"; 1206 t.style["v-text-align"] = a ? a : "left"; 1207 t.style["text-decoration"] = s.decoration; 1208 t.style["v-rotate-letters"] = s.rotated; 1209 t.style["v-text-kern"] = s.kerning; 1210 t.string = s.text; 1211 return this.setTransform(this.matrix); // self 1212 }, 1213 setFont: function(font){ 1214 // summary: sets a font object (SVG) 1215 // font: Object: a font object (see dojo.gfx.defaultFont) or a string 1216 var f = this.fontStyle = typeof font == "string" ? 1217 dojo.gfx.splitFontString(font) : 1218 dojo.gfx.makeParameters(dojo.gfx.defaultFont, font); 1219 var c = this.rawNode.childNodes; 1220 for(var i = 0; i < c.length; ++i){ 1221 if(c[i].tagName == "textpath"){ 1222 c[i].style.font = dojo.gfx.makeFontString(f); 1223 break; 1224 } 1225 } 1226 return this.setTransform(this.matrix); // self 1227 }, 1228 attachFont: function(rawNode){ 1229 // summary: deduces a font style from a Node. 1230 // rawNode: Node: an SVG node 1231 if(!rawNode){ return null; } 1232 var fontStyle = dojo.lang.shallowCopy(dojo.gfx.defaultFont, true); 1233 var c = this.rawNode.childNodes; 1234 for(var i = 0; i < c.length; ++i){ 1235 if(c[i].tagName == "textpath"){ 1236 var s = c[i].style; 1237 fontStyle.style = s.fontstyle; 1238 fontStyle.variant = s.fontvariant; 1239 fontStyle.weight = s.fontweight; 1240 fontStyle.size = s.fontsize; 1241 fontStyle.family = s.fontfamily; 1242 break; 1243 } 1244 } 1245 return fontStyle; // Object 1246 }, 1247 attachTransform: function(rawNode) { 1248 // summary: deduces a transformation matrix from a Node. 1249 // rawNode: Node: an VML node 1250 var matrix = dojo.gfx.Shape.prototype.attachTransform.call(this); 1251 if(matrix){ 1252 matrix = dojo.gfx.matrix.multiply(matrix, {dy: dojo.gfx.vml.normalizedLength(this.fontStyle.size) * 0.4}); 1253 } 1254 return matrix; // dojo.gfx.Matrix2D 1255 }, 1256 _getRealMatrix: function(){ 1257 // summary: returns the cumulative ("real") transformation matrix 1258 // by combining the shape's matrix with its parent's matrix; 1259 // it makes a correction for a font size 1260 var matrix = dojo.gfx.Shape.prototype._getRealMatrix.call(this); 1261 if(matrix){ 1262 matrix = dojo.gfx.matrix.multiply(matrix, 1263 {dy: -dojo.gfx.vml.normalizedLength(this.fontStyle ? this.fontStyle.size : "10pt") * 0.4}); 1264 } 1265 return matrix; // dojo.gfx.Matrix2D 1266 } 1267 }); 1268 dojo.gfx.Text.nodeType = "shape"; 1269 1270 dojo.gfx.vml._creators = { 1133 1271 // summary: VML shape creators 1134 1272 createPath: function(path){ 1135 // summary: creates a nSVG path shape1273 // summary: creates a SVG path shape 1136 1274 // path: Object: a path object (see dojo.gfx.defaultPath) 1137 1275 return this.createObject(dojo.gfx.Path, path, true); // dojo.gfx.Path 1138 1276 }, 1139 1277 createRect: function(rect){ 1140 // summary: creates a nVML rectangle shape1278 // summary: creates a VML rectangle shape 1141 1279 // rect: Object: a path object (see dojo.gfx.defaultRect) 1142 1280 return this.createObject(dojo.gfx.Rect, rect); // dojo.gfx.Rect 1143 1281 }, 1144 1282 createCircle: function(circle){ 1145 // summary: creates a nVML circle shape1283 // summary: creates a VML circle shape 1146 1284 // circle: Object: a circle object (see dojo.gfx.defaultCircle) 1147 1285 return this.createObject(dojo.gfx.Circle, circle); // dojo.gfx.Circle 1148 1286 }, 1149 1287 createEllipse: function(ellipse){ 1150 // summary: creates a nVML ellipse shape1288 // summary: creates a VML ellipse shape 1151 1289 // ellipse: Object: an ellipse object (see dojo.gfx.defaultEllipse) 1152 1290 return this.createObject(dojo.gfx.Ellipse, ellipse); // dojo.gfx.Ellipse 1153 1291 }, 1154 1292 createLine: function(line){ 1155 // summary: creates a nVML line shape1293 // summary: creates a VML line shape 1156 1294 // line: Object: a line object (see dojo.gfx.defaultLine) 1157 1295 return this.createObject(dojo.gfx.Line, line, true); // dojo.gfx.Line 1158 1296 }, 1159 1297 createPolyline: function(points){ 1160 // summary: creates a nVML polyline/polygon shape1298 // summary: creates a VML polyline/polygon shape 1161 1299 // points: Object: a points object (see dojo.gfx.defaultPolyline) 1162 1300 // or an Array of points … … 1164 1302 }, 1165 1303 createImage: function(image){ 1166 // summary: creates a nVML image shape1304 // summary: creates a VML image shape 1167 1305 // image: Object: an image object (see dojo.gfx.defaultImage) 1168 1306 if(!this.rawNode) return null; … … 1181 1319 return shape; // dojo.gfx.Image 1182 1320 }, 1321 createText: function(text){ 1322 // summary: creates a VML text shape 1323 // text: Object: a text object (see dojo.gfx.defaultText) 1324 return this.createObject(dojo.gfx.Text, text, true); // dojo.gfx.Text 1325 }, 1183 1326 createGroup: function(){ 1184 // summary: creates a nVML group shape1327 // summary: creates a VML group shape 1185 1328 return this.createObject(dojo.gfx.Group, null, true); // dojo.gfx.Group 1186 1329 }, … … 1206 1349 }; 1207 1350 1208 dojo.lang.extend(dojo.gfx.Group, dojo.gfx. _creators);1209 dojo.lang.extend(dojo.gfx.Surface, dojo.gfx. _creators);1210 1211 delete dojo.gfx. _creators;1351 dojo.lang.extend(dojo.gfx.Group, dojo.gfx.vml._creators); 1352 dojo.lang.extend(dojo.gfx.Surface, dojo.gfx.vml._creators); 1353 1354 delete dojo.gfx.vml._creators; 1212