Пример #1
0
		/// <summary>
		/// The following script text is experimental
		/// it is based on JyC. 
		/// It provide direct access to C# methods and objects
		/// but it may not be the most intuitive for our users
		/// It is accessbile through tags <@# .... @>
		/// 
		/// </summary>	
		public static void EvalScriptText (TTFText tm, string s, ref TTFTextInternal.LineLayout ll)
		{
#if! TTFTEXT_LITE

			//
			TTFTextStyle ts = tm.CurrentTextStyle;
			Jyc.Expr.Parser ep = new Jyc.Expr.Parser ();
			Jyc.Expr.Tree tree;
			try {
				tree = ep.Parse (s);
				Jyc.Expr.Evaluator evaluater = new Jyc.Expr.Evaluator (); 
				Jyc.Expr.ParameterVariableHolder pvh = new Jyc.Expr.ParameterVariableHolder ();
				pvh.Parameters ["T"] = pvh.Parameters ["text"] = new Jyc.Expr.Parameter (tm);
				pvh.Parameters ["S"] = pvh.Parameters ["style"] = new Jyc.Expr.Parameter (ts);
				pvh.Parameters ["L"] = pvh.Parameters ["linelayout"] = new Jyc.Expr.Parameter (ll);
				//pvh.Parameters ["I"] = pvh.Parameters ["img"] = new Jyc.Expr.Parameter(TTFTextInternal.Get);
				evaluater.VariableHolder = pvh;
				ts = (TTFTextStyle)evaluater.Eval (tree);
				if (ts != null) {
					//Debug.Log (	ts.Size);
					tm.CurrentTextStyle = ts;
				}
			} catch (System.Exception e) {
				Debug.LogError (e);
			}			
#endif				

		}
Пример #2
0
		// EASY MARKUP
		public static void EvalEasyMarkUp (TTFText tm, string bs, ref TTFTextInternal.LineLayout ll)
		{
//			Debug.Log("Eval "+bs);
#if TTFTEXT_LITE
			if (tm.DemoMode) {
#endif				

			TTFTextStyle ts = tm.CurrentTextStyle;
			try {
				bs = bs.Trim ();
				if (bs [0] == '#') {
					EvalScriptText (tm, bs.Substring (1), ref ll);
				}
				char [] separators = {'|'};	
				
				foreach (string s in bs.Split(separators)) {				
					if (s.Contains ("=")) {				
						char [] seps = {'='};
						string [] vals = s.Split (seps);
						string lval = vals [0].Trim ();
						string rval = vals [1].Trim ();
				
						if (lval == "style") {
							if (rval.Contains ("<")) {
								// probably invalid
								return;
							}
							ts = ts.PushF (rval, tm.autoCreateStyles, ref tm.nonFoundStyles);
						} else {
							if (!lval.Contains ("#")) {
								// we modify our component
								System.Type tp = typeof(TTFTextStyle);						
								System.Reflection.PropertyInfo pi = tp.GetProperty (lval);
					
								string tpn = pi.PropertyType.Name;
						
								ts = ts.Push ();
								if (tpn == tpn_float) {							
									if (rval [0] == '+') {
										pi.SetValue (ts, ((float)pi.GetValue (ts, null)) + System.Single.Parse (rval.Substring (1)), null);
									} else {
										if (rval [0] == '*') {
											pi.SetValue (ts, ((float)pi.GetValue (ts, null)) * System.Single.Parse (rval.Substring (1)), null);
										} else {
											pi.SetValue (ts, System.Single.Parse (rval), null);
										}
									}
								} else {						
									if (tpn == tpn_bool) {
										pi.SetValue (ts, System.Boolean.Parse (rval), null);
									} else {						
										if (tpn == tpn_int) {								
											pi.SetValue (ts, System.Int32.Parse (rval), null);								
										} else {
											if (tpn == tpn_string) {
												pi.SetValue (ts, rval, null);								
											} else {
												Debug.LogWarning (pi.PropertyType.Name + " : Behaviour not defined");
											}
										}
									}
						
								}	
							} else {
								int isharp = lval.IndexOf ('#');
								string comppart = lval.Substring (0, isharp);
								string fieldname = lval.Substring (isharp + 1);
								object o = (object)tm.gameObject.GetComponent (comppart);
								System.Type tp = o.GetType ();						
								System.Reflection.FieldInfo fi = tp.GetField (fieldname);
					
								string tpn = fi.FieldType.Name;
						
								if (tpn == tpn_float) {							
									if (rval [0] == '+') {
										fi.SetValue (o, ((float)fi.GetValue (o)) + System.Single.Parse (rval.Substring (1)));
									} else {
										if (rval [0] == '*') {
											fi.SetValue (o, ((float)fi.GetValue (o)) * System.Single.Parse (rval.Substring (1)));
										} else {
											fi.SetValue (o, System.Single.Parse (rval));
										}
									}
								} else {						
									if (tpn == tpn_bool) {
										fi.SetValue (o, System.Boolean.Parse (rval));
									} else {						
										if (tpn == tpn_int) {								
											fi.SetValue (o, System.Int32.Parse (rval));								
										} else {
											if (tpn == tpn_string) {
												fi.SetValue (o, rval);								
											} else {
												Debug.LogWarning (fi.FieldType.Name + " : Behaviour not defined");
											}
										}
									}
						
								}										
							}
						}
				
					} else {
						if ((s.ToLower () == "end") || (s.ToLower () == "pop")) {
							ts = ts.Pop ();
						} else {
							Debug.LogError ("(TTFText) Unknown command : " + s);
						}
					}
//					Debug.Log("Setting ts fontid :  "+ts.FontId+" getid : " +ts.getid());
					tm.CurrentTextStyle = ts;
				}
			} catch (System.Exception e) {
				Debug.LogError (e);
			}			
#if TTFTEXT_LITE
		}
#endif				

		}
