예제 #1
0
        /**
         * <summary>Shows the specified external object.</summary>
         * <param name="xObject">External object.</param>
         * <param name="size">Size of the external object.</param>
         * <param name="lineAlignment">Line alignment. It can be:
         *  <list type="bullet">
         *    <item><see cref="LineAlignmentEnum"/></item>
         *    <item><see cref="Length">: arbitrary super-/sub-script, depending on whether the value is
         *    positive or not.</item>
         *  </list>
         * </param>
         * <returns>Whether the external object was successfully shown.</returns>
         */
        public bool ShowXObject(
            xObjects::XObject xObject,
            SizeF?size,
            object lineAlignment
            )
        {
            if (xObject == null ||
                !EnsureRow(true))
            {
                return(false);
            }

            if (!size.HasValue)
            {
                size = xObject.Size;
            }
            lineAlignment = ResolveLineAlignment(lineAlignment);

            while (true)
            {
                if (OperationUtils.Compare(currentRow.Y + size.Value.Height, frame.Height) == 1) // Object's height exceeds block's remaining vertical space.
                {
                    // Terminate current row and exit!
                    EndRow(false);
                    return(false);
                }
                else if (OperationUtils.Compare(currentRow.Width + size.Value.Width, frame.Width) < 1) // There's room for the object in the current row.
                {
                    PointF location = new PointF(
                        (float)currentRow.Width,
                        (float)currentRow.Y
                        );
                    RowObject obj;
                    {
                        obj = new RowObject(
                            RowObject.TypeEnum.XObject,
                            baseComposer.BeginLocalState(), // Opens the row object's local state.
                            size.Value.Height,
                            size.Value.Width,
                            0,
                            lineAlignment,
                            size.Value.Height,
                            0,
                            0
                            );
                        baseComposer.ShowXObject(xObject, location, size);
                        baseComposer.End(); // Closes the row object's local state.
                    }
                    AddRowObject(obj, lineAlignment);

                    return(true);
                }
                else // There's NOT enough room for the object in the current row.
                {
                    // Go to next row!
                    EndRow(false);
                    BeginRow();
                }
            }
        }
예제 #2
0
        private object ResolveLineAlignment(
            object lineAlignment
            )
        {
            if (!(lineAlignment is LineAlignmentEnum ||
                  lineAlignment is Length))
            {
                throw new ArgumentException("MUST be either LineAlignmentEnum or Length.", "lineAlignment");
            }

            if (lineAlignment.Equals(LineAlignmentEnum.Super))
            {
                lineAlignment = new Length(0.33, Length.UnitModeEnum.Relative);
            }
            else if (lineAlignment.Equals(LineAlignmentEnum.Sub))
            {
                lineAlignment = new Length(-0.33, Length.UnitModeEnum.Relative);
            }
            if (lineAlignment is Length)
            {
                if (lastFontSize == 0)
                {
                    lastFontSize = baseComposer.State.FontSize;
                }
                lineAlignment = ((Length)lineAlignment).GetValue(lastFontSize);
            }

            return(lineAlignment);
        }
예제 #3
0
        private void BuildTextBlockPage2(
            Document document
            )
        {
            // 1. Add the page to the document!
            Page page = new Page(document); // Instantiates the page inside the document context.

            document.Pages.Add(page);       // Puts the page in the pages collection.

            SizeF pageSize = page.Size;

            // 2. Create a content composer for the page!
            PrimitiveComposer composer = new PrimitiveComposer(page);

            // 3. Drawing the page contents...
            fonts::Font   mainFont      = new fonts::StandardType1Font(document, fonts::StandardType1Font.FamilyEnum.Courier, true, false);
            int           stepCount     = 5;
            int           step          = (int)(pageSize.Height) / (stepCount + 1);
            BlockComposer blockComposer = new BlockComposer(composer);

            {
                blockComposer.Begin(
                    new RectangleF(
                        30,
                        0,
                        pageSize.Width - 60,
                        step * .8f
                        ),
                    XAlignmentEnum.Center,
                    YAlignmentEnum.Middle
                    );
                composer.SetFont(mainFont, 32);
                blockComposer.ShowText("Block line alignment");
                blockComposer.End();
            }

            // Drawing the text block...
            {
                fonts::Font       sampleFont         = new fonts::StandardType1Font(document, fonts::StandardType1Font.FamilyEnum.Times, false, false);
                entities::Image   sampleImage        = entities::Image.Get(GetResourcePath("images" + System.IO.Path.DirectorySeparatorChar + "gnu.jpg"));
                xObjects::XObject sampleImageXObject = sampleImage.ToXObject(document);

                IList <LineAlignmentEnum> lineAlignments = new List <LineAlignmentEnum>((LineAlignmentEnum[])Enum.GetValues(typeof(LineAlignmentEnum)));
                float frameHeight = (pageSize.Height - 130 - 5 * lineAlignments.Count * 2) / (lineAlignments.Count * 2);
                float frameWidth  = (pageSize.Width - 60 - 5 * lineAlignments.Count) / lineAlignments.Count;
                int   imageSize   = 7;
                for (int index = 0, length = lineAlignments.Count; index < length; index++)
                {
                    LineAlignmentEnum lineAlignment = lineAlignments[index];

                    for (int imageIndex = 0, imageLength = lineAlignments.Count; imageIndex < imageLength; imageIndex++)
                    {
                        LineAlignmentEnum imageAlignment = lineAlignments[imageIndex];

                        for (int index2 = 0, length2 = 2; index2 < length2; index2++)
                        {
                            RectangleF frame = new RectangleF(
                                30 + (frameWidth + 5) * imageIndex,
                                100 + (frameHeight + 5) * (index * 2 + index2),
                                frameWidth,
                                frameHeight
                                );

                            blockComposer.Begin(frame, XAlignmentEnum.Left, YAlignmentEnum.Top);
                            {
                                composer.SetFont(mainFont, 3);
                                blockComposer.ShowText("Text: " + lineAlignment);
                                blockComposer.ShowBreak();
                                blockComposer.ShowText("Image: " + imageAlignment);
                            }
                            blockComposer.End();

                            blockComposer.Begin(frame, XAlignmentEnum.Left, YAlignmentEnum.Middle);
                            {
                                composer.SetFont(sampleFont, 3);
                                blockComposer.ShowText("Previous row boundary.");
                                blockComposer.ShowBreak();
                                composer.SetFont(sampleFont, index2 == 0 ? 3 : 6);
                                blockComposer.ShowText("Alignment:");
                                composer.SetFont(sampleFont, index2 == 0 ? 6 : 3);
                                blockComposer.ShowText(" aligned to " + lineAlignment + " ", lineAlignment);
                                blockComposer.ShowXObject(sampleImageXObject, new SizeF(imageSize, imageSize), imageAlignment);
                                blockComposer.ShowBreak();
                                composer.SetFont(sampleFont, 3);
                                blockComposer.ShowText("Next row boundary.");
                            }
                            blockComposer.End();

                            composer.BeginLocalState();
                            {
                                composer.SetLineWidth(0.1f);
                                composer.SetLineDash(new LineDash(new double[] { 1, 4 }, 4));
                                composer.DrawRectangle(blockComposer.Frame);
                                composer.Stroke();
                            }
                            composer.End();

                            composer.BeginLocalState();
                            {
                                composer.SetLineWidth(0.1f);
                                composer.SetLineDash(new LineDash(new double[] { 1, 1 }, 1));
                                composer.DrawRectangle(blockComposer.BoundBox);
                                composer.Stroke();
                            }
                            composer.End();
                        }
                    }
                }
            }

            // 4. Flush the contents into the page!
            composer.Flush();
        }
