Exemplo n.º 1
0
        internal static void CalcTextBox(IFlxGraphics Canvas, TFontCache FontCache, real Zoom100, RectangleF CellRect, real Clp, bool MultiLine, real Alpha, bool Vertical, TRichString OutText, Font AFont, TAdaptativeFormats AdaptativeFormats, out SizeF TextExtent, out TXRichStringList TextLines, out TFloatList MaxDescent)
        {
            TextExtent = new SizeF(0, 0);
            TextLines  = new TXRichStringList();

            MaxDescent = new TFloatList();
            real MaxTextWidth;

            if (MultiLine || Vertical)
            {
                real Md;
                real TextHeight = RenderMetrics.CalcTextExtent(Canvas, FontCache, Zoom100, AFont, new TRichString("M"), out Md).Height; //not perfect since the rich string might have different fonts, but a good approx.
                MaxTextWidth = CalcMaxTextWidth(ref CellRect, Clp, Alpha, TextHeight);

                RenderMetrics.SplitText(Canvas, FontCache, Zoom100, OutText, AFont, MaxTextWidth, TextLines, out TextExtent, Vertical, MaxDescent, AdaptativeFormats);
            }
            else
            {
                TextLines.Add(new TXRichString(OutText, false, 0, 0, AdaptativeFormats));
                real mdx = 0;
                TextExtent           = RenderMetrics.CalcTextExtent(Canvas, FontCache, Zoom100, AFont, OutText, out mdx);
                TextLines[0].XExtent = TextExtent.Width;
                TextLines[0].YExtent = TextExtent.Height;
                MaxTextWidth         = CalcMaxTextWidth(ref CellRect, Clp, Alpha, TextExtent.Height);
                MaxDescent.Add(mdx);
            }

            if (AdaptativeFormats != null && AdaptativeFormats.WildcardPos >= 0)
            {
                MaxTextWidth -= 2 * Clp; //Add some extra clipping so the text doesn't go through the line.
                if (Vertical)
                {
                }
                else
                {
                    AddWildcard(Canvas, FontCache, Zoom100, AFont, MaxTextWidth, TextLines, ref TextExtent);
                }
            }
        }
