// 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; }
// 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); }