コード例 #1
0
ファイル: TextWidget.cs プロジェクト: jeske/agg-sharp
        public TextWidget(string text, double x = 0, double y = 0, double pointSize = 12, Justification justification = Justification.Left, RGBA_Bytes textColor = new RGBA_Bytes(), bool ellipsisIfClipped = true, bool underline = false, RGBA_Bytes backgroundColor = new RGBA_Bytes())
        {
            Selectable = false;
            DoubleBuffer = DoubleBufferDefault;
            AutoExpandBoundsToText = false;
            EllipsisIfClipped = ellipsisIfClipped; 
            OriginRelativeParent = new Vector2(x, y);
            this.textColor = textColor;
            if (this.textColor.Alpha0To255 == 0)
            {
                // we assume it is the default if alpha 0.  Also there is no reason to make a text color of this as it will draw nothing.
                this.textColor = RGBA_Bytes.Black;
            }
            if (backgroundColor.Alpha0To255 != 0)
            {
                BackgroundColor = backgroundColor;
            }

            base.Text = text;
            StyledTypeFace typeFaceStyle = new StyledTypeFace(LiberationSansFont.Instance, pointSize, underline);
            printer = new TypeFacePrinter(text, typeFaceStyle, justification: justification);

            LocalBounds = printer.LocalBounds;

            MinimumSize = new Vector2(LocalBounds.Width, LocalBounds.Height);
        }
コード例 #2
0
ファイル: TypeFacePrinter.cs プロジェクト: opencai/agg-sharp
 public TypeFacePrinter(String text, StyledTypeFace typeFaceStyle, Vector2 origin = new Vector2(), Justification justification = Justification.Left, Baseline baseline = Baseline.Text)
 {
     this.TypeFaceStyle = typeFaceStyle;
     this.text          = text;
     this.Justification = justification;
     this.Origin        = origin;
     this.Baseline      = baseline;
 }
コード例 #3
0
		public TypeFacePrinter(String text, StyledTypeFace typeFaceStyle, Vector2 origin = new Vector2(), Justification justification = Justification.Left, Baseline baseline = Baseline.Text)
		{
			this.TypeFaceStyle = typeFaceStyle;
			this.text = text;
			this.Justification = justification;
			this.Origin = origin;
			this.Baseline = baseline;
		}
コード例 #4
0
ファイル: blur.cs プロジェクト: glocklueng/agg-sharp
		public blur()
		{
			m_rbuf2 = new ImageBuffer();
			m_shape_bounds = new RectangleDouble();
			m_method = new RadioButtonGroup(new Vector2(10.0, 10.0), new Vector2(130.0, 60.0));
			m_radius = new Slider(new Vector2(130 + 10.0, 10.0 + 4.0), new Vector2(290, 8.0));
			m_shadow_ctrl = new PolygonEditWidget(4);
			m_channel_r = new CheckBox(10.0, 80.0, "Red");
			m_channel_g = new CheckBox(10.0, 95.0, "Green");
			m_channel_b = new CheckBox(10.0, 110.0, "Blue");
			m_FlattenCurves = new CheckBox(10, 315, "Convert And Flatten Curves");
			m_FlattenCurves.Checked = true;

			AddChild(m_method);
			m_method.AddRadioButton("Stack Blur");
			m_method.AddRadioButton("Recursive Blur");
			m_method.AddRadioButton("Channels");
			m_method.SelectedIndex = 1;

			AddChild(m_radius);
			m_radius.SetRange(0.0, 40.0);
			m_radius.Value = 15.0;
			m_radius.Text = "Blur Radius={0:F2}";

			AddChild(m_shadow_ctrl);

			AddChild(m_channel_r);
			AddChild(m_channel_g);
			AddChild(m_channel_b);
			AddChild(m_FlattenCurves);
			m_channel_g.Checked = true;

			m_sl = new ScanlineCachePacked8();

			StyledTypeFace typeFaceForLargeA = new StyledTypeFace(LiberationSansFont.Instance, 300, flatenCurves: false);
			m_path = typeFaceForLargeA.GetGlyphForCharacter('a');

			Affine shape_mtx = Affine.NewIdentity();
			shape_mtx *= Affine.NewTranslation(150, 100);
			m_path = new VertexSourceApplyTransform(m_path, shape_mtx);
			m_shape = new FlattenCurves(m_path);

			bounding_rect.bounding_rect_single(m_shape, 0, ref m_shape_bounds);

			m_shadow_ctrl.SetXN(0, m_shape_bounds.Left);
			m_shadow_ctrl.SetYN(0, m_shape_bounds.Bottom);
			m_shadow_ctrl.SetXN(1, m_shape_bounds.Right);
			m_shadow_ctrl.SetYN(1, m_shape_bounds.Bottom);
			m_shadow_ctrl.SetXN(2, m_shape_bounds.Right);
			m_shadow_ctrl.SetYN(2, m_shape_bounds.Top);
			m_shadow_ctrl.SetXN(3, m_shape_bounds.Left);
			m_shadow_ctrl.SetYN(3, m_shape_bounds.Top);
			m_shadow_ctrl.line_color(new RGBA_Floats(0, 0.3, 0.5, 0.3));
		}