Exemplo n.º 2
0
        internal static void DrawRichText(ExcelFile Workbook, IFlxGraphics Canvas, TFontCache FontCache, real Zoom100, bool ReverseRightToLeftStrings,
                                          ref RectangleF CellRect, ref RectangleF PaintClipRect, ref RectangleF TextRect, ref RectangleF ContainingRect,
                                          real Clp, THFlxAlignment HJustify, TVFlxAlignment VJustify, real Alpha,
                                          Color DrawFontColor, TSubscriptData SubData, TRichString OutText, SizeF TextExtent,
                                          TXRichStringList TextLines,
                                          Font AFont, TFloatList MaxDescent, real[] X, real[] Y)
        {
            RectangleF FinalRect = CellRect;

            if (ContainingRect.Right > PaintClipRect.Left &&
                ContainingRect.Left < PaintClipRect.Right &&
                Intersect(TextRect, PaintClipRect, out FinalRect))
            {
                real dy             = 0;
                int  TextLinesCount = TextLines.Count;

                if (VJustify == TVFlxAlignment.justify || VJustify == TVFlxAlignment.distributed)
                {
                    if (TextLinesCount > 1)
                    {
                        dy = (CellRect.Height - TextExtent.Height - 2 * Clp) / (TextLinesCount - 1);
                    }
                }

                float eps = 0.0001F; //Tolerance for the comparison, these are floats, not doubles, and we get rounding errors soon.
                if (TextRect.Left - eps <= ContainingRect.Left && TextRect.Right + eps >= ContainingRect.Right && TextRect.Top - eps <= ContainingRect.Top && TextRect.Bottom + eps >= ContainingRect.Bottom)
                {
                    Canvas.SetClipReplace(PaintClipRect);                      //This will improve pdf export a lot, since we can now join all the BT/ET tags inside one, and then we can also join fonts inside the ET/BT tags.
                }
                else
                {
                    if (Alpha == 0 || Alpha == 90)
                    {
                        Canvas.SetClipReplace(FinalRect);
                    }
                    else
                    {
                        Canvas.SetClipReplace(RectangleF.FromLTRB(PaintClipRect.Left, FinalRect.Top, PaintClipRect.Right, FinalRect.Bottom));                         //rotated text can move to other used cells horizontally.
                    }
                }

                real AcumDy = 0;
                for (int i = 0; i < TextLinesCount; i++)
                {
                    TXRichString TextLine = TextLines[i];
                    if ((Alpha == 0) &&
                        (HJustify == THFlxAlignment.justify && TextLine.Split) ||
                        (HJustify == THFlxAlignment.distributed)
                        )
                    {
                        Canvas.SetClipReplace(FinalRect);
                        WriteJustText(Workbook, Canvas, FontCache, Zoom100, ReverseRightToLeftStrings,
                                      AFont, DrawFontColor, Y[i] + AcumDy, SubData.Offset(Canvas, AFont), CellRect, Clp, TextLine.s,
                                      TextLine.XExtent, MaxDescent[i], HJustify == THFlxAlignment.distributed, TextLine.AdaptFormat);
                    }
                    else
                    {
                        WriteText(Workbook, Canvas, FontCache, Zoom100, AFont, DrawFontColor, X[i],
                                  Y[i] + AcumDy, SubData.Offset(Canvas, AFont), GetVisualString(TextLine.s, ReverseRightToLeftStrings),
                                  Alpha, MaxDescent[i], TextLine.AdaptFormat);
                    }
                    AcumDy += dy;
                }
            }
        }
Exemplo n.º 3
0
        internal int CalcCellHeight(int Row, int Col, TRichString val, int CellXF, ExcelFile Workbook, real RowMultDisplay, real ColMultDisplay, TMultipleCellAutofitList MultipleRowAutofits)
        {
            if (CellXF < 0)
            {
                return(0xFF);
            }
            if (CellXF >= XFHeight.Length)
            {
                return(0xFF);                                        //Just to make sure. We don't want a wrong file to blow here.
            }
            int Result  = XFHeight[CellXF];
            int Result0 = Result;

            if (val == null)
            {
                return(Result);
            }

            TXFRecord XFRec = Wg.CellXF[CellXF];
            bool      Vertical;
            real      Alpha = FlexCelRender.CalcAngle(XFRec.Rotation, out Vertical);


            if (!XFRec.WrapText && !Vertical && Alpha == 0)
            {
                return(Result);
            }

            Font AFont = gr.FontCache.GetFont(XFFonts[CellXF], 1);

            RectangleF    CellRect = new RectangleF();
            TXlsCellRange rg       = Workbook.CellMergedBounds(Row, Col);

            for (int c = rg.Left; c <= rg.Right; c++)
            {
                CellRect.Width += Workbook.GetColWidth(c, true) / ColMultDisplay;
            }

            SizeF            TextExtent;
            TXRichStringList TextLines  = new TXRichStringList();
            TFloatList       MaxDescent = new TFloatList();

            real Clp = 1 * FlexCelRender.DispMul / 100f;
            real Wr  = 0;

            if (Alpha == 0)
            {
                Wr = CellRect.Right - CellRect.Left - 2 * Clp;
            }
            else
            {
                Wr = 1e6f;                 //When we have an angle, it means "make the row as big as needed to fit". So SplitText needs no limits.
            }


            RenderMetrics.SplitText(gr.Canvas, gr.FontCache, 1, val, AFont, Wr, TextLines, out TextExtent, Vertical, MaxDescent, null);

            if (TextLines.Count <= 0)
            {
                return(Result);
            }

            real H = 0;
            real W = 0;

            for (int i = 0; i < TextLines.Count; i++)
            {
                H += TextLines[i].YExtent;
                if (TextLines[i].XExtent > W)
                {
                    W = TextLines[i].XExtent;
                }
            }

            if (Alpha != 0)
            {
                real SinAlpha = (real)Math.Sin(Alpha * Math.PI / 180); real CosAlpha = (real)Math.Cos(Alpha * Math.PI / 180);
                H = H * CosAlpha + W * Math.Abs(SinAlpha);
            }
            Result = (int)Math.Ceiling(RowMultDisplay * (H + 2 * Clp));

            if (rg.RowCount > 1)
            {
                if (MultipleRowAutofits != null)
                {
                    MultipleRowAutofits.Add(new TMultipleCellAutofit(rg, Result));
                }
                return(Result0);                //We will autofit this later.
            }
            if (Result < 0)
            {
                Result = 0;
            }

            return(Result);
        }
