From 4e1839eaf33a789441fdb5fe705dbdd86ed85129 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Fri, 13 May 2022 20:44:32 +0300 Subject: [PATCH 1/3] Add support binary format for fonts sprite --- .../main/lib/component/ComboBoxFonts.js | 131 +++++++++++++++--- 1 file changed, 110 insertions(+), 21 deletions(-) diff --git a/apps/common/main/lib/component/ComboBoxFonts.js b/apps/common/main/lib/component/ComboBoxFonts.js index df6242964..8ef1b989b 100644 --- a/apps/common/main/lib/component/ComboBoxFonts.js +++ b/apps/common/main/lib/component/ComboBoxFonts.js @@ -88,6 +88,111 @@ define([ thumbCanvas.height = thumbs[thumbIdx].height; thumbCanvas.width = thumbs[thumbIdx].width; + function CThumbnailLoader() { + this.supportBinaryFormat = (window['AscDesktopEditor'] && !window['AscDesktopEditor']['isSupportBinaryFontsSprite']) ? false : true; + + this.image = null; + this.data = null; + this.width = 0; + this.height = 0; + this.heightOne = 0; + this.count = 0; + + this.load = function(url, callback) { + if (!callback) + return; + + if (!this.supportBinaryFormat) { + this.width = thumbs[thumbIdx].width; + this.heightOne = thumbs[thumbIdx].height; + + this.image = new Image(); + this.image.onload = callback; + this.image.src = thumbs[thumbIdx].path; + } else { + var me = this; + var xhr = new XMLHttpRequest(); + xhr.open('GET', url + ".bin", true); + xhr.responseType = 'arraybuffer'; + + if (xhr.overrideMimeType) + xhr.overrideMimeType('text/plain; charset=x-user-defined'); + else + xhr.setRequestHeader('Accept-Charset', 'x-user-defined'); + + xhr.onload = function() { + // TODO: check errors + me.openBinary(this.response); + callback(); + }; + + xhr.send(null); + } + }; + + this.openBinary = function(arrayBuffer) { + var binaryAlpha = new Uint8Array(arrayBuffer); + this.width = (binaryAlpha[0] << 24) | (binaryAlpha[1] << 16) | (binaryAlpha[2] << 8) | (binaryAlpha[3] << 0); + this.heightOne = (binaryAlpha[4] << 24) | (binaryAlpha[5] << 16) | (binaryAlpha[6] << 8) | (binaryAlpha[7] << 0); + this.count = (binaryAlpha[8] << 24) | (binaryAlpha[9] << 16) | (binaryAlpha[10] << 8) | (binaryAlpha[11] << 0); + this.height = this.count * this.heightOne; + + this.data = new Uint8ClampedArray(4 * this.width * this.height); + + var binaryIndex = 12; + var binaryLen = binaryAlpha.length; + var imagePixels = this.data; + var alphaIndex = 3; + + var len0 = 0; + while (binaryIndex < binaryLen) { + imagePixels[alphaIndex] = binaryAlpha[binaryIndex]; + binaryIndex++; + alphaIndex += 4; + + if (0 === binaryAlpha[binaryIndex - 1]) { + len0 = binaryAlpha[binaryIndex++] - 1; + + while (len0 > 0) { + len0--; + imagePixels[alphaIndex] = 0; + alphaIndex += 4; + } + } + } + }; + + this.getImage = function(index, canvas, ctx) { + + //var t1 = performance.now(); + if (!canvas) + { + canvas = document.createElement("canvas"); + canvas.width = this.width; + canvas.height = this.heightOne; + canvas.style.width = iconWidth + "px"; + canvas.style.height = iconHeight + "px"; + + ctx = canvas.getContext("2d"); + } + + if (this.supportBinaryFormat) { + var dataTmp = ctx.createImageData(this.width, this.heightOne); + var sizeImage = 4 * this.width * this.heightOne; + dataTmp.data.set(new Uint8ClampedArray(this.data.buffer, index * sizeImage, sizeImage)); + ctx.putImageData(dataTmp, 0, 0); + } else { + ctx.clearRect(0, 0, this.width, this.heightOne); + ctx.drawImage(this.image, 0, -this.heightOne * index); + } + + //var t2 = performance.now(); + //console.log(t2 - t1); + + return canvas; + }; + } + return { template: _.template([ '
', @@ -305,10 +410,8 @@ define([ return img != null ? img[0].src : undefined; } - thumbContext.clearRect(0, 0, thumbs[thumbIdx].width, thumbs[thumbIdx].height); - thumbContext.drawImage(this.spriteThumbs, 0, -thumbs[thumbIdx].height * Math.floor(opts.imgidx/spriteCols)); - - return thumbCanvas.toDataURL(); + var index = Math.floor(opts.imgidx/spriteCols); + return this.spriteThumbs.getImage(index, thumbCanvas, thumbContext).toDataURL(); }, getImageWidth: function() { @@ -324,11 +427,8 @@ define([ }, loadSprite: function(callback) { - if (callback) { - this.spriteThumbs = new Image(); - this.spriteThumbs.onload = callback; - this.spriteThumbs.src = thumbs[thumbIdx].path; - } + this.spriteThumbs = new CThumbnailLoader(); + this.spriteThumbs.load(thumbs[thumbIdx].path, callback); }, fillFonts: function(store, select) { @@ -554,19 +654,8 @@ define([ for (j = 0; j < storeCount; ++j) { if (from <= j && j < to) { if (null === me.tiles[j]) { - var fontImage = document.createElement('canvas'); - var context = fontImage.getContext('2d'); - - fontImage.height = thumbs[thumbIdx].height; - fontImage.width = thumbs[thumbIdx].width; - - fontImage.style.width = iconWidth + 'px'; - fontImage.style.height = iconHeight + 'px'; - index = Math.floor(me.store.at(j).get('imgidx')/spriteCols); - - context.clearRect(0, 0, thumbs[thumbIdx].width, thumbs[thumbIdx].height); - context.drawImage(me.spriteThumbs, 0, -thumbs[thumbIdx].height * index); + var fontImage = me.spriteThumbs.getImage(index); me.tiles[j] = fontImage; $(listItems[j]).get(0).appendChild(fontImage); From 4ec247d6ce5ef5214ab9e59db02d02008ac66281 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Sat, 14 May 2022 16:34:00 +0300 Subject: [PATCH 2/3] Refactoring --- .../main/lib/component/ComboBoxFonts.js | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/apps/common/main/lib/component/ComboBoxFonts.js b/apps/common/main/lib/component/ComboBoxFonts.js index 8ef1b989b..049b4b063 100644 --- a/apps/common/main/lib/component/ComboBoxFonts.js +++ b/apps/common/main/lib/component/ComboBoxFonts.js @@ -131,35 +131,43 @@ define([ }; this.openBinary = function(arrayBuffer) { + + //var t1 = performance.now(); + var binaryAlpha = new Uint8Array(arrayBuffer); - this.width = (binaryAlpha[0] << 24) | (binaryAlpha[1] << 16) | (binaryAlpha[2] << 8) | (binaryAlpha[3] << 0); - this.heightOne = (binaryAlpha[4] << 24) | (binaryAlpha[5] << 16) | (binaryAlpha[6] << 8) | (binaryAlpha[7] << 0); - this.count = (binaryAlpha[8] << 24) | (binaryAlpha[9] << 16) | (binaryAlpha[10] << 8) | (binaryAlpha[11] << 0); - this.height = this.count * this.heightOne; + this.width = (binaryAlpha[0] << 24) | (binaryAlpha[1] << 16) | (binaryAlpha[2] << 8) | (binaryAlpha[3] << 0); + this.heightOne = (binaryAlpha[4] << 24) | (binaryAlpha[5] << 16) | (binaryAlpha[6] << 8) | (binaryAlpha[7] << 0); + this.count = (binaryAlpha[8] << 24) | (binaryAlpha[9] << 16) | (binaryAlpha[10] << 8) | (binaryAlpha[11] << 0); + this.height = this.count * this.heightOne; this.data = new Uint8ClampedArray(4 * this.width * this.height); var binaryIndex = 12; var binaryLen = binaryAlpha.length; var imagePixels = this.data; - var alphaIndex = 3; + var index = 0; var len0 = 0; + var tmpValue = 0; while (binaryIndex < binaryLen) { - imagePixels[alphaIndex] = binaryAlpha[binaryIndex]; - binaryIndex++; - alphaIndex += 4; - - if (0 === binaryAlpha[binaryIndex - 1]) { - len0 = binaryAlpha[binaryIndex++] - 1; - + tmpValue = binaryAlpha[binaryIndex++]; + if (0 == tmpValue) { + len0 = binaryAlpha[binaryIndex++]; while (len0 > 0) { len0--; - imagePixels[alphaIndex] = 0; - alphaIndex += 4; + imagePixels[index] = imagePixels[index + 1] = imagePixels[index + 2] = 255; + imagePixels[index + 3] = 0; // this value is already 0. + index += 4; } + } else { + imagePixels[index] = imagePixels[index + 1] = imagePixels[index + 2] = 255 - tmpValue; + imagePixels[index + 3] = tmpValue; + index += 4; } } + + //var t2 = performance.now(); + //console.log(t2 - t1); }; this.getImage = function(index, canvas, ctx) { From 378c4f3431ab3709282091329f633608010a3979 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Sat, 14 May 2022 17:36:18 +0300 Subject: [PATCH 3/3] Move alphaMask generation to getImage method --- apps/common/main/lib/component/ComboBoxFonts.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/common/main/lib/component/ComboBoxFonts.js b/apps/common/main/lib/component/ComboBoxFonts.js index 049b4b063..46fbea563 100644 --- a/apps/common/main/lib/component/ComboBoxFonts.js +++ b/apps/common/main/lib/component/ComboBoxFonts.js @@ -92,6 +92,7 @@ define([ this.supportBinaryFormat = (window['AscDesktopEditor'] && !window['AscDesktopEditor']['isSupportBinaryFontsSprite']) ? false : true; this.image = null; + this.binaryFormat = null; this.data = null; this.width = 0; this.height = 0; @@ -122,7 +123,7 @@ define([ xhr.onload = function() { // TODO: check errors - me.openBinary(this.response); + me.binaryFormat = this.response; callback(); }; @@ -185,6 +186,11 @@ define([ } if (this.supportBinaryFormat) { + if (!this.data) { + this.openBinary(this.binaryFormat); + delete this.binaryFormat; + } + var dataTmp = ctx.createImageData(this.width, this.heightOne); var sizeImage = 4 * this.width * this.heightOne; dataTmp.data.set(new Uint8ClampedArray(this.data.buffer, index * sizeImage, sizeImage));