Esempio n. 1
0
        /**
         * Creates a line from the chunk array.
         * @param width the width of the line
         * @return the line or null if no more chunks
         */
        protected PdfLine CreateLine(float width)
        {
            if (chunks.Count == 0)
            {
                return(null);
            }
            splittedChunkText   = null;
            currentStandbyChunk = null;
            PdfLine line = new PdfLine(0, width, alignment, 0);
            string  total;

            for (currentChunkMarker = 0; currentChunkMarker < chunks.Count; ++currentChunkMarker)
            {
                PdfChunk original = (PdfChunk)(chunks[currentChunkMarker]);
                total = original.ToString();
                currentStandbyChunk = line.Add(original);
                if (currentStandbyChunk != null)
                {
                    splittedChunkText = original.ToString();
                    original.Value    = total;
                    return(line);
                }
            }
            return(line);
        }
Esempio n. 2
0
        // constructors

        /**
         * Constructs a <CODE>PdfChunk</CODE>-object.
         *
         * @param string the content of the <CODE>PdfChunk</CODE>-object
         * @param font the <CODE>PdfFont</CODE>
         * @param attributes the metrics attributes
         * @param noStroke the non metric attributes
         */

        internal PdfChunk(string str, PdfChunk other)
        {
            thisChunk[0]    = this;
            value           = str;
            this.font       = other.font;
            this.attributes = other.attributes;
            this.noStroke   = other.noStroke;
            this.baseFont   = other.baseFont;
            Object[] obj = (Object[])attributes[Chunk.IMAGE];
            if (obj == null)
            {
                image = null;
            }
            else
            {
                image         = (Image)obj[0];
                offsetX       = (float)obj[1];
                offsetY       = (float)obj[2];
                changeLeading = (bool)obj[3];
            }
            encoding       = font.Font.Encoding;
            splitCharacter = (ISplitCharacter)noStroke[Chunk.SPLITCHARACTER];
            if (splitCharacter == null)
            {
                splitCharacter = DefaultSplitCharacter.DEFAULT;
            }
        }
Esempio n. 3
0
        public float GetWidthCorrected(float charSpacing, float wordSpacing)
        {
            float total = 0;

            for (int k = 0; k < line.Count; ++k)
            {
                PdfChunk ck = (PdfChunk)line[k];
                total += ck.GetWidthCorrected(charSpacing, wordSpacing);
            }
            return(total);
        }
Esempio n. 4
0
 private void AddToLine(PdfChunk chunk)
 {
     if (chunk.ChangeLeading && chunk.IsImage())
     {
         float f = chunk.Image.ScaledHeight + chunk.ImageOffsetY + chunk.Image.BorderWidthTop;
         if (f > height)
         {
             height = f;
         }
     }
     line.Add(chunk);
 }
Esempio n. 5
0
        /**
         * Normalizes the list of chunks when the line is accepted.
         */
        protected void ShortenChunkArray()
        {
            if (currentChunkMarker < 0)
            {
                return;
            }
            if (currentChunkMarker >= chunks.Count)
            {
                chunks.Clear();
                return;
            }
            PdfChunk split = (PdfChunk)(chunks[currentChunkMarker]);

            split.Value = splittedChunkText;
            chunks[currentChunkMarker] = currentStandbyChunk;
            for (int j = currentChunkMarker - 1; j >= 0; --j)
            {
                chunks.RemoveAt(j);
            }
        }
Esempio n. 6
0
        private void AddList(List list, float left, float right, int alignment)
        {
            PdfChunk  chunk;
            PdfChunk  overflow;
            ArrayList allActions = new ArrayList();

            ProcessActions(list, null, allActions);
            int aCounter = 0;

            foreach (IElement ele in list.Items)
            {
                switch (ele.Type)
                {
                case Element.LISTITEM:
                    ListItem item = (ListItem)ele;
                    line          = new PdfLine(left + item.IndentationLeft, right, alignment, item.Leading);
                    line.ListItem = item;
                    foreach (Chunk c in item.Chunks)
                    {
                        chunk = new PdfChunk(c, (PdfAction)(allActions[aCounter++]));
                        while ((overflow = line.Add(chunk)) != null)
                        {
                            AddLine(line);
                            line  = new PdfLine(left + item.IndentationLeft, right, alignment, item.Leading);
                            chunk = overflow;
                        }
                        line.ResetAlignment();
                        AddLine(line);
                        line = new PdfLine(left + item.IndentationLeft, right, alignment, leading);
                    }
                    break;

                case Element.LIST:
                    List sublist = (List)ele;
                    AddList(sublist, left + sublist.IndentationLeft, right, alignment);
                    break;
                }
            }
        }
Esempio n. 7
0
        // constructors

        /**
         * Constructs a <CODE>PdfCell</CODE>-object.
         *
         * @param   cell        the original <CODE>Cell</CODE>
         * @param   rownumber   the number of the <CODE>Row</CODE> the <CODE>Cell</CODE> was in.
         * @param   left        the left border of the <CODE>PdfCell</CODE>
         * @param   right       the right border of the <CODE>PdfCell</CODE>
         * @param   top         the top border of the <CODE>PdfCell</CODE>
         * @param   cellspacing the cellspacing of the <CODE>Table</CODE>
         * @param   cellpadding the cellpadding of the <CODE>Table</CODE>
         */

        public PdfCell(Cell cell, int rownumber, float left, float right, float top, float cellspacing, float cellpadding) : base(left, top, right, top)
        {
            // copying the other Rectangle attributes from class Cell
            CloneNonPositionParameters(cell);
            this.cellpadding       = cellpadding;
            this.cellspacing       = cellspacing;
            this.verticalAlignment = cell.VerticalAlignment;
            this.useAscender       = cell.UseAscender;
            this.useDescender      = cell.UseDescender;
            this.useBorderPadding  = cell.UseBorderPadding;

            // initialisation of some parameters
            PdfChunk chunk;
            PdfChunk overflow;

            lines   = new ArrayList();
            images  = new ArrayList();
            leading = cell.Leading;
            int alignment = cell.HorizontalAlignment;

            left  += cellspacing + cellpadding;
            right -= cellspacing + cellpadding;

            left         += GetBorderWidthInside(LEFT_BORDER);
            right        -= GetBorderWidthInside(RIGHT_BORDER);
            contentHeight = 0;
            rowspan       = cell.Rowspan;

            ArrayList allActions;
            int       aCounter;

            // we loop over all the elements of the cell
            foreach (IElement ele in cell.Elements)
            {
                switch (ele.Type)
                {
                case Element.JPEG:
                case Element.JPEG2000:
                case Element.JBIG2:
                case Element.IMGRAW:
                case Element.IMGTEMPLATE:
                    AddImage((Image)ele, left, right, 0.4f * leading, alignment);
                    break;

                // if the element is a list
                case Element.LIST:
                    if (line != null && line.Size > 0)
                    {
                        line.ResetAlignment();
                        AddLine(line);
                    }
                    // we loop over all the listitems
                    AddList((List)ele, left, right, alignment);
                    line = new PdfLine(left, right, alignment, leading);
                    break;

                // if the element is something else
                default:
                    allActions = new ArrayList();
                    ProcessActions(ele, null, allActions);
                    aCounter = 0;

                    float currentLineLeading = leading;
                    float currentLeft        = left;
                    float currentRight       = right;
                    if (ele is Phrase)
                    {
                        currentLineLeading = ((Phrase)ele).Leading;
                    }
                    if (ele is Paragraph)
                    {
                        Paragraph p = (Paragraph)ele;
                        currentLeft  += p.IndentationLeft;
                        currentRight -= p.IndentationRight;
                    }
                    if (line == null)
                    {
                        line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading);
                    }
                    // we loop over the chunks
                    ArrayList chunks = ele.Chunks;
                    if (chunks.Count == 0)
                    {
                        AddLine(line);     // add empty line - all cells need some lines even if they are empty
                        line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading);
                    }
                    else
                    {
                        foreach (Chunk c in chunks)
                        {
                            chunk = new PdfChunk(c, (PdfAction)allActions[aCounter++]);
                            while ((overflow = line.Add(chunk)) != null)
                            {
                                AddLine(line);
                                line  = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading);
                                chunk = overflow;
                            }
                        }
                    }
                    // if the element is a paragraph, section or chapter, we reset the alignment and add the line
                    switch (ele.Type)
                    {
                    case Element.PARAGRAPH:
                    case Element.SECTION:
                    case Element.CHAPTER:
                        line.ResetAlignment();
                        FlushCurrentLine();
                        break;
                    }
                    break;
                }
            }
            FlushCurrentLine();
            if (lines.Count > cell.MaxLines)
            {
                while (lines.Count > cell.MaxLines)
                {
                    RemoveLine(lines.Count - 1);
                }
                if (cell.MaxLines > 0)
                {
                    String more = cell.ShowTruncation;
                    if (more != null && more.Length > 0)
                    {
                        // Denote that the content has been truncated
                        lastLine = (PdfLine)lines[lines.Count - 1];
                        if (lastLine.Size >= 0)
                        {
                            PdfChunk lastChunk = lastLine.GetChunk(lastLine.Size - 1);
                            float    moreWidth = new PdfChunk(more, lastChunk).Width;
                            while (lastChunk.ToString().Length > 0 && lastChunk.Width + moreWidth > right - left)
                            {
                                // Remove characters to leave room for the 'more' indicator
                                lastChunk.Value = lastChunk.ToString().Substring(0, lastChunk.Length - 1);
                            }
                            lastChunk.Value = lastChunk.ToString() + more;
                        }
                        else
                        {
                            lastLine.Add(new PdfChunk(new Chunk(more), null));
                        }
                    }
                }
            }
            // we set some additional parameters
            if (useDescender && lastLine != null)
            {
                contentHeight -= lastLine.Descender;
            }

            // adjust first line height so that it touches the top
            if (lines.Count > 0)
            {
                firstLine = (PdfLine)lines[0];
                float firstLineRealHeight = FirstLineRealHeight;
                contentHeight   -= firstLine.Height;
                firstLine.height = firstLineRealHeight;
                contentHeight   += firstLineRealHeight;
            }

            float newBottom = top - contentHeight - (2f * Cellpadding) - (2f * Cellspacing);

            newBottom -= GetBorderWidthInside(TOP_BORDER) + GetBorderWidthInside(BOTTOM_BORDER);
            Bottom     = newBottom;

            this.rownumber = rownumber;
        }
