Esempio n. 1
0
 public override void Draw(float deltaTime, HtmlLink link, object userData)
 {
     if (!offsetApplied)
     {
         compiled.Offset(Rect.X, Rect.Y);
         offsetApplied = true;
     }
     compiled.Draw(deltaTime, userData);
 }
Esempio n. 2
0
 public override void Draw(float deltaTime, HtmlLink link, object userData)
 {
     HtDevice device = HtEngine.Device;
     if (0 != (this.Deco & DrawTextDeco.Underline))
     {
         //device.FillRect(new HtRect(Rect.X, Rect.Bottom, DecoStop ? Rect.Width : this.TotalWidth, 1), this.Color, userData);
         this.Text = "[u]" + this.Text + "[/u]"; //L.DF
     }
     if (0 != (this.Deco & DrawTextDeco.Strike))
     {
         device.FillRect(new HtRect(Rect.X, Rect.Bottom - Rect.Height / 2, DecoStop ? Rect.Width : this.TotalWidth, 1), this.Color, userData);
     }
     this.Font.Draw(this.Span, this.Id, this.Rect, this.Color, this.Text, false, Core.DrawTextEffect.None, HtColor.white, 0, link, userData);
 }
Esempio n. 3
0
		public void Parse(IEnumerator<HtmlChunk> htmlChunks, int viewportWidth, string id = null, HtFont font = null, HtColor color = default(HtColor), TextAlign align = TextAlign.Left, VertAlign valign = VertAlign.Bottom)
		{
			this.Clear();
			var defaultFont = HtEngine.Device.LoadFont(HtEngine.DefaultFontFace, HtEngine.DefaultFontSize, false, false, 0, 0);
			font = font == null ? defaultFont : font;
			color = (color.R == 0 && color.G == 0 && color.B == 0 && color.A == 0) ? HtEngine.DefaultColor : color;
			//string id = null;
			//var align = TextAlign.Left;
			//var valign = VertAlign.Bottom;
			DrawTextDeco deco = DrawTextDeco.None;
			DrawTextEffect effect = DrawTextEffect.None;
			HtColor effectColor = HtEngine.DefaultColor;
			int effectAmount = 1;
			HtmlLink currentLink = null;
			bool prevIsWord = false;

			Stack<HtSpan> spanStack = new Stack<HtSpan>();	//top item is current span
			spanStack.Push(null);

			DeviceChunkLine currLine = null;
			DeviceChunkDrawText lastTextChunk = null;

			//for (int i = 0; i < htmlChunks.Count; i++)
			while (htmlChunks.MoveNext())
			{
				HtmlChunk htmlChunk = htmlChunks.Current;

				var word = htmlChunk as HtmlChunkWord;
				if (word != null)
				{
					if (currLine == null)
					{
						currLine = this.NewLine(null, viewportWidth, align, valign);
					}

					if (effect == DrawTextEffect.None)
					{
						lastTextChunk = AcquireDeviceChunkDrawText(
							spanStack.Peek(),
							id,
							word.Text,
							font,
							color,
							deco,
							lastTextChunk != null && lastTextChunk.Deco != deco,
							prevIsWord);
					}
					else
					{
						lastTextChunk = AcquireDeviceChunkDrawTextEffect(
							spanStack.Peek(),
							id,
							word.Text,
							font,
							color,
							deco,
							lastTextChunk != null && lastTextChunk.Deco != deco,
							effect,
							effectAmount,
							effectColor,
							prevIsWord);
					}

					if (currLine.AddChunk(lastTextChunk, prevIsWord))
					{
						if (currentLink != null && !this.Links.ContainsKey(lastTextChunk))
							this.Links.Add(lastTextChunk, currentLink);
					}
					else
					{

						//prevIsWord = true;	//why? AddChunk return false means a soft line break is needed
						//currLine.IsFull = true;
						string lastText = lastTextChunk.Text;
                        lastTextChunk.Dispose();
                        lastTextChunk = null;
                        bool decoStop = lastTextChunk != null && lastTextChunk.Deco != deco;
                        //Modify dfn.li                                               
                        //if (!currLine.IsFull)
                        {
                            var prevWidth = currLine.PrevChunkWidth();
                            var avaWidth = currLine.AvailWidth;
                            string sFix = "";
                            int nPos = 0;
                            for (nPos=0; nPos < lastText.Length; ++nPos )
                            {
                                char ch = lastText[nPos];
                                var len = font.Measure(ch.ToString()).Width;
                                if (prevWidth + len > viewportWidth)
                                {
                                    break;
                                }
                                else
                                {
                                    sFix = sFix + ch;
                                    prevWidth += len;
                                }
                            }
                            //补全上一行
                            if (!string.IsNullOrEmpty(sFix))
                            {
                                DeviceChunkDrawText tmpTextChunk;
                                if (effect == DrawTextEffect.None)
                                {
                                    tmpTextChunk = AcquireDeviceChunkDrawText(
                                        spanStack.Peek(),
                                        id,
                                        sFix,
                                        font,
                                        color,
                                        deco,
                                        lastTextChunk != null && lastTextChunk.Deco != deco,
                                        prevIsWord);
                                }
                                else
                                {
                                    tmpTextChunk = AcquireDeviceChunkDrawTextEffect(
                                        spanStack.Peek(),
                                        id,
                                        sFix,
                                        font,
                                        color,
                                        deco,
                                        lastTextChunk != null && lastTextChunk.Deco != deco,
                                        effect,
                                        effectAmount,
                                        effectColor,
                                        prevIsWord);
                                }
                                if (currLine.AddChunk(tmpTextChunk, prevIsWord, false))
                                {
                                    if (currentLink != null && !this.Links.ContainsKey(tmpTextChunk))
                                        this.Links.Add(tmpTextChunk, currentLink);
                                }
                                else
                                {
                                    tmpTextChunk.Dispose();
                                    tmpTextChunk = null;
                                }
                            }

                            lastText = lastText.Substring(nPos);
                            //currLine.IsFull = true; 
                        }
                        //Modify End
                        
						// find prefix ascii string.
						//string prefixAsciiText = null;
						int pos = 0;
						//for (pos = 0; pos < lastText.Length; ++pos) {
						//  char ch = lastText[pos];
						//  if (ch > 255 || ch == ' ') {
						//    prefixAsciiText = lastText.Substring(0, pos);
						//    break;
						//  }
						//}
						//if (prefixAsciiText != null) {
						//  DeviceChunkDrawText prefixAsciiTextChunk;
						//  if (effect == DrawTextEffect.None) {
						//    prefixAsciiTextChunk = AcquireDeviceChunkDrawText(
						//      id,
						//      prefixAsciiText,
						//      font,
						//      color,
						//      deco,
						//      decoStop,
						//      prevIsWord);
						//  } else {
						//    prefixAsciiTextChunk = AcquireDeviceChunkDrawTextEffect(
						//      id,
						//      prefixAsciiText,
						//      font,
						//      color,
						//      deco,
						//      decoStop,
						//      effect,
						//      effectAmount,
						//      effectColor,
						//      prevIsWord);
						//  }
						//  if (currLine.AddChunk(prefixAsciiTextChunk, prevIsWord)) {
						//    if (currentLink != null && !this.Links.ContainsKey(prefixAsciiTextChunk))
						//      this.Links.Add(prefixAsciiTextChunk, currentLink);
						//    lastText = lastText.Substring(pos);
						//    decoStop = false;
						//  }
						//}
						//// reset the pos.
						//pos = 0;

						// add multi-lines.
						int remainingWidth = viewportWidth;

						for (; pos < lastText.Length; )
						{
							char ch = lastText[pos];
							remainingWidth -= font.Measure(ch.ToString()).Width;
							if (remainingWidth < 0)
							{
								string tmpText = lastText.Substring(0, pos);
								DeviceChunkDrawText tmpTextChunk;
								if (effect == DrawTextEffect.None)
								{
									tmpTextChunk = AcquireDeviceChunkDrawText(
										spanStack.Peek(),
										id,
										tmpText,
										font,
										color,
										deco,
										decoStop,
										prevIsWord);
								}
								else
								{
									tmpTextChunk = AcquireDeviceChunkDrawTextEffect(
										spanStack.Peek(),
										id,
										tmpText,
										font,
										color,
										deco,
										decoStop,
										effect,
										effectAmount,
										effectColor,
										prevIsWord);
								}
								currLine = this.NewLine(currLine, viewportWidth, align, valign);
								if (currLine.AddChunk(tmpTextChunk, prevIsWord,false))
								{
									if (currentLink != null && !this.Links.ContainsKey(tmpTextChunk))
										this.Links.Add(tmpTextChunk, currentLink);
								}
								else
								{
									tmpTextChunk.Dispose();
									tmpTextChunk = null;
								}
								lastText = lastText.Substring(pos);
								pos = 0;
								remainingWidth = viewportWidth;
							}
							else
							{
								++pos;
							}
						}

						// add last line.
						if (!string.IsNullOrEmpty(lastText))
						{
							if (effect == DrawTextEffect.None)
							{
								lastTextChunk = AcquireDeviceChunkDrawText(
									spanStack.Peek(),
									id,
									lastText,
									font,
									color,
									deco,
									decoStop,
									prevIsWord);
							}
							else
							{
								lastTextChunk = AcquireDeviceChunkDrawTextEffect(
									spanStack.Peek(),
									id,
									lastText,
									font,
									color,
									deco,
									decoStop,
									effect,
									effectAmount,
									effectColor,
									prevIsWord);
							}

							currLine = this.NewLine(currLine, viewportWidth, align, valign);
							if (currLine.AddChunk(lastTextChunk, prevIsWord,false))
							{
								if (currentLink != null && !this.Links.ContainsKey(lastTextChunk))
									this.Links.Add(lastTextChunk, currentLink);
							}
							else
							{
								lastTextChunk.Dispose();
								lastTextChunk = null;
							}
						}
					}
					prevIsWord = true;
				}
				else
				{
					prevIsWord = false;
				}

				var tag = htmlChunk as HtmlChunkTag;
				if (tag != null)
				{
					switch (tag.Tag)
					{
						case "spin":
							if (tag.IsSingle)
							{
								// do nothing
							}
							else if (tag.IsClosing)
							{
								id = null;
								this.FinishLine(currLine, align, valign);
								return; // return control to parent
							}
							else
							{
								id = tag.GetAttr("id");
								ExctractAligns(tag, ref align, ref valign);
								var compiled = (DeviceChunkDrawCompiled)OP_DeviceChunkDrawCompiled.Acquire();
								compiled.Font = font;
								var scompiledWidth = tag.GetAttr("width") ?? "0";
								var compiledWidth = 0;
								if (!int.TryParse(scompiledWidth, out compiledWidth)) compiledWidth = 0;
								if (compiledWidth == 0)
								{
									compiledWidth = currLine == null ? viewportWidth : currLine.AvailWidth - font.WhiteSize;
								}
								if (compiledWidth > 0)
								{
									if (compiledWidth > viewportWidth) compiledWidth = viewportWidth;
									compiled.Parse(htmlChunks, compiledWidth, id, font, color, align, valign);
									compiled.MeasureSize();
									if (currLine == null)
									{
										currLine = this.NewLine(null, viewportWidth, align, valign);
									}

									if (!currLine.AddChunk(compiled, prevIsWord))
									{
										currLine.IsFull = true;
										currLine = this.NewLine(currLine, viewportWidth, align, valign);
										if (!currLine.AddChunk(compiled, prevIsWord))
										{
											HtEngine.Log(HtLogLevel.Error, "Could not fit spin into line. Word is too big: {0}", compiled);
											compiled.Dispose();
											compiled = null;
										}
									}
								}
								else
								{
									HtEngine.Log(HtLogLevel.Warning, "spin width is not given");
								}
							}
							break;
						case "effect":
							if (tag.IsSingle)
							{
								// do nothing
							}
							else if (tag.IsClosing)
							{
								effect = DrawTextEffect.None;
							}
							else
							{
								var name = tag.GetAttr("name") ?? "outline";
								switch (name)
								{
									case "shadow":
										effect = DrawTextEffect.Shadow;
										effectAmount = 1;
										effectColor = HtColor.RGBA(0, 0, 0, 80);
										break;
									case "outline":
										effect = DrawTextEffect.Outline;
										effectAmount = 1;
										effectColor = HtColor.RGBA(0xFF, 0xFF, 0xFF, 80);
										break;
								}
								var amount = tag.GetAttr("amount");
								if (amount != null)
								{
									if (!int.TryParse(amount, out effectAmount))
									{
										HtEngine.Log(HtLogLevel.Error, "Invalid numeric value: " + amount);
									}
								}
								var colors = tag.GetAttr("color");
								if (colors != null) effectColor = HtColor.Parse(colors);
							}
							break;
						case "u":
							if (tag.IsSingle)
							{
								// do nothing
							}
							else if (tag.IsClosing)
							{
								deco &= ~DrawTextDeco.Underline;
							}
							else
							{
								deco |= DrawTextDeco.Underline;
							}
							break;
						case "s":
						case "strike":
							if (tag.IsSingle)
							{
								// do nothing
							}
							else if (tag.IsClosing)
							{
								deco &= ~DrawTextDeco.Strike;
							}
							else
							{
								deco |= DrawTextDeco.Strike;
							}
							break;
						case "code":
							if (tag.IsSingle)
							{
								// do nothing
							}
							else if (tag.IsClosing)
							{
								font = this.fontStack.Count > 0 ? this.fontStack.Pop() : defaultFont;
							}
							else
							{
								this.fontStack.Push(font);

								//const string fontName = "code";
								const string fontName = "default";
								int fontSize = font.Size;
								bool fontBold = font.Bold;
								bool fontItal = font.Italic;
								int spacingX = font.SpacingX;
								int spacingY = font.SpacingY;

								font = HtEngine.Device.LoadFont(fontName, fontSize, fontBold, fontItal, spacingX, spacingY);
							}
							break;

						case "b":
							if (tag.IsSingle)
							{
								// do nothing
							}
							else if (tag.IsClosing)
							{
								font = this.fontStack.Count > 0 ? this.fontStack.Pop() : defaultFont;
							}
							else
							{
								this.fontStack.Push(font);

								string fontName = font.Face;
								int fontSize = font.Size;
								const bool fontBold = true;
								bool fontItal = font.Italic;
								int spacingX = font.SpacingX;
								int spacingY = font.SpacingY;

								font = HtEngine.Device.LoadFont(fontName, fontSize, fontBold, fontItal, spacingX, spacingY);
							}
							break;
						case "i":
							if (tag.IsSingle)
							{
								// do nothing
							}
							else if (tag.IsClosing)
							{
								font = this.fontStack.Count > 0 ? this.fontStack.Pop() : defaultFont;
							}
							else
							{
								this.fontStack.Push(font);

								string fontName = font.Face;
								int fontSize = font.Size;
								bool fontBold = font.Bold;
								const bool fontItal = true;
								int spacingX = font.SpacingX;
								int spacingY = font.SpacingY;

								font = HtEngine.Device.LoadFont(fontName, fontSize, fontBold, fontItal, spacingX, spacingY);
							}
							break;
						case "a":
							if (tag.IsSingle)
							{
								// do nothing
							}
							else if (tag.IsClosing)
							{
								id = null;
								//if (this.colorStack.Count>0)		//不添加颜色。需要颜色时从外部指定
								//    color = this.colorStack.Pop();
								currentLink = null;
							}
							else
							{
								id = tag.GetAttr("id");
								currentLink = new HtmlLink();
								currentLink.linkID = linkID;
								currentLink.linkText = tag.GetAttr("href");
								++linkID;
								//this.colorStack.Push(color);		//不添加颜色。需要颜色时从外部指定
								//color = HtEngine.DefaultLinkColor;
							}
							break;

						case "font":
							if (tag.IsSingle)
							{
								// do nothing
							}
							else if (tag.IsClosing)
							{
								font = this.fontStack.Count > 0 ? this.fontStack.Pop() : defaultFont;
								color = this.colorStack.Count > 0 ? this.colorStack.Pop() : HtEngine.DefaultColor;
							}
							else
							{
								this.fontStack.Push(font);
								this.colorStack.Push(color);

								string fontName = tag.GetAttr("face") ?? font.Face;
								string fontSizeS = tag.GetAttr("size");
								string fontSpaceXS = tag.GetAttr("spacing-x");
								string fontSpaceYS = tag.GetAttr("spacing-y");
								int fontSize;
								if (fontSizeS == null || !int.TryParse(fontSizeS, out fontSize)) fontSize = font.Size;
								int fontSpaceX;
								if (fontSpaceXS == null || !int.TryParse(fontSpaceXS, out fontSpaceX)) fontSpaceX = 0;
								int fontSpaceY;
								if (fontSpaceYS == null || !int.TryParse(fontSpaceYS, out fontSpaceY)) fontSpaceY = 0;
								bool fontBold = font.Bold;
								bool fontItal = font.Italic;

								font = HtEngine.Device.LoadFont(fontName, fontSize, fontBold, fontItal, fontSpaceX, fontSpaceY);

								color = HtColor.Parse(tag.GetAttr("color"), color);
							}
							break;
						case "br":
							currLine = this.NewLine(currLine, viewportWidth, align, valign);
							currLine.Height = font.LineSpacing;
							break;
						case "img":
							if (tag.IsClosing)
							{
								// ignore closing tags
							}
							else
							{
								var src = tag.GetAttr("src");
								var widthS = tag.GetAttr("width");
								var heightS = tag.GetAttr("height");
								var fpsS = tag.GetAttr("fps");
								var imgId = tag.GetAttr("id");
                                var snapS = tag.GetAttr("snap");

                                int w, h, fps;
                                bool snap;//true : 原像素,false:进行缩放
								if (widthS == null || !int.TryParse(widthS, out w)) w = -1;
								if (heightS == null || !int.TryParse(heightS, out h)) h = -1;
								if (fpsS == null || !int.TryParse(fpsS, out fps)) fps = -1;
                                if (snapS == null || !bool.TryParse(snapS, out snap)) snap = true;
								//var img = HtEngine.Device.LoadImage(src, fps);
                                var img = HtEngine.Device.LoadImageEx(src, fps, snap, w, h);
								if (w < 0) w = img.Width;
								if (h < 0) h = img.Height;
								var dChunk = (DeviceChunkDrawImage)OP_DeviceChunkDrawImage.Acquire();
								if (currLine == null)
									currLine = this.NewLine(null, viewportWidth, align, valign);
								dChunk.Image = img;
                                dChunk.Rect.Width = snap ? img.Width : w;
								dChunk.Rect.Height = snap ? img.Height : h;
								dChunk.Font = font; // for whitespace measure
								dChunk.Id = imgId;
								//HtEngine.Log(HtLogLevel.Debug, "Adding image w={0} h={1}",dChunk.Width,dChunk.Height);

								if (currLine.AddChunk(dChunk, prevIsWord))
								{
									if (currentLink != null && !this.Links.ContainsKey(dChunk))
										this.Links.Add(dChunk, currentLink);
								}
								else
								{
									currLine.IsFull = true;
									currLine = this.NewLine(currLine, viewportWidth, align, valign);
									if (currLine.AddChunk(dChunk, prevIsWord))
									{
										if (currentLink != null && !this.Links.ContainsKey(dChunk))
											this.Links.Add(dChunk, currentLink);
									}
									else
									{
										HtEngine.Log(HtLogLevel.Error, "Could not fit image into line. Image is too big: {0}", dChunk);
										dChunk.Dispose();
										dChunk = null;
									}
								}
							}
							break;
						case "gameobj":
							if (tag.IsClosing)
							{
								// ignore closing tags
							}
							else
							{
								var command = tag.GetAttr("command");
								var boxcollider = tag.GetAttr("boxcollider");
								var componentname = tag.GetAttr("componentname");
								var param = tag.GetAttr("param");
								var width = tag.GetAttr("width");
								var height = tag.GetAttr("height");
								var objid = tag.GetAttr("id");
								int w, h;
								bool b;
								if (width == null || !int.TryParse(width, out w)) w = 1;
								if (height == null || !int.TryParse(height, out h)) h = 1;
								if (boxcollider == null || !bool.TryParse(boxcollider, out b)) b = false;

								var dChunk = (DeviceChunkDrawGameObject)OP_DeviceChunkDrawGameObject.Acquire();
								if (currLine == null)
									currLine = this.NewLine(null, viewportWidth, align, valign);
								var go = new HTMLEngine.NGUI.NGUIGameObject(command, b, componentname, param);
								dChunk.gameobject = go;
								dChunk.Rect.Width = w;
								dChunk.Rect.Height = h;
								dChunk.Font = font; // for whitespace measure
								dChunk.Id = objid;
								//HtEngine.Log(HtLogLevel.Debug, "Adding image w={0} h={1}",dChunk.Width,dChunk.Height);

								if (currLine.AddChunk(dChunk, prevIsWord))
								{
									if (currentLink != null && !this.Links.ContainsKey(dChunk))
										this.Links.Add(dChunk, currentLink);
								}
								else
								{
									currLine.IsFull = true;
									currLine = this.NewLine(currLine, viewportWidth, align, valign);
									if (currLine.AddChunk(dChunk, prevIsWord))
									{
										if (currentLink != null && !this.Links.ContainsKey(dChunk))
											this.Links.Add(dChunk, currentLink);
									}
									else
									{
										HtEngine.Log(HtLogLevel.Error, "Could not fit gameobj into line. gameobj is too big: {0}", dChunk);
										dChunk.Dispose();
										dChunk = null;
									}
								}
							}
							break;
						case "p":
							if (tag.IsClosing)
							{
								id = null;
							}
							else
							{
								id = tag.GetAttr("id");
								currLine = this.NewLine(currLine, viewportWidth, align, valign);

								ExctractAligns(tag, ref align, ref valign);
							}

							break;
						case "span":
							if (tag.IsClosing)
							{
								spanStack.Pop();
								id = null;
							}
							else
							{
								HtSpan currentSpan = spanStack.Peek();
								HtSpan newSpan = new HtSpan(currentSpan, tag.GetAllAttributes());
								spanStack.Push(newSpan);

								id = tag.GetAttr("id");
								//currLine = this.NewLine(currLine, viewportWidth, align, valign);

								ExctractAligns(tag, ref align, ref valign);
							}

							break;
						default:
							HtEngine.Log(HtLogLevel.Error, "Unsupported html tag {0}", tag);
							break;
					}
				}
			}

			// align last line
			this.FinishLine(currLine, align, valign);
		}
Esempio n. 4
0
		public override void Draw(float deltaTime, HtmlLink link, object userData)
		{
			gameobject.Draw(this.Id, this.Rect, userData);
		}
Esempio n. 5
0
 /// <summary>
 /// Draws chunk
 /// </summary>
 /// <param name="deltaTime">delta time</param>
 /// <param name="linkText">link text</param>
 /// <param name="userData">user data</param>
 public abstract void Draw(float deltaTime, HtmlLink link, object userData);
Esempio n. 6
0
 public override void Draw(float deltaTime, HtmlLink link, object userData)
 {
     Image.Draw(this.Id, this.Rect, this.Color, link, userData);
 }