[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