UNPKG

devexpress-richedit

Version:

DevExpress Rich Text Editor is an advanced word-processing tool designed for working with rich text documents.

98 lines (97 loc) 5.89 kB
import { UnitConverter } from '@devexpress/utils/lib/class/unit-converter'; import { Rectangle } from '@devexpress/utils/lib/geometry/rectangle'; import { isEven } from '@devexpress/utils/lib/utils/common'; import { ListUtils } from '@devexpress/utils/lib/utils/list'; export class BoundsCalculator { constructor() { this.pageIndex = -1; } init(section) { this.section = section; this.mirrorMargins = section.documentModel.mirrorMargins; const sectionProperties = this.section.sectionProperties; this.equalWidthColumns = sectionProperties.equalWidthColumns; this.columnCount = sectionProperties.columnCount; this.space = UnitConverter.twipsToPixelsF(sectionProperties.space); this.marginTop = UnitConverter.twipsToPixelsF(sectionProperties.marginTop); this.marginBottom = UnitConverter.twipsToPixelsF(sectionProperties.marginBottom); this.marginRight = UnitConverter.twipsToPixelsF(sectionProperties.marginRight); this.marginBottom = UnitConverter.twipsToPixelsF(sectionProperties.marginBottom); this.marginLeft = UnitConverter.twipsToPixelsF(sectionProperties.marginLeft); this.pageWidth = UnitConverter.twipsToPixelsF(sectionProperties.pageWidth); this.pageHeight = UnitConverter.twipsToPixelsF(sectionProperties.pageHeight); this.headerOffset = UnitConverter.twipsToPixelsF(sectionProperties.headerOffset); this.footerOffset = UnitConverter.twipsToPixelsF(sectionProperties.footerOffset); if (this.mirrorMargins && this.pageIndex >= 0 && isEven(this.pageIndex)) [this.marginRight, this.marginLeft] = [this.marginLeft, this.marginRight]; this.columnsInfo = ListUtils.map(sectionProperties.columnsInfo, (columnProps) => columnProps.clone().applyConverter(UnitConverter.twipsToPixelsF)); this.avaliablePageHeight = this.pageHeight - (this.marginTop + this.marginBottom); this.availableHeaderFooterWidth = this.pageWidth - this.marginLeft - this.marginRight; } initWhenPageStart(pageIndex) { this.pageIndex = pageIndex; this.mainPageAreasBounds = []; this.mainColumnsBounds = []; } setHeaderBounds(currHeight) { if (currHeight == 0) { this.headerPageAreaBounds = null; this.headerColumnBounds = null; return; } const height = currHeight == -1 ? Number.MAX_VALUE : Math.max(this.marginTop - this.headerOffset, Math.min(Math.floor(this.pageHeight * BoundsCalculator.MAX_HEADER_FOOTER_HEIGHT_COEFF), currHeight)); this.headerPageAreaBounds = new Rectangle(this.marginLeft, this.headerOffset, this.availableHeaderFooterWidth, height); this.headerColumnBounds = new Rectangle(0, 0, this.headerPageAreaBounds.width, this.headerPageAreaBounds.height); } setFooterBounds(currHeight) { if (currHeight == 0) { this.footerPageAreaBounds = null; this.footerColumnBounds = null; return; } if (currHeight == -1) { this.footerPageAreaBounds = new Rectangle(this.marginLeft, this.pageHeight - this.footerOffset, this.availableHeaderFooterWidth, Number.MAX_VALUE); this.footerColumnBounds = new Rectangle(0, 0, this.footerPageAreaBounds.width, this.footerPageAreaBounds.height); } else { currHeight = Math.min(Math.round(this.pageHeight * BoundsCalculator.MAX_HEADER_FOOTER_HEIGHT_COEFF), currHeight); const pageAreaHeight = this.footerOffset + currHeight; this.footerPageAreaBounds = new Rectangle(this.marginLeft, this.pageHeight - pageAreaHeight, this.availableHeaderFooterWidth, pageAreaHeight); this.footerColumnBounds = new Rectangle(0, 0, this.footerPageAreaBounds.width, currHeight); } } calculateMainPageAreaBounds(previousMainPageAreaHeight) { let y; if (previousMainPageAreaHeight > 0) { const previousPageAreaBounds = this.mainPageAreasBounds[this.mainPageAreasBounds.length - 1]; for (let colBound of this.mainColumnsBounds[this.mainColumnsBounds.length - 1]) colBound.height = previousMainPageAreaHeight; previousPageAreaBounds.height = previousMainPageAreaHeight; y = previousPageAreaBounds.bottom; } else y = Math.max(this.marginTop, this.headerPageAreaBounds ? this.headerPageAreaBounds.bottom : 0); let height = Math.min(this.pageHeight - this.marginBottom, this.footerPageAreaBounds ? this.footerPageAreaBounds.y : Number.MAX_VALUE) - y; this.mainPageAreasBounds.push(new Rectangle(this.marginLeft, y, this.availableHeaderFooterWidth, height)); } calculateColumnBounds(pageAreaBounds) { if (this.equalWidthColumns) { const oneColumnWidth = Math.floor((this.availableHeaderFooterWidth - (this.columnCount - 1) * this.space) / this.columnCount); const colWidthPlusSpace = oneColumnWidth + this.space; this.mainColumnsBounds.push(ListUtils.initByCallback(this.columnCount, (columnIndex) => new Rectangle(colWidthPlusSpace * columnIndex, 0, oneColumnWidth, pageAreaBounds.height))); } else { let currXPos = 0; this.mainColumnsBounds.push(ListUtils.map(this.columnsInfo, (columnInfo) => { const rect = new Rectangle(currXPos, 0, Math.max(1, columnInfo.width), pageAreaBounds.height); currXPos += columnInfo.width + columnInfo.space; return rect; })); } } calculatePageBounds(y) { this.pageBounds = new Rectangle(0, y, this.pageWidth, this.pageHeight); } } BoundsCalculator.MAX_HEADER_FOOTER_HEIGHT_COEFF = 0.48;