kit/Kit.cpp | 134 ++++++++++++++++++-------- loleaflet/src/control/Control.ColumnHeader.js | 6 - 2 files changed, 100 insertions(+), 40 deletions(-)
New commits: commit 053aab99e887b336b88321c71e506119cc6aeb2d Author: Jan Holesovsky <ke...@collabora.com> Date: Fri Dec 15 11:51:46 2017 +0100 Avoid an unnecessary buffer in the watermark code. Change-Id: I29b162fd9d8f43d0a2cb75853f0a3c0dc8ee92df Reviewed-on: https://gerrit.libreoffice.org/46527 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> diff --git a/kit/Kit.cpp b/kit/Kit.cpp index 051963a4..dba54ecb 100644 --- a/kit/Kit.cpp +++ b/kit/Kit.cpp @@ -537,7 +537,7 @@ public: } private: - /// Alpha blend 'pixel_count' pixels from 'from' over the 'to'. + /// Alpha blend pixels from 'from' over the 'to'. void alphaBlend(const unsigned char* from, int from_width, int from_height, int from_offset_x, int from_offset_y, unsigned char* to, int to_width, int to_height) { @@ -568,6 +568,7 @@ private: } } + /// Create bitmap that we later use as the watermark for every tile. const unsigned char* getPixmap(int width, int height) { if (_pixmap && width == _width && height == _height) @@ -597,38 +598,24 @@ private: } const unsigned int pixel_count = width * height * 4; - - // Create the blurred background; first a white text _pixmap = static_cast<unsigned char*>(malloc(pixel_count)); - unsigned char* from = text; - unsigned char* to = _pixmap; - for (; to < _pixmap + pixel_count; from += 4, to += 4) - { - // Pre-multiplied alpha! - const double alpha = from[3] / 255.0; - to[0] = 0xff * alpha; - to[1] = 0xff * alpha; - to[2] = 0xff * alpha; - to[3] = from[3]; - } - // Use box blur, which is fast, though crude. - unsigned char* buffer = static_cast<unsigned char*>(malloc(pixel_count)); - memcpy(buffer, _pixmap, pixel_count); - - // Repeat an even number of times to smooth out. + // Create the white blurred background + // Use box blur, it's enough for our purposes const int r = 2; const double weight = (r+1) * (r+1); - for (int y = r; y < height - r; ++y) + for (int y = 0; y < height; ++y) { - for (int x = r; x < width - r; ++x) + for (int x = 0; x < width; ++x) { double t = 0; - for (int ky = y - r; ky <= y + r; ++ky) + for (int ky = std::max(y - r, 0); ky <= std::min(y + r, height - 1); ++ky) { - for (int kx = x - r; kx <= x + r; ++kx) + for (int kx = std::max(x - r, 0); kx <= std::min(x + r, width - 1); ++kx) { - t += buffer[4 * (ky * width + kx) + 3]; + // Pre-multiplied alpha; the text is black, so all the + // information is only in the alpha channel + t += text[4 * (ky * width + kx) + 3]; } } @@ -636,19 +623,20 @@ private: double avg = t / weight; if (avg > 255.0) avg = 255.0; + + // Pre-multiplied alpha, but use white for the resulting color const double alpha = avg / 255.0; _pixmap[4 * (y * width + x) + 0] = 0xff * alpha; _pixmap[4 * (y * width + x) + 1] = 0xff * alpha; _pixmap[4 * (y * width + x) + 2] = 0xff * alpha; - _pixmap[4 * (y * width + x) + 3] = static_cast<unsigned char>(avg < 255.0 ? avg : 255); + _pixmap[4 * (y * width + x) + 3] = avg; } } - // Now copy text over the blur + // Now copy the (black) text over the (white) blur alphaBlend(text, _width, _height, 0, 0, _pixmap, _width, _height); // No longer needed. - std::free(buffer); std::free(text); // Make the resulting pixmap semi-transparent commit b0a7fadcc69533c18ede6405790b249ddd7a4250 Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk> Date: Sun Dec 10 21:54:07 2017 -0500 wsd: improve watermark visibility on dark and grey backgrounds The watermark text is now rendered on a blurred version of itself, using inverted colors. This makes it look sharp on light backgrounds, but inverted in a blurry haze when on dark backgrounds, thereby being readable on top of any background. Change-Id: Ia6daf987674c484980f1fdec4f74e579ed87c213 Reviewed-on: https://gerrit.libreoffice.org/46491 Reviewed-by: Ashod Nakashian <ashnak...@gmail.com> Tested-by: Ashod Nakashian <ashnak...@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/46526 Reviewed-by: Jan Holesovsky <ke...@collabora.com> Tested-by: Jan Holesovsky <ke...@collabora.com> diff --git a/kit/Kit.cpp b/kit/Kit.cpp index 0a312454..051963a4 100644 --- a/kit/Kit.cpp +++ b/kit/Kit.cpp @@ -501,7 +501,6 @@ public: , _font("Liberation Sans") , _width(0) , _height(0) - , _color{64, 64, 64} , _alphaLevel(0.2) , _pixmap(nullptr) { @@ -517,7 +516,7 @@ public: int offsetX, int offsetY, int tilesPixmapWidth, int tilesPixmapHeight, int tileWidth, int tileHeight, - LibreOfficeKitTileMode mode) + LibreOfficeKitTileMode /*mode*/) { // set requested watermark size a little bit smaller than tile size int width = tileWidth * 0.9; @@ -527,42 +526,48 @@ public: if (pixmap && tilePixmap) { - unsigned int pixmapSize = tilesPixmapWidth * tilesPixmapHeight * 4; - int maxX = std::min(tileWidth, _width); - int maxY = std::min(tileHeight, _height); - // center watermark + const int maxX = std::min(tileWidth, _width); + const int maxY = std::min(tileHeight, _height); offsetX += (tileWidth - maxX) / 2; offsetY += (tileHeight - maxY) / 2; - for (int y = 0; y < maxY; ++y) - { - for (int x = 0; x < maxX; ++x) - { - unsigned int i = (y * _width + x) * 4; - unsigned int alpha = pixmap[i + 3]; - if (alpha) - { - for (int h = 0; h < 3; ++h) - { - unsigned int j = ((y + offsetY) * tilesPixmapWidth + (x + offsetX)) * 4 + h; - if (j < pixmapSize) - { - unsigned int color = (mode == LOK_TILEMODE_BGRA) ? _color[2 - h] : _color[h]; - - // original alpha blending for smoothing text edges - color = ((color * alpha) + tilePixmap[j] * (255 - alpha)) / 255; - // blending between document tile and watermark - tilePixmap[j] = color * _alphaLevel + tilePixmap[j] * (1 - _alphaLevel); - } - } - } - } - } + alphaBlend(pixmap, _width, _height, offsetX, offsetY, tilePixmap, tilesPixmapWidth, tilesPixmapHeight); } } private: + /// Alpha blend 'pixel_count' pixels from 'from' over the 'to'. + void alphaBlend(const unsigned char* from, int from_width, int from_height, int from_offset_x, int from_offset_y, + unsigned char* to, int to_width, int to_height) + { + for (int to_y = from_offset_y, from_y = 0; (to_y < to_height) && (from_y < from_height) ; ++to_y, ++from_y) + for (int to_x = from_offset_x, from_x = 0; (to_x < to_width) && (from_x < from_width); ++to_x, ++from_x) + { + const unsigned char* f = from + 4 * (from_y * from_width + from_x); + double src_r = f[0]; + double src_g = f[1]; + double src_b = f[2]; + double src_a = f[3] / 255.0; + + unsigned char* t = to + 4 * (to_y * to_width + to_x); + double dst_r = t[0]; + double dst_g = t[1]; + double dst_b = t[2]; + double dst_a = t[3] / 255.0; + + double out_a = src_a + dst_a * (1.0 - src_a); + unsigned char out_r = src_r + dst_r * (1.0 - src_a); + unsigned char out_g = src_g + dst_g * (1.0 - src_a); + unsigned char out_b = src_b + dst_b * (1.0 - src_a); + + t[0] = out_r; + t[1] = out_g; + t[2] = out_b; + t[3] = static_cast<unsigned char>(out_a * 255.0); + } + } + const unsigned char* getPixmap(int width, int height) { if (_pixmap && width == _width && height == _height) @@ -584,13 +589,74 @@ private: // are always set to 0 (black) and the alpha level is 0 everywhere // except on the text area; the alpha level take into account of // performing anti-aliasing over the text edges. - _pixmap = _loKitDoc->renderFont(_font.c_str(), _text.c_str(), &_width, &_height); + unsigned char* text = _loKitDoc->renderFont(_font.c_str(), _text.c_str(), &_width, &_height); - if (!_pixmap) + if (!text) { LOG_ERR("Watermark: rendering failed."); } + const unsigned int pixel_count = width * height * 4; + + // Create the blurred background; first a white text + _pixmap = static_cast<unsigned char*>(malloc(pixel_count)); + unsigned char* from = text; + unsigned char* to = _pixmap; + for (; to < _pixmap + pixel_count; from += 4, to += 4) + { + // Pre-multiplied alpha! + const double alpha = from[3] / 255.0; + to[0] = 0xff * alpha; + to[1] = 0xff * alpha; + to[2] = 0xff * alpha; + to[3] = from[3]; + } + + // Use box blur, which is fast, though crude. + unsigned char* buffer = static_cast<unsigned char*>(malloc(pixel_count)); + memcpy(buffer, _pixmap, pixel_count); + + // Repeat an even number of times to smooth out. + const int r = 2; + const double weight = (r+1) * (r+1); + for (int y = r; y < height - r; ++y) + { + for (int x = r; x < width - r; ++x) + { + double t = 0; + for (int ky = y - r; ky <= y + r; ++ky) + { + for (int kx = x - r; kx <= x + r; ++kx) + { + t += buffer[4 * (ky * width + kx) + 3]; + } + } + + // Clamp the result. + double avg = t / weight; + if (avg > 255.0) + avg = 255.0; + const double alpha = avg / 255.0; + _pixmap[4 * (y * width + x) + 0] = 0xff * alpha; + _pixmap[4 * (y * width + x) + 1] = 0xff * alpha; + _pixmap[4 * (y * width + x) + 2] = 0xff * alpha; + _pixmap[4 * (y * width + x) + 3] = static_cast<unsigned char>(avg < 255.0 ? avg : 255); + } + } + + // Now copy text over the blur + alphaBlend(text, _width, _height, 0, 0, _pixmap, _width, _height); + + // No longer needed. + std::free(buffer); + std::free(text); + + // Make the resulting pixmap semi-transparent + for (unsigned char* p = _pixmap; p < _pixmap + pixel_count; p++) + { + *p = static_cast<unsigned char>(*p * _alphaLevel); + } + return _pixmap; } @@ -600,7 +666,6 @@ private: std::string _font; int _width; int _height; - unsigned char _color[3]; double _alphaLevel; unsigned char* _pixmap; }; @@ -930,7 +995,10 @@ public: const auto pixelWidth = tileCombined.getWidth(); const auto pixelHeight = tileCombined.getHeight(); - const uint64_t hash = Png::hashSubBuffer(pixmap.data(), positionX * pixelWidth, positionY * pixelHeight, + const int offsetX = positionX * pixelWidth; + const int offsetY = positionY * pixelHeight; + + const uint64_t hash = Png::hashSubBuffer(pixmap.data(), offsetX, offsetY, pixelWidth, pixelHeight, pixmapWidth, pixmapHeight); TileWireId wireId = _pngCache.hashToWireId(hash); @@ -944,16 +1012,13 @@ public: continue; } - int offsetX = positionX * pixelWidth; - int offsetY = positionY * pixelHeight; - if (_docWatermark) _docWatermark->blending(pixmap.data(), offsetX, offsetY, pixmapWidth, pixmapHeight, - tileCombined.getWidth(), tileCombined.getHeight(), + pixelWidth, pixelHeight, mode); - if (!_pngCache.encodeSubBufferToPNG(pixmap.data(), positionX * pixelWidth, positionY * pixelHeight, + if (!_pngCache.encodeSubBufferToPNG(pixmap.data(), offsetX, offsetY, pixelWidth, pixelHeight, pixmapWidth, pixmapHeight, output, mode, hash, wireId, oldWireId)) { commit 51277944c6c4a85bcc39bfc0366e81e446015db4 Author: Jan Holesovsky <ke...@collabora.com> Date: Wed Dec 13 21:33:05 2017 +0100 Adjust the vertical centering of the column headers slightly. Change-Id: Ief485cfb24bd57d5ec410866189e383658293cc4 Reviewed-on: https://gerrit.libreoffice.org/46425 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/loleaflet/src/control/Control.ColumnHeader.js b/loleaflet/src/control/Control.ColumnHeader.js index 31ac194a..7871436b 100644 --- a/loleaflet/src/control/Control.ColumnHeader.js +++ b/loleaflet/src/control/Control.ColumnHeader.js @@ -242,7 +242,11 @@ L.Control.ColumnHeader = L.Control.Header.extend({ ctx.font = this._font; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; - ctx.fillText(content, endPar - (width / 2), startOrt + (height / 2)); + // The '+ 1' below is a hack - it's currently not possible to measure + // the exact bounding box in html5's canvas, and the textBaseline + // 'middle' measures everything including the descent etc. + // '+ 1' looks visually fine, and seems safe enough + ctx.fillText(content, endPar - (width / 2), startOrt + (height / 2) + 1); // draw row separator ctx.fillStyle = this._borderColor; ctx.fillRect(endPar -1, startOrt, this._borderWidth, height); commit 525284e32d1a565c2521532fce9bea6c3d27c260 Author: Jan Holesovsky <ke...@collabora.com> Date: Wed Dec 13 14:28:57 2017 +0100 lokdialog: Set the language of the given view. Change-Id: I54d542ff736b37c9b08c3e73f65d3fc27d095acc Reviewed-on: https://gerrit.libreoffice.org/46385 Reviewed-by: pranavk <pran...@collabora.co.uk> Tested-by: pranavk <pran...@collabora.co.uk> diff --git a/kit/Kit.cpp b/kit/Kit.cpp index 956826af..0a312454 100644 --- a/kit/Kit.cpp +++ b/kit/Kit.cpp @@ -1512,9 +1512,12 @@ private: const int viewId = _loKitDocument->getView(); session->setViewId(viewId); + _sessionUserInfo[viewId] = UserInfo(session->getViewUserId(), session->getViewUserName(), session->getViewUserExtraInfo(), session->isReadOnly()); + _loKitDocument->setViewLanguage(viewId, lang.c_str()); + _viewIdToCallbackDescr.emplace(viewId, std::unique_ptr<CallbackDescriptor>(new CallbackDescriptor({ this, viewId }))); _loKitDocument->registerCallback(ViewCallback, _viewIdToCallbackDescr[viewId].get()); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits