瀏覽代碼

Refactored THREE.FontUtils into THREE.Font.

Mr.doob 9 年之前
父節點
當前提交
3dee9a76ac
共有 5 個文件被更改,包括 205 次插入316 次删除
  1. 0 271
      src/extras/FontUtils.js
  2. 184 0
      src/extras/core/Font.js
  3. 17 27
      src/extras/geometries/TextGeometry.js
  4. 3 17
      src/loaders/FontLoader.js
  5. 1 1
      utils/build/includes/extras.json

+ 0 - 271
src/extras/FontUtils.js

@@ -1,271 +0,0 @@
-/**
- * @author zz85 / http://www.lab4games.net/zz85/blog
- * @author alteredq / http://alteredqualia.com/
- *
- * For Text operations in three.js (See TextGeometry)
- *
- * It uses techniques used in:
- *
- *	Triangulation ported from AS3
- *		Simple Polygon Triangulation
- *		http://actionsnippet.com/?p=1462
- *
- * 	A Method to triangulate shapes with holes
- *		http://www.sakri.net/blog/2009/06/12/an-approach-to-triangulating-polygons-with-holes/
- *
- */
-
-THREE.FontUtils = {
-
-	faces: {},
-
-	// Just for now. face[weight][style]
-
-	face: 'helvetiker',
-	weight: 'normal',
-	style: 'normal',
-	size: 150,
-	divisions: 10,
-
-	getFace: function () {
-
-		try {
-
-			return this.faces[ this.face.toLowerCase() ][ this.weight ][ this.style ];
-
-		} catch ( e ) {
-
-			throw "The font " + this.face + " with " + this.weight + " weight and " + this.style + " style is missing.";
-
-		}
-
-	},
-
-	loadFace: function ( data ) {
-
-		var family = data.familyName.toLowerCase();
-
-		var ThreeFont = this;
-
-		ThreeFont.faces[ family ] = ThreeFont.faces[ family ] || {};
-
-		ThreeFont.faces[ family ][ data.cssFontWeight ] = ThreeFont.faces[ family ][ data.cssFontWeight ] || {};
-		ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data;
-
-		ThreeFont.faces[ family ][ data.cssFontWeight ][ data.cssFontStyle ] = data;
-
-		return data;
-
-	},
-
-	drawText: function ( text ) {
-
-		// RenderText
-
-		var i,
-			face = this.getFace(),
-			scale = this.size / face.resolution,
-			offset = 0,
-			chars = String( text ).split( '' ),
-			length = chars.length;
-
-		var fontPaths = [];
-
-		for ( i = 0; i < length; i ++ ) {
-
-			var path = new THREE.Path();
-
-			var ret = this.extractGlyphPoints( chars[ i ], face, scale, offset, path );
-			offset += ret.offset;
-
-			fontPaths.push( ret.path );
-
-		}
-
-		// get the width
-
-		var width = offset / 2;
-		//
-		// for ( p = 0; p < allPts.length; p++ ) {
-		//
-		// 	allPts[ p ].x -= width;
-		//
-		// }
-
-		//var extract = this.extractPoints( allPts, characterPts );
-		//extract.contour = allPts;
-
-		//extract.paths = fontPaths;
-		//extract.offset = width;
-
-		return { paths: fontPaths, offset: width };
-
-	},
-
-
-
-
-	extractGlyphPoints: function ( c, face, scale, offset, path ) {
-
-		var pts = [];
-
-		var b2 = THREE.ShapeUtils.b2;
-		var b3 = THREE.ShapeUtils.b3;
-
-		var i, i2, divisions,
-			outline, action, length,
-			scaleX, scaleY,
-			x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2,
-			laste,
-			glyph = face.glyphs[ c ] || face.glyphs[ '?' ];
-
-		if ( ! glyph ) return;
-
-		if ( glyph.o ) {
-
-			outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
-			length = outline.length;
-
-			scaleX = scale;
-			scaleY = scale;
-
-			for ( i = 0; i < length; ) {
-
-				action = outline[ i ++ ];
-
-				//console.log( action );
-
-				switch ( action ) {
-
-				case 'm':
-
-					// Move To
-
-					x = outline[ i ++ ] * scaleX + offset;
-					y = outline[ i ++ ] * scaleY;
-
-					path.moveTo( x, y );
-					break;
-
-				case 'l':
-
-					// Line To
-
-					x = outline[ i ++ ] * scaleX + offset;
-					y = outline[ i ++ ] * scaleY;
-					path.lineTo( x, y );
-					break;
-
-				case 'q':
-
-					// QuadraticCurveTo
-
-					cpx  = outline[ i ++ ] * scaleX + offset;
-					cpy  = outline[ i ++ ] * scaleY;
-					cpx1 = outline[ i ++ ] * scaleX + offset;
-					cpy1 = outline[ i ++ ] * scaleY;
-
-					path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
-
-					laste = pts[ pts.length - 1 ];
-
-					if ( laste ) {
-
-						cpx0 = laste.x;
-						cpy0 = laste.y;
-
-						for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
-
-							var t = i2 / divisions;
-							b2( t, cpx0, cpx1, cpx );
-							b2( t, cpy0, cpy1, cpy );
-
-						}
-
-					}
-
-					break;
-
-				case 'b':
-
-					// Cubic Bezier Curve
-
-					cpx  = outline[ i ++ ] * scaleX + offset;
-					cpy  = outline[ i ++ ] * scaleY;
-					cpx1 = outline[ i ++ ] * scaleX + offset;
-					cpy1 = outline[ i ++ ] * scaleY;
-					cpx2 = outline[ i ++ ] * scaleX + offset;
-					cpy2 = outline[ i ++ ] * scaleY;
-
-					path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
-
-					laste = pts[ pts.length - 1 ];
-
-					if ( laste ) {
-
-						cpx0 = laste.x;
-						cpy0 = laste.y;
-
-						for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
-
-							var t = i2 / divisions;
-							b3( t, cpx0, cpx1, cpx2, cpx );
-							b3( t, cpy0, cpy1, cpy2, cpy );
-
-						}
-
-					}
-
-					break;
-
-				}
-
-			}
-
-		}
-
-
-
-		return { offset: glyph.ha * scale, path: path };
-
-	}
-
-};
-
-
-THREE.FontUtils.generateShapes = function ( text, parameters ) {
-
-	// Parameters
-
-	parameters = parameters || {};
-
-	var size = parameters.size !== undefined ? parameters.size : 100;
-	var curveSegments = parameters.curveSegments !== undefined ? parameters.curveSegments : 4;
-
-	var font = parameters.font !== undefined ? parameters.font : 'helvetiker';
-	var weight = parameters.weight !== undefined ? parameters.weight : 'normal';
-	var style = parameters.style !== undefined ? parameters.style : 'normal';
-
-	THREE.FontUtils.size = size;
-	THREE.FontUtils.divisions = curveSegments;
-
-	THREE.FontUtils.face = font;
-	THREE.FontUtils.weight = weight;
-	THREE.FontUtils.style = style;
-
-	// Get a Font data json object
-
-	var data = THREE.FontUtils.drawText( text );
-
-	var paths = data.paths;
-	var shapes = [];
-
-	for ( var p = 0, pl = paths.length; p < pl; p ++ ) {
-
-		Array.prototype.push.apply( shapes, paths[ p ].toShapes() );
-
-	}
-
-	return shapes;
-
-};

