/// <summary>
        /// 
        /// </summary>
        /// <param name="htmlContainer">the container of the html to handle load stylesheet for</param>
        /// <param name="src">the source of the element to load the stylesheet by</param>
        /// <param name="attributes">the attributes of the link element</param>
        public static string LoadStylesheet(HtmlContainer htmlContainer, string src, Dictionary<string, string> attributes)
        {
            ArgChecker.AssertArgNotNull(htmlContainer, "htmlContainer");

            try
            {
                var args = new HtmlStylesheetLoadEventArgs(src, attributes);
                htmlContainer.RaiseHtmlStylesheetLoadEvent(args);

                if(args.SetStyleSheet != null)
                {
                    return args.SetStyleSheet;
                }
                else if(args.SetSrc != null)
                {
                    return LoadStylesheet(htmlContainer, args.SetSrc);
                }
                else
                {
                    return LoadStylesheet(htmlContainer, src);
                }
            }
            catch (Exception ex)
            {
                htmlContainer.ReportError(HtmlRenderErrorType.CssParsing, "Exception in handling stylesheet source", ex);
                return string.Empty;
            }
        }
Пример #2
0
        /// <summary>
        /// Generate css tree by parsing the given html and applying the given css style data on it.
        /// </summary>
        /// <param name="html">the html to parse</param>
        /// <param name="htmlContainer">the html container to use for reference resolve</param>
        /// <param name="cssData">the css data to use</param>
        /// <returns>the root of the generated tree</returns>
        public static CssBox GenerateCssTree(string html, HtmlContainer htmlContainer, ref CssData cssData)
        {
            var root = HtmlParser.ParseDocument(html);
            if (root != null)
            {
                root.HtmlContainer = htmlContainer;

                bool cssDataChanged = false;
                CascadeStyles(root, htmlContainer, ref cssData, ref cssDataChanged);

                SetTextSelectionStyle(htmlContainer, cssData);

                CorrectTextBoxes(root);

                CorrectImgBoxes(root);

                CorrectLineBreaksBlocks(root);

                CorrectInlineBoxesParent(root);

                CorrectBlockInsideInline(root);

                CorrectInlineBoxesParent(root);
            }
            return root;
        }
 /// <summary>
 /// Load stylesheet string from given source (file path or uri).
 /// </summary>
 /// <param name="htmlContainer">the container of the html to handle load stylesheet for</param>
 /// <param name="src">the file path or uri to load the stylesheet from</param>
 /// <returns>the stylesheet string</returns>
 private static string LoadStylesheet(HtmlContainer htmlContainer, string src)
 {
     var uri = CommonUtils.TryGetUri(src);
     if (uri != null && uri.Scheme != "file")
     {
         return LoadStylesheetFromUri(uri);
     }
     else
     {
         return LoadStylesheetFromFile(htmlContainer, uri != null ? uri.AbsolutePath : src);
     }
 }
Пример #4
0
        /// <summary>
        /// Set image of this image box by analyzing the src attribute.<br/>
        /// Load the image from inline base64 encoded string.<br/>
        /// Or from calling property/method on the bridge object that returns image or url to image.<br/>
        /// Or from file path<br/>
        /// Or from URI.
        /// </summary>
        /// <remarks>
        /// File path and URI image loading is executed async and after finishing calling <see cref="ImageLoadComplete"/>
        /// on the main thread and not thread-pool.
        /// </remarks>
        /// <param name="htmlContainer">the container of the html to handle load image for</param>
        /// <param name="src">the source of the image to load</param>
        /// <param name="attributes">the collection of attributes on the element to use in event</param>
        /// <returns>the image object (null if failed)</returns>
        public void LoadImage(HtmlContainer htmlContainer, string src, Dictionary<string, string> attributes)
        {
            ArgChecker.AssertArgNotNull(htmlContainer, "htmlContainer");

            _htmlContainer = htmlContainer;

            try
            {
                var args = new HtmlImageLoadEventArgs(src, attributes, OnHtmlImageLoadEventCallback);
                _htmlContainer.RaiseHtmlImageLoadEvent(args);
                _asyncCallback = true;

                if (!args.Handled)
                {
                    if (!string.IsNullOrEmpty(src))
                    {
                        if (src.StartsWith("data:image", StringComparison.CurrentCultureIgnoreCase))
                        {
                            _image = GetImageFromData(src);
                            if (_image == null)
                                _htmlContainer.ReportError(HtmlRenderErrorType.Image, "Failed extract image from inline data");
                            _releaseImageObject = true;
                            ImageLoadComplete(false);
                        }
                        else
                        {
                            SetImageFromPath(src);
                        }
                    }
                    else
                    {
                        ImageLoadComplete(false);
                    }
                }
            }
            catch (Exception ex)
            {
                _htmlContainer.ReportError(HtmlRenderErrorType.Image, "Exception in handling image source", ex);
                ImageLoadComplete(false);
            }
        }
