summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2015-01-12 13:24:47 +0100
committerLuboš Luňák <l.lunak@collabora.com>2015-01-12 13:34:14 +0100
commitca1f918c327f82568e65f7f49e24b7158c63181f (patch)
treea77f4baacacf8f0565764b86be63e1e52cdac078 /vcl
parent67d6aef4c5970b6fc32617f6ee61512236072c6a (diff)
make AA edges of objects look smoother (opengl)
Change-Id: I66a04febdbfa673e0883ab6f574bb7768cad7953
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/openglgdiimpl.hxx3
-rw-r--r--vcl/opengl/gdiimpl.cxx98
2 files changed, 65 insertions, 36 deletions
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index cf7392d38947..2b815ee80efd 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 afdb8d9642da..a284236b824c 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 );