コード例 #5
0
ファイル: FontHinting.cs プロジェクト: glocklueng/agg-sharp
		public override void OnDraw(Graphics2D graphics2D)
		{
			GammaLookUpTable gamma = new GammaLookUpTable(gammaSlider.Value);
			IRecieveBlenderByte NormalBlender = new BlenderBGR();
			IRecieveBlenderByte GammaBlender = new BlenderGammaBGR(gamma);
			ImageBuffer rasterNormal = new ImageBuffer();
			rasterNormal.Attach(graphics2D.DestImage, NormalBlender);
			ImageBuffer rasterGamma = new ImageBuffer();
			rasterGamma.Attach(graphics2D.DestImage, GammaBlender);
			ImageClippingProxy clippingProxyNormal = new ImageClippingProxy(rasterNormal);
			ImageClippingProxy clippingProxyGamma = new ImageClippingProxy(rasterGamma);

			clippingProxyNormal.clear(new RGBA_Floats(1, 1, 1));

			ScanlineRasterizer ras = new ScanlineRasterizer();
			scanline_unpacked_8 sl = new scanline_unpacked_8();

			int size_mul = (int)pixelSizeSlider.Value;

			renderer_enlarged ren_en = new renderer_enlarged(size_mul);

			StyledTypeFace type = new StyledTypeFace(LiberationSansFont.Instance, 12);
			IVertexSource character = type.GetGlyphForCharacter('E');
			character.rewind(0);
			ras.reset();
			ras.add_path(character);
			ren_en.RenderSolid(clippingProxyGamma, ras, sl, RGBA_Bytes.Black);

			ScanlineRenderer scanlineRenderer = new ScanlineRenderer();
			scanlineRenderer.RenderSolid(clippingProxyGamma, ras, sl, RGBA_Bytes.Black);

			ras.gamma(new gamma_none());

			PathStorage ps = new PathStorage();
			Stroke pg = new Stroke(ps);
			pg.width(2);

			DrawBigA(graphics2D);

			base.OnDraw(graphics2D);
		}
コード例 #6
0
ファイル: TextWrapping.cs プロジェクト: CNCBrasil/agg-sharp
		public EnglishTextWrapping(StyledTypeFace styledTypeFace)
			: base(styledTypeFace)
		{
		}
コード例 #7
0
ファイル: TextWrapping.cs プロジェクト: CNCBrasil/agg-sharp
		// you can't
		public TextWrapping(StyledTypeFace styledTypeFace)
		{
			this.styledTypeFace = styledTypeFace;
		}