Esempio n. 8
0
        /**
         * Truncates this <CODE>PdfChunk</CODE> if it's too long for the given width.
         * <P>
         * Returns <VAR>null</VAR> if the <CODE>PdfChunk</CODE> wasn't truncated.
         *
         * @param       width       a given width
         * @return      the <CODE>PdfChunk</CODE> that doesn't fit into the width.
         */

        internal PdfChunk Truncate(float width)
        {
            if (image != null)
            {
                if (image.ScaledWidth > width)
                {
                    PdfChunk pc = new PdfChunk("", this);
                    value = "";
                    attributes.Remove(Chunk.IMAGE);
                    image = null;
                    font  = PdfFont.DefaultFont;
                    return(pc);
                }
                else
                {
                    return(null);
                }
            }

            int   currentPosition = 0;
            float currentWidth    = 0;

            // it's no use trying to split if there isn't even enough place for a space
            if (width < font.Width())
            {
                string returnValue = value.Substring(1);
                value = value.Substring(0, 1);
                PdfChunk pc = new PdfChunk(returnValue, this);
                return(pc);
            }

            // loop over all the characters of a string
            // or until the totalWidth is reached
            int  length    = value.Length;
            bool surrogate = false;

            while (currentPosition < length)
            {
                // the width of every character is added to the currentWidth
                surrogate = Utilities.IsSurrogatePair(value, currentPosition);
                if (surrogate)
                {
                    currentWidth += font.Width(Utilities.ConvertToUtf32(value, currentPosition));
                }
                else
                {
                    currentWidth += font.Width(value[currentPosition]);
                }
                if (currentWidth > width)
                {
                    break;
                }
                if (surrogate)
                {
                    currentPosition++;
                }
                currentPosition++;
            }

            // if all the characters fit in the total width, null is returned (there is no overflow)
            if (currentPosition == length)
            {
                return(null);
            }

            // otherwise, the string has to be truncated
            //currentPosition -= 2;
            // we have to chop off minimum 1 character from the chunk
            if (currentPosition == 0)
            {
                currentPosition = 1;
                if (surrogate)
                {
                    ++currentPosition;
                }
            }
            string retVal = value.Substring(currentPosition);

            value = value.Substring(0, currentPosition);
            PdfChunk tmp = new PdfChunk(retVal, this);

            return(tmp);
        }
Esempio n. 9
0
        // constructors
        /**
         * Constructs a <CODE>PdfCell</CODE>-object.
         *
         * @param   cell        the original <CODE>Cell</CODE>
         * @param   rownumber   the number of the <CODE>Row</CODE> the <CODE>Cell</CODE> was in.
         * @param   left        the left border of the <CODE>PdfCell</CODE>
         * @param   right       the right border of the <CODE>PdfCell</CODE>
         * @param   top         the top border of the <CODE>PdfCell</CODE>
         * @param   cellspacing the cellspacing of the <CODE>Table</CODE>
         * @param   cellpadding the cellpadding of the <CODE>Table</CODE>
         */
        public PdfCell(Cell cell, int rownumber, float left, float right, float top, float cellspacing, float cellpadding)
            : base(left, top, right, top)
        {
            // copying the other Rectangle attributes from class Cell
            CloneNonPositionParameters(cell);
            this.cellpadding = cellpadding;
            this.cellspacing = cellspacing;
            this.verticalAlignment = cell.VerticalAlignment;
            this.useAscender = cell.UseAscender;
            this.useDescender = cell.UseDescender;
            this.useBorderPadding = cell.UseBorderPadding;

            // initialisation of some parameters
            PdfChunk chunk;
            PdfChunk overflow;
            lines = new ArrayList();
            images = new ArrayList();
            leading = cell.Leading;
            int alignment = cell.HorizontalAlignment;
            left += cellspacing + cellpadding;
            right -= cellspacing + cellpadding;

            left += GetBorderWidthInside(LEFT_BORDER);
            right -= GetBorderWidthInside(RIGHT_BORDER);
            contentHeight = 0;
            rowspan = cell.Rowspan;

            ArrayList allActions;
            int aCounter;
            // we loop over all the elements of the cell
            foreach (IElement ele in cell.Elements) {
                switch (ele.Type) {
                    case Element.JPEG:
                    case Element.JPEG2000:
                    case Element.JBIG2:
                    case Element.IMGRAW:
                    case Element.IMGTEMPLATE:
                        AddImage((Image)ele, left, right, 0.4f * leading, alignment);
                        break;
                        // if the element is a list
                    case Element.LIST:
                        if (line != null && line.Size > 0) {
                            line.ResetAlignment();
                            AddLine(line);
                        }
                        // we loop over all the listitems
                        AddList((List)ele, left, right, alignment);
                        line = new PdfLine(left, right, alignment, leading);
                        break;
                        // if the element is something else
                    default:
                        allActions = new ArrayList();
                        ProcessActions(ele, null, allActions);
                        aCounter = 0;

                        float currentLineLeading = leading;
                        float currentLeft = left;
                        float currentRight = right;
                        if (ele is Phrase) {
                            currentLineLeading = ((Phrase) ele).Leading;
                        }
                        if (ele is Paragraph) {
                            Paragraph p = (Paragraph) ele;
                            currentLeft += p.IndentationLeft;
                            currentRight -= p.IndentationRight;
                        }
                        if (line == null) {
                            line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading);
                        }
                        // we loop over the chunks
                        ArrayList chunks = ele.Chunks;
                        if (chunks.Count == 0) {
                            AddLine(line); // add empty line - all cells need some lines even if they are empty
                            line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading);
                        }
                        else {
                            foreach (Chunk c in chunks) {
                                chunk = new PdfChunk(c, (PdfAction)allActions[aCounter++]);
                                while ((overflow = line.Add(chunk)) != null) {
                                    AddLine(line);
                                    line = new PdfLine(currentLeft, currentRight, alignment, currentLineLeading);
                                    chunk = overflow;
                                }
                            }
                        }
                        // if the element is a paragraph, section or chapter, we reset the alignment and add the line
                        switch (ele.Type) {
                            case Element.PARAGRAPH:
                            case Element.SECTION:
                            case Element.CHAPTER:
                                line.ResetAlignment();
                                FlushCurrentLine();
                                break;
                        }
                        break;
                }
            }
            FlushCurrentLine();
            if (lines.Count > cell.MaxLines) {
                while (lines.Count > cell.MaxLines) {
                    RemoveLine(lines.Count - 1);
                }
                if (cell.MaxLines > 0) {
                    String more = cell.ShowTruncation;
                    if (more != null && more.Length > 0) {
                        // Denote that the content has been truncated
                        lastLine = (PdfLine) lines[lines.Count - 1];
                        if (lastLine.Size >= 0) {
                            PdfChunk lastChunk = lastLine.GetChunk(lastLine.Size - 1);
                            float moreWidth = new PdfChunk(more, lastChunk).Width;
                            while (lastChunk.ToString().Length > 0 && lastChunk.Width + moreWidth > right - left) {
                                // Remove characters to leave room for the 'more' indicator
                                lastChunk.Value = lastChunk.ToString().Substring(0, lastChunk.Length - 1);
                            }
                            lastChunk.Value = lastChunk.ToString() + more;
                        } else {
                            lastLine.Add(new PdfChunk(new Chunk(more), null));
                        }
                    }
                }
            }
            // we set some additional parameters
            if (useDescender && lastLine != null) {
                contentHeight -= lastLine.Descender;
            }

            // adjust first line height so that it touches the top
            if (lines.Count > 0) {
                firstLine = (PdfLine) lines[0];
                float firstLineRealHeight = FirstLineRealHeight;
                contentHeight -= firstLine.Height;
                firstLine.height = firstLineRealHeight;
                contentHeight += firstLineRealHeight;
            }

            float newBottom = top - contentHeight - (2f * Cellpadding) - (2f * Cellspacing);
            newBottom -= GetBorderWidthInside(TOP_BORDER) + GetBorderWidthInside(BOTTOM_BORDER);
            Bottom = newBottom;

            this.rownumber = rownumber;
        }
Esempio n. 10
0
        // methods
        /**
         * Adds a <CODE>PdfChunk</CODE> to the <CODE>PdfLine</CODE>.
         *
         * @param        chunk        the <CODE>PdfChunk</CODE> to add
         * @return        <CODE>null</CODE> if the chunk could be added completely; if not
         *                a <CODE>PdfChunk</CODE> containing the part of the chunk that could
         *                not be added is returned
         */
        internal PdfChunk Add(PdfChunk chunk)
        {
            // nothing happens if the chunk is null.
            if (chunk == null || chunk.ToString().Equals("")) {
                return null;
            }

            // we split the chunk to be added
            PdfChunk overflow = chunk.Split(width);
            newlineSplit = (chunk.IsNewlineSplit() || overflow == null);
            //        if (chunk.IsNewlineSplit() && alignment == Element.ALIGN_JUSTIFIED)
            //            alignment = Element.ALIGN_LEFT;
            if (chunk.IsTab()) {
                Object[] tab = (Object[])chunk.GetAttribute(Chunk.TAB);
                float tabPosition = (float)tab[1];
                bool newline = (bool)tab[2];
                if (newline && tabPosition < originalWidth - width) {
                    return chunk;
                }
                width = originalWidth - tabPosition;
                chunk.AdjustLeft(left);
                AddToLine(chunk);
            }
            // if the length of the chunk > 0 we add it to the line
            else if (chunk.Length > 0 || chunk.IsImage()) {
                if (overflow != null)
                    chunk.TrimLastSpace();
                width -= chunk.Width;
                AddToLine(chunk);
            }

                // if the length == 0 and there were no other chunks added to the line yet,
                // we risk to end up in an endless loop trying endlessly to add the same chunk
            else if (line.Count < 1) {
                chunk = overflow;
                overflow = chunk.Truncate(width);
                width -= chunk.Width;
                if (chunk.Length > 0) {
                    AddToLine(chunk);
                    return overflow;
                }
                    // if the chunck couldn't even be truncated, we add everything, so be it
                else {
                    if (overflow != null)
                        AddToLine(chunk);
                    return null;
                }
            }
            else {
                width += ((PdfChunk)(line[line.Count - 1])).TrimLastSpace();
            }
            return overflow;
        }
Esempio n. 11
0
        /**
         * Splits this <CODE>PdfChunk</CODE> if it's too long for the given width.
         * <P>
         * Returns <VAR>null</VAR> if the <CODE>PdfChunk</CODE> wasn't truncated.
         *
         * @param       width       a given width
         * @return      the <CODE>PdfChunk</CODE> that doesn't fit into the width.
         */
        internal PdfChunk Split(float width)
        {
            newlineSplit = false;
            if (image != null) {
                if (image.ScaledWidth > width) {
                    PdfChunk pc = new PdfChunk(Chunk.OBJECT_REPLACEMENT_CHARACTER, this);
                    value = "";
                    attributes = new Hashtable();
                    image = null;
                    font = PdfFont.DefaultFont;
                    return pc;
                }
                else
                    return null;
            }
            IHyphenationEvent hyphenationEvent = (IHyphenationEvent)noStroke[Chunk.HYPHENATION];
            int currentPosition = 0;
            int splitPosition = -1;
            float currentWidth = 0;

            // loop over all the characters of a string
            // or until the totalWidth is reached
            int lastSpace = -1;
            float lastSpaceWidth = 0;
            int length = value.Length;
            char[] valueArray = value.ToCharArray();
            char character = (char)0;
            BaseFont ft = font.Font;
            bool surrogate = false;
            if (ft.FontType == BaseFont.FONT_TYPE_CJK && ft.GetUnicodeEquivalent(' ') != ' ') {
                while (currentPosition < length) {
                    // the width of every character is added to the currentWidth
                    char cidChar = valueArray[currentPosition];
                    character = (char)ft.GetUnicodeEquivalent(cidChar);
                    // if a newLine or carriageReturn is encountered
                    if (character == '\n') {
                        newlineSplit = true;
                        string returnValue = value.Substring(currentPosition + 1);
                        value = value.Substring(0, currentPosition);
                        if (value.Length < 1) {
                            value = "\u0001";
                        }
                        PdfChunk pc = new PdfChunk(returnValue, this);
                        return pc;
                    }
                    currentWidth += font.Width(cidChar);
                    if (character == ' ') {
                        lastSpace = currentPosition + 1;
                        lastSpaceWidth = currentWidth;
                    }
                    if (currentWidth > width)
                        break;
                    // if a split-character is encountered, the splitPosition is altered
                    if (splitCharacter.IsSplitCharacter(0, currentPosition, length, valueArray, thisChunk))
                        splitPosition = currentPosition + 1;
                    currentPosition++;
                }
            }
            else {
                while (currentPosition < length) {
                    // the width of every character is added to the currentWidth
                    character = valueArray[currentPosition];
                    // if a newLine or carriageReturn is encountered
                    if (character == '\r' || character == '\n') {
                        newlineSplit = true;
                        int inc = 1;
                        if (character == '\r' && currentPosition + 1 < length && valueArray[currentPosition + 1] == '\n')
                            inc = 2;
                        string returnValue = value.Substring(currentPosition + inc);
                        value = value.Substring(0, currentPosition);
                        if (value.Length < 1) {
                            value = " ";
                        }
                        PdfChunk pc = new PdfChunk(returnValue, this);
                        return pc;
                    }
                    surrogate = Utilities.IsSurrogatePair(valueArray, currentPosition);
                    if (surrogate)
                        currentWidth += font.Width(Utilities.ConvertToUtf32(valueArray[currentPosition], valueArray[currentPosition + 1]));
                    else
                        currentWidth += font.Width(character);
                    if (character == ' ') {
                        lastSpace = currentPosition + 1;
                        lastSpaceWidth = currentWidth;
                    }
                    if (surrogate)
                        currentPosition++;
                    if (currentWidth > width)
                        break;
                    // if a split-character is encountered, the splitPosition is altered
                    if (splitCharacter.IsSplitCharacter(0, currentPosition, length, valueArray, null))
                        splitPosition = currentPosition + 1;
                    currentPosition++;
                }
            }

            // if all the characters fit in the total width, null is returned (there is no overflow)
            if (currentPosition == length) {
                return null;
            }
            // otherwise, the string has to be truncated
            if (splitPosition < 0) {
                string returnValue = value;
                value = "";
                PdfChunk pc = new PdfChunk(returnValue, this);
                return pc;
            }
            if (lastSpace > splitPosition && splitCharacter.IsSplitCharacter(0, 0, 1, singleSpace, null))
                splitPosition = lastSpace;
            if (hyphenationEvent != null && lastSpace >= 0 && lastSpace < currentPosition) {
                int wordIdx = GetWord(value, lastSpace);
                if (wordIdx > lastSpace) {
                    string pre = hyphenationEvent.GetHyphenatedWordPre(value.Substring(lastSpace, wordIdx - lastSpace), font.Font, font.Size, width - lastSpaceWidth);
                    string post = hyphenationEvent.HyphenatedWordPost;
                    if (pre.Length > 0) {
                        string returnValue = post + value.Substring(wordIdx);
                        value = Trim(value.Substring(0, lastSpace) + pre);
                        PdfChunk pc = new PdfChunk(returnValue, this);
                        return pc;
                    }
                }
            }
            string retVal = value.Substring(splitPosition);
            value = Trim(value.Substring(0, splitPosition));
            PdfChunk tmp = new PdfChunk(retVal, this);
            return tmp;
        }
Esempio n. 12
0
 // constructors
 /**
  * Constructs a <CODE>PdfChunk</CODE>-object.
  *
  * @param string the content of the <CODE>PdfChunk</CODE>-object
  * @param font the <CODE>PdfFont</CODE>
  * @param attributes the metrics attributes
  * @param noStroke the non metric attributes
  */
 internal PdfChunk(string str, PdfChunk other)
 {
     thisChunk[0] = this;
     value = str;
     this.font = other.font;
     this.attributes = other.attributes;
     this.noStroke = other.noStroke;
     this.baseFont = other.baseFont;
     Object[] obj = (Object[])attributes[Chunk.IMAGE];
     if (obj == null)
         image = null;
     else {
         image = (Image)obj[0];
         offsetX = (float)obj[1];
         offsetY = (float)obj[2];
         changeLeading = (bool)obj[3];
     }
     encoding = font.Font.Encoding;
     splitCharacter = (ISplitCharacter)noStroke[Chunk.SPLITCHARACTER];
     if (splitCharacter == null)
         splitCharacter = DefaultSplitCharacter.DEFAULT;
 }
 /**
  * Returns the current character
  * @param current current position in the array
  * @param	cc		the character array that has to be checked
  * @param ck chunk array
  * @return	the current character
  */
 protected char GetCurrentCharacter(int current, char[] cc, PdfChunk[] ck)
 {
     if (ck == null) {
         return (char)cc[current];
     }
     return (char)ck[Math.Min(current, ck.Length - 1)].GetUnicodeEquivalent(cc[current]);
 }
Esempio n. 14
0
 public void AddChunk(PdfChunk chunk)
 {
     chunks.Add(chunk);
 }
Esempio n. 15
0
        // methods

        /**
         * Adds a <CODE>PdfChunk</CODE> to the <CODE>PdfLine</CODE>.
         *
         * @param        chunk        the <CODE>PdfChunk</CODE> to add
         * @return        <CODE>null</CODE> if the chunk could be added completely; if not
         *                a <CODE>PdfChunk</CODE> containing the part of the chunk that could
         *                not be added is returned
         */

        internal PdfChunk Add(PdfChunk chunk)
        {
            // nothing happens if the chunk is null.
            if (chunk == null || chunk.ToString().Equals(""))
            {
                return(null);
            }

            // we split the chunk to be added
            PdfChunk overflow = chunk.Split(width);

            newlineSplit = (chunk.IsNewlineSplit() || overflow == null);
            //        if (chunk.IsNewlineSplit() && alignment == Element.ALIGN_JUSTIFIED)
            //            alignment = Element.ALIGN_LEFT;
            if (chunk.IsTab())
            {
                Object[] tab         = (Object[])chunk.GetAttribute(Chunk.TAB);
                float    tabPosition = (float)tab[1];
                bool     newline     = (bool)tab[2];
                if (newline && tabPosition < originalWidth - width)
                {
                    return(chunk);
                }
                width = originalWidth - tabPosition;
                chunk.AdjustLeft(left);
                AddToLine(chunk);
            }
            // if the length of the chunk > 0 we add it to the line
            else if (chunk.Length > 0 || chunk.IsImage())
            {
                if (overflow != null)
                {
                    chunk.TrimLastSpace();
                }
                width -= chunk.Width;
                AddToLine(chunk);
            }

            // if the length == 0 and there were no other chunks added to the line yet,
            // we risk to end up in an endless loop trying endlessly to add the same chunk
            else if (line.Count < 1)
            {
                chunk    = overflow;
                overflow = chunk.Truncate(width);
                width   -= chunk.Width;
                if (chunk.Length > 0)
                {
                    AddToLine(chunk);
                    return(overflow);
                }
                // if the chunck couldn't even be truncated, we add everything, so be it
                else
                {
                    if (overflow != null)
                    {
                        AddToLine(chunk);
                    }
                    return(null);
                }
            }
            else
            {
                width += ((PdfChunk)(line[line.Count - 1])).TrimLastSpace();
            }
            return(overflow);
        }
Esempio n. 16
0
 private void AddList(List list, float left, float right, int alignment)
 {
     PdfChunk chunk;
     PdfChunk overflow;
     ArrayList allActions = new ArrayList();
     ProcessActions(list, null, allActions);
     int aCounter = 0;
     foreach (IElement ele in list.Items) {
         switch (ele.Type) {
             case Element.LISTITEM:
                 ListItem item = (ListItem)ele;
                 line = new PdfLine(left + item.IndentationLeft, right, alignment, item.Leading);
                 line.ListItem = item;
                 foreach (Chunk c in item.Chunks) {
                     chunk = new PdfChunk(c, (PdfAction)(allActions[aCounter++]));
                     while ((overflow = line.Add(chunk)) != null) {
                         AddLine(line);
                         line = new PdfLine(left + item.IndentationLeft, right, alignment, item.Leading);
                         chunk = overflow;
                     }
                     line.ResetAlignment();
                     AddLine(line);
                     line = new PdfLine(left + item.IndentationLeft, right, alignment, leading);
                 }
                 break;
             case Element.LIST:
                 List sublist = (List)ele;
                 AddList(sublist, left + sublist.IndentationLeft, right, alignment);
                 break;
         }
     }
 }
