private void BuildPrivate(Graphics g)
        {
            PageText model = new PageText("");
            model.AllowSelect = false;
            model.Page = this.Page;
			model.HyperLink=null;
			model.Tooltip=null;
			int fontSizeModel = 3;

			if (_items != null)		// this has already been built
				return;
            _items = new List<PageItem>();
			_StyleStack = new Stack();

			// The first item is always a text box with the border and background attributes
			PageText pt = new PageText("");
            pt.AllowSelect = true;                // This item represents HTML item for selection in RdlViewer
            pt.Page = this.Page;
            pt.HtmlParent = this;
			pt.X = this.X;
			pt.Y = this.Y;
			pt.H = this.H;
			pt.W = this.W;
			pt.CanGrow = false;
			pt.SI = this.SI.Clone() as StyleInfo;
			pt.SI.PaddingBottom = pt.SI.PaddingLeft = pt.SI.PaddingRight = pt.SI.PaddingTop = 0;
			pt.SI.TextAlign = TextAlignEnum.Left;
			_items.Add(pt);

			// Now we create multiple items that represent what is in the box
			PageTextHtmlLexer hl = new PageTextHtmlLexer(this.Text);
			List<string> tokens = hl.Lex();

			float textWidth = this.W - pt.SI.PaddingLeft - pt.SI.PaddingRight;
			// Now set the default style for the rest of the members
			StyleInfo si = this.SI.Clone() as StyleInfo;
			si.BStyleBottom = si.BStyleLeft = si.BStyleRight = si.BStyleTop = BorderStyleEnum.None;
			pt.SI.TextAlign = TextAlignEnum.Left;
			pt.SI.VerticalAlign = VerticalAlignEnum.Top;
			si.BackgroundColor = Color.Empty;
			si.BackgroundGradientType = BackgroundGradientTypeEnum.None;
			si.BackgroundImage = null;

			bool bFirstInLine=true;
			StringBuilder sb = new StringBuilder(); // this will hold the accumulating line
			float lineXPos=0;
			float xPos = 0;
			float yPos = 0;
			float maxLineHeight=0;
			float maxDescent=0;
			float descent;				// working value for descent
			SizeF ms;
			bool bWhiteSpace=false;
			List<PageItem> lineItems = new List<PageItem>();
			foreach (string token in tokens)
			{
				if (token[0] == PageTextHtmlLexer.HTMLCMD)		// indicates an HTML command
				{
					// we need to create a PageText since the styleinfo is changing
					if (sb.Length != 0)
					{
						pt = new PageText(sb.ToString());
                        pt.AllowSelect = false;
                        pt.Page = this.Page;
                        pt.HtmlParent = this;
						pt.HyperLink = model.HyperLink;
						pt.Tooltip = model.Tooltip;
						pt.NoClip = true;
						sb = new StringBuilder();
						pt.X = this.X + lineXPos;
						pt.Y = this.Y + yPos;
						pt.CanGrow = false;
						pt.SI = CurrentStyle(si).Clone() as StyleInfo;
						_items.Add(pt);
						lineItems.Add(pt);
						ms = this.MeasureString(pt.Text, pt.SI, g, out descent);
						maxDescent = Math.Max(maxDescent, descent);
						pt.W = ms.Width;
						pt.H = ms.Height;
						pt.Descent = descent;
						maxLineHeight = Math.Max(maxLineHeight, ms.Height);
						lineXPos = xPos;
					}
					// Now reset the styleinfo
					StyleInfo cs = CurrentStyle(si);
					string ltoken = token.Substring(1,Math.Min(token.Length-1,10)).ToLower();
					if (ltoken == "<b>" || ltoken == "<strong>")
						cs.FontWeight = FontWeightEnum.Bold;
					else if (ltoken == "</b>" || ltoken == "</strong>")
						cs.FontWeight = FontWeightEnum.Normal;
					else if (ltoken == "<i>" || ltoken == "<cite>" || ltoken == "<var>" || ltoken == "<em>")
						cs.FontStyle = FontStyleEnum.Italic;
					else if (ltoken == "</i>" || ltoken == "</cite>" || ltoken == "</var>" || ltoken == "</em>")
						cs.FontStyle = FontStyleEnum.Normal;
					else if (ltoken == "<code>" || ltoken == "<samp>")
						cs.FontFamily = "Courier New";
					else if (ltoken == "</code>" || ltoken == "</samp>")
						cs.FontFamily = this.SI.FontFamily;
					else if (ltoken == "<kbd>")
					{
						cs.FontFamily = "Courier New";
						cs.FontWeight = FontWeightEnum.Bold;
					}
					else if (ltoken == "</kdd>")
					{
						cs.FontFamily = this.SI.FontFamily;
						cs.FontWeight = FontWeightEnum.Normal;
					}
					else if (ltoken == "<big>")
					{	// big makes it bigger by 20% for each time over the baseline of 3
						fontSizeModel++;
						float inc = 1;
						for (int i=3; i < fontSizeModel; i++)
						{
							inc += .2f;
						}
						float h = this.SI.FontSize * inc;
						cs.FontSize = h;
					}
					else if (ltoken == "</big>")
					{	// undoes the effect of big
						fontSizeModel--;
						float inc = 1;
						for (int i=3; i < fontSizeModel; i++)
						{
							inc += .2f;
						}
						float h = this.SI.FontSize / inc;
						cs.FontSize = h;
					}
					else if (ltoken == "<small>")
					{	// small makes it smaller by 20% for each time under the baseline of 3
						fontSizeModel--;
						float inc = 1;
						for (int i=3; i > fontSizeModel; i--)
						{
							inc += .2f;
						}
						float h = this.SI.FontSize / inc;
						cs.FontSize = h;
					}
					else if (ltoken == "</small>")
					{	// undoes the effect of small
						fontSizeModel++;
						float inc = 1;
						for (int i=3; i > fontSizeModel; i--)
						{
							inc += .2f;
						}
						float h = this.SI.FontSize * inc;
						cs.FontSize = h;
					}
					else if (ltoken.StartsWith("<br"))
					{
						yPos += maxLineHeight;
						NormalizeLineHeight(lineItems, maxLineHeight, maxDescent);
						maxLineHeight = xPos = lineXPos = maxDescent = 0;
						bFirstInLine = true;
						bWhiteSpace = false;
					}
                    else if (ltoken.StartsWith("<hr"))
                    {   // Add a line
                        // Process existing line if any
                        yPos += maxLineHeight;
                        NormalizeLineHeight(lineItems, maxLineHeight, maxDescent);
                        maxLineHeight = xPos = lineXPos = maxDescent = 0;
                        bFirstInLine = true;
                        bWhiteSpace = false;

                        PageLine pl = new PageLine();
                        pl.AllowSelect = false;
                        pl.Page = this.Page;
                        const int horzLineHeight = 10;
                        pl.SI = cs.Clone() as StyleInfo;
                        pl.SI.BStyleLeft = BorderStyleEnum.Ridge;
                        pl.Y = pl.Y2 = this.Y + yPos + horzLineHeight / 2;
                        pl.X = this.X;
                        pl.X2 = pl.X + this.W;
                        _items.Add(pl);
                        yPos += horzLineHeight;  // skip past horizontal line
                    }
                    else if (ltoken.StartsWith("<p"))
					{
						yPos += maxLineHeight * 2;
						NormalizeLineHeight(lineItems, maxLineHeight, maxDescent);
						maxLineHeight = xPos = lineXPos = maxDescent = 0;
						bFirstInLine = true;
						bWhiteSpace = false;
					}
					else if (ltoken.StartsWith("<a"))
					{
						BuildAnchor(token.Substring(1), cs, model);
					}
                    else if (ltoken.StartsWith("<img"))
                    {
                        PageImage pimg = BuildImage(g, token.Substring(1), cs, model);
                        if (pimg != null)   // We got an image; add to process list
                        {
                            pimg.Y = this.Y + yPos;
                            pimg.X = this.X;
                            _items.Add(pimg);
                            yPos += pimg.H;	        // Increment y position
                            maxLineHeight = xPos = lineXPos = maxDescent = 0;
                            bFirstInLine = true;
                            bWhiteSpace = false;
                        }
                    }
                    else if (ltoken == "</a>")
                    {
                        model.HyperLink = model.Tooltip = null;
                        PopStyle();
                    }
                    else if (ltoken.StartsWith("<span"))
                    {
                        HandleStyle(token.Substring(1), si);
                    }
                    else if (ltoken == "</span>")
                    {   // we really should match span and font but it shouldn't matter very often?
                        PopStyle();
                    }
                    else if (ltoken.StartsWith("<font"))
                    {
                        HandleFont(token.Substring(1), si);
                    }
                    else if (ltoken == "</font>")
                    {   // we really should match span and font but it shouldn't matter very often?
                        PopStyle();
                    }
                    continue;
				}
				if (token == PageTextHtmlLexer.WHITESPACE)
				{
					if (!bFirstInLine)
						bWhiteSpace = true;
					continue;
				}

				if (token != PageTextHtmlLexer.EOF)
				{
					string ntoken;
                    if (token == PageTextHtmlLexer.NBSP.ToString())
                        ntoken = bWhiteSpace ? "  " : " ";
                    else
                        ntoken = bWhiteSpace ? " " + token : token;
                    ntoken = ntoken.Replace(PageTextHtmlLexer.NBSP, ' ');

					bWhiteSpace = false;			// can only use whitespace once
					ms = this.MeasureString(ntoken, CurrentStyle(si), g, out descent);
					if (xPos + ms.Width < textWidth)
					{
						bFirstInLine = false;
						sb.Append(ntoken);

						maxDescent = Math.Max(maxDescent, descent);
						maxLineHeight = Math.Max(maxLineHeight, ms.Height);
						xPos += ms.Width;
						continue;
					}
				}
				else if (sb.Length == 0)	// EOF and no previous string means we're done
					continue;

				pt = new PageText(sb.ToString());
                pt.AllowSelect = false;
                pt.Page = this.Page;
                pt.HtmlParent = this;
                pt.NoClip = true;
				pt.HyperLink = model.HyperLink;
				pt.Tooltip = model.Tooltip;
				sb = new StringBuilder();
				sb.Append(token.Replace(PageTextHtmlLexer.NBSP, ' '));
				pt.SI = CurrentStyle(si).Clone() as StyleInfo;
				ms = this.MeasureString(pt.Text, pt.SI, g, out descent);
				pt.X = this.X + lineXPos;
				pt.Y = this.Y + yPos;
				pt.H = ms.Height;
				pt.W = ms.Width; 
				pt.Descent = descent;
				pt.CanGrow = false;
				_items.Add(pt);
				lineItems.Add(pt);
				maxDescent = Math.Max(maxDescent, descent);
				maxLineHeight = Math.Max(maxLineHeight, ms.Height);
				yPos += maxLineHeight;	// Increment y position
				NormalizeLineHeight(lineItems, maxLineHeight, maxDescent);
				lineXPos = maxLineHeight = maxDescent = 0;	// start line height over

				// Now set the xPos just after the current token
				ms = this.MeasureString(token, CurrentStyle(si), g, out descent);
				xPos = ms.Width;	 
			}
		
			_TotalHeight = yPos;		// set the calculated height of the result
			_StyleStack = null;
			return;
		}
        private void BuildPrivate(Graphics g)
        {
            PageText model = new PageText("");

            model.AllowSelect = false;
            model.Page        = this.Page;
            model.HyperLink   = null;
            model.Tooltip     = null;
            int fontSizeModel = 3;

            if (_items != null)                         // this has already been built
            {
                return;
            }
            _items      = new List <PageItem>();
            _StyleStack = new Stack();

            // The first item is always a text box with the border and background attributes
            PageText pt = new PageText("");

            pt.AllowSelect      = true;           // This item represents HTML item for selection in RdlViewer
            pt.Page             = this.Page;
            pt.HtmlParent       = this;
            pt.X                = this.X;
            pt.Y                = this.Y;
            pt.H                = this.H;
            pt.W                = this.W;
            pt.CanGrow          = false;
            pt.SI               = this.SI.Clone() as StyleInfo;
            pt.SI.PaddingBottom = pt.SI.PaddingLeft = pt.SI.PaddingRight = pt.SI.PaddingTop = 0;
            pt.SI.TextAlign     = TextAlignEnum.Left;
            _items.Add(pt);

            // Now we create multiple items that represent what is in the box
            PageTextHtmlLexer hl     = new PageTextHtmlLexer(this.Text);
            List <string>     tokens = hl.Lex();

            float textWidth = this.W - pt.SI.PaddingLeft - pt.SI.PaddingRight;
            // Now set the default style for the rest of the members
            StyleInfo si = this.SI.Clone() as StyleInfo;

            si.BStyleBottom           = si.BStyleLeft = si.BStyleRight = si.BStyleTop = BorderStyleEnum.None;
            pt.SI.TextAlign           = TextAlignEnum.Left;
            pt.SI.VerticalAlign       = VerticalAlignEnum.Top;
            si.BackgroundColor        = Color.Empty;
            si.BackgroundGradientType = BackgroundGradientTypeEnum.None;
            si.BackgroundImage        = null;

            bool            bFirstInLine  = true;
            StringBuilder   sb            = new StringBuilder(); // this will hold the accumulating line
            float           lineXPos      = 0;
            float           xPos          = 0;
            float           yPos          = 0;
            float           maxLineHeight = 0;
            float           maxDescent    = 0;
            float           descent;                            // working value for descent
            SizeF           ms;
            bool            bWhiteSpace = false;
            List <PageItem> lineItems   = new List <PageItem>();

            foreach (string token in tokens)
            {
                if (token[0] == PageTextHtmlLexer.HTMLCMD)                              // indicates an HTML command
                {
                    // we need to create a PageText since the styleinfo is changing
                    if (sb.Length != 0)
                    {
                        pt             = new PageText(sb.ToString());
                        pt.AllowSelect = false;
                        pt.Page        = this.Page;
                        pt.HtmlParent  = this;
                        pt.HyperLink   = model.HyperLink;
                        pt.Tooltip     = model.Tooltip;
                        pt.NoClip      = true;
                        sb             = new StringBuilder();
                        pt.X           = this.X + lineXPos;
                        pt.Y           = this.Y + yPos;
                        pt.CanGrow     = false;
                        pt.SI          = CurrentStyle(si).Clone() as StyleInfo;
                        _items.Add(pt);
                        lineItems.Add(pt);
                        ms            = this.MeasureString(pt.Text, pt.SI, g, out descent);
                        maxDescent    = Math.Max(maxDescent, descent);
                        pt.W          = ms.Width;
                        pt.H          = ms.Height;
                        pt.Descent    = descent;
                        maxLineHeight = Math.Max(maxLineHeight, ms.Height);
                        lineXPos      = xPos;
                    }
                    // Now reset the styleinfo
                    StyleInfo cs     = CurrentStyle(si);
                    string    ltoken = token.Substring(1, Math.Min(token.Length - 1, 10)).ToLower();
                    if (ltoken == "<b>" || ltoken == "<strong>")
                    {
                        cs.FontWeight = FontWeightEnum.Bold;
                    }
                    else if (ltoken == "</b>" || ltoken == "</strong>")
                    {
                        cs.FontWeight = FontWeightEnum.Normal;
                    }
                    else if (ltoken == "<i>" || ltoken == "<cite>" || ltoken == "<var>" || ltoken == "<em>")
                    {
                        cs.FontStyle = FontStyleEnum.Italic;
                    }
                    else if (ltoken == "</i>" || ltoken == "</cite>" || ltoken == "</var>" || ltoken == "</em>")
                    {
                        cs.FontStyle = FontStyleEnum.Normal;
                    }
                    else if (ltoken == "<code>" || ltoken == "<samp>")
                    {
                        cs.FontFamily = "Courier New";
                    }
                    else if (ltoken == "</code>" || ltoken == "</samp>")
                    {
                        cs.FontFamily = this.SI.FontFamily;
                    }
                    else if (ltoken == "<kbd>")
                    {
                        cs.FontFamily = "Courier New";
                        cs.FontWeight = FontWeightEnum.Bold;
                    }
                    else if (ltoken == "</kdd>")
                    {
                        cs.FontFamily = this.SI.FontFamily;
                        cs.FontWeight = FontWeightEnum.Normal;
                    }
                    else if (ltoken == "<big>")
                    {                           // big makes it bigger by 20% for each time over the baseline of 3
                        fontSizeModel++;
                        float inc = 1;
                        for (int i = 3; i < fontSizeModel; i++)
                        {
                            inc += .2f;
                        }
                        float h = this.SI.FontSize * inc;
                        cs.FontSize = h;
                    }
                    else if (ltoken == "</big>")
                    {                           // undoes the effect of big
                        fontSizeModel--;
                        float inc = 1;
                        for (int i = 3; i < fontSizeModel; i++)
                        {
                            inc += .2f;
                        }
                        float h = this.SI.FontSize / inc;
                        cs.FontSize = h;
                    }
                    else if (ltoken == "<small>")
                    {                           // small makes it smaller by 20% for each time under the baseline of 3
                        fontSizeModel--;
                        float inc = 1;
                        for (int i = 3; i > fontSizeModel; i--)
                        {
                            inc += .2f;
                        }
                        float h = this.SI.FontSize / inc;
                        cs.FontSize = h;
                    }
                    else if (ltoken == "</small>")
                    {                           // undoes the effect of small
                        fontSizeModel++;
                        float inc = 1;
                        for (int i = 3; i > fontSizeModel; i--)
                        {
                            inc += .2f;
                        }
                        float h = this.SI.FontSize * inc;
                        cs.FontSize = h;
                    }
                    else if (ltoken.StartsWith("<br"))
                    {
                        yPos += maxLineHeight;
                        NormalizeLineHeight(lineItems, maxLineHeight, maxDescent);
                        maxLineHeight = xPos = lineXPos = maxDescent = 0;
                        bFirstInLine  = true;
                        bWhiteSpace   = false;
                    }
                    else if (ltoken.StartsWith("<hr"))
                    {   // Add a line
                        // Process existing line if any
                        yPos += maxLineHeight;
                        NormalizeLineHeight(lineItems, maxLineHeight, maxDescent);
                        maxLineHeight = xPos = lineXPos = maxDescent = 0;
                        bFirstInLine  = true;
                        bWhiteSpace   = false;

                        PageLine pl = new PageLine();
                        pl.AllowSelect = false;
                        pl.Page        = this.Page;
                        const int horzLineHeight = 10;
                        pl.SI            = cs.Clone() as StyleInfo;
                        pl.SI.BStyleLeft = BorderStyleEnum.Ridge;
                        pl.Y             = pl.Y2 = this.Y + yPos + horzLineHeight / 2;
                        pl.X             = this.X;
                        pl.X2            = pl.X + this.W;
                        _items.Add(pl);
                        yPos += horzLineHeight;  // skip past horizontal line
                    }
                    else if (ltoken.StartsWith("<p"))
                    {
                        yPos += maxLineHeight * 2;
                        NormalizeLineHeight(lineItems, maxLineHeight, maxDescent);
                        maxLineHeight = xPos = lineXPos = maxDescent = 0;
                        bFirstInLine  = true;
                        bWhiteSpace   = false;
                    }
                    else if (ltoken.StartsWith("<a"))
                    {
                        BuildAnchor(token.Substring(1), cs, model);
                    }
                    else if (ltoken.StartsWith("<img"))
                    {
                        PageImage pimg = BuildImage(g, token.Substring(1), cs, model);
                        if (pimg != null)   // We got an image; add to process list
                        {
                            pimg.Y = this.Y + yPos;
                            pimg.X = this.X;
                            _items.Add(pimg);
                            yPos         += pimg.H;     // Increment y position
                            maxLineHeight = xPos = lineXPos = maxDescent = 0;
                            bFirstInLine  = true;
                            bWhiteSpace   = false;
                        }
                    }
                    else if (ltoken == "</a>")
                    {
                        model.HyperLink = model.Tooltip = null;
                        PopStyle();
                    }
                    else if (ltoken.StartsWith("<span"))
                    {
                        HandleStyle(token.Substring(1), si);
                    }
                    else if (ltoken == "</span>")
                    {   // we really should match span and font but it shouldn't matter very often?
                        PopStyle();
                    }
                    else if (ltoken.StartsWith("<font"))
                    {
                        HandleFont(token.Substring(1), si);
                    }
                    else if (ltoken == "</font>")
                    {   // we really should match span and font but it shouldn't matter very often?
                        PopStyle();
                    }
                    continue;
                }
                if (token == PageTextHtmlLexer.WHITESPACE)
                {
                    if (!bFirstInLine)
                    {
                        bWhiteSpace = true;
                    }
                    continue;
                }

                if (token != PageTextHtmlLexer.EOF)
                {
                    string ntoken;
                    if (token == PageTextHtmlLexer.NBSP.ToString())
                    {
                        ntoken = bWhiteSpace ? "  " : " ";
                    }
                    else
                    {
                        ntoken = bWhiteSpace ? " " + token : token;
                    }
                    ntoken = ntoken.Replace(PageTextHtmlLexer.NBSP, ' ');

                    bWhiteSpace = false;                                        // can only use whitespace once
                    ms          = this.MeasureString(ntoken, CurrentStyle(si), g, out descent);
                    if (xPos + ms.Width < textWidth)
                    {
                        bFirstInLine = false;
                        sb.Append(ntoken);

                        maxDescent    = Math.Max(maxDescent, descent);
                        maxLineHeight = Math.Max(maxLineHeight, ms.Height);
                        xPos         += ms.Width;
                        continue;
                    }
                }
                else if (sb.Length == 0)                        // EOF and no previous string means we're done
                {
                    continue;
                }

                pt             = new PageText(sb.ToString());
                pt.AllowSelect = false;
                pt.Page        = this.Page;
                pt.HtmlParent  = this;
                pt.NoClip      = true;
                pt.HyperLink   = model.HyperLink;
                pt.Tooltip     = model.Tooltip;
                sb             = new StringBuilder();
                sb.Append(token.Replace(PageTextHtmlLexer.NBSP, ' '));
                pt.SI      = CurrentStyle(si).Clone() as StyleInfo;
                ms         = this.MeasureString(pt.Text, pt.SI, g, out descent);
                pt.X       = this.X + lineXPos;
                pt.Y       = this.Y + yPos;
                pt.H       = ms.Height;
                pt.W       = ms.Width;
                pt.Descent = descent;
                pt.CanGrow = false;
                _items.Add(pt);
                lineItems.Add(pt);
                maxDescent    = Math.Max(maxDescent, descent);
                maxLineHeight = Math.Max(maxLineHeight, ms.Height);
                yPos         += maxLineHeight;             // Increment y position
                NormalizeLineHeight(lineItems, maxLineHeight, maxDescent);
                lineXPos = maxLineHeight = maxDescent = 0; // start line height over

                // Now set the xPos just after the current token
                ms   = this.MeasureString(token, CurrentStyle(si), g, out descent);
                xPos = ms.Width;
            }

            _TotalHeight = yPos;                        // set the calculated height of the result
            _StyleStack  = null;
            return;
        }