コード例 #8
0
ファイル: TypeFace.cs プロジェクト: lalanikarim/agg-sharp
        public void ShowDebugInfo(Graphics2D graphics2D)
        {
            StyledTypeFace  typeFaceNameStyle = new StyledTypeFace(this, 30);
            TypeFacePrinter fontNamePrinter   = new TypeFacePrinter(this.fontFamily + " - 30 point", typeFaceNameStyle);

            RectangleDouble bounds           = typeFaceNameStyle.BoundingBoxInPixels;
            double          origX            = 10 - bounds.Left;
            double          x                = origX;
            double          y                = 10 - typeFaceNameStyle.DescentInPixels;
            int             width            = 50;
            Color           boundingBoxColor = new Color(0, 0, 0);
            Color           originColor      = new Color(0, 0, 0);
            Color           ascentColor      = new Color(255, 0, 0);
            Color           descentColor     = new Color(255, 0, 0);
            Color           xHeightColor     = new Color(12, 25, 200);
            Color           capHeightColor   = new Color(12, 25, 200);
            Color           underlineColor   = new Color(0, 150, 55);

            // the origin
            graphics2D.Line(x, y, x + width, y, originColor);

            graphics2D.Rectangle(x + bounds.Left, y + bounds.Bottom, x + bounds.Right, y + bounds.Top, boundingBoxColor);

            x += typeFaceNameStyle.BoundingBoxInPixels.Width * 1.5;

            width = width * 3;

            double temp = typeFaceNameStyle.AscentInPixels;

            graphics2D.Line(x, y + temp, x + width, y + temp, ascentColor);

            temp = typeFaceNameStyle.DescentInPixels;
            graphics2D.Line(x, y + temp, x + width, y + temp, descentColor);

            temp = typeFaceNameStyle.XHeightInPixels;
            graphics2D.Line(x, y + temp, x + width, y + temp, xHeightColor);

            temp = typeFaceNameStyle.CapHeightInPixels;
            graphics2D.Line(x, y + temp, x + width, y + temp, capHeightColor);

            temp = typeFaceNameStyle.UnderlinePositionInPixels;
            graphics2D.Line(x, y + temp, x + width, y + temp, underlineColor);

            Affine textTransform;

            textTransform  = Affine.NewIdentity();
            textTransform *= Affine.NewTranslation(10, origX);

            VertexSourceApplyTransform transformedText = new VertexSourceApplyTransform(textTransform);

            fontNamePrinter.Render(graphics2D, Color.Black, transformedText);

            graphics2D.Render(transformedText, Color.Black);

            // render the legend
            StyledTypeFace legendFont = new StyledTypeFace(this, 12);
            Vector2        textPos    = new Vector2(x + width / 2, y + typeFaceNameStyle.EmSizeInPixels * 1.5);

            graphics2D.Render(new TypeFacePrinter("Descent"), textPos, descentColor); textPos.Y     += legendFont.EmSizeInPixels;
            graphics2D.Render(new TypeFacePrinter("Underline"), textPos, underlineColor); textPos.Y += legendFont.EmSizeInPixels;
            graphics2D.Render(new TypeFacePrinter("X Height"), textPos, xHeightColor); textPos.Y    += legendFont.EmSizeInPixels;
            graphics2D.Render(new TypeFacePrinter("CapHeight"), textPos, capHeightColor); textPos.Y += legendFont.EmSizeInPixels;
            graphics2D.Render(new TypeFacePrinter("Ascent"), textPos, ascentColor); textPos.Y       += legendFont.EmSizeInPixels;
            graphics2D.Render(new TypeFacePrinter("Origin"), textPos, originColor); textPos.Y       += legendFont.EmSizeInPixels;
            graphics2D.Render(new TypeFacePrinter("Bounding Box"), textPos, boundingBoxColor);
        }
