1/*
2 * Copyright (C) 2010 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#import "WebRenderLayer.h"
27
28#import "WebFrameInternal.h"
29#import <WebCore/Frame.h>
30#import <WebCore/FrameLoaderClient.h>
31#import <WebCore/PlatformString.h>
32#import <WebCore/RenderLayer.h>
33#import <WebCore/RenderLayerBacking.h>
34#import <WebCore/RenderView.h>
35#import <WebCore/StyledElement.h>
36
37using namespace WebCore;
38
39
40@interface WebRenderLayer(Private)
41
42- (id)initWithRenderLayer:(RenderLayer *)layer;
43- (void)buildDescendantLayers:(RenderLayer*)rootLayer;
44
45@end
46
47@implementation WebRenderLayer
48
49+ (NSString *)nameForLayer:(RenderLayer*)layer
50{
51    RenderObject* renderer = layer->renderer();
52    NSString *name = [NSString stringWithUTF8String:renderer->renderName()];
53
54    if (Node* node = renderer->node()) {
55        if (node->isElementNode())
56            name = [name stringByAppendingFormat:@" %@", (NSString *)static_cast<Element*>(node)->tagName()];
57        if (node->hasID())
58            name = [name stringByAppendingFormat:@" id=\"%@\"", (NSString *)static_cast<Element*>(node)->getIdAttribute()];
59
60        if (node->hasClass()) {
61            StyledElement* styledElement = static_cast<StyledElement*>(node);
62            String classes;
63            for (size_t i = 0; i < styledElement->classNames().size(); ++i) {
64                if (i > 0)
65                    classes += " ";
66                classes += styledElement->classNames()[i];
67            }
68            name = [name stringByAppendingFormat:@" class=\"%@\"", (NSString *)classes];
69        }
70    }
71
72    if (layer->isReflection())
73        name = [name stringByAppendingString:@" (reflection)"];
74
75    return name;
76}
77
78+ (NSString *)compositingInfoForLayer:(RenderLayer*)layer
79{
80    if (!layer->isComposited())
81        return @"";
82
83    NSString *layerType = @"";
84#if USE(ACCELERATED_COMPOSITING)
85    RenderLayerBacking* backing = layer->backing();
86    switch (backing->compositingLayerType()) {
87        case NormalCompositingLayer:
88            layerType = @"composited";
89            break;
90        case TiledCompositingLayer:
91            layerType = @"composited: tiled layer";
92            break;
93        case MediaCompositingLayer:
94            layerType = @"composited for plug-in, video or WebGL";
95            break;
96        case ContainerCompositingLayer:
97            layerType = @"composited: container layer";
98            break;
99    }
100
101    if (backing->hasClippingLayer())
102        layerType = [layerType stringByAppendingString:@" (clipping)"];
103
104    if (backing->hasAncestorClippingLayer())
105        layerType = [layerType stringByAppendingString:@" (clipped)"];
106#endif
107
108    return layerType;
109}
110
111- (id)initWithRenderLayer:(RenderLayer*)layer
112{
113    if ((self = [super init])) {
114        name = [[WebRenderLayer nameForLayer:layer] retain];
115        bounds = layer->absoluteBoundingBox();
116        composited = layer->isComposited();
117        compositingInfo = [[WebRenderLayer compositingInfoForLayer:layer] retain];
118    }
119
120    return self;
121}
122
123- (id)initWithName:(NSString*)layerName
124{
125    if ((self = [super init])) {
126        name = [layerName copy];
127        separator = YES;
128    }
129
130    return self;
131}
132
133// Only called on the root.
134- (id)initWithWebFrame:(WebFrame *)webFrame
135{
136    self = [super init];
137
138    Frame* frame = core(webFrame);
139    if (!frame->loader()->client()->hasHTMLView()) {
140        [self release];
141        return nil;
142    }
143
144    RenderObject* renderer = frame->contentRenderer();
145    if (!renderer) {
146        [self release];
147        return nil;
148    }
149
150    if (renderer->hasLayer()) {
151        RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
152
153        name = [[WebRenderLayer nameForLayer:layer] retain];
154        bounds = layer->absoluteBoundingBox();
155        composited = layer->isComposited();
156        compositingInfo = [[WebRenderLayer compositingInfoForLayer:layer] retain];
157
158        [self buildDescendantLayers:layer];
159    }
160
161    return self;
162}
163
164- (void)dealloc
165{
166    [children release];
167    [name release];
168    [compositingInfo release];
169    [super dealloc];
170}
171
172- (void)buildDescendantLayers:(RenderLayer*)layer
173{
174    NSMutableArray *childWebLayers = [[NSMutableArray alloc] init];
175
176    // Build children in back to front order.
177
178    if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
179        size_t listSize = negZOrderList->size();
180
181        if (listSize) {
182            WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithName:@"-ve z-order list"];
183            [childWebLayers addObject:newLayer];
184            [newLayer release];
185        }
186
187        for (size_t i = 0; i < listSize; ++i) {
188            RenderLayer* curLayer = negZOrderList->at(i);
189
190            WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithRenderLayer:curLayer];
191            [newLayer buildDescendantLayers:curLayer];
192
193            [childWebLayers addObject:newLayer];
194            [newLayer release];
195        }
196    }
197
198    if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
199        size_t listSize = normalFlowList->size();
200
201        if (listSize) {
202            WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithName:@"normal flow list"];
203            [childWebLayers addObject:newLayer];
204            [newLayer release];
205        }
206
207        for (size_t i = 0; i < listSize; ++i) {
208            RenderLayer* curLayer = normalFlowList->at(i);
209
210            WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithRenderLayer:curLayer];
211            [newLayer buildDescendantLayers:curLayer];
212
213            [childWebLayers addObject:newLayer];
214            [newLayer release];
215        }
216    }
217
218    if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
219        size_t listSize = posZOrderList->size();
220
221        if (listSize) {
222            WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithName:@"+ve z-order list"];
223            [childWebLayers addObject:newLayer];
224            [newLayer release];
225        }
226
227        for (size_t i = 0; i < listSize; ++i) {
228            RenderLayer* curLayer = posZOrderList->at(i);
229
230            WebRenderLayer* newLayer = [[WebRenderLayer alloc] initWithRenderLayer:curLayer];
231            [newLayer buildDescendantLayers:curLayer];
232
233            [childWebLayers addObject:newLayer];
234            [newLayer release];
235        }
236    }
237
238    children = childWebLayers;
239}
240
241- (NSArray *)children
242{
243    return children;
244}
245
246- (NSString *)name
247{
248    return name;
249}
250
251- (NSString *)positionString
252{
253    return [NSString stringWithFormat:@"(%.0f, %.0f)", bounds.origin.x, bounds.origin.y];
254}
255
256- (NSString *)widthString
257{
258    return [NSString stringWithFormat:@"%.0f", bounds.size.width];
259}
260
261- (NSString *)heightString
262{
263    return [NSString stringWithFormat:@"%.0f", bounds.size.height];
264}
265
266- (NSString *)compositingInfo
267{
268    return compositingInfo;
269}
270
271- (BOOL)isComposited
272{
273    return composited;
274}
275
276- (BOOL)isSeparator
277{
278    return separator;
279}
280
281@end
282