+ 184 - 0
src/extras/core/Font.js

@@ -0,0 +1,184 @@
+/**
+ * @author zz85 / http://www.lab4games.net/zz85/blog
+ * @author mrdoob / http://mrdoob.com/
+ */
+
+THREE.Font = function ( data ) {
+
+	this.data = data;
+
+};
+
+THREE.Font.prototype = {
+
+	constructor: THREE.Font,
+
+	generateShapes: function ( text, size, curveSegments ) {
+
+		function createPaths( text ) {
+
+			var chars = String( text ).split( '' );
+			var scale = size / data.resolution;
+			var offset = 0;
+
+			var paths = [];
+
+			for ( var i = 0; i < chars.length; i ++ ) {
+
+				var path = new THREE.Path();
+
+				var ret = extractGlyphPoints( chars[ i ], scale, offset, path );
+				offset += ret.offset;
+
+				paths.push( ret.path );
+
+			}
+
+			return paths;
+
+		}
+
+		function extractGlyphPoints( c, scale, offset, path ) {
+
+			var pts = [];
+
+			var b2 = THREE.ShapeUtils.b2;
+			var b3 = THREE.ShapeUtils.b3;
+
+			var i, i2, divisions,
+				outline, action, length,
+				scaleX, scaleY,
+				x, y, cpx, cpy, cpx0, cpy0, cpx1, cpy1, cpx2, cpy2,
+				laste,
+				glyph = data.glyphs[ c ] || data.glyphs[ '?' ];
+
+			if ( ! glyph ) return;
+
+			if ( glyph.o ) {
+
+				outline = glyph._cachedOutline || ( glyph._cachedOutline = glyph.o.split( ' ' ) );
+				length = outline.length;
+
+				scaleX = scale;
+				scaleY = scale;
+
+				for ( i = 0; i < length; ) {
+
+					action = outline[ i ++ ];
+
+					//console.log( action );
+
+					switch ( action ) {
+
+					case 'm':
+
+						// Move To
+
+						x = outline[ i ++ ] * scaleX + offset;
+						y = outline[ i ++ ] * scaleY;
+
+						path.moveTo( x, y );
+						break;
+
+					case 'l':
+
+						// Line To
+
+						x = outline[ i ++ ] * scaleX + offset;
+						y = outline[ i ++ ] * scaleY;
+						path.lineTo( x, y );
+						break;
+
+					case 'q':
+
+						// QuadraticCurveTo
+
+						cpx  = outline[ i ++ ] * scaleX + offset;
+						cpy  = outline[ i ++ ] * scaleY;
+						cpx1 = outline[ i ++ ] * scaleX + offset;
+						cpy1 = outline[ i ++ ] * scaleY;
+
+						path.quadraticCurveTo( cpx1, cpy1, cpx, cpy );
+
+						laste = pts[ pts.length - 1 ];
+
+						if ( laste ) {
+
+							cpx0 = laste.x;
+							cpy0 = laste.y;
+
+							for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
+
+								var t = i2 / divisions;
+								b2( t, cpx0, cpx1, cpx );
+								b2( t, cpy0, cpy1, cpy );
+
+							}
+
+						}
+
+						break;
+
+					case 'b':
+
+						// Cubic Bezier Curve
+
+						cpx  = outline[ i ++ ] * scaleX + offset;
+						cpy  = outline[ i ++ ] * scaleY;
+						cpx1 = outline[ i ++ ] * scaleX + offset;
+						cpy1 = outline[ i ++ ] * scaleY;
+						cpx2 = outline[ i ++ ] * scaleX + offset;
+						cpy2 = outline[ i ++ ] * scaleY;
+
+						path.bezierCurveTo( cpx1, cpy1, cpx2, cpy2, cpx, cpy );
+
+						laste = pts[ pts.length - 1 ];
+
+						if ( laste ) {
+
+							cpx0 = laste.x;
+							cpy0 = laste.y;
+
+							for ( i2 = 1, divisions = this.divisions; i2 <= divisions; i2 ++ ) {
+
+								var t = i2 / divisions;
+								b3( t, cpx0, cpx1, cpx2, cpx );
+								b3( t, cpy0, cpy1, cpy2, cpy );
+
+							}
+
+						}
+
+						break;
+
+					}
+
+				}
+
+			}
+
+			return { offset: glyph.ha * scale, path: path };
+
+		}
+
+		//
+
+		if ( size === undefined ) size = 100;
+		if ( curveSegments === undefined ) curveSegments = 4;
+
+		var data = this.data;
+
+		var paths = createPaths( text );
+		var shapes = [];
+
+		for ( var p = 0, pl = paths.length; p < pl; p ++ ) {
+
+			Array.prototype.push.apply( shapes, paths[ p ].toShapes() );
+
+		}
+
+		return shapes;
+
+	}
+
+};