예제 #4
0
        /**
         * <summary>Ends the content row.</summary>
         * <param name="broken">Indicates whether this is the end of a paragraph.</param>
         */
        private void EndRow(
            bool broken
            )
        {
            if (rowEnded)
            {
                return;
            }

            rowEnded = true;

            double[] objectXOffsets = new double[currentRow.Objects.Count]; // Horizontal object displacements.
            double   wordSpace      = 0;                                    // Exceeding space among words.
            double   rowXOffset     = 0;                                    // Horizontal row offset.

            List <RowObject> objects = currentRow.Objects;

            // Horizontal alignment.
            XAlignmentEnum xAlignment = this.xAlignment;

            switch (xAlignment)
            {
            case XAlignmentEnum.Left:
                break;

            case XAlignmentEnum.Right:
                rowXOffset = frame.Width - currentRow.Width;
                break;

            case XAlignmentEnum.Center:
                rowXOffset = (frame.Width - currentRow.Width) / 2;
                break;

            case XAlignmentEnum.Justify:
                // Are there NO spaces?
                if (currentRow.SpaceCount == 0 ||
                    broken) // NO spaces.
                {
                    /* NOTE: This situation equals a simple left alignment. */
                    xAlignment = XAlignmentEnum.Left;
                }
                else // Spaces exist.
                {
                    // Calculate the exceeding spacing among the words!
                    wordSpace = (frame.Width - currentRow.Width) / currentRow.SpaceCount;

                    // Define the horizontal offsets for justified alignment.
                    for (
                        int index = 1,
                        count = objects.Count;
                        index < count;
                        index++
                        )
                    {
                        /*
                         * NOTE: The offset represents the horizontal justification gap inserted
                         * at the left side of each object.
                         */
                        objectXOffsets[index] = objectXOffsets[index - 1] + objects[index - 1].SpaceCount * wordSpace;
                    }
                }
                break;
            }

            SetWordSpace wordSpaceOperation = new SetWordSpace(wordSpace);

            // Vertical alignment and translation.
            for (
                int index = objects.Count - 1;
                index >= 0;
                index--
                )
            {
                RowObject obj = objects[index];

                // Vertical alignment.
                double objectYOffset = 0;
                {
                    LineAlignmentEnum lineAlignment;
                    double            lineRise;
                    {
                        object objectLineAlignment = obj.LineAlignment;
                        if (objectLineAlignment is Double)
                        {
                            lineAlignment = LineAlignmentEnum.BaseLine;
                            lineRise      = (double)objectLineAlignment;
                        }
                        else
                        {
                            lineAlignment = (LineAlignmentEnum)objectLineAlignment;
                            lineRise      = 0;
                        }
                    }
                    switch (lineAlignment)
                    {
                    case LineAlignmentEnum.Top:
                        /* NOOP */
                        break;

                    case LineAlignmentEnum.Middle:
                        objectYOffset = -(currentRow.Height - obj.Height) / 2;
                        break;

                    case LineAlignmentEnum.BaseLine:
                        objectYOffset = -(currentRow.BaseLine - obj.BaseLine - lineRise);
                        break;

                    case LineAlignmentEnum.Bottom:
                        objectYOffset = -(currentRow.Height - obj.Height);
                        break;

                    default:
                        throw new NotImplementedException("Line alignment " + lineAlignment + " unknown.");
                    }
                }

                IList <ContentObject> containedGraphics = obj.Container.Objects;
                // Word spacing.
                containedGraphics.Insert(0, wordSpaceOperation);
                // Translation.
                containedGraphics.Insert(
                    0,
                    new ModifyCTM(
                        1, 0, 0, 1,
                        objectXOffsets[index] + rowXOffset, // Horizontal alignment.
                        objectYOffset                       // Vertical alignment.
                        )
                    );
            }

            // Update the actual block height!
            boundBox.Height = (float)(currentRow.Y + currentRow.Height);

            // Update the actual block vertical location!
            double yOffset;

            switch (yAlignment)
            {
            case YAlignmentEnum.Bottom:
                yOffset = frame.Height - boundBox.Height;
                break;

            case YAlignmentEnum.Middle:
                yOffset = (frame.Height - boundBox.Height) / 2;
                break;

            case YAlignmentEnum.Top:
            default:
                yOffset = 0;
                break;
            }
            boundBox.Y = (float)(frame.Y + yOffset);

            // Discard the current row!
            currentRow = null;
        }
