Browse Source

fix(old chrome dont surport actualboundingboxascent): fix it and make it beautiful

master
liuyang 5 years ago
parent
commit
5c503d8519
  1. 6
      src/controllers/menuButton.js
  2. 60
      src/global/draw.js
  3. 42
      src/global/getRowlen.js
  4. 3
      src/store/index.js

6
src/controllers/menuButton.js

@ -3839,12 +3839,12 @@ const menuButton = {
} }
if($("#luckysheetTextSizeTest").length == 0){ if($("#luckysheetTextSizeTest").length == 0){
$('<span id="luckysheetTextSizeTest" style="float:left;white-space:nowrap;visibility:hidden">' + text + '</span>').appendTo($('body')); $('<span id="luckysheetTextSizeTest" style="float:left;white-space:nowrap;visibility:hidden;margin:0;padding:0;">' + text + '</span>').appendTo($('body'));
} }
let o = $("#luckysheetTextSizeTest").text(text).css({'font': f}), let o = $("#luckysheetTextSizeTest").text(text).css({'font': f}),
w = o.width(), w = o.innerWidth(),
h = o.height(); h = o.innerHeight();
_this.getTextHeightCache[f] = [w, h]; _this.getTextHeightCache[f] = [w, h];

60
src/global/draw.js

@ -8,7 +8,7 @@ import { luckysheet_searcharray } from '../controllers/sheetSearch';
import { dynamicArrayCompute } from './dynamicArray'; import { dynamicArrayCompute } from './dynamicArray';
import browser from './browser'; import browser from './browser';
import { isRealNull } from './validate'; import { isRealNull } from './validate';
import { getCellTextSplitArr } from './getRowlen'; import { getCellTextSplitArr,getMeasureText } from './getRowlen';
import { getcellvalue } from './getdata'; import { getcellvalue } from './getdata';
import { getBorderInfoCompute } from './border'; import { getBorderInfoCompute } from './border';
import { getSheetIndex } from '../methods/get'; import { getSheetIndex } from '../methods/get';
@ -237,7 +237,7 @@ function luckysheetDrawMain(scrollWidth, scrollHeight, drawWidth, drawHeight, of
// console.trace(); // console.trace();
clearTimeout(measureTextCacheTimeOut); clearTimeout(Store.measureTextCacheTimeOut);
//参数未定义处理 //参数未定义处理
if (scrollWidth == null) { if (scrollWidth == null) {
@ -371,7 +371,7 @@ function luckysheetDrawMain(scrollWidth, scrollHeight, drawWidth, drawHeight, of
(fill_row_ed - scrollHeight) * Store.devicePixelRatio (fill_row_ed - scrollHeight) * Store.devicePixelRatio
); );
luckysheetTableContent.font = luckysheetdefaultFont(); luckysheetTableContent.font = luckysheetdefaultFont();
luckysheetTableContent.textBaseline = "top"; // luckysheetTableContent.textBaseline = "top";
luckysheetTableContent.fillStyle = luckysheetdefaultstyle.fillStyle; luckysheetTableContent.fillStyle = luckysheetdefaultstyle.fillStyle;
//表格渲染区域 非空单元格行列 起止坐标 //表格渲染区域 非空单元格行列 起止坐标
@ -860,8 +860,8 @@ function luckysheetDrawMain(scrollWidth, scrollHeight, drawWidth, drawHeight, of
); );
} }
measureTextCacheTimeOut = setTimeout(() => { Store.measureTextCacheTimeOut = setTimeout(() => {
measureTextCache = {}; Store.measureTextCache = {};
}, 2000); }, 2000);
} }
@ -1044,7 +1044,7 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee
let fontset = luckysheetfontformat(cell); let fontset = luckysheetfontformat(cell);
luckysheetTableContent.font = fontset; luckysheetTableContent.font = fontset;
luckysheetTableContent.textBaseline = 'top'; // luckysheetTableContent.textBaseline = 'top';
//水平对齐 //水平对齐
let horizonAlign = menuButton.checkstatus(Store.flowdata, r, c, "ht"); let horizonAlign = menuButton.checkstatus(Store.flowdata, r, c, "ht");
@ -1055,7 +1055,7 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee
let measureText = getMeasureText(value, luckysheetTableContent); let measureText = getMeasureText(value, luckysheetTableContent);
//luckysheetTableContent.measureText(value); //luckysheetTableContent.measureText(value);
let textMetrics = measureText.width; let textMetrics = measureText.width;
let oneLineTextHeight = measureText.actualBoundingBoxDescent - measureText.actualBoundingBoxAscent; let oneLineTextHeight = measureText.actualBoundingBoxDescent + measureText.actualBoundingBoxAscent;
//交替颜色 //交替颜色
let checksAF = alternateformat.checksAF(r, c, af_compute); let checksAF = alternateformat.checksAF(r, c, af_compute);
//条件格式 //条件格式
@ -1371,11 +1371,11 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee
if(cell.tb == '2'){ if(cell.tb == '2'){
//自动换行 //自动换行
luckysheetTableContent.textBaseline = 'top'; //textBaseline以top计算 // luckysheetTableContent.textBaseline = 'top'; //textBaseline以top计算
let strArr = [];//文本截断数组 let strArr = [];//文本截断数组
strArr = getCellTextSplitArr(value.toString(), strArr, cellWidth - space_width * 2, luckysheetTableContent); strArr = getCellTextSplitArr(value.toString(), strArr, cellWidth - space_width * 2, luckysheetTableContent);
let word_space_height = oneLineTextHeight/3;
for(let i = 0; i < strArr.length; i++){ for(let i = 0; i < strArr.length; i++){
let strV = strArr[i]; let strV = strArr[i];
@ -1395,28 +1395,31 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee
} }
//垂直对齐计算 //垂直对齐计算
let clLine = 0;
if(verticalAlign == "0"){ if(verticalAlign == "0"){
verticalAlignPos = (pos_y + cellHeight / 2) * Store.devicePixelRatio - (strHeight / 2) * strArr.length; verticalAlignPos = (pos_y + cellHeight / 2) * Store.devicePixelRatio - (strHeight+word_space_height) * (strArr.length-1)/2;
} }
else if(verticalAlign == "1"){ else if(verticalAlign == "1"){
verticalAlignPos = (pos_y + space_height) * Store.devicePixelRatio; verticalAlignPos = (pos_y + space_height) * Store.devicePixelRatio;
clLine = strHeight / 2;
} }
else{ else{
verticalAlignPos = (pos_y + cellHeight - space_height) * Store.devicePixelRatio - strHeight * strArr.length; verticalAlignPos = (pos_y + cellHeight - space_height) * Store.devicePixelRatio - (strHeight+word_space_height) * (strArr.length-1);
clLine = -strHeight / 2;
} }
luckysheetTableContent.fillText(strV, horizonAlignPos, (verticalAlignPos + i * strHeight)); luckysheetTableContent.fillText(strV, horizonAlignPos, (verticalAlignPos + i * (strHeight+word_space_height)));
if(cl == "1" && !isRealNull(strV)){ if(cl == "1" && !isRealNull(strV)){
luckysheetTableContent.beginPath(); luckysheetTableContent.beginPath();
luckysheetTableContent.strokeStyle = "#000"; luckysheetTableContent.strokeStyle = "#000";
luckysheetTableContent.moveTo(
horizonAlignPos, luckysheetTableContent.moveTo(horizonAlignPos,
(verticalAlignPos + i * strHeight) + strHeight / 2 (verticalAlignPos + i * (strHeight+word_space_height)) +clLine
); );
luckysheetTableContent.lineTo( luckysheetTableContent.lineTo(
horizonAlignPos + strWidth, horizonAlignPos + strWidth,
(verticalAlignPos + i * strHeight) + strHeight / 2 (verticalAlignPos + i * (strHeight+word_space_height)) +clLine
); );
luckysheetTableContent.stroke(); luckysheetTableContent.stroke();
luckysheetTableContent.closePath(); luckysheetTableContent.closePath();
@ -1425,7 +1428,7 @@ let cellRender = function(r, c, start_r, start_c, end_r, end_c, value, luckyshee
} }
else if(cell.tr != null && cell.tr != '0'){ else if(cell.tr != null && cell.tr != '0'){
//旋转 //旋转
luckysheetTableContent.textBaseline = 'top'; //textBaseline以top计算 // luckysheetTableContent.textBaseline = 'top'; //textBaseline以top计算
//单元格旋转属性 //单元格旋转属性
let tr = cell.tr; let tr = cell.tr;
@ -1744,7 +1747,7 @@ let cellOverflowRender = function(r, c, stc, edc,luckysheetTableContent,scrollHe
let fontset = luckysheetfontformat(cell); let fontset = luckysheetfontformat(cell);
luckysheetTableContent.font = fontset; luckysheetTableContent.font = fontset;
luckysheetTableContent.textBaseline = 'top'; // luckysheetTableContent.textBaseline = 'top';
//溢出单元格 值 //溢出单元格 值
let value = getcellvalue(r, c, null, "m"); let value = getcellvalue(r, c, null, "m");
@ -1756,7 +1759,7 @@ let cellOverflowRender = function(r, c, stc, edc,luckysheetTableContent,scrollHe
let measureText = getMeasureText(value, luckysheetTableContent); let measureText = getMeasureText(value, luckysheetTableContent);
//luckysheetTableContent.measureText(value); //luckysheetTableContent.measureText(value);
let textMetrics = measureText.width; let textMetrics = measureText.width;
let oneLineTextHeight = measureText.actualBoundingBoxDescent - measureText.actualBoundingBoxAscent; let oneLineTextHeight = measureText.actualBoundingBoxDescent + measureText.actualBoundingBoxAscent;
let pos_x = start_c + offsetLeft; let pos_x = start_c + offsetLeft;
let pos_y = start_r + offsetTop + 1; let pos_y = start_r + offsetTop + 1;
@ -2053,25 +2056,6 @@ function cellOverflow_colIn(map, r, c, col_st, col_ed){
} }
} }
//获取有值单元格文本大小
let measureTextCache = {}, measureTextCacheTimeOut = null;
function getMeasureText(value, ctx){
let mtc = measureTextCache[value + "_" + ctx.font];
if(mtc != null){
return mtc;
}
else{
let measureText = ctx.measureText(value), cache = {};
cache.width = measureText.width;
cache.actualBoundingBoxDescent = measureText.actualBoundingBoxDescent;
cache.actualBoundingBoxAscent = measureText.actualBoundingBoxAscent;
measureTextCache[value + "_" + ctx.font] = cache;
return cache;
}
}
export { export {
luckysheetDrawgrid, luckysheetDrawgrid,
luckysheetDrawgridRowTitle, luckysheetDrawgridRowTitle,

42
src/global/getRowlen.js

@ -2,6 +2,7 @@ import { luckysheetfontformat } from '../utils/util';
import menuButton from '../controllers/menuButton'; import menuButton from '../controllers/menuButton';
import { getcellvalue } from './getdata'; import { getcellvalue } from './getdata';
import { colLocationByIndex } from './location'; import { colLocationByIndex } from './location';
import { hasChinaword } from './validate';
import Store from '../store'; import Store from '../store';
//计算范围行高 //计算范围行高
@ -38,13 +39,13 @@ function rowlenByRange(d, r1, r2, cfg) {
canvas.font = fontset; canvas.font = fontset;
let value = getcellvalue(r, c, d).toString(); //单元格文本 let value = getcellvalue(r, c, d).toString(); //单元格文本
let measureText = canvas.measureText(value); let measureText = getMeasureText(value, canvas);
let textMetrics = measureText.width; //文本宽度 let textMetrics = measureText.width; //文本宽度
let oneLineTextHeight = measureText.actualBoundingBoxDescent - measureText.actualBoundingBoxAscent; let oneLineTextHeight = measureText.actualBoundingBoxDescent + measureText.actualBoundingBoxAscent;
let computeRowlen; //计算行高 let computeRowlen; //计算行高
let word_space_height = oneLineTextHeight/3;
if(cell.tb == "2"){ if(cell.tb == "2"){
//自动换行 //自动换行
let cellWidth = colLocationByIndex(c)[1] - colLocationByIndex(c)[0] - 4; //单元格宽度 let cellWidth = colLocationByIndex(c)[1] - colLocationByIndex(c)[0] - 4; //单元格宽度
@ -53,7 +54,7 @@ function rowlenByRange(d, r1, r2, cfg) {
let strArr = []; //文本截断数组 let strArr = []; //文本截断数组
strArr = getCellTextSplitArr(value, strArr, cellWidth, canvas); strArr = getCellTextSplitArr(value, strArr, cellWidth, canvas);
computeRowlen = oneLineTextHeight * strArr.length + 4; computeRowlen = (oneLineTextHeight+word_space_height) * strArr.length + 4;
} }
else{ else{
computeRowlen = oneLineTextHeight + 4; computeRowlen = oneLineTextHeight + 4;
@ -132,7 +133,7 @@ function computeRowlenArr(rowHeight, cfg) {
function getCellTextSplitArr(strValue, strArr, cellWidth, canvas){ function getCellTextSplitArr(strValue, strArr, cellWidth, canvas){
for(let strI = 1; strI <= strValue.length; strI++){ for(let strI = 1; strI <= strValue.length; strI++){
let strV = strValue.substring(0, strI); let strV = strValue.substring(0, strI);
let strtextMetrics = canvas.measureText(strV).width; let strtextMetrics = getMeasureText(strV, canvas).width;
if(strtextMetrics > cellWidth){ if(strtextMetrics > cellWidth){
if(strI - 1 <= 0){ if(strI - 1 <= 0){
@ -151,8 +152,39 @@ function getCellTextSplitArr(strValue, strArr, cellWidth, canvas){
return strArr; return strArr;
} }
//获取有值单元格文本大小
// let measureTextCache = {}, measureTextCacheTimeOut = null;
function getMeasureText(value, ctx){
let mtc = Store.measureTextCache[value + "_" + ctx.font];
if(mtc != null){
return mtc;
}
else{
let measureText = ctx.measureText(value), cache = {};
cache.width = measureText.width;
cache.actualBoundingBoxDescent = NaN;
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;
cache.actualBoundingBoxDescent = oneLineTextHeight/2;
cache.actualBoundingBoxAscent = oneLineTextHeight/2;
//console.log(value, oneLineTextHeight, measureText.actualBoundingBoxDescent+measureText.actualBoundingBoxAscent,ctx.font);
}
Store.measureTextCache[value + "_" + ctx.font] = cache;
return cache;
}
}
export { export {
rowlenByRange, rowlenByRange,
computeRowlenArr, computeRowlenArr,
getCellTextSplitArr, getCellTextSplitArr,
getMeasureText
} }

3
src/store/index.js

@ -113,6 +113,9 @@ const Store = {
chart_selection: {}, chart_selection: {},
currentChart: '', currentChart: '',
scrollRefreshSwitch:true, scrollRefreshSwitch:true,
measureTextCache:{},
measureTextCacheTimeOut:null,
} }
export default Store; export default Store;
Loading…
Cancel
Save