Ejemplo n.º 1
0
        // TODO: Could pass chapter and pageIndex here, to obtain pageInfo within, and then can set nextPageInfo
        PageInfo Paginate(ChapterInfo chapter, PageInfo pageInfo)
        {
            // Get dimensions of space character
            Size spaceSize  = fontMetrics.MeasureText(" ");
            int  lineHeight = (int)Math.Ceiling(fontSize * spaceSize.Height);
            int  spaceWidth = (int)Math.Ceiling(fontSize * spaceSize.Width);

            // Initialize a couple variables
            int      accumHeight    = 0;
            int      characterCount = pageInfo.AccumulatedCharacterCount;
            PageInfo nextPageInfo   = null;
            int      paragraphIndex = pageInfo.ParagraphIndex;
            int      characterIndex = pageInfo.CharacterIndex;

            // Loop for lines on page
            while (true)
            {
                ParagraphInfo paragraph = paragraphs[paragraphIndex];

                // For blank paragraphs, leave a gap...
                if (paragraph.Text.Length == 0)
                {
                    // .. but not when it's at the top of the page
                    if (accumHeight > 0)
                    {
                        accumHeight += (int)Math.Ceiling(ParagraphSpacing * lineHeight);
                    }
                }
                // Normal case for non-blank paragraphs
                else
                {
                    // This is the amount to indent the entire paragraph
                    int indent = spaceWidth * paragraph.Indent;

                    // Apply first line indent if paragraph indent is zero, and it's
                    //  not the first paragraph in the chapter
                    if (indent == 0 &&
                        characterIndex == 0 &&
                        paragraph != paragraphs[chapter.FirstParagraph])
                    {
                        indent = spaceWidth * FirstLineIndent;
                    }

                    // Start off accumulated line width with the indent
                    int accumWidth = indent;

                    // Loop for words within line -- always the same paragraph
                    while (true)
                    {
                        // Find next space in paragraph
                        int spaceIndex     = paragraph.Text.IndexOf(' ', characterIndex);
                        int wordCharacters = (spaceIndex == -1 ? paragraph.Text.Length : spaceIndex) - characterIndex;
                        int wordWidth      = (int)Math.Ceiling(fontSize * fontMetrics.MeasureText(paragraph.Text, characterIndex, wordCharacters).Width);

                        // Check if the accumulated width exceeds the page width,
                        //      but make sure to have at least one word.
                        if (accumWidth > indent && accumWidth + wordWidth >= pageSize.Width)
                        {
                            break;
                        }

                        WordInfo word = new WordInfo
                        {
                            LocationLeft   = accumWidth,
                            LocationTop    = accumHeight,
                            ParagraphIndex = paragraphIndex,
                            CharacterIndex = characterIndex,
                            CharacterCount = wordCharacters,
                        };
                        pageInfo.Words.Add(word);

                        accumWidth     += wordWidth;
                        characterCount += wordCharacters + (spaceIndex == -1 ? 0 : 1);
                        characterIndex += wordCharacters + (spaceIndex == -1 ? 0 : 1);

                        // End of line because it's the end of the paragraph
                        if (spaceIndex == -1)
                        {
                            characterIndex = 0;
                            break;
                        }

                        // End of line because no more words will fit
                        if (accumWidth + spaceWidth >= pageSize.Width)
                        {
                            break;
                        }

                        accumWidth += spaceWidth;

                        // Otherwise, point to next word
                        characterIndex = spaceIndex + 1;

                        // ready for next word
                    }
                    // Bump up the accumulated height of the page
                    accumHeight += lineHeight;
                }

                // Start a new line, but check first if it's a new paragraph
                if (characterIndex == 0)
                {
                    // If we've been working with the last paragraph in the chapter,
                    //      we're also done with the page
                    if (paragraphIndex + 1 == chapter.FirstParagraph + chapter.ParagraphCount)
                    {
                        pageInfo.IsLastPageInChapter = true;
                        break;
                    }
                    // Otherwise, kick up the paragraphIndex
                    paragraphIndex++;
                }

                // Check if the next paragraph is too much for this page
                if ((paragraphs[paragraphIndex].Text.Length == 0 &&
                     accumHeight + lineHeight / 2 > pageSize.Height) ||
                    accumHeight + lineHeight > pageSize.Height)
                {
                    break;
                }
            }

            pageInfo.IsPaginated = true;

            // Create PageInfo for next page
            if (!pageInfo.IsLastPageInChapter)
            {
                nextPageInfo = new PageInfo
                {
                    ParagraphIndex            = paragraphIndex,
                    CharacterIndex            = characterIndex,
                    AccumulatedCharacterCount = characterCount
                };
            }

            return(nextPageInfo);
        }