Пример #3
0
		/// <summary>
		/// Subdivides line into individual characters
		/// </summary>
		/// <returns>
		/// The one per char.
		/// </returns>
		/// <param name='l'>
		/// L.
		/// </param> 
		static IEnumerable<TTFTextInternal.LineLayout> EOnePerChar (TTFTextInternal.LineLayout l)
		{		
			
			int i = 0;
			float sa = 0;
			foreach (char c in l.line) {
				TTFTextInternal.LineLayout r = new TTFTextInternal.LineLayout ("" + c, l.tm, false);		
				r.charadvances = new float[1];
				r.charpositions = new float[1];												
				r.charstyleindex = new int[1];	
				r.charmetadata = new object[1];
				r.charadvances [0] = l.charadvances [i];	
				r.charpositions [0] = 0;	
				r.charstyleindex [0] = l.charstyleindex [i];	
				r.charmetadata [0] = l.charmetadata [i];
				r.prevadvance = l.prevadvance + sa;
				r.linewidth = l.GetCharStyle (i).LineWidth;
				r.lineno = l.lineno;
				if (i + 1 < l.line.Length) {
					r.advancelen = l.charpositions [i + 1] - l.charpositions [i];
				} else {
					r.advancelen = l.advancelen - l.charpositions [i];					
				}
				yield return r;
				sa += r.advancelen;
			
				i += 1;
			}
		} 
Пример #4
0
		static void FinalizeLL (ref TTFTextInternal.LineLayout ll, float firstlineoffset)
		{
			ll.offset = 0;

			
			if (((ll.align != TTFText.ParagraphAlignmentEnum.Right))		
					&& ((ll.align != TTFText.ParagraphAlignmentEnum.Center))) {
				ll.offset = firstlineoffset;		
			}
			ll.ComputeCharacterPositions ();
		
			if ((ll.align == TTFText.ParagraphAlignmentEnum.Right)) {
//					Debug.Log(System.String.Format("{0} {1}",ll.linewidth, ll.GetActualLinewidth()));
				ll.offset = ll.linewidth - ll.GetActualLinewidth ();
			} else {
				if ((ll.align == TTFText.ParagraphAlignmentEnum.Center)) {
					ll.offset = (ll.linewidth - ll.GetActualLinewidth ()) / 2;
				} else {
					ll.offset = firstlineoffset;								
				}
									
			}		
		}
Пример #5
0
		/// <summary>
		/// The layout atoms are line
		/// </summary>
		/// <returns>
		/// The one per line.
		/// </returns>
		/// <param name='l'>
		/// L.
		/// </param>
		static IEnumerable<TTFTextInternal.LineLayout> EOnePerLine (TTFTextInternal.LineLayout l)
		{
			yield return l;
		}
