We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3440 - [ios] [patch] support (hard-coded) display DPI reading
Summary: [ios] [patch] support (hard-coded) display DPI reading
Status: RESOLVED ABANDONED
Alias: None
Product: SDL
Classification: Unclassified
Component: video (show other bugs)
Version: HG 2.1
Hardware: iPhone/iPod touch iOS 6
: P2 normal
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-10-02 14:32 UTC by Daniel Sobe
Modified: 2018-08-06 21:20 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Sobe 2016-10-02 14:32:54 UTC
The following patch tries to guess the display DPI from the ios version string. Not a nice solution but maybe better than nothing.

The "ddpi" value is filled with the scale factor. This is in some way necessary to be returned separately to the user, because a high DPI display might or might not have been requested. The DPI value needs to be adjusted appropriately then.


--- SDL_snapshot/src/video/uikit/SDL_uikitmodes.h	2016-10-02 09:27:31.000000000 +0200
+++ SDL_patches/src/video/uikit/SDL_uikitmodes.h	2016-10-02 12:22:23.998787293 +0200
@@ -44,6 +44,7 @@
 extern int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
 extern void UIKit_QuitModes(_THIS);
 extern int UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
+extern int UIKit_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi);
 
 #endif /* _SDL_uikitmodes_h */
 
diff -aur SDL_snapshot/src/video/uikit/SDL_uikitmodes.m SDL_patches/src/video/uikit/SDL_uikitmodes.m
--- SDL_snapshot/src/video/uikit/SDL_uikitmodes.m	2016-10-02 09:27:31.000000000 +0200
+++ SDL_patches/src/video/uikit/SDL_uikitmodes.m	2016-10-02 12:24:58.951840088 +0200
@@ -25,6 +25,8 @@
 #include "SDL_assert.h"
 #include "SDL_uikitmodes.h"
 
+#include <sys/utsname.h>
+
 @implementation SDL_DisplayData
 
 @synthesize uiscreen;
@@ -308,6 +310,92 @@
     }
 }
 
+NSString *machineName()
+{
+    struct utsname systemInfo;
+    if (uname(&systemInfo) < 0) {
+        return nil;
+    } else {
+        return [NSString stringWithCString:systemInfo.machine
+                              encoding:NSUTF8StringEncoding];
+    }
+}
+
+// detects iPad mini by machine id
+BOOL isIpadMini()
+{
+
+    NSString *machName = machineName();
+    if (machName == nil) return NO;
+
+    BOOL isMini = NO;
+    if (    [machName isEqualToString:@"iPad2,5"]
+         || [machName isEqualToString:@"iPad2,6"]
+         || [machName isEqualToString:@"iPad2,7"]
+         || [machName isEqualToString:@"iPad4,4"]
+         || [machName isEqualToString:@"iPad4,5"]
+         || [machName isEqualToString:@"iPad4,6"]
+         || [machName isEqualToString:@"iPad4,7"]
+         || [machName isEqualToString:@"iPad4,8"]
+         || [machName isEqualToString:@"iPad4,9"]
+         || [machName isEqualToString:@"iPad5,1"]
+         || [machName isEqualToString:@"iPad5,2"])
+    {
+        isMini = YES;
+    }
+    return isMini;
+}
+
+// detects iPhone 6 plus and iPhone 6s plus
+BOOL isIPhone6Plus()
+{
+
+    NSString *machName = machineName();
+    if (machName == nil) return NO;
+
+    BOOL isIPhone6Plus = NO;
+    if (    [machName isEqualToString:@"iPhone7,1"]
+         || [machName isEqualToString:@"iPhone8,2"])
+    {
+        isIPhone6Plus = YES;
+    }
+    return isIPhone6Plus;
+}
+
+int 
+UIKit_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi)
+{
+	float scale = 1;
+	if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
+		scale = [[UIScreen mainScreen] scale];
+	}
+	
+	float dpi;
+	if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+		dpi = 132;
+	} else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
+		dpi = 163;
+	} else {
+		dpi = 160;
+	}
+	
+	if (isIpadMini() == YES)
+	{
+		dpi = 163;
+	}
+	
+	if (isIPhone6Plus() == YES)
+	{
+		dpi = 133;
+	}
+	
+	*ddpi = scale;
+	*hdpi = dpi;
+	*vdpi = dpi;
+	
+	return 0;
+}
+
 #endif /* SDL_VIDEO_DRIVER_UIKIT */
 
 /* vi: set ts=4 sw=4 expandtab: */
