Beispiel #1
0
        /// <summary>
        /// Page Text element at the X Y position; multiple lines handled
        /// </summary>
        /// <returns></returns>
        internal void AddText(float x, float y, float height, float width, string[] sa,
                              StyleInfo si, PdfFonts fonts, float[] tw, bool bWrap, string url, bool bNoClip)
        {
            // Calculate the RGB colors e.g. RGB(255, 0, 0) = red = 1 0 0 rg
            double r = si.Color.R;
            double g = si.Color.G;
            double b = si.Color.B;

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

            string pdfFont = fonts.GetPdfFont(si);              // get the pdf font resource name

            // Loop thru the lines of text
            for (int i = 0; i < sa.Length; i++)
            {
                string text      = sa[i];
                float  textwidth = tw[i];
                // Calculate the x position
                float startX = x + si.PaddingLeft;                                      // TODO: handle tb_rl
                float startY = y + si.PaddingTop + (i * si.FontSize);                   // TODO: handle tb_rl

                if (si.WritingMode == WritingModeEnum.lr_tb)
                {                       // TODO: not sure what alignment means with tb_lr so I'll leave it out for now
                    switch (si.TextAlign)
                    {
                    case TextAlignEnum.Center:
                        if (width > 0)
                        {
                            startX = x + si.PaddingLeft + (width - si.PaddingLeft - si.PaddingRight) / 2 - textwidth / 2;
                        }
                        break;

                    case TextAlignEnum.Right:
                        if (width > 0)
                        {
                            startX = x + width - textwidth - si.PaddingRight;
                        }
                        break;

                    case TextAlignEnum.Left:
                    default:
                        break;
                    }

                    // Calculate the y position
                    switch (si.VerticalAlign)
                    {
                    case VerticalAlignEnum.Middle:
                        if (height <= 0)
                        {
                            break;
                        }

                        // calculate the middle of the region
                        startY = y + si.PaddingTop + (height - si.PaddingTop - si.PaddingBottom) / 2 - si.FontSize / 2;
                        // now go up or down depending on which line
                        if (sa.Length == 1)
                        {
                            break;
                        }
                        if (sa.Length % 2 == 0)                                 // even number
                        {
                            startY = startY - ((sa.Length / 2 - i) * si.FontSize) + si.FontSize / 2;
                        }
                        else
                        {
                            startY = startY - ((sa.Length / 2 - i) * si.FontSize);
                        }
                        break;

                    case VerticalAlignEnum.Bottom:
                        if (height <= 0)
                        {
                            break;
                        }

                        startY = y + height - si.PaddingBottom - (si.FontSize * (sa.Length - i));
                        break;

                    case VerticalAlignEnum.Top:
                    default:
                        break;
                    }
                }

                // Draw background rectangle if needed (only put out on the first line, since we do whole rectangle)
                if (!si.BackgroundColor.IsEmpty && height > 0 && width > 0 && i == 0)
                {                       // background color, height and width are specified
                    AddFillRect(x, y, width, height, si.BackgroundColor);
                }

                // Set the clipping path
                if (height > 0 && width > 0)
                {
                    if (bNoClip)                        // no clipping but we still want URL checking
                    {
                        elements.Append("\r\nq\t");
                    }
                    else
                    {
                        elements.AppendFormat(NumberFormatInfo.InvariantInfo,
                                              "\r\nq\t{0} {1} {2} {3} re W n",
                                              x, pSize.yHeight - y - height, width, height);
                    }
                    if (url != null)
                    {
                        p.AddHyperlink(x, pSize.yHeight - y, height, width, url);
                    }
                }
                else
                {
                    elements.Append("\r\nq\t");
                }

                // Escape the text

                string newtext = PdfUtility.UTF16StringQuoter(text);

                //string newtext = text.Replace("\\", "\\\\");
                //newtext = newtext.Replace("(", "\\(");
                //newtext = newtext.Replace(")", "\\)");

                if (si.WritingMode == WritingModeEnum.lr_tb)
                {
                    elements.AppendFormat(NumberFormatInfo.InvariantInfo,
                                          "\r\nBT/{0} {1} Tf\t{5} {6} {7} rg\t{2} {3} Td \t({4}) Tj\tET\tQ\t",
                                          pdfFont, si.FontSize, startX, (pSize.yHeight - startY - si.FontSize), newtext, r, g, b);
                }
                else
                {                       // Rotate text -90 degrees=-.5 radians (this works for english don't know about true tb-rl language)
                                        //   had to play with reader to find best approximation for this rotation; didn't do what I expected
                                        //    see pdf spec section 4.2.2 pg 141  "Common Transformations"

                    elements.AppendFormat(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, si.FontSize, startX, (pSize.yHeight - startY), newtext, r, g, b,
                                          radsCos, radsSin, -radsSin, radsCos);
                }

                // Handle underlining etc.
                float maxX;
                switch (si.TextDecoration)
                {
                case TextDecorationEnum.Underline:
                    maxX = width > 0? Math.Min(x + width, startX + textwidth): startX + textwidth;
                    AddLine(startX, startY + si.FontSize + 1, maxX, startY + si.FontSize + 1, 1, si.Color, BorderStyleEnum.Solid);
                    break;

                case TextDecorationEnum.LineThrough:
                    maxX = width > 0? Math.Min(x + width, startX + textwidth): startX + textwidth;
                    AddLine(startX, startY + (si.FontSize / 2) + 1, maxX, startY + (si.FontSize / 2) + 1, 1, si.Color, BorderStyleEnum.Solid);
                    break;

                case TextDecorationEnum.Overline:
                    maxX = width > 0? Math.Min(x + width, startX + textwidth): startX + textwidth;
                    AddLine(startX, startY + 1, maxX, startY + 1, 1, si.Color, BorderStyleEnum.Solid);
                    break;

                case TextDecorationEnum.None:
                default:
                    break;
                }
            }

            AddBorder(si, x, y, height, width);                                 // add any required border

            return;
        }