コード例 #9
0
		private void AddContent(HtmlParser htmlParser, string htmlContent)
		{
			ElementState elementState = htmlParser.CurrentElementState;
			string decodedHtml = HtmlParser.UrlDecode(htmlContent);
			switch (elementState.TypeName)
			{
				case "p":
					{
						elementsUnderConstruction.Push(new FlowLayoutWidget());
						elementsUnderConstruction.Peek().Name = "p";
						elementsUnderConstruction.Peek().HAnchor = HAnchor.ParentLeftRight;

						if (decodedHtml != null && decodedHtml != "")
						{
							WrappingTextWidget content = new WrappingTextWidget(decodedHtml, pointSize: elementState.PointSize, textColor: ActiveTheme.Instance.PrimaryTextColor);
							//content.VAnchor = VAnchor.ParentTop;
							elementsUnderConstruction.Peek().AddChild(content);
						}
					}
					break;

				case "div":
					{
						elementsUnderConstruction.Push(new FlowLayoutWidget());
						elementsUnderConstruction.Peek().Name = "div";

						if (decodedHtml != null && decodedHtml != "")
						{
							TextWidget content = new TextWidget(decodedHtml, pointSize: elementState.PointSize, textColor: ActiveTheme.Instance.PrimaryTextColor);
							elementsUnderConstruction.Peek().AddChild(content);
						}
					}
					break;

				case "!DOCTYPE":
					break;

				case "body":
					break;

				case "img":
					{
						ImageBuffer image = new ImageBuffer(elementState.SizeFixed.x, elementState.SizeFixed.y, 32, new BlenderBGRA());
						ImageWidget_AsyncLoadOnDraw imageWidget = new ImageWidget_AsyncLoadOnDraw(image, elementState.src);
						// put the image into the widget when it is done downloading.

						if (elementsUnderConstruction.Peek().Name == "a")
						{
							Button linkButton = new Button(0, 0, imageWidget);
							linkButton.Cursor = Cursors.Hand;
							linkButton.Click += (sender, mouseEvent) =>
							{
								MatterControlApplication.Instance.LaunchBrowser(elementState.Href);
							};
							elementsUnderConstruction.Peek().AddChild(linkButton);
						}
						else
						{
							elementsUnderConstruction.Peek().AddChild(imageWidget);
						}
					}
					break;

				case "a":
					{
						elementsUnderConstruction.Push(new FlowLayoutWidget());
						elementsUnderConstruction.Peek().Name = "a";

						if (decodedHtml != null && decodedHtml != "")
						{
							Button linkButton = linkButtonFactory.Generate(decodedHtml);
							StyledTypeFace styled = new StyledTypeFace(LiberationSansFont.Instance, elementState.PointSize);
							double descentInPixels = styled.DescentInPixels;
							linkButton.OriginRelativeParent = new VectorMath.Vector2(linkButton.OriginRelativeParent.x, linkButton.OriginRelativeParent.y + descentInPixels);
							linkButton.Click += (sender, mouseEvent) =>
							{
								MatterControlApplication.Instance.LaunchBrowser(elementState.Href);
							};
							elementsUnderConstruction.Peek().AddChild(linkButton);
						}
					}
					break;

				case "table":
					break;

				case "td":
				case "span":
					GuiWidget widgetToAdd;

					if (elementState.Classes.Contains("translate"))
					{
						decodedHtml = decodedHtml.Localize();
					}
					if (elementState.Classes.Contains("toUpper"))
					{
						decodedHtml = decodedHtml.ToUpper();
					}
					if (elementState.Classes.Contains("versionNumber"))
					{
						decodedHtml = VersionInfo.Instance.ReleaseVersion;
					}
					if (elementState.Classes.Contains("buildNumber"))
					{
						decodedHtml = VersionInfo.Instance.BuildVersion;
					}

					Button createdButton = null;
					if (elementState.Classes.Contains("centeredButton"))
					{
						createdButton = textImageButtonFactory.Generate(decodedHtml);
						widgetToAdd = createdButton;
					}
					else if (elementState.Classes.Contains("linkButton"))
					{
						double oldFontSize = linkButtonFactory.fontSize;
						linkButtonFactory.fontSize = elementState.PointSize;
						createdButton = linkButtonFactory.Generate(decodedHtml);
						StyledTypeFace styled = new StyledTypeFace(LiberationSansFont.Instance, elementState.PointSize);
						double descentInPixels = styled.DescentInPixels;
						createdButton.OriginRelativeParent = new VectorMath.Vector2(createdButton.OriginRelativeParent.x, createdButton.OriginRelativeParent.y + descentInPixels);
						widgetToAdd = createdButton;
						linkButtonFactory.fontSize = oldFontSize;
					}
					else
					{
						TextWidget content = new TextWidget(decodedHtml, pointSize: elementState.PointSize, textColor: ActiveTheme.Instance.PrimaryTextColor);
						widgetToAdd = content;
					}

					if (createdButton != null)
					{
						if (elementState.Id == "sendFeedback")
						{
							createdButton.Click += (sender, mouseEvent) => { ContactFormWindow.Open(); };
						}
						else if (elementState.Id == "clearCache")
						{
							createdButton.Click += (sender, mouseEvent) => { AboutWidget.DeleteCacheData(); };
						}
					}

					if (elementState.VerticalAlignment == ElementState.VerticalAlignType.top)
					{
						widgetToAdd.VAnchor = VAnchor.ParentTop;
					}

					elementsUnderConstruction.Peek().AddChild(widgetToAdd);
					break;

				case "tr":
					elementsUnderConstruction.Push(new FlowLayoutWidget());
					elementsUnderConstruction.Peek().Name = "tr";
					if (elementState.SizePercent.y == 100)
					{
						elementsUnderConstruction.Peek().VAnchor = VAnchor.ParentBottomTop;
					}
					if (elementState.Alignment == ElementState.AlignType.center)
					{
						elementsUnderConstruction.Peek().HAnchor |= HAnchor.ParentCenter;
					}
					break;

				default:
					throw new NotImplementedException("Don't know what to do with {0}".FormatWith(elementState.TypeName));
			}
		}
