ソースを参照

Implement HTML alignment

Bepis 6 年 前
コミット
ba6d1e670e

+ 38 - 6
NTERA/Console/HTMLParser.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Text.RegularExpressions;
 using System.Xml.Linq;
 using MinorShift.Emuera.Content;
 using NTERA.Console;
@@ -10,21 +11,35 @@ namespace NTERA.Interop
 	{
 		public static IEnumerable<IRenderItem> ParseHtml(string html)
 		{
-			return ParseHtml_Internal(XElement.Parse(html));
+			var parent = new XElement("parent");
+
+			string fixedHtml = Regex.Replace(html, @"<img([^\/]*?)>", "<img$1 />");
+
+			parent.Add(XElement.Parse(fixedHtml));
+
+			return ParseHtml_Internal(parent, HtmlStyle.Default);
 		}
 
-		private static IEnumerable<IRenderItem> ParseHtml_Internal(XElement xmlNode)
+		private static IEnumerable<IRenderItem> ParseHtml_Internal(XElement xmlNode, HtmlStyle style)
 		{
 			List<IRenderItem> renderItems = new List<IRenderItem>();
+			HtmlStyle localStyle = (HtmlStyle)style.Clone();
 
-			foreach (var node in xmlNode.Descendants())
+			foreach (var node in xmlNode.Elements())
 			{
 				switch (node.Name.LocalName)
 				{
 					case "p":
-						renderItems.AddRange(ParseHtml_Internal(node));
+						string alignment = node.Attribute("align")?.Value;
+
+						if (alignment != null)
+							localStyle.Alignment = (DisplayLineAlignment)Enum.Parse(typeof(DisplayLineAlignment), alignment.ToUpper());
+
+						renderItems.AddRange(ParseHtml_Internal(node, localStyle));
 						break;
 					case "img":
+
+
 						string src = node.Attribute("src")?.Value;
 
 						if (src == null)
@@ -32,16 +47,33 @@ namespace NTERA.Interop
 
 						var image = AppContents.GetContent<CroppedImage>(src);
 
-						renderItems.Add(new ImageRenderItem(image.BaseImage.Bitmap, image.Rectangle));
+						renderItems.Add(new ImageRenderItem(image.BaseImage.Bitmap, image.Rectangle, alignment: localStyle.Alignment));
 
 						break;
 					default:
-						renderItems.Add(new TextRenderItem(node.ToString()));
+						renderItems.Add(new TextRenderItem(node.ToString(), alignment: localStyle.Alignment));
 						break;
 				}
 			}
 
 			return renderItems;
 		}
+
+		private class HtmlStyle : ICloneable
+		{
+			public static HtmlStyle Default => new HtmlStyle();
+
+			public DisplayLineAlignment Alignment = DisplayLineAlignment.LEFT;
+
+			public HtmlStyle()
+			{
+
+			}
+
+			public object Clone()
+			{
+				return MemberwiseClone();
+			}
+		}
 	}
 }

+ 32 - 14
NTERA/Console/RenderItem/ImageRenderItem.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Drawing;
 using System.Drawing.Imaging;
+using NTERA.Interop;
 
 namespace NTERA.Console
 {
@@ -9,29 +10,46 @@ namespace NTERA.Console
 	{
 		public Bitmap Image { get; set; }
 
-		public ImageRenderItem(Bitmap bitmap)
-		{
-			Image = bitmap;
-		}
+		public DisplayLineAlignment Alignment;
 
-		public ImageRenderItem(Bitmap original, Rectangle cropRectangle)
+		public ImageRenderItem(Bitmap bitmap, Rectangle? cropRectangle = null, DisplayLineAlignment alignment = DisplayLineAlignment.LEFT)
 		{
-			Image = new Bitmap(original.Width, cropRectangle.Height, PixelFormat.Format32bppArgb);
+			if (cropRectangle != null)
+			{
+				Image = new Bitmap(bitmap.Width, cropRectangle.Value.Height, PixelFormat.Format32bppArgb);
 
-			using (Graphics g = Graphics.FromImage(Image))
+				using (Graphics g = Graphics.FromImage(Image))
+				{
+					g.DrawImage(bitmap, new Rectangle(0, 0, bitmap.Width, cropRectangle.Value.Height), cropRectangle.Value, GraphicsUnit.Pixel);
+				}
+			}
+			else
 			{
-				g.DrawImage(original, new Rectangle(0, 0, original.Width, cropRectangle.Height), cropRectangle, GraphicsUnit.Pixel);
+				Image = bitmap;
 			}
-		}
-
-		public ImageRenderItem(string imagePath)
-		{
-			Image = new Bitmap(imagePath);
+			
+			Alignment = alignment;
 		}
 
 		public override void Render(Graphics graphics, Rectangle renderArea, Point mousePointer)
 		{
-			graphics.DrawImage(Image, new Rectangle(0, renderArea.Y, Image.Width, renderArea.Height));
+			int x;
+
+			switch (Alignment)
+			{
+				default:
+				case DisplayLineAlignment.LEFT:
+					x = 0;
+					break;
+				case DisplayLineAlignment.CENTER:
+					x = (renderArea.Width - Image.Width) / 2;
+					break;
+				case DisplayLineAlignment.RIGHT:
+					x = renderArea.Width - Image.Width;
+					break;
+			}
+
+			graphics.DrawImage(Image, new Rectangle(x, renderArea.Y, Image.Width, renderArea.Height));
 		}
 
 		public static List<ImageRenderItem> CreateFromLargeBitmap(Bitmap original, int lineHeight)

+ 26 - 2
NTERA/Console/RenderItem/TextRenderItem.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Drawing;
+using NTERA.Interop;
 
 namespace NTERA.Console
 {
@@ -12,14 +13,37 @@ namespace NTERA.Console
 
 		public string Text { get; set; }
 
-		public TextRenderItem(string text)
+		public DisplayLineAlignment Alignment;
+
+
+		public TextRenderItem(string text, DisplayLineAlignment alignment = DisplayLineAlignment.LEFT)
 		{
 			Text = text;
+			Alignment = alignment;
 		}
+		
 
 		public override void Render(Graphics graphics, Rectangle renderArea, Point mousePointer)
 		{
-			graphics.DrawString(Text, Font, TextBrush, renderArea);
+			int width = (int)graphics.MeasureString(Text, Font).Width;
+
+			int x;
+
+			switch (Alignment)
+			{
+				default:
+				case DisplayLineAlignment.LEFT:
+					x = 0;
+					break;
+				case DisplayLineAlignment.CENTER:
+					x = (renderArea.Width - width) / 2;
+					break;
+				case DisplayLineAlignment.RIGHT:
+					x = renderArea.Width - width;
+					break;
+			}
+
+			graphics.DrawString(Text, Font, TextBrush, x, renderArea.Y);
 		}
 
 		public static List<TextRenderItem> CreateFromLinedText(string text)