[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - 13 commits - bin/run include/vcl sd/source vcl/inc vcl/opengl vcl/Package_opengl.mk vcl/source

Michael Meeks michael.meeks at collabora.com
Mon Jan 19 07:02:25 PST 2015


 bin/run                                           |    6 
 include/vcl/bitmap.hxx                            |    9 
 sd/source/ui/presenter/PresenterPreviewCache.cxx  |    4 
 sd/source/ui/slidesorter/view/SlideSorterView.cxx |    4 
 vcl/Package_opengl.mk                             |    2 
 vcl/inc/opengl/program.hxx                        |    2 
 vcl/inc/opengl/salbmp.hxx                         |    1 
 vcl/inc/openglgdiimpl.hxx                         |   19 -
 vcl/opengl/areaScaleFastFragmentShader.glsl       |   43 ++
 vcl/opengl/areaScaleFragmentShader.glsl           |  131 ++++++++
 vcl/opengl/gdiimpl.cxx                            |  324 ++++++++++++++--------
 vcl/opengl/program.cxx                            |   12 
 vcl/opengl/scale.cxx                              |   76 +++++
 vcl/source/gdi/bitmap3.cxx                        |    6 
 vcl/source/outdev/polyline.cxx                    |    2 
 15 files changed, 511 insertions(+), 130 deletions(-)

New commits:
commit 38c9c6831975b5944fa19b0ab02ee61ba49e825d
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Jan 19 14:52:08 2015 +0000

    vcl: fix glsl int casts of floats.
    
    Change-Id: Ifa22e2914a1e34f6e2fd635973eca4101914bb88
    Signed-off-by: Jan Holesovsky <kendy at collabora.com>

diff --git a/vcl/opengl/areaScaleFragmentShader.glsl b/vcl/opengl/areaScaleFragmentShader.glsl
index cae5eb6..03fbe69 100644
--- a/vcl/opengl/areaScaleFragmentShader.glsl
+++ b/vcl/opengl/areaScaleFragmentShader.glsl
@@ -48,8 +48,8 @@ void main(void)
     float fsx1 = dx * xscale;
     float fsx2 = fsx1 + xscale;
     // To whole pixel coordinates.
-    int sx1 = ceil( fsx1 );
-    int sx2 = floor( fsx2 );
+    int sx1 = int( ceil( fsx1 ) );
+    int sx2 = int( floor( fsx2 ) );
     // Range checking.
     sx2 = min( sx2, swidth - 1 );
     sx1 = min( sx1, sx2 );
@@ -79,8 +79,8 @@ void main(void)
     // The same for Y.
     float fsy1 = dy * yscale;
     float fsy2 = fsy1 + yscale;
-    int sy1 = ceil( fsy1 );
-    int sy2 = floor( fsy2 );
+    int sy1 = int( ceil( fsy1 ) );
+    int sy2 = int( floor( fsy2 ) );
     sy2 = min( sy2, sheight - 1 );
     sy1 = min( sy1, sy2 );
 
commit 0394e710919b18106127a9dd08f78352b5e35939
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Wed Dec 10 17:25:25 2014 +0100

    bin/run LO_TRACE hook
    
    (similar to our CPPUNITTRACE hook)
    
    Change-Id: Iec4e8d4246ba7fca0afe5f9be6f6bcd9e0289e49
    Signed-off-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/bin/run b/bin/run
index 382ff73..20cea78 100755
--- a/bin/run
+++ b/bin/run
@@ -29,7 +29,7 @@ echo "setting URE_BOOTSTRAP to: ${URE_BOOTSTRAP}"
 echo "setting search path to: ${PATH}"
 echo "execing: ${exedir}/$1"
 
-exec "${exedir}"/$@
+exec ${LO_TRACE} "${exedir}"/$@
 
 elif [ $(uname) = Darwin ]; then
 
@@ -48,7 +48,7 @@ echo "setting URE_BOOTSTRAP to: ${URE_BOOTSTRAP}"
 echo "setting search path to: ${DYLD_LIBRARY_PATH}"
 echo "execing: ${exedir}/$1"
 
-exec "${exedir}"/$@
+exec ${LO_TRACE} "${exedir}"/$@
 
 else
 
@@ -70,6 +70,6 @@ echo "setting URE_BOOTSTRAP to: ${URE_BOOTSTRAP}"
 echo "setting search path to: ${LD_LIBRARY_PATH}"
 echo "execing: ${exedir}/$1"
 
-exec "${exedir}"/$@
+exec ${LO_TRACE} "${exedir}"/$@
 
 fi
commit 75750941b77620c215d50981f2cd8582f61d3eff
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Sun Jan 18 22:49:22 2015 +0100

    try to handle properly fillcolor != linecolor in opengl polypolygons drawing
    
    Change-Id: I962416f48fdb348d8a3d95edf747cfe2f1c929c9
    Signed-off-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 60f5a45..9584056 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -1189,7 +1189,7 @@ void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32*
         }
     }
 
-    if( UseSolidAA( mnLineColor ) )
+    if( mnLineColor != mnFillColor && UseSolidAA( mnLineColor ) )
     {
         // TODO Use glMultiDrawElements or primitive restart
         for( sal_uInt32 i = 0; i < nPoly; i++ )
@@ -1210,6 +1210,20 @@ bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rP
     if( UseSolid( mnFillColor, fTransparency ) )
         DrawPolyPolygon( rPolyPolygon );
 
+    if( mnLineColor != mnFillColor && UseSolidAA( mnLineColor ) )
+    {
+        for( sal_uInt32 i = 0; i < rPolyPolygon.count(); i++ )
+        {
+            const basegfx::B2DPolygon& polygon = rPolyPolygon.getB2DPolygon( i );
+            for( sal_uInt32 j = 0; j < polygon.count(); ++j )
+            {
+                const basegfx::B2DPoint& rPt1 = polygon.getB2DPoint( j );
+                const basegfx::B2DPoint& rPt2 = polygon.getB2DPoint(( j + 1 ) % polygon.count());
+                DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
+            }
+        }
+    }
+
     PostDraw();
 
     return true;
commit 1c5e4dcb8da19dc8674fd96ad3bb83793153e879
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Sun Jan 18 22:42:06 2015 +0100

    draw polypolygons properly in opengl backend
    
    The polygons that make the polypolygon cannot be simply drawn one onto another,
    because if they overlap, it's actually xor (as used e.g. for drawing the border
    when editing a text box Impress, which without this fix just made it a full
    rectangle instead of a frame).
    
    Change-Id: I67c7f6448fb3ee0f9742a2299c612515abff68d8
    Signed-off-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index ce49e96..7bb4532 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -89,7 +89,7 @@ public:
     void DrawEdgeAA( double nX1, double nY1, double nX2, double nY2 );
     void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry, bool blockAA = false );
     void DrawConvexPolygon( const Polygon& rPolygon, bool blockAA = false );
-    void DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoid );
+    void DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoid, bool blockAA = false );
     void DrawRect( long nX, long nY, long nWidth, long nHeight );
     void DrawRect( const Rectangle& rRect );
     void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index ed2a948..60f5a45 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -716,7 +716,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon, bool blo
     }
 }
 
