idml 0.9.2 → 0.9.3
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.
- checksums.yaml +4 -4
- data/TODO.pdf/118-table-band-fills.md +33 -0
- data/lib/idml/render/renderers/table_renderer.rb +99 -2
- data/lib/idml/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b5306c44be037a52666aa508b9cdb76978561403d72bc43896ea8575b3f61340
|
|
4
|
+
data.tar.gz: 1d46f1c6de5f53f564f69ccfc41349d48d12b5f3522b7dfae1d01dc79f92ae00
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4d6830d86be109139a52ee6c2d780f31c33488eee4090b6a64ca938c871fd78429d9da7dbd9b7911d2a814e6908c1a05d53b6083abbb6b74c9d04fec141fcf18
|
|
7
|
+
data.tar.gz: '0886ff7d2aea4389f5bd0779151be35e6dd40473c2bec635ca4ff25f10321b196c09b171d104f405c4133ab699cfc008773a11533ad43fd870e755cd29b2e168'
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# TODO PDF 118: Table alternating row/column band fills
|
|
2
|
+
|
|
3
|
+
## Status: COMPLETE — implemented 2026-08-18
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
IDML tables declare table-level alternating fills —
|
|
8
|
+
StartRowFillColor/Count + EndRowFillColor/Count (row banding),
|
|
9
|
+
StartColumnFillColor/Count + EndColumnFillColor/Count (column
|
|
10
|
+
banding), ColumnFillsPriority (true = column banding wins),
|
|
11
|
+
SkipFirst/LastAlternatingFillRows/Columns (edge suppression), and
|
|
12
|
+
per-band tints. All attributes are modeled (TODO 104) but the
|
|
13
|
+
renderer only honored per-Cell FillColor, so banded tables (zebra
|
|
14
|
+
stripes, ledger shading) rendered without their backgrounds.
|
|
15
|
+
|
|
16
|
+
## What was done
|
|
17
|
+
|
|
18
|
+
- `SchemaLayout#band_fill(col, row)` computes the effective band
|
|
19
|
+
color + tint for a cell position: row banding by default; column
|
|
20
|
+
banding when ColumnFillsPriority is true or row banding is
|
|
21
|
+
unconfigured; SkipFirst/Last offsets suppress banding at the
|
|
22
|
+
table edges; "Color/None" band colors render nothing.
|
|
23
|
+
- `TableRenderer` paints the band rect behind each cell BEFORE the
|
|
24
|
+
cell's own background — an explicit Cell FillColor overrides the
|
|
25
|
+
band, matching InDesign.
|
|
26
|
+
- `each_cell` now also yields the cell's column/row indices.
|
|
27
|
+
|
|
28
|
+
## Acceptance criteria
|
|
29
|
+
|
|
30
|
+
- [x] Rows alternate Start/End colors in the declared counts.
|
|
31
|
+
- [x] Cell-level fill overrides the band.
|
|
32
|
+
- [x] Column banding wins when ColumnFillsPriority is true.
|
|
33
|
+
- [x] SkipFirstAlternatingFillRows suppresses leading bands.
|
|
@@ -70,7 +70,10 @@ module Idml
|
|
|
70
70
|
# derived from `column_count` attribute or max col + 1.
|
|
71
71
|
def self.render_schema_faithful(canvas, table, box, context)
|
|
72
72
|
layout = SchemaLayout.new(table: table, box: box)
|
|
73
|
-
layout.each_cell do |cell_x, cell_y, cell_w, cell_h, cell
|
|
73
|
+
layout.each_cell do |cell_x, cell_y, cell_w, cell_h, cell,
|
|
74
|
+
col_idx, row_idx|
|
|
75
|
+
render_band_background(canvas, cell, layout, col_idx, row_idx,
|
|
76
|
+
cell_x, cell_y, cell_w, cell_h, context)
|
|
74
77
|
render_cell_background(canvas, cell, cell_x, cell_y, cell_w, cell_h,
|
|
75
78
|
context)
|
|
76
79
|
render_cell_border(canvas, cell_x, cell_y, cell_w, cell_h)
|
|
@@ -79,6 +82,27 @@ module Idml
|
|
|
79
82
|
end
|
|
80
83
|
private_class_method :render_schema_faithful
|
|
81
84
|
|
|
85
|
+
# Table-level alternating band fill behind a cell. An
|
|
86
|
+
# explicit Cell FillColor wins; Color/None bands and zero
|
|
87
|
+
# tints render nothing.
|
|
88
|
+
def self.render_band_background(canvas, cell, layout, col_idx,
|
|
89
|
+
row_idx, x, y, w, h, context)
|
|
90
|
+
return if cell_fill_color(cell, context)
|
|
91
|
+
|
|
92
|
+
name, tint = layout.band_fill(col_idx, row_idx)
|
|
93
|
+
return unless name
|
|
94
|
+
return if name == "Color/None"
|
|
95
|
+
|
|
96
|
+
color = context.color_resolver&.resolve(name)
|
|
97
|
+
return unless color
|
|
98
|
+
|
|
99
|
+
color = ColorHelper.apply_tint(color, tint)
|
|
100
|
+
canvas.fill_color(ColorHelper.to_canvas(color))
|
|
101
|
+
canvas.rectangle(x, y, w, h)
|
|
102
|
+
canvas.fill
|
|
103
|
+
end
|
|
104
|
+
private_class_method :render_band_background
|
|
105
|
+
|
|
82
106
|
def self.render_cell_background(canvas, cell, x, y, w, h, context)
|
|
83
107
|
color = cell_fill_color(cell, context)
|
|
84
108
|
return unless color
|
|
@@ -244,7 +268,7 @@ module Idml
|
|
|
244
268
|
|
|
245
269
|
yield cell_x(col_idx), cell_y(row_idx, col_span, row_span),
|
|
246
270
|
cell_w(col_idx, col_span), cell_h(row_idx, row_span),
|
|
247
|
-
cell
|
|
271
|
+
cell, col_idx, row_idx
|
|
248
272
|
end
|
|
249
273
|
end
|
|
250
274
|
end
|
|
@@ -269,6 +293,79 @@ module Idml
|
|
|
269
293
|
table.row
|
|
270
294
|
end
|
|
271
295
|
|
|
296
|
+
# Table-level alternating band fill for a cell position:
|
|
297
|
+
# [color_name, tint] or nil. Row banding by default; column
|
|
298
|
+
# banding when ColumnFillsPriority is true or rows are
|
|
299
|
+
# unconfigured.
|
|
300
|
+
def band_fill(col, row)
|
|
301
|
+
column_band = column_band_fill(col)
|
|
302
|
+
return column_band if column_band &&
|
|
303
|
+
(table.column_fills_priority || row_band_fill(row).nil?)
|
|
304
|
+
|
|
305
|
+
row_band_fill(row)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def row_band_fill(row)
|
|
309
|
+
band_pair(table.start_row_fill_color, table.start_row_fill_count,
|
|
310
|
+
table.end_row_fill_color, table.end_row_fill_count,
|
|
311
|
+
table.start_row_fill_tint, table.end_row_fill_tint,
|
|
312
|
+
row, row_count,
|
|
313
|
+
table.skip_first_alternating_fill_rows,
|
|
314
|
+
table.skip_last_alternating_fill_rows)
|
|
315
|
+
end
|
|
316
|
+
private :row_band_fill
|
|
317
|
+
|
|
318
|
+
def column_band_fill(col)
|
|
319
|
+
band_pair(table.start_column_fill_color,
|
|
320
|
+
table.start_column_fill_count,
|
|
321
|
+
table.end_column_fill_color,
|
|
322
|
+
table.end_column_fill_count,
|
|
323
|
+
table.start_column_fill_tint,
|
|
324
|
+
table.end_column_fill_tint,
|
|
325
|
+
col, col_count,
|
|
326
|
+
table.skip_first_alternating_fill_columns,
|
|
327
|
+
table.skip_last_alternating_fill_columns)
|
|
328
|
+
end
|
|
329
|
+
private :column_band_fill
|
|
330
|
+
|
|
331
|
+
# Alternating band for one axis: the first `start_count`
|
|
332
|
+
# positions take the start color, the next `end_count` the
|
|
333
|
+
# end color, repeating from after the skipped edge rows.
|
|
334
|
+
# Zero-count cycles band nothing.
|
|
335
|
+
def band_pair(start_color, start_count, end_color, end_count,
|
|
336
|
+
start_tint, end_tint, index, total,
|
|
337
|
+
skip_first, skip_last)
|
|
338
|
+
return nil unless start_color
|
|
339
|
+
return nil if suppressed?(index, total, skip_first, skip_last)
|
|
340
|
+
|
|
341
|
+
cycle = band_cycle(start_count, end_count)
|
|
342
|
+
return nil unless cycle.positive?
|
|
343
|
+
|
|
344
|
+
if in_start_band?(index, skip_first, cycle, start_count)
|
|
345
|
+
[start_color, start_tint]
|
|
346
|
+
else
|
|
347
|
+
[end_color, end_tint]
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
private :band_pair
|
|
351
|
+
|
|
352
|
+
def band_cycle(start_count, end_count)
|
|
353
|
+
(start_count || 1) + (end_count || 1)
|
|
354
|
+
end
|
|
355
|
+
private :band_cycle
|
|
356
|
+
|
|
357
|
+
def in_start_band?(index, skip_first, cycle, start_count)
|
|
358
|
+
((index - (skip_first || 0)) % cycle) < (start_count || 1)
|
|
359
|
+
end
|
|
360
|
+
private :in_start_band?
|
|
361
|
+
|
|
362
|
+
# Banding suppressed at the leading/trailing edges.
|
|
363
|
+
def suppressed?(index, total, skip_first, skip_last)
|
|
364
|
+
index < (skip_first || 0) ||
|
|
365
|
+
index >= total - (skip_last || 0)
|
|
366
|
+
end
|
|
367
|
+
private :suppressed?
|
|
368
|
+
|
|
272
369
|
def cells
|
|
273
370
|
table.cell
|
|
274
371
|
end
|
data/lib/idml/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: idml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose
|
|
@@ -175,6 +175,7 @@ files:
|
|
|
175
175
|
- TODO.pdf/116-applied-style-resolution.md
|
|
176
176
|
- TODO.pdf/116-justification-last-line.md
|
|
177
177
|
- TODO.pdf/117-endnote-support.md
|
|
178
|
+
- TODO.pdf/118-table-band-fills.md
|
|
178
179
|
- TODO.pdf/12-idml-to-pdf-pipeline.md
|
|
179
180
|
- TODO.pdf/13-cjk-text-layout.md
|
|
180
181
|
- TODO.pdf/14-page-item-element-models.md
|