private double BuildContext(PageRenderData context, ParagraphInfo p, double width, double defaultFontSize, int paragraphID, double top) { TextAlignment align = GetTextAlignment(p); var list = new List<TextElement>(); bool firstLine = true; foreach (TextElementBase baseInlineItem in p.Inlines) { if (baseInlineItem is EOLElement) { top = AppendLine(context, list, align, p, width, top, defaultFontSize, paragraphID, firstLine); firstLine = false; list.Clear(); } else { var inlineItem = (TextElement) baseInlineItem; list.Add(inlineItem); } } return AppendLine(context, list, align == TextAlignment.Justify ? TextAlignment.Left : align, p, width, top, defaultFontSize, paragraphID, firstLine); }
public async Task<PageRenderData> RenderPageAsync(RenderPageRequest request) { var context = new PageRenderData { Page = request.Page, Book = request.Book, Bookmarks = request.Bookmarks, PageSize = new Size( request.Panel.Width - AppSettings.Default.Margin.Left - AppSettings.Default.Margin.Right, request.Panel.Height - AppSettings.Default.Margin.Top - AppSettings.Default.Margin.Bottom), OffsetX = (int) AppSettings.Default.Margin.Left, OffsetY = (int) AppSettings.Default.Margin.Top, Panel = request.Panel, BackgroundBrush = AppSettings.Default.ColorScheme.BackgroundBrush, LinkBrush = AppSettings.Default.ColorScheme.LinkForegroundBrush.Color, Links = request.Links, Texts = request.Texts, }; await Task.Factory.StartNew(() => _contextBuilder.BuildContexts(context)); Draw(context); return context; }
private double BuildImageContext(PageRenderData context, ParagraphInfo p, double top) { var item = (ImageElement)p.Inlines.First(); BookImage bookImage = _images.First(t => t.ID == item.ImageID); double offsetX = (context.PageSize.Width - p.MarginLeft - p.MarginRight - item.Width) / 2.0; var imageContext = CreateImage(context, offsetX, top, item, bookImage); context.Images.Add(imageContext); return top + item.Height; }
public void BuildContexts(PageRenderData context) { double top = 0.0; int paragraphID = 0; foreach (ParagraphInfo p in context.Page.Paragraphs) { top = p is ImageParagraphInfo ? BuildImageContext(context, p, top) : BuildContext(context, p, context.PageSize.Width, (int)AppSettings.Default.FontSettings.FontSize, paragraphID++, top); top += p.MarginBottom; } }
private void Draw(PageRenderData context) { Panel panel = context.Panel; panel.Background = context.BackgroundBrush; panel.Children.Clear(); foreach (BookmarkModel bookmarkModel in GetHighlights(context)) { var highlight = RenderHighlight(bookmarkModel, panel, context); if(highlight != null) panel.Children.Insert(0, highlight); } foreach (WordRenderData wordContext in context.Words) { var textBlock = RenderWordContext(wordContext); panel.Children.Add(textBlock); } foreach (ImageRenderData imageContext in context.Images) { var image = RenderImageContext(imageContext); panel.Children.Add(image); } }
private static IEnumerable<BookmarkModel> GetHighlights(PageRenderData context) { int left = context.Page.FirstTokenID; int right = context.Page.LastTokenID; var lastTextToken = context.Page.Lines.OfType<TextTokenBlock>().LastOrDefault(); if (lastTextToken != null) { var lastTextElement = lastTextToken.Inlines.OfType<TextElement>().LastOrDefault(); if (lastTextElement != null) { right = lastTextElement.TokenID; } } return context.Bookmarks.Where((t => { if (t.TokenID >= left && t.TokenID <= right) return true; if (t.TokenID < left && t.EndTokenID > right) return true; if (t.EndTokenID != -1 && t.EndTokenID >= left) return t.EndTokenID <= right; return false; })).ToList(); }
private static Polygon RenderHighlight(BookmarkModel bookmarkModel, Panel canvas, PageRenderData context) { int tokenID = bookmarkModel.TokenID; TextRenderData firstHighlightedText = context.Texts.FirstOrDefault(t => t.TokenID == tokenID) ?? (context.Texts).FirstOrDefault(); if (firstHighlightedText == null) return null; int endTokenID = bookmarkModel.EndTokenID; TextRenderData lastHighlightedText = context.Texts.LastOrDefault(t => t.TokenID == endTokenID) ?? (context.Texts).LastOrDefault(); if (lastHighlightedText == null) return null; Rect firtstRect = firstHighlightedText.Rect; Rect lastRect = lastHighlightedText.Rect; var pointCollection = SelectionHelper.GetSelectionPolygon( firtstRect, lastRect, canvas.ActualWidth, context.OffsetX, Convert.ToDouble(AppSettings.Default.FontSettings.FontInterval)); var polygon = new Polygon { Width = canvas.ActualWidth, Height = canvas.ActualHeight, Fill = new SolidColorBrush(ColorHelper.ToColor(bookmarkModel.Color)) {Opacity = 0.3}, Points = pointCollection, Visibility = Visibility.Visible }; return polygon; }
private static double AppendLine(PageRenderData context, ICollection<TextElement> inlines, TextAlignment align, ParagraphInfo p, double width, double top, double defaultFontSize, int paragraphID, bool firstLine) { if (inlines.Count == 0) return top; double height = inlines.Max((t => t.Height)); double inlinesWidth = inlines.Sum((t => t.Width)); double leftMargin = 0.0; double wordSpacing = 0.0; double textIndent = !firstLine || align != TextAlignment.Justify && align != TextAlignment.Left ? 0.0 : p.TextIndent; width -= p.MarginRight + p.MarginLeft + textIndent; switch (align) { case TextAlignment.Center: leftMargin = (width - inlinesWidth)/2.0; break; case TextAlignment.Right: leftMargin = width - inlinesWidth; break; case TextAlignment.Justify: wordSpacing = (width - inlinesWidth)/(inlines.Count - 1); break; } double tempLeftMargin = leftMargin + (p.MarginLeft + textIndent); inlines.Aggregate(tempLeftMargin, (current, inlineItem) => BuildInlineItem(context, top, defaultFontSize, paragraphID, inlineItem, height, current, wordSpacing)); return top + height * (double) AppSettings.Default.FontSettings.FontInterval; }
private static ImageRenderData CreateImage(PageRenderData context, double offsetX, double top, ImageElement item, BookImage bookImage) { var imageContext = new ImageRenderData { Margin = new Thickness(offsetX + context.OffsetX, top + context.OffsetY, 0.0, 0.0), Width = item.Width, Height = item.Height, ImageStream = bookImage.CreateStream() }; return imageContext; }
private static WordRenderData CreateText(PageRenderData context, TextElement element, bool bold, bool italic, double fontSize, double left, double top, Color? color) { return new WordRenderData { Text = element.Text, Bold = bold, Italic = italic, FontSize = fontSize, Left = left + context.OffsetX, Top = top + context.OffsetY, Color = color }; }
private static TextRenderData CreateTextContext(PageRenderData context, int paragraphID, TextElement inlineItem, double height, double tempLeftMargin, double topMargin) { return new TextRenderData { Text = inlineItem.Text, Rect = new Rect(tempLeftMargin + context.OffsetX, topMargin + context.OffsetY, inlineItem.Width, height), ParagraphID = paragraphID, TokenID = inlineItem.TokenID }; }
private static double BuildInlineItem(PageRenderData context, double top, double defaultFontSize, int paragraphID, TextElement inlineItem, double height, double tempLeftMargin, double wordSpacing) { double fontSize = inlineItem.Size; if (fontSize < 0.01 || !AppSettings.Default.UseCSSFontSize) fontSize = defaultFontSize; double topMargin = top; if (inlineItem.SubOption || inlineItem.SupOption) fontSize /= 2.0; if (inlineItem.SubOption) topMargin += height/2.0; if (!string.IsNullOrEmpty(inlineItem.Text) && !string.IsNullOrWhiteSpace(inlineItem.Text)) { var textContext = CreateTextContext(context, paragraphID, inlineItem, height, tempLeftMargin, topMargin); context.Texts.Add(textContext); } var color = new Color?(); if (!string.IsNullOrEmpty(inlineItem.LinkID)) { var linkContext = CreateLinkContext(inlineItem, height, tempLeftMargin, topMargin); context.Links.Add(linkContext); color = context.LinkBrush; } var wordContext = CreateText(context, inlineItem, inlineItem.Bold, inlineItem.Italic, fontSize, tempLeftMargin, topMargin, color); context.Words.Add(wordContext); return tempLeftMargin + inlineItem.Width + wordSpacing; }