react-x11 2.22.1 → 2.22.2
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/package.json +1 -1
- package/src/backend/context2d.js +27 -1
- package/src/cocoa/overlay.js +2 -0
- package/src/cocoa/panewindow.js +2 -0
- package/src/cocoa/presenter.js +2 -0
- package/src/cocoa/surface.js +2 -0
- package/src/cocoa/window.js +2 -0
- package/src/nodes/roundclip.js +33 -13
package/package.json
CHANGED
package/src/backend/context2d.js
CHANGED
|
@@ -285,11 +285,15 @@ export class BackendContext2D {
|
|
|
285
285
|
* @param surfaceOf () => current surface handle — the owner replaces the
|
|
286
286
|
* surface on resize, and this context follows it.
|
|
287
287
|
* @param genOf () => surface generation number
|
|
288
|
+
* @param options.readback whether the bitmap this context draws into can
|
|
289
|
+
* be read back while it is being drawn into, cheaply — a CPU bitmap, as
|
|
290
|
+
* every Cocoa surface is (`readbackSource`)
|
|
288
291
|
*/
|
|
289
|
-
constructor(native, surfaceOf, genOf) {
|
|
292
|
+
constructor(native, surfaceOf, genOf, { readback = false } = {}) {
|
|
290
293
|
this._native = native;
|
|
291
294
|
this._surfaceOf = surfaceOf;
|
|
292
295
|
this._genOf = genOf;
|
|
296
|
+
this._readback = readback;
|
|
293
297
|
this._gen = -1;
|
|
294
298
|
this._stack = [];
|
|
295
299
|
this._state = {
|
|
@@ -338,6 +342,28 @@ export class BackendContext2D {
|
|
|
338
342
|
this._strokeChunking = !NO_STROKE_CHUNKING;
|
|
339
343
|
}
|
|
340
344
|
|
|
345
|
+
/**
|
|
346
|
+
* The bitmap this context draws into, as a source `drawImage` reads — for
|
|
347
|
+
* a caller that keeps a few of its pixels before drawing over them and
|
|
348
|
+
* puts them back after, which is how a rounded box clips its children
|
|
349
|
+
* without a path clip (src/nodes/roundclip.js, issue #693). A `copy` of
|
|
350
|
+
* it at a whole-pixel translate is `blitSurface`'s memcpy. Null where the
|
|
351
|
+
* owner has not said the bitmap reads back cheaply while it is drawn
|
|
352
|
+
* into: a GPU target is a different cost, and nobody has measured it.
|
|
353
|
+
*/
|
|
354
|
+
readbackSource() {
|
|
355
|
+
if (!this._readback) return null;
|
|
356
|
+
const ctx = this;
|
|
357
|
+
const { width, height } = this._native.surfaceSize(this._s());
|
|
358
|
+
return {
|
|
359
|
+
width,
|
|
360
|
+
height,
|
|
361
|
+
get _surfaceHandle() {
|
|
362
|
+
return ctx._s();
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
341
367
|
_s() {
|
|
342
368
|
const surface = this._surfaceOf();
|
|
343
369
|
const gen = this._genOf();
|
package/src/cocoa/overlay.js
CHANGED
|
@@ -127,6 +127,8 @@ export class CocoaOverlayPane {
|
|
|
127
127
|
this._ensureSurface();
|
|
128
128
|
return this._gen;
|
|
129
129
|
},
|
|
130
|
+
// a CPU bitmap: a rounded box keeps its corners by reading it back
|
|
131
|
+
{ readback: true },
|
|
130
132
|
);
|
|
131
133
|
this._ctx._fonts = this.app.fonts;
|
|
132
134
|
this._ctx._onDirty = () => {
|
package/src/cocoa/panewindow.js
CHANGED
|
@@ -195,6 +195,8 @@ export class CocoaPaneWindow {
|
|
|
195
195
|
this._ensureSurface();
|
|
196
196
|
return this._surfaceGen;
|
|
197
197
|
},
|
|
198
|
+
// a CPU bitmap: a rounded box keeps its corners by reading it back
|
|
199
|
+
{ readback: true },
|
|
198
200
|
);
|
|
199
201
|
this._ctx._fonts = this.app.fonts;
|
|
200
202
|
this._ctx._onDirty = () => {
|
package/src/cocoa/presenter.js
CHANGED
package/src/cocoa/surface.js
CHANGED
package/src/cocoa/window.js
CHANGED
|
@@ -806,6 +806,8 @@ export class CocoaWindow {
|
|
|
806
806
|
this._ensureSurface();
|
|
807
807
|
return this._surfaceGen;
|
|
808
808
|
},
|
|
809
|
+
// a CPU bitmap: a rounded box keeps its corners by reading it back
|
|
810
|
+
{ readback: true },
|
|
809
811
|
);
|
|
810
812
|
this._ctx._fonts = this.app.fonts;
|
|
811
813
|
this._ctx._onDirty = () => {
|
package/src/nodes/roundclip.js
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
//
|
|
8
8
|
// That needs a context that can read its own pixels back into a surface of
|
|
9
9
|
// its own and composite a coverage surface: ntk's, whose `picture` is the
|
|
10
|
-
// server-side picture it draws through
|
|
11
|
-
//
|
|
10
|
+
// server-side picture it draws through, and a Cocoa one, whose bitmap is CPU
|
|
11
|
+
// memory it names as a `drawImage` source (`readbackSource`, issue #693).
|
|
12
|
+
// Anywhere else the caller clips to the outline as it always has.
|
|
12
13
|
|
|
13
14
|
import { Surface } from '../offscreen.js';
|
|
14
15
|
|
|
@@ -65,6 +66,20 @@ function cornerPath(ctx, box, { radius: r, side: s }, corner) {
|
|
|
65
66
|
ctx.closePath();
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
/**
|
|
70
|
+
* A square to hold a coverage in: an a8 surface where the backend has them,
|
|
71
|
+
* and elsewhere a colour one whose alpha is the coverage — which is all the
|
|
72
|
+
* `destination-in` and `destination-out` it is drawn with read of it. The
|
|
73
|
+
* Cocoa backend has no a8 surfaces and says so by throwing.
|
|
74
|
+
*/
|
|
75
|
+
function coverageSurface(app, side) {
|
|
76
|
+
try {
|
|
77
|
+
return new Surface(app, { width: side, height: side, format: 'a8' });
|
|
78
|
+
} catch {
|
|
79
|
+
return new Surface(app, { width: side, height: side });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
68
83
|
/**
|
|
69
84
|
* How much of each pixel of a corner square lies outside the outline, as an
|
|
70
85
|
* a8 surface the size of the square: the square filled, and the outline's
|
|
@@ -77,7 +92,7 @@ function outsideCoverage(app, corners, corner) {
|
|
|
77
92
|
const key = `${corner}|${corners.radius}|${s}`;
|
|
78
93
|
let surface = state.coverage.get(key);
|
|
79
94
|
if (surface) return surface;
|
|
80
|
-
surface =
|
|
95
|
+
surface = coverageSurface(app, s);
|
|
81
96
|
// a box whose corner lands on the square's own, in the square's space
|
|
82
97
|
const far = corner === 'tr' || corner === 'br';
|
|
83
98
|
const low = corner === 'bl' || corner === 'br';
|
|
@@ -126,16 +141,21 @@ function readback(ctx) {
|
|
|
126
141
|
if (!m || m.a !== 1 || m.b !== 0 || m.c !== 0 || m.d !== 1) return null;
|
|
127
142
|
if (!Number.isInteger(m.e) || !Number.isInteger(m.f)) return null;
|
|
128
143
|
// reading it settles the picture's clip, which the next drawing re-stamps
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
144
|
+
if (ctx.picture && Number.isFinite(ctx.width)) {
|
|
145
|
+
return {
|
|
146
|
+
dx: m.e,
|
|
147
|
+
dy: m.f,
|
|
148
|
+
source: {
|
|
149
|
+
width: ctx.width,
|
|
150
|
+
height: ctx.height,
|
|
151
|
+
picture: () => ctx.picture,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
// a backend context whose owner says its bitmap reads back cheaply
|
|
156
|
+
const source =
|
|
157
|
+
typeof ctx.readbackSource === 'function' ? ctx.readbackSource() : null;
|
|
158
|
+
return source ? { dx: m.e, dy: m.f, source } : null;
|
|
139
159
|
}
|
|
140
160
|
|
|
141
161
|
/**
|