Exemplo n.º 4
0
        internal static void SplitText(IFlxGraphics Canvas, TFontCache FontCache, real Zoom100,
                                       TRichString Text, Font AFont, real w, TXRichStringList TextLines, out SizeF TextExtent, bool Vertical, TFloatList MaxDescent, TAdaptativeFormats AdaptFormat)
        {
            TextLines.Clear();
            MaxDescent.Clear();

            int idx = 0;
            int fit = 0;


            TextExtent = new SizeF(0, 0);
            if (w <= 0 || Text.Value.Length <= 0)
            {
                return;
            }

            while (idx < Text.Value.Length)
            {
                int Enter     = Text.Value.IndexOf((char)0x0A, idx);
                int MaxLength = Text.Value.Length - idx;
                if (Enter >= 0)
                {
                    MaxLength = Enter - idx;
                }

                if (Vertical)
                {
                    fit = 1;
                    CharUtils.SameOrMore(Text.Value, idx, ref fit);
                }
                else
                {
                    //Not a really efficient way, but...
                    //First Guess. whole string.
                    fit = MaxLength;

                    real md;
                    real wc = CalcTextExtent(Canvas, FontCache, Zoom100, AFont, Text.Substring(idx, fit), out md).Width;
                    FitOneLine(Canvas, FontCache, Zoom100, Text, AFont, w, idx, ref fit, ref wc);

                    if (fit <= 0)
                    {
                        fit = 1;                               //avoid infinite loop
                    }
                    CharUtils.SameOrMore(Text.Value, idx, ref fit);


                    if (Text.Value.IndexOf(' ', idx, fit) >= 0)
                    {
                        int minfit = 1;
                        CharUtils.SameOrMore(Text.Value, idx, ref minfit);
                        while (fit > minfit && fit < MaxLength && Text.Value[idx + fit] != ' ')
                        {
                            fit--;
                        }
                    }
                    while (fit < MaxLength && Text.Value[idx + fit] == ' ')
                    {
                        fit++;
                    }
                    //No need to adjust fit for surrogates. it will always be at the start of one.
                }

                //int Enter=Text.Value.IndexOf((char)0x0A, idx, fit);
                //if (Enter>0) fit=Enter-idx;
                int TextLen = Math.Min(MaxLength, fit);
                TextLines.Add(new TXRichString(Text.Substring(idx, TextLen), true, 0, 0, TAdaptativeFormats.CopyTo(AdaptFormat, idx, TextLen)));

                if (fit + idx < Text.Value.Length && Text.Value[idx + fit] == (char)0x0A)
                {
                    TextLines[TextLines.Count - 1].Split = false;
                    if (idx + fit < Text.Value.Length - 1)                  //An Enter at the end behaves different, it means we have a new empty line.
                    {
                        idx++;
                    }
                }
                if (fit + idx >= Text.Value.Length)
                {
                    TextLines[TextLines.Count - 1].Split = false;
                }

                idx += fit;

                //Recalculate dx
                real        mdx   = 0;
                TRichString sx    = TextLines[TextLines.Count - 1].s;
                SizeF       bSize = CalcTextExtent(Canvas, FontCache, Zoom100, AFont, sx, out mdx);
                if (bSize.Height == 0)
                {
                    real  mdx3;
                    SizeF bSize3 = CalcTextExtent(Canvas, FontCache, Zoom100, AFont, new TRichString("M"), out mdx3);
                    bSize.Height = bSize3.Height;
                }

                SizeF bSize2 = bSize;
                if (sx != null && sx.Length > 0 && sx.ToString()[sx.Length - 1] == ' ')             //This is to right align line with spaces at the end.
                {
                    real mdx2;
                    bSize2 = CalcTextExtent(Canvas, FontCache, Zoom100, AFont, sx.RightTrim(), out mdx2);
                }
                TextLines[TextLines.Count - 1].XExtent = bSize2.Width;
                TextLines[TextLines.Count - 1].YExtent = bSize.Height;                 // not bSize2.Height; This might be even 0.

                MaxDescent.Add(mdx);
                if (TextExtent.Width < bSize.Width)
                {
                    TextExtent.Width = bSize.Width;
                }
                TextExtent.Height += bSize.Height;
            }             //while
        }