예제 #5
0
        /**
         * <summary>Shows text.</summary>
         * <param name="text">Text to show.</param>
         * <param name="lineAlignment">Line alignment. It can be:
         *  <list type="bullet">
         *    <item><see cref="LineAlignmentEnum"/></item>
         *    <item><see cref="Length">: arbitrary super-/sub-script, depending on whether the value is
         *    positive or not.</item>
         *  </list>
         * </param>
         * <returns>Last shown character index.</returns>
         */
        public int ShowText(
            string text,
            object lineAlignment
            )
        {
            if (currentRow == null ||
                text == null)
            {
                return(0);
            }

            ContentScanner.GraphicsState state = baseComposer.State;
            fonts::Font font       = state.Font;
            double      fontSize   = state.FontSize;
            double      lineHeight = font.GetLineHeight(fontSize);
            double      baseLine   = font.GetAscent(fontSize);

            lineAlignment = ResolveLineAlignment(lineAlignment);

            TextFitter textFitter = new TextFitter(
                text,
                0,
                font,
                fontSize,
                hyphenation,
                hyphenationCharacter
                );
            int textLength = text.Length;
            int index      = 0;

            while (true)
            {
                if (currentRow.Width == 0) // Current row has just begun.
                {
                    // Removing leading space...
                    while (true)
                    {
                        if (index == textLength) // Text end reached.
                        {
                            goto endTextShowing;
                        }
                        else if (text[index] != ' ') // No more leading spaces.
                        {
                            break;
                        }

                        index++;
                    }
                }

                if (OperationUtils.Compare(currentRow.Y + lineHeight, frame.Height) == 1) // Text's height exceeds block's remaining vertical space.
                {
                    // Terminate the current row and exit!
                    EndRow(false);
                    goto endTextShowing;
                }

                // Does the text fit?
                if (textFitter.Fit(
                        index,
                        frame.Width - currentRow.Width, // Remaining row width.
                        currentRow.SpaceCount == 0
                        ))
                {
                    // Get the fitting text!
                    string textChunk         = textFitter.FittedText;
                    double textChunkWidth    = textFitter.FittedWidth;
                    PointF textChunkLocation = new PointF(
                        (float)currentRow.Width,
                        (float)currentRow.Y
                        );

                    // Insert the fitting text!
                    RowObject obj;
                    {
                        obj = new RowObject(
                            RowObject.TypeEnum.Text,
                            baseComposer.BeginLocalState(), // Opens the row object's local state.
                            lineHeight,
                            textChunkWidth,
                            CountOccurrence(' ', textChunk),
                            lineAlignment,
                            baseLine
                            );
                        baseComposer.ShowText(textChunk, textChunkLocation);
                        baseComposer.End(); // Closes the row object's local state.
                    }
                    AddRowObject(obj, lineAlignment);

                    index = textFitter.EndIndex;
                }

                // Evaluating trailing text...
                while (true)
                {
                    if (index == textLength) // Text end reached.
                    {
                        goto endTextShowing;
                    }

                    switch (text[index])
                    {
                    case '\r':
                        break;

                    case '\n':
                        // New paragraph!
                        index++;
                        ShowBreak();
                        goto endTrailParsing;

                    default:
                        // New row (within the same paragraph)!
                        EndRow(false);
                        BeginRow();
                        goto endTrailParsing;
                    }

                    index++;
                }
                endTrailParsing :;
            }
            endTextShowing :;
            if (index >= 0 &&
                lineAlignment.Equals(LineAlignmentEnum.BaseLine))
            {
                lastFontSize = fontSize;
            }

            return(index);
        }
