@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.
Files changed (55) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +174 -0
  3. package/dist/context.d.ts +1 -1
  4. package/dist/context.d.ts.map +1 -1
  5. package/dist/context.js +16 -15
  6. package/dist/context.js.map +1 -1
  7. package/dist/font-face.d.ts +2 -7
  8. package/dist/font-face.d.ts.map +1 -1
  9. package/dist/font-face.js +3 -13
  10. package/dist/font-face.js.map +1 -1
  11. package/dist/lib.d.ts +1 -3
  12. package/dist/lib.d.ts.map +1 -1
  13. package/dist/lib.js +3 -4
  14. package/dist/lib.js.map +1 -1
  15. package/dist/path.d.ts.map +1 -1
  16. package/dist/path.js +8 -5
  17. package/dist/path.js.map +1 -1
  18. package/dist/pattern.d.ts +3 -1
  19. package/dist/pattern.d.ts.map +1 -1
  20. package/dist/pattern.js +24 -6
  21. package/dist/pattern.js.map +1 -1
  22. package/dist/region.d.ts.map +1 -1
  23. package/dist/region.js +6 -5
  24. package/dist/region.js.map +1 -1
  25. package/dist/scaled-font.d.ts +3 -5
  26. package/dist/scaled-font.d.ts.map +1 -1
  27. package/dist/scaled-font.js +3 -62
  28. package/dist/scaled-font.js.map +1 -1
  29. package/dist/status.d.ts +6 -0
  30. package/dist/status.d.ts.map +1 -0
  31. package/dist/status.js +17 -0
  32. package/dist/status.js.map +1 -0
  33. package/dist/structs.d.ts +1 -1
  34. package/dist/structs.d.ts.map +1 -1
  35. package/dist/structs.js +1 -1
  36. package/dist/structs.js.map +1 -1
  37. package/dist/surface.d.ts +2 -7
  38. package/dist/surface.d.ts.map +1 -1
  39. package/dist/surface.js +21 -25
  40. package/dist/surface.js.map +1 -1
  41. package/dist/text.d.ts.map +1 -1
  42. package/dist/text.js +20 -17
  43. package/dist/text.js.map +1 -1
  44. package/package.json +60 -61
  45. package/src/context.ts +15 -16
  46. package/src/font-face.ts +3 -25
  47. package/src/lib.ts +2 -5
  48. package/src/path.ts +8 -5
  49. package/src/pattern.ts +31 -7
  50. package/src/region.ts +5 -5
  51. package/src/scaled-font.ts +3 -92
  52. package/src/status.ts +23 -0
  53. package/src/structs.ts +1 -1
  54. package/src/surface.ts +28 -29
  55. 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 and `Surface.mapToImage` use. */
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, t.float64, 0) as number,
140
- y: read(buffer, t.float64, 8) as number,
141
- width: read(buffer, t.float64, 16) as number,
142
- height: read(buffer, t.float64, 24) as number,
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
- return wrapSurface(cairoSurfaceCreateSimilar(getHandle(other), content, width, height));
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): Surface {
182
- return wrapSurface(cairoSurfaceCreateSimilarImage(getHandle(other), format, width, height));
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
- return wrapSurface(cairoSurfaceCreateForRectangle(getHandle(target), x, y, width, height));
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(cairoImageSurfaceCreate(format, width, height) as ExternalObject<Handle>, this);
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; a missing or invalid file yields a surface in an error status. */
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>, this);
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, t.uint8, index) as number);
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, read, t, write } from "@gtkx/runtime";
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, t.uint64, offset, glyph.index);
15
- write(buffer, t.float64, offset + 8, glyph.x);
16
- write(buffer, t.float64, offset + 16, glyph.y);
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, t.int32, offset, cluster.numBytes);
29
- write(buffer, t.int32, offset + 4, cluster.numGlyphs);
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, t.float64, 0) as number,
41
- yBearing: read(handle, t.float64, 8) as number,
42
- width: read(handle, t.float64, 16) as number,
43
- height: read(handle, t.float64, 24) as number,
44
- xAdvance: read(handle, t.float64, 32) as number,
45
- yAdvance: read(handle, t.float64, 40) as number,
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, t.float64, 0) as number,
50
- descent: read(handle, t.float64, 8) as number,
51
- height: read(handle, t.float64, 16) as number,
52
- maxXAdvance: read(handle, t.float64, 24) as number,
53
- maxYAdvance: read(handle, t.float64, 32) as number,
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 };