Ejemplo n.º 2
0
        private void GenerateParagraphs(StreamReader stream)
        {
            string line = null;
            string prevLine = null;
            int prevIndent = 0;
            var paragraphBuilder = new StringBuilder();

            while (null != (line = stream.ReadLine()))
            {
                // Trim line of all space and find the line indent
                line = line.TrimEnd(' ');
                int indent = line.Length;
                line = line.TrimStart(' ');
                indent -= line.Length;

                // A new paragraph is always implied with a line of zero length
                bool newParagraph = line.Length == 0;

                if (!newParagraph && paragraphBuilder.Length > 0 && prevLine != null)
                {
                    // This is the case for a list ("contents" for example)
                    //  where each line has a different indent
                    if (indent != prevIndent)
                    {
                        newParagraph = true;
                    }

                        // But some indented text needs to be concatenated (epistoles, for example)
                    else if (indent != 0)
                    {
                        string firstWord = line;
                        int spaceIndex = line.IndexOf(' ');

                        if (spaceIndex != -1)
                            firstWord = firstWord.Substring(0, spaceIndex);

                        // This works for some books, but not for "Phineas Finn" where
                        //  at least the first letter has shorter lines than normal
                        // if (indent + prevLine.Length + 1 + firstWord.Length <= 70)
                        //     newParagraph = true;
                    }
                }

                // Check for a possible paragraph termination
                if (newParagraph)
                {
                    if (paragraphBuilder.Length > 0)
                    {
                        SubstituteCharacters(paragraphBuilder);

                        // Create a new ParagraphInfo for the paragraph
                        ParagraphInfo paragraph = new ParagraphInfo
                        {
                            Indent = prevIndent,
                            Text = paragraphBuilder.ToString()
                        };
                        paragraphs.Add(paragraph);

                        // Clear the StringBuilder
                        paragraphBuilder.Remove(0, paragraphBuilder.Length);
                    }

                    if (line.Length > 0)
                    {
                        // Append the line to the paragraph
                        paragraphBuilder.Append(line);
                    }
                    else
                    {
                        // Add the current line that terminates the paragraph
                        ParagraphInfo emptyParagraph = new ParagraphInfo
                        {
                            Indent = 0,
                            Text = line
                        };
                        paragraphs.Add(emptyParagraph);
                    }
                }
                else
                {
                    // Insert a space between appended lines assembled into paragraph
                    if (paragraphBuilder.Length > 0)
                        paragraphBuilder.Append(" ");

                    paragraphBuilder.Append(line);
                }
                prevLine = line;
                prevIndent = indent;
            }

            // Add the last paragraph if there's one in progress
            if (paragraphBuilder.Length > 0)
            {
                SubstituteCharacters(paragraphBuilder);

                ParagraphInfo paragraph = new ParagraphInfo
                {
                    Indent = prevIndent,
                    Text = paragraphBuilder.ToString()
                };
                paragraphs.Add(paragraph);
            }
        }
Ejemplo n.º 3
0
        private void GenerateParagraphs(StreamReader stream)
        {
            string line             = null;
            string prevLine         = null;
            int    prevIndent       = 0;
            var    paragraphBuilder = new StringBuilder();

            while (null != (line = stream.ReadLine()))
            {
                // Trim line of all space and find the line indent
                line = line.TrimEnd(' ');
                int indent = line.Length;
                line    = line.TrimStart(' ');
                indent -= line.Length;

                // A new paragraph is always implied with a line of zero length
                bool newParagraph = line.Length == 0;

                if (!newParagraph && paragraphBuilder.Length > 0 && prevLine != null)
                {
                    // This is the case for a list ("contents" for example)
                    //  where each line has a different indent
                    if (indent != prevIndent)
                    {
                        newParagraph = true;
                    }

                    // But some indented text needs to be concatenated (epistoles, for example)
                    else if (indent != 0)
                    {
                        string firstWord  = line;
                        int    spaceIndex = line.IndexOf(' ');

                        if (spaceIndex != -1)
                        {
                            firstWord = firstWord.Substring(0, spaceIndex);
                        }

                        // This works for some books, but not for "Phineas Finn" where
                        //  at least the first letter has shorter lines than normal
                        // if (indent + prevLine.Length + 1 + firstWord.Length <= 70)
                        //     newParagraph = true;
                    }
                }

                // Check for a possible paragraph termination
                if (newParagraph)
                {
                    if (paragraphBuilder.Length > 0)
                    {
                        SubstituteCharacters(paragraphBuilder);

                        // Create a new ParagraphInfo for the paragraph
                        ParagraphInfo paragraph = new ParagraphInfo
                        {
                            Indent = prevIndent,
                            Text   = paragraphBuilder.ToString()
                        };
                        paragraphs.Add(paragraph);

                        // Clear the StringBuilder
                        paragraphBuilder.Remove(0, paragraphBuilder.Length);
                    }

                    if (line.Length > 0)
                    {
                        // Append the line to the paragraph
                        paragraphBuilder.Append(line);
                    }
                    else
                    {
                        // Add the current line that terminates the paragraph
                        ParagraphInfo emptyParagraph = new ParagraphInfo
                        {
                            Indent = 0,
                            Text   = line
                        };
                        paragraphs.Add(emptyParagraph);
                    }
                }
                else
                {
                    // Insert a space between appended lines assembled into paragraph
                    if (paragraphBuilder.Length > 0)
                    {
                        paragraphBuilder.Append(" ");
                    }

                    paragraphBuilder.Append(line);
                }
                prevLine   = line;
                prevIndent = indent;
            }

            // Add the last paragraph if there's one in progress
            if (paragraphBuilder.Length > 0)
            {
                SubstituteCharacters(paragraphBuilder);

                ParagraphInfo paragraph = new ParagraphInfo
                {
                    Indent = prevIndent,
                    Text   = paragraphBuilder.ToString()
                };
                paragraphs.Add(paragraph);
            }
        }