@@ -100,6 +100,7 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
100100 protected rSpace : number [ ] ;
101101 protected cLines : number [ ] ;
102102 protected rLines : number [ ] ;
103+ protected cWidths : string [ ] ;
103104
104105 /*
105106 * The bounding box information for the table rows and columns
@@ -120,14 +121,18 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
120121 this . numCols = this . childNodes . map ( row => ( row as CHTMLmtr < N , T , D > ) . numCells )
121122 . reduce ( ( a , b ) => Math . max ( a , b ) , 0 ) ;
122123 this . numRows = this . childNodes . length ;
124+ //
125+ // Get the frame, row, and column parameters
126+ //
123127 const attributes = node . attributes ;
124- this . cSpace = this . convertLengths ( this . getColumnAttributes ( 'columnspacing' ) ) ;
125- this . rSpace = this . convertLengths ( this . getRowAttributes ( 'rowspacing' ) ) ;
126128 this . frame = attributes . get ( 'frame' ) !== 'none' ;
127129 this . lines = this . frame || attributes . get ( 'columnlines' ) !== 'none' || attributes . get ( 'rowlines' ) !== 'none' ;
128- this . fSpace = ( this . lines ? this . convertLengths ( this . getAttributeArray ( 'framespacing' ) ) : [ ] ) ;
130+ this . fSpace = ( this . lines ? this . convertLengths ( this . getAttributeArray ( 'framespacing' ) ) : [ 0 , 0 ] ) ;
131+ this . cSpace = this . convertLengths ( this . getColumnAttributes ( 'columnspacing' ) ) ;
132+ this . rSpace = this . convertLengths ( this . getRowAttributes ( 'rowspacing' ) ) ;
129133 this . cLines = this . getColumnAttributes ( 'columnlines' ) . map ( x => ( x === 'none' ? 0 : .07 ) ) ;
130134 this . rLines = this . getColumnAttributes ( 'rowlines' ) . map ( x => ( x === 'none' ? 0 : .07 ) ) ;
135+ this . cWidths = this . getColumnAttributes ( 'columnwidth' ) ;
131136 //
132137 // Stretch the columns (rows are already taken care of in the CHTMLmtr wrapper)
133138 //
@@ -205,12 +210,11 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
205210 // Finally, add the frame, if needed
206211 //
207212 this . padRows ( ) ;
208- this . handleColumnAlign ( ) ;
209213 this . handleColumnSpacing ( ) ;
210214 this . handleColumnLines ( ) ;
211- this . handleRowAlign ( ) ;
212215 this . handleRowSpacing ( ) ;
213216 this . handleRowLines ( ) ;
217+ this . handleEqualRows ( ) ;
214218 this . handleFrame ( ) ;
215219 this . handleWidth ( ) ;
216220 this . drawBBox ( ) ;
@@ -241,16 +245,14 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
241245 }
242246 }
243247 const w = this . node . attributes . get ( 'width' ) as string ;
244- const height = H . concat ( D , this . rLines ) . reduce ( ( a , b ) => a + b , 0 )
245- + this . rSpace . reduce ( ( a , b ) => a + b , 0 )
248+ const height = H . concat ( D , this . rLines , this . rSpace ) . reduce ( ( a , b ) => a + b , 0 )
246249 + ( this . frame ? .14 : 0 )
247- + 2 * ( this . fSpace [ 1 ] || 0 ) ;
250+ + 2 * this . fSpace [ 1 ] ;
248251 let width ;
249252 if ( w === 'auto' || w . match ( / % $ / ) ) {
250- width = W . concat ( this . cLines ) . reduce ( ( a , b ) => a + b , 0 )
251- + this . cSpace . reduce ( ( a , b ) => a + b , 0 )
253+ width = W . concat ( this . cLines , this . cSpace ) . reduce ( ( a , b ) => a + b , 0 )
252254 + ( this . frame ? .14 : 0 )
253- + 2 * ( this . fSpace [ 0 ] || 0 ) ;
255+ + 2 * this . fSpace [ 0 ] ;
254256 } else {
255257 const cwidth = this . metrics . containerWidth / this . metrics . em ;
256258 width = this . length2em ( w , cwidth ) + ( this . frame ? .14 : 0 ) ;
@@ -263,7 +265,13 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
263265 * @override
264266 */
265267 public computeBBox ( bbox : BBox ) {
266- const { width, height} = this . getTableData ( ) ;
268+ let { width, height} = this . getTableData ( ) ;
269+ if ( this . node . attributes . get ( 'equalrows' ) ) {
270+ const HD = this . getEqualRowHeight ( ) ;
271+ height = [ ] . concat ( this . rLines , this . rSpace ) . reduce ( ( a , b ) => a + b , 0 )
272+ + HD * this . numRows
273+ + 2 * this . fSpace [ 1 ] ;
274+ }
267275 const a = this . font . params . axis_height ;
268276 bbox . h = height / 2 + a ;
269277 bbox . d = height / 2 - a ;
@@ -283,23 +291,6 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
283291 }
284292 }
285293
286- /*
287- * Set the cell aligments based on the table, row, or cell columnalign attributes
288- */
289- protected handleColumnAlign ( ) {
290- const colAlign = this . getColumnAttributes ( 'columnalign' ) || [ ] ;
291- for ( const row of this . childNodes ) {
292- const aligns = this . getColumnAttributes ( 'columnalign' , row ) || colAlign ;
293- let i = 0 ;
294- for ( const cell of row . childNodes ) {
295- let align = ( cell . node . attributes . get ( 'columnalign' ) as string ) || aligns [ i ++ ] ;
296- if ( align !== 'center' ) {
297- this . adaptor . setStyle ( cell . chtml , 'textAlign' , align ) ;
298- }
299- }
300- }
301- }
302-
303294 /*
304295 * Set the inter-column spacing for all columns
305296 * (Use frame spacing on the outsides, if needed, and use half the column spacing on each
@@ -310,7 +301,7 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
310301 //
311302 // Get the column spacing values, and add the frame spacing values at the left and right
312303 //
313- const fspace = this . em ( this . fSpace [ 0 ] || 0 ) ;
304+ const fspace = this . em ( this . fSpace [ 0 ] ) ;
314305 const spacing = this . addEm ( this . cSpace , 2 ) ;
315306 if ( ! spacing ) return ;
316307 spacing . unshift ( fspace ) ;
@@ -362,26 +353,6 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
362353 }
363354 }
364355
365- /*
366- * Add vertical alignment to rows, and override in the cells, if needed
367- */
368- protected handleRowAlign ( ) {
369- const rowAlign = this . getRowAttributes ( 'rowalign' ) || [ ] ;
370- let i = 0 ;
371- for ( const row of this . childNodes ) {
372- const align = ( row . node . attributes . get ( 'rowalign' ) as string ) || rowAlign [ i ++ ] ;
373- if ( align !== 'baseline' ) {
374- this . adaptor . setAttribute ( row . chtml , 'rowalign' , align ) ;
375- }
376- for ( const cell of row . childNodes ) {
377- const calign = cell . node . attributes . get ( 'rowalign' ) as string ;
378- if ( calign && calign !== align ) {
379- this . adaptor . setStyle ( cell . chtml , 'verticalAlign' , calign ) ;
380- }
381- }
382- }
383- }
384-
385356 /*
386357 * Set the inter-row spacing for all rows
387358 * (Use frame spacing on the outsides, if needed, and use half the row spacing on each
@@ -392,7 +363,7 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
392363 //
393364 // Get the row spacing values, and add the frame spacing values at the left and right
394365 //
395- const fspacing = this . em ( this . fSpace [ 1 ] || 0 ) ;
366+ const fspacing = this . em ( this . fSpace [ 1 ] ) ;
396367 const spacing = this . addEm ( this . rSpace , 2 ) ;
397368 if ( ! spacing ) return ;
398369 spacing . unshift ( fspacing ) ;
@@ -443,6 +414,30 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
443414 }
444415 }
445416
417+ protected handleEqualRows ( ) {
418+ if ( ! this . node . attributes . get ( 'equalrows' ) ) return ;
419+ const space = this . rSpace . map ( x => x / 2 ) ;
420+ space . unshift ( this . fSpace [ 1 ] ) ;
421+ space . push ( this . fSpace [ 1 ] ) ;
422+ const { H, D} = this . getTableData ( ) ;
423+ const HD = this . getEqualRowHeight ( ) ;
424+ const HDem = this . em ( HD ) ;
425+ for ( const i of Array . from ( this . childNodes . keys ( ) ) ) {
426+ const row = this . childNodes [ i ] ;
427+ this . adaptor . setStyle ( row . chtml , 'height' , this . em ( space [ i ] + HD + space [ i + 1 ] ) ) ;
428+ const ralign = row . node . attributes . get ( 'rowalign' ) ;
429+ for ( const cell of row . childNodes ) {
430+ const calign = cell . node . attributes . get ( 'rowalign' ) ;
431+ if ( calign === 'baseline' || calign === 'axis' ) {
432+ const child = this . adaptor . lastChild ( cell . chtml ) as N ;
433+ this . adaptor . setStyle ( child , 'height' , HDem ) ;
434+ this . adaptor . setStyle ( child , 'verticalAlign' , this . em ( - ( ( HD - H [ i ] + D [ i ] ) / 2 ) ) ) ;
435+ if ( ralign === 'baseline' || ralign === 'axis' ) break ;
436+ }
437+ }
438+ }
439+ }
440+
446441 /*
447442 * Add a frame to the mtable, if needed
448443 */
@@ -470,6 +465,15 @@ export class CHTMLmtable<N, T, D> extends CHTMLWrapper<N, T, D> {
470465
471466 /******************************************************************/
472467
468+ /*
469+ * Get the maximum height of a row
470+ */
471+ protected getEqualRowHeight ( ) {
472+ const { H, D} = this . getTableData ( ) ;
473+ const HD = Array . from ( H . keys ( ) ) . map ( i => H [ i ] + D [ i ] ) ;
474+ return Math . max . apply ( Math , HD ) ;
475+ }
476+
473477 /*
474478 * @param {string } name The name of the attribute to get as an array
475479 * @param {CHTMLWrapper } wrapper The wrapper whose attribute is to be used
0 commit comments