Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I would love to use this from WinForms/GDI+ #2

Open
tig opened this issue Dec 18, 2019 · 6 comments
Open

I would love to use this from WinForms/GDI+ #2

tig opened this issue Dec 18, 2019 · 6 comments

Comments

@tig
Copy link

tig commented Dec 18, 2019

I've got it building and running via VS2019 and the WPF sample. It does not look hard to port the WPF sample to WinForms/GDI+, but if someone's already done it, that'd be trick.

If not, any advice on how to proceed that might save me some time.

@tig tig changed the title I would love to use this from WinForms... I would love to use this from WinForms/GDI+ Dec 25, 2019
@tig
Copy link
Author

tig commented Dec 25, 2019

Ok, I've got GDI+ mostly working. I'll be issuing a PR once I get it fully working.

For now, the biggest problem I have is how SetViewport is supposed to work. In my app (a printing app that can print HTML) I need litehtml to render each part of the html that is just the size of a printed page. SetViewPort works brilliantly for this.

 int yPos = (pageNum - 1) * (int)Math.Round(PageSize.Height);
 litehtml.SetViewport(new LiteHtmlPoint(0, yPos), new LiteHtmlSize(Math.Round(PageSize.Width), Math.Round(PageSize.Height)));

Here's the problem: When I do this and yPos is 0, the page background, drawn by DrawBackground which is naively implemented as:

Rectangle rect = new Rectangle(pos.x, pos.y, pos.width, pos.height);
_graphics.FillRectangle(color.GetBrush(), rect);

...gets callled with 0, 0, width, FULL HEIGHT OF HTML DOC. IOW, pos.height is the full height of the doc, vs just what I set the viewport to.

Then, when I'm printing page 2, yPos is pageheight * pagenum). Again, this works great. However, once I had a non-white background, I noticed that Drawis really drawing at-0, -yPos` and the background is being drawn way off the top of the page while the text is drawn where expected.

See image.

ViewportContainer.Draw, oddly, makes the ScrollOffset negative like this:

      Document.Draw((int)-ScrollOffset.X, (int)-ScrollOffset.Y, new position
        {
            x = 0,
            y = 0,
            width = (int)Size.Width,
            height = (int)Size.Height
        });

This is what I can't figure out.

Why is ScrollOffset negative? Why does the background draw incorrectly, yet the text draw where I expect it?

image

@zone117x
Copy link
Member

I recall some difficulty in getting ViewPort to render correctly on Mac and WPF.

My suspicion is that your implementation may not be setting the DocumentSizeKnown delegate properly. Example:

LiteHtmlView.LiteHtmlContainer.DocumentSizeKnown += LiteHtmlView_DocumentSizeKnown;

void LiteHtmlView_DocumentSizeKnown(LiteHtmlSize size)
{
LiteHtmlView.SetFrameSize(new CGSize(scrollView.ContentView.Bounds.Width, size.Height));
LiteHtmlView.SetViewport(new CGRect(scrollView.ContentView.Bounds.Location, scrollView.ContentView.Frame.Size));
}

Why is ScrollOffset negative?

IIRC the C++ litehtml API expects the the scroll offset to be negative, while most GUI framework scrollviews use positive numbers -- so the C# layer performs a coord invert to make implementations easier.

If you open a draft PR then I may be able to help debug.

@tig
Copy link
Author

tig commented Dec 26, 2019

I'll try to get a draft PR going. My app is pretty besopke and I never built a Example.WinForms, which I should have. Knowing litehtm uses negative numbers for the scroll offset for sure helps (I actually noted the litebrowser code shows this as well) helped my understanding.

I'll keep you posted. This framework has put me on a path with this app that I really think will work well and I'm pretty excited. I had tried using CEF/Chromium and spent weeks struggling to trick it into rendering where I wanted it. With litehmtl and litehtmlsharp i'm this close!

I'm not sure DocumentSizeKnown has anything to do with it, in my case. The code that raises it is:

public void Render()
{
Document.Render((int)Size.Width);
DocumentSizeKnown?.Invoke(new LiteHtmlSize(Document.Width(), Document.Height()));
}

Document.Render returns 'best width':

public int Render(int maxWidth)
{
HasRendered = true;
return Calls.Render(Calls.ID, maxWidth);
}

I'm doing this:

int width = (int)PageSize.Width;
int height = (int)PageSize.Height;
Debug.WriteLine($"HtmlFileContent.CountPages - Page size: {width}x{height} @ {printerResolution.X}x{printerResolution.Y} dpi");

int bestWidth = litehtml.Document.Render((int)width);
Debug.WriteLine($"Litehtml_DocumentSizeKnown {litehtml.Document.Width()}x{litehtml.Document.Height()} bestWidth = {bestWidth}");

Which gets me Document.Width()/Height() just as it would if I used the delegate.

I've confirmed that litehmtl's DrawBackground doesn't care about ScrollOffset. I think this actually makes sense given how the background in html can be set to not scroll. It just means I need to set my clip region.

@zone117x
Copy link
Member

This framework has put me on a path with this app that I really think will work well and I'm pretty excited

Thats great!

I think this actually makes sense given how the background in html can be set to not scroll. It just means I need to set my clip region.

This sounds reasonable. I think I recall litehtml giving rendering instructions that extend past the visible content area.

@tig
Copy link
Author

tig commented Jan 20, 2020

FWIW, I'm pretty close to having this work as well as it's going to on Windows. I'm now working to get the app running under Linux as well. I can't get litehtml or 'LiteHtmlSharp` to build.

I found that libgdiplus (under System.Drawing on Linux) has tons of shorcomings. It will be interesting to see what happens...

@tig
Copy link
Author

tig commented Feb 18, 2020

The app that uses this is now available as an 'alpha'. In case you're curious...

https://github.com/tig/winprint

I have a nasty bug in my GDI+ Document Container in whitepace and empty tag sizing tho. See tig/winprint#14

I'm sure I'm doing something stupid.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants