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 let local_rect = LayoutRect::from_size(doc.content_rect.size());
106
107 builder.push_simple_stacking_context(
108 doc.content_rect.min,
109 space_and_clip.spatial_id,
110 PrimitiveFlags::IS_BACKFACE_VISIBLE,
111 );
112 builder.push_rect(
113 &CommonItemProperties::new(local_rect, space_and_clip),
114 local_rect,
115 doc.color,
116 );
117 builder.pop_stacking_context();
118
119 let mut txn = Transaction::new();
120 txn.set_display_list(
121 Epoch(0),
122 None,
123 doc.content_rect.size(),
124 builder.finalize(),
125 true,
126 );
127 txn.generate_frame(0);
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