예제 #6
0
        /**
         * <summary>Ends the content row.</summary>
         * <param name="broken">Indicates whether this is the end of a paragraph.</param>
         */
        private void EndRow(
            bool broken
            )
        {
            if (rowEnded)
            {
                return;
            }

            rowEnded = true;

            List <RowObject> objects = currentRow.Objects;

            double[] objectXOffsets = new double[objects.Count]; // Horizontal object displacements.
            double   wordSpace      = 0;                         // Exceeding space among words.
            double   rowXOffset     = 0;                         // Horizontal row offset.

            // Horizontal alignment.
            XAlignmentEnum xAlignment = this.xAlignment;

            switch (xAlignment)
            {
            case XAlignmentEnum.Left:
                break;

            case XAlignmentEnum.Right:
                rowXOffset = frame.Width - currentRow.Width;
                break;

            case XAlignmentEnum.Center:
                rowXOffset = (frame.Width - currentRow.Width) / 2;
                break;

            case XAlignmentEnum.Justify:
                if (currentRow.SpaceCount == 0 ||
                    broken) // NO spaces.
                {
                    /* NOTE: This situation equals a simple left alignment. */
                    xAlignment = XAlignmentEnum.Left;
                }
                else // Spaces exist.
                {
                    // Calculate the exceeding spacing among the words!
                    wordSpace = (frame.Width - currentRow.Width) / currentRow.SpaceCount;

                    // Define the horizontal offsets for justified alignment.
                    for (
                        int index = 1,
                        count = objects.Count;
                        index < count;
                        index++
                        )
                    {
                        /*
                         * NOTE: The offset represents the horizontal justification gap inserted at the left
                         * side of each object.
                         */
                        objectXOffsets[index] = objectXOffsets[index - 1] + objects[index - 1].SpaceCount * wordSpace;
                    }
                }
                currentRow.WordSpaceAdjustment.Value = wordSpace;
                break;
            }

            // Vertical alignment and translation.
            for (
                int index = objects.Count - 1;
                index >= 0;
                index--
                )
            {
                RowObject obj = objects[index];

                // Vertical alignment.
                double objectYOffset = 0;
                {
                    LineAlignmentEnum lineAlignment;
                    double            lineRise;
                    {
                        object objectLineAlignment = obj.LineAlignment;
                        if (objectLineAlignment is Double)
                        {
                            lineAlignment = LineAlignmentEnum.BaseLine;
                            lineRise      = (double)objectLineAlignment;
                        }
                        else
                        {
                            lineAlignment = (LineAlignmentEnum)objectLineAlignment;
                            lineRise      = 0;
                        }
                    }
                    switch (lineAlignment)
                    {
                    case LineAlignmentEnum.Top:
                        /* NOOP */
                        break;

                    case LineAlignmentEnum.Middle:
                        objectYOffset = -(currentRow.Height - obj.Height) / 2;
                        break;

                    case LineAlignmentEnum.BaseLine:
                        objectYOffset = -(currentRow.BaseLine - obj.BaseLine - lineRise);
                        break;

                    case LineAlignmentEnum.Bottom:
                        objectYOffset = -(currentRow.Height - obj.Height);
                        break;

                    default:
                        throw new NotImplementedException("Line alignment " + lineAlignment + " unknown.");
                    }
                }

                IList <ContentObject> containedGraphics = obj.Container.Objects;
                // Translation.
                containedGraphics.Insert(
                    0,
                    new ModifyCTM(
                        1, 0, 0, 1,
                        objectXOffsets[index] + rowXOffset, // Horizontal alignment.
                        objectYOffset                       // Vertical alignment.
                        )
                    );
                // Word spacing.
                if (obj.Type == RowObject.TypeEnum.Text)
                {
                    /*
                     * TODO: This temporary hack adjusts the word spacing in case of composite font.
                     * When DocumentComposer replaces BlockComposer, all the graphical properties of contents
                     * will be declared as styles and their composition will occur as a single pass without such
                     * ugly tweakings.
                     */
                    ShowText showTextOperation = (ShowText)((Text)((LocalGraphicsState)containedGraphics[1]).Objects[1]).Objects[1];
                    if (showTextOperation is ShowAdjustedText)
                    {
                        PdfInteger wordSpaceObject = PdfInteger.Get((int)Math.Round(-wordSpace * 1000 * obj.Scale / obj.FontSize));
                        PdfArray   textParams      = (PdfArray)showTextOperation.Operands[0];
                        for (int textParamIndex = 1, textParamsLength = textParams.Count; textParamIndex < textParamsLength; textParamIndex += 2)
                        {
                            textParams[textParamIndex] = wordSpaceObject;
                        }
                    }
                }
            }

            // Update the actual block height!
            boundBox.Height = (float)(currentRow.Y + currentRow.Height);

            // Update the actual block vertical location!
            double yOffset;

            switch (yAlignment)
            {
            case YAlignmentEnum.Bottom:
                yOffset = frame.Height - boundBox.Height;
                break;

            case YAlignmentEnum.Middle:
                yOffset = (frame.Height - boundBox.Height) / 2;
                break;

            case YAlignmentEnum.Top:
            default:
                yOffset = 0;
                break;
            }
            boundBox.Y = (float)(frame.Y + yOffset);

            // Discard the current row!
            currentRow = null;
        }