Пример #5
0
        static void Main()
        {
            using (var bitmap = new Bitmap(300, 200, PixelFormat.Format24bppRgb))
            {
                using (var graphics = Graphics.FromImage(bitmap))
                {
                    graphics.Clear(Color.Black);

                    graphics.DrawLine(Pens.Fuchsia, 0,0,300,200);

                    TextRenderer.DrawText(graphics, "TEST", new Font("Arial", 20), new Point(0, 0), Color.FromArgb(50, 0, 255, 0),Color.White);

                    graphics.CompositingQuality = CompositingQuality.HighQuality;
                    graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    graphics.SmoothingMode = SmoothingMode.HighQuality;
                    graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;

                    using (var htmlContainer = new HtmlContainer())
                    {
                        htmlContainer.TextRenderingMethod = TextRenderingMethod.Gdi;
                        htmlContainer.AvoidGeometryAntialias = false;
                        htmlContainer.SetHtml(File.ReadAllText(@"c:\source\html.txt"));
                        htmlContainer.MaxSize = new SizeF(bitmap.Width, bitmap.Height);
                        htmlContainer.PerformLayout(graphics);
                        htmlContainer.PerformPaint(graphics);
                    }
                }

                bitmap.Save(@"c:\source\test.png");
            }

            return;

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            Application.Run(new DemoForm());

            //            Application.Run(new PerfForm());

            //            ObfuscateHtml();
        }
 /// <summary>
 /// Load the stylesheet from local file by given path.
 /// </summary>
 /// <param name="htmlContainer">the container of the html to handle load stylesheet for</param>
 /// <param name="path">the stylesheet file to load</param>
 /// <returns>the loaded stylesheet string</returns>
 private static string LoadStylesheetFromFile(HtmlContainer htmlContainer, string path)
 {
     var fileInfo = CommonUtils.TryGetFileInfo(path);
     if (fileInfo != null)
     {
         if (fileInfo.Exists)
         {
             using (var sr = new StreamReader(fileInfo.FullName))
             {
                 return sr.ReadToEnd();
             }
         }
         else
         {
             htmlContainer.ReportError(HtmlRenderErrorType.CssParsing, "No stylesheet found by path: " + path);
         }
     }
     else
     {
         htmlContainer.ReportError(HtmlRenderErrorType.CssParsing, "Failed load image, invalid source: " + path);
     }
     return string.Empty;
 }
Пример #7
0
        /// <summary>
        /// Set the selected text style (selection text color and background color).
        /// </summary>
        /// <param name="htmlContainer"> </param>
        /// <param name="cssData">the style data</param>
        private static void SetTextSelectionStyle(HtmlContainer htmlContainer, CssData cssData)
        {
            htmlContainer.SelectionForeColor = Color.Empty;
            htmlContainer.SelectionBackColor = Color.Empty;

            if (cssData.ContainsCssBlock("::selection"))
            {
                var blocks = cssData.GetCssBlock("::selection");
                foreach (var block in blocks)
                {
                    if (block.Properties.ContainsKey("color"))
                        htmlContainer.SelectionForeColor = CssValueParser.GetActualColor(block.Properties["color"]);
                    if (block.Properties.ContainsKey("background-color"))
                        htmlContainer.SelectionBackColor = CssValueParser.GetActualColor(block.Properties["background-color"]);
                }
            }
        }
