diff --git a/Core/Notification/Screenshot/FormNotificationScreenshotable.cs b/Core/Notification/Screenshot/FormNotificationScreenshotable.cs index a0520678..b0c5dc72 100644 --- a/Core/Notification/Screenshot/FormNotificationScreenshotable.cs +++ b/Core/Notification/Screenshot/FormNotificationScreenshotable.cs @@ -15,11 +15,10 @@ sealed class FormNotificationScreenshotable : FormNotificationBase{ protected override bool CanDragWindow => false; private readonly PluginManager plugins; - private readonly int width; + private int height; public FormNotificationScreenshotable(Action callback, FormBrowser owner, PluginManager pluginManager, string html, int width) : base(owner, false){ this.plugins = pluginManager; - this.width = width; browser.RegisterAsyncJsObject("$TD_NotificationScreenshot", new ScreenshotBridge(this, SetScreenshotHeight, callback)); @@ -36,11 +35,11 @@ public FormNotificationScreenshotable(Action callback, FormBrowser owner, Plugin } using(IFrame frame = args.Browser.MainFrame){ - ScriptLoader.ExecuteScript(frame, script.Replace("{width}", ClientSize.Width.ToString()), "screenshot"); + ScriptLoader.ExecuteScript(frame, script.Replace("{width}", BrowserUtils.Scale(width, DpiScale).ToString()), "screenshot"); } }; - SetScreenshotHeight(1); + SetNotificationSize(width, 1024); LoadTweet(new TweetNotification(string.Empty, string.Empty, string.Empty, html, 0, string.Empty, string.Empty)); } @@ -54,14 +53,20 @@ protected override string GetTweetHTML(TweetNotification tweet){ return html; } - private void SetScreenshotHeight(int height){ - SetNotificationSize(width, height); + private void SetScreenshotHeight(int browserHeight){ + this.height = BrowserUtils.Scale(browserHeight, SizeScale); } - public bool TakeScreenshot(){ - if (ClientSize.Height == 0){ - FormMessage.Error("Screenshot Failed", "Could not detect screenshot size.", FormMessage.OK); - return false; + public bool TakeScreenshot(bool ignoreHeightError = false){ + if (!ignoreHeightError){ + if (height == 0){ + FormMessage.Error("Screenshot Failed", "Could not detect screenshot size.", FormMessage.OK); + return false; + } + else if (height > ClientSize.Height){ + FormMessage.Error("Screenshot Failed", $"Screenshot is too large: {height}px > {ClientSize.Height}px", FormMessage.OK); + return false; + } } IntPtr context = NativeMethods.GetDC(this.Handle); @@ -71,7 +76,7 @@ public bool TakeScreenshot(){ return false; } else{ - using(Bitmap bmp = new Bitmap(ClientSize.Width, ClientSize.Height, PixelFormat.Format32bppRgb)){ + using(Bitmap bmp = new Bitmap(ClientSize.Width, Math.Max(1, height), PixelFormat.Format32bppRgb)){ try{ NativeMethods.RenderSourceIntoBitmap(context, bmp); }finally{ diff --git a/Core/Notification/Screenshot/TweetScreenshotManager.cs b/Core/Notification/Screenshot/TweetScreenshotManager.cs index f2a072bd..8a1d48c4 100644 --- a/Core/Notification/Screenshot/TweetScreenshotManager.cs +++ b/Core/Notification/Screenshot/TweetScreenshotManager.cs @@ -3,7 +3,7 @@ // #define NO_HIDE_SCREENSHOTS // Uncomment to generate screenshots of individual frames for at most 1 second -#define GEN_SCREENSHOT_FRAMES +// #define GEN_SCREENSHOT_FRAMES #endif using System; @@ -128,7 +128,7 @@ private void StartDebugger(){ } private void debugger_Tick(object sender, EventArgs e){ - if (frameCounter < 63 && screenshot.TakeScreenshot()){ + if (frameCounter < 63 && screenshot.TakeScreenshot(true)){ try{ Clipboard.GetImage()?.Save(Path.Combine(DebugScreenshotPath, "frame_"+(++frameCounter)+".png"), ImageFormat.Png); }catch{ diff --git a/Resources/Scripts/screenshot.js b/Resources/Scripts/screenshot.js index 5db14eb7..e9fc0e54 100644 --- a/Resources/Scripts/screenshot.js +++ b/Resources/Scripts/screenshot.js @@ -10,6 +10,17 @@ let avatarBottom = avatar ? avatar.getBoundingClientRect().bottom : 0; $TD.setHeight(Math.floor(Math.max(contentHeight, avatarBottom+9))).then(() => { - setTimeout($TD.triggerScreenshot, document.getElementsByTagName("iframe").length ? 267 : 67); + let framesLeft = 5; // basic render is done in 1 frame, large media take longer + + let onNextFrame = function(){ + if (--framesLeft < 0){ + $TD.triggerScreenshot(); + } + else{ + requestAnimationFrame(onNextFrame); + } + }; + + onNextFrame(); }); })($TD_NotificationScreenshot);