From c3e26ea307248b5ed0b8638098a17b2abfd94f2e Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 14 Sep 2019 22:41:13 -0700 Subject: [PATCH] =?UTF-8?q?Scale=20images,=20when=20needed,=20before=20gen?= =?UTF-8?q?erating=20inline=20HTML=20data=20in=20ArticleRenderer=20?= =?UTF-8?q?=E2=80=94=C2=A0this=20keeps=20us=20from=20getting=20huge=20amou?= =?UTF-8?q?nts=20of=20data,=20which=20slows=20down=20rendering.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Article Rendering/ArticleRenderer.swift | 49 +++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/Shared/Article Rendering/ArticleRenderer.swift b/Shared/Article Rendering/ArticleRenderer.swift index 833228120..d66aac5a2 100644 --- a/Shared/Article Rendering/ArticleRenderer.swift +++ b/Shared/Article Rendering/ArticleRenderer.swift @@ -159,6 +159,48 @@ private extension ArticleRenderer { return permalink != preferredLink // Make date a link if it’s a different link from the title’s link } + static let avatarDimension = 48 + static let doubledDimension = CGFloat(avatarDimension * 2) + + static func imageScaledForDisplay(image: RSImage) -> RSImage { + // Aspect fit. + #if os(macOS) + + if image.size.height <= doubledDimension && image.size.width <= doubledDimension { + return image + } + + let scaledImage = NSImage.init(size: NSSize(width: doubledDimension, height: doubledDimension)) + scaledImage.lockFocus() + + var imageRectWidth = doubledDimension + var imageRectHeight = doubledDimension + var imageRectOriginX = CGFloat(0.0) + var imageRectOriginY = CGFloat(0.0) + + if image.size.width > image.size.height { + let factor: CGFloat = doubledDimension / image.size.width + imageRectHeight = image.size.height * factor + imageRectOriginY = (doubledDimension - imageRectHeight) / 2.0 + } + else if image.size.height > image.size.width { + let factor: CGFloat = doubledDimension / image.size.height + imageRectWidth = image.size.width * factor + imageRectOriginX = (doubledDimension - imageRectWidth) / 2.0 + } + + image.draw(in: NSRect(x: imageRectOriginX, y: imageRectOriginY, width: imageRectWidth, height: imageRectHeight)) + scaledImage.unlockFocus() + return scaledImage + + #else //iOS + + // TODO: https://github.com/brentsimmons/NetNewsWire/issues/1021 + + return image + #endif + } + func faviconImgTag(forFeed feed: Feed) -> String? { if let cachedImgTag = ArticleRenderer.faviconImgTagCache[feed] { @@ -166,7 +208,8 @@ private extension ArticleRenderer { } if let favicon = appDelegate.faviconDownloader.favicon(for: feed) { - if let s = base64String(forImage: favicon) { + let scaledImage = ArticleRenderer.imageScaledForDisplay(image: favicon) + if let s = base64String(forImage: scaledImage) { var dimension = min(favicon.size.height, CGFloat(ArticleRenderer.avatarDimension)) // Assuming square images. dimension = max(dimension, 16) // Some favicons say they’re < 16. Force them larger. if dimension >= CGFloat(ArticleRenderer.avatarDimension) * 0.8 { //Close enough to scale up. @@ -195,7 +238,8 @@ private extension ArticleRenderer { } if let icon = appDelegate.feedIconDownloader.icon(for: feed) { - if let s = base64String(forImage: icon) { + let scaledImage = ArticleRenderer.imageScaledForDisplay(image: icon) + if let s = base64String(forImage: scaledImage) { #if os(macOS) let imgTag = "" #else @@ -228,7 +272,6 @@ private extension ArticleRenderer { return nil } - static let avatarDimension = 48 struct Avatar { let imageURL: String