Ejemplo n.º 1
0
        /**
         * render inline area to PDF
         *
         * @param area inline area to render
         */

        public void RenderWordArea(WordArea area)
        {
            // TODO: I don't understand why we are locking the private member
            // _wordAreaPDF.  Maybe this string buffer was originally static? (MG)
            lock (_wordAreaPDF)
            {
                StringBuilder pdf = _wordAreaPDF;
                pdf.Length = 0;

                GdiKerningPairs kerning          = null;
                bool            kerningAvailable = false;

                // If no options are supplied, by default we do not enable kerning
                if (options != null && options.Kerning)
                {
                    kerning = area.GetFontState().Kerning;
                    if (kerning != null && (kerning.Count > 0))
                    {
                        kerningAvailable = true;
                    }
                }

                String name = area.GetFontState().FontName;
                int    size = area.GetFontState().FontSize;

                // This assumes that *all* CIDFonts use a /ToUnicode mapping
                Font font         = (Font)area.GetFontState().FontInfo.GetFontByName(name);
                bool useMultiByte = font.MultiByteFont;

                string startText = useMultiByte ? "<" : "(";
                string endText   = useMultiByte ? "> " : ") ";

                if ((!name.Equals(this.currentFontName)) || (size != this.currentFontSize))
                {
                    CloseText();

                    this.currentFontName = name;
                    this.currentFontSize = size;
                    pdf = pdf.Append("/" + name + " " +
                                     PdfNumber.doubleOut(size / 1000f) + " Tf\n");
                }

                // Do letter spacing (must be outside of [...] TJ]
                float letterspacing = ((float)area.GetFontState().LetterSpacing) / 1000f;
                if (letterspacing != this.currentLetterSpacing)
                {
                    this.currentLetterSpacing = letterspacing;
                    CloseText();
                    pdf.Append(PdfNumber.doubleOut(letterspacing));
                    pdf.Append(" Tc\n");
                }

                PdfColor areaColor = this.currentFill;

                if (areaColor == null || areaColor.getRed() != (double)area.getRed() ||
                    areaColor.getGreen() != (double)area.getGreen() ||
                    areaColor.getBlue() != (double)area.getBlue())
                {
                    areaColor = new PdfColor((double)area.getRed(),
                                             (double)area.getGreen(),
                                             (double)area.getBlue());


                    CloseText();
                    this.currentFill = areaColor;
                    pdf.Append(this.currentFill.getColorSpaceOut(true));
                }


                int rx = this.currentXPosition;
                int bl = this.currentYPosition;

                AddWordLines(area, rx, bl, size, areaColor);

                if (!textOpen || bl != prevWordY)
                {
                    CloseText();

                    pdf.Append("1 0 0 1 " + PdfNumber.doubleOut(rx / 1000f) +
                               " " + PdfNumber.doubleOut(bl / 1000f) + " Tm [" + startText);
                    prevWordY = bl;
                    textOpen  = true;
                }
                else
                {
                    // express the space between words in thousandths of an em
                    int   space  = prevWordX - rx + prevWordWidth;
                    float emDiff = (float)space / (float)currentFontSize * 1000f;
                    // this prevents a problem in Acrobat Reader where large
                    // numbers cause text to disappear or default to a limit
                    if (emDiff < -33000)
                    {
                        CloseText();

                        pdf.Append("1 0 0 1 " + PdfNumber.doubleOut(rx / 1000f) +
                                   " " + PdfNumber.doubleOut(bl / 1000f) + " Tm [" + startText);
                        textOpen = true;
                    }
                    else
                    {
                        pdf.Append(PdfNumber.doubleOut(emDiff));
                        pdf.Append(" ");
                        pdf.Append(startText);
                    }
                }
                prevWordWidth = area.getContentWidth();
                prevWordX     = rx;

                string s;
                if (area.getPageNumberID() != null)
                {
                    // This text is a page number, so resolve it
                    s = idReferences.getPageNumber(area.getPageNumberID());
                    if (s == null)
                    {
                        s = String.Empty;
                    }
                }
                else
                {
                    s = area.getText();
                }

                int wordLength = s.Length;
                for (int index = 0; index < wordLength; index++)
                {
                    ushort ch = area.GetFontState().MapCharacter(s[index]);

                    if (!useMultiByte)
                    {
                        if (ch > 127)
                        {
                            pdf.Append("\\");
                            pdf.Append(Convert.ToString((int)ch, 8));
                        }
                        else
                        {
                            switch (ch)
                            {
                            case '(':
                            case ')':
                            case '\\':
                                pdf.Append("\\");
                                break;
                            }
                            pdf.Append((char)ch);
                        }
                    }
                    else
                    {
                        pdf.Append(GetUnicodeString(ch));
                    }

                    if (kerningAvailable && (index + 1) < wordLength)
                    {
                        ushort ch2 = area.GetFontState().MapCharacter(s[index + 1]);
                        AddKerning(pdf, ch, ch2, kerning, startText, endText);
                    }
                }
                pdf.Append(endText);

                currentStream.Write(pdf.ToString());

                this.currentXPosition += area.getContentWidth();
            }
        }