Esempio n. 17
0
 /**
  * Creates a line from the chunk array.
  * @param width the width of the line
  * @return the line or null if no more chunks
  */
 protected PdfLine CreateLine(float width)
 {
     if (chunks.Count == 0)
         return null;
     splittedChunkText = null;
     currentStandbyChunk = null;
     PdfLine line = new PdfLine(0, width, alignment, 0);
     string total;
     for (currentChunkMarker = 0; currentChunkMarker < chunks.Count; ++currentChunkMarker) {
         PdfChunk original = (PdfChunk)(chunks[currentChunkMarker]);
         total = original.ToString();
         currentStandbyChunk = line.Add(original);
         if (currentStandbyChunk != null) {
             splittedChunkText = original.ToString();
             original.Value = total;
             return line;
         }
     }
     return line;
 }
Esempio n. 18
0
 public void AddPiece(char c, PdfChunk chunk)
 {
     if (totalTextLength >= pieceSize) {
         char[] tempText = text;
         PdfChunk[] tempDetailChunks = detailChunks;
         pieceSize *= 2;
         text = new char[pieceSize];
         detailChunks = new PdfChunk[pieceSize];
         Array.Copy(tempText, 0, text, 0, totalTextLength);
         Array.Copy(tempDetailChunks, 0, detailChunks, 0, totalTextLength);
     }
     text[totalTextLength] = c;
     detailChunks[totalTextLength++] = chunk;
 }
 /**
  * Checks if a character can be used to split a <CODE>PdfString</CODE>.
  * <P>
  * for the moment every character less than or equal to SPACE, the character '-'
  * and some specific unicode ranges are 'splitCharacters'.
  *
  * @param start start position in the array
  * @param current current position in the array
  * @param end end position in the array
  * @param	cc		the character array that has to be checked
  * @param ck chunk array
  * @return	<CODE>true</CODE> if the character can be used to split a string, <CODE>false</CODE> otherwise
  */
 public bool IsSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck)
 {
     char c = GetCurrentCharacter(current, cc, ck);
     if (c <= ' ' || c == '-' || c == '\u2010') {
         return true;
     }
     if (c < 0x2002)
         return false;
     return ((c >= 0x2002 && c <= 0x200b)
         || (c >= 0x2e80 && c < 0xd7a0)
         || (c >= 0xf900 && c < 0xfb00)
         || (c >= 0xfe30 && c < 0xfe50)
         || (c >= 0xff61 && c < 0xffa0));
 }
Esempio n. 20
0
 public ArrayList CreateArrayOfPdfChunks(int startIdx, int endIdx, PdfChunk extraPdfChunk)
 {
     bool bidi = (runDirection == PdfWriter.RUN_DIRECTION_LTR || runDirection == PdfWriter.RUN_DIRECTION_RTL);
     if (bidi)
         Reorder(startIdx, endIdx);
     ArrayList ar = new ArrayList();
     PdfChunk refCk = detailChunks[startIdx];
     PdfChunk ck = null;
     StringBuilder buf = new StringBuilder();
     char c;
     int idx = 0;
     for (; startIdx <= endIdx; ++startIdx) {
         idx = bidi ? indexChars[startIdx] : startIdx;
         c = text[idx];
         ck = detailChunks[idx];
         if (PdfChunk.NoPrint(ck.GetUnicodeEquivalent(c)))
             continue;
         if (ck.IsImage() || ck.IsSeparator() || ck.IsTab()) {
             if (buf.Length > 0) {
                 ar.Add(new PdfChunk(buf.ToString(), refCk));
                 buf = new StringBuilder();
             }
             ar.Add(ck);
         }
         else if (ck == refCk) {
             buf.Append(c);
         }
         else {
             if (buf.Length > 0) {
                 ar.Add(new PdfChunk(buf.ToString(), refCk));
                 buf = new StringBuilder();
             }
             if (!ck.IsImage() && !ck.IsSeparator() && !ck.IsTab())
                 buf.Append(c);
             refCk = ck;
         }
     }
     if (buf.Length > 0) {
         ar.Add(new PdfChunk(buf.ToString(), refCk));
     }
     if (extraPdfChunk != null)
         ar.Add(extraPdfChunk);
     return ar;
 }
Esempio n. 21
0
 internal bool IsExtSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck)
 {
     return splitCharacter.IsSplitCharacter(start, current, end, cc, ck);
 }
Esempio n. 22
0
 public PdfLine ProcessLine(float leftX, float width, int alignment, int runDirection, int arabicOptions)
 {
     this.arabicOptions = arabicOptions;
     Save();
     bool isRTL = (runDirection == PdfWriter.RUN_DIRECTION_RTL);
     if (currentChar >= totalTextLength) {
         bool hasText = GetParagraph(runDirection);
         if (!hasText)
             return null;
         if (totalTextLength == 0) {
             ArrayList ar = new ArrayList();
             PdfChunk ckx = new PdfChunk("", detailChunks[0]);
             ar.Add(ckx);
             return new PdfLine(0, 0, 0, alignment, true, ar, isRTL);
         }
     }
     float originalWidth = width;
     int lastSplit = -1;
     if (currentChar != 0)
         currentChar = TrimLeftEx(currentChar, totalTextLength - 1);
     int oldCurrentChar = currentChar;
     int uniC = 0;
     PdfChunk ck = null;
     float charWidth = 0;
     PdfChunk lastValidChunk = null;
     bool splitChar = false;
     bool surrogate = false;
     for (; currentChar < totalTextLength; ++currentChar) {
         ck = detailChunks[currentChar];
         surrogate = Utilities.IsSurrogatePair(text, currentChar);
         if (surrogate)
             uniC = ck.GetUnicodeEquivalent(Utilities.ConvertToUtf32(text, currentChar));
         else
             uniC = ck.GetUnicodeEquivalent(text[currentChar]);
         if (PdfChunk.NoPrint(uniC))
             continue;
         if (surrogate)
             charWidth = ck.GetCharWidth(uniC);
         else
             charWidth = ck.GetCharWidth(text[currentChar]);
         splitChar = ck.IsExtSplitCharacter(oldCurrentChar, currentChar, totalTextLength, text, detailChunks);
         if (splitChar && Char.IsWhiteSpace((char)uniC))
             lastSplit = currentChar;
         if (width - charWidth < 0)
             break;
         if (splitChar)
             lastSplit = currentChar;
         width -= charWidth;
         lastValidChunk = ck;
         if (surrogate)
             ++currentChar;
         if (ck.IsTab()) {
             Object[] tab = (Object[])ck.GetAttribute(Chunk.TAB);
             float tabPosition = (float)tab[1];
             bool newLine = (bool)tab[2];
             if (newLine && tabPosition < originalWidth - width) {
                 return new PdfLine(0, originalWidth, width, alignment, true, CreateArrayOfPdfChunks(oldCurrentChar, currentChar - 1), isRTL);
             }
             detailChunks[currentChar].AdjustLeft(leftX);
             width = originalWidth - tabPosition;
         }
     }
     if (lastValidChunk == null) {
         // not even a single char fit; must output the first char
         ++currentChar;
         if (surrogate)
             ++currentChar;
         return new PdfLine(0, originalWidth, 0, alignment, false, CreateArrayOfPdfChunks(currentChar - 1, currentChar - 1), isRTL);
     }
     if (currentChar >= totalTextLength) {
         // there was more line than text
         return new PdfLine(0, originalWidth, width, alignment, true, CreateArrayOfPdfChunks(oldCurrentChar, totalTextLength - 1), isRTL);
     }
     int newCurrentChar = TrimRightEx(oldCurrentChar, currentChar - 1);
     if (newCurrentChar < oldCurrentChar) {
         // only WS
         return new PdfLine(0, originalWidth, width, alignment, false, CreateArrayOfPdfChunks(oldCurrentChar, currentChar - 1), isRTL);
     }
     if (newCurrentChar == currentChar - 1) { // middle of word
         IHyphenationEvent he = (IHyphenationEvent)lastValidChunk.GetAttribute(Chunk.HYPHENATION);
         if (he != null) {
             int[] word = GetWord(oldCurrentChar, newCurrentChar);
             if (word != null) {
                 float testWidth = width + GetWidth(word[0], currentChar - 1);
                 String pre = he.GetHyphenatedWordPre(new String(text, word[0], word[1] - word[0]), lastValidChunk.Font.Font, lastValidChunk.Font.Size, testWidth);
                 String post = he.HyphenatedWordPost;
                 if (pre.Length > 0) {
                     PdfChunk extra = new PdfChunk(pre, lastValidChunk);
                     currentChar = word[1] - post.Length;
                     return new PdfLine(0, originalWidth, testWidth - lastValidChunk.Font.Width(pre), alignment, false, CreateArrayOfPdfChunks(oldCurrentChar, word[0] - 1, extra), isRTL);
                 }
             }
         }
     }
     if (lastSplit == -1 || lastSplit >= newCurrentChar) {
         // no split point or split point ahead of end
         return new PdfLine(0, originalWidth, width + GetWidth(newCurrentChar + 1, currentChar - 1), alignment, false, CreateArrayOfPdfChunks(oldCurrentChar, newCurrentChar), isRTL);
     }
     // standard split
     currentChar = lastSplit + 1;
     newCurrentChar = TrimRightEx(oldCurrentChar, lastSplit);
     if (newCurrentChar < oldCurrentChar) {
         // only WS again
         newCurrentChar = currentChar - 1;
     }
     return new PdfLine(0, originalWidth, originalWidth - GetWidth(oldCurrentChar, newCurrentChar), alignment, false, CreateArrayOfPdfChunks(oldCurrentChar, newCurrentChar), isRTL);
 }
