'use strict'; const JV = require('../jpc_value_define'); const JpcCommonHelper = { commonConstant: {}, getResultByID: function(KeyID, collectionList) { let rst = null; if (KeyID) { for (let i = 0; i < collectionList.length; i++) { const collection = collectionList[i]; if (collection && collection instanceof Array) { for (let j = 0; j < collection.length; j++) { if (collection[j][JV.PROP_ID] === KeyID) { rst = collection[j]; break; } } if (rst) break; } } } return rst; }, getFont: function(fontName, dftFonts, rptTpl) { const me = this; const list = []; if (rptTpl) list.push(rptTpl[JV.NODE_FONT_COLLECTION]); list.push(dftFonts); return me.getResultByID(fontName, list); }, getStyle: function(styleName, dftStyles, rptTpl) { const me = this; const list = []; if (rptTpl) list.push(rptTpl[JV.NODE_STYLE_COLLECTION]); list.push(dftStyles); return me.getResultByID(styleName, list); }, getControl: function(controlName, dftControls, rptTpl) { const me = this; const list = []; if (rptTpl) list.push(rptTpl[JV.NODE_CONTROL_COLLECTION]); list.push(dftControls); return me.getResultByID(controlName, list); }, getLayoutAlignment: function(alignStr) { let rst = JV.LAYOUT.indexOf(alignStr); if (rst < 0) rst = JV.LAYOUT_FULFILL; return rst; }, getPosCalculationType: function (typeStr) { let rst = JV.CAL_TYPE.indexOf(typeStr); if (rst < 0) rst = JV.CAL_TYPE_ABSTRACT; return rst; }, getBoolean: function(bStr) { let rst = false; if (bStr !== null && bStr !== undefined) { const valType = typeof bStr; if (valType === 'boolean') { rst = bStr; } else if (valType === 'string') { const tS = bStr.toUpperCase(); rst = (tS === 'T' || tS === 'TRUE' || tS === 'YES' || tS === 'Y'); } else if (valType === 'number') { rst = (bStr === 1); } } return rst; }, getScreenDPI: function() { const me = this; let arrDPI = []; if (!me.commonConstant.resolution) { arrDPI = [96,96]; // arrDPI = [100,100]; me.commonConstant.resolution = arrDPI; } else { arrDPI = me.commonConstant.resolution; } return arrDPI; }, getUnitFactor: function(rptTpl) { const me = this; return me.translateUnit(rptTpl[JV.NODE_MAIN_INFO][JV.PROP_UNITS]); }, translateUnit: function(unitStr) { const me = this; let rst = 1.0; if (unitStr) { const resolution = me.getScreenDPI(); if (JV.MEASUREMENT.PIXEL.indexOf(unitStr) >= 0) { rst = 1.0; } else if (JV.MEASUREMENT.CM.indexOf(unitStr) >= 0) { rst = 1.0 * resolution[0] / 2.54; } else if (JV.MEASUREMENT.INCH.indexOf(unitStr) >= 0) { rst = 1.0 * resolution[0]; } } return rst; }, getPageSize: function(rptTpl) { let size = null; const sizeStr = rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE]; const sizeIdx = JV.PAGES_SIZE_STR.indexOf(sizeStr); if (sizeIdx >= 0) { size = JV.PAGES_SIZE[sizeIdx].slice(0); } else if (sizeStr === JV.PAGE_SELF_DEFINE) { // } else { size = JV.SIZE_A4.slice(0); } const page_orientation = rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION]; if (page_orientation === JV.ORIENTATION_LANDSCAPE || page_orientation === JV.ORIENTATION_LANDSCAPE_CHN) { //swap x,y const tmp = size[0]; size[0] = size[1]; size[1] = tmp; } return size; }, getReportArea: function(rptTpl, unitFactor) { const me = this; const resolution = me.getScreenDPI(); const rst = []; const size = me.getPageSize(rptTpl); size[0] = resolution[0] * size[0]; size[1] = resolution[0] * size[1]; rst.push(unitFactor * rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]); rst.push(unitFactor * rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_TOP]); rst.push(size[0] - unitFactor * rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT]); rst.push(size[1] - unitFactor * rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_BOTTOM]); return rst; }, getSegIdxByPageIdx: function(page, page_seg_map) { let rst = -1; for (let pIdx = 0; pIdx < page_seg_map.length; pIdx++) { if (page_seg_map[pIdx][0] === page) { rst = page_seg_map[pIdx][1]; break; } } return rst; }, getStringLinesInArea: function(area, strVal, chnW, otherW) { // 备注: 因后台的pdf kit判断字符串长度与前端的不一样,需要做些调整,不一次性地判断字符串长度。 // 分2种字符:中文与非中文,按照各种字符的数量分别乘以相关一个字符的宽度再累计。 // 另判断行数还不能直接用总长度除以宽度来计算,因每一行都会有不同的余量,所以得一行行走过来判断。 let rst = 0; if (strVal) { const areaWidth = area[JV.PROP_RIGHT] - area[JV.PROP_LEFT] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_LEFT] - 1; let txtWidth = 0; let currentW = 0; for (let sIdx = 0; sIdx < strVal.length; sIdx++) { currentW = (strVal.charCodeAt(sIdx) > 127)?chnW:otherW; txtWidth += currentW; if (txtWidth > areaWidth) { rst++; txtWidth = currentW; } if (sIdx === strVal.length - 1) { rst++; } } } if (rst === 0) rst = 1; // 即使是空字符串,也得有一行啊 return rst; // 备注: 其实是想用canvas的,但node canvas装起来麻烦,暂时用PDF Kit来顶用一下,以后有更好的再换 }, splitString: function(area, strVal, chnW, otherW) { const rst = []; if (strVal) { const areaWidth = area[JV.PROP_RIGHT] - area[JV.PROP_LEFT] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_LEFT] - 1; let preSIdx = 0; let txtWidth = 0; let currentW = 0; for (let sIdx = 0; sIdx < strVal.length; sIdx++) { currentW = (strVal.charCodeAt(sIdx) > 127) ? chnW : otherW; txtWidth += currentW; if (txtWidth > areaWidth) { if (preSIdx < sIdx) { rst.push(strVal.substr(preSIdx, sIdx - preSIdx)); preSIdx = sIdx; } else { rst.push(strVal.substr(preSIdx, 1)); preSIdx = sIdx + 1; } txtWidth = currentW; } if (sIdx === strVal.length - 1) { rst.push(strVal.substr(preSIdx, strVal.length - preSIdx)); } } } if (rst.length === 0) rst.push(''); // 什么都没有,也得整个空串 return rst; }, }; module.exports = JpcCommonHelper;