-void OpenGLSalGraphicsImpl::DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoid )
+void OpenGLSalGraphicsImpl::DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoid, bool blockAA )
 {
     const basegfx::B2DPolygon& rPolygon = trapezoid.getB2DPolygon();
     sal_uInt16 nPoints = rPolygon.count();
@@ -733,7 +733,7 @@ void OpenGLSalGraphicsImpl::DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoi
     mpProgram->SetVertices( &aVertices[0] );
     glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
 
-    if( mrParent.getAntiAliasB2DDraw())
+    if( !blockAA && mrParent.getAntiAliasB2DDraw())
     {
         // Make the edges antialiased by drawing the edge lines again with AA.
         // TODO: If transparent drawing is set up, drawing the lines themselves twice
@@ -803,56 +803,15 @@ void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPt
 
 void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon, bool blockAA )
 {
-    ::std::vector< GLfloat > aVertices;
-    GLfloat nWidth = GetWidth();
-    GLfloat nHeight = GetHeight();
     const ::basegfx::B2DPolyPolygon& aSimplePolyPolygon = ::basegfx::tools::solveCrossovers( rPolyPolygon );
-
-    for( sal_uInt32 i = 0; i < aSimplePolyPolygon.count(); i++ )
+    basegfx::B2DTrapezoidVector aB2DTrapVector;
+    basegfx::tools::trapezoidSubdivide( aB2DTrapVector, aSimplePolyPolygon );
+    // draw tesselation result
+    if( aB2DTrapVector.size())
     {
-        const basegfx::B2DPolygon& rPolygon( aSimplePolyPolygon.getB2DPolygon( i ) );
-        const ::basegfx::B2DPolygon& aResult(
-            ::basegfx::triangulator::triangulate( rPolygon ) );
-
-        for( sal_uInt32 j = 0; j < aResult.count(); j++ )
-        {
-            const ::basegfx::B2DPoint& rPt( aResult.getB2DPoint( j ) );
-            aVertices.push_back( 2 * rPt.getX() / nWidth - 1.0f );
-            aVertices.push_back( 1.0f - 2 * rPt.getY() / nHeight );
-        }
+        for( size_t i = 0; i < aB2DTrapVector.size(); ++i )
+            DrawTrapezoid( aB2DTrapVector[ i ], blockAA );
     }
-
-    mpProgram->SetVertices( aVertices.data() );
-    glDrawArrays( GL_TRIANGLES, 0, aVertices.size() / 2 );
-
-    if( !blockAA && mrParent.getAntiAliasB2DDraw())
-    {
-        // Make the edges antialiased by drawing the edge lines again with AA.
-        // TODO: If transparent drawing is set up, drawing the lines themselves twice
-        // may be a problem, if that is a real problem, the polygon areas itself needs to be
-        // masked out for this or something.
-#ifdef DBG_UTIL
-        assert( mProgramIsSolidColor );
-#endif
-        SalColor lastSolidColor = mProgramSolidColor;
-        double lastSolidTransparency = mProgramSolidTransparency;
-        if( UseSolidAA( lastSolidColor, lastSolidTransparency ))
-        {
-            for( sal_uInt32 i = 0; i < aSimplePolyPolygon.count(); i++ )
-            {
-                const basegfx::B2DPolygon& rPolygon( aSimplePolyPolygon.getB2DPolygon( i ) );
-                for( sal_uInt32 j = 0; j < rPolygon.count(); j++ )
-                {
-                    const ::basegfx::B2DPoint& rPt1( rPolygon.getB2DPoint( j ) );
-                    const ::basegfx::B2DPoint& rPt2( rPolygon.getB2DPoint(( j + 1 ) % rPolygon.count()) );
-                    DrawEdgeAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
-                }
-            }
-            UseSolid( lastSolidColor, lastSolidTransparency );
-        }
-    }
-
-    CHECK_GL_ERROR();
 }
 
 void OpenGLSalGraphicsImpl::DrawRegionBand( const RegionBand& rRegion )
@@ -1210,8 +1169,24 @@ void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32*
 
     if( UseSolid( mnFillColor ) )
     {
-        for( sal_uInt32 i = 0; i < nPoly; i++ )
-            DrawPolygon( pPoints[i], pPtAry[i] );
+        if( nPoly == 1 )
+        {
+            for( sal_uInt32 i = 0; i < nPoly; i++ )
+                DrawPolygon( pPoints[i], pPtAry[i] );
+        }
+        else
+        {
+            basegfx::B2DPolyPolygon polyPolygon;
+            for( sal_uInt32 i = 0; i < nPoly; ++i )
+            {
+                basegfx::B2DPolygon polygon;
+                for( sal_uInt32 j = 0; j < pPoints[ i ]; ++j )
+                    polygon.append( basegfx::B2DPoint( pPtAry[i][j].mnX, pPtAry[i][j].mnY ) );
+                polygon.setClosed( true );
+                polyPolygon.append( polygon );
+            }
+            DrawPolyPolygon( polyPolygon );
+        }
     }
 
     if( UseSolidAA( mnLineColor ) )
@@ -1233,13 +1208,7 @@ bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rP
     PreDraw();
 
     if( UseSolid( mnFillColor, fTransparency ) )
-    {
-        for( sal_uInt32 i = 0; i < rPolyPolygon.count(); i++ )
-        {
-            const ::basegfx::B2DPolyPolygon aOnePoly( rPolyPolygon.getB2DPolygon( i ) );
-            DrawPolyPolygon( aOnePoly );
-        }
-    }
+        DrawPolyPolygon( rPolyPolygon );
 
     PostDraw();
 
commit 11771ca280430bd06071f6bf6976470392a604f1
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Sun Jan 18 19:00:32 2015 +0100

    fix opengl hairline special casing
    
    Apparently polygons can consist of curves too.
    
    Change-Id: Ie35861e6d182e4bd4ac0523e78a90618c96f09a6
    Signed-off-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 4b50469..ce49e96 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -35,6 +35,11 @@
 class SalFrame;
 class SalVirtualDevice;
 
+namespace basegfx
+{
+class B2DTrapezoid;
+};
+
 class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
 {
 protected:
@@ -84,6 +89,7 @@ public:
     void DrawEdgeAA( double nX1, double nY1, double nX2, double nY2 );
     void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry, bool blockAA = false );
     void DrawConvexPolygon( const Polygon& rPolygon, bool blockAA = false );
+    void DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoid );
     void DrawRect( long nX, long nY, long nWidth, long nHeight );
     void DrawRect( const Rectangle& rRect );
     void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 80800bf..ed2a948 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -716,6 +716,47 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon, bool blo
     }
 }
 
