Skip to content

Pen motion could be more precise (Windows) #12084

@FullPtrDereference

Description

@FullPtrDereference

I would have made a PR instead, but I never use github and I didn't wanna screw something up.

I saw how pen motion coordinates are basically just ints, but other programs like Krita manage to get more precision somehow, and I figured out how to do that, as without it a tablet is basically just a mouse with pressure, which affects your lines.

After this from SDL_windowsevents.c:

    case WM_POINTERDOWN:
    case WM_POINTERUP: {
        ...
        ScreenToClient(data->hwnd, &position);

I added this:

        const POINTER_INFO pointerInfo = pen_info.pointerInfo;
        
        SDL_FPoint tabletPos = {
            pointerInfo.ptHimetricLocationRaw.x,
            pointerInfo.ptHimetricLocationRaw.y
        };
        
        RECT tabletBounds  = {0};
        RECT tabletMapping = {0};
        
        float outX, outY;
        
        // should cache this somewhere?
        if(!GetPointerDeviceRects(pointerInfo.sourceDevice, &tabletBounds, &tabletMapping)) {
            outX = (float) position.x;
            outY = (float) position.y;
        } else {
            SDL_FPoint windowPos;
            
            {
                int x, y;
                
                SDL_GetWindowPosition(window, &x, &y);
                windowPos.x = x;
                windowPos.y = y;
            }
            
            const float facX = tabletPos.x / (float) (tabletBounds.right );
            const float facY = tabletPos.y / (float) (tabletBounds.bottom);
            
            const float w = tabletMapping.right  - tabletMapping.left;
            const float h = tabletMapping.bottom - tabletMapping.top;
            
            outX = (tabletMapping.left + (facX * w)) - windowPos.x;
            outY = (tabletMapping.top  + (facY * h)) - windowPos.y;
        }
        
        SDL_SendPenMotion(timestamp, pen, window, outX, outY);
        // SDL_SendPenMotion(timestamp, pen, window, (float) position.x, (float) position.y);

I couldn't test this on HiDPI, and you might wanna cache the result of GetPointerDeviceRects but I don't know where, but otherwise this worked for me at least, using 1 and 2 monitors.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions