aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-04-08 13:41:35 +0200
committerDavid Robillard <d@drobilla.net>2020-04-08 13:41:35 +0200
commit29ba1095370abcdc341086b258bfe046f50100fc (patch)
treeecd130c3d3f5755cdd083c66e01c483238cd5404
parent53d8fe0c19408a54165f6422319be8139758a5b2 (diff)
downloadpugl-29ba1095370abcdc341086b258bfe046f50100fc.tar.gz
pugl-29ba1095370abcdc341086b258bfe046f50100fc.tar.bz2
pugl-29ba1095370abcdc341086b258bfe046f50100fc.zip
Mac: Use high-resolution backing surfaces
-rw-r--r--pugl/detail/mac.m133
-rw-r--r--pugl/detail/mac_cairo.m15
-rw-r--r--pugl/detail/mac_gl.m6
3 files changed, 111 insertions, 43 deletions
diff --git a/pugl/detail/mac.m b/pugl/detail/mac.m
index 480253e..0b26cb7 100644
--- a/pugl/detail/mac.m
+++ b/pugl/detail/mac.m
@@ -40,27 +40,72 @@ typedef NSUInteger NSWindowStyleMask;
#endif
static NSRect
-rectToScreen(NSRect rect)
+rectToScreen(NSScreen* screen, NSRect rect)
{
- const double screenHeight = [[NSScreen mainScreen] frame].size.height;
+ const double screenHeight = [screen frame].size.height;
rect.origin.y = screenHeight - rect.origin.y - rect.size.height;
return rect;
}
+static NSScreen*
+viewScreen(PuglView* view)
+{
+ return view->impl->window ? [view->impl->window screen] : [NSScreen mainScreen];
+}
+
+static NSRect
+nsRectToPoints(PuglView* view, const NSRect rect)
+{
+ const double scaleFactor = [viewScreen(view) backingScaleFactor];
+
+ return NSMakeRect(rect.origin.x / scaleFactor,
+ rect.origin.y / scaleFactor,
+ rect.size.width / scaleFactor,
+ rect.size.height / scaleFactor);
+}
+
+static NSRect
+nsRectFromPoints(PuglView* view, const NSRect rect)
+{
+ const double scaleFactor = [viewScreen(view) backingScaleFactor];
+
+ return NSMakeRect(rect.origin.x * scaleFactor,
+ rect.origin.y * scaleFactor,
+ rect.size.width * scaleFactor,
+ rect.size.height * scaleFactor);
+}
+
+static NSRect
+rectToNsRect(const PuglRect rect)
+{
+ return NSMakeRect(rect.x, rect.y, rect.width, rect.height);
+}
+
+static NSSize
+sizePoints(PuglView* view, const double width, const double height)
+{
+ const double scaleFactor = [viewScreen(view) backingScaleFactor];
+
+ return NSMakeSize(width / scaleFactor, height / scaleFactor);
+}
+
static void
updateViewRect(PuglView* view)
{
NSWindow* const window = view->impl->window;
if (window) {
- const double screenHeight = [[NSScreen mainScreen] frame].size.height;
- const NSRect frame = [window frame];
- const NSRect content = [window contentRectForFrameRect:frame];
-
- view->frame.x = content.origin.x;
- view->frame.y = screenHeight - content.origin.y - content.size.height;
- view->frame.width = content.size.width;
- view->frame.height = content.size.height;
+ const NSRect screenFramePt = [[NSScreen mainScreen] frame];
+ const NSRect screenFramePx = nsRectFromPoints(view, screenFramePt);
+ const NSRect framePt = [window frame];
+ const NSRect contentPt = [window contentRectForFrameRect:framePt];
+ const NSRect contentPx = nsRectFromPoints(view, contentPt);
+ const double screenHeight = screenFramePx.size.height;
+
+ view->frame.x = contentPx.origin.x;
+ view->frame.y = screenHeight - contentPx.origin.y - contentPx.size.height;
+ view->frame.width = contentPx.size.width;
+ view->frame.height = contentPx.size.height;
}
}
@@ -85,7 +130,9 @@ updateViewRect(PuglView* view)
- (void)setPuglview:(PuglView*)view
{
puglview = view;
- [self setContentSize:NSMakeSize(view->frame.width, view->frame.height)];
+
+ [self
+ setContentSize:sizePoints(view, view->frame.width, view->frame.height)];
}
- (BOOL) canBecomeKeyWindow
@@ -127,10 +174,12 @@ updateViewRect(PuglView* view)
- (void) dispatchExpose:(NSRect)rect
{
+ const double scaleFactor = [[NSScreen mainScreen] backingScaleFactor];
+
if (reshaped) {
updateViewRect(puglview);
- const PuglEventConfigure ev = {
+ const PuglEventConfigure ev = {
PUGL_CONFIGURE,
0,
puglview->frame.x,
@@ -150,10 +199,10 @@ updateViewRect(PuglView* view)
const PuglEventExpose ev = {
PUGL_EXPOSE,
0,
- rect.origin.x,
- rect.origin.y,
- rect.size.width,
- rect.size.height,
+ rect.origin.x * scaleFactor,
+ rect.origin.y * scaleFactor,
+ rect.size.width * scaleFactor,
+ rect.size.height * scaleFactor,
0
};
@@ -757,14 +806,20 @@ puglRealize(PuglView* view)
{
PuglInternals* impl = view->impl;
+ const double scaleFactor = [[NSScreen mainScreen] backingScaleFactor];
+ const NSRect framePx = rectToNsRect(view->frame);
+ const NSRect framePt = NSMakeRect(framePx.origin.x / scaleFactor,
+ framePx.origin.y / scaleFactor,
+ framePx.size.width / scaleFactor,
+ framePx.size.height / scaleFactor);
+
// Create wrapper view to handle input
impl->wrapperView = [PuglWrapperView alloc];
impl->wrapperView->puglview = view;
impl->wrapperView->userTimers = [[NSMutableDictionary alloc] init];
impl->wrapperView->markedText = [[NSMutableAttributedString alloc] init];
[impl->wrapperView setAutoresizesSubviews:YES];
- [impl->wrapperView initWithFrame:
- NSMakeRect(0, 0, view->frame.width, view->frame.height)];
+ [impl->wrapperView initWithFrame:framePt];
[impl->wrapperView addConstraint:
puglConstraint(impl->wrapperView, NSLayoutAttributeWidth, view->minWidth)];
[impl->wrapperView addConstraint:
@@ -788,10 +843,6 @@ puglRealize(PuglView* view)
[impl->drawView setHidden:NO];
[[impl->drawView window] makeFirstResponder:impl->wrapperView];
} else {
- const NSRect frame = rectToScreen(
- NSMakeRect(view->frame.x, view->frame.y,
- view->minWidth, view->minHeight));
-
unsigned style = (NSClosableWindowMask |
NSTitledWindowMask |
NSMiniaturizableWindowMask );
@@ -800,7 +851,7 @@ puglRealize(PuglView* view)
}
PuglWindow* window = [[[PuglWindow alloc]
- initWithContentRect:frame
+ initWithContentRect:rectToScreen([NSScreen mainScreen], framePt)
styleMask:style
backing:NSBackingStoreBuffered
defer:NO
@@ -817,7 +868,8 @@ puglRealize(PuglView* view)
}
if (view->minWidth || view->minHeight) {
- [window setContentMinSize:NSMakeSize(view->minWidth,
+ [window setContentMinSize:sizePoints(view,
+ view->minWidth,
view->minHeight)];
}
impl->window = window;
@@ -826,7 +878,8 @@ puglRealize(PuglView* view)
initWithPuglWindow:window];
if (view->minAspectX && view->minAspectY) {
- [window setContentAspectRatio:NSMakeSize(view->minAspectX,
+ [window setContentAspectRatio:sizePoints(view,
+ view->minAspectX,
view->minAspectY)];
}
@@ -1066,8 +1119,9 @@ puglPostRedisplay(PuglView* view)
PuglStatus
puglPostRedisplayRect(PuglView* view, const PuglRect rect)
{
- [view->impl->drawView setNeedsDisplayInRect:
- NSMakeRect(rect.x, rect.y, rect.width, rect.height)];
+ const NSRect rectPx = rectToNsRect(rect);
+
+ [view->impl->drawView setNeedsDisplayInRect:nsRectToPoints(view, rectPx)];
return PUGL_SUCCESS;
}
@@ -1103,19 +1157,22 @@ puglSetFrame(PuglView* view, const PuglRect frame)
// Update view frame to exactly the requested frame in Pugl coordinates
view->frame = frame;
- const NSRect rect = NSMakeRect(frame.x, frame.y, frame.width, frame.height);
+ const NSRect framePx = rectToNsRect(frame);
+ const NSRect framePt = nsRectToPoints(view, framePx);
if (impl->window) {
// Resize window to fit new content rect
- const NSRect windowFrame = [
- impl->window frameRectForContentRect:rectToScreen(rect)];
+ const NSRect screenPt = rectToScreen(viewScreen(view), framePt);
+ const NSRect winFrame = [impl->window frameRectForContentRect:screenPt];
- [impl->window setFrame:windowFrame display:NO];
+ [impl->window setFrame:winFrame display:NO];
}
// Resize views
- const NSRect drawRect = NSMakeRect(0, 0, frame.width, frame.height);
- [impl->wrapperView setFrame:(impl->window ? drawRect : rect)];
- [impl->drawView setFrame:drawRect];
+ const NSRect sizePx = NSMakeRect(0, 0, frame.width, frame.height);
+ const NSRect sizePt = [impl->drawView convertRectFromBacking:sizePx];
+
+ [impl->wrapperView setFrame:(impl->window ? sizePt : framePt)];
+ [impl->drawView setFrame:sizePt];
return PUGL_SUCCESS;
}
@@ -1127,8 +1184,9 @@ puglSetMinSize(PuglView* const view, const int width, const int height)
view->minHeight = height;
if (view->impl->window && (view->minWidth || view->minHeight)) {
- [view->impl->window
- setContentMinSize:NSMakeSize(view->minWidth, view->minHeight)];
+ [view->impl->window setContentMinSize:sizePoints(view,
+ view->minWidth,
+ view->minHeight)];
}
return PUGL_SUCCESS;
@@ -1147,7 +1205,8 @@ puglSetAspectRatio(PuglView* const view,
view->maxAspectY = maxY;
if (view->impl->window && view->minAspectX && view->minAspectY) {
- [view->impl->window setContentAspectRatio:NSMakeSize(view->minAspectX,
+ [view->impl->window setContentAspectRatio:sizePoints(view,
+ view->minAspectX,
view->minAspectY)];
}
diff --git a/pugl/detail/mac_cairo.m b/pugl/detail/mac_cairo.m
index 51c1c13..ccce14e 100644
--- a/pugl/detail/mac_cairo.m
+++ b/pugl/detail/mac_cairo.m
@@ -43,7 +43,9 @@
- (id) initWithFrame:(NSRect)frame
{
- return (self = [super initWithFrame:frame]);
+ self = [super initWithFrame:frame];
+
+ return self;
}
- (void) resizeWithOldSuperviewSize:(NSSize)oldSize
@@ -69,7 +71,7 @@ puglMacCairoCreate(PuglView* view)
PuglCairoView* drawView = [PuglCairoView alloc];
drawView->puglview = view;
- [drawView initWithFrame:NSMakeRect(0, 0, view->frame.width, view->frame.height)];
+ [drawView initWithFrame:[impl->wrapperView bounds]];
if (view->hints[PUGL_RESIZABLE]) {
[drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
} else {
@@ -103,10 +105,17 @@ puglMacCairoEnter(PuglView* view, const PuglEventExpose* expose)
assert(!drawView->surface);
assert(!drawView->cr);
+ const double scale = 1.0 / [[NSScreen mainScreen] backingScaleFactor];
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
+ const CGSize sizePx = {view->frame.width, view->frame.height};
+ const CGSize sizePt = CGContextConvertSizeToUserSpace(context, sizePx);
+
+ // Convert coordinates to standard Cairo space
+ CGContextTranslateCTM(context, 0.0, -sizePt.height);
+ CGContextScaleCTM(context, scale, -scale);
drawView->surface = cairo_quartz_surface_create_for_cg_context(
- context, view->frame.width, view->frame.height);
+ context, sizePx.width, sizePx.height);
drawView->cr = cairo_create(drawView->surface);
diff --git a/pugl/detail/mac_gl.m b/pugl/detail/mac_gl.m
index eda4371..3d55056 100644
--- a/pugl/detail/mac_gl.m
+++ b/pugl/detail/mac_gl.m
@@ -69,6 +69,8 @@
self = [super initWithFrame:frame];
}
+ [self setWantsBestResolutionOpenGLSurface:YES];
+
if (self) {
[[self openGLContext] makeCurrentContext];
[self reshape];
@@ -97,11 +99,9 @@ puglMacGlCreate(PuglView* view)
{
PuglInternals* impl = view->impl;
PuglOpenGLView* drawView = [PuglOpenGLView alloc];
- const NSRect rect = NSMakeRect(
- 0, 0, view->frame.width, view->frame.height);
drawView->puglview = view;
- [drawView initWithFrame:rect];
+ [drawView initWithFrame:[impl->wrapperView bounds]];
if (view->hints[PUGL_RESIZABLE]) {
[drawView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
} else {