+void OpenGLSalGraphicsImpl::DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoid )
+{
+    const basegfx::B2DPolygon& rPolygon = trapezoid.getB2DPolygon();
+    sal_uInt16 nPoints = rPolygon.count();
+    std::vector<GLfloat> aVertices(nPoints * 2);
+    sal_uInt32 i, j;
+
+    for( i = 0, j = 0; i < nPoints; i++, j += 2 )
+    {
+        const basegfx::B2DPoint& rPt = rPolygon.getB2DPoint( i );
+        aVertices[j] = (2 * rPt.getX()) / GetWidth() - 1.0;
+        aVertices[j+1] = 1.0 - (2 * rPt.getY() / GetHeight());
+    }
+
+    mpProgram->SetVertices( &aVertices[0] );
+    glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+
+    if( mrParent.getAntiAliasB2DDraw())
+    {
+        // Make the edges antialiased by drawing the edge lines again with AA.
+        // TODO: If transparent drawing is set up, drawing the lines themselves twice
+        // may be a problem, if that is a real problem, the polygon areas itself needs to be
+        // masked out for this or something.
+#ifdef DBG_UTIL
+        assert( mProgramIsSolidColor );
+#endif
+        SalColor lastSolidColor = mProgramSolidColor;
+        double lastSolidTransparency = mProgramSolidTransparency;
+        if( UseSolidAA( lastSolidColor, lastSolidTransparency ))
+        {
+            for( i = 0; i < nPoints; ++i )
+            {
+                const basegfx::B2DPoint& rPt1 = rPolygon.getB2DPoint( i );
+                const basegfx::B2DPoint& rPt2 = rPolygon.getB2DPoint(( i + 1 ) % nPoints );
+                DrawEdgeAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
+            }
+            UseSolid( lastSolidColor, lastSolidTransparency );
+        }
+    }
+}
+
 void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, long nWidth, long nHeight )
 {
     long nX1( nX );
@@ -1243,17 +1284,19 @@ bool OpenGLSalGraphicsImpl::drawPolyLine(
     if( bIsHairline )
     {
         // hairlines can be drawn in a simpler way (the linejoin and linecap styles can be ignored)
-        PreDraw();
-        if( UseSolidAA( mnLineColor, fTransparency ))
+        basegfx::B2DTrapezoidVector aB2DTrapVector;
+        basegfx::tools::createLineTrapezoidFromB2DPolygon( aB2DTrapVector, aPolygon, rLineWidth.getX() );
+        // draw tesselation result
+        if( aB2DTrapVector.size())
         {
-            for( sal_uInt32 j = 0; j < rPolygon.count() - 1; j++ )
+            PreDraw();
+            if( UseSolid( mnLineColor, fTransparency ))
             {
-                const ::basegfx::B2DPoint& rPt1( rPolygon.getB2DPoint( j ) );
-                const ::basegfx::B2DPoint& rPt2( rPolygon.getB2DPoint(( j + 1 )) );
-                DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
+                for( size_t i = 0; i < aB2DTrapVector.size(); ++i )
+                    DrawTrapezoid( aB2DTrapVector[ i ] );
             }
+            PostDraw();
         }
-        PostDraw();
         return true;
     }
 
commit 9bd4b1c7eb400cd478907f75b66443787e674aca
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Sun Jan 18 18:58:20 2015 +0100

    use AA for convex polygons when needed too
    
    Change-Id: I8e66d369956a9bcf9c63c6eccad47d4b7a7eb67d
    Signed-off-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 2b815ee..4b50469 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -82,8 +82,8 @@ public:
     void DrawLineAA( double nX1, double nY1, double nX2, double nY2 );
     void DrawLinesAA( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
     void DrawEdgeAA( double nX1, double nY1, double nX2, double nY2 );
-    void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
-    void DrawConvexPolygon( const Polygon& rPolygon );
+    void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry, bool blockAA = false );
+    void DrawConvexPolygon( const Polygon& rPolygon, bool blockAA = false );
     void DrawRect( long nX, long nY, long nWidth, long nHeight );
     void DrawRect( const Rectangle& rRect );
     void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 6c565fa..80800bf 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -638,7 +638,7 @@ void OpenGLSalGraphicsImpl::DrawEdgeAA( double nX1, double nY1, double nX2, doub
     ImplDrawLineAA( nX1, nY1, nX2, nY2, true );
 }
 
-void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
+void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry, bool blockAA )
 {
     std::vector<GLfloat> aVertices(nPoints * 2);
     sal_uInt32 i, j;
@@ -651,9 +651,32 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin
 
     mpProgram->SetVertices( &aVertices[0] );
     glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
+
+    if( !blockAA && mrParent.getAntiAliasB2DDraw())
+    {
+        // Make the edges antialiased by drawing the edge lines again with AA.
+        // TODO: If transparent drawing is set up, drawing the lines themselves twice
+        // may be a problem, if that is a real problem, the polygon areas itself needs to be
+        // masked out for this or something.
+#ifdef DBG_UTIL
+        assert( mProgramIsSolidColor );
+#endif
+        SalColor lastSolidColor = mProgramSolidColor;
+        double lastSolidTransparency = mProgramSolidTransparency;
+        if( UseSolidAA( lastSolidColor, lastSolidTransparency ))
+        {
+            for( i = 0; i < nPoints; ++i )
+            {
+                const SalPoint& rPt1 = pPtAry[ i ];
+                const SalPoint& rPt2 = pPtAry[ ( i + 1 ) % nPoints ];
+                DrawEdgeAA( rPt1.mnX, rPt1.mnY, rPt2.mnX, rPt2.mnY );
+            }
+            UseSolid( lastSolidColor, lastSolidTransparency );
+        }
+    }
 }
 
-void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon )
+void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon, bool blockAA )
 {
     sal_uInt16 nPoints = rPolygon.GetSize() - 1;
     std::vector<GLfloat> aVertices(nPoints * 2);
@@ -669,7 +692,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon )
     mpProgram->SetVertices( &aVertices[0] );
     glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
 
-    if( mrParent.getAntiAliasB2DDraw())
+    if( !blockAA && mrParent.getAntiAliasB2DDraw())
     {
         // Make the edges antialiased by drawing the edge lines again with AA.
         // TODO: If transparent drawing is set up, drawing the lines themselves twice
@@ -702,7 +725,7 @@ void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, long nWidth, long nHeigh
     const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 },
                                  { nX2, nY1 }, { nX2, nY2 }};
 
-    DrawConvexPolygon( 4, aPoints );
+    DrawConvexPolygon( 4, aPoints, true );
 }
 
 void OpenGLSalGraphicsImpl::DrawRect( const Rectangle& rRect )
@@ -714,7 +737,7 @@ void OpenGLSalGraphicsImpl::DrawRect( const Rectangle& rRect )
     const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 },
                                  { nX2, nY1 }, { nX2, nY2 }};
 
-    DrawConvexPolygon( 4, aPoints );
+    DrawConvexPolygon( 4, aPoints, true );
 }
 
 void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
@@ -956,7 +979,7 @@ void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const
     GLfloat fMin = 1.0 - 100.0 / (100.0 - rGradient.GetBorder());
     aTexCoord[5] = aTexCoord[7] = fMin;
     mpProgram->SetTextureCoord( aTexCoord );
-    DrawConvexPolygon( aPoly );
+    DrawConvexPolygon( aPoly, true );
 }
 
 void OpenGLSalGraphicsImpl::DrawAxialGradient( const Gradient& rGradient, const Rectangle& rRect )
@@ -1006,7 +1029,7 @@ void OpenGLSalGraphicsImpl::DrawAxialGradient( const Gradient& rGradient, const
     GLfloat fMin = 1.0 - 100.0 / (100.0 - rGradient.GetBorder());
     aTexCoord[3] = aTexCoord[5] = aTexCoord[9] = aTexCoord[11] = fMin;
     mpProgram->SetTextureCoord( aTexCoord );
-    DrawConvexPolygon( aPoly );
+    DrawConvexPolygon( aPoly, true );
 }
 
 void OpenGLSalGraphicsImpl::DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect )
commit 568b40d24e0017b2d2042c8ba956c498f6d16247
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Sat Jan 17 20:46:55 2015 +0100

    use supersampling in Impress if fast opengl scaling is available
    
    So far it's been always disabled, with the exception of the slide preview
    extension.
    
    Change-Id: Iaee6fe2d5267c9dfdc31cbf4fb90a9ac0e08e781
    Signed-off-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/include/vcl/bitmap.hxx b/include/vcl/bitmap.hxx
index 1ce4481..44b6211 100644
--- a/include/vcl/bitmap.hxx
+++ b/include/vcl/bitmap.hxx
@@ -561,6 +561,15 @@ public:
      */
     bool                    Scale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag = BMP_SCALE_DEFAULT );
 
+    /**
+      Returns true if bitmap scaling is considered to be fast.
+
+      Currently this returns true if OpenGL is used for scaling, otherwise false (CPU scaling is slower).
+
+      @since 4.5
+    */
+    static bool HasFastScale();
+
     // Adapt the BitCount of rNew to BitCount of lolal, including grey or color paltette
     // Can be used to create alpha/mask bitmaps after their processing in 24bit
     void                    AdaptBitCount(Bitmap& rNew) const;
diff --git a/sd/source/ui/presenter/PresenterPreviewCache.cxx b/sd/source/ui/presenter/PresenterPreviewCache.cxx
index f88d2a5..da47d90 100644
--- a/sd/source/ui/presenter/PresenterPreviewCache.cxx
+++ b/sd/source/ui/presenter/PresenterPreviewCache.cxx
@@ -96,7 +96,7 @@ PresenterPreviewCache::PresenterPreviewCache (const Reference<XComponentContext>
     : PresenterPreviewCacheInterfaceBase(m_aMutex),
       maPreviewSize(Size(200,200)),
       mpCacheContext(new PresenterCacheContext()),
-      mpCache(new PageCache(maPreviewSize, false, mpCacheContext))
+      mpCache(new PageCache(maPreviewSize, Bitmap::HasFastScale(), mpCacheContext))
 {
     (void)rxContext;
 }
@@ -146,7 +146,7 @@ void SAL_CALL PresenterPreviewCache::setPreviewSize (
     OSL_ASSERT(mpCache.get()!=NULL);
 
     maPreviewSize = Size(rSize.Width, rSize.Height);
-    mpCache->ChangeSize(maPreviewSize, false);
+    mpCache->ChangeSize(maPreviewSize, Bitmap::HasFastScale());
 }
 
 Reference<rendering::XBitmap> SAL_CALL PresenterPreviewCache::getSlidePreview (
diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx
index 51d1a66..e467a0d 100644
--- a/sd/source/ui/slidesorter/view/SlideSorterView.cxx
+++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx
@@ -425,7 +425,7 @@ void SlideSorterView::Layout ()
             const Size aNewPreviewSize (mpLayouter->GetPageObjectLayouter()->GetPreviewSize(PageObjectLayouter::WindowCoordinateSystem));
             if (maPreviewSize != aNewPreviewSize && GetPreviewCache())
             {
-                mpPreviewCache->ChangeSize(aNewPreviewSize, false);
+                mpPreviewCache->ChangeSize(aNewPreviewSize, Bitmap::HasFastScale());
                 maPreviewSize = aNewPreviewSize;
             }
         }
@@ -707,7 +707,7 @@ void SlideSorterView::ConfigurationChanged (
         mpPreviewCache.reset(
             new cache::PageCache(
                 mpLayouter->GetPageObjectSize(),
-                false,
+                Bitmap::HasFastScale(),
                 cache::SharedCacheContext(new ViewCacheContext(mrSlideSorter))));
     }
 
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
index 38816e4..2115160 100644
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -24,6 +24,7 @@
 #include <vcl/bitmapex.hxx>
 #include <vcl/bitmap.hxx>
 #include <vcl/bitmapscalesuper.hxx>
+#include <vcl/opengl/OpenGLHelper.hxx>
 
 #include <boost/scoped_array.hpp>
 
@@ -993,6 +994,11 @@ bool Bitmap::Scale( const Size& rNewSize, sal_uInt32 nScaleFlag )
     return bRet;
 }
 
