import { luckysheetfontformat } from '../utils/util'; import menuButton from '../controllers/menuButton'; import { getcellvalue,checkstatusByCell } from './getdata'; import { colLocationByIndex } from './location'; import { hasChinaword, isRealNull,checkWordByteLength } from './validate'; import { isInlineStringCell } from '../controllers/inlineString'; import Store from '../store'; //计算范围行高 function rowlenByRange(d, r1, r2, cfg) { let cfg_clone = $.extend(true, {}, cfg); if(cfg_clone["rowlen"] == null){ cfg_clone["rowlen"] = {}; } if(cfg_clone["customHeight"] == null){ cfg_clone["customHeight"] = {}; } let canvas = $("#luckysheetTableContent").get(0).getContext("2d"); canvas.textBaseline = 'top'; //textBaseline以top计算 for(let r = r1; r <= r2; r++){ if (cfg_clone["rowhidden"] != null && cfg_clone["rowhidden"][r] != null) { continue; } let currentRowLen = Store.defaultrowlen; if(cfg_clone["customHeight"][r]==1){ continue; } delete cfg_clone["rowlen"][r]; for(let c = 0; c < d[r].length; c++){ let cell = d[r][c]; if(cell == null || cell.mc != null){ continue; } if(cell != null && (cell.v != null || isInlineStringCell(cell)) ){ let cellWidth = colLocationByIndex(c)[1] - colLocationByIndex(c)[0] - 2; let textInfo = getCellTextInfo(cell, canvas,{ r:r, c:c, cellWidth:cellWidth }); let computeRowlen = 0; if(textInfo!=null){ computeRowlen = textInfo.textHeightAll+2; } //比较计算高度和当前高度取最大高度 if(computeRowlen > currentRowLen){ currentRowLen = computeRowlen; } } } currentRowLen = currentRowLen/Store.zoomRatio; if(currentRowLen != Store.defaultrowlen){ cfg_clone["rowlen"][r] = currentRowLen; } } return cfg_clone; } //计算表格行高数组 function computeRowlenArr(rowHeight, cfg) { let rowlenArr = []; let rh_height = 0; for (let i = 0; i < rowHeight; i++) { let rowlen = Store.defaultrowlen; if (cfg["rowlen"] != null && cfg["rowlen"][i] != null) { rowlen = cfg["rowlen"][i]; } if (cfg["rowhidden"] != null && cfg["rowhidden"][i] != null) { rowlen = cfg["rowhidden"][i]; rowlenArr.push(rh_height); continue; } else { rh_height += rowlen + 1; } rowlenArr.push(rh_height);//行的临时长度分布 } return rowlenArr; } //获取换行单元格截断数组 function getCellTextSplitArr(strValue, strArr, cellWidth, canvas){ for(let strI = 1; strI <= strValue.length; strI++){ let strV = strValue.substring(0, strI); let strtextMetrics = getMeasureText(strV, canvas).width; if(strtextMetrics > cellWidth){ if(strI - 1 <= 0){ return strArr; } else{ strArr.push(strValue.substring(0, strI - 1)); return getCellTextSplitArr(strValue.substring(strI - 1), strArr, cellWidth, canvas); } } else if(strI == strValue.length){ strArr.push(strV); } } return strArr; } //获取有值单元格文本大小 // let measureTextCache = {}, measureTextCacheTimeOut = null; function getMeasureText(value, ctx, fontset){ let mtc = Store.measureTextCache[value + "_" + ctx.font]; if(fontset!=null){ mtc = Store.measureTextCache[value + "_" + fontset]; } if(mtc != null){ return mtc; } else{ if(fontset!=null){ let preFont = ctx.font; ctx.font = fontset; } let measureText = ctx.measureText(value), cache = {}; // var regu = "^[ ]+$"; // var re = new RegExp(regu); // if(measureText.actualBoundingBoxRight==null || re.test(value)){ // cache.width = measureText.width; // } // else{ // //measureText.actualBoundingBoxLeft + // cache.width = measureText.actualBoundingBoxRight; // } cache.width = measureText.width; if(fontset!=null){ ctx.font = fontset; } cache.actualBoundingBoxDescent = measureText.actualBoundingBoxDescent; cache.actualBoundingBoxAscent = measureText.actualBoundingBoxAscent; if(cache.actualBoundingBoxDescent==null || cache.actualBoundingBoxAscent==null || isNaN(cache.actualBoundingBoxDescent) || isNaN(cache.actualBoundingBoxAscent)){ let commonWord = "M" if(hasChinaword(value)){ commonWord = "田"; } let oneLineTextHeight = menuButton.getTextSize(commonWord, ctx.font)[1]*0.8; if(ctx.textBaseline=="top"){ cache.actualBoundingBoxDescent = oneLineTextHeight; cache.actualBoundingBoxAscent = 0; } else if(ctx.textBaseline=="middle"){ cache.actualBoundingBoxDescent = oneLineTextHeight/2; cache.actualBoundingBoxAscent = oneLineTextHeight/2; } else{ cache.actualBoundingBoxDescent = 0; cache.actualBoundingBoxAscent = oneLineTextHeight; } //console.log(value, oneLineTextHeight, measureText.actualBoundingBoxDescent+measureText.actualBoundingBoxAscent,ctx.font); } if(ctx.textBaseline == 'alphabetic'){ let descText = "gjpqy", matchText="abcdABCD"; let descTextMeasure = Store.measureTextCache[descText + "_" + ctx.font]; if(fontset!=null){ descTextMeasure = Store.measureTextCache[descText + "_" + fontset]; } let matchTextMeasure = Store.measureTextCache[matchText + "_" + ctx.font]; if(fontset!=null){ matchTextMeasure = Store.measureTextCache[matchText + "_" + fontset]; } if(descTextMeasure == null){ descTextMeasure = ctx.measureText(descText); } if(matchTextMeasure == null){ matchTextMeasure = ctx.measureText(matchText); } if(cache.actualBoundingBoxDescent<=matchTextMeasure.actualBoundingBoxDescent){ cache.actualBoundingBoxDescent = descTextMeasure.actualBoundingBoxDescent; if(cache.actualBoundingBoxDescent==null){ cache.actualBoundingBoxDescent = 0; } } } cache.width *= Store.zoomRatio; cache.actualBoundingBoxDescent *= Store.zoomRatio; cache.actualBoundingBoxAscent *= Store.zoomRatio; Store.measureTextCache[value + "_" + Store.zoomRatio + "_" + ctx.font] = cache; // console.log(measureText, value); return cache; } } function isSupportBoundingBox(ctx){ let measureText = ctx.measureText("田"); if(measureText.actualBoundingBoxAscent==null){ return false; } return true; } //获取单元格文本内容的渲染信息 // let measureTextCache = {}, measureTextCacheTimeOut = null; // option {cellWidth,cellHeight,space_width,space_height} function getCellTextInfo(cell , ctx, option){ let cellWidth = option.cellWidth; let cellHeight = option.cellHeight; let isMode = "", isModeSplit = ""; // console.log("initialinfo", cell, option); if(cellWidth==null){ isMode = "onlyWidth"; isModeSplit = "_"; } let textInfo = Store.measureTextCellInfoCache[option.r + "_" + option.c + isModeSplit + isMode]; if(textInfo != null){ return textInfo; } // let cell = Store.flowdata[r][c]; let space_width = option.space_width, space_height = option.space_height; //宽高方向 间隙 if(space_width==null){ space_width = 2; } if(space_height==null){ space_height = 2; } //水平对齐 let horizonAlign = checkstatusByCell(cell, "ht"); //垂直对齐 let verticalAlign = checkstatusByCell(cell, "vt"); let tb = checkstatusByCell(cell ,"tb");//wrap overflow let tr = checkstatusByCell(cell ,"tr");//rotate let rt = checkstatusByCell(cell ,"rt");//rotate angle let isRotateUp = 1, isRotateDown=0; if(rt==null){ if(tr=="0"){ rt = 0; } else if(tr=="1"){ rt = 45; } else if(tr=="4"){ rt = 90; } else if(tr=="2"){ rt = 135; } else if(tr=="5"){ rt = 180; } if(rt==null){ rt = 0; } } if(rt>180 || rt<0){ rt = 0; } rt = parseInt(rt); if(rt>90){ rt = 90 -rt; isRotateUp = 0; isRotateDown = 1; } ctx.textAlign="start"; let textContent = {}; textContent.values = []; let fontset, cancelLine="0", underLine="0", fontSize=11, isInline=false, value, inlineStringArr=[]; if(isInlineStringCell(cell)){ let sharedStrings = cell.ct.s, similarIndex = 0; for(let i=0;icellHeight && textH_all_Column[colIndex]!=null){ // textW_all += textW; // textH_all = Math.max(textH_all,textH_all_cache); // console.log(">",i,colIndex); textH_all_ColumnHeight.push(textH_all_cache-textH); textH_all_cache = textH; colIndex +=1; } } if(i== inlineStringArr.length-1){ textH_all_ColumnHeight.push(textH_all_cache); } if(textH_all_Column[colIndex]==null){ textH_all_Column[colIndex]= []; } let item = { content:showValue, style:shareCell, width:textW, height:textH, left:0, top:0, colIndex:colIndex, asc:measureText.actualBoundingBoxAscent, desc:measureText.actualBoundingBoxDescent, inline:true, } if(shareCell.wrap===true){ item.wrap=true; } textH_all_Column[colIndex].push(item); console.log("normal",i,colIndex,shareCell, preShareCell, textH_all_Column); preShareCell = shareCell; } } else{ let measureText = getMeasureText(value, ctx); let textHeight = measureText.actualBoundingBoxDescent + measureText.actualBoundingBoxAscent; value = value.toString(); let vArr = []; if(value.length > 1){ vArr = value.split(""); } else{ vArr.push(value); } let oneWordWidth = getMeasureText(vArr[0], ctx).width; for(let i = 0; i < vArr.length; i++){ let textW = oneWordWidth + space_width; let textH = textHeight + space_height; // textW_all += textW; textH_all_cache += textH; if(tb=="2"){ if(textH_all_cache>cellHeight && textH_all_Column[colIndex]!=null){ // textW_all += textW; // textH_all = Math.max(textH_all,textH_all_cache); textH_all_ColumnHeight.push(textH_all_cache-textH); textH_all_cache = textH; colIndex +=1; } } if(i== vArr.length-1){ textH_all_ColumnHeight.push(textH_all_cache); } if(textH_all_Column[colIndex]==null){ textH_all_Column[colIndex]= []; } textH_all_Column[colIndex].push({ content:vArr[i], style:fontset, width:textW, height:textH, left:0, top:0, colIndex:colIndex, asc:measureText.actualBoundingBoxAscent, desc:measureText.actualBoundingBoxDescent }); } } let textH_all_ColumWidth = []; for(let i = 0; i < textH_all_ColumnHeight.length; i++){ let columnHeight = textH_all_ColumnHeight[i]; let col = textH_all_Column[i], colMaxW=0; for(let c=0;c1){ for(let s=0;scellHeight); if((height+space_height)>cellHeight && text_all_split[splitIndex]!=null && tb=="2" && i!= inlineStringArr.length){ // console.log("cut",anchor, i , str); if(spaceOrTwoByteIndex!=null && spaceOrTwoByteIndexcellWidth && text_all_split[splitIndex]!=null && tb=="2" && i!= inlineStringArr.length){ if(spaceOrTwoByteIndex!=null && spaceOrTwoByteIndexcellHeight && text_all_split[splitIndex]!=null && i!= value.length){ // console.log("cut",anchor, i , str); if(spaceOrTwoByte!=null && spaceOrTwoByte.indexcellWidth && text_all_split[splitIndex]!=null && i!= value.length){ // console.log(spaceOrTwoByte, i, anchor); if(spaceOrTwoByte!=null && spaceOrTwoByte.index=0;c--){ let wordGroup = splitLists[c]; let left, top; if(rt!=0){//rotate let x, y = cumWordHeight+size.asc; x = (cumWordHeight)/Math.tan(rtPI) - cumColumnWidth + textW_all_inner; if(horizonAlign == "0"){//center let sh = textH_all/Math.sin(rtPI); if(verticalAlign == "0"){//mid left = x + cellWidth/2 - (textW_all/2) + lastLineSpaceHeight*Math.cos(rtPI)/2; top = y + cellHeight/2 - textH_all/2 - lastLineSpaceHeight*Math.cos(rtPI)/2; } else if(verticalAlign == "1"){//top left = x + cellWidth/2 - textW_all/2; top = y - (textH_all/2 - rh/2); } else if(verticalAlign == "2"){//bottom left = x + cellWidth/2 - (textW_all/2)+lastLineSpaceHeight*Math.cos(rtPI); top = y + cellHeight - rh/2 - textH_all/2 - lastLineSpaceHeight*Math.cos(rtPI); } } else if(horizonAlign == "1"){//left if(verticalAlign == "0"){//mid left = x - rh*Math.sin(rtPI)/2 + lastLineSpaceHeight*Math.cos(rtPI)/2; top = y + cellHeight/2 + rh*Math.cos(rtPI)/2 - lastLineSpaceHeight*Math.cos(rtPI)/2; } else if(verticalAlign == "1"){//top left = x - rh*Math.sin(rtPI); top = y + rh*Math.cos(rtPI); } else if(verticalAlign == "2"){//bottom left = x + lastLineSpaceHeight*Math.cos(rtPI); top = y + cellHeight - lastLineSpaceHeight*Math.cos(rtPI); } } else if(horizonAlign == "2"){//right if(verticalAlign == "0"){//mid left = x + cellWidth - rw/2 - (textW_all_inner/2+(textH_all/2)/Math.tan(rtPI))+ lastLineSpaceHeight*Math.cos(rtPI)/2; top = y + cellHeight/2 - textH_all/2 - lastLineSpaceHeight*Math.cos(rtPI)/2; } else if(verticalAlign == "1"){//top fixOneLineLeft left = x + cellWidth - textW_all + fixOneLineLeft; top = y - textH_all; } else if(verticalAlign == "2"){//bottom left = x + cellWidth - rw*Math.cos(rtPI) + lastLineSpaceHeight*Math.cos(rtPI); top = y + cellHeight - rw*Math.sin(rtPI) - lastLineSpaceHeight*Math.cos(rtPI); } } } wordGroup.left = left; wordGroup.top = top; // console.log(left, top, cumWordHeight, size.height); drawLineInfo(wordGroup, cancelLine, underLine,{ width:wordGroup.width, height:wordGroup.height, left:left-wordGroup.width, top:top, asc:size.asc, desc:size.desc, fs:wordGroup.fs }); textContent.values.push(wordGroup); cumColumnWidth += wordGroup.width; } cumWordHeight += size.height; } } else{ for(let i = 0; i < splitLen; i++){ let splitLists = text_all_split[i]; if(splitLists==null){ continue; } let size = split_all_size[i]; cumColumnWidth = 0; for(let c=0;c