コード例 #10
0
ファイル: TypeFace.cs プロジェクト: glocklueng/agg-sharp
		public void ShowDebugInfo(Graphics2D graphics2D)
		{
			StyledTypeFace typeFaceNameStyle = new StyledTypeFace(this, 30);
			TypeFacePrinter fontNamePrinter = new TypeFacePrinter(this.fontFamily + " - 30 point", typeFaceNameStyle);

			RectangleDouble bounds = typeFaceNameStyle.BoundingBoxInPixels;
			double origX = 10 - bounds.Left;
			double x = origX;
			double y = 10 - typeFaceNameStyle.DescentInPixels;
			int width = 50;
			RGBA_Bytes boundingBoxColor = new RGBA_Bytes(0, 0, 0);
			RGBA_Bytes originColor = new RGBA_Bytes(0, 0, 0);
			RGBA_Bytes ascentColor = new RGBA_Bytes(255, 0, 0);
			RGBA_Bytes descentColor = new RGBA_Bytes(255, 0, 0);
			RGBA_Bytes xHeightColor = new RGBA_Bytes(12, 25, 200);
			RGBA_Bytes capHeightColor = new RGBA_Bytes(12, 25, 200);
			RGBA_Bytes underlineColor = new RGBA_Bytes(0, 150, 55);

			// the origin
			graphics2D.Line(x, y, x + width, y, originColor);

			graphics2D.Rectangle(x + bounds.Left, y + bounds.Bottom, x + bounds.Right, y + bounds.Top, boundingBoxColor);

			x += typeFaceNameStyle.BoundingBoxInPixels.Width * 1.5;

			width = width * 3;

			double temp = typeFaceNameStyle.AscentInPixels;
			graphics2D.Line(x, y + temp, x + width, y + temp, ascentColor);

			temp = typeFaceNameStyle.DescentInPixels;
			graphics2D.Line(x, y + temp, x + width, y + temp, descentColor);

			temp = typeFaceNameStyle.XHeightInPixels;
			graphics2D.Line(x, y + temp, x + width, y + temp, xHeightColor);

			temp = typeFaceNameStyle.CapHeightInPixels;
			graphics2D.Line(x, y + temp, x + width, y + temp, capHeightColor);

			temp = typeFaceNameStyle.UnderlinePositionInPixels;
			graphics2D.Line(x, y + temp, x + width, y + temp, underlineColor);

			Affine textTransform;
			textTransform = Affine.NewIdentity();
			textTransform *= Affine.NewTranslation(10, origX);

			VertexSourceApplyTransform transformedText = new VertexSourceApplyTransform(textTransform);
			fontNamePrinter.Render(graphics2D, RGBA_Bytes.Black, transformedText);

			graphics2D.Render(transformedText, RGBA_Bytes.Black);

			// render the legend
			StyledTypeFace legendFont = new StyledTypeFace(this, 12);
			Vector2 textPos = new Vector2(x + width / 2, y + typeFaceNameStyle.EmSizeInPixels * 1.5);
			graphics2D.Render(new TypeFacePrinter("Descent"), textPos, descentColor); textPos.y += legendFont.EmSizeInPixels;
			graphics2D.Render(new TypeFacePrinter("Underline"), textPos, underlineColor); textPos.y += legendFont.EmSizeInPixels;
			graphics2D.Render(new TypeFacePrinter("X Height"), textPos, xHeightColor); textPos.y += legendFont.EmSizeInPixels;
			graphics2D.Render(new TypeFacePrinter("CapHeight"), textPos, capHeightColor); textPos.y += legendFont.EmSizeInPixels;
			graphics2D.Render(new TypeFacePrinter("Ascent"), textPos, ascentColor); textPos.y += legendFont.EmSizeInPixels;
			graphics2D.Render(new TypeFacePrinter("Origin"), textPos, originColor); textPos.y += legendFont.EmSizeInPixels;
			graphics2D.Render(new TypeFacePrinter("Bounding Box"), textPos, boundingBoxColor);
		}