+bool Bitmap::HasFastScale()
+{
+    return OpenGLHelper::isVCLOpenGLEnabled();
+}
+
 void Bitmap::AdaptBitCount(Bitmap& rNew) const
 {
     ImplAdaptBitCount(rNew);
commit 4cff453efd33e5b94d7f9e54d48aa30bd550da76
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Sat Jan 17 20:00:52 2015 +0100

    "area" scaling for opengl that has good results for downscaling
    
    Change-Id: I0e4ad776cbf31f9a130aedf0f9741927560b5ac1
    Signed-off-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk
index 0aa324f..0a54ad6 100644
--- a/vcl/Package_opengl.mk
+++ b/vcl/Package_opengl.mk
@@ -10,6 +10,8 @@
 $(eval $(call gb_Package_Package,vcl_opengl_shader,$(SRCDIR)/vcl/opengl))
 
 $(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
+	areaScaleFastFragmentShader.glsl \
+	areaScaleFragmentShader.glsl \
 	blendedTextureFragmentShader.glsl \
 	blendedTextureVertexShader.glsl \
 	dumbVertexShader.glsl \
diff --git a/vcl/inc/opengl/program.hxx b/vcl/inc/opengl/program.hxx
index 996bc61..1e137aa 100644
--- a/vcl/inc/opengl/program.hxx
+++ b/vcl/inc/opengl/program.hxx
@@ -55,6 +55,8 @@ public:
     void SetUniform2f( const OString& rName, GLfloat v1, GLfloat v2 );
     void SetUniform1fv( const OString& rName, GLsizei nCount, GLfloat* aValues );
     void SetUniform2fv( const OString& rName, GLsizei nCount, GLfloat* aValues );
+    void SetUniform1i( const OString& rName, GLint v1 );
+    void SetUniform1iv( const OString& rName, GLsizei nCount, GLint* aValues );
     void SetColor( const OString& rName, const Color& rColor );
     void SetColor( const OString& rName, SalColor nColor, sal_uInt8 nTransparency );
     void SetColorf( const OString& rName, SalColor nColor, double fTransparency );
diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx
index 200698f..84c64ed 100644
--- a/vcl/inc/opengl/salbmp.hxx
+++ b/vcl/inc/opengl/salbmp.hxx
@@ -104,6 +104,7 @@ private:
     bool ImplScaleFilter( const double& rScaleX, const double& rScaleY, GLenum nFilter );
     void ImplCreateKernel( const double& fScale, const Kernel& rKernel, GLfloat*& pWeights, sal_uInt32& aKernelSize );
     bool ImplScaleConvolution( const double& rScaleX, const double& rScaleY, const Kernel& aKernel );
+    bool ImplScaleArea( double rScaleX, double rScaleY );
 
 public:
 
diff --git a/vcl/opengl/areaScaleFastFragmentShader.glsl b/vcl/opengl/areaScaleFastFragmentShader.glsl
new file mode 100644
index 0000000..b8874d1
--- /dev/null
+++ b/vcl/opengl/areaScaleFastFragmentShader.glsl
@@ -0,0 +1,43 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/* TODO Use textureOffset for newest version of GLSL */
+
+uniform sampler2D sampler;
+uniform int xscale;
+uniform int yscale;
+uniform float xstep;
+uniform float ystep;
+uniform float ratio; // = 1.0/(xscale*yscale)
+
+varying vec2 tex_coord;
+
+/*
+ Just make the resulting color the average of all the source pixels
+ (which is an area (xscale)x(yscale) ).
+*/
+void main(void)
+{
+    vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );
+    vec2 offset = vec2( 0.0, 0.0 );
+    for( int y = 0; y < yscale; ++y )
+    {
+        for( int x = 0; x < xscale; ++x )
+        {
+            sum += texture2D( sampler, tex_coord.st + offset );
+            offset.x += xstep;
+        }
+        offset.y += ystep;
+        offset.x = 0.0;
+    }
+    sum *= ratio;
+    gl_FragColor = sum;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/areaScaleFragmentShader.glsl b/vcl/opengl/areaScaleFragmentShader.glsl
new file mode 100644
index 0000000..cae5eb6
--- /dev/null
+++ b/vcl/opengl/areaScaleFragmentShader.glsl
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/* TODO Use textureOffset for newest version of GLSL */
+
+uniform sampler2D sampler;
+uniform int swidth;
+uniform int sheight;
+uniform float xscale;
+uniform float yscale;
+uniform float xsrcconvert;
+uniform float ysrcconvert;
+uniform float xdestconvert;
+uniform float ydestconvert;
+
+varying vec2 tex_coord;
+
+void main(void)
+{
+    // Convert to pixel coordinates again.
+    int dx = int( tex_coord.s * xdestconvert );
+    int dy = int( tex_coord.t * ydestconvert );
+
+    // Note: These values are always the same for the same X (or Y),
+    // so they could be precalculated in C++ and passed to the shader,
+    // but GLSL has limits on the size of uniforms passed to it,
+    // so it'd need something like texture buffer objects from newer
+    // GLSL versions, and it seems the hassle is not really worth it.
+
+    // How much each column/row will contribute to the resulting pixel.
+    // assert( xscale <= 100 ); assert( yscale <= 100 );
+    float xratio[ 100 + 2 ];
+    float yratio[ 100 + 2 ];
+    // For finding the first and last source pixel.
+    int xpixel[ 100 + 2 ];
+    int ypixel[ 100 + 2 ];
+
+    int xpos = 0;
+    int ypos = 0;
+
+    // Compute the range of source pixels which will make up this destination pixel.
+    float fsx1 = dx * xscale;
+    float fsx2 = fsx1 + xscale;
+    // To whole pixel coordinates.
+    int sx1 = ceil( fsx1 );
+    int sx2 = floor( fsx2 );
+    // Range checking.
+    sx2 = min( sx2, swidth - 1 );
+    sx1 = min( sx1, sx2 );
+
+    // How much one full column contributes to the resulting pixel.
+    float width = min( xscale, swidth - fsx1 );
+
+    if( sx1 - fsx1 > 0.001 )
+    {   // The first column contributes only partially.
+        xpixel[ xpos ] = sx1 - 1;
+        xratio[ xpos ] = ( sx1 - fsx1 ) / width;
+        ++xpos;
+    }
+    for( int sx = sx1; sx < sx2; ++sx )
+    {   // Columns that fully contribute to the resulting pixel.
+        xpixel[ xpos ] = sx;
+        xratio[ xpos ] = 1.0 / width;
+        ++xpos;
+    }
+    if( fsx2 - sx2 > 0.001 )
+    {   // The last column contributes only partially.
+        xpixel[ xpos ] = sx2;
+        xratio[ xpos ] = min( min( fsx2 - sx2, 1.0 ) / width, 1.0 );
+        ++xpos;
+    }
+
+    // The same for Y.
+    float fsy1 = dy * yscale;
+    float fsy2 = fsy1 + yscale;
+    int sy1 = ceil( fsy1 );
+    int sy2 = floor( fsy2 );
+    sy2 = min( sy2, sheight - 1 );
+    sy1 = min( sy1, sy2 );
+
+    float height = min( yscale, sheight - fsy1 );
+
+    if( sy1 - fsy1 > 0.001 )
+    {
+        ypixel[ ypos ] = sy1 - 1;
+        yratio[ ypos ] = ( sy1 - fsy1 ) / height;
+        ++ypos;
+    }
+    for( int sy = sy1; sy < sy2; ++sy )
+    {
+        ypixel[ ypos ] = sy;
+        yratio[ ypos ] = 1.0 / height;
+        ++ypos;
+    }
+    if( fsy2 - sy2 > 0.001 )
+    {
+        ypixel[ ypos ] = sy2;
+        yratio[ ypos ] = min( min( fsy2 - sy2, 1.0 ) / height, 1.0 );
+        ++ypos;
+    }
+
+    int xstart = xpixel[ 0 ];
+    int xend = xpixel[ xpos - 1 ];
+    int ystart = ypixel[ 0 ];
+    int yend = ypixel[ ypos - 1 ];
+
+    vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );
+
+    ypos = 0;
+    for( int y = ystart; y <= yend; ++y, ++ypos )
+    {
+        vec4 tmp = vec4( 0.0, 0.0, 0.0, 0.0 );
+        xpos = 0;
+        for( int x = xstart; x <= xend; ++x, ++xpos )
+        {
+            vec2 offset = vec2( x * xsrcconvert, y * ysrcconvert );
+            tmp += texture2D( sampler, offset ) * xratio[ xpos ];
+        }
+        sum += tmp * yratio[ ypos ];
+    }
+
+    gl_FragColor = sum;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/program.cxx b/vcl/opengl/program.cxx
index 8b92c4b..80c2395 100644
--- a/vcl/opengl/program.cxx
+++ b/vcl/opengl/program.cxx
@@ -150,6 +150,18 @@ void OpenGLProgram::SetUniform2fv( const OString& rName, GLsizei nCount, GLfloat
     glUniform2fv( nUniform, nCount, aValues );
 }
 
+void OpenGLProgram::SetUniform1i( const OString& rName, GLint v1 )
+{
+    GLuint nUniform = GetUniformLocation( rName );
+    glUniform1i( nUniform, v1 );
+}
+
+void OpenGLProgram::SetUniform1iv( const OString& rName, GLsizei nCount, GLint* aValues )
+{
+    GLuint nUniform = GetUniformLocation( rName );
+    glUniform1iv( nUniform, nCount, aValues );
+}
+
 void OpenGLProgram::SetColor( const OString& rName, SalColor nColor, sal_uInt8 nTransparency )
 {
     GLuint nUniform = GetUniformLocation( rName );
diff --git a/vcl/opengl/scale.cxx b/vcl/opengl/scale.cxx
index a81c63b..84cf967 100644
--- a/vcl/opengl/scale.cxx
+++ b/vcl/opengl/scale.cxx
@@ -188,6 +188,78 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
     return true;
 }
 
+/*
+ "Area" scaling algorithm, which seems to give better results for downscaling
+ than other algorithms. The principle (taken from opencv, see resize.cl)
+ is that each resulting pixel is the average of all the source pixel values
+ it represents. Which is trivial in the case of exact multiples for downscaling,
+ the generic case needs to also consider that some source pixels contribute
+ only partially to their resulting pixels (becauses of non-integer multiples).
+*/
+bool OpenGLSalBitmap::ImplScaleArea( double rScaleX, double rScaleY )
+{
+    int nNewWidth( mnWidth * rScaleX );
+    int nNewHeight( mnHeight * rScaleY );
+
+    if( nNewWidth == mnWidth && nNewHeight == mnHeight )
+        return true;
+
+    double ixscale = 1 / rScaleX;
+    double iyscale = 1 / rScaleY;
+    bool fast = ( ixscale == int( ixscale ) && iyscale == int( iyscale )
+        && int( nNewWidth * ixscale ) == mnWidth && int( nNewHeight * iyscale ) == mnHeight );
+
+    // The generic case has arrays only up to 100 ratio downscaling, which is hopefully enough
+    // in practice, but protect against buffer overflows in case such an extreme case happens
+    // (and in such case the precision of the generic algorithm probably doesn't matter anyway).
+    if( ixscale > 100 || iyscale > 100 )
+        fast = true;
+
+    // TODO Make sure the framebuffer is alright
+
+    OpenGLProgram* pProgram = mpContext->UseProgram( "textureVertexShader",
+        fast ? OUString( "areaScaleFastFragmentShader" ) : OUString( "areaScaleFragmentShader" ));
+    if( pProgram == 0 )
+        return false;
+
+    OpenGLTexture aScratchTex = OpenGLTexture( nNewWidth, nNewHeight );
+    OpenGLFramebuffer* pFramebuffer = mpContext->AcquireFramebuffer( aScratchTex );
+
+    if( fast )
+    {
+        pProgram->SetUniform1i( "xscale", ixscale );
+        pProgram->SetUniform1i( "yscale", iyscale );
+        pProgram->SetUniform1f( "xstep", 1.0 / mnWidth );
+        pProgram->SetUniform1f( "ystep", 1.0 / mnHeight );
+        pProgram->SetUniform1f( "ratio", 1.0 / ( ixscale * iyscale ));
+    }
+    else
+    {
+        pProgram->SetUniform1f( "xscale", ixscale );
+        pProgram->SetUniform1f( "yscale", iyscale );
+        pProgram->SetUniform1i( "swidth", mnWidth );
+        pProgram->SetUniform1i( "sheight", mnHeight );
+        // For converting between <0,mnWidth-1> and <0.0,1.0> coordinate systems.
+        pProgram->SetUniform1f( "xsrcconvert", 1.0 / ( mnWidth - 1 ));
+        pProgram->SetUniform1f( "ysrcconvert", 1.0 / ( mnHeight - 1 ));
+        pProgram->SetUniform1f( "xdestconvert", 1.0 * ( nNewWidth - 1 ));
+        pProgram->SetUniform1f( "ydestconvert", 1.0 * ( nNewHeight - 1 ));
+    }
+
+    pProgram->SetTexture( "sampler", maTexture );
+    pProgram->DrawTexture( maTexture );
+    pProgram->Clean();
+
+    maTexture = aScratchTex;
+    mpContext->ReleaseFramebuffer( pFramebuffer );
+
+    mnWidth = nNewWidth;
+    mnHeight = nNewHeight;
+
+    CHECK_GL_ERROR();
+    return true;
+}
+
 bool OpenGLSalBitmap::ImplScale( const double& rScaleX, const double& rScaleY, sal_uInt32 nScaleFlag )
 {
     SAL_INFO( "vcl.opengl", "::ImplScale" );
@@ -209,6 +281,10 @@ bool OpenGLSalBitmap::ImplScale( const double& rScaleX, const double& rScaleY, s
 
         return ImplScaleConvolution( rScaleX, rScaleY, aKernel );
     }
+    else if( nScaleFlag == BMP_SCALE_BESTQUALITY && rScaleX <= 1 && rScaleY <= 1 )
+    { // Use are scaling for best quality, but only if downscaling.
+        return ImplScaleArea( rScaleX, rScaleY );
+    }
     else if( nScaleFlag == BMP_SCALE_LANCZOS || nScaleFlag == BMP_SCALE_BESTQUALITY  )
     {
         const Lanczos3Kernel aKernel;
commit d1e8c8b43820cb8bba54bfe9275cc87f06c108aa
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Thu Jan 8 18:09:49 2015 +0100

    implement optimized hairline drawing for opengl
    
    As a side effect, this prevents the lines from looking too wide,
    because of generic polygon drawing being a bit too generous with AA.
    
    Change-Id: I17314c39fd57e33ecbd10b8a8785c600bdc5b212
    Signed-off-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 07a7cd7..6c565fa 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -1219,17 +1219,19 @@ bool OpenGLSalGraphicsImpl::drawPolyLine(
     //bool bDrawnOk = true;
     if( bIsHairline )
     {
-        // hairlines can benefit from a simplified tesselation
-        // e.g. for hairlines the linejoin style can be ignored
-        /*basegfx::B2DTrapezoidVector aB2DTrapVector;
-        basegfx::tools::createLineTrapezoidFromB2DPolygon( aB2DTrapVector, aPolygon, rLineWidth.getX() );
-
-        // draw tesselation result
-        const int nTrapCount = aB2DTrapVector.size();
-        if( nTrapCount > 0 )
-            bDrawnOk = drawFilledTrapezoids( &aB2DTrapVector[0], nTrapCount, fTransparency );
-
-        return bDrawnOk;*/
+        // hairlines can be drawn in a simpler way (the linejoin and linecap styles can be ignored)
+        PreDraw();
+        if( UseSolidAA( mnLineColor, fTransparency ))
+        {
+            for( sal_uInt32 j = 0; j < rPolygon.count() - 1; j++ )
+            {
+                const ::basegfx::B2DPoint& rPt1( rPolygon.getB2DPoint( j ) );
+                const ::basegfx::B2DPoint& rPt2( rPolygon.getB2DPoint(( j + 1 )) );
+                DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
+            }
+        }
+        PostDraw();
+        return true;
     }
 
     // get the area polygon for the line polygon
commit 2ee908b885f474b8f7d6feaa8984999804edf4b9
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Wed Jan 7 17:43:39 2015 +0100

    do not set Y line width to 0
    
    I'm somewhat confused by why there needs to be a separate line width
    for X and Y, but apparently there is, and the latter shouldn't be just plain 0
    (otherwise a number of drawPolyLine() implementations either skip using
    a simpler path for the usual case of them being equal, or even plain to refuse
    work at all and cause a fall back).
    And I hope this doesn't lead to finding out that some of those implementation
    are actually buggy.
    
    Change-Id: I2dbbd1539c4a96d41935cce9ae6565872e2a459b
    Signed-off-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/vcl/source/outdev/polyline.cxx b/vcl/source/outdev/polyline.cxx
index ece1d6f..78eb139 100644
--- a/vcl/source/outdev/polyline.cxx
+++ b/vcl/source/outdev/polyline.cxx
@@ -302,7 +302,7 @@ bool OutputDevice::DrawPolyLineDirect( const basegfx::B2DPolygon& rB2DPolygon,
         // transform the line width if used
         if( fLineWidth != 0.0 )
         {
-            aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, 0.0 );
+            aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, fLineWidth );
         }
 
         // transform the polygon
commit 0df46f36575d44a2dec0d117ca909c74fddd2fae
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Mon Jan 12 13:24:47 2015 +0100

    make AA edges of objects look smoother (opengl)
    
    Change-Id: I66a04febdbfa673e0883ab6f574bb7768cad7953
    Signed-off-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index cf7392d..2b815ee 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -64,7 +64,7 @@ protected:
 
     void ImplInitClipRegion();
     void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask );
-
+    void ImplDrawLineAA( double nX1, double nY1, double nX2, double nY2, bool edge = false );
     bool CheckOffscreenTexture();
 
 public:
@@ -81,6 +81,7 @@ public:
     void DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
     void DrawLineAA( double nX1, double nY1, double nX2, double nY2 );
     void DrawLinesAA( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
+    void DrawEdgeAA( double nX1, double nY1, double nX2, double nY2 );
     void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
     void DrawConvexPolygon( const Polygon& rPolygon );
     void DrawRect( long nX, long nY, long nWidth, long nHeight );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 6900efd..07a7cd7 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -472,7 +472,11 @@ void OpenGLSalGraphicsImpl::DrawLineAA( double nX1, double nY1, double nX2, doub
         glDrawArrays( GL_LINES, 0, 2 );
         return;
     }
+    ImplDrawLineAA( nX1, nY1, nX2, nY2 );
+}
 
+void OpenGLSalGraphicsImpl::ImplDrawLineAA( double nX1, double nY1, double nX2, double nY2, bool edge )
+{
     // Draw the line anti-aliased. Based on code with the following notice:
     /* Drawing nearly perfect 2D line segments in OpenGL
      * You can use this code however you want.
@@ -486,39 +490,52 @@ void OpenGLSalGraphicsImpl::DrawLineAA( double nX1, double nY1, double nX2, doub
     double y1 = nY1;
     double x2 = nX2;
     double y2 = nY2;
-    const int w = 1; // line width
+
+    // A special hack for drawing lines that are in fact AA edges of a shape. Make the line somewhat
+    // wider, but (done further below) draw the entire width as a gradient. This would be wrong for a line
+    // (too wide and seemingly less straight), but it makes the edges look smoother and the width difference
+    // is almost unnoticeable.
+    const double w = edge ? 1.4 : 1.0;
 
     double t;
     double R;
+    double f = w - static_cast<int>(w);
     //determine parameters t,R
-    switch( w )
+    if ( w>=0.0 && w<1.0 )
     {
-        case 0:
-            return;
-        case 1:
-            t=0.05;
-            R=0.768;
-        break;
-        case 2:
-            t=0.38;
-            R=1.08;
-        break;
-        case 3:
-            t=0.96;
-            R=1.08;
-            break;
-        case 4:
-            t=1.44;
-            R=1.08;
-            break;
-        case 5:
-            t=1.9;
-            R=1.08;
-            break;
-        default:
-            t=2.5+(w-6)*0.50;
-            R=1.08;
-            break;
+        t=0.05;
+        R=0.48+0.32*f;
+    }
+    else if ( w>=1.0 && w<2.0 )
+    {
+        t=0.05+f*0.33;
+        R=0.768+0.312*f;
+    }
+    else if ( w>=2.0 && w<3.0 )
+    {
+        t=0.38+f*0.58;
+        R=1.08;
+    }
+    else if ( w>=3.0 && w<4.0 )
+    {
+        t=0.96+f*0.48;
+        R=1.08;
+    }
+    else if ( w>=4.0 && w<5.0 )
+    {
+        t=1.44+f*0.46;
+        R=1.08;
+    }
+    else if ( w>=5.0 && w<6.0 )
+    {
+        t=1.9+f*0.6;
+        R=1.08;
+    }
+    else if ( w>=6.0 )
+    {
+        double ff=w-6.0;
+        t=2.5+ff*0.50;
+        R=1.08;
     }
 
     //determine angle of the line to horizontal
@@ -526,7 +543,7 @@ void OpenGLSalGraphicsImpl::DrawLineAA( double nX1, double nY1, double nX2, doub
     double Rx=0,Ry=0; //fading edge of a line
     double dx=x2-x1;
     double dy=y2-y1;
-    if ( w < 3)
+    if ( w < 3 )
     {   //approximate to make things even faster
         double m=dy/dx;
         //and calculate tx,ty,Rx,Ry
@@ -568,6 +585,13 @@ void OpenGLSalGraphicsImpl::DrawLineAA( double nX1, double nY1, double nX2, doub
         Rx=R*dx; Ry=R*dy;
     }
 
+    if( edge )
+    {   // See above.
+        Rx += tx;
+        Ry += ty;
+        tx = ty = 0;
+    }
+
     GLfloat vertices[]=
     {
 #define convertX( x ) GLfloat( (2 * (x)) / GetWidth()  - 1.0f)
@@ -606,6 +630,14 @@ void OpenGLSalGraphicsImpl::DrawLinesAA( sal_uInt32 nPoints, const SalPoint* pPt
         DrawLineAA( pPtAry[ nPoints - 1 ].mnX, pPtAry[ nPoints - 1 ].mnY, pPtAry[ 0 ].mnX, pPtAry[ 0 ].mnY );
 }
 
+void OpenGLSalGraphicsImpl::DrawEdgeAA( double nX1, double nY1, double nX2, double nY2 )
+{
+    assert( mrParent.getAntiAliasB2DDraw());
+    if( nX1 == nX2 || nY1 == nY2 )
+        return; //horizontal/vertical, no need for AA
+    ImplDrawLineAA( nX1, nY1, nX2, nY2, true );
+}
+
 void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
 {
     std::vector<GLfloat> aVertices(nPoints * 2);
@@ -654,9 +686,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon )
             {
                 const Point& rPt1 = rPolygon.GetPoint( i );
                 const Point& rPt2 = rPolygon.GetPoint(( i + 1 ) % nPoints );
-                if( rPt1.getX() == rPt2.getX() || rPt1.getY() == rPt2.getY())
-                    continue; //horizontal/vertical, no need for AA
-                DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
+                DrawEdgeAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
             }
             UseSolid( lastSolidColor, lastSolidTransparency );
         }
@@ -751,9 +781,7 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPol
                 {
                     const ::basegfx::B2DPoint& rPt1( rPolygon.getB2DPoint( j ) );
                     const ::basegfx::B2DPoint& rPt2( rPolygon.getB2DPoint(( j + 1 ) % rPolygon.count()) );
-                    if( rPt1.getX() == rPt2.getX() || rPt1.getY() == rPt2.getY())
-                        continue; //horizontal/vertical, no need for AA
-                    DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
+                    DrawEdgeAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
                 }
             }
             UseSolid( lastSolidColor, lastSolidTransparency );
commit f773a0f62b69795c31146d749626949eb5b325ed
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Mon Jan 12 13:20:54 2015 +0100

    clean up resetting of solid color when using opengl AA
    
    118529d4644a and 011903894 might have been technically correct, but
    'mProgramIsSolidLineColor' is clearly a misnomer at best, and they'd
    have made it even more likely that this would break yet again.
    
    Change-Id: I1f01663e2abc0b1b0e557ae7241637a96e1a402a
    Signed-off-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 69c211d..cf7392d 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -57,8 +57,10 @@ protected:
     SalColor mnLineColor;
     SalColor mnFillColor;
 #ifdef DBG_UTIL
-    bool mProgramIsSolidLineColor;
+    bool mProgramIsSolidColor;
 #endif
+    SalColor mProgramSolidColor;
+    double mProgramSolidTransparency;
 
     void ImplInitClipRegion();
     void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask );
@@ -84,7 +86,7 @@ public:
     void DrawRect( long nX, long nY, long nWidth, long nHeight );
     void DrawRect( const Rectangle& rRect );
     void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
-    void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bLine, bool blockAA = false );
+    void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon, bool blockAA = false );
     void DrawRegionBand( const RegionBand& rRegion );
     void DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false );
     void DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted = false );
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index fc01730..6900efd 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -48,7 +48,7 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryPr
     , mnLineColor(SALCOLOR_NONE)
     , mnFillColor(SALCOLOR_NONE)
 #ifdef DBG_UTIL
-    , mProgramIsSolidLineColor(false)
+    , mProgramIsSolidColor(false)
 #endif
 {
 }
@@ -166,7 +166,7 @@ void OpenGLSalGraphicsImpl::PostDraw()
         mpProgram->Clean();
         mpProgram = NULL;
 #ifdef DBG_UTIL
-        mProgramIsSolidLineColor = false;
+        mProgramIsSolidColor = false;
 #endif
     }
 
@@ -198,7 +198,7 @@ void OpenGLSalGraphicsImpl::ImplSetClipBit( const vcl::Region& rClip, GLuint nMa
         if( rClip.getRegionBand() )
             DrawRegionBand( *rClip.getRegionBand() );
         else
-            DrawPolyPolygon( rClip.GetAsB2DPolyPolygon(), false, true );
+            DrawPolyPolygon( rClip.GetAsB2DPolyPolygon(), true );
     }
 
     glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
@@ -361,7 +361,7 @@ bool OpenGLSalGraphicsImpl::UseProgram( const OUString& rVertexShader, const OUS
         mpProgram->Clean();
     mpProgram = mpContext->UseProgram( rVertexShader, rFragmentShader );
 #ifdef DBG_UTIL
-    mProgramIsSolidLineColor = false; // UseSolid() will set to true if needed
+    mProgramIsSolidColor = false; // UseSolid() will set to true if needed
 #endif
     return ( mpProgram != NULL );
 }
@@ -374,8 +374,10 @@ bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, sal_uInt8 nTransparency )
         return false;
     mpProgram->SetColor( "color", nColor, nTransparency );
 #ifdef DBG_UTIL
-    mProgramIsSolidLineColor = true;
+    mProgramIsSolidColor = true;
 #endif
+    mProgramSolidColor = nColor;
+    mProgramSolidTransparency = nTransparency / 100.0;
     return true;
 }
 
@@ -387,8 +389,10 @@ bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, double fTransparency )
         return false;
     mpProgram->SetColorf( "color", nColor, fTransparency );
 #ifdef DBG_UTIL
-    mProgramIsSolidLineColor = true;
+    mProgramIsSolidColor = true;
 #endif
+    mProgramSolidColor = nColor;
+    mProgramSolidTransparency = fTransparency;
     return true;
 }
 
@@ -640,18 +644,22 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon )
         // may be a problem, if that is a real problem, the polygon areas itself needs to be
         // masked out for this or something.
 #ifdef DBG_UTIL
-        assert( mProgramIsSolidLineColor );
+        assert( mProgramIsSolidColor );
 #endif
-        UseSolidAA( mnLineColor );
-        for( i = 0; i < nPoints; ++i )
+        SalColor lastSolidColor = mProgramSolidColor;
+        double lastSolidTransparency = mProgramSolidTransparency;
+        if( UseSolidAA( lastSolidColor, lastSolidTransparency ))
         {
-            const Point& rPt1 = rPolygon.GetPoint( i );
-            const Point& rPt2 = rPolygon.GetPoint(( i + 1 ) % nPoints );
-            if( rPt1.getX() == rPt2.getX() || rPt1.getY() == rPt2.getY())
-                continue; //horizontal/vertical, no need for AA
-            DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
+            for( i = 0; i < nPoints; ++i )
+            {
+                const Point& rPt1 = rPolygon.GetPoint( i );
+                const Point& rPt2 = rPolygon.GetPoint(( i + 1 ) % nPoints );
+                if( rPt1.getX() == rPt2.getX() || rPt1.getY() == rPt2.getY())
+                    continue; //horizontal/vertical, no need for AA
+                DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
+            }
+            UseSolid( lastSolidColor, lastSolidTransparency );
         }
-        UseSolid( mnLineColor );
     }
 }
 
@@ -695,11 +703,11 @@ void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPt
     else
     {
         const ::basegfx::B2DPolyPolygon aPolyPolygon( aPolygon );
-        DrawPolyPolygon( aPolyPolygon, false );
+        DrawPolyPolygon( aPolyPolygon );
     }
 }
 
-void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon, bool bLine, bool blockAA )
+void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon, bool blockAA )
 {
     ::std::vector< GLfloat > aVertices;
     GLfloat nWidth = GetWidth();
@@ -730,23 +738,26 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPol
         // may be a problem, if that is a real problem, the polygon areas itself needs to be
         // masked out for this or something.
 #ifdef DBG_UTIL
-        assert( mProgramIsSolidLineColor );
+        assert( mProgramIsSolidColor );
 #endif
-        bool bUseLineColor = bLine || mnLineColor != SALCOLOR_NONE;
-        UseSolidAA( bUseLineColor ? mnLineColor : mnFillColor );
-        for( sal_uInt32 i = 0; i < aSimplePolyPolygon.count(); i++ )
+        SalColor lastSolidColor = mProgramSolidColor;
+        double lastSolidTransparency = mProgramSolidTransparency;
+        if( UseSolidAA( lastSolidColor, lastSolidTransparency ))
         {
-            const basegfx::B2DPolygon& rPolygon( aSimplePolyPolygon.getB2DPolygon( i ) );
-            for( sal_uInt32 j = 0; j < rPolygon.count(); j++ )
+            for( sal_uInt32 i = 0; i < aSimplePolyPolygon.count(); i++ )
             {
-                const ::basegfx::B2DPoint& rPt1( rPolygon.getB2DPoint( j ) );
-                const ::basegfx::B2DPoint& rPt2( rPolygon.getB2DPoint(( j + 1 ) % rPolygon.count()) );
-                if( rPt1.getX() == rPt2.getX() || rPt1.getY() == rPt2.getY())
-                    continue; //horizontal/vertical, no need for AA
-                DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
+                const basegfx::B2DPolygon& rPolygon( aSimplePolyPolygon.getB2DPolygon( i ) );
+                for( sal_uInt32 j = 0; j < rPolygon.count(); j++ )
+                {
+                    const ::basegfx::B2DPoint& rPt1( rPolygon.getB2DPoint( j ) );
+                    const ::basegfx::B2DPoint& rPt2( rPolygon.getB2DPoint(( j + 1 ) % rPolygon.count()) );
+                    if( rPt1.getX() == rPt2.getX() || rPt1.getY() == rPt2.getY())
+                        continue; //horizontal/vertical, no need for AA
+                    DrawLineAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
+                }
             }
+            UseSolid( lastSolidColor, lastSolidTransparency );
         }
-        UseSolid( bLine ? mnLineColor : mnFillColor );
     }
 
     CHECK_GL_ERROR();
@@ -1134,7 +1145,7 @@ bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rP
         for( sal_uInt32 i = 0; i < rPolyPolygon.count(); i++ )
         {
             const ::basegfx::B2DPolyPolygon aOnePoly( rPolyPolygon.getB2DPolygon( i ) );
-            DrawPolyPolygon( aOnePoly, false );
+            DrawPolyPolygon( aOnePoly );
         }
     }
 
@@ -1217,7 +1228,7 @@ bool OpenGLSalGraphicsImpl::drawPolyLine(
         for( sal_uInt32 i = 0; i < aAreaPolyPoly.count(); i++ )
         {
             const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( i ) );
-            DrawPolyPolygon( aOnePoly, true );
+            DrawPolyPolygon( aOnePoly );
         }
     }
     PostDraw();
commit a2bf2e315c68eb761be0a3b32e98f204de4024fb
Author: Luboš Luňák <l.lunak at collabora.com>
Date:   Wed Jan 7 18:06:25 2015 +0100

    fix confusion between transparency and opacity
    
    Change-Id: Ifa69f3272ebda2a61ac00d2affb8aebd4524f0fc
    Signed-off-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 1e72c0a..fc01730 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -404,14 +404,14 @@ bool OpenGLSalGraphicsImpl::UseSolidAA( SalColor nColor, double fTransparency )
         return UseSolid( nColor );
     if( !UseProgram( "textureVertexShader", "linearGradientFragmentShader" ) )
         return false;
-    mpProgram->SetColorf( "start_color", nColor, 0.0f );
-    mpProgram->SetColorf( "end_color", nColor, fTransparency );
+    mpProgram->SetColorf( "start_color", nColor, fTransparency );
+    mpProgram->SetColorf( "end_color", nColor, 1.0f );
     return true;
 }
 
 bool OpenGLSalGraphicsImpl::UseSolidAA( SalColor nColor )
 {
-    return UseSolidAA( nColor, 1.0 );
+    return UseSolidAA( nColor, 0.0 );
 }
 
 bool OpenGLSalGraphicsImpl::UseInvert()


More information about the Libreoffice-commits mailing list