News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

GetDeviceCaps() with ASPECTX and ASPECTY

Started by Rockoon, December 08, 2007, 04:18:55 AM

Previous topic - Next topic

Rockoon


Does anyone know what units these values are in?

On my system, giving GetDeviceCaps a Device Context of my primary display (1280x1024 native) I get:

HORZSIZE = 337mm
VERTSIZE = 270mm
HORZRES = 1280px
VERTRES = 1024px

The size values are for sure in millimeters and are more or less correct (perhaps a few millimeters off...)

I also get:

ASPECTX = 36
ASPECTY = 36

I just can't seem to figure out what these units are in and my google karma is apparently lacking.

I dont mind relying on ASPECTX and ASPECTY but I would feel a lot more comfortable if I knew what units they were in.

The physical size of the pixels as I calculate them are:

337 / 1280 = 0.26328125mm
270 / 1024 = 0.26367188mm

and their reciprocals:

1280 / 337 = 3.79821958
1024 / 270 = 3.7925925


..any ideas?
When C++ compilers can be coerced to emit rcl and rcr, I *might* consider using one.

MichaelW

I get 36 for both for my CRT at 1024x768 (4:3) and 1280x1024 (5:4). From the little information returned by my searches, I suspect the value is the pixel aspect ratio (never mind how little sense that might make, given the way pixels are created on a color display), perhaps as a dimensionless number. Assuming you are using a flat panel display, what do you get at a non-native resolution?
eschew obfuscation

Rockoon

Quote from: MichaelW on December 08, 2007, 05:29:58 AM
I get 36 for both for my CRT at 1024x768 (4:3) and 1280x1024 (5:4). From the little information returned by my searches, I suspect the value is the pixel aspect ratio (never mind how little sense that might make, given the way pixels are created on a color display), perhaps as a dimensionless number. Assuming you are using a flat panel display, what do you get at a non-native resolution?

I was acting under the presumption that the ratio of these values was indeed the pixel aspect ratio..

..but by your suggestion, I tried a different graphics mode (1024x768) and again the same 36/36 falls out.

Interrestingly, in 1024x768 the HORZSIZE and VERTSIZE caps return different, incorrect, results. This is all contrary to my expectations. I expected HORZSIZE and VERTSIZE to remain constant over multiple video modes, reflecting the actual physical measurements of the display. They seem to only be accurate for my native LCD video mode and now I'm wondering if that was just by chance (seems unlikely since 5:4 displays like mine arent as common as the 4:3 displays)

sigh... I really wanted to be able to detect when pixels were square and now I'm wondering if thats even possible

When C++ compilers can be coerced to emit rcl and rcr, I *might* consider using one.

MichaelW

#3
I was hoping this would show something useful, but on my Sony CRT the aperture grille effects make it impossible to gauge (under 10x magnification) the aspect ratio of the pixels. Perhaps it will work better on other displays, or with some other pixel pattern.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
drawline MACRO hdc,x1,y1,x2,y2
  invoke CreatePen, PS_SOLID, 0, 0
  invoke SelectObject, hdc, eax
  push eax
  invoke MoveToEx, hdc, x1, y1, NULL
  invoke LineTo, hdc, x2, y2
  pop eax
  invoke SelectObject, hdc, eax
  invoke DeleteObject, eax
ENDM
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
    hWnd  dd          0
    hInst dd          0
    _x    dd          0
    _y    dd          0
    wcx   WNDCLASSEX  <>
    wMsg  MSG         <>
    szDisplayName     db "Test",0
    szClassName       db "test_class",0
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
WindowProc proc uses ebx hwnd:DWORD, uMsg:DWORD,
                         wParam:DWORD, lParam:DWORD
    LOCAL ps :PAINTSTRUCT
    SWITCH uMsg
      CASE WM_PAINT
        invoke BeginPaint, hwnd, ADDR ps
        xor ebx, ebx
        .WHILE ebx < ps.rcPaint.bottom
          drawline ps.hdc, 0, ebx, ps.rcPaint.right, ebx
          add ebx, 3
        .ENDW
        xor ebx, ebx
        .WHILE ebx < ps.rcPaint.right
          drawline ps.hdc, ebx, 0, ebx, ps.rcPaint.bottom
          add ebx, 3
        .ENDW
        invoke EndPaint, hwnd, ADDR ps
      CASE WM_CLOSE
        invoke DestroyWindow, hwnd
      CASE WM_DESTROY
        invoke PostQuitMessage, NULL
      DEFAULT
        invoke DefWindowProc, hwnd, uMsg, wParam, lParam
        ret
    ENDSW
    return 0
WindowProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    invoke GetModuleHandle, NULL
    mov hInst, eax
    mov wcx.cbSize, SIZEOF WNDCLASSEX
    mov wcx.style, CS_HREDRAW or CS_VREDRAW
    mov wcx.lpfnWndProc, OFFSET WindowProc
    mov wcx.cbClsExtra, NULL
    mov wcx.cbWndExtra, NULL
    push hInst
    pop wcx.hInstance
    invoke LoadIcon, NULL, IDI_APPLICATION
    mov wcx.hIcon, eax
    invoke LoadCursor, NULL, IDC_ARROW
    mov wcx.hCursor, eax
    mov wcx.hbrBackground, COLOR_HIGHLIGHTTEXT+1
    mov wcx.lpszMenuName, NULL
    mov wcx.lpszClassName, OFFSET szClassName
    mov wcx.hIconSm, 0
    invoke RegisterClassEx, ADDR wcx
    W = 400
    H = 300
    invoke GetSystemMetrics, SM_CXSCREEN
    shr eax, 1
    sub eax, W / 2
    mov _x, eax
    invoke GetSystemMetrics, SM_CYSCREEN
    shr eax, 1
    sub eax, H / 2
    mov _y, eax
    invoke CreateWindowEx, NULL,
                           ADDR szClassName,
                           ADDR szDisplayName,
                           WS_OVERLAPPED or WS_SYSMENU,
                           _x, _y, W, H,
                           NULL, NULL,
                           hInst, NULL
    mov hWnd, eax
    invoke ShowWindow, hWnd, SW_SHOWNORMAL
    invoke UpdateWindow, hWnd
  msgloop:
    invoke GetMessage, ADDR wMsg, NULL, 0, 0
    .IF eax != 0
      invoke TranslateMessage, ADDR wMsg
      invoke DispatchMessage, ADDR wMsg
      jmp msgloop
    .ENDIF
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start

eschew obfuscation

Tedd

ASCPECTX and ASPECTY are the relative dimensions of a device pixel -- relative to what?!
Relative to the logical screen size, which is related to the DPI setting of the device (see LOGPIXELSX and LOGPIXELSY) to ensure fonts are sized sensibly on different sized devices/screens.
And as it's effectively a multiplier, there are no units.

Anyway, if ASPECTX==ASPECTY, the pixels are square.
No snowflake in an avalanche feels responsible.

Rockoon

Quote from: Tedd on December 08, 2007, 06:00:02 PM

Anyway, if ASPECTX==ASPECTY, the pixels are square.


Already shown not to be true.

To re-iterate,

in my LCD's native resolution in a 5:4 mode (1280x1024), ASPECTX=ASPECTY
on the same LCD, when its in a 4:3  mode (1024x768), ASPECTX=ASPECTY

..these both cannot be true if ASPECTX and ASPECTY have any meaning in regards to pixel width and height. I know that the first mode is the one with a true 1:1 pixel (physically measured the display with a ruler)

Here is the output of a prototype app I cooked up:

When in 1280x1024:

*SIZE   = 337 270
*RES    = 1280 1024
ASPECT* = 36 36

When in 1024x768:

*SIZE   = 340 255
*RES    = 1024 768
ASPECT* = 36 36

As you can see, instead of changing the ASPECT* values when the mode changes, it instead changed the HORZSIZE and VERTSIZE values and simply pretends that the pixels are square (which they are now not square.) Restated: the OS always assumes that display pixels are square.

It is unreasonable to expect end users to know what modes have square pixels and what modes do not, and it now seems unlikely that my app can even recommend a video mode or do any compensation since it doesnt seem possible to detect which ones have square pixels and which ones do not.

sigh..
When C++ compilers can be coerced to emit rcl and rcr, I *might* consider using one.

jj2007

Found this below at http://webster.cs.ucr.edu/Page_win32/WindowsAsmPgm/html/Ch07.html

