private float MeasureStringBlank(Graphics g, Font drawFont, StringFormat drawFormat)
        {
            SizeF ms    = MeasureString(" ", g, drawFont, drawFormat);
            float width = RSize.PointsFromPixels(g, ms.Width);  // convert to points from pixels

            return(width * 2);
        }
        public float RunTextCalcHeight(Report rpt, Graphics g, Row row, PageTextHtml pth)
        {               // normally only called when CanGrow is true
            Size s = Size.Empty;

            if (IsHidden(rpt, row))
            {
                return(0);
            }

            object o = _Value.Evaluate(rpt, row);

            TypeCode tc    = _Value.GetTypeCode();
            int      width = this.WidthCalc(rpt, g);

            if (this.Style != null)
            {
                width -= (Style.EvalPaddingLeftPx(rpt, row) + Style.EvalPaddingRightPx(rpt, row));

                if (this.IsHtml(rpt, row))
                {
                    if (pth == null)
                    {
                        pth = new PageTextHtml(o == null? "": o.ToString());
                        SetPagePositionAndStyle(rpt, pth, row);
                    }
                    pth.Build(g);
                    s.Height = RSize.PixelsFromPoints(pth.TotalHeight);
                }
                else
                {
                    s = Style.MeasureString(rpt, g, o, tc, row, width);
                }
            }
            else                // call the class static method
            {
                s = Style.MeasureStringDefaults(rpt, g, o, tc, row, width);
            }

            TextboxRuntime tbr = TextboxRuntime.GetTextboxRuntime(rpt, this);

            tbr.RunHeight = RSize.PointsFromPixels(g, s.Height);
            if (Style != null)
            {
                tbr.RunHeight += (Style.EvalPaddingBottom(rpt, row) + Style.EvalPaddingTop(rpt, row));
            }
            return(tbr.RunHeight);
        }
        /// <summary>
        /// Measures the location of words within a string;  limited by .Net 1.1 to 32 words
        ///     MEASUREMAX is a constant that defines that limit
        /// </summary>
        /// <param name="s"></param>
        /// <param name="g"></param>
        /// <param name="drawFont"></param>
        /// <param name="drawFormat"></param>
        /// <param name="cra"></param>
        /// <returns></returns>
        private WordStartFinish[] MeasureString32(string s, Graphics g, Font drawFont, StringFormat drawFormat, CharacterRange[] cra)
        {
            if (s == null || s.Length == 0)
            {
                return(null);
            }

            drawFormat.SetMeasurableCharacterRanges(cra);
            Region[] rs = new Region[cra.Length];
            rs = g.MeasureCharacterRanges(s, drawFont, new RectangleF(0, 0, float.MaxValue, float.MaxValue),
                                          drawFormat);
            WordStartFinish[] sz = new WordStartFinish[cra.Length];
            int isz = 0;

            foreach (Region r in rs)
            {
                RectangleF mr = r.GetBounds(g);
                sz[isz].start = RSize.PointsFromPixels(g, mr.Left);
                sz[isz].end   = RSize.PointsFromPixels(g, mr.Right);
                isz++;
            }
            return(sz);
        }
        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();
                }
            }
        }
        // render all the objects in a page in PDF
        private void ProcessPage(Pages pgs, IEnumerable items)
        {
            foreach (PageItem pi in items)
            {
                if (pi.SI.BackgroundImage != null)
                {       // put out any background image
                    PageImage bgImg = pi.SI.BackgroundImage;
                    //					elements.AddImage(images, i.Name, content.objectNum, i.SI, i.ImgFormat,
                    //						pi.X, pi.Y, pi.W, pi.H, i.ImageData,i.SamplesW, i.SamplesH, null);


                    //Duc Phan modified 10 Dec, 2007 to support on background image
                    float imW     = RSize.PointsFromPixels(pgs.G, bgImg.SamplesW);
                    float imH     = RSize.PointsFromPixels(pgs.G, bgImg.SamplesH);
                    int   repeatX = 0;
                    int   repeatY = 0;
                    float itemW   = pi.W - (pi.SI.PaddingLeft + pi.SI.PaddingRight);
                    float itemH   = pi.H - (pi.SI.PaddingTop + pi.SI.PaddingBottom);
                    switch (bgImg.Repeat)
                    {
                    case ImageRepeat.Repeat:
                        repeatX = (int)Math.Floor(itemW / imW);
                        repeatY = (int)Math.Floor(itemH / imH);
                        break;

                    case ImageRepeat.RepeatX:
                        repeatX = (int)Math.Floor(itemW / imW);
                        repeatY = 1;
                        break;

                    case ImageRepeat.RepeatY:
                        repeatY = (int)Math.Floor(itemH / imH);
                        repeatX = 1;
                        break;

                    case ImageRepeat.NoRepeat:
                    default:
                        repeatX = repeatY = 1;
                        break;
                    }

                    //make sure the image is drawn at least 1 times
                    repeatX = Math.Max(repeatX, 1);
                    repeatY = Math.Max(repeatY, 1);

                    float currX  = pi.X + pi.SI.PaddingLeft;
                    float currY  = pi.Y + pi.SI.PaddingTop;
                    float startX = currX;
                    float startY = currY;
                    for (int i = 0; i < repeatX; i++)
                    {
                        for (int j = 0; j < repeatY; j++)
                        {
                            currX = startX + i * imW;
                            currY = startY + j * imH;
                            elements.AddImage(images, bgImg.Name,
                                              content.objectNum, bgImg.SI, bgImg.ImgFormat,
                                              currX, currY, imW, imH, RectangleF.Empty, bgImg.ImageData, bgImg.SamplesW, bgImg.SamplesH, null, pi.Tooltip);
                        }
                    }
                }

                if (pi is PageTextHtml)
                {
                    PageTextHtml pth = pi as PageTextHtml;
                    pth.Build(pgs.G);
                    ProcessPage(pgs, pth);
                    continue;
                }

                if (pi is PageText)
                {
                    PageText pt = pi as PageText;
                    float[]  textwidth;
                    string[] sa = MeasureString(pt, pgs.G, out textwidth);
                    elements.AddText(pt.X, pt.Y, pt.H, pt.W, sa, pt.SI,
                                     fonts, textwidth, pt.CanGrow, pt.HyperLink, pt.NoClip, pt.Tooltip);
                    if (pt.Bookmark != null)
                    {
                        outline.Bookmarks.Add(new PdfOutlineEntry(anchor, page.objectNum, pt.Bookmark, pt.X, elements.PageSize.yHeight - pt.Y));
                    }
                    continue;
                }

                if (pi is PageLine)
                {
                    PageLine pl = pi as PageLine;
                    elements.AddLine(pl.X, pl.Y, pl.X2, pl.Y2, pl.SI);
                    continue;
                }

                if (pi is PageEllipse)
                {
                    PageEllipse pe = pi as PageEllipse;
                    elements.AddEllipse(pe.X, pe.Y, pe.H, pe.W, pe.SI, pe.HyperLink);
                    continue;
                }



                if (pi is PageImage)
                {
                    //PageImage i = pi as PageImage;
                    //float x = i.X + i.SI.PaddingLeft;
                    //float y = i.Y + i.SI.PaddingTop;
                    //float w = i.W - i.SI.PaddingLeft - i.SI.PaddingRight;
                    //float h = i.H - i.SI.PaddingTop - i.SI.PaddingBottom;
                    //elements.AddImage(images, i.Name, content.objectNum, i.SI, i.ImgFormat,
                    //    x, y, w, h, i.ImageData,i.SamplesW, i.SamplesH, i.HyperLink);
                    //continue;
                    PageImage i = pi as PageImage;

                    //Duc Phan added 20 Dec, 2007 to support sized image
                    RectangleF r2 = new RectangleF(i.X + i.SI.PaddingLeft, i.Y + i.SI.PaddingTop, i.W - i.SI.PaddingLeft - i.SI.PaddingRight, i.H - i.SI.PaddingTop - i.SI.PaddingBottom);

                    RectangleF adjustedRect;   // work rectangle
                    RectangleF clipRect = RectangleF.Empty;
                    switch (i.Sizing)
                    {
                    case ImageSizingEnum.AutoSize:
                        adjustedRect = new RectangleF(r2.Left, r2.Top,
                                                      r2.Width, r2.Height);
                        break;

                    case ImageSizingEnum.Clip:
                        adjustedRect = new RectangleF(r2.Left, r2.Top,
                                                      RSize.PointsFromPixels(pgs.G, i.SamplesW), RSize.PointsFromPixels(pgs.G, i.SamplesH));
                        clipRect = new RectangleF(r2.Left, r2.Top,
                                                  r2.Width, r2.Height);
                        break;

                    case ImageSizingEnum.FitProportional:
                        float height;
                        float width;
                        float ratioIm = (float)i.SamplesH / i.SamplesW;
                        float ratioR  = r2.Height / r2.Width;
                        height = r2.Height;
                        width  = r2.Width;
                        if (ratioIm > ratioR)
                        {       // this means the rectangle width must be corrected
                            width = height * (1 / ratioIm);
                        }
                        else if (ratioIm < ratioR)
                        {       // this means the rectangle height must be corrected
                            height = width * ratioIm;
                        }
                        adjustedRect = new RectangleF(r2.X, r2.Y, width, height);
                        break;

                    case ImageSizingEnum.Fit:
                    default:
                        adjustedRect = r2;
                        break;
                    }
                    if (i.ImgFormat == System.Drawing.Imaging.ImageFormat.Wmf || i.ImgFormat == System.Drawing.Imaging.ImageFormat.Emf)
                    {
                        //We dont want to add it - its already been broken down into page items;
                    }
                    else
                    {
                        elements.AddImage(images, i.Name, content.objectNum, i.SI, i.ImgFormat,
                                          adjustedRect.X, adjustedRect.Y, adjustedRect.Width, adjustedRect.Height, clipRect, i.ImageData, i.SamplesW, i.SamplesH, i.HyperLink, i.Tooltip);
                    }
                    continue;
                }

                if (pi is PageRectangle)
                {
                    PageRectangle pr = pi as PageRectangle;
                    elements.AddRectangle(pr.X, pr.Y, pr.H, pr.W, pi.SI, pi.HyperLink, patterns, pi.Tooltip);
                    continue;
                }
                if (pi is PagePie)
                {   // TODO
                    PagePie pp = pi as PagePie;
                    // elements.AddPie(pr.X, pr.Y, pr.H, pr.W, pi.SI, pi.HyperLink, patterns, pi.Tooltip);
                    continue;
                }
                if (pi is PagePolygon)
                {
                    PagePolygon ppo = pi as PagePolygon;
                    elements.AddPolygon(ppo.Points, pi.SI, pi.HyperLink, patterns);
                    continue;
                }
                if (pi is PageCurve)
                {
                    PageCurve pc = pi as PageCurve;

                    elements.AddCurve(pc.Points, pi.SI);
                    continue;
                }
            }
        }
        private SizeF MeasureString(string s, StyleInfo si, Graphics g, out float descent)
        {
            Font         drawFont   = null;
            StringFormat drawFormat = null;
            SizeF        ms         = SizeF.Empty;

            descent = 0;
            if (s == null || s.Length == 0)
            {
                return(ms);
            }
            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;
                }
                try
                {
                    FontFamily ff = si.GetFontFamily();
                    drawFont = new Font(ff, si.FontSize, fs);
                    // following algorithm comes from the C# Font Metrics documentation
                    float descentPixel = si.FontSize * ff.GetCellDescent(fs) / ff.GetEmHeight(fs);
                    descent = RSize.PointsFromPixels(g, descentPixel);
                }
                catch
                {
                    drawFont = new Font("Arial", si.FontSize, fs);                      // usually because font not found
                    descent  = 0;
                }
                drawFormat           = new StringFormat();
                drawFormat.Alignment = StringAlignment.Near;

                CharacterRange[] cr = { new CharacterRange(0, s.Length) };
                drawFormat.SetMeasurableCharacterRanges(cr);
                Region[] rs = new Region[1];
                rs = g.MeasureCharacterRanges(s, drawFont, new RectangleF(0, 0, float.MaxValue, float.MaxValue),
                                              drawFormat);
                RectangleF mr = rs[0].GetBounds(g);

                ms.Height = RSize.PointsFromPixels(g, mr.Height);                       // convert to points from pixels
                ms.Width  = RSize.PointsFromPixels(g, mr.Width);                        // convert to points from pixels
                return(ms);
            }
            finally
            {
                if (drawFont != null)
                {
                    drawFont.Dispose();
                }
                if (drawFormat != null)
                {
                    drawFont.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);
        }
Beispiel #8
0
 private int GetTwipsFromPixels(int pixels)
 {
     return((int)Math.Round(RSize.PointsFromPixels(GetGraphics, pixels) * 20, 0));
 }