@gtkx/cairo 1.2.2 → 1.4.0
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/LICENSE +373 -0
- package/README.md +174 -0
- package/dist/context.d.ts +1 -1
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +16 -15
- package/dist/context.js.map +1 -1
- package/dist/font-face.d.ts +2 -7
- package/dist/font-face.d.ts.map +1 -1
- package/dist/font-face.js +3 -13
- package/dist/font-face.js.map +1 -1
- package/dist/lib.d.ts +1 -3
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +3 -4
- package/dist/lib.js.map +1 -1
- package/dist/path.d.ts.map +1 -1
- package/dist/path.js +8 -5
- package/dist/path.js.map +1 -1
- package/dist/pattern.d.ts +3 -1
- package/dist/pattern.d.ts.map +1 -1
- package/dist/pattern.js +24 -6
- package/dist/pattern.js.map +1 -1
- package/dist/region.d.ts.map +1 -1
- package/dist/region.js +6 -5
- package/dist/region.js.map +1 -1
- package/dist/scaled-font.d.ts +3 -5
- package/dist/scaled-font.d.ts.map +1 -1
- package/dist/scaled-font.js +3 -62
- package/dist/scaled-font.js.map +1 -1
- package/dist/status.d.ts +6 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +17 -0
- package/dist/status.js.map +1 -0
- package/dist/structs.d.ts +1 -1
- package/dist/structs.d.ts.map +1 -1
- package/dist/structs.js +1 -1
- package/dist/structs.js.map +1 -1
- package/dist/surface.d.ts +2 -7
- package/dist/surface.d.ts.map +1 -1
- package/dist/surface.js +21 -25
- package/dist/surface.js.map +1 -1
- package/dist/text.d.ts.map +1 -1
- package/dist/text.js +20 -17
- package/dist/text.js.map +1 -1
- package/package.json +60 -61
- package/src/context.ts +15 -16
- package/src/font-face.ts +3 -25
- package/src/lib.ts +2 -5
- package/src/path.ts +8 -5
- package/src/pattern.ts +31 -7
- package/src/region.ts +5 -5
- package/src/scaled-font.ts +3 -92
- package/src/status.ts +23 -0
- package/src/structs.ts +1 -1
- package/src/surface.ts +28 -29
- package/src/text.ts +20 -17
package/src/status.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ExternalObject, Handle } from "@gtkx/runtime";
|
|
2
|
+
import { t } from "@gtkx/runtime";
|
|
3
|
+
import { Status } from "./enums.js";
|
|
4
|
+
import { bindCairo, SURFACE_T } from "./lib.js";
|
|
5
|
+
import { statusToString } from "./version.js";
|
|
6
|
+
|
|
7
|
+
const cairoSurfaceStatus = bindCairo("cairo_surface_status", [SURFACE_T], t.int32);
|
|
8
|
+
|
|
9
|
+
const checkStatus = (status: Status, subject: string): void => {
|
|
10
|
+
if (status === Status.SUCCESS) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
throw new Error(`cairo error on ${subject}: "${statusToString(status)}" (${String(status)})`);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const checkSurface = (handle: ExternalObject<Handle>): ExternalObject<Handle> => {
|
|
18
|
+
checkStatus(cairoSurfaceStatus(handle) as Status, "surface");
|
|
19
|
+
|
|
20
|
+
return handle;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export { checkStatus, checkSurface };
|
package/src/structs.ts
CHANGED
|
@@ -147,7 +147,7 @@ class Rectangle {
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
/** A rectangle with integer edges, as regions
|
|
150
|
+
/** A rectangle with integer edges, as Cairo regions use. */
|
|
151
151
|
class RectangleInt {
|
|
152
152
|
static {
|
|
153
153
|
registerWrapperClass(this, RECTANGLE_INT_TYPE);
|
package/src/surface.ts
CHANGED
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
type ExternalObject,
|
|
4
4
|
getHandle,
|
|
5
5
|
type Handle,
|
|
6
|
-
read,
|
|
7
6
|
registerWrapperClass,
|
|
8
7
|
registerWrapperClassResolver,
|
|
9
8
|
setHandle,
|
|
@@ -12,7 +11,6 @@ import {
|
|
|
12
11
|
type WrapperClassResolver,
|
|
13
12
|
write,
|
|
14
13
|
} from "@gtkx/runtime";
|
|
15
|
-
import type { RectangleInt } from "./structs.js";
|
|
16
14
|
import type { DeviceOffset, DeviceScale, FallbackResolution, InkExtents, RectangleData } from "./types.js";
|
|
17
15
|
import { type Content, type Format, type Status, SurfaceType } from "./enums.js";
|
|
18
16
|
import { FontOptions } from "./font-options.js";
|
|
@@ -22,14 +20,16 @@ import {
|
|
|
22
20
|
cairoGType,
|
|
23
21
|
DEVICE_T,
|
|
24
22
|
FONT_OPTIONS_T,
|
|
25
|
-
RECTANGLE_INT_T,
|
|
26
23
|
RECTANGLE_T,
|
|
27
24
|
SURFACE_FULL_T,
|
|
28
25
|
SURFACE_T,
|
|
29
26
|
} from "./lib.js";
|
|
27
|
+
import { checkSurface } from "./status.js";
|
|
30
28
|
|
|
31
29
|
const SURFACE_TYPE = cairoGType("cairo_gobject_surface_get_type");
|
|
32
30
|
const RECTANGLE_SIZE = 32;
|
|
31
|
+
const DOUBLE = t.fieldAt(t.float64);
|
|
32
|
+
const UINT8 = t.fieldAt(t.uint8);
|
|
33
33
|
const DEVICE_PAIR_ARGS = [SURFACE_T, t.float64, t.float64];
|
|
34
34
|
const DEVICE_PAIR_OUT_ARGS = [SURFACE_T, t.ref(t.float64), t.ref(t.float64)];
|
|
35
35
|
const SIMILAR_ARGS = [SURFACE_T, t.int32, t.int32, t.int32];
|
|
@@ -81,8 +81,6 @@ const cairoSurfaceSupportsMimeType = bindCairo(
|
|
|
81
81
|
t.boolean,
|
|
82
82
|
);
|
|
83
83
|
|
|
84
|
-
const cairoSurfaceMapToImage = bindCairo("cairo_surface_map_to_image", [SURFACE_T, RECTANGLE_INT_T], SURFACE_T);
|
|
85
|
-
const cairoSurfaceUnmapImage = bindCairo("cairo_surface_unmap_image", [SURFACE_T, SURFACE_T], t.void);
|
|
86
84
|
const cairoImageSurfaceCreate = bindCairo("cairo_image_surface_create", [t.int32, t.int32, t.int32], SURFACE_FULL_T);
|
|
87
85
|
|
|
88
86
|
const cairoImageSurfaceCreateFromPng = bindCairo(
|
|
@@ -136,10 +134,10 @@ const allocRectangle = (rect: RectangleData): ExternalObject<Handle> => {
|
|
|
136
134
|
};
|
|
137
135
|
|
|
138
136
|
const readRectangle = (buffer: ExternalObject<Handle>): RectangleData => ({
|
|
139
|
-
x: read(buffer,
|
|
140
|
-
y: read(buffer,
|
|
141
|
-
width: read(buffer,
|
|
142
|
-
height: read(buffer,
|
|
137
|
+
x: DOUBLE.read(buffer, 0) as number,
|
|
138
|
+
y: DOUBLE.read(buffer, 8) as number,
|
|
139
|
+
width: DOUBLE.read(buffer, 16) as number,
|
|
140
|
+
height: DOUBLE.read(buffer, 24) as number,
|
|
143
141
|
});
|
|
144
142
|
|
|
145
143
|
const createRecordingSurface = (content: Content, extents?: RectangleData): ExternalObject<Handle> =>
|
|
@@ -174,17 +172,25 @@ abstract class Surface {
|
|
|
174
172
|
|
|
175
173
|
/** Creates a surface of the given `content` and size as compatible as possible with `other`. */
|
|
176
174
|
static createSimilar(other: Surface, content: Content, width: number, height: number): Surface {
|
|
177
|
-
|
|
175
|
+
const handle = cairoSurfaceCreateSimilar(getHandle(other), content, width, height) as ExternalObject<Handle>;
|
|
176
|
+
|
|
177
|
+
return wrapSurface(checkSurface(handle));
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
/** Creates an image surface of the given `format` and size as compatible as possible with `other`. */
|
|
181
|
-
static createSimilarImage(other: Surface, format: Format, width: number, height: number):
|
|
182
|
-
|
|
181
|
+
static createSimilarImage(other: Surface, format: Format, width: number, height: number): ImageSurface {
|
|
182
|
+
const handle =
|
|
183
|
+
cairoSurfaceCreateSimilarImage(getHandle(other), format, width, height) as ExternalObject<Handle>;
|
|
184
|
+
|
|
185
|
+
return wrapHandle(checkSurface(handle), ImageSurface);
|
|
183
186
|
}
|
|
184
187
|
|
|
185
188
|
/** Creates a surface that draws onto the given rectangle of `target`. */
|
|
186
189
|
static createForRectangle(target: Surface, x: number, y: number, width: number, height: number): Surface {
|
|
187
|
-
|
|
190
|
+
const handle =
|
|
191
|
+
cairoSurfaceCreateForRectangle(getHandle(target), x, y, width, height) as ExternalObject<Handle>;
|
|
192
|
+
|
|
193
|
+
return wrapSurface(checkSurface(handle));
|
|
188
194
|
}
|
|
189
195
|
|
|
190
196
|
/** GType of `CairoSurface`, the boxed type this class is registered under. */
|
|
@@ -300,34 +306,27 @@ abstract class Surface {
|
|
|
300
306
|
supportsMimeType(mimeType: string): boolean {
|
|
301
307
|
return cairoSurfaceSupportsMimeType(getHandle(this), mimeType) as boolean;
|
|
302
308
|
}
|
|
303
|
-
|
|
304
|
-
/** Returns an image surface giving direct access to the pixels of `extents`; release it with `unmapImage`. */
|
|
305
|
-
mapToImage(extents: RectangleInt): Surface {
|
|
306
|
-
return wrapSurface(cairoSurfaceMapToImage(getHandle(this), getHandle(extents)));
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/** Uploads the pixels of `image`, obtained from `mapToImage`, back to the surface and releases it. */
|
|
310
|
-
unmapImage(image: Surface): void {
|
|
311
|
-
cairoSurfaceUnmapImage(getHandle(this), getHandle(image));
|
|
312
|
-
}
|
|
313
309
|
}
|
|
314
310
|
|
|
315
311
|
/** A surface backed by an in-memory pixel buffer, the usual target for offscreen drawing. */
|
|
316
312
|
class ImageSurface extends Surface {
|
|
317
313
|
/** Creates an image surface of the given pixel `format` and size, the same as `new ImageSurface(...)`. */
|
|
318
314
|
static create(format: Format, width: number, height: number): ImageSurface {
|
|
319
|
-
return wrapHandle(
|
|
315
|
+
return wrapHandle(
|
|
316
|
+
checkSurface(cairoImageSurfaceCreate(format, width, height) as ExternalObject<Handle>),
|
|
317
|
+
this,
|
|
318
|
+
);
|
|
320
319
|
}
|
|
321
320
|
|
|
322
|
-
/** Loads a PNG file into a new image surface;
|
|
321
|
+
/** Loads a PNG file into a new image surface; throws when the file is missing or invalid. */
|
|
323
322
|
static createFromPng(filename: string): ImageSurface {
|
|
324
|
-
return wrapHandle(cairoImageSurfaceCreateFromPng(filename) as ExternalObject<Handle
|
|
323
|
+
return wrapHandle(checkSurface(cairoImageSurfaceCreateFromPng(filename) as ExternalObject<Handle>), this);
|
|
325
324
|
}
|
|
326
325
|
|
|
327
326
|
/** Creates an image surface of the given pixel `format` and size. */
|
|
328
327
|
constructor(format: Format, width: number, height: number) {
|
|
329
328
|
super();
|
|
330
|
-
setHandle(this, cairoImageSurfaceCreate(format, width, height) as ExternalObject<Handle>);
|
|
329
|
+
setHandle(this, checkSurface(cairoImageSurfaceCreate(format, width, height) as ExternalObject<Handle>));
|
|
331
330
|
}
|
|
332
331
|
|
|
333
332
|
/** Returns the width of the surface in pixels. */
|
|
@@ -371,7 +370,7 @@ class ImageSurface extends Surface {
|
|
|
371
370
|
return new Uint8Array(0);
|
|
372
371
|
}
|
|
373
372
|
|
|
374
|
-
return Uint8Array.from({ length: totalBytes }, (_, index) => read(data,
|
|
373
|
+
return Uint8Array.from({ length: totalBytes }, (_, index) => UINT8.read(data, index) as number);
|
|
375
374
|
}
|
|
376
375
|
}
|
|
377
376
|
|
|
@@ -385,7 +384,7 @@ class RecordingSurface extends Surface {
|
|
|
385
384
|
/** Creates a recording surface of the given `content`, bounded to `extents` or unbounded when omitted. */
|
|
386
385
|
constructor(content: Content, extents?: RectangleData) {
|
|
387
386
|
super();
|
|
388
|
-
setHandle(this, createRecordingSurface(content, extents));
|
|
387
|
+
setHandle(this, checkSurface(createRecordingSurface(content, extents)));
|
|
389
388
|
}
|
|
390
389
|
|
|
391
390
|
/** Returns the area that has been drawn on so far. */
|
package/src/text.ts
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
import { alloc, type ExternalObject, type Handle,
|
|
1
|
+
import { alloc, type ExternalObject, type Handle, t } from "@gtkx/runtime";
|
|
2
2
|
import type { CairoGlyph, CairoTextCluster, FontExtents, TextExtents } from "./types.js";
|
|
3
3
|
|
|
4
4
|
const GLYPH_SIZE = 24;
|
|
5
5
|
const CLUSTER_SIZE = 8;
|
|
6
6
|
const TEXT_EXTENTS_SIZE = 48;
|
|
7
7
|
const FONT_EXTENTS_SIZE = 40;
|
|
8
|
+
const DOUBLE = t.fieldAt(t.float64);
|
|
9
|
+
const UINT64 = t.fieldAt(t.uint64);
|
|
10
|
+
const INT = t.fieldAt(t.int32);
|
|
8
11
|
|
|
9
12
|
const allocGlyphBuffer = (glyphs: CairoGlyph[]): ExternalObject<Handle> => {
|
|
10
13
|
const buffer = alloc(glyphs.length * GLYPH_SIZE);
|
|
11
14
|
let offset = 0;
|
|
12
15
|
|
|
13
16
|
for (const glyph of glyphs) {
|
|
14
|
-
write(buffer,
|
|
15
|
-
write(buffer,
|
|
16
|
-
write(buffer,
|
|
17
|
+
UINT64.write(buffer, offset, glyph.index);
|
|
18
|
+
DOUBLE.write(buffer, offset + 8, glyph.x);
|
|
19
|
+
DOUBLE.write(buffer, offset + 16, glyph.y);
|
|
17
20
|
offset += GLYPH_SIZE;
|
|
18
21
|
}
|
|
19
22
|
|
|
@@ -25,8 +28,8 @@ const allocClusterBuffer = (clusters: CairoTextCluster[]): ExternalObject<Handle
|
|
|
25
28
|
let offset = 0;
|
|
26
29
|
|
|
27
30
|
for (const cluster of clusters) {
|
|
28
|
-
write(buffer,
|
|
29
|
-
write(buffer,
|
|
31
|
+
INT.write(buffer, offset, cluster.numBytes);
|
|
32
|
+
INT.write(buffer, offset + 4, cluster.numGlyphs);
|
|
30
33
|
offset += CLUSTER_SIZE;
|
|
31
34
|
}
|
|
32
35
|
|
|
@@ -37,20 +40,20 @@ const allocTextExtents = (): ExternalObject<Handle> => alloc(TEXT_EXTENTS_SIZE);
|
|
|
37
40
|
const allocFontExtents = (): ExternalObject<Handle> => alloc(FONT_EXTENTS_SIZE);
|
|
38
41
|
|
|
39
42
|
const readTextExtents = (handle: ExternalObject<Handle>): TextExtents => ({
|
|
40
|
-
xBearing: read(handle,
|
|
41
|
-
yBearing: read(handle,
|
|
42
|
-
width: read(handle,
|
|
43
|
-
height: read(handle,
|
|
44
|
-
xAdvance: read(handle,
|
|
45
|
-
yAdvance: read(handle,
|
|
43
|
+
xBearing: DOUBLE.read(handle, 0) as number,
|
|
44
|
+
yBearing: DOUBLE.read(handle, 8) as number,
|
|
45
|
+
width: DOUBLE.read(handle, 16) as number,
|
|
46
|
+
height: DOUBLE.read(handle, 24) as number,
|
|
47
|
+
xAdvance: DOUBLE.read(handle, 32) as number,
|
|
48
|
+
yAdvance: DOUBLE.read(handle, 40) as number,
|
|
46
49
|
});
|
|
47
50
|
|
|
48
51
|
const readFontExtents = (handle: ExternalObject<Handle>): FontExtents => ({
|
|
49
|
-
ascent: read(handle,
|
|
50
|
-
descent: read(handle,
|
|
51
|
-
height: read(handle,
|
|
52
|
-
maxXAdvance: read(handle,
|
|
53
|
-
maxYAdvance: read(handle,
|
|
52
|
+
ascent: DOUBLE.read(handle, 0) as number,
|
|
53
|
+
descent: DOUBLE.read(handle, 8) as number,
|
|
54
|
+
height: DOUBLE.read(handle, 16) as number,
|
|
55
|
+
maxXAdvance: DOUBLE.read(handle, 24) as number,
|
|
56
|
+
maxYAdvance: DOUBLE.read(handle, 32) as number,
|
|
54
57
|
});
|
|
55
58
|
|
|
56
59
|
export { allocClusterBuffer, allocFontExtents, allocGlyphBuffer, allocTextExtents, readFontExtents, readTextExtents };
|