예제 #7
0
        private object ResolveLineAlignment(
      object lineAlignment
      )
        {
            if(!(lineAlignment is LineAlignmentEnum
            || lineAlignment is Length))
            throw new ArgumentException("MUST be either LineAlignmentEnum or Length.", "lineAlignment");

              if(lineAlignment.Equals(LineAlignmentEnum.Super))
              {lineAlignment = new Length(0.33, Length.UnitModeEnum.Relative);}
              else if(lineAlignment.Equals(LineAlignmentEnum.Sub))
              {lineAlignment = new Length(-0.33, Length.UnitModeEnum.Relative);}
              if(lineAlignment is Length)
              {
            if(lastFontSize == 0)
            {lastFontSize = baseComposer.State.FontSize;}
            lineAlignment = ((Length)lineAlignment).GetValue(lastFontSize);
              }

              return lineAlignment;
        }
예제 #8
0
        /**
          <summary>Ends the content row.</summary>
          <param name="broken">Indicates whether this is the end of a paragraph.</param>
        */
        private void EndRow(
      bool broken
      )
        {
            if(rowEnded)
            return;

              rowEnded = true;

              double[] objectXOffsets = new double[currentRow.Objects.Count]; // Horizontal object displacements.
              double wordSpace = 0; // Exceeding space among words.
              double rowXOffset = 0; // Horizontal row offset.

              List<RowObject> objects = currentRow.Objects;

              // Horizontal alignment.
              XAlignmentEnum xAlignment = this.xAlignment;
              switch(xAlignment)
              {
            case XAlignmentEnum.Left:
              break;
            case XAlignmentEnum.Right:
              rowXOffset = frame.Width - currentRow.Width;
              break;
            case XAlignmentEnum.Center:
              rowXOffset = (frame.Width - currentRow.Width) / 2;
              break;
            case XAlignmentEnum.Justify:
              // Are there NO spaces?
              if(currentRow.SpaceCount == 0
            || broken) // NO spaces.
              {
            /* NOTE: This situation equals a simple left alignment. */
            xAlignment = XAlignmentEnum.Left;
              }
              else // Spaces exist.
              {
            // Calculate the exceeding spacing among the words!
            wordSpace = (frame.Width - currentRow.Width) / currentRow.SpaceCount;

            // Define the horizontal offsets for justified alignment.
            for(
              int index = 1,
                count = objects.Count;
              index < count;
              index++
              )
            {
              /*
                NOTE: The offset represents the horizontal justification gap inserted
                at the left side of each object.
              */
              objectXOffsets[index] = objectXOffsets[index - 1] + objects[index - 1].SpaceCount * wordSpace;
            }
              }
              break;
              }

              SetWordSpace wordSpaceOperation = new SetWordSpace(wordSpace);

              // Vertical alignment and translation.
              for(
            int index = objects.Count - 1;
            index >= 0;
            index--
            )
              {
            RowObject obj = objects[index];

            // Vertical alignment.
            double objectYOffset = 0;
            {
              LineAlignmentEnum lineAlignment;
              double lineRise;
              {
            object objectLineAlignment = obj.LineAlignment;
            if(objectLineAlignment is Double)
            {
              lineAlignment = LineAlignmentEnum.BaseLine;
              lineRise = (double)objectLineAlignment;
            }
            else
            {
              lineAlignment = (LineAlignmentEnum)objectLineAlignment;
              lineRise = 0;
            }
              }
              switch (lineAlignment)
              {
              case LineAlignmentEnum.Top:
                  /* NOOP */
                  break;
              case LineAlignmentEnum.Middle:
                  objectYOffset = -(currentRow.Height - obj.Height) / 2;
                  break;
              case LineAlignmentEnum.BaseLine:
                  objectYOffset = -(currentRow.BaseLine - obj.BaseLine - lineRise);
                  break;
              case LineAlignmentEnum.Bottom:
                  objectYOffset = -(currentRow.Height - obj.Height);
                  break;
              default:
                  throw new NotImplementedException("Line alignment " + lineAlignment + " unknown.");
              }
            }

            IList<ContentObject> containedGraphics = obj.Container.Objects;
            // Word spacing.
            containedGraphics.Insert(0,wordSpaceOperation);
            // Translation.
            containedGraphics.Insert(
              0,
              new ModifyCTM(
            1, 0, 0, 1,
            objectXOffsets[index] + rowXOffset, // Horizontal alignment.
            objectYOffset // Vertical alignment.
            )
              );
              }

              // Update the actual block height!
              boundBox.Height = (float)(currentRow.Y + currentRow.Height);

              // Update the actual block vertical location!
              double yOffset;
              switch(yAlignment)
              {
            case YAlignmentEnum.Bottom:
              yOffset = frame.Height - boundBox.Height;
              break;
            case YAlignmentEnum.Middle:
              yOffset = (frame.Height - boundBox.Height) / 2;
              break;
            case YAlignmentEnum.Top:
            default:
              yOffset = 0;
              break;
              }
              boundBox.Y = (float)(frame.Y + yOffset);

              // Discard the current row!
              currentRow = null;
        }
