Ejemplo n.º 1
0
        /**
         * <summary>Shows text.</summary>
         * <returns>Last shown character index.</returns>
         */
        public int ShowText(
            string text
            )
        {
            if (currentRow == null ||
                text == null)
            {
                return(0);
            }

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

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

            while (true)
            {
                // Beginning of current row?
                if (currentRow.Width == 0)
                {
                    // Removing leading space...
                    while (true)
                    {
                        // Did we reach the text end?
                        if (index == textLength)
                        {
                            goto endTextShowing; // NOTE: I know GOTO is evil, yet in this case it's a much cleaner solution.
                        }
                        if (text[index] != ' ')
                        {
                            break;
                        }

                        index++;
                    }
                }

                // Text height: exceeds current row's height?
                if (lineHeight > currentRow.Height)
                {
                    // Text height: exceeds block's remaining vertical space?
                    if (lineHeight > frame.Height - currentRow.Y) // Text exceeds.
                    {
                        // Terminate the current row!
                        EndRow(false);
                        goto endTextShowing; // NOTE: I know GOTO is evil, yet in this case it's a much cleaner solution.
                    }
                    else // Text doesn't exceed.
                    {
                        // Adapt current row's height!
                        currentRow.Height = lineHeight;
                    }
                }

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

                    // Render the fitting text:
                    // - open the row object's local state!

                    /*
                     * NOTE: This device allows a fine-grained control over the row object's representation.
                     * It MUST be coupled with a closing statement on row object's end.
                     */
                    RowObject obj = new RowObject(
                        baseComposer.BeginLocalState(),
                        lineHeight,
                        textChunkWidth,
                        CountOccurrence(' ', textChunk)
                        );
                    currentRow.Objects.Add(obj);
                    currentRow.SpaceCount += obj.SpaceCount;
                    // - show the text chunk!
                    baseComposer.ShowText(
                        textChunk,
                        textChunkLocation
                        );
                    // - close the row object's local state!
                    baseComposer.End();

                    // Update ancillary parameters:
                    // - update row width!
                    currentRow.Width += textChunkWidth;
                    // - update cursor position!
                    index = textFitter.EndIndex;
                }

                // Evaluating trailing text...
                while (true)
                {
                    // Did we reach the text end?
                    if (index == textLength)
                    {
                        goto endTextShowing; // NOTE: I know GOTO is evil, yet in this case it's a much cleaner solution.
                    }
                    switch (text[index])
                    {
                    case '\r':
                        break;

                    case '\n':
                        // New paragraph!
                        index++;
                        ShowBreak();
                        goto endTrailParsing; // NOTE: I know GOTO is evil, yet in this case it's a much cleaner solution.

                    default:
                        // New row (within the same paragraph)!
                        EndRow(false); BeginRow();
                        goto endTrailParsing; // NOTE: I know GOTO is evil, yet in this case it's a much cleaner solution.
                    }

                    index++;
                }
                endTrailParsing :;
            }
            endTextShowing :;

            return(index);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Conta o número de linhas que o texto vai ocupar.
        /// </summary>
        /// <param name="font">Fonte do texto</param>
        /// <param name="fontSize">Tamanho da fonte</param>
        /// <param name="width">Largura máxima do texto</param>
        /// <param name="text">Texto</param>
        /// <returns>Número de linhas</returns>
        internal static int CountTextLines(Font font, double fontSize, double width, String text)
        {
            if (String.IsNullOrWhiteSpace(text))
            {
                return 0;
            }

            if (font == null)
            {
                throw new ArgumentNullException("font");
            }

            if (fontSize <= 0)
            {
                throw new ArgumentOutOfRangeException("fontSize");
            }

            if (width <= 0)
            {
                throw new ArgumentOutOfRangeException("width");
            }

            int lines = 0;
            int index = 0, end;
            TextFitter tf = new TextFitter(text, width, font, fontSize, false, '-');

            while (index < text.Length)
            {
                tf.Fit(index, width, true);
                end = tf.EndIndex;

                // Isso evita um loop infinito, impedindo que o index permaneça o mesmo.
                index = index == end ? end + 1 : end;
                lines++;
            }

            return lines;
        }
Ejemplo n.º 4
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;
        }