Esempio n. 23
0
        /**
         * Truncates this <CODE>PdfChunk</CODE> if it's too long for the given width.
         * <P>
         * Returns <VAR>null</VAR> if the <CODE>PdfChunk</CODE> wasn't truncated.
         *
         * @param       width       a given width
         * @return      the <CODE>PdfChunk</CODE> that doesn't fit into the width.
         */
        internal PdfChunk Truncate(float width)
        {
            if (image != null) {
                if (image.ScaledWidth > width) {
                    PdfChunk pc = new PdfChunk("", this);
                    value = "";
                    attributes.Remove(Chunk.IMAGE);
                    image = null;
                    font = PdfFont.DefaultFont;
                    return pc;
                }
                else
                    return null;
            }

            int currentPosition = 0;
            float currentWidth = 0;

            // it's no use trying to split if there isn't even enough place for a space
            if (width < font.Width()) {
                string returnValue = value.Substring(1);
                value = value.Substring(0, 1);
                PdfChunk pc = new PdfChunk(returnValue, this);
                return pc;
            }

            // loop over all the characters of a string
            // or until the totalWidth is reached
            int length = value.Length;
            bool surrogate = false;
            while (currentPosition < length) {
                // the width of every character is added to the currentWidth
                surrogate = Utilities.IsSurrogatePair(value, currentPosition);
                if (surrogate)
                    currentWidth += font.Width(Utilities.ConvertToUtf32(value, currentPosition));
                else
                    currentWidth += font.Width(value[currentPosition]);
                if (currentWidth > width)
                    break;
                if (surrogate)
                    currentPosition++;
                currentPosition++;
            }

            // if all the characters fit in the total width, null is returned (there is no overflow)
            if (currentPosition == length) {
                return null;
            }

            // otherwise, the string has to be truncated
            //currentPosition -= 2;
            // we have to chop off minimum 1 character from the chunk
            if (currentPosition == 0) {
                currentPosition = 1;
                if (surrogate)
                    ++currentPosition;
            }
            string retVal = value.Substring(currentPosition);
            value = value.Substring(0, currentPosition);
            PdfChunk tmp = new PdfChunk(retVal, this);
            return tmp;
        }
Esempio n. 24
0
        /**
         * Splits this <CODE>PdfChunk</CODE> if it's too long for the given width.
         * <P>
         * Returns <VAR>null</VAR> if the <CODE>PdfChunk</CODE> wasn't truncated.
         *
         * @param       width       a given width
         * @return      the <CODE>PdfChunk</CODE> that doesn't fit into the width.
         */

        internal PdfChunk Split(float width)
        {
            newlineSplit = false;
            if (image != null)
            {
                if (image.ScaledWidth > width)
                {
                    PdfChunk pc = new PdfChunk(Chunk.OBJECT_REPLACEMENT_CHARACTER, this);
                    value      = "";
                    attributes = new Hashtable();
                    image      = null;
                    font       = PdfFont.DefaultFont;
                    return(pc);
                }
                else
                {
                    return(null);
                }
            }
            IHyphenationEvent hyphenationEvent = (IHyphenationEvent)noStroke[Chunk.HYPHENATION];
            int   currentPosition = 0;
            int   splitPosition   = -1;
            float currentWidth    = 0;

            // loop over all the characters of a string
            // or until the totalWidth is reached
            int   lastSpace      = -1;
            float lastSpaceWidth = 0;
            int   length         = value.Length;

            char[]   valueArray = value.ToCharArray();
            char     character  = (char)0;
            BaseFont ft         = font.Font;
            bool     surrogate  = false;

            if (ft.FontType == BaseFont.FONT_TYPE_CJK && ft.GetUnicodeEquivalent(' ') != ' ')
            {
                while (currentPosition < length)
                {
                    // the width of every character is added to the currentWidth
                    char cidChar = valueArray[currentPosition];
                    character = (char)ft.GetUnicodeEquivalent(cidChar);
                    // if a newLine or carriageReturn is encountered
                    if (character == '\n')
                    {
                        newlineSplit = true;
                        string returnValue = value.Substring(currentPosition + 1);
                        value = value.Substring(0, currentPosition);
                        if (value.Length < 1)
                        {
                            value = "\u0001";
                        }
                        PdfChunk pc = new PdfChunk(returnValue, this);
                        return(pc);
                    }
                    currentWidth += font.Width(cidChar);
                    if (character == ' ')
                    {
                        lastSpace      = currentPosition + 1;
                        lastSpaceWidth = currentWidth;
                    }
                    if (currentWidth > width)
                    {
                        break;
                    }
                    // if a split-character is encountered, the splitPosition is altered
                    if (splitCharacter.IsSplitCharacter(0, currentPosition, length, valueArray, thisChunk))
                    {
                        splitPosition = currentPosition + 1;
                    }
                    currentPosition++;
                }
            }
            else
            {
                while (currentPosition < length)
                {
                    // the width of every character is added to the currentWidth
                    character = valueArray[currentPosition];
                    // if a newLine or carriageReturn is encountered
                    if (character == '\r' || character == '\n')
                    {
                        newlineSplit = true;
                        int inc = 1;
                        if (character == '\r' && currentPosition + 1 < length && valueArray[currentPosition + 1] == '\n')
                        {
                            inc = 2;
                        }
                        string returnValue = value.Substring(currentPosition + inc);
                        value = value.Substring(0, currentPosition);
                        if (value.Length < 1)
                        {
                            value = " ";
                        }
                        PdfChunk pc = new PdfChunk(returnValue, this);
                        return(pc);
                    }
                    surrogate = Utilities.IsSurrogatePair(valueArray, currentPosition);
                    if (surrogate)
                    {
                        currentWidth += font.Width(Utilities.ConvertToUtf32(valueArray[currentPosition], valueArray[currentPosition + 1]));
                    }
                    else
                    {
                        currentWidth += font.Width(character);
                    }
                    if (character == ' ')
                    {
                        lastSpace      = currentPosition + 1;
                        lastSpaceWidth = currentWidth;
                    }
                    if (surrogate)
                    {
                        currentPosition++;
                    }
                    if (currentWidth > width)
                    {
                        break;
                    }
                    // if a split-character is encountered, the splitPosition is altered
                    if (splitCharacter.IsSplitCharacter(0, currentPosition, length, valueArray, null))
                    {
                        splitPosition = currentPosition + 1;
                    }
                    currentPosition++;
                }
            }

            // if all the characters fit in the total width, null is returned (there is no overflow)
            if (currentPosition == length)
            {
                return(null);
            }
            // otherwise, the string has to be truncated
            if (splitPosition < 0)
            {
                string returnValue = value;
                value = "";
                PdfChunk pc = new PdfChunk(returnValue, this);
                return(pc);
            }
            if (lastSpace > splitPosition && splitCharacter.IsSplitCharacter(0, 0, 1, singleSpace, null))
            {
                splitPosition = lastSpace;
            }
            if (hyphenationEvent != null && lastSpace >= 0 && lastSpace < currentPosition)
            {
                int wordIdx = GetWord(value, lastSpace);
                if (wordIdx > lastSpace)
                {
                    string pre  = hyphenationEvent.GetHyphenatedWordPre(value.Substring(lastSpace, wordIdx - lastSpace), font.Font, font.Size, width - lastSpaceWidth);
                    string post = hyphenationEvent.HyphenatedWordPost;
                    if (pre.Length > 0)
                    {
                        string returnValue = post + value.Substring(wordIdx);
                        value = Trim(value.Substring(0, lastSpace) + pre);
                        PdfChunk pc = new PdfChunk(returnValue, this);
                        return(pc);
                    }
                }
            }
            string retVal = value.Substring(splitPosition);

            value = Trim(value.Substring(0, splitPosition));
            PdfChunk tmp = new PdfChunk(retVal, this);

            return(tmp);
        }
Esempio n. 25
0
 private void AddToLine(PdfChunk chunk)
 {
     if (chunk.ChangeLeading && chunk.IsImage()) {
         float f = chunk.Image.ScaledHeight + chunk.ImageOffsetY + chunk.Image.BorderWidthTop;
         if (f > height) height = f;
     }
     line.Add(chunk);
 }
Esempio n. 26
0
        /**
        * Signals that an <CODE>Element</CODE> was added to the <CODE>Document</CODE>.
        *
        * @param element the element to add
        * @return <CODE>true</CODE> if the element was added, <CODE>false</CODE> if not.
        * @throws DocumentException when a document isn't open yet, or has been closed
        */
        public override bool Add(IElement element)
        {
            if (writer != null && writer.IsPaused()) {
                return false;
            }
            switch (element.Type) {

                // Information (headers)
                case Element.HEADER:
                    info.Addkey(((Meta)element).Name, ((Meta)element).Content);
                    break;
                case Element.TITLE:
                    info.AddTitle(((Meta)element).Content);
                    break;
                case Element.SUBJECT:
                    info.AddSubject(((Meta)element).Content);
                    break;
                case Element.KEYWORDS:
                    info.AddKeywords(((Meta)element).Content);
                    break;
                case Element.AUTHOR:
                    info.AddAuthor(((Meta)element).Content);
                    break;
                case Element.CREATOR:
                    info.AddCreator(((Meta)element).Content);
                    break;
                case Element.PRODUCER:
                    // you can not change the name of the producer
                    info.AddProducer();
                    break;
                case Element.CREATIONDATE:
                    // you can not set the creation date, only reset it
                    info.AddCreationDate();
                    break;

                    // content (text)
                case Element.CHUNK: {
                    // if there isn't a current line available, we make one
                    if (line == null) {
                        CarriageReturn();
                    }

                    // we cast the element to a chunk
                    PdfChunk chunk = new PdfChunk((Chunk) element, anchorAction);
                    // we try to add the chunk to the line, until we succeed
                    {
                        PdfChunk overflow;
                        while ((overflow = line.Add(chunk)) != null) {
                            CarriageReturn();
                            chunk = overflow;
                            chunk.TrimFirstSpace();
                        }
                    }
                    pageEmpty = false;
                    if (chunk.IsAttribute(Chunk.NEWPAGE)) {
                        NewPage();
                    }
                    break;
                }
                case Element.ANCHOR: {
                    leadingCount++;
                    Anchor anchor = (Anchor) element;
                    String url = anchor.Reference;
                    leading = anchor.Leading;
                    if (url != null) {
                        anchorAction = new PdfAction(url);
                    }

                    // we process the element
                    element.Process(this);
                    anchorAction = null;
                    leadingCount--;
                    break;
                }
                case Element.ANNOTATION: {
                    if (line == null) {
                        CarriageReturn();
                    }
                    Annotation annot = (Annotation) element;
                    Rectangle rect = new Rectangle(0, 0);
                    if (line != null)
                        rect = new Rectangle(annot.GetLlx(IndentRight - line.WidthLeft), annot.GetLly(IndentTop - currentHeight), annot.GetUrx(IndentRight - line.WidthLeft + 20), annot.GetUry(IndentTop - currentHeight - 20));
                    PdfAnnotation an = PdfAnnotationsImp.ConvertAnnotation(writer, annot, rect);
                    annotationsImp.AddPlainAnnotation(an);
                    pageEmpty = false;
                    break;
                }
                case Element.PHRASE: {
                    leadingCount++;
                    // we cast the element to a phrase and set the leading of the document
                    leading = ((Phrase) element).Leading;
                    // we process the element
                    element.Process(this);
                    leadingCount--;
                    break;
                }
                case Element.PARAGRAPH: {
                    leadingCount++;
                    // we cast the element to a paragraph
                    Paragraph paragraph = (Paragraph) element;

                    AddSpacing(paragraph.SpacingBefore, leading, paragraph.Font);

                    // we adjust the parameters of the document
                    alignment = paragraph.Alignment;
                    leading = paragraph.TotalLeading;

                    CarriageReturn();
                    // we don't want to make orphans/widows
                    if (currentHeight + line.Height + leading > IndentTop - IndentBottom) {
                        NewPage();
                    }

                    indentation.indentLeft += paragraph.IndentationLeft;
                    indentation.indentRight += paragraph.IndentationRight;

                    CarriageReturn();

                    IPdfPageEvent pageEvent = writer.PageEvent;
                    if (pageEvent != null && !isSectionTitle)
                        pageEvent.OnParagraph(writer, this, IndentTop - currentHeight);

                    // if a paragraph has to be kept together, we wrap it in a table object
                    if (paragraph.KeepTogether) {
                        CarriageReturn();
                        PdfPTable table = new PdfPTable(1);
                        table.WidthPercentage = 100f;
                        PdfPCell cell = new PdfPCell();
                        cell.AddElement(paragraph);
                        cell.Border = Rectangle.NO_BORDER;
                        cell.Padding = 0;
                        table.AddCell(cell);
                        indentation.indentLeft -= paragraph.IndentationLeft;
                        indentation.indentRight -= paragraph.IndentationRight;
                        this.Add(table);
                        indentation.indentLeft += paragraph.IndentationLeft;
                        indentation.indentRight += paragraph.IndentationRight;
                    }
                    else {
                        line.SetExtraIndent(paragraph.FirstLineIndent);
                        element.Process(this);
                        CarriageReturn();
                        AddSpacing(paragraph.SpacingAfter, paragraph.TotalLeading, paragraph.Font);
                    }

                    if (pageEvent != null && !isSectionTitle)
                        pageEvent.OnParagraphEnd(writer, this, IndentTop - currentHeight);

                    alignment = Element.ALIGN_LEFT;
                    indentation.indentLeft -= paragraph.IndentationLeft;
                    indentation.indentRight -= paragraph.IndentationRight;
                    CarriageReturn();
                    leadingCount--;
                    break;
                }
                case Element.SECTION:
                case Element.CHAPTER: {
                    // Chapters and Sections only differ in their constructor
                    // so we cast both to a Section
                    Section section = (Section) element;
                    IPdfPageEvent pageEvent = writer.PageEvent;

                    bool hasTitle = section.NotAddedYet && section.Title != null;

                    // if the section is a chapter, we begin a new page
                    if (section.TriggerNewPage) {
                        NewPage();
                    }

                    if (hasTitle) {
                        float fith = IndentTop - currentHeight;
                        int rotation = pageSize.Rotation;
                        if (rotation == 90 || rotation == 180)
                            fith = pageSize.Height - fith;
                        PdfDestination destination = new PdfDestination(PdfDestination.FITH, fith);
                        while (currentOutline.Level >= section.Depth) {
                            currentOutline = currentOutline.Parent;
                        }
                        PdfOutline outline = new PdfOutline(currentOutline, destination, section.GetBookmarkTitle(), section.BookmarkOpen);
                        currentOutline = outline;
                    }

                    // some values are set
                    CarriageReturn();
                    indentation.sectionIndentLeft += section.IndentationLeft;
                    indentation.sectionIndentRight += section.IndentationRight;
                    if (section.NotAddedYet && pageEvent != null)
                        if (element.Type == Element.CHAPTER)
                            pageEvent.OnChapter(writer, this, IndentTop - currentHeight, section.Title);
                        else
                            pageEvent.OnSection(writer, this, IndentTop - currentHeight, section.Depth, section.Title);

                    // the title of the section (if any has to be printed)
                    if (hasTitle) {
                        isSectionTitle = true;
                        Add(section.Title);
                        isSectionTitle = false;
                    }
                    indentation.sectionIndentLeft += section.Indentation;
                    // we process the section
                    element.Process(this);
                    // some parameters are set back to normal again
                    indentation.sectionIndentLeft -= (section.IndentationLeft + section.Indentation);
                    indentation.sectionIndentRight -= section.IndentationRight;

                    if (section.ElementComplete && pageEvent != null)
                        if (element.Type == Element.CHAPTER)
                            pageEvent.OnChapterEnd(writer, this, IndentTop - currentHeight);
                        else
                            pageEvent.OnSectionEnd(writer, this, IndentTop - currentHeight);

                    break;
                }
                case Element.LIST: {
                    // we cast the element to a List
                    List list = (List) element;
                    if (list.Alignindent) {
                        list.NormalizeIndentation();
                    }
                    // we adjust the document
                    indentation.listIndentLeft += list.IndentationLeft;
                    indentation.indentRight += list.IndentationRight;
                    // we process the items in the list
                    element.Process(this);
                    // some parameters are set back to normal again
                    indentation.listIndentLeft -= list.IndentationLeft;
                    indentation.indentRight -= list.IndentationRight;
                    CarriageReturn();
                    break;
                }
                case Element.LISTITEM: {
                    leadingCount++;
                    // we cast the element to a ListItem
                    ListItem listItem = (ListItem) element;

                    AddSpacing(listItem.SpacingBefore, leading, listItem.Font);

                    // we adjust the document
                    alignment = listItem.Alignment;
                    indentation.listIndentLeft += listItem.IndentationLeft;
                    indentation.indentRight += listItem.IndentationRight;
                    leading = listItem.TotalLeading;
                    CarriageReturn();
                    // we prepare the current line to be able to show us the listsymbol
                    line.ListItem = listItem;
                    // we process the item
                    element.Process(this);

                    AddSpacing(listItem.SpacingAfter, listItem.TotalLeading, listItem.Font);

                    // if the last line is justified, it should be aligned to the left
                    if (line.HasToBeJustified()) {
                        line.ResetAlignment();
                    }
                    // some parameters are set back to normal again
                    CarriageReturn();
                    indentation.listIndentLeft -= listItem.IndentationLeft;
                    indentation.indentRight -= listItem.IndentationRight;
                    leadingCount--;
                    break;
                }
                case Element.RECTANGLE: {
                    Rectangle rectangle = (Rectangle) element;
                    graphics.Rectangle(rectangle);
                    pageEmpty = false;
                    break;
                }
                case Element.PTABLE: {
                    PdfPTable ptable = (PdfPTable)element;
                    if (ptable.Size <= ptable.HeaderRows)
                        break; //nothing to do

                    // before every table, we add a new line and flush all lines
                    EnsureNewLine();
                    FlushLines();

                    AddPTable(ptable);
                    pageEmpty = false;
                    NewLine();
                    break;
                }
                case Element.MULTI_COLUMN_TEXT: {
                    EnsureNewLine();
                    FlushLines();
                    MultiColumnText multiText = (MultiColumnText) element;
                    float height = multiText.Write(writer.DirectContent, this, IndentTop - currentHeight);
                    currentHeight += height;
                    text.MoveText(0, -1f* height);
                    pageEmpty = false;
                    break;
                }
                case Element.TABLE : {
                    if (element is SimpleTable) {
                        PdfPTable ptable = ((SimpleTable)element).CreatePdfPTable();
                        if (ptable.Size <= ptable.HeaderRows)
                            break; //nothing to do

                        // before every table, we add a new line and flush all lines
                        EnsureNewLine();
                        FlushLines();
                        AddPTable(ptable);
                        pageEmpty = false;
                        break;
                    } else if (element is Table) {

                        try {
                            PdfPTable ptable = ((Table)element).CreatePdfPTable();
                            if (ptable.Size <= ptable.HeaderRows)
                                break; //nothing to do

                            // before every table, we add a new line and flush all lines
                            EnsureNewLine();
                            FlushLines();
                            AddPTable(ptable);
                            pageEmpty = false;
                            break;
                        }
                        catch (BadElementException) {
                            // constructing the PdfTable
                            // Before the table, add a blank line using offset or default leading
                            float offset = ((Table)element).Offset;
                            if (float.IsNaN(offset))
                                offset = leading;
                            CarriageReturn();
                            lines.Add(new PdfLine(IndentLeft, IndentRight, alignment, offset));
                            currentHeight += offset;
                            AddPdfTable((Table)element);
                        }
                    } else {
                        return false;
                    }
                    break;
                }
                case Element.JPEG:
                case Element.JPEG2000:
                case Element.JBIG2:
                case Element.IMGRAW:
                case Element.IMGTEMPLATE: {
                    //carriageReturn(); suggestion by Marc Campforts
                    Add((Image) element);
                    break;
                }
                case Element.YMARK: {
                    IDrawInterface zh = (IDrawInterface)element;
                    zh.Draw(graphics, IndentLeft, IndentBottom, IndentRight, IndentTop, IndentTop - currentHeight - (leadingCount > 0 ? leading : 0));
                    pageEmpty = false;
                    break;
                }
                case Element.MARKED: {
                    MarkedObject mo;
                    if (element is MarkedSection) {
                        mo = ((MarkedSection)element).Title;
                        if (mo != null) {
                            mo.Process(this);
                        }
                    }
                    mo = (MarkedObject)element;
                    mo.Process(this);
                    break;
                }
                default:
                    return false;
            }
            lastElementType = element.Type;
            return true;
        }