w.ASPECTX, w.ASPECTY and w.ASPECTXY will be very important to you.
These values specify the relative width, height, and diagonal length of pixels on the
screen. What this means is that if you draw a line segment that is n pixels long along the
X-axis, you would need to draw a line segment with (n*w.ASPECTY)/w.ASPECTX pixels
along the Y-axis to obtain a line that is physically the same size.
You would use these calculations to ensure that the shapes you draw on the screen
don't come out looking elongated or squashed. For example, when drawing a square on the
display, you would not draw an object with n pixels on each edge of the rectangle; doing so
would likely produce a rectangle whose sides have a different length than the top and
bottom line segments (that is, you'd have a proper rectangle rather than a square).
However, if you use the ratio w.ASPECTX:w.ASPECTY when drawing the sides of the
rectangle then the image you create will physically look like a square on the display
device. Generally, you'll only adjust one of the two coordinates via this ratio


In a nutshell: It's the width and height of a diagonal line. Probably relevant for those fancy little widescreen displays.

MichaelW

The Microsoft example here uses LOGPIXELSX and LOGPIXELSY, along with StretchDIBits to compensate for the difference in aspect ratios between the display and a printer.

Rockoon,

For a CRT even under the best conditions, where the displayed pixel pitch matched the dot pitch, with each dot composed of 0 to 3 (active) components I can’t see how the aspect ratio of a pixel could have much meaning, or any readily predictable effect on image quality.

The only device on my system that allows me to specify a DPI where the x and y values differ is the NT Fax Driver. For the Normal (200x200 dpi) image quality setting:

ASPECTX 200
ASPECTY 200
LOGPIXELSX 200
LOGPIXELSY 200

For the Draft (200x100 dpi) image quality setting:

ASPECTX 100
ASPECTY 200
LOGPIXELSX 200
LOGPIXELSY 100

So ASPECTX and ASPECTY do seem to be connected to the DPI settings.
eschew obfuscation

Rockoon

Quote from: jj2007 on December 08, 2007, 09:33:10 PM
In a nutshell: It's the width and height of a diagonal line. Probably relevant for those fancy little widescreen displays.

That is yet another incorrect resource :(



I am not the only person who has tried to tackle this issue it seems:

https://mollyrocket.com/forums/viewtopic.php?p=1940



He/She mentions LOGXPIXELSX and LOGPIXELSY, and when I prototype:

*SIZE   = 337 270
*RES    = 1280 1024
ASPECT* = 36 36
LOGPIXELS* = 96 96

*SIZE   = 340 255
*RES    = 1024 768
ASPECT* = 36 36
LOGPIXELS* = 96 96

Same problem. Both cannot be true.
When C++ compilers can be coerced to emit rcl and rcr, I *might* consider using one.

Rockoon

Quote from: MichaelW on December 08, 2007, 10:47:19 PM
For a CRT even under the best conditions, where the displayed pixel pitch matched the dot pitch, with each dot composed of 0 to 3 (active) components I can’t see how the aspect ratio of a pixel could have much meaning, or any readily predictable effect on image quality.

It matters not in "quality", but in geometric accuracy.

How do I draw a square?
How do I draw a circle?

If the "square" I draw appears as a rectangle, and the "circle" I draw appears as an oval, then surely you see the problem, right?

Consider an educational software game targeting 5 year old children, intended to be marketed to schools. This game is a geometry game intended to teach the children the difference between a rectangle and a square, and the diference between circles and ovals. It becomes of primary importance that squares really are square, and circles really are circles.

While for the resolutions 1280x1024 vs 1024x768 the difference is only about 7%, I have many display resolutions to choose from, yet only one of them actualy has a 5:4 size where pixels are square. Every other resolution choice offers a different pixel aspect ratio, some of them are very far from 1:1 (I can set a video mode intended for 16:10 wide screen monitors)
When C++ compilers can be coerced to emit rcl and rcr, I *might* consider using one.

u

On a side note, the only place where I know pixels are non-rectangular is a PAL TV-out. And I haven't seen any monitor do aspect-correction, however simple that is (with the RAM and DSP they obviously already have to do stretching on LCD, and the circuitry they have on CRT). For the same reason I bet the monitor outputs predefined constants as its pixel-aspect ratio.
Just for an experiment, could someone with WinXP (not Win2k or earlier) see what the pixel-aspect ratio of the tv-out of the videocard is?

For the important task of that children's game, CRT monitors are always 4:3 (and no sane person would use non-4:3 screen-size, it's impossible to read text otherwise). LCD monitors will either be set at their native resolution or make text unreadable, too. Guess what- the customers solved their problem themselves  :toothy. (this also shows the reasoning behind that constant 36:36 ratio).

It's silently become a standard to have square pixels, with LCDs having become predominant :).
Please use a smaller graphic in your signature.

jj2007

Quote from: Ultrano on December 09, 2007, 12:13:21 AM
CRT monitors are always 4:3 (and no sane person would use non-4:3 screen-size, it's impossible to read text otherwise)
Sane or not sane, 16:9 is becoming the standard for home tv, and for ultraportable laptops.
Since Rockoon has no confidence in non-MS sources, here a quote from the Microsoft Windows Device Driver Kit (DDK) for Windows versions:

Windows uses the AspectX, AspectY, and AspectXY constants returned by
GetDeviceCaps() to draw dotted and dashed lines that appear the same
regardless of the line's orientation. The AspectX and AspectY values are
dimensionless numbers that form the legs of a right triangle on the device;
the AspectXY value is the length of the hypotenuse. The ratio of AspectY to
AspectX is the aspect ratio of the device. The Windows graphics device
interface (GDI) uses this information to draw round circles, for example.

The AspectX, AspectY, and AspectXY values should be small (less than
100 each, for example). The size of these values impacts the length of
a patterned brush provided by GDI.

The LogPixelsX and LogPixelsY values describe the actual physical
resolution of the device.

ASPECTX & Y were not always 36:36 - see CGA:
GetDeviceCaps          CGA   EGA   VGA   8514/A
ASPECTX (horizontal)     5    38    36     10
ASPECTY (vertical)       12    48    36     10

Rockoon

Quote from: Ultrano on December 09, 2007, 12:13:21 AM
For the important task of that children's game, CRT monitors are always 4:3 (and no sane person would use non-4:3 screen-size, it's impossible to read text otherwise).

When I was running a CRT, I used the highest resolution that the monitor could sync to (1280x960), and that most definately did have square pixels.

My father OTOH, who now has that same CRT, runs at 1024x768 because 1280x960 makes text too small for him. Now you might argue that he could have altered the DPI settings in windows to produce the same effect.. but you would be wrong.. people who change the DPI setting in windows from 96 to anything else ("large fonts") eventualy regret it when poory written applications become unusable, and web pages unreadable.

For instance, http://blogs.msdn.com/oldnewthing/archive/2004/07/14/182971.aspx

Quote from: Ultrano on December 09, 2007, 12:13:21 AM
LCD monitors will either be set at their native resolution or make text unreadable, too.

..or will be set to the lowest resolution possible (likely to be 640x480) so the whole class can see whats on the screen.

We arent talking about programmers here. We are talking about people.

..and while it might seem fine to dismiss the people using other resolutions as being "insane" in passing conversation, it is not fine to do so from a software development standpoint. They might use "insane" resolutions.. they may type in "insane" filenames.. hell they might even have their desktop set to a 16-color (4-bit) graphics mode.. quality software addresses the idiot at the keyboard issue wherever possible.
When C++ compilers can be coerced to emit rcl and rcr, I *might* consider using one.

Rockoon

Quote from: jj2007 on December 09, 2007, 12:40:25 AM
Since Rockoon has no confidence in non-MS sources, here a quote from the Microsoft Windows Device Driver Kit (DDK) for Windows versions:

I dont have confidence in any resources that disagrees with emperical evidence. I havent seen a single one that agrees with the evidence, including the one you just quoted. The non-MS resources seem to be simply regurgitating the MS resources, which are emperically incorrect.

Quote
ASPECTX & Y were not always 36:36 - see CGA:
GetDeviceCaps      Â    CGA   EGA   VGA   8514/A
ASPECTX (horizontal)   Â  5    38    36   Â  10
ASPECTY (vertical)   Â    12    48    36   Â  10

See? They are constants! How can they be constants if they are supposed to represent pixel aspect ratios?

CGA for instance could do (among other lower resolutions) 320x200 (2-bit color) or 640x200 (1-bit color).

A 1" square in the later resolution would would be 2"x1" in the former...

When C++ compilers can be coerced to emit rcl and rcr, I *might* consider using one.

u

Quote from: Rockoon on December 09, 2007, 01:50:51 AM
When I was running a CRT, I used the highest resolution that the monitor could sync to (1280x960), and that most definately did have square pixels.
My father OTOH, who now has that same CRT, runs at 1024x768 because 1280x960 makes text too small for him.
Both resolutions you mentioned are 4:3. No wonder "definitely square pixels".
I still stand firm behind the idea that GPU/display manufacturers and Microsoft have come to the conclusion, that almost all (if not absolutely all) users keep their AR correct. I see no other reason why my previous designers'-class CRT and my current 16:10 HDCP-enabled dual-input LCD monitor stretch any input to fit the whole screen, (and all LCDs disallow manual vertical stretching). Or it's all a bug in Windows, that has become a standard.

Now, let's stop pondering about how we would perform AR corrections, and see how professional software, whose primary selling point and concern is keeping AR and physical dimensions intact, does the job under Windows. Namely, launch Acrobat Reader with a document, where a square is shown. Switch to a screen-size with bad AR, and you get a nice rectangle. Ok, ok Acrobat is for printing correctly, but what about creating the documents? I bet the editor is also plagued by this "problem".

DPI and text-sizes aren't part of the topic, how about keeping the topic about ASPECTX and ASPECTY :) ?

P.S.
QuoteSane or not sane, 16:9 is becoming the standard for home tv, and for ultraportable laptops.
Read the context I wrote that in. It's about CRT monitors. Don't forget 16:10 is becoming the standard for home PCs.
Please use a smaller graphic in your signature.