Пример #8
0
        /// <summary>
        /// Applies style to all boxes in the tree.<br/>
        /// If the html tag has style defined for each apply that style to the css box of the tag.<br/>
        /// If the html tag has "class" attribute and the class name has style defined apply that style on the tag css box.<br/>
        /// If the html tag has "style" attribute parse it and apply the parsed style on the tag css box.<br/>
        /// If the html tag is "style" tag parse it content and add to the css data for all future tags parsing.<br/>
        /// If the html tag is "link" that point to style data parse it content and add to the css data for all future tags parsing.<br/>
        /// </summary>
        /// <param name="box"></param>
        /// <param name="htmlContainer">the html container to use for reference resolve</param>
        /// <param name="cssData"> </param>
        /// <param name="cssDataChanged">check if the css data has been modified by the handled html not to change the base css data</param>
        private static void CascadeStyles(CssBox box, HtmlContainer htmlContainer, ref CssData cssData, ref bool cssDataChanged)
        {
            box.InheritStyle();

            if (box.HtmlTag != null)
            {
                // try assign style using the html element tag
                AssignCssBlocks(box, cssData, box.HtmlTag.Name);

                // try assign style using the "class" attribute of the html element
                if (box.HtmlTag.HasAttribute("class"))
                {
                    AssignClassCssBlocks(box, cssData);
                }

                // try assign style using the "id" attribute of the html element
                if (box.HtmlTag.HasAttribute("id"))
                {
                    var id = box.HtmlTag.TryGetAttribute("id");
                    AssignCssBlocks(box, cssData, "#" + id);
                }

                TranslateAttributes(box.HtmlTag, box);

                // Check for the style="" attribute
                if (box.HtmlTag.HasAttribute("style"))
                {
                    var block = CssParser.ParseCssBlock(box.HtmlTag.Name, box.HtmlTag.TryGetAttribute("style"));
                    AssignCssBlock(box, block);
                }

                // Check for the <style> tag
                if (box.HtmlTag.Name.Equals("style", StringComparison.CurrentCultureIgnoreCase) && box.Boxes.Count == 1)
                {
                    CloneCssData(ref cssData, ref cssDataChanged);
                    CssParser.ParseStyleSheet(cssData, box.Boxes[0].Text.CutSubstring());
                }

                // Check for the <link rel=stylesheet> tag
                if (box.HtmlTag.Name.Equals("link", StringComparison.CurrentCultureIgnoreCase) &&
                    box.GetAttribute("rel", string.Empty).Equals("stylesheet", StringComparison.CurrentCultureIgnoreCase))
                {
                    CloneCssData(ref cssData, ref cssDataChanged);
                    var styleSheet = StylesheetLoadHelper.LoadStylesheet(htmlContainer, box.GetAttribute("href", string.Empty), box.HtmlTag.Attributes);
                    CssParser.ParseStyleSheet(cssData, styleSheet);
                }
            }

            // cascade text decoration only to boxes that actually have text so it will be handled correctly.
            if (box.TextDecoration != String.Empty && box.Text == null)
            {
                foreach (var childBox in box.Boxes)
                    childBox.TextDecoration = box.TextDecoration;
                box.TextDecoration = string.Empty;
            }

            foreach (var childBox in box.Boxes)
            {
                CascadeStyles(childBox, htmlContainer, ref cssData, ref cssDataChanged);
            }
        }
        /// <summary>
        /// Init.
        /// </summary>
        /// <param name="selectionHandler">the selection handler linked to the context menu handler</param>
        /// <param name="htmlContainer">the html container the handler is on</param>
        public ContextMenuHandler(SelectionHandler selectionHandler, HtmlContainer htmlContainer)
        {
            ArgChecker.AssertArgNotNull(selectionHandler, "selectionHandler");
            ArgChecker.AssertArgNotNull(htmlContainer, "htmlContainer");

            _selectionHandler = selectionHandler;
            _htmlContainer = htmlContainer;
        }