6e60ebf1ffa6590f6f34e528a3e3358318b5ebdf
[WebKit-https.git] / Source / WebCore / platform / graphics / cocoa / TextTrackRepresentationCocoa.mm
1 /*
2  * Copyright (C) 2012 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #if (PLATFORM(IOS_FAMILY) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))) && ENABLE(VIDEO_TRACK)
29 #include "TextTrackRepresentationCocoa.h"
30
31 #include "FloatRect.h"
32 #include "GraphicsContextCG.h"
33 #include "IntRect.h"
34
35 #if PLATFORM(IOS_FAMILY)
36 #include "WebCoreThread.h"
37 #include "WebCoreThreadRun.h"
38 #endif
39
40 #import <pal/spi/cocoa/QuartzCoreSPI.h>
41
42 using namespace WebCore;
43
44 @interface WebCoreTextTrackRepresentationCocoaHelper : NSObject <CALayerDelegate> {
45     TextTrackRepresentationCocoa* _parent;
46 }
47 - (id)initWithParent:(TextTrackRepresentationCocoa*)parent;
48 @property (assign) TextTrackRepresentationCocoa* parent;
49 @end
50
51 @implementation WebCoreTextTrackRepresentationCocoaHelper
52 - (id)initWithParent:(TextTrackRepresentationCocoa*)parent
53 {
54     if (!(self = [super init]))
55         return nil;
56
57     self.parent = parent;
58
59     return self;
60 }
61
62 - (void)dealloc
63 {
64     self.parent = nullptr;
65     [super dealloc];
66 }
67
68 - (void)setParent:(TextTrackRepresentationCocoa*)parent
69 {
70     if (_parent)
71         [_parent->platformLayer() removeObserver:self forKeyPath:@"bounds"];
72
73     _parent = parent;
74
75     if (_parent)
76         [_parent->platformLayer() addObserver:self forKeyPath:@"bounds" options:0 context:0];
77 }
78
79 - (TextTrackRepresentationCocoa*)parent
80 {
81     return _parent;
82 }
83
84 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
85 {
86     UNUSED_PARAM(change);
87     UNUSED_PARAM(context);
88 #if PLATFORM(IOS_FAMILY)
89     WebThreadRun(^{
90         if (_parent && [keyPath isEqual:@"bounds"] && object == _parent->platformLayer())
91             _parent->client().textTrackRepresentationBoundsChanged(_parent->bounds());
92     });
93 #else
94     if (_parent && [keyPath isEqual:@"bounds"] && object == _parent->platformLayer())
95         _parent->client().textTrackRepresentationBoundsChanged(_parent->bounds());
96 #endif
97 }
98
99 - (id)actionForLayer:(CALayer *)layer forKey:(NSString *)event
100 {
101     UNUSED_PARAM(layer);
102     UNUSED_PARAM(event);
103     // Returning a NSNull from this delegate method disables all implicit CALayer actions.
104     return [NSNull null];
105 }
106
107 @end
108
109 std::unique_ptr<TextTrackRepresentation> TextTrackRepresentation::create(TextTrackRepresentationClient& client)
110 {
111     return std::make_unique<TextTrackRepresentationCocoa>(client);
112 }
113
114 TextTrackRepresentationCocoa::TextTrackRepresentationCocoa(TextTrackRepresentationClient& client)
115     : m_client(client)
116     , m_layer(adoptNS([[CALayer alloc] init]))
117     , m_delegate(adoptNS([[WebCoreTextTrackRepresentationCocoaHelper alloc] initWithParent:this]))
118 {
119     [m_layer.get() setDelegate:m_delegate.get()];
120     [m_layer.get() setContentsGravity:kCAGravityBottom];
121 }
122
123 TextTrackRepresentationCocoa::~TextTrackRepresentationCocoa()
124 {
125     [m_layer.get() setDelegate:nil];
126     [m_delegate.get() setParent:nullptr];
127 }
128
129 void TextTrackRepresentationCocoa::update()
130 {
131     if (auto representation = m_client.createTextTrackRepresentationImage())
132         [m_layer.get() setContents:(__bridge id)representation->nativeImage().get()];
133 }
134
135 void TextTrackRepresentationCocoa::setContentScale(float scale)
136 {
137     [m_layer.get() setContentsScale:scale];
138 }
139
140 IntRect TextTrackRepresentationCocoa::bounds() const
141 {
142     return enclosingIntRect(FloatRect([m_layer.get() bounds]));
143 }
144
145 #endif // (PLATFORM(IOS_FAMILY) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))) && ENABLE(VIDEO_TRACK)