bfg-common 1.2.19 → 1.2.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/atoms/alert/Notification.vue +167 -167
- package/components/atoms/autocomplete/Autocomplete.vue +236 -236
- package/components/atoms/datepicker/Datepicker.vue +612 -612
- package/components/atoms/list/SelectList.vue +62 -62
- package/components/atoms/nav/NavBar.vue +116 -116
- package/components/atoms/nav/VerticalNavBar.vue +89 -89
- package/components/atoms/notificationBar/NotificationBar.vue +175 -175
- package/components/atoms/perPage/PerPage.vue +52 -52
- package/components/atoms/popup/SimplePopup.vue +90 -90
- package/components/atoms/step/VerticalStep.vue +104 -104
- package/components/atoms/switch/Switch.vue +107 -107
- package/components/atoms/table/dataGrid/DataGridColumnSwitch.vue +206 -206
- package/components/atoms/table/dataGrid/DataGridPage.vue +189 -189
- package/components/atoms/tabs/Tabs.vue +189 -189
- package/components/atoms/tooltip/Signpost.vue +224 -224
- package/components/common/BadBrowser.vue +58 -0
- package/components/common/adapterManager/AddAdapterWarningModal.vue +82 -82
- package/components/common/adapterManager/NoActiveAdaptersModal.vue +62 -62
- package/components/common/adapterManager/NoConnectedActiveAdaptersModal.vue +62 -62
- package/components/common/browse/Browse.vue +182 -182
- package/components/common/browse/blocks/Title.vue +66 -66
- package/components/common/diagramMain/Diagram.vue +186 -186
- package/components/common/diagramMain/DiagramMain.vue +986 -986
- package/components/common/diagramMain/adapter/AdapterItem.vue +227 -227
- package/components/common/diagramMain/adapter/AdapterItems.vue +57 -57
- package/components/common/diagramMain/modals/editSettings/tabs/port/IpvFourSettings.vue +339 -339
- package/components/common/diagramMain/modals/editSettings/tabs/port/PortProperties.vue +202 -202
- package/components/common/diagramMain/modals/remove/RemoveModal.vue +226 -226
- package/components/common/diagramMain/network/Contents.vue +238 -238
- package/components/common/feedback/Buttons.vue +232 -232
- package/components/common/feedback/Message.vue +468 -468
- package/components/common/feedback/VisitPortal.vue +54 -54
- package/components/common/help/navbar/left/Left.vue +159 -159
- package/components/common/help/navbar/left/utils/constructAccordion.ts +27 -27
- package/components/common/mainNavigationPanel/MainNavigationPanel.vue +359 -359
- package/components/common/modals/Rename.vue +165 -165
- package/components/common/perPage/PerPage.vue +51 -51
- package/components/common/recursionTree/RecursionTree.vue +201 -201
- package/components/common/vm/actions/add/config/capabilities.ts +338 -338
- package/components/common/vm/actions/add/customizeHardware/virtualHardware/VirtualHardware.vue +657 -657
- package/components/common/vm/actions/add/customizeHardware/virtualHardware/cpu/CoresPerSocket.vue +109 -109
- package/components/common/vm/actions/add/customizeHardware/virtualHardware/cpu/Cpu.vue +383 -383
- package/components/common/vm/actions/add/customizeHardware/virtualHardware/limit/Limit.vue +234 -234
- package/components/common/vm/actions/add/customizeHardware/virtualHardware/limit/config/options.ts +28 -28
- package/components/common/vm/actions/add/customizeHardware/virtualHardware/memory/Memory.vue +316 -316
- package/components/common/vm/actions/add/customizeHardware/virtualHardware/memory/config/memoryOptions.ts +35 -35
- package/components/common/vm/actions/add/customizeHardware/virtualHardware/newHardDisk/NewHardDisk.vue +445 -445
- package/components/common/vm/actions/add/customizeHardware/virtualHardware/newNetwork/NewNetwork.vue +288 -288
- package/components/common/vm/actions/add/customizeHardware/virtualHardware/reservation/Reservation.vue +235 -235
- package/components/common/vm/actions/add/customizeHardware/virtualHardware/videoCard/VideoCard.vue +177 -177
- package/components/common/vm/actions/add/customizeHardware/vmoptions/bootOptions/order/Order.vue +197 -197
- package/components/common/vm/actions/add/customizeHardware/vmoptions/generalOptions/GeneralOptions.vue +181 -181
- package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/CopyPaste.vue +51 -51
- package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/RemoteConsoleOptions.vue +253 -253
- package/components/common/vm/actions/add/customizeHardware/vmoptions/remoteConsoleOptions/keymap/Keymap.vue +55 -55
- package/components/common/vm/actions/add/select/storage/config/config.ts +154 -154
- package/components/common/vm/actions/clone/Clone.vue +544 -544
- package/components/common/vm/actions/clone/select/options/Options.vue +65 -65
- package/components/common/vm/actions/clone/utils.ts +43 -43
- package/components/common/wizards/datastore/add/nfs/configuration/Configuration.vue +373 -373
- package/components/common/wizards/datastore/add/nfs/configuration/serversList/ServersList.vue +123 -123
- package/components/common/wizards/datastore/add/nfs/kerberosAuthentication/KerberosAuthentication.vue +54 -54
- package/components/common/wizards/datastore/add/sharedStorm/deviceSelection/hostTable/HostTable.vue +131 -131
- package/components/common/wizards/datastore/add/sharedStorm/partitionConfiguration/PartitionConfiguration.vue +230 -230
- package/composables/useLocal.ts +38 -38
- package/minify.js +146 -146
- package/models/store/interfaces.ts +37 -37
- package/models/store/storage/interfaces.ts +32 -32
- package/models/store/types.ts +32 -32
- package/modules/fixContentBuild/utils/methods.ts +114 -114
- package/package.json +1 -1
- package/public/spice-console/application/codec.js +257 -257
- package/public/spice-console/lib/rasterEngine.js +907 -907
- package/public/spice-console/network/spicechannel.js +369 -369
- package/utils/contentBuild.ts +34 -34
|
@@ -1,907 +1,907 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright (c) 2016 eyeOS
|
|
3
|
-
|
|
4
|
-
This file is part of Open365.
|
|
5
|
-
|
|
6
|
-
Open365 is free software: you can redistribute it and/or modify
|
|
7
|
-
it under the terms of the GNU Affero General Public License as
|
|
8
|
-
published by the Free Software Foundation, either version 3 of the
|
|
9
|
-
License, or (at your option) any later version.
|
|
10
|
-
|
|
11
|
-
This program is distributed in the hope that it will be useful,
|
|
12
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
-
GNU Affero General Public License for more details.
|
|
15
|
-
|
|
16
|
-
You should have received a copy of the GNU Affero General Public License
|
|
17
|
-
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
wdi.RasterEngine = $.spcExtend(wdi.EventObject.prototype, {
|
|
21
|
-
init: function (c) {
|
|
22
|
-
this.time = Date.now()
|
|
23
|
-
this.clientGui = c.clientGui
|
|
24
|
-
|
|
25
|
-
// h264
|
|
26
|
-
this.codecH264 = wdi.CodecH264
|
|
27
|
-
|
|
28
|
-
// vp8
|
|
29
|
-
this.codecVp8 = wdi.CodecVp8
|
|
30
|
-
|
|
31
|
-
// vp9
|
|
32
|
-
// this.videoDecoderVp9 = {}
|
|
33
|
-
|
|
34
|
-
// h265
|
|
35
|
-
this.codecH265 = wdi.CodecH265
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
dispose: function () {
|
|
39
|
-
this.clientGui = null
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
drawCanvas: function (spiceMessage) {
|
|
43
|
-
wdi.Debug.log('rasterEngine', this.time)
|
|
44
|
-
return this.clientGui.drawCanvas(spiceMessage)
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
removeCanvas: function (spiceMessage) {
|
|
48
|
-
return this.clientGui.removeCanvas(spiceMessage)
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
invalList: function (spiceMessage) {
|
|
52
|
-
var items = spiceMessage.args.items
|
|
53
|
-
var item = null
|
|
54
|
-
for (var i in items) {
|
|
55
|
-
item = items[i]
|
|
56
|
-
wdi.ImageCache.delImage(item.id)
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
handleStreamCreate: function (spiceMessage) {
|
|
61
|
-
var stream = spiceMessage.args
|
|
62
|
-
stream.computedBox = wdi.graphics.getBoxFromSrcArea(stream.rect)
|
|
63
|
-
wdi.Stream.addStream(spiceMessage.args.id, stream)
|
|
64
|
-
|
|
65
|
-
console.log('%chandleStreamCreate', 'color:rgb(100,255,100)')
|
|
66
|
-
switch (stream.codec) {
|
|
67
|
-
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_H264:
|
|
68
|
-
this.handleH264StreamCreate(stream.id)
|
|
69
|
-
break
|
|
70
|
-
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_VP8:
|
|
71
|
-
this.handleVp8StreamCreate(stream.id)
|
|
72
|
-
break
|
|
73
|
-
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_VP9:
|
|
74
|
-
break
|
|
75
|
-
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_H265:
|
|
76
|
-
this.handleH265StreamCreate(stream.id)
|
|
77
|
-
break
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (wdi.graphicDebug) {
|
|
81
|
-
wdi.graphicDebug.handleStreamInfo()
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
handleVp8StreamCreate: function (streamId) {
|
|
86
|
-
this.codecVp8.create(streamId)
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
handleH265StreamCreate: async function (streamId) {
|
|
90
|
-
const stream = wdi.Stream.getStream(streamId)
|
|
91
|
-
const context = this.clientGui.getContext(stream.surface_id)
|
|
92
|
-
const box = stream.computedBox
|
|
93
|
-
|
|
94
|
-
this.codecH265.create(streamId, context, box)
|
|
95
|
-
},
|
|
96
|
-
|
|
97
|
-
handleH264StreamCreate: function (streamId) {
|
|
98
|
-
this.codecH264.create(streamId)
|
|
99
|
-
},
|
|
100
|
-
|
|
101
|
-
handleStreamData: function (spiceMessage) {
|
|
102
|
-
var stream = wdi.Stream.getStream(spiceMessage.args.id)
|
|
103
|
-
switch (stream.codec) {
|
|
104
|
-
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_H264:
|
|
105
|
-
this.handleH264Stream(spiceMessage)
|
|
106
|
-
break
|
|
107
|
-
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_VP8:
|
|
108
|
-
this.handleVp8Stream(spiceMessage)
|
|
109
|
-
break
|
|
110
|
-
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_VP9:
|
|
111
|
-
break
|
|
112
|
-
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_H265:
|
|
113
|
-
this.handleH265Stream(spiceMessage)
|
|
114
|
-
break
|
|
115
|
-
default:
|
|
116
|
-
this.handleMjpegStream(spiceMessage)
|
|
117
|
-
break
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
|
|
121
|
-
handleStreamClip: function (spiceMessage) {
|
|
122
|
-
wdi.Stream.clip(spiceMessage.args.id, spiceMessage.args.clip)
|
|
123
|
-
wdi.Stream.startTransition(spiceMessage.args.id)
|
|
124
|
-
console.log('%chandleStreamClip', 'color:rgb(100,100,255)')
|
|
125
|
-
},
|
|
126
|
-
|
|
127
|
-
handleStreamDataSized: function (spiceMessage) {
|
|
128
|
-
// console.log(spiceMessage, 'handleStreamDataSized');
|
|
129
|
-
},
|
|
130
|
-
|
|
131
|
-
handleStreamActiveReport: function (spiceMessage) {
|
|
132
|
-
// console.log(spiceMessage, 'handleStreamActiveReport');
|
|
133
|
-
},
|
|
134
|
-
|
|
135
|
-
handleStreamDestroy: function (spiceMessage) {
|
|
136
|
-
wdi.Stream.deleteStream(spiceMessage.args.surface_id)
|
|
137
|
-
|
|
138
|
-
// Destroy H264
|
|
139
|
-
this.codecH264.destroy(spiceMessage.args.surface_id)
|
|
140
|
-
|
|
141
|
-
// Destroy VP8
|
|
142
|
-
this.codecVp8.destroy()
|
|
143
|
-
|
|
144
|
-
// h265
|
|
145
|
-
this.codecH265.destroy()
|
|
146
|
-
|
|
147
|
-
if (wdi.graphicDebug) {
|
|
148
|
-
wdi.graphicDebug.handleStreamInfo()
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
console.log('%chandleStreamDestroy', 'color:rgb(255,100,100)')
|
|
152
|
-
},
|
|
153
|
-
|
|
154
|
-
handleMjpegStream: function (spiceMessage) {
|
|
155
|
-
var imageData = spiceMessage.args.data //jpeg string encoded
|
|
156
|
-
var stream = wdi.Stream.getStream(spiceMessage.args.id) //recover the stream
|
|
157
|
-
var context = this.clientGui.getContext(stream.surface_id)
|
|
158
|
-
var img = wdi.GlobalPool.create('Image') //auto-release pool
|
|
159
|
-
wdi.ExecutionControl.sync = true
|
|
160
|
-
var url
|
|
161
|
-
img.onload = function () {
|
|
162
|
-
URL.revokeObjectURL(url)
|
|
163
|
-
var box = stream.computedBox
|
|
164
|
-
// we only rotate the stream if spice tells us so through the TOP_DOWN flag mask
|
|
165
|
-
if (!stream.flags & wdi.SpiceStreamFlags.SPICE_STREAM_FLAGS_TOP_DOWN) {
|
|
166
|
-
var offsetX = box.x + this.width / 2
|
|
167
|
-
var offsetY = box.y + this.height / 2
|
|
168
|
-
context.save()
|
|
169
|
-
context.translate(offsetX, offsetY)
|
|
170
|
-
context.rotate(Math.PI)
|
|
171
|
-
context.scale(-1, 1)
|
|
172
|
-
context.drawImage(
|
|
173
|
-
this,
|
|
174
|
-
box.x - offsetX,
|
|
175
|
-
box.y - offsetY,
|
|
176
|
-
box.width,
|
|
177
|
-
box.height
|
|
178
|
-
)
|
|
179
|
-
context.restore()
|
|
180
|
-
} else {
|
|
181
|
-
context.drawImage(this, box.x, box.y, box.width, box.height)
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
img.onerror = function () {
|
|
186
|
-
URL.revokeObjectURL(url)
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
url = wdi.SpiceObject.bytesToURI(imageData)
|
|
190
|
-
img.src = url
|
|
191
|
-
},
|
|
192
|
-
|
|
193
|
-
handleH264Stream: function (spiceMessage) {
|
|
194
|
-
var imageData = spiceMessage.args.data
|
|
195
|
-
var stream = wdi.Stream.getStream(spiceMessage.args.id) //recover the stream
|
|
196
|
-
|
|
197
|
-
// Был баг, который не запускал стрим
|
|
198
|
-
// это условие помогло
|
|
199
|
-
if (!this.codecH264.isReady[stream.id]) {
|
|
200
|
-
this.codecH264.addQueue(stream.id, imageData)
|
|
201
|
-
return
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
var context = this.clientGui.getContext(stream.surface_id)
|
|
205
|
-
wdi.ExecutionControl.sync = true
|
|
206
|
-
wdi.Stream.endTransition(spiceMessage.args.id)
|
|
207
|
-
|
|
208
|
-
this.codecH264.loadedVideo[stream.id] = () => {
|
|
209
|
-
var box = stream.computedBox
|
|
210
|
-
// we only rotate the stream if spice tells us so through the TOP_DOWN flag mask
|
|
211
|
-
if (!stream.flags & wdi.SpiceStreamFlags.SPICE_STREAM_FLAGS_TOP_DOWN) {
|
|
212
|
-
var offsetX = box.x + this.codecH264.video[stream.id].width / 2
|
|
213
|
-
var offsetY = box.y + this.codecH264.video[stream.id].height / 2
|
|
214
|
-
context.save()
|
|
215
|
-
context.translate(offsetX, offsetY)
|
|
216
|
-
context.rotate(Math.PI)
|
|
217
|
-
context.scale(-1, 1)
|
|
218
|
-
context.drawImage(
|
|
219
|
-
this.codecH264.video[stream.id],
|
|
220
|
-
box.x - offsetX,
|
|
221
|
-
box.y - offsetY,
|
|
222
|
-
box.width,
|
|
223
|
-
box.height
|
|
224
|
-
)
|
|
225
|
-
context.restore()
|
|
226
|
-
} else {
|
|
227
|
-
if (
|
|
228
|
-
!this.codecH264.video[stream.id] ||
|
|
229
|
-
!this.codecH264.loadedVideo[stream.id]
|
|
230
|
-
)
|
|
231
|
-
return
|
|
232
|
-
if (stream.transiting) {
|
|
233
|
-
requestAnimationFrame(this.codecH264.loadedVideo[stream.id])
|
|
234
|
-
return
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
context.drawImage(
|
|
238
|
-
this.codecH264.video[stream.id],
|
|
239
|
-
box.x,
|
|
240
|
-
box.y,
|
|
241
|
-
box.width,
|
|
242
|
-
box.height
|
|
243
|
-
)
|
|
244
|
-
requestAnimationFrame(this.codecH264.loadedVideo[stream.id])
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
this.codecH264.feed(stream.id, imageData)
|
|
249
|
-
},
|
|
250
|
-
|
|
251
|
-
handleH265Stream: function (spiceMessage) {
|
|
252
|
-
const imageData = spiceMessage.args.data
|
|
253
|
-
const stream = wdi.Stream.getStream(spiceMessage.args.id)
|
|
254
|
-
const box = stream.computedBox
|
|
255
|
-
|
|
256
|
-
// Так как метод handleH265StreamCreate ан синхронный и ждет пока сделается проверка поддерживает ли браузер VideoDecoder,
|
|
257
|
-
// некоторые кадры могут быть упущены, их нужно хранить т.к. в них есть ключевые кадры
|
|
258
|
-
if (!this.codecH265.isReady[stream.id]) {
|
|
259
|
-
this.codecH265.addQueue(stream.id, imageData)
|
|
260
|
-
return
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (!this.codecH265.configed[stream.id]) {
|
|
264
|
-
this.codecH265.setConfig(stream.id, box)
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
this.codecH265.decode(stream.id, imageData)
|
|
268
|
-
},
|
|
269
|
-
|
|
270
|
-
handleVp8Stream: function (spiceMessage) {
|
|
271
|
-
var imageData = spiceMessage.args.data
|
|
272
|
-
var stream = wdi.Stream.getStream(spiceMessage.args.id)
|
|
273
|
-
var context = this.clientGui.getContext(stream.surface_id)
|
|
274
|
-
var box = stream.computedBox
|
|
275
|
-
|
|
276
|
-
this.codecVp8.feed(stream.id, imageData, context, box)
|
|
277
|
-
},
|
|
278
|
-
|
|
279
|
-
drawRop3: function (spiceMessage) {
|
|
280
|
-
var box = wdi.graphics.getBoxFromSrcArea(spiceMessage.args.base.box)
|
|
281
|
-
var context = this.clientGui.getContext(spiceMessage.args.base.surface_id)
|
|
282
|
-
var destImg = context.getImageData(box.x, box.y, box.width, box.height)
|
|
283
|
-
var clientGui = this.clientGui
|
|
284
|
-
|
|
285
|
-
var brush = spiceMessage.args.brush
|
|
286
|
-
var rop = spiceMessage.args.rop_descriptor
|
|
287
|
-
|
|
288
|
-
var srcArea = wdi.graphics.getBoxFromSrcArea(spiceMessage.args.src_area)
|
|
289
|
-
wdi.graphics.getImageFromSpice(
|
|
290
|
-
spiceMessage.args.src_image.imageDescriptor,
|
|
291
|
-
spiceMessage.args.src_image.data,
|
|
292
|
-
this.clientGui,
|
|
293
|
-
function (sourceCanvas) {
|
|
294
|
-
if (sourceCanvas) {
|
|
295
|
-
//Get source image data (image coming from the packet)
|
|
296
|
-
var sourceContext = sourceCanvas.getContext('2d')
|
|
297
|
-
var srcImg = sourceContext.getImageData(
|
|
298
|
-
srcArea.x,
|
|
299
|
-
srcArea.y,
|
|
300
|
-
srcArea.width,
|
|
301
|
-
srcArea.height
|
|
302
|
-
)
|
|
303
|
-
var srcImgData = srcImg.data //this
|
|
304
|
-
|
|
305
|
-
//Get pattern image data
|
|
306
|
-
//brush
|
|
307
|
-
var tmpcanvas = wdi.graphics.getNewTmpCanvas(box.width, box.height)
|
|
308
|
-
var tmpcontext = tmpcanvas.getContext('2d')
|
|
309
|
-
var brushBox = {
|
|
310
|
-
width: box.width,
|
|
311
|
-
height: box.height,
|
|
312
|
-
x: 0,
|
|
313
|
-
y: 0,
|
|
314
|
-
}
|
|
315
|
-
wdi.graphics.setBrush(
|
|
316
|
-
clientGui,
|
|
317
|
-
tmpcontext,
|
|
318
|
-
brush,
|
|
319
|
-
brushBox,
|
|
320
|
-
wdi.SpiceRopd.SPICE_ROPD_OP_PUT
|
|
321
|
-
) //Without alpha?
|
|
322
|
-
var pattern = tmpcontext.getImageData(0, 0, box.width, box.height)
|
|
323
|
-
var patImgData = pattern.data //this
|
|
324
|
-
|
|
325
|
-
//Get dest image data
|
|
326
|
-
var destImgData = destImg.data
|
|
327
|
-
|
|
328
|
-
//Get result image data
|
|
329
|
-
tmpcanvas = wdi.graphics.getNewTmpCanvas(box.width, box.height)
|
|
330
|
-
tmpcontext = tmpcanvas.getContext('2d')
|
|
331
|
-
var result = tmpcontext.createImageData(box.width, box.height)
|
|
332
|
-
var resultData = result.data
|
|
333
|
-
|
|
334
|
-
if (
|
|
335
|
-
srcImg.width != pattern.width ||
|
|
336
|
-
srcImg.width != destImg.width ||
|
|
337
|
-
srcImg.height != pattern.height ||
|
|
338
|
-
srcImg.height != destImg.height
|
|
339
|
-
) {
|
|
340
|
-
//TODO: resize
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
//Do the Ternary Raster Operation
|
|
344
|
-
var length = destImgData.length //Could be anyone
|
|
345
|
-
var func = wdi.Rop3[rop]
|
|
346
|
-
for (var i = 0; i < length; i += 4) {
|
|
347
|
-
resultData[i] =
|
|
348
|
-
func(patImgData[i], srcImgData[i], destImgData[i]) & 255
|
|
349
|
-
resultData[i + 1] =
|
|
350
|
-
func(patImgData[i + 1], srcImgData[i + 1], destImgData[i + 1]) &
|
|
351
|
-
255
|
|
352
|
-
resultData[i + 2] =
|
|
353
|
-
func(patImgData[i + 2], srcImgData[i + 2], destImgData[i + 2]) &
|
|
354
|
-
255
|
|
355
|
-
resultData[i + 3] = 255
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
tmpcontext.putImageData(result, 0, 0)
|
|
359
|
-
|
|
360
|
-
this.drawClip(tmpcanvas, box, context)
|
|
361
|
-
} else {
|
|
362
|
-
wdi.Debug.log('Unable to get image!')
|
|
363
|
-
}
|
|
364
|
-
},
|
|
365
|
-
this
|
|
366
|
-
)
|
|
367
|
-
},
|
|
368
|
-
|
|
369
|
-
drawInvers: function (spiceMessage) {
|
|
370
|
-
var drawBase = spiceMessage.args.base
|
|
371
|
-
var box = wdi.graphics.getBoxFromSrcArea(drawBase.box)
|
|
372
|
-
|
|
373
|
-
var surface_id = drawBase.surface_id
|
|
374
|
-
|
|
375
|
-
var context = this.clientGui.getContext(surface_id)
|
|
376
|
-
|
|
377
|
-
var destImg = wdi.graphics.getRect(box, context.canvas)
|
|
378
|
-
var imageData = wdi.RasterOperation.process(
|
|
379
|
-
wdi.SpiceRopd.SPICE_ROPD_OP_INVERS,
|
|
380
|
-
null,
|
|
381
|
-
destImg
|
|
382
|
-
) //this operation modifies destination
|
|
383
|
-
|
|
384
|
-
context.drawImage(imageData, box.x, box.y, box.width, box.height)
|
|
385
|
-
},
|
|
386
|
-
|
|
387
|
-
drawStroke: function (spiceMessage) {
|
|
388
|
-
var stroke = spiceMessage.args,
|
|
389
|
-
context = this.clientGui.getContext(spiceMessage.args.base.surface_id),
|
|
390
|
-
color = stroke.brush.color.html_color,
|
|
391
|
-
lineWidth = 1,
|
|
392
|
-
pointsLength,
|
|
393
|
-
firstPoint,
|
|
394
|
-
i,
|
|
395
|
-
j,
|
|
396
|
-
length = stroke.path.num_segments,
|
|
397
|
-
seg
|
|
398
|
-
|
|
399
|
-
if (stroke.attr.flags & wdi.SpiceLineFlags.SPICE_LINE_FLAGS_STYLED) {
|
|
400
|
-
wdi.Debug.log('SPICE_LINE_FLAGS_STYLED')
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
for (var i = 0; i < length; i++) {
|
|
404
|
-
seg = stroke.path.segments[i]
|
|
405
|
-
|
|
406
|
-
if (seg.flags & wdi.SpicePathFlags.SPICE_PATH_BEGIN) {
|
|
407
|
-
context.beginPath()
|
|
408
|
-
context.moveTo(seg.points[0].x, seg.points[0].y)
|
|
409
|
-
context.strokeStyle = color
|
|
410
|
-
context.lineWidth = lineWidth
|
|
411
|
-
}
|
|
412
|
-
if (seg.flags & wdi.SpicePathFlags.SPICE_PATH_BEZIER) {
|
|
413
|
-
pointsLength = seg.points.length
|
|
414
|
-
if (pointsLength % 3 == 0) {
|
|
415
|
-
for (j = 0; j < pointsLength; j += 3) {
|
|
416
|
-
context.bezierCurveTo(
|
|
417
|
-
seg.points[j].x,
|
|
418
|
-
seg.points[j].y,
|
|
419
|
-
seg.points[j + 1].x,
|
|
420
|
-
seg.points[j + 1].y,
|
|
421
|
-
seg.points[j + 2].x,
|
|
422
|
-
seg.points[j + 2].y
|
|
423
|
-
)
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
} else {
|
|
427
|
-
pointsLength = seg.points.length
|
|
428
|
-
|
|
429
|
-
for (j = 0; j < pointsLength; j++) {
|
|
430
|
-
if (j == 0) firstPoint = seg.points[j]
|
|
431
|
-
context.lineTo(
|
|
432
|
-
seg.points[j].x + lineWidth / 2,
|
|
433
|
-
seg.points[j].y + lineWidth / 2
|
|
434
|
-
)
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
if (seg.flags & wdi.SpicePathFlags.SPICE_PATH_END) {
|
|
438
|
-
if (seg.flags & wdi.SpicePathFlags.SPICE_PATH_CLOSE) {
|
|
439
|
-
context.lineTo(
|
|
440
|
-
firstPoint.x + lineWidth / 2,
|
|
441
|
-
firstPoint.y + lineWidth / 2
|
|
442
|
-
)
|
|
443
|
-
}
|
|
444
|
-
context.stroke()
|
|
445
|
-
context.closePath()
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
},
|
|
449
|
-
|
|
450
|
-
drawImage: function (spiceMessage) {
|
|
451
|
-
var args = spiceMessage.args
|
|
452
|
-
var drawBase = args.base
|
|
453
|
-
var surface_id = drawBase.surface_id
|
|
454
|
-
var rop = args.rop_descriptor
|
|
455
|
-
|
|
456
|
-
var scale = args.scale_mode
|
|
457
|
-
|
|
458
|
-
//calculate src_area box
|
|
459
|
-
var box_origin = wdi.graphics.getBoxFromSrcArea(args.src_area)
|
|
460
|
-
|
|
461
|
-
var box_dest = wdi.graphics.getBoxFromSrcArea(drawBase.box)
|
|
462
|
-
|
|
463
|
-
if (window.vdiLoadTest && window.firstImage === undefined) {
|
|
464
|
-
window.firstImage = true
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
//get the image in imagedata format
|
|
468
|
-
wdi.graphics.getImageFromSpice(
|
|
469
|
-
args.image.imageDescriptor,
|
|
470
|
-
args.image.data,
|
|
471
|
-
this.clientGui,
|
|
472
|
-
function (srcImg) {
|
|
473
|
-
//we have image?
|
|
474
|
-
if (srcImg) {
|
|
475
|
-
if (window.firstImage) {
|
|
476
|
-
var data
|
|
477
|
-
if (srcImg.getContext) {
|
|
478
|
-
data = srcImg
|
|
479
|
-
.getContext('2d')
|
|
480
|
-
.getImageData(0, 0, srcImg.width, srcImg.height)
|
|
481
|
-
.data.buffer.slice(0)
|
|
482
|
-
} else {
|
|
483
|
-
data = srcImg.data.buffer.slice(0)
|
|
484
|
-
}
|
|
485
|
-
window.firstImageData = data
|
|
486
|
-
window.firstImage = false
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
var rectangle = false
|
|
490
|
-
|
|
491
|
-
if (
|
|
492
|
-
box_origin.width !== box_dest.width &&
|
|
493
|
-
box_origin.height !== box_dest.height
|
|
494
|
-
) {
|
|
495
|
-
rectangle = true
|
|
496
|
-
srcImg = wdi.graphics.getRect(box_origin, srcImg)
|
|
497
|
-
srcImg = wdi.graphics.getImageFromData(srcImg)
|
|
498
|
-
var newSrcImg = wdi.graphics.getNewTmpCanvas(
|
|
499
|
-
box_dest.width,
|
|
500
|
-
box_dest.height
|
|
501
|
-
)
|
|
502
|
-
var tmpcontext = newSrcImg.getContext('2d')
|
|
503
|
-
tmpcontext.drawImage(
|
|
504
|
-
srcImg,
|
|
505
|
-
0,
|
|
506
|
-
0,
|
|
507
|
-
box_origin.width,
|
|
508
|
-
box_origin.height,
|
|
509
|
-
0,
|
|
510
|
-
0,
|
|
511
|
-
box_dest.width,
|
|
512
|
-
box_dest.height
|
|
513
|
-
)
|
|
514
|
-
srcImg = newSrcImg
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
//depending on the rop, we can avoid to get destImg
|
|
518
|
-
if (rop !== wdi.SpiceRopd.SPICE_ROPD_OP_PUT) {
|
|
519
|
-
//rop
|
|
520
|
-
if (!rectangle) {
|
|
521
|
-
srcImg = wdi.graphics.getRect(box_origin, srcImg)
|
|
522
|
-
}
|
|
523
|
-
var destImg = wdi.graphics.getRect(
|
|
524
|
-
box_dest,
|
|
525
|
-
this.clientGui.getCanvas(surface_id)
|
|
526
|
-
)
|
|
527
|
-
srcImg = wdi.RasterOperation.process(rop, srcImg, destImg)
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
var context = this.clientGui.getContext(surface_id)
|
|
531
|
-
|
|
532
|
-
if (srcImg instanceof ImageData) {
|
|
533
|
-
if (rectangle) {
|
|
534
|
-
//a subrectangle has been created, use it
|
|
535
|
-
context.putImageData(
|
|
536
|
-
srcImg,
|
|
537
|
-
box_dest.x,
|
|
538
|
-
box_dest.y,
|
|
539
|
-
0,
|
|
540
|
-
0,
|
|
541
|
-
box_dest.width,
|
|
542
|
-
box_dest.height
|
|
543
|
-
)
|
|
544
|
-
} else {
|
|
545
|
-
context.putImageData(
|
|
546
|
-
srcImg,
|
|
547
|
-
box_dest.x,
|
|
548
|
-
box_dest.y,
|
|
549
|
-
box_origin.x,
|
|
550
|
-
box_origin.y,
|
|
551
|
-
box_origin.width,
|
|
552
|
-
box_origin.height
|
|
553
|
-
)
|
|
554
|
-
}
|
|
555
|
-
} else {
|
|
556
|
-
if (rectangle) {
|
|
557
|
-
context.drawImage(
|
|
558
|
-
srcImg,
|
|
559
|
-
box_dest.x,
|
|
560
|
-
box_dest.y,
|
|
561
|
-
box_dest.width,
|
|
562
|
-
box_dest.height
|
|
563
|
-
)
|
|
564
|
-
} else {
|
|
565
|
-
context.drawImage(
|
|
566
|
-
srcImg,
|
|
567
|
-
box_origin.x,
|
|
568
|
-
box_origin.y,
|
|
569
|
-
box_origin.width,
|
|
570
|
-
box_origin.height,
|
|
571
|
-
box_dest.x,
|
|
572
|
-
box_dest.y,
|
|
573
|
-
box_dest.width,
|
|
574
|
-
box_dest.height
|
|
575
|
-
)
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
} else {
|
|
579
|
-
//failed to get image, cache error?
|
|
580
|
-
wdi.Debug.log('Unable to get image!')
|
|
581
|
-
}
|
|
582
|
-
},
|
|
583
|
-
this,
|
|
584
|
-
{ opaque: true, brush: args.brush, raw: false }
|
|
585
|
-
)
|
|
586
|
-
},
|
|
587
|
-
|
|
588
|
-
drawClip: function (srcImg, box, context) {
|
|
589
|
-
context.drawImage(srcImg, box.x, box.y, box.width, box.height)
|
|
590
|
-
},
|
|
591
|
-
|
|
592
|
-
drawFill: function (spiceMessage) {
|
|
593
|
-
var args = spiceMessage.args
|
|
594
|
-
var context = this.clientGui.getContext(args.base.surface_id)
|
|
595
|
-
var box = wdi.graphics.getBoxFromSrcArea(args.base.box)
|
|
596
|
-
var brush = args.brush
|
|
597
|
-
var ropd = args.rop_descriptor
|
|
598
|
-
|
|
599
|
-
wdi.graphics.setBrush(this.clientGui, context, brush, box, ropd)
|
|
600
|
-
},
|
|
601
|
-
|
|
602
|
-
drawCopyBits: function (spiceMessage) {
|
|
603
|
-
var drawBase = spiceMessage.args.base
|
|
604
|
-
var surface_id = drawBase.surface_id
|
|
605
|
-
var src_position = spiceMessage.args.src_position
|
|
606
|
-
var context = this.clientGui.getContext(surface_id)
|
|
607
|
-
var box = drawBase.box
|
|
608
|
-
|
|
609
|
-
var width = box.right - box.left
|
|
610
|
-
var height = box.bottom - box.top
|
|
611
|
-
|
|
612
|
-
context.drawImage(
|
|
613
|
-
context.canvas,
|
|
614
|
-
src_position.x,
|
|
615
|
-
src_position.y,
|
|
616
|
-
width,
|
|
617
|
-
height,
|
|
618
|
-
drawBase.box.left,
|
|
619
|
-
drawBase.box.top,
|
|
620
|
-
width,
|
|
621
|
-
height
|
|
622
|
-
)
|
|
623
|
-
},
|
|
624
|
-
|
|
625
|
-
drawBlend: function (spiceMessage) {
|
|
626
|
-
//TODO: alpha_flags
|
|
627
|
-
//TODO: resize
|
|
628
|
-
var descriptor = spiceMessage.args.image.imageDescriptor
|
|
629
|
-
var drawBase = spiceMessage.args.base
|
|
630
|
-
var imgData = spiceMessage.args.image.data
|
|
631
|
-
var surface_id = spiceMessage.args.base.surface_id
|
|
632
|
-
var rop_desc = spiceMessage.args.rop_descriptor
|
|
633
|
-
var flags = spiceMessage.args.flags
|
|
634
|
-
|
|
635
|
-
wdi.graphics.getImageFromSpice(
|
|
636
|
-
descriptor,
|
|
637
|
-
imgData,
|
|
638
|
-
this.clientGui,
|
|
639
|
-
function (srcImg) {
|
|
640
|
-
if (!srcImg) {
|
|
641
|
-
wdi.Debug.log('There is no image on Blend')
|
|
642
|
-
return
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
//get box from src area
|
|
646
|
-
var box = wdi.graphics.getBoxFromSrcArea(spiceMessage.args.src_area)
|
|
647
|
-
|
|
648
|
-
//adapt to src_area
|
|
649
|
-
srcImg = wdi.graphics.getRect(box, srcImg)
|
|
650
|
-
|
|
651
|
-
//destination box
|
|
652
|
-
var dest_box = wdi.graphics.getBoxFromSrcArea(drawBase.box)
|
|
653
|
-
var destImg = wdi.graphics.getRect(
|
|
654
|
-
dest_box,
|
|
655
|
-
this.clientGui.getCanvas(surface_id)
|
|
656
|
-
)
|
|
657
|
-
|
|
658
|
-
var result = wdi.RasterOperation.process(rop_desc, srcImg, destImg)
|
|
659
|
-
|
|
660
|
-
this.clientGui
|
|
661
|
-
.getCanvas(surface_id)
|
|
662
|
-
.getContext('2d')
|
|
663
|
-
.drawImage(
|
|
664
|
-
result,
|
|
665
|
-
dest_box.x,
|
|
666
|
-
dest_box.y,
|
|
667
|
-
dest_box.width,
|
|
668
|
-
dest_box.height
|
|
669
|
-
)
|
|
670
|
-
},
|
|
671
|
-
this
|
|
672
|
-
)
|
|
673
|
-
},
|
|
674
|
-
|
|
675
|
-
drawAlphaBlend: function (spiceMessage) {
|
|
676
|
-
//TODO: alpha_flags
|
|
677
|
-
//TODO: resize
|
|
678
|
-
|
|
679
|
-
var descriptor = spiceMessage.args.image.imageDescriptor
|
|
680
|
-
var drawBase = spiceMessage.args.base
|
|
681
|
-
var imgData = spiceMessage.args.image.data
|
|
682
|
-
var surface_id = spiceMessage.args.base.surface_id
|
|
683
|
-
var flags = spiceMessage.args.alpha_flags
|
|
684
|
-
var alpha = spiceMessage.args.alpha
|
|
685
|
-
|
|
686
|
-
wdi.graphics.getImageFromSpice(
|
|
687
|
-
descriptor,
|
|
688
|
-
imgData,
|
|
689
|
-
this.clientGui,
|
|
690
|
-
function (srcImg) {
|
|
691
|
-
if (!srcImg) {
|
|
692
|
-
wdi.Debug.log('There is no image on drawAlphaBlend')
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
var box = wdi.graphics.getBoxFromSrcArea(spiceMessage.args.src_area)
|
|
696
|
-
|
|
697
|
-
//adapt to src_area
|
|
698
|
-
srcImg = wdi.graphics.getRect(box, srcImg)
|
|
699
|
-
|
|
700
|
-
//destination box
|
|
701
|
-
var box_dest = wdi.graphics.getBoxFromSrcArea(drawBase.box)
|
|
702
|
-
var destImg = wdi.graphics.getRect(
|
|
703
|
-
box_dest,
|
|
704
|
-
this.clientGui.getCanvas(surface_id)
|
|
705
|
-
)
|
|
706
|
-
|
|
707
|
-
if (box.width !== box_dest.width && box.height !== box_dest.height) {
|
|
708
|
-
var tmpcanvas = wdi.graphics.getNewTmpCanvas(
|
|
709
|
-
box_dest.width,
|
|
710
|
-
box_dest.height
|
|
711
|
-
)
|
|
712
|
-
var tmpcontext = tmpcanvas.getContext('2d')
|
|
713
|
-
tmpcontext.drawImage(
|
|
714
|
-
srcImg,
|
|
715
|
-
0,
|
|
716
|
-
0,
|
|
717
|
-
box.width,
|
|
718
|
-
box.height,
|
|
719
|
-
0,
|
|
720
|
-
0,
|
|
721
|
-
box_dest.width,
|
|
722
|
-
box_dest.height
|
|
723
|
-
)
|
|
724
|
-
srcImg = tmpcanvas
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
var src = wdi.graphics.getDataFromImage(srcImg).data
|
|
728
|
-
var dst = wdi.graphics.getDataFromImage(destImg).data
|
|
729
|
-
|
|
730
|
-
var length = src.length - 1
|
|
731
|
-
|
|
732
|
-
//create a new imagedata to store result
|
|
733
|
-
var imageResult = wdi.graphics.getNewTmpCanvas(
|
|
734
|
-
box_dest.width,
|
|
735
|
-
box_dest.height
|
|
736
|
-
)
|
|
737
|
-
var context = imageResult.getContext('2d')
|
|
738
|
-
|
|
739
|
-
var resultImageData = context.createImageData(
|
|
740
|
-
box_dest.width,
|
|
741
|
-
box_dest.height
|
|
742
|
-
)
|
|
743
|
-
var result = resultImageData.data
|
|
744
|
-
|
|
745
|
-
var rS, rD
|
|
746
|
-
var gS, gD
|
|
747
|
-
var bS, bD
|
|
748
|
-
var aS
|
|
749
|
-
|
|
750
|
-
for (var px = 0; px < length; px += 4) {
|
|
751
|
-
rS = src[px]
|
|
752
|
-
gS = src[px + 1]
|
|
753
|
-
bS = src[px + 2]
|
|
754
|
-
|
|
755
|
-
if (flags || alpha === 255) {
|
|
756
|
-
aS = src[px + 3]
|
|
757
|
-
} else {
|
|
758
|
-
aS = alpha
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
rD = dst[px]
|
|
762
|
-
gD = dst[px + 1]
|
|
763
|
-
bD = dst[px + 2]
|
|
764
|
-
|
|
765
|
-
if (aS > 30 && alpha === 255) {
|
|
766
|
-
//formula from reactos, this is premultiplied alpha values
|
|
767
|
-
result[px] = ((rD * (255 - aS)) / 255 + rS) & 0xff
|
|
768
|
-
result[px + 1] = ((gD * (255 - aS)) / 255 + gS) & 0xff
|
|
769
|
-
result[px + 2] = ((bD * (255 - aS)) / 255 + bS) & 0xff
|
|
770
|
-
} else {
|
|
771
|
-
//homemade blend function, this is the typical blend function simplified
|
|
772
|
-
result[px] = ((rS * aS + rD * (255 - aS)) / 255) & 0xff
|
|
773
|
-
result[px + 1] = ((gS * aS + gD * (255 - aS)) / 255) & 0xff
|
|
774
|
-
result[px + 2] = ((bS * aS + bD * (255 - aS)) / 255) & 0xff
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
result[px + 3] = 255
|
|
778
|
-
}
|
|
779
|
-
imageResult.getContext('2d').putImageData(resultImageData, 0, 0)
|
|
780
|
-
|
|
781
|
-
this.drawClip(
|
|
782
|
-
imageResult,
|
|
783
|
-
box_dest,
|
|
784
|
-
this.clientGui.getContext(surface_id)
|
|
785
|
-
)
|
|
786
|
-
},
|
|
787
|
-
this
|
|
788
|
-
)
|
|
789
|
-
},
|
|
790
|
-
|
|
791
|
-
drawWhiteness: function (spiceMessage) {
|
|
792
|
-
//TODO: mask
|
|
793
|
-
var base = spiceMessage.args.base
|
|
794
|
-
var context = this.clientGui.getContext(base.surface_id)
|
|
795
|
-
var box = wdi.graphics.getBoxFromSrcArea(base.box)
|
|
796
|
-
context.fillStyle = 'white'
|
|
797
|
-
context.fillRect(box.x, box.y, box.width, box.height)
|
|
798
|
-
},
|
|
799
|
-
|
|
800
|
-
drawBlackness: function (spiceMessage) {
|
|
801
|
-
//TODO: mask
|
|
802
|
-
var base = spiceMessage.args.base
|
|
803
|
-
var context = this.clientGui.getContext(base.surface_id)
|
|
804
|
-
var box = wdi.graphics.getBoxFromSrcArea(base.box)
|
|
805
|
-
context.fillStyle = 'black'
|
|
806
|
-
context.fillRect(box.x, box.y, box.width, box.height)
|
|
807
|
-
},
|
|
808
|
-
|
|
809
|
-
drawTransparent: function (spiceMessage) {
|
|
810
|
-
var drawBase = spiceMessage.args.base
|
|
811
|
-
var surface_id = drawBase.surface_id
|
|
812
|
-
|
|
813
|
-
//calculate src_area box
|
|
814
|
-
var box = wdi.graphics.getBoxFromSrcArea(spiceMessage.args.src_area)
|
|
815
|
-
var dest_box = wdi.graphics.getBoxFromSrcArea(drawBase.box)
|
|
816
|
-
|
|
817
|
-
//get destination iamge, in imagedata format because is what we need
|
|
818
|
-
var destImg = this.clientGui
|
|
819
|
-
.getContext(surface_id)
|
|
820
|
-
.getImageData(dest_box.x, dest_box.y, dest_box.width, dest_box.height)
|
|
821
|
-
|
|
822
|
-
wdi.graphics.getImageFromSpice(
|
|
823
|
-
spiceMessage.args.image.imageDescriptor,
|
|
824
|
-
spiceMessage.args.image.data,
|
|
825
|
-
this.clientGui,
|
|
826
|
-
function (srcImg) {
|
|
827
|
-
if (srcImg) {
|
|
828
|
-
//adapt to src_area
|
|
829
|
-
srcImg = wdi.graphics.getRect(box, srcImg)
|
|
830
|
-
|
|
831
|
-
var source = wdi.graphics.getDataFromImage(srcImg).data
|
|
832
|
-
var dest = destImg.data
|
|
833
|
-
|
|
834
|
-
var length = source.length - 1
|
|
835
|
-
var resultImageData = this.clientGui
|
|
836
|
-
.getContext(surface_id)
|
|
837
|
-
.createImageData(dest_box.width, dest_box.height)
|
|
838
|
-
|
|
839
|
-
var color = spiceMessage.args.transparent_true_color
|
|
840
|
-
while (length > 0) {
|
|
841
|
-
resultImageData.data[length] = 255 //alpha
|
|
842
|
-
if (
|
|
843
|
-
source[length - 1] === color.b &&
|
|
844
|
-
source[length - 2] === color.g &&
|
|
845
|
-
source[length - 3] === color.r
|
|
846
|
-
) {
|
|
847
|
-
resultImageData.data[length - 1] = dest[length - 1] //b
|
|
848
|
-
resultImageData.data[length - 2] = dest[length - 2] //g
|
|
849
|
-
resultImageData.data[length - 3] = dest[length - 3] //r
|
|
850
|
-
} else {
|
|
851
|
-
resultImageData.data[length - 1] = source[length - 1] //b
|
|
852
|
-
resultImageData.data[length - 2] = source[length - 2] //g
|
|
853
|
-
resultImageData.data[length - 3] = source[length - 3] //r
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
length -= 4
|
|
857
|
-
}
|
|
858
|
-
var resultImage = wdi.graphics.getImageFromData(resultImageData)
|
|
859
|
-
this.drawClip(
|
|
860
|
-
resultImage,
|
|
861
|
-
dest_box,
|
|
862
|
-
this.clientGui.getContext(surface_id)
|
|
863
|
-
)
|
|
864
|
-
} else {
|
|
865
|
-
//failed to get image, cache error?
|
|
866
|
-
wdi.Debug.log('Unable to get image!')
|
|
867
|
-
}
|
|
868
|
-
},
|
|
869
|
-
this
|
|
870
|
-
)
|
|
871
|
-
},
|
|
872
|
-
|
|
873
|
-
drawText: function (spiceMessage) {
|
|
874
|
-
var context = this.clientGui.getContext(spiceMessage.args.base.surface_id)
|
|
875
|
-
var bbox = spiceMessage.args.base.box
|
|
876
|
-
var clip = spiceMessage.args.base.clip
|
|
877
|
-
var text = spiceMessage.args
|
|
878
|
-
var string = text.glyph_string
|
|
879
|
-
var bpp = string.flags === 1 ? 1 : string.flags * 2
|
|
880
|
-
|
|
881
|
-
if (text.back_mode !== 0) {
|
|
882
|
-
wdi.graphics.drawBackText(this.clientGui, context, text)
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
wdi.graphics.drawString(
|
|
886
|
-
context,
|
|
887
|
-
string,
|
|
888
|
-
bpp,
|
|
889
|
-
text.fore_brush,
|
|
890
|
-
clip.type,
|
|
891
|
-
this
|
|
892
|
-
)
|
|
893
|
-
},
|
|
894
|
-
|
|
895
|
-
/**
|
|
896
|
-
* Clears all color palettes
|
|
897
|
-
* @param spiceMessage
|
|
898
|
-
* @param app
|
|
899
|
-
*/
|
|
900
|
-
invalPalettes: function (spiceMessage) {
|
|
901
|
-
wdi.ImageCache.clearPalettes()
|
|
902
|
-
},
|
|
903
|
-
|
|
904
|
-
handleReset: function (spiceMessage) {
|
|
905
|
-
// console.log(spiceMessage, 222);
|
|
906
|
-
},
|
|
907
|
-
})
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2016 eyeOS
|
|
3
|
+
|
|
4
|
+
This file is part of Open365.
|
|
5
|
+
|
|
6
|
+
Open365 is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU Affero General Public License as
|
|
8
|
+
published by the Free Software Foundation, either version 3 of the
|
|
9
|
+
License, or (at your option) any later version.
|
|
10
|
+
|
|
11
|
+
This program is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU Affero General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU Affero General Public License
|
|
17
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
wdi.RasterEngine = $.spcExtend(wdi.EventObject.prototype, {
|
|
21
|
+
init: function (c) {
|
|
22
|
+
this.time = Date.now()
|
|
23
|
+
this.clientGui = c.clientGui
|
|
24
|
+
|
|
25
|
+
// h264
|
|
26
|
+
this.codecH264 = wdi.CodecH264
|
|
27
|
+
|
|
28
|
+
// vp8
|
|
29
|
+
this.codecVp8 = wdi.CodecVp8
|
|
30
|
+
|
|
31
|
+
// vp9
|
|
32
|
+
// this.videoDecoderVp9 = {}
|
|
33
|
+
|
|
34
|
+
// h265
|
|
35
|
+
this.codecH265 = wdi.CodecH265
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
dispose: function () {
|
|
39
|
+
this.clientGui = null
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
drawCanvas: function (spiceMessage) {
|
|
43
|
+
wdi.Debug.log('rasterEngine', this.time)
|
|
44
|
+
return this.clientGui.drawCanvas(spiceMessage)
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
removeCanvas: function (spiceMessage) {
|
|
48
|
+
return this.clientGui.removeCanvas(spiceMessage)
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
invalList: function (spiceMessage) {
|
|
52
|
+
var items = spiceMessage.args.items
|
|
53
|
+
var item = null
|
|
54
|
+
for (var i in items) {
|
|
55
|
+
item = items[i]
|
|
56
|
+
wdi.ImageCache.delImage(item.id)
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
handleStreamCreate: function (spiceMessage) {
|
|
61
|
+
var stream = spiceMessage.args
|
|
62
|
+
stream.computedBox = wdi.graphics.getBoxFromSrcArea(stream.rect)
|
|
63
|
+
wdi.Stream.addStream(spiceMessage.args.id, stream)
|
|
64
|
+
|
|
65
|
+
console.log('%chandleStreamCreate', 'color:rgb(100,255,100)')
|
|
66
|
+
switch (stream.codec) {
|
|
67
|
+
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_H264:
|
|
68
|
+
this.handleH264StreamCreate(stream.id)
|
|
69
|
+
break
|
|
70
|
+
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_VP8:
|
|
71
|
+
this.handleVp8StreamCreate(stream.id)
|
|
72
|
+
break
|
|
73
|
+
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_VP9:
|
|
74
|
+
break
|
|
75
|
+
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_H265:
|
|
76
|
+
this.handleH265StreamCreate(stream.id)
|
|
77
|
+
break
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (wdi.graphicDebug) {
|
|
81
|
+
wdi.graphicDebug.handleStreamInfo()
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
handleVp8StreamCreate: function (streamId) {
|
|
86
|
+
this.codecVp8.create(streamId)
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
handleH265StreamCreate: async function (streamId) {
|
|
90
|
+
const stream = wdi.Stream.getStream(streamId)
|
|
91
|
+
const context = this.clientGui.getContext(stream.surface_id)
|
|
92
|
+
const box = stream.computedBox
|
|
93
|
+
|
|
94
|
+
this.codecH265.create(streamId, context, box)
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
handleH264StreamCreate: function (streamId) {
|
|
98
|
+
this.codecH264.create(streamId)
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
handleStreamData: function (spiceMessage) {
|
|
102
|
+
var stream = wdi.Stream.getStream(spiceMessage.args.id)
|
|
103
|
+
switch (stream.codec) {
|
|
104
|
+
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_H264:
|
|
105
|
+
this.handleH264Stream(spiceMessage)
|
|
106
|
+
break
|
|
107
|
+
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_VP8:
|
|
108
|
+
this.handleVp8Stream(spiceMessage)
|
|
109
|
+
break
|
|
110
|
+
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_VP9:
|
|
111
|
+
break
|
|
112
|
+
case wdi.SpiceVideoCodecType.SPICE_VIDEO_CODEC_TYPE_H265:
|
|
113
|
+
this.handleH265Stream(spiceMessage)
|
|
114
|
+
break
|
|
115
|
+
default:
|
|
116
|
+
this.handleMjpegStream(spiceMessage)
|
|
117
|
+
break
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
handleStreamClip: function (spiceMessage) {
|
|
122
|
+
wdi.Stream.clip(spiceMessage.args.id, spiceMessage.args.clip)
|
|
123
|
+
wdi.Stream.startTransition(spiceMessage.args.id)
|
|
124
|
+
console.log('%chandleStreamClip', 'color:rgb(100,100,255)')
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
handleStreamDataSized: function (spiceMessage) {
|
|
128
|
+
// console.log(spiceMessage, 'handleStreamDataSized');
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
handleStreamActiveReport: function (spiceMessage) {
|
|
132
|
+
// console.log(spiceMessage, 'handleStreamActiveReport');
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
handleStreamDestroy: function (spiceMessage) {
|
|
136
|
+
wdi.Stream.deleteStream(spiceMessage.args.surface_id)
|
|
137
|
+
|
|
138
|
+
// Destroy H264
|
|
139
|
+
this.codecH264.destroy(spiceMessage.args.surface_id)
|
|
140
|
+
|
|
141
|
+
// Destroy VP8
|
|
142
|
+
this.codecVp8.destroy()
|
|
143
|
+
|
|
144
|
+
// h265
|
|
145
|
+
this.codecH265.destroy()
|
|
146
|
+
|
|
147
|
+
if (wdi.graphicDebug) {
|
|
148
|
+
wdi.graphicDebug.handleStreamInfo()
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
console.log('%chandleStreamDestroy', 'color:rgb(255,100,100)')
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
handleMjpegStream: function (spiceMessage) {
|
|
155
|
+
var imageData = spiceMessage.args.data //jpeg string encoded
|
|
156
|
+
var stream = wdi.Stream.getStream(spiceMessage.args.id) //recover the stream
|
|
157
|
+
var context = this.clientGui.getContext(stream.surface_id)
|
|
158
|
+
var img = wdi.GlobalPool.create('Image') //auto-release pool
|
|
159
|
+
wdi.ExecutionControl.sync = true
|
|
160
|
+
var url
|
|
161
|
+
img.onload = function () {
|
|
162
|
+
URL.revokeObjectURL(url)
|
|
163
|
+
var box = stream.computedBox
|
|
164
|
+
// we only rotate the stream if spice tells us so through the TOP_DOWN flag mask
|
|
165
|
+
if (!stream.flags & wdi.SpiceStreamFlags.SPICE_STREAM_FLAGS_TOP_DOWN) {
|
|
166
|
+
var offsetX = box.x + this.width / 2
|
|
167
|
+
var offsetY = box.y + this.height / 2
|
|
168
|
+
context.save()
|
|
169
|
+
context.translate(offsetX, offsetY)
|
|
170
|
+
context.rotate(Math.PI)
|
|
171
|
+
context.scale(-1, 1)
|
|
172
|
+
context.drawImage(
|
|
173
|
+
this,
|
|
174
|
+
box.x - offsetX,
|
|
175
|
+
box.y - offsetY,
|
|
176
|
+
box.width,
|
|
177
|
+
box.height
|
|
178
|
+
)
|
|
179
|
+
context.restore()
|
|
180
|
+
} else {
|
|
181
|
+
context.drawImage(this, box.x, box.y, box.width, box.height)
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
img.onerror = function () {
|
|
186
|
+
URL.revokeObjectURL(url)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
url = wdi.SpiceObject.bytesToURI(imageData)
|
|
190
|
+
img.src = url
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
handleH264Stream: function (spiceMessage) {
|
|
194
|
+
var imageData = spiceMessage.args.data
|
|
195
|
+
var stream = wdi.Stream.getStream(spiceMessage.args.id) //recover the stream
|
|
196
|
+
|
|
197
|
+
// Был баг, который не запускал стрим
|
|
198
|
+
// это условие помогло
|
|
199
|
+
if (!this.codecH264.isReady[stream.id]) {
|
|
200
|
+
this.codecH264.addQueue(stream.id, imageData)
|
|
201
|
+
return
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
var context = this.clientGui.getContext(stream.surface_id)
|
|
205
|
+
wdi.ExecutionControl.sync = true
|
|
206
|
+
wdi.Stream.endTransition(spiceMessage.args.id)
|
|
207
|
+
|
|
208
|
+
this.codecH264.loadedVideo[stream.id] = () => {
|
|
209
|
+
var box = stream.computedBox
|
|
210
|
+
// we only rotate the stream if spice tells us so through the TOP_DOWN flag mask
|
|
211
|
+
if (!stream.flags & wdi.SpiceStreamFlags.SPICE_STREAM_FLAGS_TOP_DOWN) {
|
|
212
|
+
var offsetX = box.x + this.codecH264.video[stream.id].width / 2
|
|
213
|
+
var offsetY = box.y + this.codecH264.video[stream.id].height / 2
|
|
214
|
+
context.save()
|
|
215
|
+
context.translate(offsetX, offsetY)
|
|
216
|
+
context.rotate(Math.PI)
|
|
217
|
+
context.scale(-1, 1)
|
|
218
|
+
context.drawImage(
|
|
219
|
+
this.codecH264.video[stream.id],
|
|
220
|
+
box.x - offsetX,
|
|
221
|
+
box.y - offsetY,
|
|
222
|
+
box.width,
|
|
223
|
+
box.height
|
|
224
|
+
)
|
|
225
|
+
context.restore()
|
|
226
|
+
} else {
|
|
227
|
+
if (
|
|
228
|
+
!this.codecH264.video[stream.id] ||
|
|
229
|
+
!this.codecH264.loadedVideo[stream.id]
|
|
230
|
+
)
|
|
231
|
+
return
|
|
232
|
+
if (stream.transiting) {
|
|
233
|
+
requestAnimationFrame(this.codecH264.loadedVideo[stream.id])
|
|
234
|
+
return
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
context.drawImage(
|
|
238
|
+
this.codecH264.video[stream.id],
|
|
239
|
+
box.x,
|
|
240
|
+
box.y,
|
|
241
|
+
box.width,
|
|
242
|
+
box.height
|
|
243
|
+
)
|
|
244
|
+
requestAnimationFrame(this.codecH264.loadedVideo[stream.id])
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
this.codecH264.feed(stream.id, imageData)
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
handleH265Stream: function (spiceMessage) {
|
|
252
|
+
const imageData = spiceMessage.args.data
|
|
253
|
+
const stream = wdi.Stream.getStream(spiceMessage.args.id)
|
|
254
|
+
const box = stream.computedBox
|
|
255
|
+
|
|
256
|
+
// Так как метод handleH265StreamCreate ан синхронный и ждет пока сделается проверка поддерживает ли браузер VideoDecoder,
|
|
257
|
+
// некоторые кадры могут быть упущены, их нужно хранить т.к. в них есть ключевые кадры
|
|
258
|
+
if (!this.codecH265.isReady[stream.id]) {
|
|
259
|
+
this.codecH265.addQueue(stream.id, imageData)
|
|
260
|
+
return
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (!this.codecH265.configed[stream.id]) {
|
|
264
|
+
this.codecH265.setConfig(stream.id, box)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
this.codecH265.decode(stream.id, imageData)
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
handleVp8Stream: function (spiceMessage) {
|
|
271
|
+
var imageData = spiceMessage.args.data
|
|
272
|
+
var stream = wdi.Stream.getStream(spiceMessage.args.id)
|
|
273
|
+
var context = this.clientGui.getContext(stream.surface_id)
|
|
274
|
+
var box = stream.computedBox
|
|
275
|
+
|
|
276
|
+
this.codecVp8.feed(stream.id, imageData, context, box)
|
|
277
|
+
},
|
|
278
|
+
|
|
279
|
+
drawRop3: function (spiceMessage) {
|
|
280
|
+
var box = wdi.graphics.getBoxFromSrcArea(spiceMessage.args.base.box)
|
|
281
|
+
var context = this.clientGui.getContext(spiceMessage.args.base.surface_id)
|
|
282
|
+
var destImg = context.getImageData(box.x, box.y, box.width, box.height)
|
|
283
|
+
var clientGui = this.clientGui
|
|
284
|
+
|
|
285
|
+
var brush = spiceMessage.args.brush
|
|
286
|
+
var rop = spiceMessage.args.rop_descriptor
|
|
287
|
+
|
|
288
|
+
var srcArea = wdi.graphics.getBoxFromSrcArea(spiceMessage.args.src_area)
|
|
289
|
+
wdi.graphics.getImageFromSpice(
|
|
290
|
+
spiceMessage.args.src_image.imageDescriptor,
|
|
291
|
+
spiceMessage.args.src_image.data,
|
|
292
|
+
this.clientGui,
|
|
293
|
+
function (sourceCanvas) {
|
|
294
|
+
if (sourceCanvas) {
|
|
295
|
+
//Get source image data (image coming from the packet)
|
|
296
|
+
var sourceContext = sourceCanvas.getContext('2d')
|
|
297
|
+
var srcImg = sourceContext.getImageData(
|
|
298
|
+
srcArea.x,
|
|
299
|
+
srcArea.y,
|
|
300
|
+
srcArea.width,
|
|
301
|
+
srcArea.height
|
|
302
|
+
)
|
|
303
|
+
var srcImgData = srcImg.data //this
|
|
304
|
+
|
|
305
|
+
//Get pattern image data
|
|
306
|
+
//brush
|
|
307
|
+
var tmpcanvas = wdi.graphics.getNewTmpCanvas(box.width, box.height)
|
|
308
|
+
var tmpcontext = tmpcanvas.getContext('2d')
|
|
309
|
+
var brushBox = {
|
|
310
|
+
width: box.width,
|
|
311
|
+
height: box.height,
|
|
312
|
+
x: 0,
|
|
313
|
+
y: 0,
|
|
314
|
+
}
|
|
315
|
+
wdi.graphics.setBrush(
|
|
316
|
+
clientGui,
|
|
317
|
+
tmpcontext,
|
|
318
|
+
brush,
|
|
319
|
+
brushBox,
|
|
320
|
+
wdi.SpiceRopd.SPICE_ROPD_OP_PUT
|
|
321
|
+
) //Without alpha?
|
|
322
|
+
var pattern = tmpcontext.getImageData(0, 0, box.width, box.height)
|
|
323
|
+
var patImgData = pattern.data //this
|
|
324
|
+
|
|
325
|
+
//Get dest image data
|
|
326
|
+
var destImgData = destImg.data
|
|
327
|
+
|
|
328
|
+
//Get result image data
|
|
329
|
+
tmpcanvas = wdi.graphics.getNewTmpCanvas(box.width, box.height)
|
|
330
|
+
tmpcontext = tmpcanvas.getContext('2d')
|
|
331
|
+
var result = tmpcontext.createImageData(box.width, box.height)
|
|
332
|
+
var resultData = result.data
|
|
333
|
+
|
|
334
|
+
if (
|
|
335
|
+
srcImg.width != pattern.width ||
|
|
336
|
+
srcImg.width != destImg.width ||
|
|
337
|
+
srcImg.height != pattern.height ||
|
|
338
|
+
srcImg.height != destImg.height
|
|
339
|
+
) {
|
|
340
|
+
//TODO: resize
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
//Do the Ternary Raster Operation
|
|
344
|
+
var length = destImgData.length //Could be anyone
|
|
345
|
+
var func = wdi.Rop3[rop]
|
|
346
|
+
for (var i = 0; i < length; i += 4) {
|
|
347
|
+
resultData[i] =
|
|
348
|
+
func(patImgData[i], srcImgData[i], destImgData[i]) & 255
|
|
349
|
+
resultData[i + 1] =
|
|
350
|
+
func(patImgData[i + 1], srcImgData[i + 1], destImgData[i + 1]) &
|
|
351
|
+
255
|
|
352
|
+
resultData[i + 2] =
|
|
353
|
+
func(patImgData[i + 2], srcImgData[i + 2], destImgData[i + 2]) &
|
|
354
|
+
255
|
|
355
|
+
resultData[i + 3] = 255
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
tmpcontext.putImageData(result, 0, 0)
|
|
359
|
+
|
|
360
|
+
this.drawClip(tmpcanvas, box, context)
|
|
361
|
+
} else {
|
|
362
|
+
wdi.Debug.log('Unable to get image!')
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
this
|
|
366
|
+
)
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
drawInvers: function (spiceMessage) {
|
|
370
|
+
var drawBase = spiceMessage.args.base
|
|
371
|
+
var box = wdi.graphics.getBoxFromSrcArea(drawBase.box)
|
|
372
|
+
|
|
373
|
+
var surface_id = drawBase.surface_id
|
|
374
|
+
|
|
375
|
+
var context = this.clientGui.getContext(surface_id)
|
|
376
|
+
|
|
377
|
+
var destImg = wdi.graphics.getRect(box, context.canvas)
|
|
378
|
+
var imageData = wdi.RasterOperation.process(
|
|
379
|
+
wdi.SpiceRopd.SPICE_ROPD_OP_INVERS,
|
|
380
|
+
null,
|
|
381
|
+
destImg
|
|
382
|
+
) //this operation modifies destination
|
|
383
|
+
|
|
384
|
+
context.drawImage(imageData, box.x, box.y, box.width, box.height)
|
|
385
|
+
},
|
|
386
|
+
|
|
387
|
+
drawStroke: function (spiceMessage) {
|
|
388
|
+
var stroke = spiceMessage.args,
|
|
389
|
+
context = this.clientGui.getContext(spiceMessage.args.base.surface_id),
|
|
390
|
+
color = stroke.brush.color.html_color,
|
|
391
|
+
lineWidth = 1,
|
|
392
|
+
pointsLength,
|
|
393
|
+
firstPoint,
|
|
394
|
+
i,
|
|
395
|
+
j,
|
|
396
|
+
length = stroke.path.num_segments,
|
|
397
|
+
seg
|
|
398
|
+
|
|
399
|
+
if (stroke.attr.flags & wdi.SpiceLineFlags.SPICE_LINE_FLAGS_STYLED) {
|
|
400
|
+
wdi.Debug.log('SPICE_LINE_FLAGS_STYLED')
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
for (var i = 0; i < length; i++) {
|
|
404
|
+
seg = stroke.path.segments[i]
|
|
405
|
+
|
|
406
|
+
if (seg.flags & wdi.SpicePathFlags.SPICE_PATH_BEGIN) {
|
|
407
|
+
context.beginPath()
|
|
408
|
+
context.moveTo(seg.points[0].x, seg.points[0].y)
|
|
409
|
+
context.strokeStyle = color
|
|
410
|
+
context.lineWidth = lineWidth
|
|
411
|
+
}
|
|
412
|
+
if (seg.flags & wdi.SpicePathFlags.SPICE_PATH_BEZIER) {
|
|
413
|
+
pointsLength = seg.points.length
|
|
414
|
+
if (pointsLength % 3 == 0) {
|
|
415
|
+
for (j = 0; j < pointsLength; j += 3) {
|
|
416
|
+
context.bezierCurveTo(
|
|
417
|
+
seg.points[j].x,
|
|
418
|
+
seg.points[j].y,
|
|
419
|
+
seg.points[j + 1].x,
|
|
420
|
+
seg.points[j + 1].y,
|
|
421
|
+
seg.points[j + 2].x,
|
|
422
|
+
seg.points[j + 2].y
|
|
423
|
+
)
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
} else {
|
|
427
|
+
pointsLength = seg.points.length
|
|
428
|
+
|
|
429
|
+
for (j = 0; j < pointsLength; j++) {
|
|
430
|
+
if (j == 0) firstPoint = seg.points[j]
|
|
431
|
+
context.lineTo(
|
|
432
|
+
seg.points[j].x + lineWidth / 2,
|
|
433
|
+
seg.points[j].y + lineWidth / 2
|
|
434
|
+
)
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
if (seg.flags & wdi.SpicePathFlags.SPICE_PATH_END) {
|
|
438
|
+
if (seg.flags & wdi.SpicePathFlags.SPICE_PATH_CLOSE) {
|
|
439
|
+
context.lineTo(
|
|
440
|
+
firstPoint.x + lineWidth / 2,
|
|
441
|
+
firstPoint.y + lineWidth / 2
|
|
442
|
+
)
|
|
443
|
+
}
|
|
444
|
+
context.stroke()
|
|
445
|
+
context.closePath()
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
|
|
450
|
+
drawImage: function (spiceMessage) {
|
|
451
|
+
var args = spiceMessage.args
|
|
452
|
+
var drawBase = args.base
|
|
453
|
+
var surface_id = drawBase.surface_id
|
|
454
|
+
var rop = args.rop_descriptor
|
|
455
|
+
|
|
456
|
+
var scale = args.scale_mode
|
|
457
|
+
|
|
458
|
+
//calculate src_area box
|
|
459
|
+
var box_origin = wdi.graphics.getBoxFromSrcArea(args.src_area)
|
|
460
|
+
|
|
461
|
+
var box_dest = wdi.graphics.getBoxFromSrcArea(drawBase.box)
|
|
462
|
+
|
|
463
|
+
if (window.vdiLoadTest && window.firstImage === undefined) {
|
|
464
|
+
window.firstImage = true
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
//get the image in imagedata format
|
|
468
|
+
wdi.graphics.getImageFromSpice(
|
|
469
|
+
args.image.imageDescriptor,
|
|
470
|
+
args.image.data,
|
|
471
|
+
this.clientGui,
|
|
472
|
+
function (srcImg) {
|
|
473
|
+
//we have image?
|
|
474
|
+
if (srcImg) {
|
|
475
|
+
if (window.firstImage) {
|
|
476
|
+
var data
|
|
477
|
+
if (srcImg.getContext) {
|
|
478
|
+
data = srcImg
|
|
479
|
+
.getContext('2d')
|
|
480
|
+
.getImageData(0, 0, srcImg.width, srcImg.height)
|
|
481
|
+
.data.buffer.slice(0)
|
|
482
|
+
} else {
|
|
483
|
+
data = srcImg.data.buffer.slice(0)
|
|
484
|
+
}
|
|
485
|
+
window.firstImageData = data
|
|
486
|
+
window.firstImage = false
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
var rectangle = false
|
|
490
|
+
|
|
491
|
+
if (
|
|
492
|
+
box_origin.width !== box_dest.width &&
|
|
493
|
+
box_origin.height !== box_dest.height
|
|
494
|
+
) {
|
|
495
|
+
rectangle = true
|
|
496
|
+
srcImg = wdi.graphics.getRect(box_origin, srcImg)
|
|
497
|
+
srcImg = wdi.graphics.getImageFromData(srcImg)
|
|
498
|
+
var newSrcImg = wdi.graphics.getNewTmpCanvas(
|
|
499
|
+
box_dest.width,
|
|
500
|
+
box_dest.height
|
|
501
|
+
)
|
|
502
|
+
var tmpcontext = newSrcImg.getContext('2d')
|
|
503
|
+
tmpcontext.drawImage(
|
|
504
|
+
srcImg,
|
|
505
|
+
0,
|
|
506
|
+
0,
|
|
507
|
+
box_origin.width,
|
|
508
|
+
box_origin.height,
|
|
509
|
+
0,
|
|
510
|
+
0,
|
|
511
|
+
box_dest.width,
|
|
512
|
+
box_dest.height
|
|
513
|
+
)
|
|
514
|
+
srcImg = newSrcImg
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
//depending on the rop, we can avoid to get destImg
|
|
518
|
+
if (rop !== wdi.SpiceRopd.SPICE_ROPD_OP_PUT) {
|
|
519
|
+
//rop
|
|
520
|
+
if (!rectangle) {
|
|
521
|
+
srcImg = wdi.graphics.getRect(box_origin, srcImg)
|
|
522
|
+
}
|
|
523
|
+
var destImg = wdi.graphics.getRect(
|
|
524
|
+
box_dest,
|
|
525
|
+
this.clientGui.getCanvas(surface_id)
|
|
526
|
+
)
|
|
527
|
+
srcImg = wdi.RasterOperation.process(rop, srcImg, destImg)
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
var context = this.clientGui.getContext(surface_id)
|
|
531
|
+
|
|
532
|
+
if (srcImg instanceof ImageData) {
|
|
533
|
+
if (rectangle) {
|
|
534
|
+
//a subrectangle has been created, use it
|
|
535
|
+
context.putImageData(
|
|
536
|
+
srcImg,
|
|
537
|
+
box_dest.x,
|
|
538
|
+
box_dest.y,
|
|
539
|
+
0,
|
|
540
|
+
0,
|
|
541
|
+
box_dest.width,
|
|
542
|
+
box_dest.height
|
|
543
|
+
)
|
|
544
|
+
} else {
|
|
545
|
+
context.putImageData(
|
|
546
|
+
srcImg,
|
|
547
|
+
box_dest.x,
|
|
548
|
+
box_dest.y,
|
|
549
|
+
box_origin.x,
|
|
550
|
+
box_origin.y,
|
|
551
|
+
box_origin.width,
|
|
552
|
+
box_origin.height
|
|
553
|
+
)
|
|
554
|
+
}
|
|
555
|
+
} else {
|
|
556
|
+
if (rectangle) {
|
|
557
|
+
context.drawImage(
|
|
558
|
+
srcImg,
|
|
559
|
+
box_dest.x,
|
|
560
|
+
box_dest.y,
|
|
561
|
+
box_dest.width,
|
|
562
|
+
box_dest.height
|
|
563
|
+
)
|
|
564
|
+
} else {
|
|
565
|
+
context.drawImage(
|
|
566
|
+
srcImg,
|
|
567
|
+
box_origin.x,
|
|
568
|
+
box_origin.y,
|
|
569
|
+
box_origin.width,
|
|
570
|
+
box_origin.height,
|
|
571
|
+
box_dest.x,
|
|
572
|
+
box_dest.y,
|
|
573
|
+
box_dest.width,
|
|
574
|
+
box_dest.height
|
|
575
|
+
)
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
} else {
|
|
579
|
+
//failed to get image, cache error?
|
|
580
|
+
wdi.Debug.log('Unable to get image!')
|
|
581
|
+
}
|
|
582
|
+
},
|
|
583
|
+
this,
|
|
584
|
+
{ opaque: true, brush: args.brush, raw: false }
|
|
585
|
+
)
|
|
586
|
+
},
|
|
587
|
+
|
|
588
|
+
drawClip: function (srcImg, box, context) {
|
|
589
|
+
context.drawImage(srcImg, box.x, box.y, box.width, box.height)
|
|
590
|
+
},
|
|
591
|
+
|
|
592
|
+
drawFill: function (spiceMessage) {
|
|
593
|
+
var args = spiceMessage.args
|
|
594
|
+
var context = this.clientGui.getContext(args.base.surface_id)
|
|
595
|
+
var box = wdi.graphics.getBoxFromSrcArea(args.base.box)
|
|
596
|
+
var brush = args.brush
|
|
597
|
+
var ropd = args.rop_descriptor
|
|
598
|
+
|
|
599
|
+
wdi.graphics.setBrush(this.clientGui, context, brush, box, ropd)
|
|
600
|
+
},
|
|
601
|
+
|
|
602
|
+
drawCopyBits: function (spiceMessage) {
|
|
603
|
+
var drawBase = spiceMessage.args.base
|
|
604
|
+
var surface_id = drawBase.surface_id
|
|
605
|
+
var src_position = spiceMessage.args.src_position
|
|
606
|
+
var context = this.clientGui.getContext(surface_id)
|
|
607
|
+
var box = drawBase.box
|
|
608
|
+
|
|
609
|
+
var width = box.right - box.left
|
|
610
|
+
var height = box.bottom - box.top
|
|
611
|
+
|
|
612
|
+
context.drawImage(
|
|
613
|
+
context.canvas,
|
|
614
|
+
src_position.x,
|
|
615
|
+
src_position.y,
|
|
616
|
+
width,
|
|
617
|
+
height,
|
|
618
|
+
drawBase.box.left,
|
|
619
|
+
drawBase.box.top,
|
|
620
|
+
width,
|
|
621
|
+
height
|
|
622
|
+
)
|
|
623
|
+
},
|
|
624
|
+
|
|
625
|
+
drawBlend: function (spiceMessage) {
|
|
626
|
+
//TODO: alpha_flags
|
|
627
|
+
//TODO: resize
|
|
628
|
+
var descriptor = spiceMessage.args.image.imageDescriptor
|
|
629
|
+
var drawBase = spiceMessage.args.base
|
|
630
|
+
var imgData = spiceMessage.args.image.data
|
|
631
|
+
var surface_id = spiceMessage.args.base.surface_id
|
|
632
|
+
var rop_desc = spiceMessage.args.rop_descriptor
|
|
633
|
+
var flags = spiceMessage.args.flags
|
|
634
|
+
|
|
635
|
+
wdi.graphics.getImageFromSpice(
|
|
636
|
+
descriptor,
|
|
637
|
+
imgData,
|
|
638
|
+
this.clientGui,
|
|
639
|
+
function (srcImg) {
|
|
640
|
+
if (!srcImg) {
|
|
641
|
+
wdi.Debug.log('There is no image on Blend')
|
|
642
|
+
return
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
//get box from src area
|
|
646
|
+
var box = wdi.graphics.getBoxFromSrcArea(spiceMessage.args.src_area)
|
|
647
|
+
|
|
648
|
+
//adapt to src_area
|
|
649
|
+
srcImg = wdi.graphics.getRect(box, srcImg)
|
|
650
|
+
|
|
651
|
+
//destination box
|
|
652
|
+
var dest_box = wdi.graphics.getBoxFromSrcArea(drawBase.box)
|
|
653
|
+
var destImg = wdi.graphics.getRect(
|
|
654
|
+
dest_box,
|
|
655
|
+
this.clientGui.getCanvas(surface_id)
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
var result = wdi.RasterOperation.process(rop_desc, srcImg, destImg)
|
|
659
|
+
|
|
660
|
+
this.clientGui
|
|
661
|
+
.getCanvas(surface_id)
|
|
662
|
+
.getContext('2d')
|
|
663
|
+
.drawImage(
|
|
664
|
+
result,
|
|
665
|
+
dest_box.x,
|
|
666
|
+
dest_box.y,
|
|
667
|
+
dest_box.width,
|
|
668
|
+
dest_box.height
|
|
669
|
+
)
|
|
670
|
+
},
|
|
671
|
+
this
|
|
672
|
+
)
|
|
673
|
+
},
|
|
674
|
+
|
|
675
|
+
drawAlphaBlend: function (spiceMessage) {
|
|
676
|
+
//TODO: alpha_flags
|
|
677
|
+
//TODO: resize
|
|
678
|
+
|
|
679
|
+
var descriptor = spiceMessage.args.image.imageDescriptor
|
|
680
|
+
var drawBase = spiceMessage.args.base
|
|
681
|
+
var imgData = spiceMessage.args.image.data
|
|
682
|
+
var surface_id = spiceMessage.args.base.surface_id
|
|
683
|
+
var flags = spiceMessage.args.alpha_flags
|
|
684
|
+
var alpha = spiceMessage.args.alpha
|
|
685
|
+
|
|
686
|
+
wdi.graphics.getImageFromSpice(
|
|
687
|
+
descriptor,
|
|
688
|
+
imgData,
|
|
689
|
+
this.clientGui,
|
|
690
|
+
function (srcImg) {
|
|
691
|
+
if (!srcImg) {
|
|
692
|
+
wdi.Debug.log('There is no image on drawAlphaBlend')
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
var box = wdi.graphics.getBoxFromSrcArea(spiceMessage.args.src_area)
|
|
696
|
+
|
|
697
|
+
//adapt to src_area
|
|
698
|
+
srcImg = wdi.graphics.getRect(box, srcImg)
|
|
699
|
+
|
|
700
|
+
//destination box
|
|
701
|
+
var box_dest = wdi.graphics.getBoxFromSrcArea(drawBase.box)
|
|
702
|
+
var destImg = wdi.graphics.getRect(
|
|
703
|
+
box_dest,
|
|
704
|
+
this.clientGui.getCanvas(surface_id)
|
|
705
|
+
)
|
|
706
|
+
|
|
707
|
+
if (box.width !== box_dest.width && box.height !== box_dest.height) {
|
|
708
|
+
var tmpcanvas = wdi.graphics.getNewTmpCanvas(
|
|
709
|
+
box_dest.width,
|
|
710
|
+
box_dest.height
|
|
711
|
+
)
|
|
712
|
+
var tmpcontext = tmpcanvas.getContext('2d')
|
|
713
|
+
tmpcontext.drawImage(
|
|
714
|
+
srcImg,
|
|
715
|
+
0,
|
|
716
|
+
0,
|
|
717
|
+
box.width,
|
|
718
|
+
box.height,
|
|
719
|
+
0,
|
|
720
|
+
0,
|
|
721
|
+
box_dest.width,
|
|
722
|
+
box_dest.height
|
|
723
|
+
)
|
|
724
|
+
srcImg = tmpcanvas
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
var src = wdi.graphics.getDataFromImage(srcImg).data
|
|
728
|
+
var dst = wdi.graphics.getDataFromImage(destImg).data
|
|
729
|
+
|
|
730
|
+
var length = src.length - 1
|
|
731
|
+
|
|
732
|
+
//create a new imagedata to store result
|
|
733
|
+
var imageResult = wdi.graphics.getNewTmpCanvas(
|
|
734
|
+
box_dest.width,
|
|
735
|
+
box_dest.height
|
|
736
|
+
)
|
|
737
|
+
var context = imageResult.getContext('2d')
|
|
738
|
+
|
|
739
|
+
var resultImageData = context.createImageData(
|
|
740
|
+
box_dest.width,
|
|
741
|
+
box_dest.height
|
|
742
|
+
)
|
|
743
|
+
var result = resultImageData.data
|
|
744
|
+
|
|
745
|
+
var rS, rD
|
|
746
|
+
var gS, gD
|
|
747
|
+
var bS, bD
|
|
748
|
+
var aS
|
|
749
|
+
|
|
750
|
+
for (var px = 0; px < length; px += 4) {
|
|
751
|
+
rS = src[px]
|
|
752
|
+
gS = src[px + 1]
|
|
753
|
+
bS = src[px + 2]
|
|
754
|
+
|
|
755
|
+
if (flags || alpha === 255) {
|
|
756
|
+
aS = src[px + 3]
|
|
757
|
+
} else {
|
|
758
|
+
aS = alpha
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
rD = dst[px]
|
|
762
|
+
gD = dst[px + 1]
|
|
763
|
+
bD = dst[px + 2]
|
|
764
|
+
|
|
765
|
+
if (aS > 30 && alpha === 255) {
|
|
766
|
+
//formula from reactos, this is premultiplied alpha values
|
|
767
|
+
result[px] = ((rD * (255 - aS)) / 255 + rS) & 0xff
|
|
768
|
+
result[px + 1] = ((gD * (255 - aS)) / 255 + gS) & 0xff
|
|
769
|
+
result[px + 2] = ((bD * (255 - aS)) / 255 + bS) & 0xff
|
|
770
|
+
} else {
|
|
771
|
+
//homemade blend function, this is the typical blend function simplified
|
|
772
|
+
result[px] = ((rS * aS + rD * (255 - aS)) / 255) & 0xff
|
|
773
|
+
result[px + 1] = ((gS * aS + gD * (255 - aS)) / 255) & 0xff
|
|
774
|
+
result[px + 2] = ((bS * aS + bD * (255 - aS)) / 255) & 0xff
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
result[px + 3] = 255
|
|
778
|
+
}
|
|
779
|
+
imageResult.getContext('2d').putImageData(resultImageData, 0, 0)
|
|
780
|
+
|
|
781
|
+
this.drawClip(
|
|
782
|
+
imageResult,
|
|
783
|
+
box_dest,
|
|
784
|
+
this.clientGui.getContext(surface_id)
|
|
785
|
+
)
|
|
786
|
+
},
|
|
787
|
+
this
|
|
788
|
+
)
|
|
789
|
+
},
|
|
790
|
+
|
|
791
|
+
drawWhiteness: function (spiceMessage) {
|
|
792
|
+
//TODO: mask
|
|
793
|
+
var base = spiceMessage.args.base
|
|
794
|
+
var context = this.clientGui.getContext(base.surface_id)
|
|
795
|
+
var box = wdi.graphics.getBoxFromSrcArea(base.box)
|
|
796
|
+
context.fillStyle = 'white'
|
|
797
|
+
context.fillRect(box.x, box.y, box.width, box.height)
|
|
798
|
+
},
|
|
799
|
+
|
|
800
|
+
drawBlackness: function (spiceMessage) {
|
|
801
|
+
//TODO: mask
|
|
802
|
+
var base = spiceMessage.args.base
|
|
803
|
+
var context = this.clientGui.getContext(base.surface_id)
|
|
804
|
+
var box = wdi.graphics.getBoxFromSrcArea(base.box)
|
|
805
|
+
context.fillStyle = 'black'
|
|
806
|
+
context.fillRect(box.x, box.y, box.width, box.height)
|
|
807
|
+
},
|
|
808
|
+
|
|
809
|
+
drawTransparent: function (spiceMessage) {
|
|
810
|
+
var drawBase = spiceMessage.args.base
|
|
811
|
+
var surface_id = drawBase.surface_id
|
|
812
|
+
|
|
813
|
+
//calculate src_area box
|
|
814
|
+
var box = wdi.graphics.getBoxFromSrcArea(spiceMessage.args.src_area)
|
|
815
|
+
var dest_box = wdi.graphics.getBoxFromSrcArea(drawBase.box)
|
|
816
|
+
|
|
817
|
+
//get destination iamge, in imagedata format because is what we need
|
|
818
|
+
var destImg = this.clientGui
|
|
819
|
+
.getContext(surface_id)
|
|
820
|
+
.getImageData(dest_box.x, dest_box.y, dest_box.width, dest_box.height)
|
|
821
|
+
|
|
822
|
+
wdi.graphics.getImageFromSpice(
|
|
823
|
+
spiceMessage.args.image.imageDescriptor,
|
|
824
|
+
spiceMessage.args.image.data,
|
|
825
|
+
this.clientGui,
|
|
826
|
+
function (srcImg) {
|
|
827
|
+
if (srcImg) {
|
|
828
|
+
//adapt to src_area
|
|
829
|
+
srcImg = wdi.graphics.getRect(box, srcImg)
|
|
830
|
+
|
|
831
|
+
var source = wdi.graphics.getDataFromImage(srcImg).data
|
|
832
|
+
var dest = destImg.data
|
|
833
|
+
|
|
834
|
+
var length = source.length - 1
|
|
835
|
+
var resultImageData = this.clientGui
|
|
836
|
+
.getContext(surface_id)
|
|
837
|
+
.createImageData(dest_box.width, dest_box.height)
|
|
838
|
+
|
|
839
|
+
var color = spiceMessage.args.transparent_true_color
|
|
840
|
+
while (length > 0) {
|
|
841
|
+
resultImageData.data[length] = 255 //alpha
|
|
842
|
+
if (
|
|
843
|
+
source[length - 1] === color.b &&
|
|
844
|
+
source[length - 2] === color.g &&
|
|
845
|
+
source[length - 3] === color.r
|
|
846
|
+
) {
|
|
847
|
+
resultImageData.data[length - 1] = dest[length - 1] //b
|
|
848
|
+
resultImageData.data[length - 2] = dest[length - 2] //g
|
|
849
|
+
resultImageData.data[length - 3] = dest[length - 3] //r
|
|
850
|
+
} else {
|
|
851
|
+
resultImageData.data[length - 1] = source[length - 1] //b
|
|
852
|
+
resultImageData.data[length - 2] = source[length - 2] //g
|
|
853
|
+
resultImageData.data[length - 3] = source[length - 3] //r
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
length -= 4
|
|
857
|
+
}
|
|
858
|
+
var resultImage = wdi.graphics.getImageFromData(resultImageData)
|
|
859
|
+
this.drawClip(
|
|
860
|
+
resultImage,
|
|
861
|
+
dest_box,
|
|
862
|
+
this.clientGui.getContext(surface_id)
|
|
863
|
+
)
|
|
864
|
+
} else {
|
|
865
|
+
//failed to get image, cache error?
|
|
866
|
+
wdi.Debug.log('Unable to get image!')
|
|
867
|
+
}
|
|
868
|
+
},
|
|
869
|
+
this
|
|
870
|
+
)
|
|
871
|
+
},
|
|
872
|
+
|
|
873
|
+
drawText: function (spiceMessage) {
|
|
874
|
+
var context = this.clientGui.getContext(spiceMessage.args.base.surface_id)
|
|
875
|
+
var bbox = spiceMessage.args.base.box
|
|
876
|
+
var clip = spiceMessage.args.base.clip
|
|
877
|
+
var text = spiceMessage.args
|
|
878
|
+
var string = text.glyph_string
|
|
879
|
+
var bpp = string.flags === 1 ? 1 : string.flags * 2
|
|
880
|
+
|
|
881
|
+
if (text.back_mode !== 0) {
|
|
882
|
+
wdi.graphics.drawBackText(this.clientGui, context, text)
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
wdi.graphics.drawString(
|
|
886
|
+
context,
|
|
887
|
+
string,
|
|
888
|
+
bpp,
|
|
889
|
+
text.fore_brush,
|
|
890
|
+
clip.type,
|
|
891
|
+
this
|
|
892
|
+
)
|
|
893
|
+
},
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* Clears all color palettes
|
|
897
|
+
* @param spiceMessage
|
|
898
|
+
* @param app
|
|
899
|
+
*/
|
|
900
|
+
invalPalettes: function (spiceMessage) {
|
|
901
|
+
wdi.ImageCache.clearPalettes()
|
|
902
|
+
},
|
|
903
|
+
|
|
904
|
+
handleReset: function (spiceMessage) {
|
|
905
|
+
// console.log(spiceMessage, 222);
|
|
906
|
+
},
|
|
907
|
+
})
|