示例#1
0
        public FrameworkElement GetPage(int chapterIndex, int pageIndex)
        {
            if (pageSize.IsEmpty)
            {
                return(null);
            }

            if (pageIndex < 0)
            {
                return(null);
            }

            if (chapterIndex < 0 || chapterIndex > this.Book.Chapters.Count - 1)
            {
                return(null);
            }

            ChapterInfo chapter = this.Book.Chapters[chapterIndex];

            // Check if the last page of the paragraph has already been established,
            //  and the requested page is greater than that last page
            if (chapter.Pages[chapter.Pages.Count - 1].IsLastPageInChapter && pageIndex > chapter.Pages.Count - 1)
            {
                return(null);
            }

            // If the last page of a chapter is requested, and it's already available, get it
            if (pageIndex < chapter.Pages.Count && chapter.Pages[pageIndex].IsLastPageInChapter)
            {
                return(BuildPageElement(chapter, chapter.Pages[pageIndex]));
            }

            // Otherwise, if the page has already been paginated, get it
            if (pageIndex + 1 < chapter.Pages.Count && chapter.Pages[pageIndex].IsPaginated)
            {
                return(BuildPageElement(chapter, chapter.Pages[pageIndex]));
            }

            if (pageIndex != chapter.Pages.Count - 1)
            {
                throw new Exception(String.Format("GetPage can only paginate one page per call: pageIndex = {0} while chapter.Pages.Count = {1}", pageIndex, chapter.Pages.Count));
            }

            PageInfo pageInfo = chapter.Pages[pageIndex];

            PageInfo nextPageInfo = Paginate(chapter, pageInfo);

            if (nextPageInfo != null)   // ie, if !pageInfo.IsLastPageInChapter
            {
                chapter.Pages.Add(nextPageInfo);
            }

            return(BuildPageElement(chapter, pageInfo));
        }
示例#2
0
        void GenerateChapters()
        {
            // Set so the beginning of the book becomes the first chapter
            int         consecutiveBlankLineCount = 10;
            int         accumulatedCharacterCount = 0;
            ChapterInfo chapterInfo = null;

            for (int paragraphIndex = 0; paragraphIndex < paragraphs.Count; paragraphIndex++)
            {
                if (paragraphs[paragraphIndex].Text.Length == 0)
                {
                    consecutiveBlankLineCount += 1;
                }
                else
                {
                    if (consecutiveBlankLineCount > 2)
                    {
                        PageInfo pageInfo = new PageInfo
                        {
                            ParagraphIndex            = paragraphIndex,
                            CharacterIndex            = 0,
                            AccumulatedCharacterCount = accumulatedCharacterCount
                        };

                        chapterInfo = new ChapterInfo
                        {
                            Title          = paragraphs[paragraphIndex].Text.Length < 100 ? paragraphs[paragraphIndex].Text : paragraphs[paragraphIndex].Text.Substring(0, 100),
                            FirstParagraph = paragraphIndex,
                            ParagraphCount = 1
                        };
                        chapterInfo.Pages.Add(pageInfo);
                        this.Book.Chapters.Add(chapterInfo);
                    }
                    else
                    {
                        // Accumulate number of paragraphs in the chapter
                        chapterInfo.ParagraphCount += 1 + consecutiveBlankLineCount;
                    }
                    consecutiveBlankLineCount  = 0;
                    accumulatedCharacterCount += paragraphs[paragraphIndex].Text.Length;
                }
            }

            // Flag the last chapter
            this.Book.Chapters[this.Book.Chapters.Count - 1].IsLastChapter = true;
            this.Book.CharacterCount = accumulatedCharacterCount;
        }
示例#3
0
        FrameworkElement GetLastPage(int chapterIndex, out int pageIndex, bool paginateIfNecessary)
        {
            if (pageSize.IsEmpty)
            {
                pageIndex = -1;
                return(null);
            }

            if (chapterIndex < 0 || chapterIndex > this.Book.Chapters.Count - 1)
            {
                pageIndex = -1;
                return(null);
            }

            ChapterInfo chapter   = this.Book.Chapters[chapterIndex];
            int         lastIndex = chapter.Pages.Count - 1;

            if (chapter.Pages[lastIndex].IsLastPageInChapter &&
                chapter.Pages[lastIndex].IsPaginated)               // IsPaginated should be implied
            {
                pageIndex = lastIndex;
                return(BuildPageElement(chapter, chapter.Pages[lastIndex]));
            }

            if (!paginateIfNecessary)
            {
                pageIndex = -1;
                return(null);
            }

            while (!chapter.Pages[chapter.Pages.Count - 1].IsLastPageInChapter)
            {
                Paginate(chapterIndex, chapter.Pages.Count - 1);
            }

            pageIndex = chapter.Pages.Count - 1;
            return(BuildPageElement(chapter, chapter.Pages[chapter.Pages.Count - 1]));
        }
示例#4
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;
        }
示例#5
0
        void GenerateChapters()
        {
            // Set so the beginning of the book becomes the first chapter
            int consecutiveBlankLineCount = 10;
            int accumulatedCharacterCount = 0;
            ChapterInfo chapterInfo = null;

            for (int paragraphIndex = 0; paragraphIndex < paragraphs.Count; paragraphIndex++)
            {
                if (paragraphs[paragraphIndex].Text.Length == 0)
                {
                    consecutiveBlankLineCount += 1;
                }
                else
                {
                    if (consecutiveBlankLineCount > 2)
                    {
                        PageInfo pageInfo = new PageInfo
                        {
                            ParagraphIndex = paragraphIndex,
                            CharacterIndex = 0,
                            AccumulatedCharacterCount = accumulatedCharacterCount
                        };

                        chapterInfo = new ChapterInfo
                        {
                            Title = paragraphs[paragraphIndex].Text.Length < 100 ? paragraphs[paragraphIndex].Text : paragraphs[paragraphIndex].Text.Substring(0, 100),
                            FirstParagraph = paragraphIndex,
                            ParagraphCount = 1
                        };
                        chapterInfo.Pages.Add(pageInfo);
                        this.Book.Chapters.Add(chapterInfo);
                    }
                    else
                    {
                        // Accumulate number of paragraphs in the chapter
                        chapterInfo.ParagraphCount += 1 + consecutiveBlankLineCount;
                    }
                    consecutiveBlankLineCount = 0;
                    accumulatedCharacterCount += paragraphs[paragraphIndex].Text.Length;
                }
            }

            // Flag the last chapter
            this.Book.Chapters[this.Book.Chapters.Count - 1].IsLastChapter = true;
            this.Book.CharacterCount = accumulatedCharacterCount;
        }
示例#6
0
        FrameworkElement BuildPageElement(ChapterInfo chapter,
            PageInfo pageInfo)
        {
            if (pageInfo.Words.Count == 0)
            {
                Paginate(chapter, pageInfo);
            }

            Canvas canvas = new Canvas();

            foreach (WordInfo word in pageInfo.Words)
            {
                TextBlock txtblk = new TextBlock
                {
                    FontFamily = fontMetrics.Font.FontFamily,
                    FontSize = this.fontSize,
                    Text = paragraphs[word.ParagraphIndex].Text.
                                Substring(word.CharacterIndex,
                                          word.CharacterCount),
                    Tag = word
                };

                Canvas.SetLeft(txtblk, word.LocationLeft);
                Canvas.SetTop(txtblk, word.LocationTop);
                canvas.Children.Add(txtblk);
            }
            return canvas;
        }
示例#7
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);
        }