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;
		}
		override public void RunPage(Pages pgs, Row row)
		{
			Report r = pgs.Report;
			if (IsHidden(r, row))
				return;

			base.RunPage(pgs, row);

			// need to save the owner report and nest in this defintion
			ReportDefn saveReport = r.ReportDefinition;
            NeedPassword np = r.GetDataSourceReferencePassword;   // get current password

			r.SetReportDefinition(_ReportDefn);
			r.Folder = _ReportDefn.ParseFolder;		// folder needs to get set since the id of the report is used by the cache
            r.GetDataSourceReferencePassword = np;

			DataSourcesDefn saveDS = r.ParentConnections;
			if (this.MergeTransactions)
				r.ParentConnections = saveReport.DataSourcesDefn;
			else
			    r.ParentConnections = null;

            r.SubreportDataRetrievalTriggerEvent();

            bool bRows = true;
			if (_Parameters == null)
			{	// When no parameters we only retrieve data once
                SubreportWorkClass wc = r.Cache.Get(this, "report") as SubreportWorkClass;

				if (wc == null)
				{   // run report first time; 
					bRows = r.RunGetData(null);
                    if (!r.IsSubreportDataRetrievalDefined)       // if use has defined subreportdataretrieval they might set data
                        r.Cache.Add(this, "report", new SubreportWorkClass(bRows));	    // so we can't cache
				}
                else
                    bRows = wc.bRows;
			}
			else
			{
				SetSubreportParameters(r, row);		// apply the parameters
				bRows = r.RunGetData(null);
			}

			SetPageLeft(r);				// Set the Left attribute since this will be the margin for this report

			SetPagePositionBegin(pgs);

            float yOffset;

            if (bRows)  // Only run subreport if have a row in some Dataset
            {
                //
                // Run the subreport -- this is the major effort in creating the display objects in the page
                //
                r.ReportDefinition.Body.RunPage(pgs);		// create a the subreport items
                yOffset = pgs.CurrentPage.YOffset;
            }
            else
            {   // Handle NoRows message 
                string msg;
                if (this.NoRows != null)
                    msg = this.NoRows.EvaluateString(pgs.Report, null);
                else
                    msg = null;

                if (msg != null)
                {
                    PageText pt = new PageText(msg);
                    SetPagePositionAndStyle(pgs.Report, pt, null);

                    if (pt.SI.BackgroundImage != null)
                        pt.SI.BackgroundImage.H = pt.H;		//   and in the background image

                    pgs.CurrentPage.AddObject(pt);

                    yOffset = pt.Y + pt.H;
                }
                else
                    yOffset = pgs.CurrentPage.YOffset;
            }

			r.SetReportDefinition(saveReport);			// restore the current report
			r.ParentConnections = saveDS;				// restore the data connnections

			SetPagePositionEnd(pgs, yOffset);
		}
		private void BuildAnchor(string token, StyleInfo oldsi, PageText model)
		{
			StyleInfo si= oldsi.Clone() as StyleInfo;	// always push a StyleInfo
			_StyleStack.Push(si);						//   since they will always be popped

			Hashtable ht = ParseHtmlCmd(token);

			string href = (string) ht["href"];
			if (href == null || href.Length < 1)
				return;
			model.HyperLink = model.Tooltip = href;
			si.TextDecoration = TextDecorationEnum.Underline;
			si.Color = Color.Blue;
		}
        private PageImage BuildImage(Graphics g, string token, StyleInfo oldsi, PageText model)
        {
            PageTextHtmlCmdLexer hc = new PageTextHtmlCmdLexer(token.Substring(4));
            Hashtable ht = hc.Lex();

            string src = (string)ht["src"];
            if (src == null || src.Length < 1)
                return null;

            string alt = (string)ht["alt"];

            string height = (string)ht["height"];
            string width = (string)ht["width"];
            string align = (string)ht["align"];

            Stream strm = null;
            System.Drawing.Image im = null;
            PageImage pi = null;
            try
            {
                // Obtain the image stream
                if (src.StartsWith("http:") ||
                    src.StartsWith("file:") ||
                    src.StartsWith("https:"))
                {
                    WebRequest wreq = WebRequest.Create(src);
                    WebResponse wres = wreq.GetResponse();
                    strm = wres.GetResponseStream();
                }
                else
                    strm = new FileStream(src, System.IO.FileMode.Open, FileAccess.Read);

                im = System.Drawing.Image.FromStream(strm);
                int h = im.Height;
                int w = im.Width;
                MemoryStream ostrm = new MemoryStream();
                ImageFormat imf;
                imf = ImageFormat.Jpeg;
                im.Save(ostrm, imf);
                byte[] ba = ostrm.ToArray();
                ostrm.Close();
                pi = new PageImage(imf, ba, w, h);
                pi.AllowSelect = false;
                pi.Page = this.Page;
                pi.HyperLink = model.HyperLink;
                pi.Tooltip = alt == null ? model.Tooltip : alt;
                pi.X = 0;
                pi.Y = 0;

                pi.W = RSize.PointsFromPixels(g, width != null? Convert.ToInt32(width): w);
                pi.H = RSize.PointsFromPixels(g, height != null? Convert.ToInt32(height): h);
                pi.SI = new StyleInfo();
            }
            catch 
            {
                pi = null;
            }
            finally
            {
                if (strm != null)
                    strm.Close();
                if (im != null)
                    im.Dispose();
            }

            return pi;
        }
        private void HighlightString(Graphics g, PageText dtext, RectangleF r, Font f, StringFormat sf)
        {
            if (_HighlightText == null || _HighlightText.Length == 0)
                return;         // nothing to highlight
            bool bhighlightItem = dtext == _HighlightItem ||
                    (_HighlightItem != null && dtext.HtmlParent == _HighlightItem);
            if (!(_HighlightAll || bhighlightItem))
                return;         // not highlighting all and not on current highlight item

            string hlt = _HighlightCaseSensitive ? _HighlightText : _HighlightText.ToLower();
            string text = _HighlightCaseSensitive ? dtext.Text : dtext.Text.ToLower();

            if (text.IndexOf(hlt) < 0)
                return;         // string not in text

            StringFormat sf2 = null;
            try
            {
                // Create a CharacterRange array with the highlight location and length
                // Handle multiple occurences of text
                List<CharacterRange> rangel = new List<CharacterRange>();
                int loc = text.IndexOf(hlt);
                int hlen = hlt.Length;
                int len = text.Length;
                while (loc >= 0)
                {
                    rangel.Add(new CharacterRange(loc, hlen));
                    if (loc + hlen < len)  // out of range of text
                        loc = text.IndexOf(hlt, loc + hlen);
                    else
                        loc = -1;
                }

                if (rangel.Count <= 0)      // we should have gotten one; but
                    return;

                CharacterRange[] ranges = rangel.ToArray();

                // Construct a new StringFormat object.
                sf2 = sf.Clone() as StringFormat;

                // Set the ranges on the StringFormat object.
                sf2.SetMeasurableCharacterRanges(ranges);

                // Get the Regions to highlight by calling the 
                // MeasureCharacterRanges method.
                if (r.Width <= 0 || r.Height <= 0)
                {
                    SizeF ts = g.MeasureString(dtext.Text, f);
                    r.Height = ts.Height;
                    r.Width = ts.Width;
                }
                Region[] charRegion = g.MeasureCharacterRanges(dtext.Text, f, r, sf2);

                // Fill in the region using a semi-transparent color to highlight
                foreach (Region rg in charRegion)
                {
                    Color hl = bhighlightItem ? _HighlightItemColor : _HighlightAllColor;
                    g.FillRegion(new SolidBrush(Color.FromArgb(50, hl)), rg);
                }
            }
            catch { }   // if highlighting fails we don't care; need to continue
            finally
            {
                if (sf2 != null)
                    sf2.Dispose();
            }
        }
 private void InsertContentControl(int number, string content, float X, float Y, float W, float H, StyleInfo styleInfo, PageText pt)
 {
     int sCountTo, sCountFrom;
     sCountFrom = (int)(X / spaceWidth);
     sCountTo = (int)((X + W) / spaceWidth);
     int rCount = (int)((Y + H) / rowHeight);
     //if (styleInfo.FontWeight == FontWeightEnum.Bold)
     //{
     //    content = content.Insert(0, BoldOn);
     //    content = content.Insert(content.Length, BoldOff);
     //}
     //if (styleInfo.FontSize > 11f)
     //{
     //    content = content.Insert(0, Expanded);
     //    content = content.Insert(content.Length, ExpandedNormal);
     //}
     DMPControl control = new DMPControl();
     control.Number = number;
     control.LineNumber = rCount;
     control.FromIndex = sCountFrom;
     control.ToIndex = sCountTo;
     control.ContentLength = content.Length;
     control.VerticalAlign = styleInfo.VerticalAlign;
     control.TextAlign = styleInfo.TextAlign;
     control.String = content;
     control.CanGrow = pt.CanGrow;
     control.SI = styleInfo;
     control.TopBorder = styleInfo.BStyleTop == BorderStyleEnum.Solid || styleInfo.BStyleTop == BorderStyleEnum.Dotted;
     control.BottomBorder = styleInfo.BStyleBottom == BorderStyleEnum.Solid || styleInfo.BStyleBottom == BorderStyleEnum.Dotted;
     ContentControls.Add(control);
 }
        private void DoInstructions(Font f, StringFormat sf, Brush br, Single recX, Single recY, Single recWidth, Single recHeight, String Text)
        {
            Color Col = Color.Black;
            if (br.GetType().Name.Equals("SolidBrush"))
            {
                SolidBrush sb = (SolidBrush)br;
                Col = sb.Color;
            }

            PageText pt = new PageText(Text);

            pt.X = X + recX * SCALEFACTOR;
            pt.Y = Y + recY * SCALEFACTOR;
            pt.W = recWidth * SCALEFACTOR;
            pt.H = recHeight * SCALEFACTOR;          
            StyleInfo SI = new StyleInfo();
            SI.Color = Col;           
            SI.Direction = DirectionEnum.LTR;
            SI.FontFamily = f.Name;
            SI.FontSize = f.Size * SCALEFACTOR; 
            if (f.Italic) {SI.FontStyle = FontStyleEnum.Italic;}
            if (f.Bold) { SI.FontWeight = FontWeightEnum.Bold; }
            if (f.Underline) { SI.TextDecoration = TextDecorationEnum.Underline; }
            if (sf.LineAlignment == StringAlignment.Center)
            {
                SI.TextAlign = TextAlignEnum.Center;
            }
            else if (sf.LineAlignment == StringAlignment.Far)
            {
                SI.TextAlign = TextAlignEnum.Right;
            }

            if (sf.Alignment == StringAlignment.Center)
            {
                SI.VerticalAlign = VerticalAlignEnum.Middle;
            }
            else if (sf.Alignment == StringAlignment.Far)
            {
                SI.VerticalAlign = VerticalAlignEnum.Bottom;
            }
            if ((sf.FormatFlags & StringFormatFlags.DirectionVertical) == StringFormatFlags.DirectionVertical)
            {
                SI.WritingMode = WritingModeEnum.tb_rl;
            }
            else
            {
                SI.WritingMode = WritingModeEnum.lr_tb;
            }
            pt.SI = SI;
            items.Add(pt);
            

            //r = Math.Round((r / 255), 3);
            //g = Math.Round((g / 255), 3);
            //b = Math.Round((b / 255), 3);

            //string pdfFont = fonts.GetPdfFont(f.Name);
            ////need a graphics object...
            //Bitmap bm = new Bitmap(1, 1);
            //Graphics gr = Graphics.FromImage(bm);
            //Font scaleFont = new Font(f.Name, (f.Size * ScaleY) * 1.5f, f.Style, f.Unit);
            //SizeF TextSize = gr.MeasureString(Text.Substring(0, Text.Length), scaleFont, (int)(recWidth * ScaleX), sf);
            //float textwidth = TextSize.Width;
            //float textHeight = TextSize.Height;
            //float startX = X + recX * ScaleX;
            //float startY = Y + Height - recY * ScaleY - (scaleFont.Size);
            //if ((sf.FormatFlags & StringFormatFlags.DirectionVertical) != StringFormatFlags.DirectionVertical)
            //{
            //    if (sf.LineAlignment == StringAlignment.Center)
            //    {
            //        startX = (startX + (recWidth * ScaleX) / 2) - (textwidth / 4);
            //    }
            //    else if (sf.LineAlignment == StringAlignment.Far)
            //    {
            //        startX = (startX + recWidth * ScaleX) - (textwidth / 1.8f);
            //    }
            //}
            //else
            //{
            //    startX += textwidth / 4;
            //    if (sf.LineAlignment == StringAlignment.Center)
            //    {
            //        startY = (startY - (recHeight * ScaleY) / 2) + (textHeight / 4);
            //    }
            //    else if (sf.LineAlignment == StringAlignment.Far)
            //    {
            //        startY = (startY - recHeight * ScaleY) + (textHeight / 1.8f);
            //    }
            //}

            //Lines.Append("\r\nq\t");

            //string newtext = PdfUtility.UTF16StringQuoter(Text);
            //if ((sf.FormatFlags & StringFormatFlags.DirectionVertical) != StringFormatFlags.DirectionVertical)
            //{
            //    Lines.AppendFormat(System.Globalization.NumberFormatInfo.InvariantInfo,
            //           "\r\nBT/{0} {1} Tf\t{5} {6} {7} rg\t{2} {3} Td \t({4}) Tj\tET\tQ\t",
            //           pdfFont, scaleFont.SizeInPoints, startX, startY, newtext, r, g, b);
            //}
            //else
            //{
            //    double rads = -283.0 / 180.0;
            //    double radsCos = Math.Cos(rads);
            //    double radsSin = Math.Sin(rads);

            //    Lines.AppendFormat(System.Globalization.NumberFormatInfo.InvariantInfo,
            //                "\r\nBT/{0} {1} Tf\t{5} {6} {7} rg\t{8} {9} {10} {11} {2} {3} Tm \t({4}) Tj\tET\tQ\t",
            //                pdfFont, scaleFont.SizeInPoints, startX, startY, newtext, r, g, b,
            //                radsCos, radsSin, -radsSin, radsCos);
            //}
        }
        private void DrawString(PageText pt, Graphics g, RectangleF r)
        {
            StyleInfo si = pt.SI;
            string s = pt.Text;

            Font drawFont = null;
            StringFormat drawFormat = null;
            Brush drawBrush = null;
            try
            {
                // STYLE
                System.Drawing.FontStyle fs = 0;
                if (si.FontStyle == FontStyleEnum.Italic)
                    fs |= System.Drawing.FontStyle.Italic;

                switch (si.TextDecoration)
                {
                    case TextDecorationEnum.Underline:
                        fs |= System.Drawing.FontStyle.Underline;
                        break;
                    case TextDecorationEnum.LineThrough:
                        fs |= System.Drawing.FontStyle.Strikeout;
                        break;
                    case TextDecorationEnum.Overline:
                    case TextDecorationEnum.None:
                        break;
                }

                // WEIGHT
                switch (si.FontWeight)
                {
                    case FontWeightEnum.Bold:
                    case FontWeightEnum.Bolder:
                    case FontWeightEnum.W500:
                    case FontWeightEnum.W600:
                    case FontWeightEnum.W700:
                    case FontWeightEnum.W800:
                    case FontWeightEnum.W900:
                        fs |= System.Drawing.FontStyle.Bold;
                        break;
                    default:
                        break;
                }
                try
                {
                    drawFont = new Font(si.GetFontFamily(), si.FontSize, fs);	// si.FontSize already in points
                }
                catch (ArgumentException)
                {
                    drawFont = new Font("Arial", si.FontSize, fs);	// if this fails we'll let the error pass thru
                }
                // ALIGNMENT
                drawFormat = new StringFormat();
                switch (si.TextAlign)
                {
                    case TextAlignEnum.Right:
                        drawFormat.Alignment = StringAlignment.Far;
                        break;
                    case TextAlignEnum.Center:
                        drawFormat.Alignment = StringAlignment.Center;
                        break;
                    case TextAlignEnum.Left:
                    default:
                        drawFormat.Alignment = StringAlignment.Near;
                        break;
                }
                if (pt.SI.WritingMode == WritingModeEnum.tb_rl)
                {
                    drawFormat.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
                    drawFormat.FormatFlags |= StringFormatFlags.DirectionVertical;
                }
                switch (si.VerticalAlign)
                {
                    case VerticalAlignEnum.Bottom:
                        drawFormat.LineAlignment = StringAlignment.Far;
                        break;
                    case VerticalAlignEnum.Middle:
                        drawFormat.LineAlignment = StringAlignment.Center;
                        break;
                    case VerticalAlignEnum.Top:
                    default:
                        drawFormat.LineAlignment = StringAlignment.Near;
                        break;
                }
                // draw the background 
                DrawBackground(g, r, si);

                // adjust drawing rectangle based on padding
                RectangleF r2 = new RectangleF(r.Left + si.PaddingLeft,
                                               r.Top + si.PaddingTop,
                                               r.Width - si.PaddingLeft - si.PaddingRight,
                                               r.Height - si.PaddingTop - si.PaddingBottom);

                drawBrush = new SolidBrush(si.Color);
                if (pt.NoClip)	// request not to clip text
                {
                    g.DrawString(pt.Text, drawFont, drawBrush, new PointF(r.Left, r.Top), drawFormat);
                    HighlightString(g, pt, new RectangleF(r.Left, r.Top, float.MaxValue, float.MaxValue),
                        drawFont, drawFormat);
                }
                else
                {
                    g.DrawString(pt.Text, drawFont, drawBrush, r2, drawFormat);
                    HighlightString(g, pt, r2, drawFont, drawFormat);
                }
                if (SelectTool)
                {
                    if (pt.AllowSelect && _SelectList.Contains(pt))
                        g.FillRectangle(new SolidBrush(Color.FromArgb(50, _SelectItemColor)), r2);
                }
            }
            finally
            {
                if (drawFont != null)
                    drawFont.Dispose();
                if (drawFormat != null)
                    drawFont.Dispose();
                if (drawBrush != null)
                    drawBrush.Dispose();
            }
        }
        private PageImage BuildImage(Graphics g, string token, StyleInfo oldsi, PageText model)
        {
            PageTextHtmlCmdLexer hc = new PageTextHtmlCmdLexer(token.Substring(4));
            Hashtable            ht = hc.Lex();

            string src = (string)ht["src"];

            if (src == null || src.Length < 1)
            {
                return(null);
            }

            string alt = (string)ht["alt"];

            string height = (string)ht["height"];
            string width  = (string)ht["width"];
            string align  = (string)ht["align"];

            Stream strm = null;

            System.Drawing.Image im = null;
            PageImage            pi = null;

            try
            {
                // Obtain the image stream
                if (src.StartsWith("http:") ||
                    src.StartsWith("file:") ||
                    src.StartsWith("https:"))
                {
                    WebRequest  wreq = WebRequest.Create(src);
                    WebResponse wres = wreq.GetResponse();
                    strm = wres.GetResponseStream();
                }
                else
                {
                    strm = new FileStream(src, System.IO.FileMode.Open, FileAccess.Read);
                }

                im = System.Drawing.Image.FromStream(strm);
                int          h     = im.Height;
                int          w     = im.Width;
                MemoryStream ostrm = new MemoryStream();
                ImageFormat  imf;
                imf = ImageFormat.Jpeg;
                im.Save(ostrm, imf);
                byte[] ba = ostrm.ToArray();
                ostrm.Close();
                pi             = new PageImage(imf, ba, w, h);
                pi.AllowSelect = false;
                pi.Page        = this.Page;
                pi.HyperLink   = model.HyperLink;
                pi.Tooltip     = alt == null ? model.Tooltip : alt;
                pi.X           = 0;
                pi.Y           = 0;

                pi.W  = RSize.PointsFromPixels(g, width != null? Convert.ToInt32(width): w);
                pi.H  = RSize.PointsFromPixels(g, height != null? Convert.ToInt32(height): h);
                pi.SI = new StyleInfo();
            }
            catch
            {
                pi = null;
            }
            finally
            {
                if (strm != null)
                {
                    strm.Close();
                }
                if (im != null)
                {
                    im.Dispose();
                }
            }

            return(pi);
        }
        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 InsertContentControl(int number, string content, float X, float Y, float W, float H, StyleInfo styleInfo, PageText pt)
        {
            int sCountTo, sCountFrom;

            sCountFrom = (int)(X / spaceWidth);
            sCountTo   = (int)((X + W) / spaceWidth);
            int rCount = (int)((Y + H) / rowHeight);
            //if (styleInfo.FontWeight == FontWeightEnum.Bold)
            //{
            //    content = content.Insert(0, BoldOn);
            //    content = content.Insert(content.Length, BoldOff);
            //}
            //if (styleInfo.FontSize > 11f)
            //{
            //    content = content.Insert(0, Expanded);
            //    content = content.Insert(content.Length, ExpandedNormal);
            //}
            DMPControl control = new DMPControl();

            control.Number        = number;
            control.LineNumber    = rCount;
            control.FromIndex     = sCountFrom;
            control.ToIndex       = sCountTo;
            control.ContentLength = content.Length;
            control.VerticalAlign = styleInfo.VerticalAlign;
            control.TextAlign     = styleInfo.TextAlign;
            control.String        = content;
            control.CanGrow       = pt.CanGrow;
            control.SI            = styleInfo;
            control.TopBorder     = styleInfo.BStyleTop == BorderStyleEnum.Solid || styleInfo.BStyleTop == BorderStyleEnum.Dotted;
            control.BottomBorder  = styleInfo.BStyleBottom == BorderStyleEnum.Solid || styleInfo.BStyleBottom == BorderStyleEnum.Dotted;
            ContentControls.Add(control);
        }
		private string[] MeasureString(PageText pt, Graphics g, out float[] width)
		{
			StyleInfo si = pt.SI;
			string s = pt.Text;

			Font drawFont=null;
			StringFormat drawFormat=null;
			SizeF ms;
			string[] sa=null;
			width=null;
			try
			{
				// STYLE
				System.Drawing.FontStyle fs = 0;
				if (si.FontStyle == FontStyleEnum.Italic)
					fs |= System.Drawing.FontStyle.Italic;

				// WEIGHT
				switch (si.FontWeight)
				{
					case FontWeightEnum.Bold:
					case FontWeightEnum.Bolder:
					case FontWeightEnum.W500:
					case FontWeightEnum.W600:
					case FontWeightEnum.W700:
					case FontWeightEnum.W800:
					case FontWeightEnum.W900:
						fs |= System.Drawing.FontStyle.Bold;
						break;
					default:
						break;
				}

				drawFont = new Font(StyleInfo.GetFontFamily(si.FontFamilyFull), si.FontSize, fs);
				drawFormat = new StringFormat();
				drawFormat.Alignment = StringAlignment.Near;

				// Measure string   
				//  pt.NoClip indicates that this was generated by PageTextHtml Build.  It has already word wrapped.
				if (pt.NoClip || pt.SI.WritingMode == WritingModeEnum.tb_rl)	// TODO: support multiple lines for vertical text
				{
					ms = MeasureString(s, g, drawFont, drawFormat);
					width = new float[1];
					width[0] = RSize.PointsFromPixels(g, ms.Width);	// convert to points from pixels
					sa = new string[1];
					sa[0] = s;
					return sa;
				}

				// handle multiple lines;
				//  1) split the string into the forced line breaks (ie "\n and \r")
				//  2) foreach of the forced line breaks; break these into words and recombine 
				s = s.Replace("\r\n", "\n");	// don't want this to result in double lines
				string[] flines = s.Split(lineBreak);
				List<string> lines = new List<string>();
				List<float> lineWidths = new List<float>();
                // remove the size reserved for left and right padding
                float ptWidth = pt.W - pt.SI.PaddingLeft - pt.SI.PaddingRight;
                if (ptWidth <= 0)
                    ptWidth = 1;
				foreach (string tfl in flines)
				{
					string fl;
					if (tfl.Length > 0 && tfl[tfl.Length-1] == ' ')
						fl = tfl.TrimEnd(' ');
					else
						fl = tfl;

                    // Check if entire string fits into a line
                    ms = MeasureString(fl, g, drawFont, drawFormat);
                    float tw = RSize.PointsFromPixels(g, ms.Width);
                    if (tw <= ptWidth)      
                    {                       // line fits don't need to break it down further
                        lines.Add(fl);
                        lineWidths.Add(tw);
                        continue;
                    }
                    
                    // Line too long; need to break into multiple lines
                    // 1) break line into parts; then build up again keeping track of word positions
					string[] parts = fl.Split(wordBreak);	// this is the maximum split of lines
                    StringBuilder sb = new StringBuilder(fl.Length);
                    CharacterRange[] cra = new CharacterRange[parts.Length];
                    for (int i = 0; i < parts.Length; i++)
					{
                        int sc = sb.Length;     // starting character
                        sb.Append(parts[i]);    // endding character
                        if (i != parts.Length - 1)  // last item doesn't need blank
                            sb.Append(" ");
                        int ec = sb.Length;   
                        CharacterRange cr = new CharacterRange(sc, ec - sc);
                        cra[i] = cr;            // add to character array
					}

                    // 2) Measure the word locations within the line
                    string wfl = sb.ToString();
                    WordStartFinish[] wordLocations = MeasureString(wfl, g, drawFont, drawFormat, cra);
                    if (wordLocations == null)
                        continue;

					// 3) Loop thru creating new lines as needed
                    int startLoc = 0;
                    CharacterRange crs = cra[startLoc];
                    CharacterRange cre = cra[startLoc];
                    float cwidth = wordLocations[0].end;    // length of the first
                    float bwidth = wordLocations[0].start;  // characters need a little extra on start
                    string ts;
                    bool bLine = true;
                    for (int i=1; i < cra.Length; i++)
					{
                        cwidth = wordLocations[i].end - wordLocations[startLoc].start + bwidth;
                        if (cwidth > ptWidth)
						{	// time for a new line
                            cre = cra[i-1];
                            ts = wfl.Substring(crs.First, cre.First + cre.Length - crs.First);
                            lines.Add(ts);
                            lineWidths.Add(wordLocations[i-1].end - wordLocations[startLoc].start + bwidth);
                            
                            // Find the first non-blank character of the next line
                            while (i < cra.Length &&
                                    cra[i].Length == 1 &&
                                    fl[cra[i].First] == ' ')
                            {
                                i++;
                            }
                            if (i < cra.Length)   // any lines left?
                            {  // yes, continue on
                                startLoc = i;
                                crs = cre = cra[startLoc];
                                cwidth = wordLocations[i].end - wordLocations[startLoc].start + bwidth;
                            }
                            else  // no, we can stop
                                bLine = false;
                          //  bwidth = wordLocations[startLoc].start - wordLocations[startLoc - 1].end;
                        }
                        else
                            cre = cra[i];
                    }
                    if (bLine)
                    {
                        ts = fl.Substring(crs.First, cre.First + cre.Length - crs.First);
                        lines.Add(ts);
                        lineWidths.Add(cwidth);
                    }
				}
                // create the final array from the Lists
                string[] la = lines.ToArray();
                width = lineWidths.ToArray(); 
				return la;
			}
			finally
			{
				if (drawFont != null)
					drawFont.Dispose();
				if (drawFormat != null)
					drawFont.Dispose();
			}
		}
