Closed vivek306 closed 3 years ago
The Optimus itself does not make layout or rendering.
Thanks :) is there any rendering engine that can be attached to this?
There is Knyaz.Optimus.Graphics. But first of all, it is too unstable. Secondly, there is no way to connect to the Optimus to enable GetBoundingClientRect. I will think about how to add such a feature.
New API in Optimus
//Define own layout service
class MyDocumentLayout: ILayoutService
{
public RectangleF[] GetElementBounds(Element element)
{
//todo: evaluate element rectangles
}
}
...
//Attach layout service to the document using extension method
engine.Document.AttachLayoutService(new MyDocumentLayout());
New API in Optimus.Graphics
using Knyaz.Optimus.Graphics;
//create document layout and attach it to the document
engine.Document.CreateLayout();
hey the latest version 0.2.0-alpha-93 does not seem to have CreateLayout. @RusKnyaz can you please let me know when you are planning to launch the new API for Graphics?
I uploaded latest 0.2.0-alpha-109. Check it.
sorry i am still not sure on how to evaluate the element rectangles. Currently i set it up as follows and it crashes with "Value cannot be null. (Parameter 'source')"
var engine = EngineBuilder.New().Build();
var page = await engine.OpenUrl("http://google.com");
var doc = page.Document;
var myLayout = new MyDocumentLayout();
doc.AttachLayoutService(myLayout);
var layout = doc.CreateLayout();
var element = engine.Document.GetElementById("hplogo");
var value = myLayout.GetElementBounds(element);
MyDocumentLayout is the same as you recommended above but with following changes
class MyDocumentLayout : ILayoutService
{
public System.Drawing.RectangleF[] GetElementBounds(Knyaz.Optimus.Dom.Elements.Element element)
{
var boundingBox = element.GetBoundingClientRect();
return new [] { new System.Drawing.RectangleF(boundingBox.X, boundingBox.Y, boundingBox.Width, boundingBox.Height) };
}
}
doc.AttachLayoutService should be used if you want to use your own rendering engine. doc.CreateLayout should be used if you want to use Knyaz.Optimus.Graphics rendering engine.
You shouldn't use both at the same time. Try to remove these two lines:
var myLayout = new MyDocumentLayout();
doc.AttachLayoutService(myLayout);
If the problem persists, please attach a full stack trace.
great, that makes more sense
var engine = EngineBuilder.New().Build();
var page = await engine.OpenUrl("http://google.com");
var doc = page.Document;
var layout = doc.CreateLayout();
var element = engine.Document.GetElementById("hplogo");
var boundingBox = element.GetBoundingClientRect();
I tried using Knyaz.Optimus.Graphics rendering engine and it gives the following error after "GetBoundingClientRect"
at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
at System.Linq.Enumerable.Where[TSource](IEnumerable`1 source, Func`2 predicate)
at Knyaz.Optimus.Graphics.DocumentLayout.Knyaz.Optimus.ILayoutService.GetElementBounds(Element elt)
at Knyaz.Optimus.Dom.Elements.Element.GetBoundingClientRect()
Do u recommend any other rendering engine that works well with ILayoutService?
My bad. Layout process must be done before. You have to call Refresh method to preform html document layout within a given window size, Update your code:
doc.CreateLayout().Refresh(new Size(1000,1000));
My library is no so popular. So, there is only one rendering engine. And this engine doesn't do a lot. Therefore, be prepared for the fact that the result will be different from what is expected, or even be empty rectangle.
Great this works :)
Is there a way to save the layout as picture to get an idea of how it rendered the html?
Yes, there is.
var bitmap = engine.ToImage(1000, 1000);//Window's size
bitmap.Save("goo.bpm", ImageFormat.Bmp);
Can you please give an example for getting the co-ordinates of html elements?