You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1623 lines
64 KiB
1623 lines
64 KiB
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;i<sharedStrings.length;i++){
|
|
let shareCell = sharedStrings[i];
|
|
let scfontset = luckysheetfontformat(shareCell);
|
|
let fc = shareCell.fc, cl=shareCell.cl,un = shareCell.un, v = shareCell.v, fs=shareCell.fs;
|
|
v = v.replace(/\r\n/g, "_x000D_").replace(/ /g, "_x000D_").replace(/\r/g, "_x000D_").replace(/\n/g, "_x000D_");
|
|
let splitArr = v.split("_x000D_"), preNewValue=null;
|
|
for(let x=0;x<splitArr.length;x++){
|
|
let newValue = splitArr[x];
|
|
|
|
if(newValue=="" && x!=splitArr.length-1){
|
|
inlineStringArr.push({
|
|
fontset:scfontset,
|
|
fc:fc==null?"#000":fc,
|
|
cl:cl==null?0:cl,
|
|
un:un==null?0:un,
|
|
wrap:true,
|
|
fs:fs==null?11:fs,
|
|
});
|
|
similarIndex++;
|
|
}
|
|
else{
|
|
let newValueArray = newValue.split("");
|
|
for(let n=0;n<newValueArray.length;n++){
|
|
let nv = newValueArray[n];
|
|
|
|
inlineStringArr.push({
|
|
fontset:scfontset,
|
|
fc:fc==null?"#000":fc,
|
|
cl:cl==null?0:cl,
|
|
un:un==null?0:un,
|
|
v: nv,
|
|
si:similarIndex,
|
|
fs:fs==null?11:fs,
|
|
});
|
|
|
|
}
|
|
|
|
if(x!=splitArr.length-1 && preNewValue!="" ){
|
|
inlineStringArr.push({
|
|
fontset:scfontset,
|
|
fc:fc==null?"#000":fc,
|
|
cl:cl==null?0:cl,
|
|
un:un==null?0:un,
|
|
wrap:true,
|
|
fs:fs==null?11:fs,
|
|
});
|
|
similarIndex++;
|
|
}
|
|
}
|
|
|
|
preNewValue = newValue;
|
|
|
|
}
|
|
|
|
similarIndex++;
|
|
|
|
}
|
|
isInline = true;
|
|
}
|
|
else{
|
|
fontset = luckysheetfontformat(cell);
|
|
ctx.font = fontset;
|
|
|
|
cancelLine = checkstatusByCell(cell ,"cl");//cancelLine
|
|
underLine = checkstatusByCell(cell ,"un");//underLine
|
|
fontSize = checkstatusByCell(cell ,"fs");
|
|
|
|
if(cell instanceof Object){
|
|
value = cell.m;
|
|
if(value == null){
|
|
value = cell.v;
|
|
}
|
|
}
|
|
else{
|
|
value = cell;
|
|
}
|
|
|
|
if(isRealNull(value)){
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
// let measureText = getMeasureText(value, ctx);
|
|
// //luckysheetTableContent.measureText(value);
|
|
// let textWidth = measureText.width;
|
|
// let textHeight = measureText.actualBoundingBoxDescent + measureText.actualBoundingBoxAscent;
|
|
|
|
if(tr=="3"){//vertical text
|
|
ctx.textBaseline = 'top';
|
|
|
|
|
|
let textW_all = 0; //拆分后宽高度合计
|
|
let textH_all = 0;
|
|
let colIndex=0, textH_all_cache=0, textH_all_Column = {}, textH_all_ColumnHeight=[];
|
|
if(isInline){
|
|
let preShareCell = null;
|
|
for(let i = 0; i < inlineStringArr.length; i++){
|
|
let shareCell = inlineStringArr[i];
|
|
let value = shareCell.v, showValue=shareCell.v;
|
|
if(shareCell.wrap===true){
|
|
value = "M";
|
|
showValue = "";
|
|
|
|
|
|
if( preShareCell!=null && preShareCell.wrap!==true && (i<inlineStringArr.length-1)){
|
|
// console.log("wrap",i,colIndex,preShareCell.wrap);
|
|
textH_all_ColumnHeight.push(textH_all_cache);
|
|
textH_all_cache = 0;
|
|
colIndex +=1;
|
|
|
|
preShareCell = shareCell;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
let measureText = getMeasureText(value, ctx, shareCell.fontset);
|
|
|
|
let textW = measureText.width + space_width;
|
|
let textH = measureText.actualBoundingBoxAscent + measureText.actualBoundingBoxDescent + space_height;
|
|
|
|
// textW_all += textW;
|
|
textH_all_cache += textH;
|
|
|
|
|
|
if(tb=="2" && !shareCell.wrap){
|
|
if(textH_all_cache>cellHeight && 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;c<col.length;c++){
|
|
let word = col[c];
|
|
colMaxW = Math.max(colMaxW, word.width);
|
|
}
|
|
textH_all_ColumWidth.push(colMaxW);
|
|
textW_all += colMaxW;
|
|
textH_all = Math.max(textH_all, columnHeight);
|
|
}
|
|
|
|
textContent.type = "verticalWrap";
|
|
textContent.textWidthAll = textW_all;
|
|
textContent.textHeightAll = textH_all;
|
|
|
|
if(isMode=="onlyWidth"){
|
|
// console.log("verticalWrap", textContent,cell, option);
|
|
return textContent;
|
|
}
|
|
|
|
let cumColumnWidth = 0;
|
|
for(let i = 0; i < textH_all_ColumnHeight.length; i++){
|
|
let columnHeight = textH_all_ColumnHeight[i];
|
|
let columnWidth = textH_all_ColumWidth[i];
|
|
|
|
let col = textH_all_Column[i];
|
|
let cumWordHeight = 0;
|
|
for(let c=0;c<col.length;c++){
|
|
let word = col[c];
|
|
|
|
let left = space_width + cumColumnWidth;
|
|
if(horizonAlign == "0"){
|
|
left = cellWidth / 2 + cumColumnWidth - textW_all/2 + space_width*textH_all_ColumnHeight.length;
|
|
}
|
|
else if(horizonAlign == "2"){
|
|
left = cellWidth + cumColumnWidth - textW_all + space_width;
|
|
}
|
|
|
|
let top = (cellHeight - space_height) + cumWordHeight - columnHeight;
|
|
if(verticalAlign == "0"){
|
|
top = cellHeight / 2 + cumWordHeight - columnHeight/2;
|
|
}
|
|
else if(verticalAlign == "1"){
|
|
top = space_height + cumWordHeight;
|
|
}
|
|
|
|
cumWordHeight += word.height;
|
|
|
|
word.left = left;
|
|
word.top = top;
|
|
|
|
drawLineInfo(word, cancelLine, underLine,{
|
|
width:columnWidth,
|
|
height:word.height,
|
|
left:left,
|
|
top:top+word.height-space_height,
|
|
asc:word.height,
|
|
desc:0,
|
|
fs:fontSize
|
|
});
|
|
|
|
textContent.values.push(word);
|
|
}
|
|
|
|
cumColumnWidth+=columnWidth;
|
|
|
|
}
|
|
}
|
|
else{
|
|
let supportBoundBox = isSupportBoundingBox(ctx);
|
|
if(supportBoundBox){
|
|
ctx.textBaseline = 'alphabetic';
|
|
}
|
|
else{
|
|
ctx.textBaseline = 'bottom';
|
|
}
|
|
|
|
if(tb=="2" || isInline){//wrap
|
|
|
|
let textW_all = 0; //拆分后宽高度合计
|
|
let textH_all = 0;
|
|
let textW_all_inner = 0;
|
|
|
|
// let oneWordWidth = getMeasureText(vArr[0], ctx).width;
|
|
let splitIndex=0, text_all_cache=0, text_all_split = {}, text_all_splitLen=[];
|
|
|
|
textContent.rotate = rt;
|
|
rt = Math.abs(rt);
|
|
|
|
let anchor = 0, preHeight = 0, preWidth=0, preStr, preTextHeight, preTextWidth, preMeasureText, i=1, wrapStyle={}, spaceOrTwoByte=null, spaceOrTwoByteIndex=null;
|
|
if(isInline){
|
|
while(i <= inlineStringArr.length){
|
|
let shareCells = inlineStringArr.slice(anchor, i);
|
|
if(shareCells[shareCells.length-1].wrap===true){
|
|
|
|
anchor = i;
|
|
|
|
if(shareCells.length>1){
|
|
for(let s=0;s<shareCells.length-1;s++){
|
|
let sc = shareCells[s];
|
|
let item = {
|
|
content:sc.v,
|
|
style:sc,
|
|
width:sc.measureText.width,
|
|
height:sc.measureText.actualBoundingBoxAscent+sc.measureText.actualBoundingBoxDescent,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
asc:sc.measureText.actualBoundingBoxAscent,
|
|
desc:sc.measureText.actualBoundingBoxDescent,
|
|
inline:true,
|
|
fs:sc.fs
|
|
}
|
|
|
|
// if(rt!=0){//rotate
|
|
// item.textHeight = sc.textHeight;
|
|
// item.textWidth = sc.textWidth;
|
|
// }
|
|
|
|
text_all_split[splitIndex].push(item);
|
|
}
|
|
}
|
|
|
|
if(shareCells.length==1 || i==inlineStringArr.length){
|
|
let sc = shareCells[0];
|
|
let measureText = getMeasureText("M", ctx, sc.fontset);
|
|
if(text_all_split[splitIndex]==null){
|
|
text_all_split[splitIndex] = [];
|
|
}
|
|
text_all_split[splitIndex].push({
|
|
content:"",
|
|
style:sc,
|
|
width:measureText.width,
|
|
height:measureText.actualBoundingBoxAscent+measureText.actualBoundingBoxDescent,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
asc:measureText.actualBoundingBoxAscent,
|
|
desc:measureText.actualBoundingBoxDescent,
|
|
inline:true,
|
|
wrap:true,
|
|
fs:sc.fs
|
|
});
|
|
}
|
|
|
|
|
|
|
|
splitIndex +=1;
|
|
|
|
i++;
|
|
|
|
continue;
|
|
}
|
|
|
|
let textWidth=0, textHeight=0;
|
|
for(let s=0;s<shareCells.length;s++){
|
|
let sc = shareCells[s];
|
|
if(sc.measureText==null){
|
|
sc.measureText = getMeasureText(sc.v, ctx, sc.fontset);
|
|
}
|
|
textWidth += sc.measureText.width;
|
|
textHeight = Math.max(sc.measureText.actualBoundingBoxAscent+sc.measureText.actualBoundingBoxDescent);
|
|
// console.log(sc.v,sc.measureText.width,sc.measureText.actualBoundingBoxAscent,sc.measureText.actualBoundingBoxDescent);
|
|
}
|
|
|
|
let width = textWidth * Math.cos(rt*Math.PI/180) + textHeight * Math.sin(rt*Math.PI/180);//consider text box wdith and line height
|
|
|
|
let height = textWidth * Math.sin(rt*Math.PI/180) + textHeight * Math.cos(rt*Math.PI/180);//consider text box wdith and line height
|
|
|
|
// textW_all += textW;
|
|
|
|
|
|
let lastWord = shareCells[shareCells.length-1];
|
|
if(lastWord.v==" " || checkWordByteLength(lastWord.v)==2){
|
|
spaceOrTwoByteIndex = i;
|
|
}
|
|
|
|
|
|
if(rt!=0){//rotate
|
|
// console.log("all",anchor, i , str);
|
|
console.log(height,space_height, cellHeight, shareCells,(height+space_height)>cellHeight);
|
|
if((height+space_height)>cellHeight && text_all_split[splitIndex]!=null && tb=="2" && i!= inlineStringArr.length){
|
|
// console.log("cut",anchor, i , str);
|
|
|
|
if(spaceOrTwoByteIndex!=null && spaceOrTwoByteIndex<i){
|
|
|
|
for(let s=0;s<spaceOrTwoByteIndex-anchor;s++){
|
|
let sc = shareCells[s];
|
|
text_all_split[splitIndex].push({
|
|
content:sc.v,
|
|
style:sc,
|
|
width:sc.measureText.width,
|
|
height:sc.measureText.actualBoundingBoxAscent+sc.measureText.actualBoundingBoxDescent,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
asc:sc.measureText.actualBoundingBoxAscent,
|
|
desc:sc.measureText.actualBoundingBoxDescent,
|
|
inline:true,
|
|
fs:sc.fs
|
|
});
|
|
}
|
|
anchor = spaceOrTwoByteIndex;
|
|
|
|
i = spaceOrTwoByteIndex + 1;
|
|
|
|
splitIndex +=1;
|
|
|
|
spaceOrTwoByteIndex = null;
|
|
|
|
}
|
|
else{
|
|
|
|
anchor = i-1;
|
|
|
|
for(let s=0;s<shareCells.length-1;s++){
|
|
let sc = shareCells[s];
|
|
text_all_split[splitIndex].push({
|
|
content:sc.v,
|
|
style:sc,
|
|
width:sc.measureText.width,
|
|
height:sc.measureText.actualBoundingBoxAscent+sc.measureText.actualBoundingBoxDescent,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
asc:sc.measureText.actualBoundingBoxAscent,
|
|
desc:sc.measureText.actualBoundingBoxDescent,
|
|
inline:true,
|
|
fs:sc.fs
|
|
});
|
|
}
|
|
|
|
splitIndex +=1;
|
|
}
|
|
|
|
}
|
|
else if(i== inlineStringArr.length){
|
|
// console.log("last",anchor, i , str);
|
|
if(text_all_split[splitIndex]==null){
|
|
text_all_split[splitIndex]= [];
|
|
}
|
|
for(let s=0;s<shareCells.length;s++){
|
|
let sc = shareCells[s];
|
|
text_all_split[splitIndex].push({
|
|
content:sc.v,
|
|
style:sc,
|
|
width:sc.measureText.width,
|
|
height:sc.measureText.actualBoundingBoxAscent+sc.measureText.actualBoundingBoxDescent,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
asc:sc.measureText.actualBoundingBoxAscent,
|
|
desc:sc.measureText.actualBoundingBoxDescent,
|
|
inline:true,
|
|
fs:sc.fs
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
else{
|
|
if(text_all_split[splitIndex]==null){
|
|
text_all_split[splitIndex]= [];
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
else{//plain
|
|
if((width+space_width)>cellWidth && text_all_split[splitIndex]!=null && tb=="2" && i!= inlineStringArr.length){
|
|
|
|
|
|
if(spaceOrTwoByteIndex!=null && spaceOrTwoByteIndex<i){
|
|
|
|
for(let s=0;s<spaceOrTwoByteIndex-anchor;s++){
|
|
let sc = shareCells[s];
|
|
text_all_split[splitIndex].push({
|
|
content:sc.v,
|
|
style:sc,
|
|
width:sc.measureText.width,
|
|
height:sc.measureText.actualBoundingBoxAscent+sc.measureText.actualBoundingBoxDescent,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
asc:sc.measureText.actualBoundingBoxAscent,
|
|
desc:sc.measureText.actualBoundingBoxDescent,
|
|
inline:true,
|
|
fs:sc.fs
|
|
});
|
|
}
|
|
anchor = spaceOrTwoByteIndex;
|
|
|
|
i = spaceOrTwoByteIndex + 1;
|
|
|
|
splitIndex +=1;
|
|
|
|
spaceOrTwoByteIndex = null;
|
|
|
|
}
|
|
else{
|
|
anchor = i-1;
|
|
|
|
for(let s=0;s<shareCells.length-1;s++){
|
|
let sc = shareCells[s];
|
|
text_all_split[splitIndex].push({
|
|
content:sc.v,
|
|
style:sc,
|
|
width:sc.measureText.width,
|
|
height:sc.measureText.actualBoundingBoxAscent+sc.measureText.actualBoundingBoxDescent,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
asc:sc.measureText.actualBoundingBoxAscent,
|
|
desc:sc.measureText.actualBoundingBoxDescent,
|
|
inline:true,
|
|
fs:sc.fs
|
|
});
|
|
}
|
|
|
|
splitIndex +=1;
|
|
}
|
|
|
|
}
|
|
else if(i== inlineStringArr.length){
|
|
if(text_all_split[splitIndex]==null){
|
|
text_all_split[splitIndex]= [];
|
|
}
|
|
|
|
for(let s=0;s<shareCells.length;s++){
|
|
let sc = shareCells[s];
|
|
text_all_split[splitIndex].push({
|
|
content:sc.v,
|
|
style:sc,
|
|
width:sc.measureText.width,
|
|
height:sc.measureText.actualBoundingBoxAscent+sc.measureText.actualBoundingBoxDescent,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
asc:sc.measureText.actualBoundingBoxAscent,
|
|
desc:sc.measureText.actualBoundingBoxDescent,
|
|
inline:true,
|
|
fs:sc.fs
|
|
});
|
|
}
|
|
|
|
break;
|
|
}
|
|
else{
|
|
if(text_all_split[splitIndex]==null){
|
|
text_all_split[splitIndex]= [];
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
else{
|
|
value = value.toString();
|
|
while(i <= value.length){
|
|
let str = value.substring(anchor, i);
|
|
let measureText = getMeasureText(str, ctx);
|
|
let textWidth = measureText.width;
|
|
let textHeight = measureText.actualBoundingBoxAscent+measureText.actualBoundingBoxDescent;
|
|
|
|
let width = textWidth * Math.cos(rt*Math.PI/180) + textHeight * Math.sin(rt*Math.PI/180);//consider text box wdith and line height
|
|
|
|
let height = textWidth * Math.sin(rt*Math.PI/180) + textHeight * Math.cos(rt*Math.PI/180);//consider text box wdith and line height
|
|
let lastWord = str.substr(str.length-1,1);
|
|
if(lastWord==" " || checkWordByteLength(lastWord)==2){
|
|
if(preMeasureText!=null){
|
|
spaceOrTwoByte = {
|
|
index:i,
|
|
str:preStr,
|
|
width:preTextWidth,
|
|
height:preTextHeight,
|
|
asc:preMeasureText.actualBoundingBoxAscent,
|
|
desc:preMeasureText.actualBoundingBoxDescent,
|
|
};
|
|
}
|
|
|
|
}
|
|
// textW_all += textW;
|
|
// console.log(str,anchor,i);
|
|
if(rt!=0){//rotate
|
|
// console.log("all",anchor, i , str);
|
|
if((height+space_height)>cellHeight && text_all_split[splitIndex]!=null && i!= value.length){
|
|
// console.log("cut",anchor, i , str);
|
|
|
|
if(spaceOrTwoByte!=null && spaceOrTwoByte.index<i){
|
|
|
|
anchor = spaceOrTwoByte.index;
|
|
|
|
i = spaceOrTwoByte.index + 1;
|
|
|
|
text_all_split[splitIndex].push({
|
|
content:spaceOrTwoByte.str,
|
|
style:fontset,
|
|
width:spaceOrTwoByte.width,
|
|
height:spaceOrTwoByte.height,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
asc:spaceOrTwoByte.asc,
|
|
desc:spaceOrTwoByte.desc,
|
|
fs:fontSize,
|
|
});
|
|
|
|
// console.log(1,anchor,i,splitIndex , spaceOrTwoByte.str);
|
|
|
|
splitIndex +=1;
|
|
|
|
spaceOrTwoByte = null;
|
|
|
|
|
|
|
|
}
|
|
else{
|
|
anchor = i-1;
|
|
|
|
text_all_split[splitIndex].push({
|
|
content:preStr,
|
|
style:fontset,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
height:preTextHeight,
|
|
width:preTextWidth,
|
|
asc:measureText.actualBoundingBoxAscent,
|
|
desc:measureText.actualBoundingBoxDescent,
|
|
fs:fontSize,
|
|
});
|
|
|
|
// console.log(2,anchor,i, splitIndex, preStr);
|
|
|
|
splitIndex +=1;
|
|
|
|
|
|
}
|
|
}
|
|
else if(i== value.length){
|
|
// console.log("last",anchor, i , str);
|
|
if(text_all_split[splitIndex]==null){
|
|
text_all_split[splitIndex]= [];
|
|
}
|
|
text_all_split[splitIndex].push({
|
|
content:str,
|
|
style:fontset,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
height:textHeight,
|
|
width:textWidth,
|
|
asc:measureText.actualBoundingBoxAscent,
|
|
desc:measureText.actualBoundingBoxDescent,
|
|
fs:fontSize,
|
|
});
|
|
break;
|
|
}
|
|
else{
|
|
if(text_all_split[splitIndex]==null){
|
|
text_all_split[splitIndex]= [];
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
else{//plain
|
|
if((width+space_width)>cellWidth && text_all_split[splitIndex]!=null && i!= value.length){
|
|
// console.log(spaceOrTwoByte, i, anchor);
|
|
if(spaceOrTwoByte!=null && spaceOrTwoByte.index<i){
|
|
|
|
anchor = spaceOrTwoByte.index;
|
|
|
|
i = spaceOrTwoByte.index + 1;
|
|
|
|
text_all_split[splitIndex].push({
|
|
content:spaceOrTwoByte.str,
|
|
style:fontset,
|
|
width:spaceOrTwoByte.width,
|
|
height:spaceOrTwoByte.height,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
asc:spaceOrTwoByte.asc,
|
|
desc:spaceOrTwoByte.desc,
|
|
fs:fontSize,
|
|
});
|
|
|
|
splitIndex +=1;
|
|
|
|
spaceOrTwoByte = null;
|
|
|
|
|
|
|
|
}
|
|
else{
|
|
|
|
spaceOrTwoByte = null;
|
|
anchor = i-1;
|
|
|
|
text_all_split[splitIndex].push({
|
|
content:preStr,
|
|
style:fontset,
|
|
width:preTextWidth,
|
|
height:preTextHeight,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
asc:measureText.actualBoundingBoxAscent,
|
|
desc:measureText.actualBoundingBoxDescent,
|
|
fs:fontSize,
|
|
});
|
|
|
|
// console.log(2);
|
|
|
|
|
|
|
|
splitIndex +=1;
|
|
}
|
|
}
|
|
else if(i== value.length){
|
|
if(text_all_split[splitIndex]==null){
|
|
text_all_split[splitIndex]= [];
|
|
}
|
|
text_all_split[splitIndex].push({
|
|
content:str,
|
|
style:fontset,
|
|
width:textWidth,
|
|
height:textHeight,
|
|
left:0,
|
|
top:0,
|
|
splitIndex:splitIndex,
|
|
asc:measureText.actualBoundingBoxAscent,
|
|
desc:measureText.actualBoundingBoxDescent,
|
|
fs:fontSize,
|
|
});
|
|
|
|
break;
|
|
}
|
|
else{
|
|
if(text_all_split[splitIndex]==null){
|
|
text_all_split[splitIndex]= [];
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
preStr = str;
|
|
preTextHeight = textHeight;
|
|
preTextWidth = textWidth;
|
|
preMeasureText = measureText;
|
|
|
|
}
|
|
|
|
// console.log(text_all_split)
|
|
}
|
|
|
|
let split_all_size = [], oneLinemaxWordCount=0;
|
|
// console.log("split",splitIndex, text_all_split);
|
|
let splitLen = Object.keys(text_all_split).length;
|
|
for(let i = 0; i < splitLen; i++){
|
|
let splitLists = text_all_split[i];
|
|
if(splitLists==null){
|
|
continue;
|
|
}
|
|
let sWidth = 0, sHeight=0, maxDesc=0,maxAsc=0, lineHeight=0, maxWordCount=0;
|
|
for(let s=0;s<splitLists.length;s++){
|
|
let sp = splitLists[s];
|
|
if(rt!=0){//rotate
|
|
sWidth += sp.width;
|
|
sHeight = Math.max(sHeight, sp.height-(supportBoundBox?sp.desc:0));
|
|
}
|
|
else{//plain
|
|
sWidth += sp.width;
|
|
sHeight = Math.max(sHeight, sp.height-(supportBoundBox?sp.desc:0));
|
|
}
|
|
maxDesc = Math.max(maxDesc,(supportBoundBox?sp.desc:0));
|
|
maxAsc = Math.max(maxAsc, sp.asc);
|
|
maxWordCount++;
|
|
}
|
|
|
|
lineHeight = sHeight/2;
|
|
oneLinemaxWordCount = Math.max(oneLinemaxWordCount, maxWordCount);
|
|
if(rt!=0){//rotate
|
|
sHeight+=lineHeight;
|
|
textW_all_inner = Math.max(textW_all_inner, sWidth);
|
|
// textW_all = Math.max(textW_all, sWidth+ (textH_all)/Math.tan(rt*Math.PI/180));
|
|
textH_all += sHeight;
|
|
}
|
|
else{//plain
|
|
// console.log("textH_all",textW_all, textH_all);
|
|
sHeight+=lineHeight;
|
|
textW_all=Math.max(textW_all, sWidth);
|
|
textH_all+=sHeight;
|
|
}
|
|
|
|
|
|
split_all_size.push({
|
|
width:sWidth,
|
|
height:sHeight,
|
|
desc:maxDesc,
|
|
asc:maxAsc,
|
|
lineHeight:lineHeight,
|
|
wordCount: maxWordCount
|
|
});
|
|
}
|
|
// console.log(textH_all,textW_all,textW_all_inner);
|
|
// let cumColumnWidth = 0;
|
|
let cumWordHeight = 0,cumColumnWidth = 0;
|
|
let rtPI = rt*Math.PI/180;
|
|
let lastLine = split_all_size[splitLen-1];
|
|
let lastLineSpaceHeight = lastLine.lineHeight;
|
|
textH_all = textH_all - lastLineSpaceHeight + lastLine.desc;
|
|
let rw = (textH_all)/Math.sin(rtPI) + textW_all_inner*Math.cos(rtPI);
|
|
let rh = textW_all_inner*Math.sin(rtPI), fixOneLineLeft = 0;
|
|
|
|
if(rt!=0){
|
|
if(splitLen==1){
|
|
textW_all = textW_all_inner + 2*(textH_all/Math.tan(rtPI));
|
|
fixOneLineLeft = textH_all/Math.tan(rtPI);
|
|
}
|
|
else{
|
|
textW_all = textW_all_inner + textH_all/Math.tan(rtPI);
|
|
}
|
|
textContent.textWidthAll = rw;
|
|
textContent.textHeightAll = rh;
|
|
}
|
|
else{
|
|
textContent.textWidthAll = textW_all;
|
|
textContent.textHeightAll = textH_all;
|
|
}
|
|
|
|
if(isMode=="onlyWidth"){
|
|
// console.log("plainWrap", textContent,cell, option);
|
|
return textContent;
|
|
}
|
|
|
|
if(rt!=0 && isRotateUp=="1"){
|
|
ctx.textAlign="end";
|
|
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=splitLists.length-1;c>=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<splitLists.length;c++){
|
|
let wordGroup = splitLists[c];
|
|
let left, top;
|
|
if(rt!=0){//rotate
|
|
let x, y = cumWordHeight+size.asc;
|
|
|
|
x = (textH_all-cumWordHeight)/Math.tan(rtPI) + cumColumnWidth;
|
|
|
|
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 - lastLineSpaceHeight*Math.cos(rtPI)/2;
|
|
top = y - (textH_all/2 - rh/2)+lastLineSpaceHeight*Math.cos(rtPI)/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 - textH_all + cellHeight/2 - rh*Math.cos(rtPI)/2 - lastLineSpaceHeight*Math.cos(rtPI)/2;
|
|
}
|
|
else if(verticalAlign == "1"){//top
|
|
left = x;
|
|
top = y - textH_all;
|
|
}
|
|
else if(verticalAlign == "2"){//bottom
|
|
left = x - rh*Math.sin(rtPI) - lastLineSpaceHeight*Math.cos(rtPI);
|
|
top = y - textH_all + cellHeight - rh*Math.cos(rtPI) - lastLineSpaceHeight*Math.cos(rtPI);
|
|
}
|
|
}
|
|
else if(horizonAlign == "2"){//right
|
|
if(verticalAlign == "0"){//mid
|
|
left = x + cellWidth - rw/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 fixOneLineLeft
|
|
left = x + cellWidth - rw*Math.cos(rtPI);
|
|
top = y + rh*Math.cos(rtPI);
|
|
}
|
|
else if(verticalAlign == "2"){//bottom
|
|
left = x + cellWidth - textW_all - lastLineSpaceHeight*Math.cos(rtPI) + fixOneLineLeft;
|
|
top = y + cellHeight - lastLineSpaceHeight*Math.cos(rtPI);
|
|
}
|
|
}
|
|
|
|
drawLineInfo(wordGroup, cancelLine, underLine,{
|
|
width:wordGroup.width,
|
|
height:wordGroup.height,
|
|
left:left,
|
|
top:top,
|
|
asc:size.asc,
|
|
desc:size.desc,
|
|
fs:wordGroup.fs
|
|
});
|
|
|
|
}
|
|
else{//plain
|
|
left = space_width + cumColumnWidth;
|
|
if(horizonAlign == "0"){
|
|
//+ space_width*textH_all_ColumnHeight.length
|
|
left = cellWidth / 2 + cumColumnWidth - size.width/2;
|
|
}
|
|
else if(horizonAlign == "2"){
|
|
left = cellWidth + cumColumnWidth - size.width;
|
|
}
|
|
|
|
top = (cellHeight - space_height) + cumWordHeight +size.asc-textH_all;
|
|
if(verticalAlign == "0"){
|
|
top = cellHeight / 2 + cumWordHeight - textH_all/2 + size.asc;
|
|
}
|
|
else if(verticalAlign == "1"){
|
|
top = space_height + cumWordHeight+ size.asc;
|
|
}
|
|
|
|
|
|
|
|
drawLineInfo(wordGroup, cancelLine, underLine,{
|
|
width:wordGroup.width,
|
|
height:wordGroup.height,
|
|
left:left,
|
|
top:top,
|
|
asc:size.asc,
|
|
desc:size.desc,
|
|
fs:wordGroup.fs
|
|
});
|
|
}
|
|
|
|
|
|
wordGroup.left = left;
|
|
wordGroup.top = top;
|
|
|
|
textContent.values.push(wordGroup);
|
|
|
|
cumColumnWidth += wordGroup.width;
|
|
}
|
|
|
|
|
|
cumWordHeight += size.height;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
textContent.type = "plainWrap";
|
|
|
|
if(rt!=0){
|
|
// let leftCenter = (textW_all + textH_all/Math.tan(rt*Math.PI/180))/2;
|
|
// let topCenter = textH_all/2;
|
|
|
|
// if(isRotateUp=="1"){
|
|
// textContent.textLeftAll += leftCenter;
|
|
// textContent.textTopAll += topCenter;
|
|
// }
|
|
// else {
|
|
// textContent.textLeftAll += leftCenter;
|
|
// textContent.textTopAll -= topCenter;
|
|
// }
|
|
|
|
if(horizonAlign == "0"){//center
|
|
if(verticalAlign == "0"){//mid
|
|
textContent.textLeftAll = cellWidth/2;
|
|
textContent.textTopAll = cellHeight/2;
|
|
}
|
|
else if(verticalAlign == "1"){//top
|
|
textContent.textLeftAll = cellWidth/2;
|
|
textContent.textTopAll = rh/2;
|
|
|
|
}
|
|
else if(verticalAlign == "2"){//bottom
|
|
textContent.textLeftAll = cellWidth/2;
|
|
textContent.textTopAll = cellHeight - rh/2;
|
|
}
|
|
}
|
|
else if(horizonAlign == "1"){//left
|
|
if(verticalAlign == "0"){//mid
|
|
textContent.textLeftAll = 0;
|
|
textContent.textTopAll = cellHeight/2;
|
|
}
|
|
else if(verticalAlign == "1"){//top
|
|
textContent.textLeftAll = 0;
|
|
textContent.textTopAll = 0;
|
|
}
|
|
else if(verticalAlign == "2"){//bottom
|
|
textContent.textLeftAll = 0;
|
|
textContent.textTopAll = cellHeight;
|
|
}
|
|
}
|
|
else if(horizonAlign == "2"){//right
|
|
if(verticalAlign == "0"){//mid
|
|
textContent.textLeftAll = cellWidth - rw/2;
|
|
textContent.textTopAll = cellHeight/2;
|
|
}
|
|
else if(verticalAlign == "1"){//top
|
|
textContent.textLeftAll = cellWidth;
|
|
textContent.textTopAll = 0;
|
|
}
|
|
else if(verticalAlign == "2"){//bottom
|
|
textContent.textLeftAll = cellWidth;
|
|
textContent.textTopAll = cellHeight;
|
|
}
|
|
}
|
|
|
|
}
|
|
// else{
|
|
// textContent.textWidthAll = textW_all;
|
|
// textContent.textHeightAll = textH_all;
|
|
// }
|
|
|
|
}
|
|
else{
|
|
let measureText = getMeasureText(value, ctx);
|
|
let textWidth = measureText.width;
|
|
let textHeight = measureText.actualBoundingBoxDescent + measureText.actualBoundingBoxAscent;
|
|
|
|
textContent.rotate = rt;
|
|
|
|
rt = Math.abs(rt);
|
|
let rtPI = rt*Math.PI/180;
|
|
|
|
let textWidthAll = textWidth * Math.cos(rtPI) + textHeight * Math.sin(rtPI);//consider text box wdith and line height
|
|
|
|
let textHeightAll = textWidth * Math.sin(rtPI) + textHeight * Math.cos(rtPI);//consider text box wdith and line height
|
|
|
|
if(rt!=0){
|
|
textContent.textHeightAll = textHeightAll;
|
|
}
|
|
else{
|
|
textContent.textHeightAll = textHeightAll+textHeight/2-measureText.actualBoundingBoxDescent-space_height;
|
|
}
|
|
textContent.textWidthAll = textWidthAll;
|
|
|
|
// console.log(textContent.textWidthAll , textContent.textHeightAll);
|
|
if(isMode=="onlyWidth"){
|
|
// console.log("plain", textContent,cell, option);
|
|
return textContent;
|
|
}
|
|
|
|
let width = textWidthAll, height = textHeightAll;
|
|
|
|
let left = space_width + textHeight * Math.sin(rtPI)*isRotateUp; //默认为1,左对齐
|
|
if(horizonAlign == "0"){ //居中对齐
|
|
left = cellWidth / 2 - (width / 2) + textHeight * Math.sin(rtPI)*isRotateUp;
|
|
}
|
|
else if(horizonAlign == "2"){ //右对齐
|
|
left = (cellWidth - space_width) - width + textHeight * Math.sin(rtPI)*isRotateUp;
|
|
}
|
|
|
|
let top = (cellHeight - space_height) - height + measureText.actualBoundingBoxAscent * Math.cos(rtPI) + textWidth * Math.sin(rtPI)*isRotateUp; //默认为2,下对齐
|
|
if(verticalAlign == "0"){ //居中对齐
|
|
top = cellHeight / 2 - (height / 2) + measureText.actualBoundingBoxAscent* Math.cos(rtPI) + textWidth * Math.sin(rtPI)*isRotateUp;
|
|
}
|
|
else if(verticalAlign == "1"){ //上对齐
|
|
top = space_height + measureText.actualBoundingBoxAscent* Math.cos(rtPI) + textWidth * Math.sin(rtPI)*isRotateUp;
|
|
}
|
|
|
|
textContent.type = "plain";
|
|
|
|
let wordGroup = {
|
|
content:value,
|
|
style:fontset,
|
|
width:width,
|
|
height:height,
|
|
left:left,
|
|
top:top,
|
|
}
|
|
|
|
drawLineInfo(wordGroup, cancelLine, underLine,{
|
|
width:textWidth,
|
|
height:textHeight,
|
|
left:left,
|
|
top:top,
|
|
asc:measureText.actualBoundingBoxAscent,
|
|
desc:measureText.actualBoundingBoxDescent,
|
|
fs:fontSize,
|
|
});
|
|
|
|
textContent.values.push(wordGroup);
|
|
|
|
textContent.textLeftAll = left;
|
|
textContent.textTopAll = top;
|
|
|
|
textContent.asc = measureText.actualBoundingBoxAscent;
|
|
textContent.desc = measureText.actualBoundingBoxDescent;
|
|
|
|
// console.log("plain",left,top);
|
|
}
|
|
}
|
|
|
|
return textContent;
|
|
}
|
|
|
|
|
|
function drawLineInfo(wordGroup, cancelLine,underLine,option){
|
|
let left = option.left, top = option.top, width=option.width, height = option.height, asc = option.asc,desc = option.desc,fs = option.fs;
|
|
|
|
if(wordGroup.wrap===true){
|
|
return;
|
|
}
|
|
|
|
if(wordGroup.inline==true && wordGroup.style!=null){
|
|
cancelLine = wordGroup.style.cl;
|
|
underLine = wordGroup.style.un;
|
|
}
|
|
|
|
if(cancelLine!="0"){
|
|
wordGroup.cancelLine = {};
|
|
wordGroup.cancelLine.startX = left;
|
|
wordGroup.cancelLine.startY = top-asc/2+1;
|
|
|
|
wordGroup.cancelLine.endX = left + width;
|
|
wordGroup.cancelLine.endY = top-asc/2+1;
|
|
|
|
wordGroup.cancelLine.fs = fs;
|
|
|
|
}
|
|
|
|
if(underLine!="0"){
|
|
wordGroup.underLine = [];
|
|
if(underLine=="1" || underLine=="2"){
|
|
let item = {};
|
|
item.startX = left;
|
|
item.startY = top;
|
|
|
|
item.endX = left + width;
|
|
item.endY = top;
|
|
|
|
item.fs = fs;
|
|
|
|
wordGroup.underLine.push(item);
|
|
}
|
|
|
|
if(underLine=="2"){
|
|
let item = {};
|
|
item.startX = left;
|
|
item.startY = top+desc;
|
|
|
|
item.endX = left + width;
|
|
item.endY = top+desc;
|
|
|
|
item.fs = fs;
|
|
|
|
wordGroup.underLine.push(item);
|
|
}
|
|
|
|
if(underLine=="3" || underLine=="4"){
|
|
let item = {};
|
|
item.startX = left;
|
|
item.startY = top+desc;
|
|
|
|
item.endX = left + width;
|
|
item.endY = top+desc;
|
|
|
|
item.fs = fs;
|
|
|
|
wordGroup.underLine.push(item);
|
|
}
|
|
|
|
if(underLine=="4"){
|
|
let item = {};
|
|
item.startX = left;
|
|
item.startY = top+desc+2;
|
|
|
|
item.endX = left + width;
|
|
item.endY = top+desc+2;
|
|
|
|
item.fs = fs;
|
|
|
|
wordGroup.underLine.push(item);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export {
|
|
rowlenByRange,
|
|
computeRowlenArr,
|
|
getCellTextSplitArr,
|
|
getMeasureText,
|
|
getCellTextInfo
|
|
}
|