@gtkx/cairo 1.2.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/dist/context.d.ts +229 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +646 -0
- package/dist/context.js.map +1 -0
- package/dist/device.d.ts +21 -0
- package/dist/device.d.ts.map +1 -0
- package/dist/device.js +39 -0
- package/dist/device.js.map +1 -0
- package/dist/enums.d.ts +526 -0
- package/dist/enums.d.ts.map +1 -0
- package/dist/enums.js +482 -0
- package/dist/enums.js.map +1 -0
- package/dist/font-face.d.ts +55 -0
- package/dist/font-face.d.ts.map +1 -0
- package/dist/font-face.js +103 -0
- package/dist/font-face.js.map +1 -0
- package/dist/font-options.d.ts +43 -0
- package/dist/font-options.d.ts.map +1 -0
- package/dist/font-options.js +95 -0
- package/dist/font-options.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/lib.d.ts +36 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +120 -0
- package/dist/lib.js.map +1 -0
- package/dist/matrix.d.ts +40 -0
- package/dist/matrix.d.ts.map +1 -0
- package/dist/matrix.js +93 -0
- package/dist/matrix.js.map +1 -0
- package/dist/path.d.ts +14 -0
- package/dist/path.d.ts.map +1 -0
- package/dist/path.js +67 -0
- package/dist/path.js.map +1 -0
- package/dist/pattern.d.ts +95 -0
- package/dist/pattern.d.ts.map +1 -0
- package/dist/pattern.js +250 -0
- package/dist/pattern.js.map +1 -0
- package/dist/region.d.ts +59 -0
- package/dist/region.d.ts.map +1 -0
- package/dist/region.js +154 -0
- package/dist/region.js.map +1 -0
- package/dist/scaled-font.d.ts +43 -0
- package/dist/scaled-font.d.ts.map +1 -0
- package/dist/scaled-font.js +156 -0
- package/dist/scaled-font.js.map +1 -0
- package/dist/structs.d.ts +120 -0
- package/dist/structs.d.ts.map +1 -0
- package/dist/structs.js +185 -0
- package/dist/structs.js.map +1 -0
- package/dist/surface.d.ts +98 -0
- package/dist/surface.d.ts.map +1 -0
- package/dist/surface.js +274 -0
- package/dist/surface.js.map +1 -0
- package/dist/text.d.ts +10 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +45 -0
- package/dist/text.js.map +1 -0
- package/dist/types.d.ts +245 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/version.d.ts +9 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +13 -0
- package/dist/version.js.map +1 -0
- package/package.json +64 -0
- package/src/context.ts +899 -0
- package/src/device.ts +50 -0
- package/src/enums.ts +571 -0
- package/src/font-face.ts +157 -0
- package/src/font-options.ts +142 -0
- package/src/index.ts +28 -0
- package/src/lib.ts +186 -0
- package/src/matrix.ts +135 -0
- package/src/path.ts +87 -0
- package/src/pattern.ts +423 -0
- package/src/region.ts +216 -0
- package/src/scaled-font.ts +268 -0
- package/src/structs.ts +306 -0
- package/src/surface.ts +411 -0
- package/src/text.ts +56 -0
- package/src/types.ts +290 -0
- package/src/version.ts +16 -0
package/src/region.ts
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import {
|
|
2
|
+
alloc,
|
|
3
|
+
type ExternalObject,
|
|
4
|
+
getHandle,
|
|
5
|
+
type Handle,
|
|
6
|
+
registerWrapperClass,
|
|
7
|
+
setHandle,
|
|
8
|
+
t,
|
|
9
|
+
wrapHandle,
|
|
10
|
+
write,
|
|
11
|
+
} from "@gtkx/runtime";
|
|
12
|
+
import type { RegionOverlap, Status } from "./enums.js";
|
|
13
|
+
import type { RectangleData } from "./types.js";
|
|
14
|
+
import {
|
|
15
|
+
bindCairo,
|
|
16
|
+
type BoundFunction,
|
|
17
|
+
cairoGType,
|
|
18
|
+
RECTANGLE_INT_ARRAY_T,
|
|
19
|
+
RECTANGLE_INT_T,
|
|
20
|
+
REGION_FULL_T,
|
|
21
|
+
REGION_T,
|
|
22
|
+
} from "./lib.js";
|
|
23
|
+
import { RectangleInt } from "./structs.js";
|
|
24
|
+
|
|
25
|
+
const REGION_TYPE = cairoGType("cairo_gobject_region_get_type");
|
|
26
|
+
const RECTANGLE_INT_SIZE = 16;
|
|
27
|
+
const BINARY_OP_ARGS = [REGION_T, REGION_T];
|
|
28
|
+
const RECTANGLE_OP_ARGS = [REGION_T, RECTANGLE_INT_T];
|
|
29
|
+
const cairoRegionCreate = bindCairo("cairo_region_create", [], REGION_FULL_T);
|
|
30
|
+
const cairoRegionCreateRectangle = bindCairo("cairo_region_create_rectangle", [RECTANGLE_INT_T], REGION_FULL_T);
|
|
31
|
+
|
|
32
|
+
const cairoRegionCreateRectangles = bindCairo(
|
|
33
|
+
"cairo_region_create_rectangles",
|
|
34
|
+
[RECTANGLE_INT_ARRAY_T, t.int32],
|
|
35
|
+
REGION_FULL_T,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const cairoRegionCopy = bindCairo("cairo_region_copy", [REGION_T], REGION_FULL_T);
|
|
39
|
+
const cairoRegionStatus = bindCairo("cairo_region_status", [REGION_T], t.int32);
|
|
40
|
+
const cairoRegionGetExtents = bindCairo("cairo_region_get_extents", [REGION_T, RECTANGLE_INT_T], t.void);
|
|
41
|
+
const cairoRegionNumRectangles = bindCairo("cairo_region_num_rectangles", [REGION_T], t.int32);
|
|
42
|
+
const cairoRegionGetRectangle = bindCairo("cairo_region_get_rectangle", [REGION_T, t.int32, RECTANGLE_INT_T], t.void);
|
|
43
|
+
const cairoRegionIsEmpty = bindCairo("cairo_region_is_empty", [REGION_T], t.boolean);
|
|
44
|
+
const cairoRegionContainsPoint = bindCairo("cairo_region_contains_point", [REGION_T, t.int32, t.int32], t.boolean);
|
|
45
|
+
const cairoRegionContainsRectangle = bindCairo("cairo_region_contains_rectangle", RECTANGLE_OP_ARGS, t.int32);
|
|
46
|
+
const cairoRegionEqual = bindCairo("cairo_region_equal", BINARY_OP_ARGS, t.boolean);
|
|
47
|
+
const cairoRegionTranslate = bindCairo("cairo_region_translate", [REGION_T, t.int32, t.int32], t.void);
|
|
48
|
+
const cairoRegionIntersect = bindCairo("cairo_region_intersect", BINARY_OP_ARGS, t.int32);
|
|
49
|
+
const cairoRegionSubtract = bindCairo("cairo_region_subtract", BINARY_OP_ARGS, t.int32);
|
|
50
|
+
const cairoRegionUnion = bindCairo("cairo_region_union", BINARY_OP_ARGS, t.int32);
|
|
51
|
+
const cairoRegionXor = bindCairo("cairo_region_xor", BINARY_OP_ARGS, t.int32);
|
|
52
|
+
const cairoRegionIntersectRectangle = bindCairo("cairo_region_intersect_rectangle", RECTANGLE_OP_ARGS, t.int32);
|
|
53
|
+
const cairoRegionSubtractRectangle = bindCairo("cairo_region_subtract_rectangle", RECTANGLE_OP_ARGS, t.int32);
|
|
54
|
+
const cairoRegionUnionRectangle = bindCairo("cairo_region_union_rectangle", RECTANGLE_OP_ARGS, t.int32);
|
|
55
|
+
const cairoRegionXorRectangle = bindCairo("cairo_region_xor_rectangle", RECTANGLE_OP_ARGS, t.int32);
|
|
56
|
+
|
|
57
|
+
const allocRectangleBuffer = (rects: RectangleData[]): ExternalObject<Handle> => {
|
|
58
|
+
const buffer = alloc(rects.length * RECTANGLE_INT_SIZE);
|
|
59
|
+
let offset = 0;
|
|
60
|
+
|
|
61
|
+
for (const rect of rects) {
|
|
62
|
+
write(buffer, t.int32, offset, rect.x);
|
|
63
|
+
write(buffer, t.int32, offset + 4, rect.y);
|
|
64
|
+
write(buffer, t.int32, offset + 8, rect.width);
|
|
65
|
+
write(buffer, t.int32, offset + 12, rect.height);
|
|
66
|
+
offset += RECTANGLE_INT_SIZE;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return buffer;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const applyRegionOp = (self: object, boundFn: BoundFunction, arg: object): void => {
|
|
73
|
+
boundFn(getHandle(self), getHandle(arg));
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A cairo region (`cairo_region_t`): a set of integer rectangles, as GTK uses for clip and damage areas.
|
|
78
|
+
* Set operations modify the region in place.
|
|
79
|
+
*/
|
|
80
|
+
class Region {
|
|
81
|
+
static {
|
|
82
|
+
registerWrapperClass(this, REGION_TYPE);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Creates an empty region. */
|
|
86
|
+
static empty(): Region {
|
|
87
|
+
return wrapHandle(cairoRegionCreate() as ExternalObject<Handle>, this);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Creates a region with the same rectangles as `original`. */
|
|
91
|
+
static copy(original: Region): Region {
|
|
92
|
+
return wrapHandle(cairoRegionCopy(getHandle(original)) as ExternalObject<Handle>, this);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Creates a region covering `rect`. */
|
|
96
|
+
static forRectangle(rect: RectangleInt): Region {
|
|
97
|
+
return wrapHandle(cairoRegionCreateRectangle(getHandle(rect)) as ExternalObject<Handle>, this);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Creates a region covering the union of `rects`; an empty list yields an empty region. */
|
|
101
|
+
static createRectangles(rects: RectangleData[]): Region {
|
|
102
|
+
if (rects.length === 0) {
|
|
103
|
+
return this.empty();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const buffer = allocRectangleBuffer(rects);
|
|
107
|
+
|
|
108
|
+
return wrapHandle(cairoRegionCreateRectangles(buffer, rects.length) as ExternalObject<Handle>, this);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** GType of `CairoRegion`, the boxed type this class is registered under. */
|
|
112
|
+
declare __type__: bigint;
|
|
113
|
+
|
|
114
|
+
/** Creates a region covering `rect`. */
|
|
115
|
+
constructor(rect: RectangleInt) {
|
|
116
|
+
setHandle(this, cairoRegionCreateRectangle(getHandle(rect)) as ExternalObject<Handle>);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Returns a region with the same rectangles as this one. */
|
|
120
|
+
copy(): Region {
|
|
121
|
+
return wrapHandle(cairoRegionCopy(getHandle(this)) as ExternalObject<Handle>, Region);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Returns the error status of the region, `Status.SUCCESS` when it is usable. */
|
|
125
|
+
status(): Status {
|
|
126
|
+
return cairoRegionStatus(getHandle(this)) as Status;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Returns the bounding rectangle of the region. */
|
|
130
|
+
getExtents(): RectangleInt {
|
|
131
|
+
const rect = new RectangleInt();
|
|
132
|
+
cairoRegionGetExtents(getHandle(this), getHandle(rect));
|
|
133
|
+
|
|
134
|
+
return rect;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Returns how many rectangles make up the region. */
|
|
138
|
+
numRectangles(): number {
|
|
139
|
+
return cairoRegionNumRectangles(getHandle(this)) as number;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Returns the `nth` rectangle of the region, counting from zero. */
|
|
143
|
+
getRectangle(nth: number): RectangleInt {
|
|
144
|
+
const rect = new RectangleInt();
|
|
145
|
+
cairoRegionGetRectangle(getHandle(this), nth, getHandle(rect));
|
|
146
|
+
|
|
147
|
+
return rect;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Returns whether the region covers no area. */
|
|
151
|
+
isEmpty(): boolean {
|
|
152
|
+
return cairoRegionIsEmpty(getHandle(this)) as boolean;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Returns whether the point `(x, y)` lies inside the region. */
|
|
156
|
+
containsPoint(x: number, y: number): boolean {
|
|
157
|
+
return cairoRegionContainsPoint(getHandle(this), x, y) as boolean;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/** Returns whether `rect` lies inside, outside or partly inside the region. */
|
|
161
|
+
containsRectangle(rect: RectangleInt): RegionOverlap {
|
|
162
|
+
return cairoRegionContainsRectangle(getHandle(this), getHandle(rect)) as RegionOverlap;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Returns whether the region covers the same area as `other`. */
|
|
166
|
+
equal(other: Region): boolean {
|
|
167
|
+
return cairoRegionEqual(getHandle(this), getHandle(other)) as boolean;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Moves the region by `dx` and `dy`. */
|
|
171
|
+
translate(dx: number, dy: number): void {
|
|
172
|
+
cairoRegionTranslate(getHandle(this), dx, dy);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** Keeps only the area the region shares with `other`. */
|
|
176
|
+
intersect(other: Region): void {
|
|
177
|
+
applyRegionOp(this, cairoRegionIntersect, other);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Keeps only the area the region shares with `rect`. */
|
|
181
|
+
intersectRectangle(rect: RectangleInt): void {
|
|
182
|
+
applyRegionOp(this, cairoRegionIntersectRectangle, rect);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Removes the area of `other` from the region. */
|
|
186
|
+
subtract(other: Region): void {
|
|
187
|
+
applyRegionOp(this, cairoRegionSubtract, other);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** Removes the area of `rect` from the region. */
|
|
191
|
+
subtractRectangle(rect: RectangleInt): void {
|
|
192
|
+
applyRegionOp(this, cairoRegionSubtractRectangle, rect);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Adds the area of `other` to the region. */
|
|
196
|
+
union(other: Region): void {
|
|
197
|
+
applyRegionOp(this, cairoRegionUnion, other);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** Adds the area of `rect` to the region. */
|
|
201
|
+
unionRectangle(rect: RectangleInt): void {
|
|
202
|
+
applyRegionOp(this, cairoRegionUnionRectangle, rect);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** Keeps the area covered by exactly one of the region and `other`. */
|
|
206
|
+
xor(other: Region): void {
|
|
207
|
+
applyRegionOp(this, cairoRegionXor, other);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** Keeps the area covered by exactly one of the region and `rect`. */
|
|
211
|
+
xorRectangle(rect: RectangleInt): void {
|
|
212
|
+
applyRegionOp(this, cairoRegionXorRectangle, rect);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export { Region };
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type ExternalObject,
|
|
3
|
+
getHandle,
|
|
4
|
+
type Handle,
|
|
5
|
+
read,
|
|
6
|
+
registerWrapperClass,
|
|
7
|
+
setHandle,
|
|
8
|
+
t,
|
|
9
|
+
wrapHandle,
|
|
10
|
+
} from "@gtkx/runtime";
|
|
11
|
+
import type { FontType, Status, TextClusterFlags } from "./enums.js";
|
|
12
|
+
import type { CairoGlyph, CairoTextCluster, FontExtents, TextExtents } from "./types.js";
|
|
13
|
+
import { FontFace } from "./font-face.js";
|
|
14
|
+
import { FontOptions } from "./font-options.js";
|
|
15
|
+
import {
|
|
16
|
+
bindCairo,
|
|
17
|
+
type BoundFunction,
|
|
18
|
+
cairoGType,
|
|
19
|
+
FONT_EXTENTS_T,
|
|
20
|
+
FONT_FACE_T,
|
|
21
|
+
FONT_OPTIONS_T,
|
|
22
|
+
GLYPH_T,
|
|
23
|
+
MATRIX_T,
|
|
24
|
+
SCALED_FONT_FULL_T,
|
|
25
|
+
SCALED_FONT_T,
|
|
26
|
+
TEXT_CLUSTER_T,
|
|
27
|
+
TEXT_EXTENTS_T,
|
|
28
|
+
} from "./lib.js";
|
|
29
|
+
import { allocMatrix, Matrix } from "./matrix.js";
|
|
30
|
+
import { allocFontExtents, allocGlyphBuffer, allocTextExtents, readFontExtents, readTextExtents } from "./text.js";
|
|
31
|
+
|
|
32
|
+
const SCALED_FONT_TYPE = cairoGType("cairo_gobject_scaled_font_get_type");
|
|
33
|
+
const GLYPH_SIZE = 24;
|
|
34
|
+
const CLUSTER_SIZE = 8;
|
|
35
|
+
const cairoScaledFontStatus = bindCairo("cairo_scaled_font_status", [SCALED_FONT_T], t.int32);
|
|
36
|
+
const cairoScaledFontExtents = bindCairo("cairo_scaled_font_extents", [SCALED_FONT_T, FONT_EXTENTS_T], t.void);
|
|
37
|
+
const cairoScaledFontGetFontFace = bindCairo("cairo_scaled_font_get_font_face", [SCALED_FONT_T], FONT_FACE_T);
|
|
38
|
+
const cairoScaledFontGetFontMatrix = bindCairo("cairo_scaled_font_get_font_matrix", [SCALED_FONT_T, MATRIX_T], t.void);
|
|
39
|
+
const cairoScaledFontGetCtm = bindCairo("cairo_scaled_font_get_ctm", [SCALED_FONT_T, MATRIX_T], t.void);
|
|
40
|
+
const cairoScaledFontGetType = bindCairo("cairo_scaled_font_get_type", [SCALED_FONT_T], t.int32);
|
|
41
|
+
const cairoGlyphFree = bindCairo("cairo_glyph_free", [GLYPH_T], t.void);
|
|
42
|
+
const cairoTextClusterFree = bindCairo("cairo_text_cluster_free", [TEXT_CLUSTER_T], t.void);
|
|
43
|
+
|
|
44
|
+
const cairoScaledFontCreate = bindCairo(
|
|
45
|
+
"cairo_scaled_font_create",
|
|
46
|
+
[FONT_FACE_T, MATRIX_T, MATRIX_T, FONT_OPTIONS_T],
|
|
47
|
+
SCALED_FONT_FULL_T,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const cairoScaledFontTextExtents = bindCairo(
|
|
51
|
+
"cairo_scaled_font_text_extents",
|
|
52
|
+
[SCALED_FONT_T, t.string("full"), TEXT_EXTENTS_T],
|
|
53
|
+
t.void,
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const cairoScaledFontGlyphExtents = bindCairo(
|
|
57
|
+
"cairo_scaled_font_glyph_extents",
|
|
58
|
+
[SCALED_FONT_T, GLYPH_T, t.int32, TEXT_EXTENTS_T],
|
|
59
|
+
t.void,
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
const cairoScaledFontGetFontOptions = bindCairo(
|
|
63
|
+
"cairo_scaled_font_get_font_options",
|
|
64
|
+
[SCALED_FONT_T, FONT_OPTIONS_T],
|
|
65
|
+
t.void,
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const cairoScaledFontGetScaleMatrix = bindCairo(
|
|
69
|
+
"cairo_scaled_font_get_scale_matrix",
|
|
70
|
+
[SCALED_FONT_T, MATRIX_T],
|
|
71
|
+
t.void,
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const cairoScaledFontGetReferenceCount = bindCairo(
|
|
75
|
+
"cairo_scaled_font_get_reference_count",
|
|
76
|
+
[SCALED_FONT_T],
|
|
77
|
+
t.int32,
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const cairoScaledFontTextToGlyphs = bindCairo(
|
|
81
|
+
"cairo_scaled_font_text_to_glyphs",
|
|
82
|
+
[
|
|
83
|
+
SCALED_FONT_T,
|
|
84
|
+
t.float64,
|
|
85
|
+
t.float64,
|
|
86
|
+
t.string("full"),
|
|
87
|
+
t.int32,
|
|
88
|
+
t.ref(t.struct("borrowed")),
|
|
89
|
+
t.ref(t.int32),
|
|
90
|
+
t.ref(t.struct("borrowed")),
|
|
91
|
+
t.ref(t.int32),
|
|
92
|
+
t.ref(t.int32),
|
|
93
|
+
],
|
|
94
|
+
t.int32,
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const readMatrixVia = (self: ScaledFont, boundFn: BoundFunction): Matrix => {
|
|
98
|
+
const { handle, matrix } = allocMatrix();
|
|
99
|
+
boundFn(getHandle(self), handle);
|
|
100
|
+
|
|
101
|
+
return matrix;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const readGlyphs = (buffer: ExternalObject<Handle> | null, count: number): CairoGlyph[] => {
|
|
105
|
+
if (buffer === null) {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return Array.from({ length: count }, (_, index) => {
|
|
110
|
+
const offset = index * GLYPH_SIZE;
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
index: read(buffer, t.uint64, offset) as number,
|
|
114
|
+
x: read(buffer, t.float64, offset + 8) as number,
|
|
115
|
+
y: read(buffer, t.float64, offset + 16) as number,
|
|
116
|
+
};
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const readClusters = (buffer: ExternalObject<Handle> | null, count: number): CairoTextCluster[] => {
|
|
121
|
+
if (buffer === null) {
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return Array.from({ length: count }, (_, index) => {
|
|
126
|
+
const offset = index * CLUSTER_SIZE;
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
numBytes: read(buffer, t.int32, offset) as number,
|
|
130
|
+
numGlyphs: read(buffer, t.int32, offset + 4) as number,
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* A cairo scaled font (`cairo_scaled_font_t`): a font face frozen at a given font matrix, transformation and
|
|
137
|
+
* set of font options, ready to measure and shape text.
|
|
138
|
+
*/
|
|
139
|
+
class ScaledFont {
|
|
140
|
+
static {
|
|
141
|
+
registerWrapperClass(this, SCALED_FONT_TYPE);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Creates a scaled font, the same as `new ScaledFont(fontFace, fontMatrix, ctm, options)`. */
|
|
145
|
+
static create(fontFace: FontFace, fontMatrix: Matrix, ctm: Matrix, options: FontOptions): ScaledFont {
|
|
146
|
+
return new ScaledFont(fontFace, fontMatrix, ctm, options);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** GType of `CairoScaledFont`, the boxed type this class is registered under. */
|
|
150
|
+
declare __type__: bigint;
|
|
151
|
+
|
|
152
|
+
/** Creates a scaled font from a font face, a font matrix, a user-to-device transformation and font options. */
|
|
153
|
+
constructor(fontFace: FontFace, fontMatrix: Matrix, ctm: Matrix, options: FontOptions) {
|
|
154
|
+
const handle = cairoScaledFontCreate(
|
|
155
|
+
getHandle(fontFace),
|
|
156
|
+
getHandle(fontMatrix),
|
|
157
|
+
getHandle(ctm),
|
|
158
|
+
getHandle(options),
|
|
159
|
+
) as ExternalObject<Handle>;
|
|
160
|
+
|
|
161
|
+
setHandle(this, handle);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** Returns the error status of the scaled font, `Status.SUCCESS` when it is usable. */
|
|
165
|
+
status(): Status {
|
|
166
|
+
return cairoScaledFontStatus(getHandle(this)) as Status;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Returns the metrics of the font. */
|
|
170
|
+
extents(): FontExtents {
|
|
171
|
+
const ext = allocFontExtents();
|
|
172
|
+
cairoScaledFontExtents(getHandle(this), ext);
|
|
173
|
+
|
|
174
|
+
return readFontExtents(ext);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Measures `text` with the font. */
|
|
178
|
+
textExtents(text: string): TextExtents {
|
|
179
|
+
const ext = allocTextExtents();
|
|
180
|
+
cairoScaledFontTextExtents(getHandle(this), text, ext);
|
|
181
|
+
|
|
182
|
+
return readTextExtents(ext);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Measures positioned glyphs with the font. */
|
|
186
|
+
glyphExtents(glyphs: CairoGlyph[]): TextExtents {
|
|
187
|
+
const buf = allocGlyphBuffer(glyphs);
|
|
188
|
+
const ext = allocTextExtents();
|
|
189
|
+
cairoScaledFontGlyphExtents(getHandle(this), buf, glyphs.length, ext);
|
|
190
|
+
|
|
191
|
+
return readTextExtents(ext);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Returns the font face the scaled font was created from, wrapped as its concrete class. */
|
|
195
|
+
getFontFace(): FontFace {
|
|
196
|
+
return wrapHandle(cairoScaledFontGetFontFace(getHandle(this)) as ExternalObject<Handle>, FontFace);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** Returns a copy of the font options the scaled font was created with. */
|
|
200
|
+
getFontOptions(): FontOptions {
|
|
201
|
+
const options = FontOptions.create();
|
|
202
|
+
cairoScaledFontGetFontOptions(getHandle(this), getHandle(options));
|
|
203
|
+
|
|
204
|
+
return options;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** Returns the font matrix the scaled font was created with. */
|
|
208
|
+
getFontMatrix(): Matrix {
|
|
209
|
+
return readMatrixVia(this, cairoScaledFontGetFontMatrix);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** Returns the user-to-device transformation the scaled font was created with. */
|
|
213
|
+
getCtm(): Matrix {
|
|
214
|
+
return readMatrixVia(this, cairoScaledFontGetCtm);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** Returns the scale matrix: the font matrix multiplied by the transformation, without translation. */
|
|
218
|
+
getScaleMatrix(): Matrix {
|
|
219
|
+
return readMatrixVia(this, cairoScaledFontGetScaleMatrix);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Returns the backend the scaled font belongs to. */
|
|
223
|
+
getType(): FontType {
|
|
224
|
+
return cairoScaledFontGetType(getHandle(this)) as FontType;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** Returns the reference count of the scaled font. */
|
|
228
|
+
getReferenceCount(): number {
|
|
229
|
+
return cairoScaledFontGetReferenceCount(getHandle(this)) as number;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** Shapes `text` starting at `(x, y)` into glyphs, clusters and the flags describing their order. */
|
|
233
|
+
textToGlyphs(x: number, y: number, text: string): [CairoGlyph[], CairoTextCluster[], TextClusterFlags] {
|
|
234
|
+
const glyphsRef: { value: ExternalObject<Handle> | null } = { value: null };
|
|
235
|
+
const numGlyphsRef = { value: 0 };
|
|
236
|
+
const clustersRef: { value: ExternalObject<Handle> | null } = { value: null };
|
|
237
|
+
const numClustersRef = { value: 0 };
|
|
238
|
+
const clusterFlagsRef = { value: 0 };
|
|
239
|
+
|
|
240
|
+
cairoScaledFontTextToGlyphs(
|
|
241
|
+
getHandle(this),
|
|
242
|
+
x,
|
|
243
|
+
y,
|
|
244
|
+
text,
|
|
245
|
+
-1,
|
|
246
|
+
glyphsRef,
|
|
247
|
+
numGlyphsRef,
|
|
248
|
+
clustersRef,
|
|
249
|
+
numClustersRef,
|
|
250
|
+
clusterFlagsRef,
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
const glyphs = readGlyphs(glyphsRef.value, numGlyphsRef.value);
|
|
254
|
+
const clusters = readClusters(clustersRef.value, numClustersRef.value);
|
|
255
|
+
|
|
256
|
+
if (glyphsRef.value !== null) {
|
|
257
|
+
cairoGlyphFree(glyphsRef.value);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (clustersRef.value !== null) {
|
|
261
|
+
cairoTextClusterFree(clustersRef.value);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return [glyphs, clusters, clusterFlagsRef.value as TextClusterFlags];
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export { ScaledFont };
|