Beispiel #13
0
        override public void RunPage(Pages pgs, Row row)
        {
            Report r = pgs.Report;

            if (IsHidden(r, row))
            {
                return;
            }

            base.RunPage(pgs, row);

            // need to save the owner report and nest in this defintion
            ReportDefn   saveReport = r.ReportDefinition;
            NeedPassword np         = r.GetDataSourceReferencePassword; // get current password

            r.SetReportDefinition(_ReportDefn);
            r.Folder = _ReportDefn.ParseFolder;                         // folder needs to get set since the id of the report is used by the cache
            r.GetDataSourceReferencePassword = np;

            DataSourcesDefn saveDS = r.ParentConnections;

            if (this.MergeTransactions)
            {
                r.ParentConnections = saveReport.DataSourcesDefn;
            }
            else
            {
                r.ParentConnections = null;
            }

            r.SubreportDataRetrievalTriggerEvent();

            bool bRows = true;

            if (_Parameters == null)
            {                   // When no parameters we only retrieve data once
                SubreportWorkClass wc = r.Cache.Get(this, "report") as SubreportWorkClass;

                if (wc == null)
                {                                                                   // run report first time;
                    bRows = r.RunGetData(null);
                    if (!r.IsSubreportDataRetrievalDefined)                         // if use has defined subreportdataretrieval they might set data
                    {
                        r.Cache.Add(this, "report", new SubreportWorkClass(bRows)); // so we can't cache
                    }
                }
                else
                {
                    bRows = wc.bRows;
                }
            }
            else
            {
                SetSubreportParameters(r, row);                         // apply the parameters
                bRows = r.RunGetData(null);
            }

            SetPageLeft(r);                                     // Set the Left attribute since this will be the margin for this report

            SetPagePositionBegin(pgs);

            float yOffset;

            if (bRows)  // Only run subreport if have a row in some Dataset
            {
                //
                // Run the subreport -- this is the major effort in creating the display objects in the page
                //
                r.ReportDefinition.Body.RunPage(pgs);           // create a the subreport items
                yOffset = pgs.CurrentPage.YOffset;
            }
            else
            {   // Handle NoRows message
                string msg;
                if (this.NoRows != null)
                {
                    msg = this.NoRows.EvaluateString(pgs.Report, null);
                }
                else
                {
                    msg = null;
                }

                if (msg != null)
                {
                    PageText pt = new PageText(msg);
                    SetPagePositionAndStyle(pgs.Report, pt, null);

                    if (pt.SI.BackgroundImage != null)
                    {
                        pt.SI.BackgroundImage.H = pt.H;         //   and in the background image
                    }
                    pgs.CurrentPage.AddObject(pt);

                    yOffset = pt.Y + pt.H;
                }
                else
                {
                    yOffset = pgs.CurrentPage.YOffset;
                }
            }

            r.SetReportDefinition(saveReport);                                  // restore the current report
            r.ParentConnections = saveDS;                                       // restore the data connnections

            SetPagePositionEnd(pgs, yOffset);
        }
		public bool AnyRowsPage(Pages pgs, Rows data)
		{
			if (data != null && data.Data != null &&
				data.Data.Count > 0)
				return true;

			string msg;
			if (this.NoRows != null)
				msg = this.NoRows.EvaluateString(pgs.Report, null);
			else
				msg = null;

			if (msg == null)
				return false;

			// OK we have a message we need to put out
			RunPageRegionBegin(pgs);				// still perform page break if needed

			PageText pt = new PageText(msg);
			SetPagePositionAndStyle(pgs.Report, pt, null);

			if (pt.SI.BackgroundImage != null)
				pt.SI.BackgroundImage.H = pt.H;		//   and in the background image

			pgs.CurrentPage.AddObject(pt);

			RunPageRegionEnd(pgs);					// perform end page break if needed

            SetPagePositionEnd(pgs, pt.Y + pt.H);
            
            return false;
		}
		override public void RunPage(Pages pgs, Row row)
		{
			Report r = pgs.Report;
			TextboxRuntime tbr = TextboxRuntime.GetTextboxRuntime(r, this);

			tbr.RunCount++;		// Increment the run count

            bool bHidden = IsHidden(r, row);

			SetPagePositionBegin(pgs);

			string t;
            if (bHidden)
                t = "";
            else
                t = RunText(r, row);	// get the text

			bool bDup =	RunTextIsDuplicate(tbr, t, pgs.CurrentPage);
			if (bDup)
			{
				if (!(this.IsTableOrMatrixCell(r)))	// don't put out anything if not in Table or Matrix
					bHidden = true;
				t = "";		// still need to put out the cell
			}
			PageText pt;
			PageTextHtml pth=null;
			if (IsHtml(r, row))
				pt = pth = new PageTextHtml(t);
			else
				pt = new PageText(t);
			SetPagePositionAndStyle(r, pt, row);
			if (this.CanGrow && tbr.RunHeight == 0)	// when textbox is in a DataRegion this will already be called
			{
				this.RunTextCalcHeight(r, pgs.G, row, pt is PageTextHtml? pt as PageTextHtml: null);
			}
			pt.H = Math.Max(pt.H, tbr.RunHeight);		// reset height
			if (pt.SI.BackgroundImage != null)
				pt.SI.BackgroundImage.H = pt.H;		//   and in the background image
			pt.CanGrow = this.CanGrow;

            // check TextAlign: if General then correct based on data type
            if (pt.SI.TextAlign == TextAlignEnum.General)
            {
                if (DataType.IsNumeric(this.Value.GetTypeCode() ))
                    pt.SI.TextAlign = TextAlignEnum.Right;
            }

            // Hidden objects don't affect the current page?
            if (!bHidden)
            {
                // Force page break if it doesn't fit on a page
                if (this.IsInBody &&                         // Only force page when object directly in body
                    pgs.CurrentPage.YOffset + pt.Y + pt.H >= pgs.BottomOfPage && // running off end of page
                    !pgs.CurrentPage.IsEmpty())                             // if page is already empty don't force new
                {	// force page break if it doesn't fit on the page
                    pgs.NextOrNew();
                    pgs.CurrentPage.YOffset = OwnerReport.TopOfPage;
                    if (this.YParents != null)
                        pt.Y = 0;
                }

                Page p = pgs.CurrentPage;
                RecordPageReference(r, p, row);			// save information for late page header/footer references
                p.AddObject(pt);
                if (!bDup)
                {
                    tbr.PreviousText = t;	// previous text displayed
                    tbr.PreviousPage = p;	//  page previous text was shown on
                }
            }

			SetPagePositionEnd(pgs, pt.Y+pt.H);
			if (pth != null)
				pth.Reset();
			if (this.CanGrow && !Value.IsConstant())
			{
				tbr.RunHeight = 0;					// need to recalculate
			}
		}