コード例 #11
0
 public EnglishTextWrapping(StyledTypeFace styledTypeFace)
     : base(styledTypeFace)
 {
 }
コード例 #12
0
 // you can't
 public TextWrapping(StyledTypeFace styledTypeFace)
 {
     this.styledTypeFace = styledTypeFace;
 }
コード例 #13
0
		private void InsertTextDoWork(string brailleText, string wordText)
		{
			Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

			asyncMeshGroups.Clear();
			asyncMeshGroupTransforms.Clear();
			asyncPlatingDatas.Clear();

			TypeFacePrinter brailPrinter = new TypeFacePrinter(brailleText, new StyledTypeFace(brailTypeFace, 12));

			int firstNewCharacter = 0;
			StyledTypeFace boldStyled = new StyledTypeFace(monoSpacedTypeFace, 12);

			if (includeText.Checked)
			{
				TypeFacePrinter normalPrinter = new TypeFacePrinter(wordText, boldStyled);
				Vector2 normalSize = normalPrinter.GetSize();
				AddCharacterMeshes(wordText, normalPrinter);
				
				firstNewCharacter = asyncPlatingDatas.Count;
			}

			AddCharacterMeshes(brailleText, brailPrinter);
			Vector2 brailSize = brailPrinter.GetSize();

			for (int i = 0; i < firstNewCharacter; i++)
			{
				asyncPlatingDatas[i].spacing = asyncPlatingDatas[i].spacing + new Vector2(0, boldStyled.CapHeightInPixels * 1.5);
			}

			CreateBase(asyncMeshGroups, asyncMeshGroupTransforms, asyncPlatingDatas);

			SetWordPositions(asyncMeshGroups, asyncMeshGroupTransforms, asyncPlatingDatas);
			SetWordSize(asyncMeshGroups, asyncMeshGroupTransforms);
			SetWordHeight(asyncMeshGroups, asyncMeshGroupTransforms);

			CenterTextOnScreen(asyncMeshGroups, asyncMeshGroupTransforms);

			processingProgressControl.PercentComplete = 95;
		}