+ 17 - 27
src/extras/geometries/TextGeometry.js

@@ -2,45 +2,35 @@
  * @author zz85 / http://www.lab4games.net/zz85/blog
  * @author alteredq / http://alteredqualia.com/
  *
- * For creating 3D text geometry in three.js
- *
  * Text = 3D Text
  *
  * parameters = {
- *  size: 			<float>, 	// size of the text
- *  height: 		<float>, 	// thickness to extrude text
- *  curveSegments: 	<int>,		// number of points on the curves
- *
- *  font: 			<string>,		// font name
- *  weight: 		<string>,		// font weight (normal, bold)
- *  style: 			<string>,		// font style  (normal, italics)
+ *  font: <THREE.Font>, // font
  *
- *  bevelEnabled:	<bool>,			// turn on bevel
- *  bevelThickness: <float>, 		// how deep into text bevel goes
- *  bevelSize:		<float>, 		// how far from text outline is bevel
- *  }
+ *  size: <float>, // size of the text
+ *  height: <float>, // thickness to extrude text
+ *  curveSegments: <int>, // number of points on the curves
  *
+ *  bevelEnabled: <bool>, // turn on bevel
+ *  bevelThickness: <float>, // how deep into text bevel goes
+ *  bevelSize: <float> // how far from text outline is bevel
+ * }
  */
 
