/************************************************************************/ /* */ /* Manipulate iten properties in a document. */ /* */ /************************************************************************/ # include "docBaseConfig.h" # include # include # include # include "docPropVal.h" # include "docSectProperties.h" # define MIN_COL_WIDE ( 20* 36 ) # define MIN_GAP_WIDE ( 20* 12 ) # define DEF_GAP_WIDE ( 20* 36 ) /************************************************************************/ /* */ /* Translate section property numbers to notes property numbers. */ /* */ /************************************************************************/ const int DOCsectNOTE_PROP_MAP[FEPprop_COUNT]= { SPpropFOOTNOTE_STARTNR, SPpropFOOTNOTE_JUSTIFICATION, -1, /* No SPpropFOOTNOTE_PLACEMENT, */ SPpropFOOTNOTE_RESTART, SPpropFOOTNOTE_STYLE, SPpropENDNOTE_STARTNR, -1, /* No SPpropENDNOTE_JUSTIFICATION, */ -1, /* No SPpropENDNOTE_PLACEMENT, */ SPpropENDNOTE_RESTART, SPpropENDNOTE_STYLE, }; const int * const DOCsectFOOTNOTE_PROP_MAP= DOCsectNOTE_PROP_MAP; const int * const DOCsectENDNOTE_PROP_MAP= DOCsectNOTE_PROP_MAP+ NOTESprop_COUNT; static const int DocSectIntProps[]= { DGpropPAGE_WIDTH, DGpropPAGE_HEIGHT, DGpropLEFT_MARGIN, DGpropRIGHT_MARGIN, DGpropTOP_MARGIN, DGpropBOTTOM_MARGIN, DGpropHEADER_POSITION, DGpropFOOTER_POSITION, DGpropGUTTER, DGpropMARGMIR, SPpropSTYLE, SPpropTITLEPG, SPpropBREAK_KIND, SPpropNUMBER_STYLE, SPpropNUMBER_HYPHEN, SPpropPAGE_RESTART, SPpropSTART_PAGE, SPpropCOLUMN_COUNT, SPpropCOLUMN_SPACING, SPpropLINEBETCOL, SPpropFOOTNOTE_STARTNR, SPpropFOOTNOTE_JUSTIFICATION, /* No SPpropFOOTNOTE_PLACEMENT, */ SPpropFOOTNOTE_RESTART, SPpropFOOTNOTE_STYLE, SPpropENDNOTE_STARTNR, /* No SPpropENDNOTE_JUSTIFICATION, */ /* No SPpropENDNOTE_PLACEMENT, */ SPpropENDNOTE_RESTART, SPpropENDNOTE_STYLE, }; static const int DocSectIntPropCount= sizeof(DocSectIntProps)/sizeof(int); /************************************************************************/ /* */ /* Fill a mask with notes properties that are relevant for a section. */ /* I.E: Set those section properties that are a note property. */ /* */ /************************************************************************/ void docFillSectNotesMask( PropertyMask * spMask ) { int i; for ( i= 0; i < FEPprop_COUNT; i++ ) { if ( DOCsectNOTE_PROP_MAP[i] >= 0 ) { PROPmaskADD( spMask, DOCsectNOTE_PROP_MAP[i] ); } } } /************************************************************************/ /* */ /* Make sure all column width are zero, or that none of them is. */ /* */ /************************************************************************/ static void docSectCheckFixedColumnWidth( SectionProperties * sp ) { if ( sp->spColumnCount > 1 ) { int haveZero= 0; int haveWidth= 0; int col; SectionColumn * sc; sc= sp->spColumns; for ( col= 0; col < sp->spColumnCount; sc++, col++ ) { if ( sc->scColumnWidthTwips == 0 ) { haveZero++; } else{ haveWidth++; } } if ( haveZero && haveWidth ) { sc= sp->spColumns; for ( col= 0; col < sp->spColumnCount; sc++, col++ ) { sc->scColumnWidthTwips= 0; } } } return; } /************************************************************************/ /* */ /* Change section properties and tell what has been changed. */ /* */ /************************************************************************/ int docUpdSectProperties( PropertyMask * pSpDoneMask, SectionProperties * spTo, const PropertyMask * spSetMask, const SectionProperties * spSet ) { PropertyMask doneMask; int p; utilPropMaskClear( &doneMask ); for ( p= 0; p < DocSectIntPropCount; p++ ) { int prop= DocSectIntProps[p]; int oval; int nval; if ( ! PROPmaskISSET( spSetMask, prop ) ) { continue; } oval= docGetSectionProperty( spTo, prop ); nval= docGetSectionProperty( spSet, prop ); if ( oval == nval ) { continue; } if ( docSetSectionProperty( spTo, prop, nval ) ) { LLDEB(prop,nval); return -1; } PROPmaskADD( &doneMask, prop ); } if ( PROPmaskISSET( spSetMask, SPpropCOLUMN_COUNT ) ) { if ( spTo->spColumnCount != spSet->spColumnCount ) { if ( docSectionPropertiesSetColumnCount( spTo, spSet->spColumnCount ) ) { LDEB(spSet->spColumnCount); return -1; } PROPmaskADD( &doneMask, SPpropCOLUMN_COUNT ); } } if ( PROPmaskISSET( spSetMask, SPpropCOLUMNS ) ) { int count; if ( spTo->spColumnCount < spSet->spColumnCount ) { count= spTo->spColumnCount; } else{ count= spSet->spColumnCount; } if ( count > 1 ) { const SectionColumn * scFrom= spSet->spColumns; SectionColumn * scTo= spTo->spColumns; int col; for ( col= 0; col < count- 1; scTo++, scFrom++, col++ ) { if ( scTo->scColumnWidthTwips != scFrom->scColumnWidthTwips ) { scTo->scColumnWidthTwips= scFrom->scColumnWidthTwips; PROPmaskADD( &doneMask, SPpropCOLUMNS ); } if ( scTo->scSpaceToRightTwips != scFrom->scSpaceToRightTwips ) { scTo->scSpaceToRightTwips= scFrom->scSpaceToRightTwips; PROPmaskADD( &doneMask, SPpropCOLUMNS ); } } if ( scTo->scColumnWidthTwips != scFrom->scColumnWidthTwips ) { scTo->scColumnWidthTwips= scFrom->scColumnWidthTwips; PROPmaskADD( &doneMask, SPpropCOLUMNS ); } } } docSectCheckFixedColumnWidth( spTo ); if ( pSpDoneMask ) { *pSpDoneMask= doneMask; } return 0; } void docSectPropertyDifference( PropertyMask * pDiffMask, const SectionProperties * sp1, const PropertyMask * cmpMask, const SectionProperties * sp2 ) { PropertyMask diffMask; int p; utilPropMaskClear( &diffMask ); for ( p= 0; p < DocSectIntPropCount; p++ ) { int prop= DocSectIntProps[p]; int oval; int nval; if ( ! PROPmaskISSET( cmpMask, prop ) ) { continue; } oval= docGetSectionProperty( sp1, prop ); nval= docGetSectionProperty( sp2, prop ); if ( oval == nval ) { continue; } PROPmaskADD( &diffMask, prop ); } if ( PROPmaskISSET( cmpMask, SPpropCOLUMNS ) ) { int count; if ( sp1->spColumnCount < sp2->spColumnCount ) { count= sp1->spColumnCount; } else{ count= sp2->spColumnCount; } if ( count > 1 ) { const SectionColumn * sc1= sp1->spColumns; const SectionColumn * sc2= sp2->spColumns; int col; for ( col= 0; col < count- 1; sc1++, sc2++, col++ ) { if ( sc1->scColumnWidthTwips != sc2->scColumnWidthTwips ) { PROPmaskADD( &diffMask, SPpropCOLUMNS ); } if ( sc1->scSpaceToRightTwips != sc2->scSpaceToRightTwips ) { PROPmaskADD( &diffMask, SPpropCOLUMNS ); } } if ( sc1->scColumnWidthTwips != sc2->scColumnWidthTwips ) { PROPmaskADD( &diffMask, SPpropCOLUMNS ); } } } *pDiffMask= diffMask; return; } /************************************************************************/ /* */ /* Clean, Initialize section properties. */ /* */ /************************************************************************/ void docCleanSectionProperties( SectionProperties * sp ) { if ( sp->spColumns ) { free( sp->spColumns ); } return; } void docInitSectionProperties( SectionProperties * sp ) { utilInitDocumentGeometry( &(sp->spDocumentGeometry) ); sp->spStyle= 0; sp->spColumnSpacingTwips= DEF_GAP_WIDE; sp->spLineBetweenColumns= 0; sp->spHasTitlePage= 0; sp->spBreakKind= DOCibkPAGE; sp->spPageNumberStyle= DOCpgnDEC; sp->spPageNumberHyphen= DOCpgnhPGNHNSH; sp->spRestartPageNumbers= 0; sp->spColumnCount= 1; sp->spColumns= (SectionColumn *)0; sp->spStartPageNumber= 0; docInitFootEndNotesProperties( &(sp->spNotesProperties) ); return; } int docSectionPropertiesSetColumnCount( SectionProperties * sp, int n ) { if ( n > 1 && sp->spColumnCount < n ) { SectionColumn * sc= (SectionColumn *)realloc( sp->spColumns, n* sizeof(SectionColumn) ); if ( ! sc ) { LXDEB(n,sc); return -1; } sp->spColumns= sc; if ( sp->spColumnCount == 1 ) { sc->scSpaceToRightTwips= 0; sc->scColumnWidthTwips= 0; } sc= sp->spColumns+ sp->spColumnCount; while( sp->spColumnCount < n ) { sc->scSpaceToRightTwips= 0; sc->scColumnWidthTwips= 0; sc++; sp->spColumnCount++; } } sp->spColumnCount= n; return 0; } /************************************************************************/ /* */ /* Copy SectionProperties. */ /* */ /* NOTE that the headers and footers are not copied. */ /* */ /************************************************************************/ int docCopySectionProperties( SectionProperties * to, const SectionProperties * from ) { int i; if ( docSectionPropertiesSetColumnCount( to, from->spColumnCount ) ) { LDEB(from->spColumnCount); return -1; } to->spDocumentGeometry= from->spDocumentGeometry; to->spStyle= from->spStyle; to->spColumnSpacingTwips= from->spColumnSpacingTwips; to->spLineBetweenColumns= from->spLineBetweenColumns; to->spHasTitlePage= from->spHasTitlePage; to->spBreakKind= from->spBreakKind; to->spPageNumberStyle= from->spPageNumberStyle; to->spPageNumberHyphen= from->spPageNumberHyphen; to->spRestartPageNumbers= from->spRestartPageNumbers; to->spStartPageNumber= from->spStartPageNumber; /* docSectionPropertiesSetColumnCount() has allocated the memory */ if ( from->spColumnCount > 1 ) { for ( i= 0; i < from->spColumnCount; i++ ) { to->spColumns[i]= from->spColumns[i]; } } to->spNotesProperties= from->spNotesProperties; docSectCheckFixedColumnWidth( to ); return 0; } int docSectSetEqualColumnWidth( SectionProperties * sp ) { int col; SectionColumn * sc; const DocumentGeometry * dg= &(sp->spDocumentGeometry); int pageWide; int colWide; pageWide= dg->dgPageWideTwips- dg->dgLeftMarginTwips- dg->dgRightMarginTwips; if ( sp->spColumnCount < 2 ) { return pageWide; } colWide= ( pageWide- ( sp->spColumnCount- 1 )* sp->spColumnSpacingTwips )/ sp->spColumnCount; sc= sp->spColumns; for ( col= 0; col < sp->spColumnCount; sc++, col++ ) { sc->scColumnWidthTwips= 0; sc->scSpaceToRightTwips= 0; } return colWide; } int docSectSetExplicitColumnWidth( SectionProperties * sp ) { int col; SectionColumn * sc; const DocumentGeometry * dg= &(sp->spDocumentGeometry); int pageWide; int colWide; pageWide= dg->dgPageWideTwips- dg->dgLeftMarginTwips- dg->dgRightMarginTwips; if ( sp->spColumnCount < 2 ) { LDEB(sp->spColumnCount); return -1; } colWide= ( pageWide- ( sp->spColumnCount- 1 )* sp->spColumnSpacingTwips )/ sp->spColumnCount; if ( colWide < MIN_COL_WIDE ) { LLDEB(colWide,MIN_COL_WIDE); return -1; } sc= sp->spColumns; for ( col= 0; col < sp->spColumnCount; sc++, col++ ) { sc->scColumnWidthTwips= colWide; sc->scSpaceToRightTwips= sp->spColumnSpacingTwips; } return 0; } /************************************************************************/ /* */ /* Determine the column margins. */ /* */ /* Because of gutters and/or mirrored margins, the page geometry is */ /* not necessarily identical to that in the section properties. */ /* */ /************************************************************************/ void docSectGetColumnX( int * pXLine, int * pX0, int * pX1, const SectionProperties * sp, const DocumentGeometry * dgPage, int column ) { int x0= dgPage->dgLeftMarginTwips; int col; if ( sp->spColumnCount < 2 ) { *pX0= dgPage->dgLeftMarginTwips; *pX1= dgPage->dgPageWideTwips- dgPage->dgRightMarginTwips; return; } for ( col= 0; col < column; col++ ) { if ( sp->spColumns[col].scColumnWidthTwips == 0 ) { break; } x0 += sp->spColumns[col].scColumnWidthTwips; x0 += sp->spColumns[col].scSpaceToRightTwips; } if ( col < column || sp->spColumns[column].scColumnWidthTwips == 0 ) { int pageWide; int colWide; pageWide= dgPage->dgPageWideTwips- dgPage->dgLeftMarginTwips- dgPage->dgRightMarginTwips; colWide= ( pageWide- ( sp->spColumnCount- 1 )* sp->spColumnSpacingTwips )/ sp->spColumnCount; x0= dgPage->dgLeftMarginTwips+ column* ( colWide+ sp->spColumnSpacingTwips ); *pXLine= x0- sp->spColumnSpacingTwips/ 2; *pX0= x0; *pX1= x0+ colWide; } else{ if ( column == 0 ) { *pXLine= x0- sp->spColumnSpacingTwips/ 2; } else{ *pXLine= x0- sp->spColumns[column-1].scSpaceToRightTwips/ 2; } *pX0= x0; *pX1= x0+ sp->spColumns[column].scColumnWidthTwips; } return; } /************************************************************************/ /* */ /* Set a section property. */ /* */ /************************************************************************/ int docSetSectionProperty( SectionProperties * sp, int prop, int arg ) { DocumentGeometry * dg= &(sp->spDocumentGeometry); switch( prop ) { case DGpropPAGE_WIDTH: dg->dgPageWideTwips= arg; break; case DGpropPAGE_HEIGHT: dg->dgPageHighTwips= arg; break; case DGpropLEFT_MARGIN: dg->dgLeftMarginTwips= arg; break; case DGpropRIGHT_MARGIN: dg->dgRightMarginTwips= arg; break; case DGpropTOP_MARGIN: dg->dgTopMarginTwips= arg; break; case DGpropBOTTOM_MARGIN: dg->dgBottomMarginTwips= arg; break; case DGpropHEADER_POSITION: if ( arg != 0 ) { dg->dgHeaderPositionTwips= arg; } break; case DGpropFOOTER_POSITION: if ( arg != 0 ) { dg->dgFooterPositionTwips= arg; } break; case DGpropGUTTER: dg->dgGutterTwips= arg; break; case DGpropMARGMIR: dg->dgMirrorMargins= arg != 0; break; case SPpropSTYLE: sp->spStyle= arg; break; case SPpropTITLEPG: sp->spHasTitlePage= ( arg != 0 ); break; case SPpropBREAK_KIND: sp->spBreakKind= arg; break; case SPpropNUMBER_STYLE: sp->spPageNumberStyle= arg; break; case SPpropNUMBER_HYPHEN: sp->spPageNumberHyphen= arg; break; case SPpropPAGE_RESTART: sp->spRestartPageNumbers= arg; break; case SPpropSTART_PAGE: sp->spStartPageNumber= arg; break; case SPpropCOLUMN_COUNT: if ( docSectionPropertiesSetColumnCount( sp, arg ) ) { LDEB(arg); return -1; } break; case SPpropCOLUMN_SPACING: sp->spColumnSpacingTwips= arg; break; case SPpropLINEBETCOL: sp->spLineBetweenColumns= ( arg != 0 ); break; /* FOOTNOTE */ case SPpropFOOTNOTE_STARTNR: docSetNotesProperty( &(sp->spNotesProperties.fepFootnotesProps), NOTESpropSTARTNR, arg ); return 0; case SPpropFOOTNOTE_JUSTIFICATION: docSetNotesProperty( &(sp->spNotesProperties.fepFootnotesProps), NOTESpropJUSTIFICATION, arg ); return 0; /* No case SPpropFOOTNOTE_PLACEMENT: docSetNotesProperty( &(sp->spNotesProperties.fepFootnotesProps), NOTESpropPLACEMENT, arg ); return 0; */ case SPpropFOOTNOTE_RESTART: docSetNotesProperty( &(sp->spNotesProperties.fepFootnotesProps), NOTESpropRESTART, arg ); return 0; case SPpropFOOTNOTE_STYLE: docSetNotesProperty( &(sp->spNotesProperties.fepFootnotesProps), NOTESpropSTYLE, arg ); return 0; /* ENDNOTE */ case SPpropENDNOTE_STARTNR: docSetNotesProperty( &(sp->spNotesProperties.fepEndnotesProps), NOTESpropSTARTNR, arg ); return 0; /* No case SPpropENDNOTE_JUSTIFICATION: docSetNotesProperty( &(sp->spNotesProperties.fepEndnotesProps), NOTESpropJUSTIFICATION, arg ); return 0; */ /* No case SPpropENDNOTE_PLACEMENT: docSetNotesProperty( &(sp->spNotesProperties.fepEndnotesProps), NOTESpropPLACEMENT, arg ); return 0; */ case SPpropENDNOTE_RESTART: docSetNotesProperty( &(sp->spNotesProperties.fepEndnotesProps), NOTESpropRESTART, arg ); return 0; case SPpropENDNOTE_STYLE: docSetNotesProperty( &(sp->spNotesProperties.fepEndnotesProps), NOTESpropSTYLE, arg ); return 0; default: LLDEB(prop,arg); return -1; } return 0; } /************************************************************************/ /* */ /* Get a section property. */ /* */ /************************************************************************/ int docGetSectionProperty( const SectionProperties * sp, int prop ) { const DocumentGeometry * dg= &(sp->spDocumentGeometry); switch( prop ) { case DGpropPAGE_WIDTH: return dg->dgPageWideTwips; case DGpropPAGE_HEIGHT: return dg->dgPageHighTwips; case DGpropLEFT_MARGIN: return dg->dgLeftMarginTwips; case DGpropRIGHT_MARGIN: return dg->dgRightMarginTwips; case DGpropTOP_MARGIN: return dg->dgTopMarginTwips; case DGpropBOTTOM_MARGIN: return dg->dgBottomMarginTwips; case DGpropHEADER_POSITION: return dg->dgHeaderPositionTwips; case DGpropFOOTER_POSITION: return dg->dgFooterPositionTwips; case DGpropGUTTER: return dg->dgGutterTwips; case DGpropMARGMIR: return dg->dgMirrorMargins; case SPpropSTYLE: return sp->spStyle; case SPpropTITLEPG: return sp->spHasTitlePage; case SPpropBREAK_KIND: return sp->spBreakKind; case SPpropNUMBER_STYLE: return sp->spPageNumberStyle; case SPpropNUMBER_HYPHEN: return sp->spPageNumberHyphen; case SPpropPAGE_RESTART: return sp->spRestartPageNumbers; case SPpropSTART_PAGE: return sp->spStartPageNumber; case SPpropCOLUMN_COUNT: return sp->spColumnCount; case SPpropCOLUMN_SPACING: return sp->spColumnSpacingTwips; break; case SPpropLINEBETCOL: return sp->spLineBetweenColumns; break; /* FOOTNOTE */ case SPpropFOOTNOTE_STARTNR: return docGetNotesProperty( &(sp->spNotesProperties.fepFootnotesProps), NOTESpropSTARTNR ); return 0; case SPpropFOOTNOTE_JUSTIFICATION: return docGetNotesProperty( &(sp->spNotesProperties.fepFootnotesProps), NOTESpropJUSTIFICATION ); return 0; /* No case SPpropFOOTNOTE_PLACEMENT: return docGetNotesProperty( &(sp->spNotesProperties.fepFootnotesProps), NOTESpropPLACEMENT ); return 0; */ case SPpropFOOTNOTE_RESTART: return docGetNotesProperty( &(sp->spNotesProperties.fepFootnotesProps), NOTESpropRESTART ); return 0; case SPpropFOOTNOTE_STYLE: return docGetNotesProperty( &(sp->spNotesProperties.fepFootnotesProps), NOTESpropSTYLE ); return 0; /* ENDNOTE */ case SPpropENDNOTE_STARTNR: return docGetNotesProperty( &(sp->spNotesProperties.fepEndnotesProps), NOTESpropSTARTNR ); return 0; /* No case SPpropENDNOTE_JUSTIFICATION: return docGetNotesProperty( &(sp->spNotesProperties.fepEndnotesProps), NOTESpropJUSTIFICATION ); return 0; */ /* No case SPpropENDNOTE_PLACEMENT: return docGetNotesProperty( &(sp->spNotesProperties.fepEndnotesProps), NOTESpropPLACEMENT ); return 0; */ case SPpropENDNOTE_RESTART: return docGetNotesProperty( &(sp->spNotesProperties.fepEndnotesProps), NOTESpropRESTART ); return 0; case SPpropENDNOTE_STYLE: return docGetNotesProperty( &(sp->spNotesProperties.fepEndnotesProps), NOTESpropSTYLE ); return 0; default: LDEB(prop); return -1; } return 0; } /************************************************************************/ /* */ /* Return the sum of the other widths in a section with explicit */ /* column layout. Additionally, assign a victim whose column width can */ /* be narrowed to allocate extra space. */ /* */ /* The maximum value is the value that leaves MIN_COL_WIDE as the */ /* column width of the victim. */ /* */ /************************************************************************/ static int docSectColsSumOthers( int * pVictim, int * pMaxValue, const SectionProperties * sp, int col, int colOther ) { const DocumentGeometry * dg= &(sp->spDocumentGeometry); int pageWide; int sumOthers= 0; int i; int victim; int left; pageWide= dg->dgPageWideTwips- dg->dgLeftMarginTwips- dg->dgRightMarginTwips; for ( i= 0; i < sp->spColumnCount- 1; i++ ) { if ( i == col ) { continue; } sumOthers += sp->spColumns[i].scColumnWidthTwips; sumOthers += sp->spColumns[i].scSpaceToRightTwips; } if ( i != col ) { sumOthers += sp->spColumns[i].scColumnWidthTwips; } sumOthers += colOther; if ( col == sp->spColumnCount- 1 ) { victim= sp->spColumnCount-2; } else{ victim= sp->spColumnCount-1; } left= sp->spColumns[victim].scColumnWidthTwips- MIN_COL_WIDE; if ( pVictim ) { *pVictim= victim; } if ( pMaxValue ) { *pMaxValue= pageWide- sumOthers+ left; } return sumOthers; } /************************************************************************/ /* */ /* Claim extra space by subtracting it from the column width of the */ /* victim. Applies for explicit column layout only. */ /* */ /************************************************************************/ static int docSectReserveWidth( SectionProperties * sp, int victim, int sumValues ) { const DocumentGeometry * dg= &(sp->spDocumentGeometry); int pageWide; pageWide= dg->dgPageWideTwips- dg->dgLeftMarginTwips- dg->dgRightMarginTwips; if ( sumValues > pageWide ) { int narrowed; narrowed= pageWide- sumValues+ sp->spColumns[victim].scColumnWidthTwips; if ( narrowed < MIN_COL_WIDE ) { LDEB(narrowed); return -1; } sp->spColumns[victim].scColumnWidthTwips= narrowed; } return 0; } /************************************************************************/ static void docSectGetEqualWidths( int * pColWide, int * pGapWide, int * pMaxColWide, int * pMaxGapWide, const SectionProperties * sp ) { const DocumentGeometry * dg= &(sp->spDocumentGeometry); int pageWide; int colWide; int maxColWide; int gapWide; int maxGapWide; int ncol= sp->spColumnCount; int ngap= sp->spColumnCount- 1; pageWide= dg->dgPageWideTwips- dg->dgLeftMarginTwips- dg->dgRightMarginTwips; colWide= ( pageWide- ngap* sp->spColumnSpacingTwips )/ ncol; maxColWide= ( pageWide- ngap* MIN_GAP_WIDE )/ ncol; gapWide= sp->spColumnSpacingTwips; if ( ngap == 0 ) { maxGapWide= 0; } else{ maxGapWide= ( pageWide- ncol* MIN_COL_WIDE )/ ngap; } if ( pColWide ) { *pColWide= colWide; } if ( pGapWide ) { *pGapWide= gapWide; } if ( pMaxColWide ) { *pMaxColWide= maxColWide; } if ( pMaxGapWide ) { *pMaxGapWide= maxGapWide; } return; } /************************************************************************/ /* */ /* Get the spacing right of a column. */ /* */ /************************************************************************/ int docSectGetColumnSpacing( int * pMinValue, int * pMaxValue, const SectionProperties * sp, int col ) { int value; int maxValue; int haveFixedWidth; haveFixedWidth= docSectPropsFixedWidthColumns( sp ); if ( haveFixedWidth ) { docSectGetEqualWidths( (int *)0, &value, (int *)0, &maxValue, sp ); } else{ docSectColsSumOthers( (int *)0, &maxValue, sp, col, sp->spColumns[col].scColumnWidthTwips ); value= sp->spColumns[col].scSpaceToRightTwips; } if ( pMaxValue ) { *pMaxValue= maxValue; } if ( pMinValue ) { *pMinValue= MIN_GAP_WIDE; } return value; } /************************************************************************/ /* */ /* Set the spacing right of a column. */ /* */ /************************************************************************/ int docSectSetColumnSpacing( SectionProperties * sp, int col, int newValue ) { int maxValue; int haveFixedWidth; haveFixedWidth= docSectPropsFixedWidthColumns( sp ); if ( haveFixedWidth ) { if ( col > 0 ) { LLLDEB(haveFixedWidth,col,newValue); return -1; } docSectGetEqualWidths( (int *)0, (int *)0, (int *)0, &maxValue, sp ); if ( newValue < MIN_GAP_WIDE || newValue > maxValue ) { LLDEB(newValue,maxValue); return -1; } sp->spColumnSpacingTwips= newValue; } else{ int victim; int sumOthers; sumOthers= docSectColsSumOthers( &victim, &maxValue, sp, col, sp->spColumns[col].scColumnWidthTwips ); if ( newValue < MIN_GAP_WIDE || newValue > maxValue ) { LLDEB(newValue,maxValue); return -1; } if ( victim == col ) { LLDEB(victim,col); return -1; } if ( docSectReserveWidth( sp, victim, sumOthers+ newValue ) ) { LLDEB(sumOthers,newValue); return -1; } sp->spColumns[col].scSpaceToRightTwips= newValue; } return 0; } /************************************************************************/ /* */ /* Get the spacing right of a column. */ /* */ /************************************************************************/ int docSectGetColumnWidth( int * pMinValue, int * pMaxValue, const SectionProperties * sp, int col ) { int value; int maxValue; int haveFixedWidth; haveFixedWidth= docSectPropsFixedWidthColumns( sp ); if ( haveFixedWidth ) { docSectGetEqualWidths( &value, (int *)0, &maxValue, (int *)0, sp ); } else{ docSectColsSumOthers( (int *)0, &maxValue, sp, col, sp->spColumns[col].scSpaceToRightTwips ); value= sp->spColumns[col].scColumnWidthTwips; } if ( pMinValue ) { *pMinValue= MIN_COL_WIDE; } if ( pMaxValue ) { *pMaxValue= maxValue; } return value; } /************************************************************************/ /* */ /* Set the spacing right of a column. */ /* */ /************************************************************************/ int docSectSetColumnWidth( SectionProperties * sp, int col, int newValue ) { int maxValue; int haveFixedWidth; haveFixedWidth= docSectPropsFixedWidthColumns( sp ); if ( haveFixedWidth ) { const DocumentGeometry * dg= &(sp->spDocumentGeometry); int pageWide; int gapWide; docSectGetEqualWidths( (int *)0, &gapWide, &maxValue, (int *)0, sp ); if ( newValue < MIN_COL_WIDE || newValue > maxValue ) { LLDEB(newValue,maxValue); return -1; } pageWide= dg->dgPageWideTwips- dg->dgLeftMarginTwips- dg->dgRightMarginTwips; gapWide= ( pageWide- ( sp->spColumnCount* newValue ) )/ ( sp->spColumnCount- 1 ); if ( gapWide < MIN_GAP_WIDE ) { LLDEB(gapWide,MIN_GAP_WIDE); gapWide= MIN_GAP_WIDE; } sp->spColumnSpacingTwips= gapWide; } else{ int victim; int sumOthers; sumOthers= docSectColsSumOthers( &victim, &maxValue, sp, col, sp->spColumns[col].scSpaceToRightTwips ); if ( newValue < MIN_COL_WIDE || newValue > maxValue ) { LLDEB(newValue,maxValue); return -1; } if ( victim == col ) { LLDEB(victim,col); return -1; } if ( docSectReserveWidth( sp, victim, sumOthers+ newValue ) ) { LLDEB(sumOthers,newValue); return -1; } sp->spColumns[col].scColumnWidthTwips= newValue; } return 0; }