bug 674373 pt 1 - Mac OS X native theme rendering support for HiDPI display. r=smichaud

This commit is contained in:
Markus Stange 2012-08-13 17:45:57 +01:00
parent efcb97d866
commit a67e645c79

View File

@ -460,6 +460,16 @@ nsNativeThemeCocoa::~nsNativeThemeCocoa()
// different amounts of RAM.
#define BITMAP_MAX_AREA 500000
static int
GetBackingScaleFactorForRendering(CGContextRef cgContext)
{
CGAffineTransform ctm = CGContextGetUserSpaceToDeviceSpaceTransform(cgContext);
CGRect transformedUserSpacePixel = CGRectApplyAffineTransform(CGRectMake(0, 0, 1, 1), ctm);
float maxScale = NS_MAX(fabs(transformedUserSpacePixel.size.width),
fabs(transformedUserSpacePixel.size.height));
return maxScale > 1.0 ? 2 : 1;
}
/*
* Draw the given NSCell into the given cgContext.
*
@ -542,10 +552,11 @@ static void DrawCellWithScaling(NSCell *cell,
w += MAX_FOCUS_RING_WIDTH * 2.0;
h += MAX_FOCUS_RING_WIDTH * 2.0;
int backingScaleFactor = GetBackingScaleFactorForRendering(cgContext);
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(NULL,
(int) w, (int) h,
8, (int) w * 4,
(int) w * backingScaleFactor, (int) h * backingScaleFactor,
8, (int) w * backingScaleFactor * 4,
rgb, kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(rgb);
@ -561,6 +572,8 @@ static void DrawCellWithScaling(NSCell *cell,
NSGraphicsContext* savedContext = [NSGraphicsContext currentContext];
[NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:YES]];
CGContextScaleCTM(ctx, backingScaleFactor, backingScaleFactor);
// This is the second flip transform, applied to ctx.
CGContextScaleCTM(ctx, 1.0f, -1.0f);
CGContextTranslateCTM(ctx, 0.0f, -(2.0 * tmpRect.origin.y + tmpRect.size.height));
@ -967,12 +980,18 @@ RenderTransformedHIThemeControl(CGContextRef aCGContext, const HIRect& aRect,
int w = ceil(drawRect.size.width) + 2 * MAX_FOCUS_RING_WIDTH;
int h = ceil(drawRect.size.height) + 2 * MAX_FOCUS_RING_WIDTH;
int backingScaleFactor = GetBackingScaleFactorForRendering(aCGContext);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapctx = CGBitmapContextCreate(NULL, w, h, 8, w * 4,
CGContextRef bitmapctx = CGBitmapContextCreate(NULL,
w * backingScaleFactor,
h * backingScaleFactor,
8,
w * backingScaleFactor * 4,
colorSpace,
kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(colorSpace);
CGContextScaleCTM(bitmapctx, backingScaleFactor, backingScaleFactor);
CGContextTranslateCTM(bitmapctx, MAX_FOCUS_RING_WIDTH, MAX_FOCUS_RING_WIDTH);
// HITheme always wants to draw into a flipped context, or things
@ -1774,10 +1793,12 @@ ToolbarCanBeUnified(CGContextRef cgContext, const HIRect& inBoxRect, NSWindow* a
return false;
float unifiedToolbarHeight = [(ToolbarWindow*)aWindow unifiedToolbarHeight];
CGAffineTransform ctm = CGContextGetUserSpaceToDeviceSpaceTransform(cgContext);
CGRect deviceRect = CGRectApplyAffineTransform(inBoxRect, ctm);
return inBoxRect.origin.x == 0 &&
inBoxRect.size.width >= [aWindow frame].size.width &&
deviceRect.size.width >= [aWindow frame].size.width &&
inBoxRect.origin.y <= 0.0 &&
inBoxRect.origin.y + inBoxRect.size.height <= unifiedToolbarHeight;
floor(inBoxRect.origin.y + inBoxRect.size.height) <= unifiedToolbarHeight;
}
void
@ -1876,6 +1897,14 @@ nsNativeThemeCocoa::DrawResizer(CGContextRef cgContext, const HIRect& aRect,
NS_OBJC_END_TRY_ABORT_BLOCK;
}
static bool
IsContextZoomedToHighResolution(nsDeviceContext* aContext)
{
const float devPixelsPerCSSPixel = 1.0f *
nsPresContext::AppUnitsPerCSSPixel() / aContext->AppUnitsPerDevPixel();
return devPixelsPerCSSPixel > 1.5f;
}
NS_IMETHODIMP
nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
nsIFrame* aFrame,
@ -1901,6 +1930,15 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
if (!thebesCtx)
return NS_ERROR_FAILURE;
gfxContextMatrixAutoSaveRestore save(thebesCtx);
if (IsContextZoomedToHighResolution(aContext->DeviceContext())) {
// Use high-resolution drawing.
nativeWidgetRect.ScaleInverse(2.0f);
nativeDirtyRect.ScaleInverse(2.0f);
thebesCtx->Scale(2.0f, 2.0f);
}
gfxQuartzNativeDrawing nativeDrawing(thebesCtx, nativeDirtyRect);
CGContextRef cgContext = nativeDrawing.BeginNativeDrawing();
@ -2298,8 +2336,8 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext,
CGContextFillRect(cgContext, macRect);
// #8E8E8E for the top border, #BEBEBE for the rest.
int x = macRect.origin.x, y = macRect.origin.y;
int w = macRect.size.width, h = macRect.size.height;
float x = macRect.origin.x, y = macRect.origin.y;
float w = macRect.size.width, h = macRect.size.height;
CGContextSetRGBFillColor(cgContext, 0.557, 0.557, 0.557, 1.0);
CGContextFillRect(cgContext, CGRectMake(x, y, w, 1));
CGContextSetRGBFillColor(cgContext, 0.745, 0.745, 0.745, 1.0);
@ -2449,6 +2487,10 @@ nsNativeThemeCocoa::GetWidgetBorder(nsDeviceContext* aContext,
break;
}
if (IsContextZoomedToHighResolution(aContext)) {
*aResult = *aResult + *aResult; // doubled
}
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
@ -2718,6 +2760,10 @@ nsNativeThemeCocoa::GetMinimumWidgetSize(nsRenderingContext* aContext,
}
}
if (IsContextZoomedToHighResolution(aContext->DeviceContext())) {
*aResult = *aResult * 2;
}
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;