예제 #9
0
        /**
          <summary>Shows the specified external object.</summary>
          <param name="xObject">External object.</param>
          <param name="size">Size of the external object.</param>
          <param name="lineAlignment">Line alignment. It can be:
        <list type="bullet">
          <item><see cref="LineAlignmentEnum"/></item>
          <item><see cref="Length">: arbitrary super-/sub-script, depending on whether the value is
          positive or not.</item>
        </list>
          </param>
          <returns>Whether the external object was successfully shown.</returns>
        */
        public bool ShowXObject(
      xObjects::XObject xObject,
      SizeF? size,
      object lineAlignment
      )
        {
            if(currentRow == null
            || xObject == null)
            return false;

              if(!size.HasValue)
              {size = xObject.Size;}
              lineAlignment = ResolveLineAlignment(lineAlignment);

              while(true)
              {
            if(OperationUtils.Compare(currentRow.Y + size.Value.Height, frame.Height) == 1) // Object's height exceeds block's remaining vertical space.
            {
              // Terminate current row and exit!
              EndRow(false);
              return false;
            }
            else if(OperationUtils.Compare(currentRow.Width + size.Value.Width, frame.Width) < 1) // There's room for the object in the current row.
            {
              PointF location = new PointF(
            (float)currentRow.Width,
            (float)currentRow.Y
            );
              RowObject obj;
              {
            obj = new RowObject(
              RowObject.TypeEnum.XObject,
              baseComposer.BeginLocalState(), // Opens the row object's local state.
              size.Value.Height,
              size.Value.Width,
              0,
              lineAlignment,
              size.Value.Height
              );
            baseComposer.ShowXObject(xObject, location, size);
            baseComposer.End(); // Closes the row object's local state.
              }
              AddRowObject(obj, lineAlignment);

              return true;
            }
            else // There's NOT enough room for the object in the current row.
            {
              // Go to next row!
              EndRow(false);
              BeginRow();
            }
              }
        }
