1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 extern crate euclid;
6 extern crate gleam;
7 extern crate glutin;
8 extern crate webrender;
9 extern crate winit;
10 
11 #[path = "common/boilerplate.rs"]
12 mod boilerplate;
13 
14 use crate::boilerplate::Example;
15 use euclid::Scale;
16 use webrender::api::*;
17 use webrender::render_api::*;
18 use webrender::api::units::*;
19 
20 // This example creates multiple documents overlapping each other with
21 // specified layer indices.
22 
23 struct Document {
24     id: DocumentId,
25     pipeline_id: PipelineId,
26     content_rect: LayoutRect,
27     color: ColorF,
28 }
29 
30 struct App {
31     documents: Vec<Document>,
32 }
33 
34 impl App {
init( &mut self, api: &mut RenderApi, device_pixel_ratio: f32, )35     fn init(
36         &mut self,
37         api: &mut RenderApi,
38         device_pixel_ratio: f32,
39     ) {
40         let init_data = vec![
41             (
42                 PipelineId(1, 0),
43                 ColorF::new(0.0, 1.0, 0.0, 1.0),
44                 DeviceIntPoint::new(0, 0),
45             ),
46             (
47                 PipelineId(2, 0),
48                 ColorF::new(1.0, 1.0, 0.0, 1.0),
49                 DeviceIntPoint::new(200, 0),
50             ),
51             (
52                 PipelineId(3, 0),
53                 ColorF::new(1.0, 0.0, 0.0, 1.0),
54                 DeviceIntPoint::new(200, 200),
55             ),
56             (
57                 PipelineId(4, 0),
58                 ColorF::new(1.0, 0.0, 1.0, 1.0),
59                 DeviceIntPoint::new(0, 200),
60             ),
61         ];
62 
63         for (pipeline_id, color, offset) in init_data {
64             let size = DeviceIntSize::new(250, 250);
65             let bounds = DeviceIntRect::from_origin_and_size(offset, size);
66 
67             let document_id = api.add_document(size);
68             let mut txn = Transaction::new();
69             txn.set_root_pipeline(pipeline_id);
70             api.send_transaction(document_id, txn);
71 
72             self.documents.push(Document {
73                 id: document_id,
74                 pipeline_id,
75                 content_rect: LayoutRect::from_size(
76                     bounds.size().to_f32() / Scale::new(device_pixel_ratio),
77                 ),
78                 color,
79             });
80         }
81     }
82 }
83 
84 impl Example for App {
render( &mut self, api: &mut RenderApi, _base_builder: &mut DisplayListBuilder, _txn: &mut Transaction, _device_size: DeviceIntSize, _pipeline_id: PipelineId, _: DocumentId, )85     fn render(
86         &mut self,
87         api: &mut RenderApi,
88         _base_builder: &mut DisplayListBuilder,
89         _txn: &mut Transaction,
90         _device_size: DeviceIntSize,
91         _pipeline_id: PipelineId,
92         _: DocumentId,
93     ) {
94         if self.documents.is_empty() {
95             // this is the first run, hack around the boilerplate,
96             // which assumes an example only needs one document
97             self.init(api, 1.0);
98         }
99 
100         for doc in &self.documents {
101             let space_and_clip = SpaceAndClipInfo::root_scroll(doc.pipeline_id);
102             let mut builder = DisplayListBuilder::new(
103                 doc.pipeline_id,
104             );
105             builder.begin();
106             let local_rect = LayoutRect::from_size(doc.content_rect.size());
107 
108             builder.push_simple_stacking_context(
109                 doc.content_rect.min,
110                 space_and_clip.spatial_id,
111                 PrimitiveFlags::IS_BACKFACE_VISIBLE,
112             );
113             builder.push_rect(
114                 &CommonItemProperties::new(local_rect, space_and_clip),
115                 local_rect,
116                 doc.color,
117             );
118             builder.pop_stacking_context();
119 
120             let mut txn = Transaction::new();
121             txn.set_display_list(
122                 Epoch(0),
123                 None,
124                 doc.content_rect.size(),
125                 builder.end(),
126             );
127             txn.generate_frame(0, RenderReasons::empty());
128             api.send_transaction(doc.id, txn);
129         }
130     }
131 }
132 
main()133 fn main() {
134     let mut app = App {
135         documents: Vec::new(),
136     };
137     boilerplate::main_wrapper(&mut app, None);
138 }
139