Пример #6
0
		/// <summary>
		/// Subdivide lines into words
		/// </summary>
		/// <returns>
		/// The one per line.
		/// </returns>
		/// <param name='l'>
		/// L.
		/// </param>	
		static IEnumerable<TTFTextInternal.LineLayout> EOnePerWord (TTFTextInternal.LineLayout l)
		{

			char[] seps = new char[] { ' ' };
			string[] words = l.line.Split (seps, System.StringSplitOptions.RemoveEmptyEntries);
		
			int p = 0;
			float sa = 0;
			foreach (string w in words) {			
				int wlen = w.Length;
				int p0 = p;
			
				while (l.line[p] != w[0])
					p++; // <- skipping spaces : BUG TO BE FIXED !
		    
				TTFTextInternal.LineLayout r = new TTFTextInternal.LineLayout (w, l.tm, false);
				r.prevadvance = l.prevadvance + sa;
				if (wlen > 0) {
					r.linewidth = l.GetCharStyle (p).LineWidth;
				}
				r.charadvances = new float[w.Length];
				r.charpositions = new float[w.Length];
				r.charstyleindex = new int[w.Length];
				r.charmetadata = new object[w.Length];
			
				for (int i = 0; i < wlen; i++) {
					r.charadvances [i] = l.charadvances [p + i];	
					r.charpositions [i] = l.charpositions [p + i] - l.charpositions [p0];		
					r.charstyleindex [i] = l.charstyleindex [p + i];	
					r.charmetadata [i] = l.charmetadata [p + i];
				}
			
				if (p + wlen < l.line.Length) {
					r.advancelen = l.charpositions [p + wlen] - l.charpositions [p0];
				} else {
					r.advancelen = l.advancelen - l.charpositions [p0];
				}
				r.lineno = l.lineno;
				yield return r;
				sa += r.advancelen;
				p += wlen;
			}
		}
Пример #7
0
		static TTFTextOutline[] MakeBevelOutlines (TTFTextInternal.LineLayout ll, TTFText tm, TTFTextStyle ts)
		{
			//Vector3 min=Vector3.zero; Vector3 max=Vector3.zero;
			//Vector3 min_; Vector3 max_;
			int NS = tm.NbDiv;
			if (NS < 2) {
				NS = 2;
			}
		
			TTFTextOutline[] outlines = new TTFTextOutline[NS * 2];
			//Vector3[] szs = new Vector3[NS*2];
		
			float bevelDepth = ts.BevelDepth * ts.ExtrusionDepth / 2;
		
			for (int i = 0; i < NS; ++i) {
			
				float f = ((float)i) / ((float)NS - 1); // [0,1]
			
				float embold = ts.Embold + Mathf.Sin (Mathf.Acos (1 - f)) * ts.BevelForce;
			
				TTFTextOutline o = MakeOutline (ll, embold, tm);
			
				o.Slant (ts.Slant);
			
				outlines [i] = o;
				outlines [2 * NS - 1 - i] = new TTFTextOutline (o);
			
				//outlines[i].GetMinMax(out min_, out max_);
				//szs[i]=max_-min_;
				float z = f * bevelDepth;
			
				outlines [i].Translate (Vector3.forward * z);
				outlines [2 * NS - 1 - i].Translate (Vector3.forward * (ts.ExtrusionDepth - z));
			
				//szs[2*NS-1-i]=max_-min_;
				//min = Vector3.Min(min, min_);
				//max = Vector3.Max(max, max_);			
			}


			//Vector3 sz=max-min;
			//for (int i=0;i<(2*NS);i++) {
			//	outlines[i].Translate((sz-szs[i])/2);
			//}
		
	
			return outlines;
		}
Пример #8
0
		public static TTFTextOutline MakeOutline (TTFTextInternal.LineLayout ll, float embold, TTFText tm)
		{
			return MakeOutline (ll.line, ll.hspacing, embold, tm, tm.OrientationReversed, ll.charpositions, ll.charstyleindex, ll.charmetadata);
		}
Пример #9
0
		static TTFTextOutline[] MakeBentOutlines (TTFTextInternal.LineLayout ll, TTFText tm, TTFTextStyle ts)
		{			
			//Vector3 min=Vector3.zero; Vector3 max=Vector3.zero;
			int NS = ts.ExtrusionSteps.Length; 
		
			TTFTextOutline[] outlines = new TTFTextOutline[NS];
			//Vector3 [] szs = new Vector3[NS];
		
			for (int i = 0; i < NS; i++) {
			
				//Vector3 min_, max_;
			
		    
				float embold = ts.Embold + ts.BevelForce * Mathf.Sin (i * Mathf.PI / (NS - 1));
		    
				// wierd error with poly2tri/embold for the backface
				if (i == NS - 1) {
					embold = ts.Embold;		
				}
				
				outlines [i] = MakeOutline (ll, embold, tm);
		
				float z = (ts.ExtrusionSteps [i] - 0.5f) * ts.ExtrusionDepth;// - tm.exstrusionDepth / 2;
				outlines [i].Translate (Vector3.forward * z);
			
				if (ts.Slant != 0) {
					outlines [i].Slant (ts.Slant);
				}
			
				//outlines[i].GetMinMax(out min_, out max_);
				//szs[i]=max_-min_;
				//min = Vector3.Min(min, min_);
				//max = Vector3.Max(max, max_);
			}
		
			//Vector3 sz=max-min;
			//for (int i=0;i<NS;i++) {
			//	outlines[i].Translate((sz-szs[i])/2);
			//}

			return outlines;
		}
Пример #10
0
		// FreeHand Curve Extrusion
		public static TTFTextOutline[] MakeFreeHandOutlines (TTFTextInternal.LineLayout ll, TTFText tm, TTFTextStyle ts)
		{
			//Vector3 min=Vector3.zero; Vector3 max=Vector3.zero;
			Keyframe[] keys = ts.FreeHandCurve.keys;
		
			int NS = keys.Length;
		
			TTFTextOutline[] outlines = new TTFTextOutline[NS];
			float[] z = new float[NS];

			//min = Vector3.zero;
			//max = Vector3.zero;
			//Vector3 [] szs = new Vector3[NS];
		
			for (int i=0; i<NS; i++) {			
// 			Vector3 min_, max_;
				z [i] = keys [i].time * ts.ExtrusionDepth;
			
				outlines [i] = MakeOutline (ll, ts.Embold + keys [i].value * ts.BevelForce, tm);			
				outlines [i].Translate (Vector3.forward * z [i]);
			
				if (ts.Slant != 0) {
					outlines [i].Slant (ts.Slant);
				}
			
				//outlines[i].GetMinMax(out min_, out max_);
				//szs[i]=max_-min_;
				//min = Vector3.Min(min, min_);
				//max = Vector3.Max(max, max_);
			}
			//Vector3 sz=max-min;
			//for (int i=0;i<NS;i++) {
			//	outlines[i].Translate((sz-szs[i])/2);
			//}
			return outlines;
		}
Пример #11
0
		// Simple extrusion
		public static TTFTextOutline[] MakeSimpleOutlines (TTFTextInternal.LineLayout ll, TTFText tm, TTFTextStyle ts)
		{	
			TTFTextOutline o = MakeOutline (ll, ts.Embold, tm);
			if (ts.Slant != 0) {
				o.Slant (ts.Slant);
			}
		
			TTFTextOutline[] outlines = new TTFTextOutline[2];
			outlines [0] = o;
			outlines [1] = new TTFTextOutline (o);
			outlines [0].Translate (Vector3.forward * (-ts.ExtrusionDepth) / 2);
			outlines [1].Translate (Vector3.forward * ts.ExtrusionDepth / 2);
		
			return outlines;
		}