예제 #10
0
        /**
          <summary>Shows text.</summary>
          <param name="text">Text to show.</param>
          <param name="lineAlignment">Line alignment. It can be:
        <list type="bullet">
          <item><see cref="LineAlignmentEnum"/></item>
          <item><see cref="Length">: arbitrary super-/sub-script, depending on whether the value is
          positive or not.</item>
        </list>
          </param>
          <returns>Last shown character index.</returns>
        */
        public int ShowText(
      string text,
      object lineAlignment
      )
        {
            if(currentRow == null
            || text == null)
            return 0;

              ContentScanner.GraphicsState state = baseComposer.State;
              fonts::Font font = state.Font;
              double fontSize = state.FontSize;
              double lineHeight = font.GetLineHeight(fontSize);
              double baseLine = font.GetAscent(fontSize);
              lineAlignment = ResolveLineAlignment(lineAlignment);

              TextFitter textFitter = new TextFitter(
            text,
            0,
            font,
            fontSize,
            hyphenation,
            hyphenationCharacter
            );
              int textLength = text.Length;
              int index = 0;

              while(true)
              {
            if(currentRow.Width == 0) // Current row has just begun.
            {
              // Removing leading space...
              while(true)
              {
            if(index == textLength) // Text end reached.
              goto endTextShowing;
            else if(text[index] != ' ') // No more leading spaces.
              break;

            index++;
              }
            }

            if(OperationUtils.Compare(currentRow.Y + lineHeight, frame.Height) == 1) // Text's height exceeds block's remaining vertical space.
            {
              // Terminate the current row and exit!
              EndRow(false);
              goto endTextShowing;
            }

            // Does the text fit?
            if(textFitter.Fit(
              index,
              frame.Width - currentRow.Width, // Remaining row width.
              currentRow.SpaceCount == 0
              ))
            {
              // Get the fitting text!
              string textChunk = textFitter.FittedText;
              double textChunkWidth = textFitter.FittedWidth;
              PointF textChunkLocation = new PointF(
            (float)currentRow.Width,
            (float)currentRow.Y
            );

              // Insert the fitting text!
              RowObject obj;
              {
            obj = new RowObject(
              RowObject.TypeEnum.Text,
              baseComposer.BeginLocalState(), // Opens the row object's local state.
              lineHeight,
              textChunkWidth,
              CountOccurrence(' ',textChunk),
              lineAlignment,
              baseLine
              );
            baseComposer.ShowText(textChunk, textChunkLocation);
            baseComposer.End();  // Closes the row object's local state.
              }
              AddRowObject(obj, lineAlignment);

              index = textFitter.EndIndex;
            }

            // Evaluating trailing text...
            while(true)
            {
              if(index == textLength) // Text end reached.
            goto endTextShowing;

              switch(text[index])
              {
            case '\r':
              break;
            case '\n':
              // New paragraph!
              index++;
              ShowBreak();
              goto endTrailParsing;
            default:
              // New row (within the same paragraph)!
              EndRow(false);
              BeginRow();
              goto endTrailParsing;
              }

              index++;
            } endTrailParsing:;
              } endTextShowing:;
              if(index >= 0
            && lineAlignment.Equals(LineAlignmentEnum.BaseLine))
              {lastFontSize = fontSize;}

              return index;
        }