-/*	Usage Examples
-
-	// TextGeometry wrapper
-
-	var text3d = new TextGeometry( text, options );
-
-	// Complete manner
+THREE.TextGeometry = function ( text, parameters ) {
 
-	var textShapes = THREE.FontUtils.generateShapes( text, options );
-	var text3d = new ExtrudeGeometry( textShapes, options );
+	parameters = parameters || {};
 
-*/
+	var font = parameters.font;
 
+	if ( font instanceof THREE.Font === false ) {
 
-THREE.TextGeometry = function ( text, parameters ) {
+		console.error( 'THREE.TextGeometry: font parameter is not an instance of THREE.Font.' );
+		return new THREE.Geometry();
 
-	parameters = parameters || {};
+	}
 
-	var textShapes = THREE.FontUtils.generateShapes( text, parameters );
+	var shapes = font.generateShapes( text, parameters.size, parameters.curveSegments );
 
 	// translate parameters to ExtrudeGeometry API
 
@@ -52,7 +42,7 @@ THREE.TextGeometry = function ( text, parameters ) {
 	if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;
 	if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;
 
-	THREE.ExtrudeGeometry.call( this, textShapes, parameters );
+	THREE.ExtrudeGeometry.call( this, shapes, parameters );
 
 	this.type = 'TextGeometry';
 

+ 3 - 17
src/loaders/FontLoader.js

@@ -10,31 +10,17 @@ THREE.FontLoader = function ( manager ) {
 
 THREE.FontLoader.prototype = {
 
-	constructor: THREE.TextureLoader,
+	constructor: THREE.FontLoader,
 
 	load: function ( url, onLoad, onProgress, onError ) {
 
-		var scope = this;
-
-		var loader = new THREE.XHRLoader( scope.manager );
+		var loader = new THREE.XHRLoader( this.manager );
 		loader.load( url, function ( text ) {
 
-			onLoad( THREE.FontUtils.loadFace( JSON.parse( text ) ) );
+			onLoad( new THREE.Font( JSON.parse( text ) ) );
 
 		}, onProgress, onError );
 
-	},
-
-	setCrossOrigin: function ( value ) {
-
-		this.crossOrigin = value;
-
-	},
-
-	setPath: function ( value ) {
-
-		this.path = value;
-
 	}
 
 };

+ 1 - 1
utils/build/includes/extras.json

@@ -1,10 +1,10 @@
 [
 	"src/extras/CurveUtils.js",
-	"src/extras/FontUtils.js",
 	"src/extras/SceneUtils.js",
 	"src/extras/ShapeUtils.js",
 	"src/extras/core/Curve.js",
 	"src/extras/core/CurvePath.js",
+	"src/extras/core/Font.js",
 	"src/extras/core/Path.js",
 	"src/extras/core/Shape.js",
 	"src/extras/curves/LineCurve.js",