Пример #12
0
		public static Mesh BuildMesh (ref Mesh mesh, TTFTextInternal.LineLayout ll, TTFText tm, out Vector3 advance)
		{
		
			Mesh front = null;
			Mesh back = null;
			TTFTextOutline[] outlines = {};
			bool[] mask;
			advance = Vector3.zero;
		
			TTFTextStyle ts = tm.InitTextStyle;
			object charmetadata = null;
		
			if ((ll.charstyleindex != null) && (ll.charstyleindex [0] != -1)) {
				ts = ll.GetCharStyle (0);			
				charmetadata = ll.charmetadata [0];
			}
		
		
		
			if ((charmetadata != null) || (ts.ExtrusionMode == TTFText.ExtrusionModeEnum.None)) { // No extrusion		
				TTFTextOutline o = MakeOutline (ll, ts.Embold, tm);
				charmetadata = ll.charmetadata [0];
				o = o.Simplify (ts.SimplifyAmount, ts.Size);
				if (ts.Slant != 0) {
					o.Slant (ts.Slant);
				}
				advance = o.advance;		
				front = TTFTextInternal.Tesselators.Triangulate (o, tm.DynamicTextRuntimeTriangulationMethod == TTFText.DynamicTextRuntimeTriangulationMethodEnum.CSharpLibs);
			
				if (tm.DynamicTextRuntimeTriangulationMethod == TTFText.DynamicTextRuntimeTriangulationMethodEnum.CSharpLibs) {
					TTFTextInternal.Utilities.ReverseTriangles (front);
				}	
		
				if (tm.BackFace) {
					back = new Mesh ();
					back.vertices = front.vertices;
					back.triangles = front.triangles;
					TTFTextInternal.Utilities.ReverseTriangles (back);
				
					CombineInstance[] combine = new CombineInstance[2];
					combine [0].mesh = front;
					combine [1].mesh = back;
				
					mesh.CombineMeshes (combine, false, false);
				
					Utilities.DestroyObj (front);
					Utilities.DestroyObj (back);
		
				} else {
					CombineInstance[] combine = new CombineInstance[1];
					combine [0].mesh = front;
					mesh.CombineMeshes (combine, false, false);
					Utilities.DestroyObj (front);
				}
		
			} else if (ts.ExtrusionMode == TTFText.ExtrusionModeEnum.Pipe) {
#if TTFTEXT_LITE        
		if (tm.DemoMode) {	
#endif			
				TTFTextOutline o = MakeOutline (ll, ts.Embold, tm);

				o = o.Simplify (ts.SimplifyAmount, ts.Size);
				if (ts.Slant != 0) {
					o.Slant (ts.Slant);
				}
				advance = o.advance;
	
				TTFTextInternalMeshGenerators.Piped (ref mesh, o, ts.Radius, ts.NumPipeEdges);
#if TTFTEXT_LITE        
			}
#endif			
			
			} else {
		
				switch (ts.ExtrusionMode) {

				case TTFText.ExtrusionModeEnum.Simple:
					outlines = MakeSimpleOutlines (ll, tm, ts);
					break;

				case TTFText.ExtrusionModeEnum.Bent:
#if TTFTEXT_LITE        
		if (tm.DemoMode) {	
#endif							
					outlines = MakeBentOutlines (ll, tm, ts);
#if TTFTEXT_LITE        
			}
#endif			
					
					break;

				case TTFText.ExtrusionModeEnum.Bevel:
#if TTFTEXT_LITE        
		if (tm.DemoMode) {	
#endif								
					outlines = MakeBevelOutlines (ll, tm, ts);
#if TTFTEXT_LITE        
			}
#endif			
					
					break;

				case TTFText.ExtrusionModeEnum.FreeHand:
#if TTFTEXT_LITE        
		if (tm.DemoMode) {	
#endif			
					outlines = MakeFreeHandOutlines (ll, tm, ts);
#if TTFTEXT_LITE        
			}
#endif			
					
					break;
				default:
					Debug.LogError ("(TTFText) Unexpected Extrusion Mode:" + tm.ExtrusionMode);
					break;
				}		
	
				if (outlines.Length == 0) {
					mesh.Clear ();
					advance = Vector3.zero;
					return mesh;
				}
			
			
				//if (ts.OutlineEmbold >= 0) {
				//	outlines = OutlineOutlines(outlines, ts.OutlineEmbold);
				//}
			
				mask = outlines [0].SimplifyMask (ts.SimplifyAmount, tm.Size);
		
				// front
				TTFTextOutline o = outlines [0].ApplyMask (mask);
				front = TTFTextInternal.Tesselators.Triangulate (o,
				tm.DynamicTextRuntimeTriangulationMethod == TTFText.DynamicTextRuntimeTriangulationMethodEnum.CSharpLibs);//tm.EmbedCharset);
				
				advance = o.advance;
				advance.z = 0;
				
				//back
				o = outlines [outlines.Length - 1].ApplyMask (mask);
				back = TTFTextInternal.Tesselators.Triangulate (o,
				tm.DynamicTextRuntimeTriangulationMethod == TTFText.DynamicTextRuntimeTriangulationMethodEnum.CSharpLibs);//tm.EmbedCharset);
			

				
				if (tm.DynamicTextRuntimeTriangulationMethod == TTFText.DynamicTextRuntimeTriangulationMethodEnum.CSharpLibs) {
					Utilities.ReverseTriangles (front);
				} else {
					Utilities.ReverseTriangles (back);
				}
			
				TTFTextInternalMeshGenerators.ExtrudeOutlines (ref mesh, front, back, outlines, mask);
			
				Utilities.DestroyObj (front);
				Utilities.DestroyObj (back);

				if (! tm.SplitSides) { // merge submeshes
					Utilities.MergeSubmeshes (mesh);
					//CombineInstance ci[] = new CombineInstance[mesh.subMeshCount];
					//Mesh tmesh=new Mesh();
					//mesh.CombineMeshes(true, false);
				}

			}
	
			ShaderMaps.ComputeUVs2 (mesh, ts.UvType, ts.NormalizeUV, ts.UvScaling, charmetadata);
			mesh.RecalculateNormals ();
			ShaderMaps.ComputeTangents (mesh);
				
			return mesh;
		}
