cvdl-ts 1.0.9 → 1.0.10
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/README.md +5 -0
- package/dist/Layout.d.ts +8 -4
- package/dist/Layout.js +79 -25
- package/package.json +1 -1
package/README.md
ADDED
package/dist/Layout.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export declare class SectionLayout {
|
|
|
18
18
|
toJson(): any;
|
|
19
19
|
width(): Width;
|
|
20
20
|
is_container(): boolean;
|
|
21
|
+
is_fill(): boolean;
|
|
21
22
|
is_ref(): boolean;
|
|
22
23
|
type_(): "Stack" | "Row" | "Elem";
|
|
23
24
|
tag_(): "Stack" | "FlexRow" | "FrozenRow" | "Ref" | "Text";
|
|
@@ -25,6 +26,7 @@ export declare class SectionLayout {
|
|
|
25
26
|
with_margin(margin: Margin): SectionLayout;
|
|
26
27
|
with_alignment(alignment: Alignment): SectionLayout;
|
|
27
28
|
with_width(width: Width): SectionLayout;
|
|
29
|
+
total_elements_width(): number;
|
|
28
30
|
is_instantiated(): boolean;
|
|
29
31
|
instantiate(section: Map<string, ItemContent>): SectionLayout;
|
|
30
32
|
static instantiate_ref_element(element: Elem, section: Map<string, ItemContent>): SectionLayout;
|
|
@@ -42,8 +44,9 @@ export declare class Stack {
|
|
|
42
44
|
margin: Margin;
|
|
43
45
|
alignment: Alignment;
|
|
44
46
|
width: Width;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
is_fill: boolean;
|
|
48
|
+
constructor(elements: SectionLayout[], margin?: Margin, alignment?: Alignment, width?: Width, is_fill?: boolean);
|
|
49
|
+
static stack(elements: SectionLayout[], margin?: Margin, alignment?: Alignment, width?: Width, is_fill?: boolean): SectionLayout;
|
|
47
50
|
copy(): Stack;
|
|
48
51
|
static default_(): Stack;
|
|
49
52
|
instantiate(section: Map<string, ItemContent>): Stack;
|
|
@@ -61,8 +64,9 @@ export declare class Row {
|
|
|
61
64
|
alignment: Alignment;
|
|
62
65
|
width: Width;
|
|
63
66
|
is_frozen: boolean;
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
is_fill: boolean;
|
|
68
|
+
constructor(elements: SectionLayout[], is_frozen?: boolean, margin?: Margin, alignment?: Alignment, width?: Width, is_fill?: boolean);
|
|
69
|
+
static row(elements: SectionLayout[], is_frozen?: boolean, margin?: Margin, alignment?: Alignment, width?: Width, is_fill?: boolean): SectionLayout;
|
|
66
70
|
copy(): Row;
|
|
67
71
|
static default_(): Row;
|
|
68
72
|
instantiate(section: Map<string, ItemContent>): Row;
|
package/dist/Layout.js
CHANGED
|
@@ -105,6 +105,16 @@ class SectionLayout {
|
|
|
105
105
|
is_container() {
|
|
106
106
|
return this.inner.tag === "Stack" || this.inner.tag === "Row";
|
|
107
107
|
}
|
|
108
|
+
is_fill() {
|
|
109
|
+
switch (this.type_()) {
|
|
110
|
+
case "Stack":
|
|
111
|
+
return this.inner.is_fill && this.inner.elements.map(e => e.is_fill()).reduce((a, b) => a && b, true);
|
|
112
|
+
case "Row":
|
|
113
|
+
return this.inner.is_fill && this.inner.elements.map(e => e.is_fill()).reduce((a, b) => a && b, true);
|
|
114
|
+
case "Elem":
|
|
115
|
+
return this.inner.is_fill;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
108
118
|
is_ref() {
|
|
109
119
|
return this.inner.tag === "Elem" && this.inner.is_ref;
|
|
110
120
|
}
|
|
@@ -143,6 +153,14 @@ class SectionLayout {
|
|
|
143
153
|
this.inner = this.inner.with_width(width);
|
|
144
154
|
return this;
|
|
145
155
|
}
|
|
156
|
+
total_elements_width() {
|
|
157
|
+
if (this.is_container()) {
|
|
158
|
+
return this.inner.elements.map(e => e.total_elements_width()).reduce((a, b) => a + b, 0.0);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
return Width_1.Width.get_fixed_unchecked(this.width());
|
|
162
|
+
}
|
|
163
|
+
}
|
|
146
164
|
is_instantiated() {
|
|
147
165
|
if (this.is_container()) {
|
|
148
166
|
return this.inner.elements.map(e => e.is_instantiated()).reduce((a, b) => a && b, true);
|
|
@@ -189,7 +207,7 @@ class SectionLayout {
|
|
|
189
207
|
if (this.inner.tag === "Elem" && this.inner.is_ref) {
|
|
190
208
|
throw new Error("Cannot propagate widths of uninstantiated layout");
|
|
191
209
|
}
|
|
192
|
-
this.inner = this.inner.bound_width(bound);
|
|
210
|
+
this.inner = this.inner.bound_width(bound - this.inner.margin.left - this.inner.margin.right);
|
|
193
211
|
return this;
|
|
194
212
|
}
|
|
195
213
|
scale_width(document_width) {
|
|
@@ -222,6 +240,17 @@ class SectionLayout {
|
|
|
222
240
|
case "Stack":
|
|
223
241
|
case "Row":
|
|
224
242
|
this.inner.elements = this.inner.elements.map(e => e.fill_fonts(font_dict));
|
|
243
|
+
console.error(this, this.is_fill());
|
|
244
|
+
if (this.is_fill()) {
|
|
245
|
+
const total_width = this.total_elements_width();
|
|
246
|
+
console.error(this);
|
|
247
|
+
console.error(total_width);
|
|
248
|
+
console.error(this.inner.elements);
|
|
249
|
+
if (total_width <= Width_1.Width.get_fixed_unchecked(this.width())) {
|
|
250
|
+
// throw `Cannot fill fonts of row with width ${JSON.stringify(this.width())} and total width ${total_width}`
|
|
251
|
+
this.inner = this.inner.with_width(Width_1.Width.absolute(total_width));
|
|
252
|
+
}
|
|
253
|
+
}
|
|
225
254
|
break;
|
|
226
255
|
case "Elem":
|
|
227
256
|
this.inner = this.inner.fill_fonts(font_dict);
|
|
@@ -262,6 +291,11 @@ class SectionLayout {
|
|
|
262
291
|
}
|
|
263
292
|
const elem = this.inner;
|
|
264
293
|
const lines = elem.break_lines(font_dict).map(l => new SectionLayout(l));
|
|
294
|
+
// Make last line left if it's justified
|
|
295
|
+
if (lines[lines.length - 1].inner.alignment === "Justified") {
|
|
296
|
+
console.error(lines[lines.length - 1]);
|
|
297
|
+
lines[lines.length - 1] = lines[lines.length - 1].with_alignment("Left");
|
|
298
|
+
}
|
|
265
299
|
return new SectionLayout(new Stack(lines, elem.margin, elem.alignment, elem.width));
|
|
266
300
|
}
|
|
267
301
|
}
|
|
@@ -278,6 +312,7 @@ class SectionLayout {
|
|
|
278
312
|
switch (this.type_()) {
|
|
279
313
|
case "Stack": {
|
|
280
314
|
const stack = this.inner;
|
|
315
|
+
top_left = top_left.move_y_by(stack.margin.top).move_x_by(stack.margin.left);
|
|
281
316
|
for (const element of stack.elements) {
|
|
282
317
|
depth = element.compute_textbox_positions(textbox_positions, top_left, font_dict);
|
|
283
318
|
top_left = top_left.move_y_to(depth);
|
|
@@ -286,6 +321,7 @@ class SectionLayout {
|
|
|
286
321
|
}
|
|
287
322
|
case "Row": {
|
|
288
323
|
const row = this.inner;
|
|
324
|
+
top_left = top_left.move_y_by(row.margin.top).move_x_by(row.margin.left);
|
|
289
325
|
let per_elem_space = 0.0;
|
|
290
326
|
switch (row.alignment) {
|
|
291
327
|
case "Center":
|
|
@@ -315,6 +351,7 @@ class SectionLayout {
|
|
|
315
351
|
}
|
|
316
352
|
const height = elem.font.get_height(font_dict);
|
|
317
353
|
const width = Width_1.Width.get_fixed_unchecked(elem.text_width);
|
|
354
|
+
top_left = top_left.move_y_by(elem.margin.top).move_x_by(elem.margin.left);
|
|
318
355
|
switch (elem.alignment) {
|
|
319
356
|
case "Center":
|
|
320
357
|
top_left = top_left.move_x_by((Width_1.Width.get_fixed_unchecked(elem.width) - width) / 2.0);
|
|
@@ -322,11 +359,25 @@ class SectionLayout {
|
|
|
322
359
|
case "Right":
|
|
323
360
|
top_left = top_left.move_x_by(Width_1.Width.get_fixed_unchecked(elem.width) - width);
|
|
324
361
|
break;
|
|
325
|
-
case "Justified":
|
|
326
|
-
throw new Error("Cannot compute textbox positions of justified element");
|
|
327
362
|
}
|
|
328
|
-
|
|
329
|
-
|
|
363
|
+
if (elem.alignment === "Justified") {
|
|
364
|
+
const words = elem.item.split(/\s+/);
|
|
365
|
+
const word_elems = words.map((word) => {
|
|
366
|
+
const word_width = elem.font.get_width(word, font_dict);
|
|
367
|
+
const word_elem = new Elem(word, null, false, false, Width_1.Width.absolute(word_width), elem.font, Margin_1.Margin.default_(), Alignment_1.Alignment.default_(), Width_1.Width.absolute(word_width), elem.background_color);
|
|
368
|
+
return word_elem;
|
|
369
|
+
});
|
|
370
|
+
const per_elem_space = (Width_1.Width.get_fixed_unchecked(elem.width) - (word_elems.reduce((w, elem) => w + Width_1.Width.get_fixed_unchecked(elem.width), 0.0))) / (words.length);
|
|
371
|
+
for (const word_elem of word_elems) {
|
|
372
|
+
const textbox = new Box_1.Box(top_left, top_left.move_x_by(width).move_y_by(height));
|
|
373
|
+
textbox_positions.push([textbox, word_elem]);
|
|
374
|
+
top_left = top_left.move_x_by(Width_1.Width.get_fixed_unchecked(word_elem.width) + per_elem_space);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
const textbox = new Box_1.Box(top_left, top_left.move_x_by(width).move_y_by(height));
|
|
379
|
+
textbox_positions.push([textbox, elem]);
|
|
380
|
+
}
|
|
330
381
|
return top_left.y + height;
|
|
331
382
|
}
|
|
332
383
|
}
|
|
@@ -334,15 +385,16 @@ class SectionLayout {
|
|
|
334
385
|
}
|
|
335
386
|
exports.SectionLayout = SectionLayout;
|
|
336
387
|
class Stack {
|
|
337
|
-
constructor(elements, margin, alignment, width) {
|
|
388
|
+
constructor(elements, margin, alignment, width, is_fill) {
|
|
338
389
|
this.tag = "Stack";
|
|
339
390
|
this.elements = elements;
|
|
340
391
|
this.margin = margin !== null && margin !== void 0 ? margin : Margin_1.Margin.default_();
|
|
341
392
|
this.alignment = alignment !== null && alignment !== void 0 ? alignment : Alignment_1.Alignment.default_();
|
|
342
393
|
this.width = width !== null && width !== void 0 ? width : Width_1.Width.default_();
|
|
394
|
+
this.is_fill = is_fill !== null && is_fill !== void 0 ? is_fill : false;
|
|
343
395
|
}
|
|
344
|
-
static stack(elements, margin, alignment, width) {
|
|
345
|
-
return new SectionLayout(new Stack(elements, margin, alignment, width));
|
|
396
|
+
static stack(elements, margin, alignment, width, is_fill) {
|
|
397
|
+
return new SectionLayout(new Stack(elements, margin, alignment, width, is_fill));
|
|
346
398
|
}
|
|
347
399
|
copy() {
|
|
348
400
|
return new Stack(this.elements.map((e) => e.copy()), this.margin.copy(), this.alignment, Width_1.Width.copy(this.width));
|
|
@@ -351,19 +403,19 @@ class Stack {
|
|
|
351
403
|
return new Stack([]);
|
|
352
404
|
}
|
|
353
405
|
instantiate(section) {
|
|
354
|
-
return new Stack(this.elements.map(e => e.instantiate(section)), this.margin, this.alignment, this.width);
|
|
406
|
+
return new Stack(this.elements.map(e => e.instantiate(section)), this.margin, this.alignment, this.width, this.is_fill);
|
|
355
407
|
}
|
|
356
408
|
with_elements(elements) {
|
|
357
|
-
return new Stack(elements, this.margin, this.alignment, this.width);
|
|
409
|
+
return new Stack(elements, this.margin, this.alignment, this.width, this.is_fill);
|
|
358
410
|
}
|
|
359
411
|
with_margin(margin) {
|
|
360
|
-
return new Stack(this.elements, margin, this.alignment, this.width);
|
|
412
|
+
return new Stack(this.elements, margin, this.alignment, this.width, this.is_fill);
|
|
361
413
|
}
|
|
362
414
|
with_alignment(alignment) {
|
|
363
|
-
return new Stack(this.elements, this.margin, alignment, this.width);
|
|
415
|
+
return new Stack(this.elements, this.margin, alignment, this.width, this.is_fill);
|
|
364
416
|
}
|
|
365
417
|
with_width(width) {
|
|
366
|
-
return new Stack(this.elements, this.margin, this.alignment, width);
|
|
418
|
+
return new Stack(this.elements, this.margin, this.alignment, width, this.is_fill);
|
|
367
419
|
}
|
|
368
420
|
bound_width(width) {
|
|
369
421
|
const bound = this.width.tag === "Absolute" ? Math.min(this.width.value, width)
|
|
@@ -372,7 +424,7 @@ class Stack {
|
|
|
372
424
|
if (bound === null) {
|
|
373
425
|
throw new Error("Cannot bound width of non-unitized widths!");
|
|
374
426
|
}
|
|
375
|
-
return new Stack(this.elements.map(e => e.bound_width(bound)), this.margin, this.alignment, Width_1.Width.absolute(bound));
|
|
427
|
+
return new Stack(this.elements.map(e => e.bound_width(bound)), this.margin, this.alignment, Width_1.Width.absolute(bound), Width_1.Width.is_fill(this.width));
|
|
376
428
|
}
|
|
377
429
|
scale_width(w) {
|
|
378
430
|
return this.with_elements(this.elements.map(e => e.scale_width(w))).with_width(Width_1.Width.scale(this.width, w));
|
|
@@ -380,37 +432,38 @@ class Stack {
|
|
|
380
432
|
}
|
|
381
433
|
exports.Stack = Stack;
|
|
382
434
|
class Row {
|
|
383
|
-
constructor(elements, is_frozen, margin, alignment, width) {
|
|
435
|
+
constructor(elements, is_frozen, margin, alignment, width, is_fill) {
|
|
384
436
|
this.tag = "Row";
|
|
385
437
|
this.elements = elements;
|
|
386
438
|
this.is_frozen = is_frozen !== null && is_frozen !== void 0 ? is_frozen : false;
|
|
387
439
|
this.margin = margin !== null && margin !== void 0 ? margin : Margin_1.Margin.default_();
|
|
388
440
|
this.alignment = alignment !== null && alignment !== void 0 ? alignment : Alignment_1.Alignment.default_();
|
|
389
441
|
this.width = width !== null && width !== void 0 ? width : Width_1.Width.default_();
|
|
442
|
+
this.is_fill = is_fill !== null && is_fill !== void 0 ? is_fill : false;
|
|
390
443
|
}
|
|
391
|
-
static row(elements, is_frozen, margin, alignment, width) {
|
|
392
|
-
return new SectionLayout(new Row(elements, is_frozen, margin, alignment, width));
|
|
444
|
+
static row(elements, is_frozen, margin, alignment, width, is_fill) {
|
|
445
|
+
return new SectionLayout(new Row(elements, is_frozen, margin, alignment, width, is_fill));
|
|
393
446
|
}
|
|
394
447
|
copy() {
|
|
395
|
-
return new Row(this.elements.map((e) => e.copy()), this.is_frozen, this.margin.copy(), this.alignment, Width_1.Width.copy(this.width));
|
|
448
|
+
return new Row(this.elements.map((e) => e.copy()), this.is_frozen, this.margin.copy(), this.alignment, Width_1.Width.copy(this.width), this.is_fill);
|
|
396
449
|
}
|
|
397
450
|
static default_() {
|
|
398
451
|
return new Row([]);
|
|
399
452
|
}
|
|
400
453
|
instantiate(section) {
|
|
401
|
-
return new Row(this.elements.map(e => e.instantiate(section)), this.is_frozen, this.margin, this.alignment, this.width);
|
|
454
|
+
return new Row(this.elements.map(e => e.instantiate(section)), this.is_frozen, this.margin, this.alignment, this.width, this.is_fill);
|
|
402
455
|
}
|
|
403
456
|
with_elements(elements) {
|
|
404
|
-
return new Row(elements, this.is_frozen, this.margin, this.alignment, this.width);
|
|
457
|
+
return new Row(elements, this.is_frozen, this.margin, this.alignment, this.width, this.is_fill);
|
|
405
458
|
}
|
|
406
459
|
with_margin(margin) {
|
|
407
|
-
return new Row(this.elements, this.is_frozen, margin, this.alignment, this.width);
|
|
460
|
+
return new Row(this.elements, this.is_frozen, margin, this.alignment, this.width, this.is_fill);
|
|
408
461
|
}
|
|
409
462
|
with_alignment(alignment) {
|
|
410
|
-
return new Row(this.elements, this.is_frozen, this.margin, alignment, this.width);
|
|
463
|
+
return new Row(this.elements, this.is_frozen, this.margin, alignment, this.width, this.is_fill);
|
|
411
464
|
}
|
|
412
465
|
with_width(width) {
|
|
413
|
-
return new Row(this.elements, this.is_frozen, this.margin, this.alignment, width);
|
|
466
|
+
return new Row(this.elements, this.is_frozen, this.margin, this.alignment, width, this.is_fill);
|
|
414
467
|
}
|
|
415
468
|
elements_width() {
|
|
416
469
|
return this.elements.map(e => Width_1.Width.get_fixed_unchecked(e.width())).reduce((a, b) => a + b, 0.0);
|
|
@@ -422,7 +475,7 @@ class Row {
|
|
|
422
475
|
if (bound === null) {
|
|
423
476
|
throw new Error("Cannot bound width of non-unitized widths!");
|
|
424
477
|
}
|
|
425
|
-
return new Row(this.elements.map(e => e.bound_width(bound)), this.is_frozen, this.margin, this.alignment, Width_1.Width.absolute(bound));
|
|
478
|
+
return new Row(this.elements.map(e => e.bound_width(bound)), this.is_frozen, this.margin, this.alignment, Width_1.Width.absolute(bound), Width_1.Width.is_fill(this.width));
|
|
426
479
|
}
|
|
427
480
|
scale_width(w) {
|
|
428
481
|
return this.with_elements(this.elements.map(e => e.scale_width(w))).with_width(Width_1.Width.scale(this.width, w));
|
|
@@ -526,7 +579,7 @@ class Elem {
|
|
|
526
579
|
}
|
|
527
580
|
justified_lines(lines, font_dict) {
|
|
528
581
|
const rowLines = [];
|
|
529
|
-
for (const line of lines) {
|
|
582
|
+
for (const line of lines.slice(0, -1)) {
|
|
530
583
|
const words = line.item.split(/\s+/);
|
|
531
584
|
const row = new Row([], false, line.margin, line.alignment, line.width);
|
|
532
585
|
words.forEach(word => {
|
|
@@ -535,6 +588,7 @@ class Elem {
|
|
|
535
588
|
});
|
|
536
589
|
rowLines.push(row);
|
|
537
590
|
}
|
|
591
|
+
rowLines.push(new Row([new SectionLayout(lines[lines.length - 1]).with_alignment("Left")], false, lines[0].margin, "Left", lines[0].width));
|
|
538
592
|
return rowLines;
|
|
539
593
|
}
|
|
540
594
|
break_lines(font_dict) {
|