[M3devel] pixmap problem (some success)
Jay
jayk123 at hotmail.com
Fri Aug 8 02:16:49 CEST 2008
Awesome. I expect it is easy from here. Thanks David!
I *assume* the 75 should have been 86 in the one case,
but close enough that nobody noticed.
So these numbers come pretty directly from the GetDeviceCaps / GetSystemMetrics.
And then X Windows too.
Does anyone have a high DPI monitor running X Windows?
Probably easy enough to do this blind.
I'm trying to ignore the fact that systems have multiple
monitors, with varying dpi. You are supposed to loop your
drawing over monitors and compute what it looks like per-monitor.
I'm just making that up, right? :)
- Jay
________________________________
Date: Thu, 7 Aug 2008 19:42:33 -0400
From: rcoleburn at scires.com
To: m3devel at elegosoft.com; jayk123 at hotmail.com; dabenavidesd at yahoo.es
Subject: Re: [M3devel] pixmap problem (some success)
Ok, I solved the Microsoft problem.
Here are the results on Dell M4300 at 1920x1200:
horizonal pixels 1920
veritical pixels SM_CYSCREEN 1200
horizontal millimeters 330
veritical millimeters 206
horizontal pixels per millimeter 5.818182
vertical pixels per millimeter 5.825243
horizontal pixels per inch 147.781818
vertical pixels per inch 147.961165
Wow! these numbers are radically different than the IBM T60 at 1280x1024:
horizonal pixels 1280
veritical pixels SM_CYSCREEN 1024
horizontal millimeters 375
veritical millimeters 300
horizontal pixels per millimeter 3.413333
vertical pixels per millimeter 3.413333
horizontal pixels per inch 86.698667
vertical pixels per inch 86.698667
Now, if you look at the Windows dpi setting for the 1920x1200 machine, it says 96dpi, but this is in the General tab of the Display properties Advanced settings. I suspect this is just the dpi setting applied to fonts.
I tried plugging the numbers into Image.i3 as suggested by Daniel:
TYPE
Raw = OBJECT
width, height: INTEGER;
xres: REAL := 147.781818; (* in pixels per inch *)
yres: REAL := 147.961165; (* in pixels per inch *)
METHODS
get (h, v: INTEGER): Pixel;
set (h, v: INTEGER; pixel: Pixel);
END;
When I do this, my pixmaps look correct on the 1920x1200 display!!!!!
Now, the problem I am faced with is how to come up with a way that the code will work on any type of monitor. I can't edit Image.i3 for every resolution and produce a different binary. Any ideas?
Regards,
Randy
>>> Jay 8/5/2008 9:01 AM>>>
Randy, I'm pretty clueless here.
I don't do gui or graphics.
If anyone has a clue, please stand up.
If you can get us code to run, please do.
But I think I need multiple particularly configured machines too.
I'm curious what this code prints on the systems:
#include
#include
int main()
{
int pix_ver = { 0 };
int pix_hor = { 0 };
int mm_hor = { 0 };
int mm_ver = { 0 };
HWND hwnd = { 0 };
HDC hdc = { 0 };
hwnd = GetDesktopWindow();
hdc = GetDC(hwnd);
mm_hor = GetDeviceCaps(hdc, HORZSIZE);
mm_ver = GetDeviceCaps(hdc, VERTSIZE);
pix_hor = GetSystemMetrics(SM_CXSCREEN);
pix_ver = GetSystemMetrics(SM_CYSCREEN);
printf("horizonal pixels %d\n", pix_hor);
printf("veritical pixels SM_CYSCREEN %d\n", pix_ver);
printf("horizontal millimeters %d\n", mm_hor);
printf("veritical millimeters %d\n", mm_ver);
printf("horizontal pixels per millimeter %f\n", (((float) pix_hor) / ((float) mm_hor)));
printf("vertical pixels per millimeter %f\n", (((float) pix_ver) / ((float) mm_ver)));
printf("horizontal pixels per inch %f\n", (((float) pix_hor) / ((float) mm_hor) * 10.0 * 2.54));
printf("vertical pixels per inch %f\n", (((float) pix_ver) / ((float) mm_ver) * 10.0 * 2.54));
return 0;
}
for me:
$ gcc dpi.c -luser32 -lgdi32
jay at jay-win9 /dev2/j/dpi
$ ./a
horizonal pixels 1280
veritical pixels SM_CYSCREEN 800
horizontal millimeters 384
veritical millimeters 240
horizontal pixels per millimeter 3.333333
vertical pixels per millimeter 3.333333
horizontal pixels per inch 84.666667
vertical pixels per inch 84.666667
(Visual C++ is fine:
cl dpi.c user32.lib gdi32.lib
.\dpi
)
I wonder if lying in this code:
Searching for 'GetDeviceCaps'...
D:\dev2\cm3.2\m3-ui\ui\src\winvbt\WinScreenType.m3(25): VAR res := NEW(T); n_colors := GetDeviceCaps (WinGDI.NUMCOLORS);
D:\dev2\cm3.2\m3-ui\ui\src\winvbt\WinScreenType.m3(32): res.depth := GetDeviceCaps(WinGDI.BITSPIXEL); (* John Karnak 8/3/98 *)
D:\dev2\cm3.2\m3-ui\ui\src\winvbt\WinScreenType.m3(68): mm_hor = GetDeviceCaps (WinGDI.HORZSIZE),
D:\dev2\cm3.2\m3-ui\ui\src\winvbt\WinScreenType.m3(69): mm_ver = GetDeviceCaps (WinGDI.VERTSIZE) DO
Searching for 'res.res[Axis.T.'...
D:\dev2\cm3.2\m3-ui\ui\src\winvbt\WinScreenType.m3(71): res.res[Axis.T.Hor] := FLOAT(pix_hor) / FLOAT(mm_hor);
D:\dev2\cm3.2\m3-ui\ui\src\winvbt\WinScreenType.m3(72): res.res[Axis.T.Ver] := FLOAT(pix_ver) / FLOAT(mm_ver);
D:\dev2\cm3.2\m3-ui\ui\src\winvbt\WinScreenType.m3(89):PROCEDURE GetDeviceCaps (cap: Ctypes.int): INTEGER =
D:\dev2\cm3.2\m3-ui\ui\src\winvbt\WinScreenType.m3(93): res := WinGDI.GetDeviceCaps (hdc, cap);
D:\dev2\cm3.2\m3-ui\ui\src\winvbt\WinScreenType.m3(98): END GetDeviceCaps;
D:\dev2\cm3.2\m3-ui\ui\src\winvbt\WinScrnColorMap.m3(268): cnt := WinGDI.GetDeviceCaps (hdc, WinGDI.NUMCOLORS);
D:\dev2\cm3.2\m3-ui\ui\src\winvbt\WinScrnFont.m3(316): LogicalPixelsPerVertInch := WinGDI.GetDeviceCaps(er.hdc, WinGDI.LOGPIXELSY);
9 occurrence(s) have been found.
Searching for '1000.0'...
D:\dev2\cm3.2\m3-ui\ui\src\winvbt\WinScrnPixmap.m3(463): bmih.biXPelsPerMeter := ROUND (st.res[Axis.T.Hor] * 1000.0);
D:\dev2\cm3.2\m3-ui\ui\src\winvbt\WinScrnPixmap.m3(464): bmih.biYPelsPerMeter := ROUND (st.res[Axis.T.Ver] * 1000.0);
and just claiming 96dpi is the way to go.
Can you try that??
Specifically try setting res.res[Axis.T.Hor] and .Ver to 3.779527559055118.
Or heck to 3.3333 like my laptop has.
Or maybe claiming ignorance and setting biXPelsPerMeter and biYPelsPerMeter to 0???
Claiming ignorance feels better than lying of course. :)
Hm, so throw in also:
printf("LogicalPixelsX %u\n", GetDeviceCaps(hdc, LOGPIXELSX));
printf("LogicalPixelsY %u\n", GetDeviceCaps(hdc, LOGPIXELSY));
I get the magic number 96.
- Jay
More information about the M3devel
mailing list