Пример #13
0
		// THIS FUNCTION BUILD INDIVIDUAL SUBOBJECTS FOR EACH OBJECT		
		public static IEnumerable BuildSubtext (TTFTextInternal.LineLayout ll,
									        LineSplitter split, 
		                                    int idx, 
											Vector3 pos, 
											TTFText tm)
											//out Bounds bounds, 
											//out int num)
		{				
			Vector3 adv = Vector3.zero;
			Bounds bounds = new Bounds (Vector3.zero, Vector3.zero);				
			int num = 0;
			
			
			
			
			foreach (TTFTextInternal.LineLayout l in split(ll)) {
				//Debug.Log("ll=" + l.line + " pos=" + pos + " charpos0=" + l.charpositions[0] + " advlen=" + l.advance);			
				GameObject go;
				
				
				
				// instantiate the letter
				bool b0 = ((l.line.Length > 0) 
					    && (l.GetCharStyle (0).GlyphPrefab != null));
				if (b0 || (tm.GlyphPrefab != null)) {
					if (b0) {
						go = GameObject.Instantiate (l.GetCharStyle (0).GlyphPrefab) as GameObject;
					} else {
						go = GameObject.Instantiate (tm.GlyphPrefab) as GameObject;
					}
				} else {
					go = new GameObject ();
					go.AddComponent<MeshFilter> ();
					go.AddComponent<MeshRenderer> ();
				
					if (tm.gameObject.renderer != null) {
						
						if (tm.gameObject.renderer.sharedMaterials != null) {
							if ((tm.gameObject.renderer.sharedMaterials.Length != 0) && (tm.gameObject.renderer.sharedMaterials [0] != null)) {
								go.renderer.sharedMaterials = tm.gameObject.renderer.sharedMaterials;
							}
						} else {
							if (tm.gameObject.renderer.sharedMaterial != null) {
								go.renderer.sharedMaterial = tm.gameObject.renderer.sharedMaterial;
							}	
						}
					}					
				}
			
				
			
				// ---------------------------------------------------------------------
				// set up the letter/text positon and scale
				// ---------------------------------------------------------------------
				int no = idx + num;
				go.name = System.String.Format ("{0}. {1}", no, l.line);
				go.transform.parent = tm.transform;

				if (/*tm.rebuildLayout ||*/ (!tm.SaveTokenPos) || tm.TokenPos.Count <= no) {				
					go.transform.localPosition = pos;
					go.transform.localRotation = Quaternion.identity;				
				} else {
					TTFText.TrInfo tr = tm.TokenPos [no];
					go.transform.localPosition = tr.localPosition;
					go.transform.localRotation = tr.localRotation;
					go.transform.localScale = tr.localScale;
				}
				if (l.line.Length > 0) {
					if ((l.GetCharStyle (0).sharedMaterials != null)
					&& (l.GetCharStyle (0).sharedMaterials.Length > 0)
					&& (l.GetCharStyle (0).sharedMaterials [0] != null)) {
						go.renderer.sharedMaterials = l.GetCharStyle (0).sharedMaterials;
					}
				}
			
				
				
				// ----------------------------------------------------------
				// build the mesh associated with letter/text
				// ----------------------------------------------------------			
				Mesh mesh = new Mesh ();
				TTFTextInternal.Engine.BuildMesh (ref mesh, l, tm, out adv);
				Bounds b = mesh.bounds;
				b.center = b.center + pos;
				TTFTextInternal.Utilities.MergeBounds (ref bounds, b);				

				
				
				// --------------------------------------------------------------------------
				// set up some metadata so that the script attached to the letters may update
				// --------------------------------------------------------------------------
#if TTFTEXT_LITE
			if (tm.DemoMode) {
#endif				

				TTFSubtext st = go.GetComponent<TTFSubtext> ();
				if (st == null) {
					st = go.AddComponent<TTFSubtext> ();
				}
			
#if !TTFTEXT_LITE				
				st.Layout = l;
#endif				
				st.Text = l.line;
				st.LineNo = l.lineno;
				st.SequenceNo = idx + num;
				st.Advance = adv;
#if TTFTEXT_LITE
			}
#endif				
				
				
				
				// ---------------------------------------------------------------------
				//
				// IF A SPECIAL TEXTURE IS AFFECTED TO THIS CHARACTER THIS IS THE MOMENT
				//
				// ---------------------------------------------------------------------
				if (l.line.Length >= 1) {					
					if (((l.charmetadata [0] as TextureElement) != null)) {
						TextureElement tel = (l.charmetadata [0] as TextureElement);
						Material m = tel.material;
						Material [] mx = new Material[1];
						
						if (m == null) {
							//m=new Material(Shader.Find("GUI/Text Shader"));
							m = new Material (Shader.Find ("Self-Illumin/Diffuse"));
							m.name = "[generated material for text]";
							m.mainTexture = tel.texture;
						}

						mx [0] = m;
						go.renderer.sharedMaterials = mx;
							
						TTFTextReleaseTempResources rmod = go.GetComponent<TTFTextReleaseTempResources> ();
						if (rmod == null) {
							rmod = go.AddComponent<TTFTextReleaseTempResources> ();
						}
						
						if ((tel.material == null) && (tel.shouldReleaseMaterial)) {
							rmod.material = m;
						}
						if (tel.shouldReleaseTexture) {
							rmod.texture = tel.texture;
							
						}
					} else {
				
						int cmo = l.GetCharStyle (0).MaterialOffset;
						if (cmo != 0) {
							//Debug.Log(cmo);
							if (go.renderer != null) {
								if (go.renderer.sharedMaterials != null) {
									int ml = go.renderer.sharedMaterials.Length;
									int tml = 1;
									if (l.GetCharStyle (0).SplitSides) {
										tml = 3;
										TTFText.ExtrusionModeEnum em = l.GetCharStyle (0).ExtrusionMode;
										if (em == TTFText.ExtrusionModeEnum.None) {
											tml = 1;
											if (l.GetCharStyle (0).BackFace) {
												tml += 1;
											}

										}
										if (em == TTFText.ExtrusionModeEnum.Pipe) {
											tml = 1;
										}
									}
									int mo = ((cmo % ml) + ml) % ml;
									Material [] omx = go.renderer.sharedMaterials;
									Material [] nmx = new Material[tml];
									//Debug.Log(mo);
									for (int i=0; i<tml; i++) {
										nmx [i] = omx [(i + mo) % ml];
									}
									go.renderer.sharedMaterial = nmx [0];
									//go.renderer.sharedMaterials=new Material[0] {nmx[0]};
									//go.renderer.
									go.renderer.sharedMaterials = nmx;
									
								}
							}
						}
					
					}

				}	
			
				//
				// time to update every one
				//
				UpdateComponentsWithNewMesh (go, mesh);
				
				
				
				pos += l.advance;
				num++;
				yield return bounds;
			}
		}