/// <summary> /// Find based on the fitting pixel size /// </summary> IconFrame FindBySize(float scale, Size fittingSize) { // adjust fitting size to scale to get pixel size desired fittingSize = Size.Ceiling((SizeF)fittingSize * scale); var fs = fittingSize.Width * fittingSize.Height; var frame = Frames .Select(r => Tuple.Create(r.PixelSize.Width * r.PixelSize.Height, r)) .OrderBy(r => r.Item1) .FirstOrDefault(r => r.Item1 >= fs)?.Item2; return(frame ?? Frames.OrderBy(r => r.PixelSize.Width * r.PixelSize.Height).Last()); }
/// <summary> /// find based on scale alone, we don't know the final render size /// </summary> IconFrame FindByScale(float scale) { IconFrame selected = null; float scaleDiff = 0; float lastScale = 0; foreach (var frame in Frames.OrderBy(r => r.Scale).ThenByDescending(r => r.Size.Width * r.Size.Height)) { var ps = Size.Ceiling((SizeF)Size * scale); var pixelSizeNeeded = ps.Width * ps.Height; var diff = scale - frame.Scale; if (selected == null || (diff < scaleDiff && (diff >= 0 || scaleDiff > 0))) { // found where scale is the next greater or equal to desired scale scaleDiff = diff; lastScale = frame.Scale; selected = frame; } else if (lastScale == frame.Scale) { // multiple resolutions with the same scale, use the one with the best pixel size // (e.g. ico file with multiple resolutions) ps = frame.PixelSize; if (ps.Width * ps.Height >= pixelSizeNeeded) { selected = frame; scaleDiff = diff; lastScale = frame.Scale; } else { break; } } else { break; } } if (selected == null) { // get largest selected = Frames.OrderBy(r => r.PixelSize.Width * r.PixelSize.Height).Last(); } return(selected); }