[Libreoffice-commits] core.git: Branch 'feature/skia' - 4 commits - external/skia vcl/inc vcl/opengl vcl/skia vcl/win
Luboš Luňák (via logerrit)
logerrit at kemper.freedesktop.org
Fri Oct 25 18:10:18 UTC 2019
external/skia/fix-shader-locale.patch.1 | 95 +++++++++++++-------------------
vcl/inc/opengl/win/gdiimpl.hxx | 6 +-
vcl/inc/skia/win/gdiimpl.hxx | 8 +-
vcl/inc/win/salgdi.h | 7 +-
vcl/inc/win/wingdiimpl.hxx | 4 -
vcl/opengl/win/gdiimpl.cxx | 4 -
vcl/skia/gdiimpl.cxx | 17 +----
vcl/skia/win/gdiimpl.cxx | 79 +++++++++++++++++++++++---
vcl/win/gdi/winlayout.cxx | 9 ++-
9 files changed, 136 insertions(+), 93 deletions(-)
New commits:
commit 477f604ae0508c9fb7c936c55bab862c5c0ae803
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Oct 25 16:29:49 2019 +0200
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Fri Oct 25 20:09:33 2019 +0200
fix Skia Windows text rendering
There are two cases in WinSalGraphics::DrawTextLayout(), with and
without cached glyphs:
- Cached case DeferredTextDraw() gets data as BGRA with the glyph
drawn in white, it just needs to be modulated to the proper color
and drawn.
- Uncached case DrawTextMask() gets data as BGRA with A invalid,
it must be used as mask for the color to drawn, but without
the inverse alpha VCL idiosyncracy that DrawMask() handles.
Change-Id: I05dcec994df68d5986cd85cffa42a8f9f23c42c4
diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx
index 142af9768387..2101818472ae 100644
--- a/vcl/inc/opengl/win/gdiimpl.hxx
+++ b/vcl/inc/opengl/win/gdiimpl.hxx
@@ -26,8 +26,8 @@ class OpenGLCompatibleDC : public CompatibleDC
public:
OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height);
- virtual std::unique_ptr<Texture> getTexture() override;
- // overload, caller must delete
+ virtual std::unique_ptr<Texture> getAsMaskTexture() override;
+ // caller must delete
OpenGLTexture* getOpenGLTexture();
virtual bool copyToTexture(Texture& aTexture) override;
@@ -68,7 +68,7 @@ public:
virtual bool UseTextDraw() const override { return true; }
virtual void PreDrawText() override;
virtual void PostDrawText() override;
- virtual void DrawMask( CompatibleDC::Texture* rTexture, Color nMaskColor, const SalTwoRect& rPosAry ) override;
+ virtual void DrawTextMask( CompatibleDC::Texture* rTexture, Color nMaskColor, const SalTwoRect& rPosAry ) override;
using OpenGLSalGraphicsImpl::DrawMask;
virtual void DeferredTextDraw(const CompatibleDC::Texture* pTexture, Color nMaskColor, const SalTwoRect& rPosAry) override;
diff --git a/vcl/inc/skia/win/gdiimpl.hxx b/vcl/inc/skia/win/gdiimpl.hxx
index bc177337b3de..6bd52b073aa5 100644
--- a/vcl/inc/skia/win/gdiimpl.hxx
+++ b/vcl/inc/skia/win/gdiimpl.hxx
@@ -28,10 +28,12 @@ class SkiaCompatibleDC : public CompatibleDC
public:
SkiaCompatibleDC(SalGraphics& rGraphics, int x, int y, int width, int height);
- virtual std::unique_ptr<Texture> getTexture() override;
+ virtual std::unique_ptr<Texture> getAsMaskTexture() override;
virtual bool copyToTexture(Texture& aTexture) override;
+ virtual bool wantsTextColorWhite() const override { return true; }
+
struct Texture;
};
@@ -65,8 +67,8 @@ public:
virtual bool UseTextDraw() const override { return true; }
virtual void PreDrawText() override;
virtual void PostDrawText() override;
- virtual void DrawMask(CompatibleDC::Texture* rTexture, Color nMaskColor,
- const SalTwoRect& rPosAry) override;
+ virtual void DrawTextMask(CompatibleDC::Texture* rTexture, Color nMaskColor,
+ const SalTwoRect& rPosAry) override;
virtual void DeferredTextDraw(const CompatibleDC::Texture* pTexture, Color nMaskColor,
const SalTwoRect& rPosAry) override;
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index f7fb206624b5..fc12bc823b93 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -138,11 +138,14 @@ public:
/// Base texture class (OpenGL and Skia will provide their implementations).
struct Texture;
- /// Obtain the texture.
- virtual std::unique_ptr<Texture> getTexture() { abort(); };
+ /// Obtain the texture in format for WinSalGraphicsImplBase::DrawTextMask().
+ virtual std::unique_ptr<Texture> getAsMaskTexture() { abort(); };
/// Copy bitmap data to the texture. Texture must be initialized and the correct size to hold the bitmap.
virtual bool copyToTexture(Texture& /*aTexture*/) { abort(); };
+
+ /// Return true if text glyphs should be drawn as white instead of black.
+ virtual bool wantsTextColorWhite() const { return false; }
};
struct CompatibleDC::Texture
diff --git a/vcl/inc/win/wingdiimpl.hxx b/vcl/inc/win/wingdiimpl.hxx
index 2264eecf353d..84884220318f 100644
--- a/vcl/inc/win/wingdiimpl.hxx
+++ b/vcl/inc/win/wingdiimpl.hxx
@@ -39,8 +39,8 @@ public:
virtual bool UseTextDraw() const { return false; }
virtual void PreDrawText() {}
virtual void PostDrawText() {}
- virtual void DrawMask(CompatibleDC::Texture* /*rTexture*/, Color /*nMaskColor*/,
- const SalTwoRect& /*rPosAry*/)
+ virtual void DrawTextMask(CompatibleDC::Texture* /*rTexture*/, Color /*nMaskColor*/,
+ const SalTwoRect& /*rPosAry*/)
{
abort();
};
diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx
index d71a03714198..bb6e5bf0a16c 100644
--- a/vcl/opengl/win/gdiimpl.cxx
+++ b/vcl/opengl/win/gdiimpl.cxx
@@ -770,7 +770,7 @@ OpenGLTexture* OpenGLCompatibleDC::getOpenGLTexture()
return new OpenGLTexture(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, mpData);
}
-std::unique_ptr<CompatibleDC::Texture> OpenGLCompatibleDC::getTexture()
+std::unique_ptr<CompatibleDC::Texture> OpenGLCompatibleDC::getAsMaskTexture()
{
auto ret = std::make_unique<OpenGLCompatibleDC::Texture>();
ret->texture = OpenGLTexture(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, mpData);
@@ -881,7 +881,7 @@ void WinOpenGLSalGraphicsImpl::DeferredTextDraw(const CompatibleDC::Texture* pTe
PostBatchDraw();
}
-void WinOpenGLSalGraphicsImpl::DrawMask( CompatibleDC::Texture* pTexture, Color nMaskColor, const SalTwoRect& rPosAry )
+void WinOpenGLSalGraphicsImpl::DrawTextMask( CompatibleDC::Texture* pTexture, Color nMaskColor, const SalTwoRect& rPosAry )
{
assert(dynamic_cast<OpenGLCompatibleDC::Texture*>(pTexture));
DrawMask( static_cast<OpenGLCompatibleDC::Texture*>(pTexture)->texture, nMaskColor, rPosAry );
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx
index 9a41ffc7da27..e583cea86f3c 100644
--- a/vcl/skia/win/gdiimpl.cxx
+++ b/vcl/skia/win/gdiimpl.cxx
@@ -12,6 +12,9 @@
#include <tools/sk_app/win/WindowContextFactory_win.h>
#include <tools/sk_app/WindowContext.h>
+#include <SkColorFilter.h>
+#include <SkPixelRef.h>
+
WinSkiaSalGraphicsImpl::WinSkiaSalGraphicsImpl(WinSalGraphics& rGraphics,
SalGeometryProvider* mpProvider)
: SkiaSalGraphicsImpl(rGraphics, mpProvider)
@@ -102,18 +105,54 @@ void WinSkiaSalGraphicsImpl::PreDrawText() { preDraw(); }
void WinSkiaSalGraphicsImpl::PostDrawText() { postDraw(); }
+SkColor toSkColor(Color color)
+{
+ return SkColorSetARGB(255 - color.GetTransparency(), color.GetRed(), color.GetGreen(),
+ color.GetBlue());
+}
+
void WinSkiaSalGraphicsImpl::DeferredTextDraw(const CompatibleDC::Texture* pTexture,
Color aMaskColor, const SalTwoRect& rPosAry)
{
assert(dynamic_cast<const SkiaCompatibleDC::Texture*>(pTexture));
- drawMask(rPosAry, static_cast<const SkiaCompatibleDC::Texture*>(pTexture)->bitmap, aMaskColor);
+ preDraw();
+ SkPaint paint;
+ // The glyph is painted as white, modulate it to be of the appropriate color.
+ // SkiaCompatibleDC::wantsTextColorWhite() ensures the glyph is white.
+ // TODO maybe other black/white in WinFontInstance::CacheGlyphToAtlas() should be swapped.
+ paint.setColorFilter(SkColorFilters::Blend(toSkColor(aMaskColor), SkBlendMode::kModulate));
+ mSurface->getCanvas()->drawBitmapRect(
+ static_cast<const SkiaCompatibleDC::Texture*>(pTexture)->bitmap,
+ SkRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight),
+ SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth,
+ rPosAry.mnDestHeight),
+ &paint);
+ postDraw();
}
-void WinSkiaSalGraphicsImpl::DrawMask(CompatibleDC::Texture* pTexture, Color nMaskColor,
- const SalTwoRect& rPosAry)
+void WinSkiaSalGraphicsImpl::DrawTextMask(CompatibleDC::Texture* pTexture, Color nMaskColor,
+ const SalTwoRect& rPosAry)
{
assert(dynamic_cast<SkiaCompatibleDC::Texture*>(pTexture));
- drawMask(rPosAry, static_cast<const SkiaCompatibleDC::Texture*>(pTexture)->bitmap, nMaskColor);
+ const SkBitmap& bitmap = static_cast<const SkiaCompatibleDC::Texture*>(pTexture)->bitmap;
+ preDraw();
+ SkBitmap tmpBitmap;
+ if (!tmpBitmap.tryAllocN32Pixels(bitmap.width(), bitmap.height()))
+ abort();
+ tmpBitmap.eraseColor(toSkColor(nMaskColor));
+ SkPaint paint;
+ // Draw the color with the given mask.
+ // TODO figure out the right blend mode to avoid the temporary bitmap
+ paint.setBlendMode(SkBlendMode::kDstOut);
+ SkCanvas canvas(tmpBitmap);
+ canvas.drawBitmap(bitmap, 0, 0, &paint);
+ mSurface->getCanvas()->drawBitmapRect(
+ tmpBitmap,
+ SkRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight),
+ SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth,
+ rPosAry.mnDestHeight),
+ nullptr);
+ postDraw();
}
SkiaCompatibleDC::SkiaCompatibleDC(SalGraphics& rGraphics, int x, int y, int width, int height)
@@ -121,15 +160,35 @@ SkiaCompatibleDC::SkiaCompatibleDC(SalGraphics& rGraphics, int x, int y, int wid
{
}
-std::unique_ptr<CompatibleDC::Texture> SkiaCompatibleDC::getTexture()
+std::unique_ptr<CompatibleDC::Texture> SkiaCompatibleDC::getAsMaskTexture()
{
auto ret = std::make_unique<SkiaCompatibleDC::Texture>();
- // TODO is this correct?
- // TODO make copy of data?
- if (!ret->bitmap.installPixels(SkImageInfo::Make(maRects.mnSrcWidth, maRects.mnSrcHeight,
- kBGRA_8888_SkColorType, kUnpremul_SkAlphaType),
- mpData, maRects.mnSrcWidth * 4))
+ // mpData is in the BGRA format, with A unused (and set to 0), and RGB are grey,
+ // so convert it to Skia format, then to 8bit and finally use as alpha mask
+ SkBitmap tmpBitmap;
+ if (!tmpBitmap.installPixels(SkImageInfo::Make(maRects.mnSrcWidth, maRects.mnSrcHeight,
+ kBGRA_8888_SkColorType, kOpaque_SkAlphaType),
+ mpData, maRects.mnSrcWidth * 4))
+ abort();
+ SkBitmap bitmap8;
+ if (!bitmap8.tryAllocPixels(SkImageInfo::Make(maRects.mnSrcWidth, maRects.mnSrcHeight,
+ kGray_8_SkColorType, kOpaque_SkAlphaType)))
abort();
+ SkCanvas canvas8(bitmap8);
+ SkPaint paint8;
+ paint8.setBlendMode(SkBlendMode::kSrc); // copy and convert depth
+ // The data we got is upside-down.
+ SkMatrix matrix;
+ matrix.preTranslate(0, maRects.mnSrcHeight);
+ matrix.setConcat(matrix, SkMatrix::MakeScale(1, -1));
+ canvas8.concat(matrix);
+ canvas8.drawBitmap(tmpBitmap, 0, 0, &paint8);
+ // use the 8bit data as an alpha channel
+ SkBitmap alpha;
+ alpha.setInfo(bitmap8.info().makeColorType(kAlpha_8_SkColorType), bitmap8.rowBytes());
+ alpha.setPixelRef(sk_ref_sp(bitmap8.pixelRef()), bitmap8.pixelRefOrigin().x(),
+ bitmap8.pixelRefOrigin().y());
+ ret->bitmap = alpha;
return ret;
}
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index d8ccc3783ab1..a5e1056d1379 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -169,7 +169,8 @@ bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex,
auto pRT = pTxt->GetRenderTarget();
ID2D1SolidColorBrush* pBrush = nullptr;
- if (!SUCCEEDED(pRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &pBrush)))
+ D2D1::ColorF textColor = aDC->wantsTextColorWhite() ? D2D1::ColorF::White : D2D1::ColorF::Black;
+ if (!SUCCEEDED(pRT->CreateSolidColorBrush(textColor, &pBrush)))
return false;
D2D1_POINT_2F baseline = {
@@ -579,9 +580,9 @@ void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
// the actual drawing
DrawTextLayout(rLayout, aDC->getCompatibleHDC(), !bForceGDI);
- std::unique_ptr<CompatibleDC::Texture> xTexture(aDC->getTexture());
+ std::unique_ptr<CompatibleDC::Texture> xTexture(aDC->getAsMaskTexture());
if (xTexture)
- pImpl->DrawMask(xTexture.get(), salColor, aDC->getTwoRect());
+ pImpl->DrawTextMask(xTexture.get(), salColor, aDC->getTwoRect());
::SelectFont(aDC->getCompatibleHDC(), hOrigFont);
commit 1f0ebf6a0cba419280e2e9d3f9dd7c104ebdb57d
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Oct 25 16:07:26 2019 +0200
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Fri Oct 25 20:09:30 2019 +0200
fix SkiaSalGraphicsImpl::drawMask()
Now that SalBitmap::convertDataBitCount() has been fixed,
the implementation here gets rather trivial.
This breaks Windows text drawing, which uses drawMask() incorrectly
(to be fixed in the next commit).
Change-Id: I98f11c1bd4b1600bb5e03e570319d29b40daa27e
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index 560dcab6b99a..d6a956e4e76f 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -652,23 +652,16 @@ void SkiaSalGraphicsImpl::drawMask(const SalTwoRect& rPosAry, const SkBitmap& rB
Color nMaskColor)
{
preDraw();
- SkBitmap tmpBitmap;
- if (!tmpBitmap.tryAllocN32Pixels(rBitmap.width(), rBitmap.height()))
- abort();
- SkCanvas canvas(tmpBitmap);
SkPaint paint;
- paint.setBlendMode(SkBlendMode::kSrc);
- canvas.drawBitmap(rBitmap, 0, 0, &paint);
- // TODO what is this function supposed to do exactly?
- // Text drawing on Windows doesn't work if this is uncommented.
- // tmpBitmap.eraseColor(toSkColor(nMaskColor));
- (void)nMaskColor;
+ // Draw the color with the given mask, and mask uses inversed alpha.
+ paint.setBlendMode(SkBlendMode::kDstOut);
+ paint.setColor(toSkColor(nMaskColor));
mSurface->getCanvas()->drawBitmapRect(
- tmpBitmap,
+ rBitmap,
SkRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight),
SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth,
rPosAry.mnDestHeight),
- nullptr);
+ &paint);
postDraw();
}
commit 0e02f6b773e5a0173ce8ad8ccdb478d473bbedd8
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Oct 25 15:17:56 2019 +0200
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Fri Oct 25 20:09:27 2019 +0200
skip text drawing if there is nothing to draw
If the rectangle is empty, there is nothing to draw. This also avoids
problems with WinSalVirtualDevice::ImplCreateVirDevBitmap() calling
CreateDIBSection() with zero dimensions.
Change-Id: I3a56e64fc32cfb855443f4ab665d53604d724d9b
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index f92f16d4e732..d8ccc3783ab1 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -550,6 +550,8 @@ void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
tools::Rectangle aRect;
rLayout.GetBoundRect(aRect);
+ if( aRect.IsEmpty())
+ return;
pImpl->PreDrawText();
commit 6778b361c9b90c0acd074eef7da2537c289670e4
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Oct 25 10:45:34 2019 +0200
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Fri Oct 25 20:09:23 2019 +0200
update Skia fix-shader-locale.patch.1 to the upstream version
Change-Id: Ie8606f30d3f821d7b195aa7978886d529a57bfd2
diff --git a/external/skia/fix-shader-locale.patch.1 b/external/skia/fix-shader-locale.patch.1
index 71a5b0e00c82..af6405fe517c 100644
--- a/external/skia/fix-shader-locale.patch.1
+++ b/external/skia/fix-shader-locale.patch.1
@@ -1,57 +1,40 @@
-https://bugs.chromium.org/p/skia/issues/detail?id=9550
+From b653813d58146fb41cd1852e5f24cdfc0ad9532a Mon Sep 17 00:00:00 2001
+From: Ethan Nicholas <ethannicholas at google.com>
+Date: Tue, 22 Oct 2019 16:00:18 -0400
+Subject: [PATCH 1/7] Vulkan SkSL code now works in locales which use ',' as
+ the decimal separator.
+
+Bug: skia:9550
+Change-Id: Ib844971bd1daebdf7a0f93388ad40e4977822233
+Reviewed-on: https://skia-review.googlesource.com/c/skia/+/250076
+Reviewed-by: Greg Daniel <egdaniel at google.com>
+Commit-Queue: Ethan Nicholas <ethannicholas at google.com>
+---
+ src/gpu/vk/GrVkPipelineStateBuilder.cpp | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/gpu/vk/GrVkPipelineStateBuilder.cpp b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
+index 4d595e7eca..dbe16f6e7f 100644
+--- a/src/gpu/vk/GrVkPipelineStateBuilder.cpp
++++ b/src/gpu/vk/GrVkPipelineStateBuilder.cpp
+@@ -6,6 +6,7 @@
+ */
+
+ #include "include/gpu/GrContext.h"
++#include "src/gpu/GrAutoLocaleSetter.h"
+ #include "src/gpu/GrContextPriv.h"
+ #include "src/gpu/GrPersistentCacheUtils.h"
+ #include "src/gpu/GrShaderCaps.h"
+@@ -27,6 +28,9 @@ GrVkPipelineState* GrVkPipelineStateBuilder::CreatePipelineState(
+ GrPrimitiveType primitiveType,
+ Desc* desc,
+ VkRenderPass compatibleRenderPass) {
++ // ensure that we use "." as a decimal separator when creating SkSL code
++ GrAutoLocaleSetter als("C");
++
+ // create a builder. This will be handed off to effects so they can use it to add
+ // uniforms, varyings, textures, etc
+ GrVkPipelineStateBuilder builder(gpu, renderTarget, programInfo, desc);
+--
+2.16.4
-diff --git a/src/core/SkString.cpp b/src/core/SkString.cpp
-index d42ee6f07e..1e3ebddf95 100644
---- a/src/core/SkString.cpp
-+++ b/src/core/SkString.cpp
-@@ -502,11 +502,15 @@ void SkString::appendf(const char format[], ...) {
- }
-
- void SkString::appendVAList(const char format[], va_list args) {
-+ char* oldlocale = strdup( setlocale( LC_NUMERIC, nullptr ));
-+ setlocale( LC_NUMERIC, "C" );
- char buffer[kBufferSize];
- int length = vsnprintf(buffer, kBufferSize, format, args);
- SkASSERT(length >= 0 && length < SkToInt(kBufferSize));
-
- this->append(buffer, length);
-+ setlocale( LC_NUMERIC, oldlocale );
-+ free( oldlocale );
- }
-
- void SkString::prependf(const char format[], ...) {
-@@ -519,11 +523,15 @@ void SkString::prependf(const char format[], ...) {
- }
-
- void SkString::prependVAList(const char format[], va_list args) {
-+ char* oldlocale = strdup( setlocale( LC_NUMERIC, nullptr ));
-+ setlocale( LC_NUMERIC, "C" );
- char buffer[kBufferSize];
- int length = vsnprintf(buffer, kBufferSize, format, args);
- SkASSERT(length >= 0 && length < SkToInt(kBufferSize));
-
- this->prepend(buffer, length);
-+ setlocale( LC_NUMERIC, oldlocale );
-+ free( oldlocale );
- }
-
-
-diff --git a/src/sksl/SkSLOutputStream.cpp b/src/sksl/SkSLOutputStream.cpp
-index f72637d4cb..6e31e8f302 100644
---- a/src/sksl/SkSLOutputStream.cpp
-+++ b/src/sksl/SkSLOutputStream.cpp
-@@ -21,10 +21,14 @@ void OutputStream::printf(const char format[], ...) {
- }
-
- void OutputStream::appendVAList(const char format[], va_list args) {
-+ char* oldlocale = strdup( setlocale( LC_NUMERIC, nullptr ));
-+ setlocale( LC_NUMERIC, "C" );
- char buffer[kBufferSize];
- int length = vsnprintf(buffer, kBufferSize, format, args);
- SkASSERT(length >= 0 && length < (int) kBufferSize);
- this->write(buffer, length);
-+ setlocale( LC_NUMERIC, oldlocale );
-+ free( oldlocale );
- }
-
- }
More information about the Libreoffice-commits
mailing list