1/* 2 * Copyright (C) 2009 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27 28#if USE(ACCELERATED_COMPOSITING) 29 30#import "WebLayer.h" 31 32#import "GraphicsContext.h" 33#import "GraphicsLayer.h" 34#import <QuartzCore/QuartzCore.h> 35#import <wtf/UnusedParam.h> 36 37using namespace WebCore; 38 39@implementation WebLayer 40 41+ (void)drawContents:(WebCore::GraphicsLayer*)layerContents ofLayer:(CALayer*)layer intoContext:(CGContextRef)context 42{ 43 if (!layerContents) 44 return; 45 46 CGContextSaveGState(context); 47 48 CGRect layerBounds = [layer bounds]; 49 if (layerContents->contentsOrientation() == WebCore::GraphicsLayer::CompositingCoordinatesBottomUp) { 50 CGContextScaleCTM(context, 1, -1); 51 CGContextTranslateCTM(context, 0, -layerBounds.size.height); 52 } 53 54 if (layerContents->client()) { 55 [NSGraphicsContext saveGraphicsState]; 56 57 // Set up an NSGraphicsContext for the context, so that parts of AppKit that rely on 58 // the current NSGraphicsContext (e.g. NSCell drawing) get the right one. 59 NSGraphicsContext* layerContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context flipped:YES]; 60 [NSGraphicsContext setCurrentContext:layerContext]; 61 62 GraphicsContext graphicsContext(context); 63 64 // It's important to get the clip from the context, because it may be significantly 65 // smaller than the layer bounds (e.g. tiled layers) 66 CGRect clipBounds = CGContextGetClipBoundingBox(context); 67 IntRect clip(enclosingIntRect(clipBounds)); 68 layerContents->paintGraphicsLayerContents(graphicsContext, clip); 69 70 [NSGraphicsContext restoreGraphicsState]; 71 } 72#ifndef NDEBUG 73 else { 74 ASSERT_NOT_REACHED(); 75 76 // FIXME: ideally we'd avoid calling -setNeedsDisplay on a layer that is a plain color, 77 // so CA never makes backing store for it (which is what -setNeedsDisplay will do above). 78 CGContextSetRGBFillColor(context, 0.0f, 1.0f, 0.0f, 1.0f); 79 CGContextFillRect(context, layerBounds); 80 } 81#endif 82 83#ifndef NDEBUG 84 if (layerContents->showRepaintCounter()) { 85 bool isTiledLayer = [layer isKindOfClass:[CATiledLayer class]]; 86 87 char text[16]; // that's a lot of repaints 88 snprintf(text, sizeof(text), "%d", layerContents->incrementRepaintCount()); 89 90 CGContextSaveGState(context); 91 if (isTiledLayer) 92 CGContextSetRGBFillColor(context, 0.0f, 1.0f, 0.0f, 0.8f); 93 else 94 CGContextSetRGBFillColor(context, 1.0f, 0.0f, 0.0f, 0.8f); 95 96 CGRect aBounds = layerBounds; 97 98 aBounds.size.width = 10 + 12 * strlen(text); 99 aBounds.size.height = 25; 100 CGContextFillRect(context, aBounds); 101 102 CGContextSetRGBFillColor(context, 0.0f, 0.0f, 0.0f, 1.0f); 103 104 CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1.0f, -1.0f)); 105 CGContextSelectFont(context, "Helvetica", 25, kCGEncodingMacRoman); 106 CGContextShowTextAtPoint(context, aBounds.origin.x + 3.0f, aBounds.origin.y + 20.0f, text, strlen(text)); 107 108 CGContextRestoreGState(context); 109 } 110#endif 111 112 CGContextRestoreGState(context); 113} 114 115// Disable default animations 116- (id<CAAction>)actionForKey:(NSString *)key 117{ 118 UNUSED_PARAM(key); 119 return nil; 120} 121 122// Implement this so presentationLayer can get our custom attributes 123- (id)initWithLayer:(id)layer 124{ 125 if ((self = [super initWithLayer:layer])) 126 m_layerOwner = [(WebLayer*)layer layerOwner]; 127 128 return self; 129} 130 131- (void)setNeedsDisplay 132{ 133 if (m_layerOwner && m_layerOwner->client() && m_layerOwner->drawsContent()) 134 [super setNeedsDisplay]; 135} 136 137- (void)setNeedsDisplayInRect:(CGRect)dirtyRect 138{ 139 if (m_layerOwner && m_layerOwner->client() && m_layerOwner->drawsContent()) { 140#if defined(BUILDING_ON_LEOPARD) 141 dirtyRect = CGRectApplyAffineTransform(dirtyRect, [self contentsTransform]); 142#endif 143 [super setNeedsDisplayInRect:dirtyRect]; 144 145#ifndef NDEBUG 146 if (m_layerOwner->showRepaintCounter()) { 147 CGRect bounds = [self bounds]; 148 CGRect indicatorRect = CGRectMake(bounds.origin.x, bounds.origin.y, 46, 25); 149#if defined(BUILDING_ON_LEOPARD) 150 indicatorRect = CGRectApplyAffineTransform(indicatorRect, [self contentsTransform]); 151#endif 152 [super setNeedsDisplayInRect:indicatorRect]; 153 } 154#endif 155 } 156} 157 158- (void)drawInContext:(CGContextRef)context 159{ 160 [WebLayer drawContents:m_layerOwner ofLayer:self intoContext:context]; 161} 162 163@end // implementation WebLayer 164 165#pragma mark - 166 167@implementation WebLayer(WebLayerAdditions) 168 169- (void)setLayerOwner:(GraphicsLayer*)aLayer 170{ 171 m_layerOwner = aLayer; 172} 173 174- (GraphicsLayer*)layerOwner 175{ 176 return m_layerOwner; 177} 178 179@end 180 181#pragma mark - 182 183#ifndef NDEBUG 184 185@implementation CALayer(ExtendedDescription) 186 187- (NSString*)_descriptionWithPrefix:(NSString*)inPrefix 188{ 189 CGRect aBounds = [self bounds]; 190 CGPoint aPos = [self position]; 191 CATransform3D t = [self transform]; 192 193 NSString* selfString = [NSString stringWithFormat:@"%@<%@ 0x%08x> \"%@\" bounds(%.1f, %.1f, %.1f, %.1f) pos(%.1f, %.1f), sublayers=%d masking=%d", 194 inPrefix, 195 [self class], 196 self, 197 [self name], 198 aBounds.origin.x, aBounds.origin.y, aBounds.size.width, aBounds.size.height, 199 aPos.x, aPos.y, 200 [[self sublayers] count], 201 [self masksToBounds]]; 202 203 NSMutableString* curDesc = [NSMutableString stringWithString:selfString]; 204 205 if ([[self sublayers] count] > 0) 206 [curDesc appendString:@"\n"]; 207 208 NSString* sublayerPrefix = [inPrefix stringByAppendingString:@"\t"]; 209 210 NSEnumerator* sublayersEnum = [[self sublayers] objectEnumerator]; 211 CALayer* curLayer; 212 while ((curLayer = [sublayersEnum nextObject])) 213 [curDesc appendString:[curLayer _descriptionWithPrefix:sublayerPrefix]]; 214 215 if ([[self sublayers] count] == 0) 216 [curDesc appendString:@"\n"]; 217 218 return curDesc; 219} 220 221- (NSString*)extendedDescription 222{ 223 return [self _descriptionWithPrefix:@""]; 224} 225 226@end // implementation WebLayer(ExtendedDescription) 227 228#endif // NDEBUG 229 230#endif // USE(ACCELERATED_COMPOSITING) 231