Exemplo n.º 5
0
        internal int CalcCellWidth(int Row, int Col, TRichString val, int CellXF, ExcelFile Workbook, real RowMultDisplay, real ColMultDisplay, TMultipleCellAutofitList MultipleColAutofits)
        {
            if (val == null || val.Value == null || val.Value.Length == 0)
            {
                return(0);
            }

            TXFRecord XFRec = Wg.CellXF[CellXF];
            bool      Vertical;
            real      Alpha = FlexCelRender.CalcAngle(XFRec.Rotation, out Vertical);

            Font AFont = gr.FontCache.GetFont(XFFonts[CellXF], 1);             //dont dispose

            TXlsCellRange rg = Workbook.CellMergedBounds(Row, Col);

            SizeF            TextExtent;
            TXRichStringList TextLines  = new TXRichStringList();
            TFloatList       MaxDescent = new TFloatList();

            real Clp = 1 * FlexCelRender.DispMul / 100f;
            real Wr  = 0;

            if (Alpha != 90 && Alpha != -90)
            {
                Wr = 1e6f;                                          //this means "make the column as big as needed to fit". So SplitText needs no limits.
            }
            else
            {
                RectangleF CellRect = new RectangleF();
                for (int r = rg.Top; r <= rg.Bottom; r++)
                {
                    CellRect.Height += Workbook.GetRowHeight(r, true) / RowMultDisplay;
                }
                Wr = CellRect.Height - 2 * Clp;
            }


            RenderMetrics.SplitText(gr.Canvas, gr.FontCache, 1, val, AFont, Wr, TextLines, out TextExtent, Vertical, MaxDescent, null);

            if (TextLines.Count <= 0)
            {
                return(0);
            }

            real Rr = 0;
            real Ww = 0;

            for (int i = 0; i < TextLines.Count; i++)
            {
                Rr += TextLines[i].YExtent;
                if (TextLines[i].XExtent > Ww)
                {
                    Ww = TextLines[i].XExtent;
                }
            }
            if (Alpha != 0)
            {
                real SinAlpha = (real)Math.Sin(Alpha * Math.PI / 180); real CosAlpha = (real)Math.Cos(Alpha * Math.PI / 180);
                Ww = Ww * CosAlpha + Rr * Math.Abs(SinAlpha);
            }
            int Result = (int)Math.Ceiling(ColMultDisplay * (Ww + 4 * Clp));

            if (rg.ColCount > 1)
            {
                if (MultipleColAutofits != null)
                {
                    MultipleColAutofits.Add(new TMultipleCellAutofit(rg, Result));
                }
                return(0);                //We will autofit this later.
            }

            if (Result < 0)
            {
                Result = 0;
            }
            return(Result);
        }