diff -aur SDL_snapshot/src/video/uikit/SDL_uikitvideo.m SDL_patches/src/video/uikit/SDL_uikitvideo.m
--- SDL_snapshot/src/video/uikit/SDL_uikitvideo.m	2016-10-02 09:27:31.000000000 +0200
+++ SDL_patches/src/video/uikit/SDL_uikitvideo.m	2016-10-02 12:29:07.357533425 +0200
@@ -87,6 +87,7 @@
         device->VideoInit = UIKit_VideoInit;
         device->VideoQuit = UIKit_VideoQuit;
         device->GetDisplayModes = UIKit_GetDisplayModes;
+        device->GetDisplayDPI = UIKit_GetDisplayDPI;
         device->SetDisplayMode = UIKit_SetDisplayMode;
         device->PumpEvents = UIKit_PumpEvents;
         device->SuspendScreenSaver = UIKit_SuspendScreenSaver;
Comment 1 Alex Szpakowski 2016-10-02 14:44:07 UTC
I won't be merging this personally. It will break with any new device, and using physical DPI is generally an inferior solution to using the pixel density scale factor (SDL_WINDOW_ALLOW_HIGHDPI, plus SDL_GL_GetDrawableSize / SDL_GetWindowSize or SDL_GetRendererOutputSize / SDL_GetWindowSize).

The iOS demo code has recently been updated to use the above techniques.
Comment 2 Daniel Sobe 2016-10-02 19:09:13 UTC
Hmm, what about returning the known hard-coded values for existing devices, and an error if the device is not in the database?

Is the GetDisplayDPI() function meant to return physical DPI? If not, can it be somehow "delegated" to returning the result of the computation you suggest?
Comment 3 Alex Szpakowski 2016-10-02 19:10:37 UTC
(In reply to Daniel Sobe from comment #2)
> Is the GetDisplayDPI() function meant to return physical DPI? If not, can it
> be somehow "delegated" to returning the result of the computation you
> suggest?

It is, but that's not as useful as people often think, the pixel density scale is what literally every app on iOS uses instead – it's much more useful (and already exposed by SDL).
Comment 4 Daniel Sobe 2016-10-02 19:28:40 UTC
I am so far considering it to be useful information. If I want to understand how big the area in pixels covered by a finger of, say, diameter 10mm, is - then this is only possible with physical DPI. 

I agree that maintaining a list of hard-coded values is not the best solution. But the current situation to simply not support it at all, is also not so nice.
Comment 5 Alex Szpakowski 2017-09-01 03:00:27 UTC
(In reply to Daniel Sobe from comment #4)
> I am so far considering it to be useful information. If I want to understand
> how big the area in pixels covered by a finger of, say, diameter 10mm, is -
> then this is only possible with physical DPI. 

iOS provides dedicated APIs for querying the estimated radius (in DPI-scaled points) of a touch press. Despite the fact that it's an estimate, it would still be more accurate than hard-coding a diameter in millimeters into your app.

I think the estimated radius probably a useful property to expose as a SDL_touch API, and a lot more acceptable than a hard-coded DPI list.
Comment 6 Daniel Sobe 2017-09-01 08:11:05 UTC
This is indeed sth worth exploring, not just for iOS but also other touch platforms. Thanks for pointing this out - I did not know such a property existed at all!

(I'm still not dropping my idea of supporting the GetDisplayDPI() in one way or another though.)
Comment 7 Ryan C. Gordon 2018-08-06 21:20:18 UTC
Hello, and sorry if you're getting dozens of copies of this message by email.

We are closing out bugs that appear to be abandoned in some form. This can happen for lots of reasons: we couldn't reproduce it, conversation faded out, the bug was noted as fixed in a comment but we forgot to mark it resolved, the report is good but the fix is impractical, we fixed it a long time ago without realizing there was an associated report, etc.

Individually, any of these bugs might have a better resolution (such as WONTFIX or WORKSFORME or INVALID) but we've added a new resolution of ABANDONED to make this easily searchable and make it clear that it's not necessarily unreasonable to revive a given bug report.

So if this bug is still a going concern and you feel it should still be open: please feel free to reopen it! But unless you respond, we'd like to consider these bugs closed, as many of them are several years old and overwhelming our ability to prioritize recent issues.

(please note that hundred of bug reports were sorted through here, so we apologize for any human error. Just reopen the bug in that case!)

Thanks,
--ryan.