コード例 #14
0
        private void AddContent(HtmlParser htmlParser, string htmlContent)
        {
            ElementState elementState = htmlParser.CurrentElementState;
            string decodedHtml = HtmlParser.UrlDecode(htmlContent);
            switch (elementState.TypeName)
            {
                case "a":
                    {
                        Button linkButton = linkButtonFactory.Generate(decodedHtml);
                        StyledTypeFace styled = new StyledTypeFace(LiberationSansFont.Instance, elementState.PointSize);
                        double descentInPixels = styled.DescentInPixels;
                        linkButton.OriginRelativeParent = new VectorMath.Vector2(linkButton.OriginRelativeParent.x, linkButton.OriginRelativeParent.y + descentInPixels);
                        linkButton.Click += (sender, mouseEvent) => 
                        {
                            System.Diagnostics.Process.Start(elementState.Href); 
                        };
                        currentRow.AddChild(linkButton);
                    }
                    break;

                case "table":
                    break;

                case "td":
                case "span":
                    GuiWidget widgetToAdd;

                    if (elementState.Classes.Contains("translate"))
                    {
                        decodedHtml = decodedHtml.Localize();
                    }
                    if (elementState.Classes.Contains("toUpper"))
                    {
                        decodedHtml = decodedHtml.ToUpper();
                    }
                    if (elementState.Classes.Contains("versionNumber"))
                    {
                        decodedHtml = VersionInfo.Instance.ReleaseVersion;
                    }
                    if (elementState.Classes.Contains("buildNumber"))
                    {
                        decodedHtml = VersionInfo.Instance.BuildVersion;
                    }

                    Button createdButton = null;
                    if (elementState.Classes.Contains("centeredButton"))
                    {
                        createdButton = textImageButtonFactory.Generate(decodedHtml);
                        widgetToAdd = createdButton;
                    }
                    else if (elementState.Classes.Contains("linkButton"))
                    {
                        double oldFontSize = linkButtonFactory.fontSize;
                        linkButtonFactory.fontSize = elementState.PointSize;
                        createdButton = linkButtonFactory.Generate(decodedHtml);
                        StyledTypeFace styled = new StyledTypeFace(LiberationSansFont.Instance, elementState.PointSize);
                        double descentInPixels = styled.DescentInPixels;
                        createdButton.OriginRelativeParent = new VectorMath.Vector2(createdButton.OriginRelativeParent.x, createdButton.OriginRelativeParent.y + descentInPixels);
                        widgetToAdd = createdButton;
                        linkButtonFactory.fontSize = oldFontSize;
                    }
                    else
                    {
                        TextWidget content = new TextWidget(decodedHtml, pointSize: elementState.PointSize, textColor: ActiveTheme.Instance.PrimaryTextColor);
                        widgetToAdd = content;
                    }

                    if (createdButton != null)
                    {
                        if (elementState.Id == "sendFeedback")
                        {
                            createdButton.Click += (sender, mouseEvent) => { ContactFormWindow.Open(); };
                        }
                        else if (elementState.Id == "clearCache")
                        {
                            createdButton.Click += (sender, mouseEvent) => { DeleteCacheData(); };
                        }
                    }

                    if (elementState.VerticalAlignment == ElementState.VerticalAlignType.top)
                    {
                        widgetToAdd.VAnchor = VAnchor.ParentTop;
                    }

                    currentRow.AddChild(widgetToAdd);
                    break;

                case "tr":
                    currentRow = new FlowLayoutWidget();
                    if (elementState.HeightPercent == 100)
                    {
                        currentRow.VAnchor = VAnchor.ParentBottomTop;
                    }
                    if (elementState.Alignment == ElementState.AlignType.center)
                    {
                        currentRow.HAnchor |= HAnchor.ParentCenter;
                    }
                    break;

                default:
                    throw new NotImplementedException("Don't know what to do with {0}".FormatWith(elementState.TypeName));
            }
        }